Commit 5fa7d3f9 authored by David S. Miller's avatar David S. Miller

Merge branch 'rhashtable-bit-locking-m68k'

NeilBrown says:

====================
Fix rhashtable bit-locking for m68k

As reported by Guenter Roeck, the new rhashtable bit-locking
doesn't work on m68k as it only requires 2-byte alignment, so BIT(1)
is addresses is not unused.

We current use BIT(0) to identify a NULLS marker, but that is only
needed in ->next pointers.  The bucket head does not need a NULLS
marker, so the lsb there can be used for locking.

the first 4 patches make some small improvements and re-arrange some
code.  The final patch converts to using only BIT(0) for these two
different special purposes.

I had previously suggested dropping the series until I fix it.  Given
that this was fairly easy, I retract that I think it best simply to
add these patches to fix the code.
====================
Tested-by: default avatarGuenter Roeck <linux@roeck-us.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c252aa3e ca0b709d
This diff is collapsed.
...@@ -59,7 +59,7 @@ int lockdep_rht_bucket_is_held(const struct bucket_table *tbl, u32 hash) ...@@ -59,7 +59,7 @@ int lockdep_rht_bucket_is_held(const struct bucket_table *tbl, u32 hash)
return 1; return 1;
if (unlikely(tbl->nest)) if (unlikely(tbl->nest))
return 1; return 1;
return bit_spin_is_locked(1, (unsigned long *)&tbl->buckets[hash]); return bit_spin_is_locked(0, (unsigned long *)&tbl->buckets[hash]);
} }
EXPORT_SYMBOL_GPL(lockdep_rht_bucket_is_held); EXPORT_SYMBOL_GPL(lockdep_rht_bucket_is_held);
#else #else
...@@ -223,7 +223,7 @@ static int rhashtable_rehash_one(struct rhashtable *ht, ...@@ -223,7 +223,7 @@ static int rhashtable_rehash_one(struct rhashtable *ht,
struct bucket_table *new_tbl = rhashtable_last_table(ht, old_tbl); struct bucket_table *new_tbl = rhashtable_last_table(ht, old_tbl);
int err = -EAGAIN; int err = -EAGAIN;
struct rhash_head *head, *next, *entry; struct rhash_head *head, *next, *entry;
struct rhash_head **pprev = NULL; struct rhash_head __rcu **pprev = NULL;
unsigned int new_hash; unsigned int new_hash;
if (new_tbl->nest) if (new_tbl->nest)
...@@ -231,7 +231,8 @@ static int rhashtable_rehash_one(struct rhashtable *ht, ...@@ -231,7 +231,8 @@ static int rhashtable_rehash_one(struct rhashtable *ht,
err = -ENOENT; err = -ENOENT;
rht_for_each_from(entry, rht_ptr(*bkt), old_tbl, old_hash) { rht_for_each_from(entry, rht_ptr(bkt, old_tbl, old_hash),
old_tbl, old_hash) {
err = 0; err = 0;
next = rht_dereference_bucket(entry->next, old_tbl, old_hash); next = rht_dereference_bucket(entry->next, old_tbl, old_hash);
...@@ -248,8 +249,7 @@ static int rhashtable_rehash_one(struct rhashtable *ht, ...@@ -248,8 +249,7 @@ static int rhashtable_rehash_one(struct rhashtable *ht,
rht_lock_nested(new_tbl, &new_tbl->buckets[new_hash], SINGLE_DEPTH_NESTING); rht_lock_nested(new_tbl, &new_tbl->buckets[new_hash], SINGLE_DEPTH_NESTING);
head = rht_ptr(rht_dereference_bucket(new_tbl->buckets[new_hash], head = rht_ptr(new_tbl->buckets + new_hash, new_tbl, new_hash);
new_tbl, new_hash));
RCU_INIT_POINTER(entry->next, head); RCU_INIT_POINTER(entry->next, head);
...@@ -259,7 +259,7 @@ static int rhashtable_rehash_one(struct rhashtable *ht, ...@@ -259,7 +259,7 @@ static int rhashtable_rehash_one(struct rhashtable *ht,
rcu_assign_pointer(*pprev, next); rcu_assign_pointer(*pprev, next);
else else
/* Need to preserved the bit lock. */ /* Need to preserved the bit lock. */
rcu_assign_pointer(*bkt, rht_ptr_locked(next)); rht_assign_locked(bkt, next);
out: out:
return err; return err;
...@@ -486,12 +486,12 @@ static void *rhashtable_lookup_one(struct rhashtable *ht, ...@@ -486,12 +486,12 @@ static void *rhashtable_lookup_one(struct rhashtable *ht,
.ht = ht, .ht = ht,
.key = key, .key = key,
}; };
struct rhash_head **pprev = NULL; struct rhash_head __rcu **pprev = NULL;
struct rhash_head *head; struct rhash_head *head;
int elasticity; int elasticity;
elasticity = RHT_ELASTICITY; elasticity = RHT_ELASTICITY;
rht_for_each_from(head, rht_ptr(*bkt), tbl, hash) { rht_for_each_from(head, rht_ptr(bkt, tbl, hash), tbl, hash) {
struct rhlist_head *list; struct rhlist_head *list;
struct rhlist_head *plist; struct rhlist_head *plist;
...@@ -517,7 +517,7 @@ static void *rhashtable_lookup_one(struct rhashtable *ht, ...@@ -517,7 +517,7 @@ static void *rhashtable_lookup_one(struct rhashtable *ht,
rcu_assign_pointer(*pprev, obj); rcu_assign_pointer(*pprev, obj);
else else
/* Need to preserve the bit lock */ /* Need to preserve the bit lock */
rcu_assign_pointer(*bkt, rht_ptr_locked(obj)); rht_assign_locked(bkt, obj);
return NULL; return NULL;
} }
...@@ -557,7 +557,7 @@ static struct bucket_table *rhashtable_insert_one(struct rhashtable *ht, ...@@ -557,7 +557,7 @@ static struct bucket_table *rhashtable_insert_one(struct rhashtable *ht,
if (unlikely(rht_grow_above_100(ht, tbl))) if (unlikely(rht_grow_above_100(ht, tbl)))
return ERR_PTR(-EAGAIN); return ERR_PTR(-EAGAIN);
head = rht_ptr(rht_dereference_bucket(*bkt, tbl, hash)); head = rht_ptr(bkt, tbl, hash);
RCU_INIT_POINTER(obj->next, head); RCU_INIT_POINTER(obj->next, head);
if (ht->rhlist) { if (ht->rhlist) {
...@@ -570,7 +570,7 @@ static struct bucket_table *rhashtable_insert_one(struct rhashtable *ht, ...@@ -570,7 +570,7 @@ static struct bucket_table *rhashtable_insert_one(struct rhashtable *ht,
/* bkt is always the head of the list, so it holds /* bkt is always the head of the list, so it holds
* the lock, which we need to preserve * the lock, which we need to preserve
*/ */
rcu_assign_pointer(*bkt, rht_ptr_locked(obj)); rht_assign_locked(bkt, obj);
atomic_inc(&ht->nelems); atomic_inc(&ht->nelems);
if (rht_grow_above_75(ht, tbl)) if (rht_grow_above_75(ht, tbl))
...@@ -1139,7 +1139,7 @@ void rhashtable_free_and_destroy(struct rhashtable *ht, ...@@ -1139,7 +1139,7 @@ void rhashtable_free_and_destroy(struct rhashtable *ht,
struct rhash_head *pos, *next; struct rhash_head *pos, *next;
cond_resched(); cond_resched();
for (pos = rht_ptr(rht_dereference(*rht_bucket(tbl, i), ht)), for (pos = rht_ptr_exclusive(rht_bucket(tbl, i)),
next = !rht_is_a_nulls(pos) ? next = !rht_is_a_nulls(pos) ?
rht_dereference(pos->next, ht) : NULL; rht_dereference(pos->next, ht) : NULL;
!rht_is_a_nulls(pos); !rht_is_a_nulls(pos);
......
...@@ -500,7 +500,7 @@ static unsigned int __init print_ht(struct rhltable *rhlt) ...@@ -500,7 +500,7 @@ static unsigned int __init print_ht(struct rhltable *rhlt)
struct rhash_head *pos, *next; struct rhash_head *pos, *next;
struct test_obj_rhl *p; struct test_obj_rhl *p;
pos = rht_ptr(rht_dereference(tbl->buckets[i], ht)); pos = rht_ptr_exclusive(tbl->buckets + i);
next = !rht_is_a_nulls(pos) ? rht_dereference(pos->next, ht) : NULL; next = !rht_is_a_nulls(pos) ? rht_dereference(pos->next, ht) : NULL;
if (!rht_is_a_nulls(pos)) { if (!rht_is_a_nulls(pos)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment