Whamcloud - gitweb
b=19557 actually make lustre_hash_for_each_empty() more efficient
authorRobert Read <rread@sun.com>
Wed, 13 Jan 2010 02:25:03 +0000 (18:25 -0800)
committerRobert Read <rread@sun.com>
Mon, 25 Jan 2010 18:21:51 +0000 (10:21 -0800)
a=johann
i=adilger
i=herring4

libcfs/include/libcfs/libcfs_hash.h
libcfs/libcfs/hash.c

index 769854f..e195c24 100644 (file)
@@ -407,8 +407,13 @@ cfs_hash_u64_hash(__u64 key, unsigned mask)
 #define cfs_hash_for_each_bucket(hs, hsb, pos)   \
         for (pos = 0;                            \
              pos <= hs->hs_cur_mask &&           \
 #define cfs_hash_for_each_bucket(hs, hsb, pos)   \
         for (pos = 0;                            \
              pos <= hs->hs_cur_mask &&           \
-             ({ hsb = hs->hs_buckets[i]; 1; });  \
+             (hsb = hs->hs_buckets[pos]);       \
              pos++)
 
              pos++)
 
+#define cfs_hash_for_each_bucket_restart(hs, hsb, pos)  \
+        for (/* pos=0 done once by caller */;           \
+             pos <= hs->hs_cur_mask &&                  \
+             (hsb = hs->hs_buckets[pos]);              \
+             pos++)
 /* !__LIBCFS__HASH_H__ */
 #endif
 /* !__LIBCFS__HASH_H__ */
 #endif
index 56e2df5..4aca010 100644 (file)
@@ -515,13 +515,20 @@ cfs_hash_for_each_empty(cfs_hash_t *hs,
 {
         cfs_hlist_node_t     *hnode;
         cfs_hash_bucket_t    *hsb;
 {
         cfs_hlist_node_t     *hnode;
         cfs_hash_bucket_t    *hsb;
+        cfs_hash_bucket_t    **hsb_last = NULL;
         void                 *obj;
         void                 *obj;
-        int                   i;
+        int                   i = 0;
         ENTRY;
 
 restart:
         cfs_hash_rlock(hs);
         ENTRY;
 
 restart:
         cfs_hash_rlock(hs);
-        cfs_hash_for_each_bucket(hs, hsb, i) {
+        /* If the hash table has changed since we last held lh_rwlock,
+         * we need to start traversing the list from the start. */
+        if (hs->hs_buckets != hsb_last) {
+                i = 0;
+                hsb_last = hs->hs_buckets;
+        }
+        cfs_hash_for_each_bucket_restart(hs, hsb, i) {
                 cfs_write_lock(&hsb->hsb_rwlock);
                 while (!cfs_hlist_empty(&hsb->hsb_head)) {
                         hnode =  hsb->hsb_head.first;
                 cfs_write_lock(&hsb->hsb_rwlock);
                 while (!cfs_hlist_empty(&hsb->hsb_head)) {
                         hnode =  hsb->hsb_head.first;