Message ID | 20210715182517.994942248@linuxfoundation.org |
---|---|
State | Superseded |
Headers | show |
Series | None | expand |
Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote: > From: Varad Gautam <varad.gautam@suse.com> > > commit d7b0408934c749f546b01f2b33d07421a49b6f3e upstream. This patch has been reverted in the ipsec tree, the problem was then addressed via 2580d3f40022642452dd8422bfb8c22e54cf84bb ("xfrm: Fix RCU vs hash_resize_mutex lock inversion"). AFAICS its not in mainline yet.
On Thu, Jul 15, 2021 at 08:54:47PM +0200, Florian Westphal wrote: > Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote: > > From: Varad Gautam <varad.gautam@suse.com> > > > > commit d7b0408934c749f546b01f2b33d07421a49b6f3e upstream. > > This patch has been reverted in the ipsec tree, the problem was then > addressed via 2580d3f40022642452dd8422bfb8c22e54cf84bb > ("xfrm: Fix RCU vs hash_resize_mutex lock inversion"). > > AFAICS its not in mainline yet. Thank you, I have now dropped this from everywhere. greg k-h
--- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -2089,12 +2089,15 @@ static struct xfrm_policy *xfrm_policy_l if (unlikely(!daddr || !saddr)) return NULL; - rcu_read_lock(); retry: - do { - sequence = read_seqcount_begin(&xfrm_policy_hash_generation); - chain = policy_hash_direct(net, daddr, saddr, family, dir); - } while (read_seqcount_retry(&xfrm_policy_hash_generation, sequence)); + sequence = read_seqcount_begin(&xfrm_policy_hash_generation); + rcu_read_lock(); + + chain = policy_hash_direct(net, daddr, saddr, family, dir); + if (read_seqcount_retry(&xfrm_policy_hash_generation, sequence)) { + rcu_read_unlock(); + goto retry; + } ret = NULL; hlist_for_each_entry_rcu(pol, chain, bydst) { @@ -2125,11 +2128,15 @@ static struct xfrm_policy *xfrm_policy_l } skip_inexact: - if (read_seqcount_retry(&xfrm_policy_hash_generation, sequence)) + if (read_seqcount_retry(&xfrm_policy_hash_generation, sequence)) { + rcu_read_unlock(); goto retry; + } - if (ret && !xfrm_pol_hold_rcu(ret)) + if (ret && !xfrm_pol_hold_rcu(ret)) { + rcu_read_unlock(); goto retry; + } fail: rcu_read_unlock();