aboutsummaryrefslogtreecommitdiffstats
path: root/net/llc/llc_sap.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/llc/llc_sap.c')
-rw-r--r--net/llc/llc_sap.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c
index 94cb706f6cc4..ad6e6e1cf22f 100644
--- a/net/llc/llc_sap.c
+++ b/net/llc/llc_sap.c
@@ -321,10 +321,12 @@ static struct sock *llc_lookup_dgram(struct llc_sap *sap,
321{ 321{
322 struct sock *rc; 322 struct sock *rc;
323 struct hlist_nulls_node *node; 323 struct hlist_nulls_node *node;
324 int slot = llc_sk_laddr_hashfn(sap, laddr);
325 struct hlist_nulls_head *laddr_hb = &sap->sk_laddr_hash[slot];
324 326
325 rcu_read_lock_bh(); 327 rcu_read_lock_bh();
326again: 328again:
327 sk_nulls_for_each_rcu(rc, node, &sap->sk_list) { 329 sk_nulls_for_each_rcu(rc, node, laddr_hb) {
328 if (llc_dgram_match(sap, laddr, rc)) { 330 if (llc_dgram_match(sap, laddr, rc)) {
329 /* Extra checks required by SLAB_DESTROY_BY_RCU */ 331 /* Extra checks required by SLAB_DESTROY_BY_RCU */
330 if (unlikely(!atomic_inc_not_zero(&rc->sk_refcnt))) 332 if (unlikely(!atomic_inc_not_zero(&rc->sk_refcnt)))
@@ -338,6 +340,13 @@ again:
338 } 340 }
339 } 341 }
340 rc = NULL; 342 rc = NULL;
343 /*
344 * if the nulls value we got at the end of this lookup is
345 * not the expected one, we must restart lookup.
346 * We probably met an item that was moved to another chain.
347 */
348 if (unlikely(get_nulls_value(node) != slot))
349 goto again;
341found: 350found:
342 rcu_read_unlock_bh(); 351 rcu_read_unlock_bh();
343 return rc; 352 return rc;