Skip to content

Commit 1e7236c

Browse files
qsnUlrich Hecht
authored andcommitted
Revert "xfrm: destroy xfrm_state synchronously on net exit path"
[ Upstream commit 2a198bbec6913ae1c90ec963750003c6213668c7 ] This reverts commit f75a2804da391571563c4b6b29e7797787332673. With all states (whether user or kern) removed from the hashtables during deletion, there's no need for synchronous destruction of states. xfrm6_tunnel states still need to have been destroyed (which will be the case when its last user is deleted (not destroyed)) so that xfrm6_tunnel_free_spi removes it from the per-netns hashtable before the netns is destroyed. This has the benefit of skipping one synchronize_rcu per state (in __xfrm_state_destroy(sync=true)) when we exit a netns. Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Ulrich Hecht <uli@kernel.org>
1 parent 002c448 commit 1e7236c

5 files changed

Lines changed: 15 additions & 26 deletions

File tree

include/net/xfrm.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,7 @@ static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols)
850850
xfrm_pol_put(pols[i]);
851851
}
852852

853-
void __xfrm_state_destroy(struct xfrm_state *, bool);
853+
void __xfrm_state_destroy(struct xfrm_state *);
854854

855855
static inline void __xfrm_state_put(struct xfrm_state *x)
856856
{
@@ -860,13 +860,7 @@ static inline void __xfrm_state_put(struct xfrm_state *x)
860860
static inline void xfrm_state_put(struct xfrm_state *x)
861861
{
862862
if (refcount_dec_and_test(&x->refcnt))
863-
__xfrm_state_destroy(x, false);
864-
}
865-
866-
static inline void xfrm_state_put_sync(struct xfrm_state *x)
867-
{
868-
if (refcount_dec_and_test(&x->refcnt))
869-
__xfrm_state_destroy(x, true);
863+
__xfrm_state_destroy(x);
870864
}
871865

872866
static inline void xfrm_state_hold(struct xfrm_state *x)
@@ -1638,7 +1632,7 @@ struct xfrmk_spdinfo {
16381632

16391633
struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq);
16401634
int xfrm_state_delete(struct xfrm_state *x);
1641-
int xfrm_state_flush(struct net *net, u8 proto, bool task_valid, bool sync);
1635+
int xfrm_state_flush(struct net *net, u8 proto, bool task_valid);
16421636
int xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_valid);
16431637
void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si);
16441638
void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si);

net/ipv6/xfrm6_tunnel.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ static void __net_exit xfrm6_tunnel_net_exit(struct net *net)
344344
struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
345345
unsigned int i;
346346

347-
xfrm_state_flush(net, 0, false, true);
347+
xfrm_state_flush(net, IPSEC_PROTO_ANY, false);
348348
xfrm_flush_gc();
349349

350350
for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++)

net/key/af_key.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1776,7 +1776,7 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, const struct sadb_m
17761776
if (proto == 0)
17771777
return -EINVAL;
17781778

1779-
err = xfrm_state_flush(net, proto, true, false);
1779+
err = xfrm_state_flush(net, proto, true);
17801780
err2 = unicast_flush_resp(sk, hdr);
17811781
if (err || err2) {
17821782
if (err == -ESRCH) /* empty table - go quietly */

net/xfrm/xfrm_state.c

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ void xfrm_state_free(struct xfrm_state *x)
431431
}
432432
EXPORT_SYMBOL(xfrm_state_free);
433433

434-
static void ___xfrm_state_destroy(struct xfrm_state *x)
434+
static void xfrm_state_gc_destroy(struct xfrm_state *x)
435435
{
436436
tasklet_hrtimer_cancel(&x->mtimer);
437437
del_timer_sync(&x->rtimer);
@@ -475,7 +475,7 @@ static void xfrm_state_gc_task(struct work_struct *work)
475475
synchronize_rcu();
476476

477477
hlist_for_each_entry_safe(x, tmp, &gc_list, gclist)
478-
___xfrm_state_destroy(x);
478+
xfrm_state_gc_destroy(x);
479479
}
480480

481481
static enum hrtimer_restart xfrm_timer_handler(struct hrtimer *me)
@@ -599,19 +599,14 @@ struct xfrm_state *xfrm_state_alloc(struct net *net)
599599
}
600600
EXPORT_SYMBOL(xfrm_state_alloc);
601601

602-
void __xfrm_state_destroy(struct xfrm_state *x, bool sync)
602+
void __xfrm_state_destroy(struct xfrm_state *x)
603603
{
604604
WARN_ON(x->km.state != XFRM_STATE_DEAD);
605605

606-
if (sync) {
607-
synchronize_rcu();
608-
___xfrm_state_destroy(x);
609-
} else {
610-
spin_lock_bh(&xfrm_state_gc_lock);
611-
hlist_add_head(&x->gclist, &xfrm_state_gc_list);
612-
spin_unlock_bh(&xfrm_state_gc_lock);
613-
schedule_work(&xfrm_state_gc_work);
614-
}
606+
spin_lock_bh(&xfrm_state_gc_lock);
607+
hlist_add_head(&x->gclist, &xfrm_state_gc_list);
608+
spin_unlock_bh(&xfrm_state_gc_lock);
609+
schedule_work(&xfrm_state_gc_work);
615610
}
616611
EXPORT_SYMBOL(__xfrm_state_destroy);
617612

@@ -717,7 +712,7 @@ xfrm_dev_state_flush_secctx_check(struct net *net, struct net_device *dev, bool
717712
}
718713
#endif
719714

720-
int xfrm_state_flush(struct net *net, u8 proto, bool task_valid, bool sync)
715+
int xfrm_state_flush(struct net *net, u8 proto, bool task_valid)
721716
{
722717
int i, err = 0, cnt = 0;
723718

@@ -2425,7 +2420,7 @@ void xfrm_state_fini(struct net *net)
24252420
unsigned int sz;
24262421

24272422
flush_work(&net->xfrm.state_hash_work);
2428-
xfrm_state_flush(net, 0, false, true);
2423+
xfrm_state_flush(net, IPSEC_PROTO_ANY, false);
24292424
flush_work(&xfrm_state_gc_work);
24302425

24312426
WARN_ON(!list_empty(&net->xfrm.state_all));

net/xfrm/xfrm_user.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1958,7 +1958,7 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
19581958
struct xfrm_usersa_flush *p = nlmsg_data(nlh);
19591959
int err;
19601960

1961-
err = xfrm_state_flush(net, p->proto, true, false);
1961+
err = xfrm_state_flush(net, p->proto, true);
19621962
if (err) {
19631963
if (err == -ESRCH) /* empty table */
19641964
return 0;

0 commit comments

Comments
 (0)