diff options
author | Florian Westphal <fw@strlen.de> | 2019-01-04 14:17:01 +0100 |
---|---|---|
committer | Steffen Klassert <steffen.klassert@secunet.com> | 2019-01-09 13:58:23 +0100 |
commit | 7a474c36586f4277f930ab7e6865c97e44dfc3bc (patch) | |
tree | 5495f12516af3b388932004c7ee9dd1eaa179e44 /net/xfrm/xfrm_policy.c | |
parent | 355b00d1e14051c13aea48c1c5430c486fed2d7a (diff) | |
download | linux-7a474c36586f4277f930ab7e6865c97e44dfc3bc.tar.gz linux-7a474c36586f4277f930ab7e6865c97e44dfc3bc.tar.bz2 linux-7a474c36586f4277f930ab7e6865c97e44dfc3bc.zip |
xfrm: policy: increment xfrm_hash_generation on hash rebuild
Hash rebuild will re-set all the inexact entries, then re-insert them.
Lookups that can occur in parallel will therefore not find any policies.
This was safe when lookups were still guarded by rwlock.
After rcu-ification, lookups check the hash_generation seqcount to detect
when a hash resize takes place. Hash rebuild missed the needed increment.
Hash resizes and hash rebuilds cannot occur in parallel (both acquire
hash_resize_mutex), so just increment xfrm_hash_generation, like resize.
Fixes: a7c44247f704e3 ("xfrm: policy: make xfrm_policy_lookup_bytype lockless")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 628b389af2ba..d8fba27a4bfb 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -1235,6 +1235,7 @@ static void xfrm_hash_rebuild(struct work_struct *work) } while (read_seqretry(&net->xfrm.policy_hthresh.lock, seq)); spin_lock_bh(&net->xfrm.xfrm_policy_lock); + write_seqcount_begin(&xfrm_policy_hash_generation); /* make sure that we can insert the indirect policies again before * we start with destructive action. @@ -1334,6 +1335,7 @@ static void xfrm_hash_rebuild(struct work_struct *work) out_unlock: __xfrm_policy_inexact_flush(net); + write_seqcount_end(&xfrm_policy_hash_generation); spin_unlock_bh(&net->xfrm.xfrm_policy_lock); mutex_unlock(&hash_resize_mutex); |