Skip to content

Commit

Permalink
xfrm: add and use xfrm_state_afinfo_get_rcu
Browse files Browse the repository at this point in the history
xfrm_init_tempstate is always called from within rcu read side section.
We can thus use a simpler function that doesn't call rcu_read_lock
again.

While at it, also make xfrm_init_tempstate return value void, the
return value was never tested.

A followup patch will replace remaining callers of xfrm_state_get_afinfo
with xfrm_state_afinfo_get_rcu variant and then remove the 'old'
get_afinfo interface.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
  • Loading branch information
Florian Westphal authored and klassert committed Jan 10, 2017
1 parent af5d27c commit 711059b
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 10 deletions.
1 change: 1 addition & 0 deletions include/net/xfrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ struct xfrm_state_afinfo {
int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo);
struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
struct xfrm_state_afinfo *xfrm_state_afinfo_get_rcu(unsigned int family);

struct xfrm_input_afinfo {
unsigned int family;
Expand Down
25 changes: 15 additions & 10 deletions net/xfrm/xfrm_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -639,26 +639,23 @@ void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si)
}
EXPORT_SYMBOL(xfrm_sad_getinfo);

static int
static void
xfrm_init_tempstate(struct xfrm_state *x, const struct flowi *fl,
const struct xfrm_tmpl *tmpl,
const xfrm_address_t *daddr, const xfrm_address_t *saddr,
unsigned short family)
{
struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family);
if (!afinfo)
return -1;
afinfo->init_tempsel(&x->sel, fl);
struct xfrm_state_afinfo *afinfo = xfrm_state_afinfo_get_rcu(family);

if (afinfo)
afinfo->init_tempsel(&x->sel, fl);

if (family != tmpl->encap_family) {
rcu_read_unlock();
afinfo = xfrm_state_get_afinfo(tmpl->encap_family);
afinfo = xfrm_state_afinfo_get_rcu(tmpl->encap_family);
if (!afinfo)
return -1;
return;
}
afinfo->init_temprop(x, tmpl, daddr, saddr);
rcu_read_unlock();
return 0;
}

static struct xfrm_state *__xfrm_state_lookup(struct net *net, u32 mark,
Expand Down Expand Up @@ -1966,6 +1963,14 @@ int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo)
}
EXPORT_SYMBOL(xfrm_state_unregister_afinfo);

struct xfrm_state_afinfo *xfrm_state_afinfo_get_rcu(unsigned int family)
{
if (unlikely(family >= NPROTO))
return NULL;

return rcu_dereference(xfrm_state_afinfo[family]);
}

struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family)
{
struct xfrm_state_afinfo *afinfo;
Expand Down

0 comments on commit 711059b

Please sign in to comment.