diff options
-rw-r--r-- | fs/bcachefs/hashtable.c | 2 | ||||
-rw-r--r-- | fs/bcachefs/hashtable.h | 25 |
2 files changed, 20 insertions, 7 deletions
diff --git a/fs/bcachefs/hashtable.c b/fs/bcachefs/hashtable.c index 5b11266c734a..604f9e7f6b15 100644 --- a/fs/bcachefs/hashtable.c +++ b/fs/bcachefs/hashtable.c @@ -53,6 +53,7 @@ void bch2_htable_expand(struct htable *ht, const struct htable_params p) } smp_store_release(&ht->table, (unsigned long) new.table | (shift + 1)); + ht->max_chain = 1; call_rcu(&free_rcu->rcu, htable_free_rcu); } @@ -71,6 +72,7 @@ int bch2_htable_init(struct htable *ht) ht->hash_seed = get_random_u32(); ht->nelems = 0; + ht->max_chain = 1; ht->table = __get_free_page(GFP_KERNEL|__GFP_ZERO); if (!ht->table) return -ENOMEM; diff --git a/fs/bcachefs/hashtable.h b/fs/bcachefs/hashtable.h index 316f955b9480..a58ed21a8dda 100644 --- a/fs/bcachefs/hashtable.h +++ b/fs/bcachefs/hashtable.h @@ -13,6 +13,7 @@ struct htable { struct mutex lock; unsigned hash_seed; unsigned nelems; + unsigned max_chain; unsigned long table; }; @@ -124,23 +125,33 @@ static inline int htable_insert(struct htable *ht, void *obj, const struct htable_params p) { struct htable_ptr t; - struct hlist_head *hash_head; - unsigned hash; + struct hlist_head *head; + struct hlist_node *n; + unsigned hash, chainlen = 1; hash = htable_obj_get_hash(obj, ht->hash_seed, p); mutex_lock(&ht->lock); t = htable_read_ptr(ht); - hash_head = htable_bucket(t, hash); + head = htable_bucket(t, hash); - if (__htable_lookup(hash_head, obj + p.key_offset, p)) { - mutex_unlock(&ht->lock); - return -EEXIST; + __hlist_for_each_rcu(n, head) { + if (!htable_cmp(obj + p.key_offset, htable_obj(n, p), p)) { + mutex_unlock(&ht->lock); + return -EEXIST; + } + chainlen++; } - hlist_add_head_rcu(obj + p.head_offset, hash_head); + hlist_add_head_rcu(obj + p.head_offset, head); ht->nelems++; + if (chainlen > ht->max_chain) { + ht->max_chain = chainlen; + printk(KERN_INFO "%pf ht with %u/%u has chain %u", + (void *) _THIS_IP_, ht->nelems, t.size, ht->max_chain); + } + if (ht->nelems > t.size >> 2) bch2_htable_expand(ht, p); mutex_unlock(&ht->lock); |