Whamcloud - gitweb
b=19557 actually make lustre_hash_for_each_empty() more efficient
authoryangsheng <Sheng.Yang@Sun.COM>
Wed, 23 Dec 2009 07:21:19 +0000 (15:21 +0800)
committerAndrew Perepechko <andrew.perepechko@sun.com>
Wed, 23 Dec 2009 12:01:45 +0000 (15:01 +0300)
i=johann
i=herring3

lustre/include/class_hash.h
lustre/obdclass/class_hash.c

index 0a345f8..afa2060 100644 (file)
@@ -346,7 +346,13 @@ lh_u64_hash(__u64 key, unsigned mask)
 #define lh_for_each_bucket(lh, lhb, pos)         \
         for (pos = 0;                            \
              pos <= lh->lh_cur_mask &&           \
-             ({ lhb = lh->lh_buckets[i]; 1; });  \
+             (lhb = lh->lh_buckets[pos]);       \
+             pos++)
+
+#define lh_for_each_bucket_restart(lh, lhb, pos) \
+        for (/* pos=0 done once by caller */;    \
+             pos <= lh->lh_cur_mask &&           \
+             (lhb = lh->lh_buckets[pos]);       \
              pos++)
 
 #endif /* __CLASS_HASH_H */
index 2e51f27..9bf81f4 100644 (file)
@@ -508,13 +508,20 @@ lustre_hash_for_each_empty(lustre_hash_t *lh, lh_for_each_cb func, void *data)
 {
         struct hlist_node    *hnode;
         lustre_hash_bucket_t *lhb;
+        lustre_hash_bucket_t **lhb_last = NULL;
         void                 *obj;
-        int                   i;
+        int                   i = 0;
         ENTRY;
 
 restart:
         lh_read_lock(lh);
-        lh_for_each_bucket(lh, lhb, i) {
+        /* If the hash table has changed since we last held lh_rwlock,
+         * we need to start traversing the list from the start. */
+        if (lh->lh_buckets != lhb_last) {
+                i = 0;
+                lhb_last = lh->lh_buckets;
+        }
+        lh_for_each_bucket_restart(lh, lhb, i) {
                 write_lock(&lhb->lhb_rwlock);
                 while (!hlist_empty(&lhb->lhb_head)) {
                         hnode =  lhb->lhb_head.first;