Skip to content

Commit

Permalink
xfrm: policy: use atomic_inc_not_zero in rcu section
Browse files Browse the repository at this point in the history
If we don't hold the policy lock anymore the refcnt might
already be 0, i.e. policy struct is about to be free'd.

Switch to atomic_inc_not_zero to avoid this.

On removal policies are already unlinked from the tables (lists)
before the last _put occurs so we are not supposed to find the same
'dead' entry on the next loop, so its safe to just repeat the lookup.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
  • Loading branch information
Florian Westphal authored and Steffen Klassert committed Aug 12, 2016
1 parent 3084609 commit e37cc8a
Showing 1 changed file with 7 additions and 1 deletion.
8 changes: 7 additions & 1 deletion net/xfrm/xfrm_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ static void __xfrm_policy_link(struct xfrm_policy *pol, int dir);
static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol,
int dir);

static inline bool xfrm_pol_hold_rcu(struct xfrm_policy *policy)
{
return atomic_inc_not_zero(&policy->refcnt);
}

static inline bool
__xfrm4_selector_match(const struct xfrm_selector *sel, const struct flowi *fl)
{
Expand Down Expand Up @@ -1164,7 +1169,8 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(struct net *net, u8 type,
if (read_seqcount_retry(&xfrm_policy_hash_generation, sequence))
goto retry;

xfrm_pol_hold(ret);
if (ret && !xfrm_pol_hold_rcu(ret))
goto retry;
fail:
read_unlock_bh(&net->xfrm.xfrm_policy_lock);

Expand Down

0 comments on commit e37cc8a

Please sign in to comment.