From e29cba679e46a2bea2298760cc54f1b52d22b727 Mon Sep 17 00:00:00 2001 From: yangsheng Date: Wed, 23 Dec 2009 15:21:19 +0800 Subject: [PATCH] b=19557 actually make lustre_hash_for_each_empty() more efficient i=johann i=herring3 --- lustre/include/class_hash.h | 8 +++++++- lustre/obdclass/class_hash.c | 11 +++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/lustre/include/class_hash.h b/lustre/include/class_hash.h index 0a345f8..afa2060 100644 --- a/lustre/include/class_hash.h +++ b/lustre/include/class_hash.h @@ -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 */ diff --git a/lustre/obdclass/class_hash.c b/lustre/obdclass/class_hash.c index 2e51f27..9bf81f4 100644 --- a/lustre/obdclass/class_hash.c +++ b/lustre/obdclass/class_hash.c @@ -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; -- 1.8.3.1