tcp/dccp: get rid of inet_twsk_purge()
Prior patches in the series made sure tw_timer_handler() can be fired after netns has been dismantled/freed. We no longer have to scan a potentially big TCP ehash table at netns dismantle. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
27dd35e022
commit
0dad4087a8
@ -110,8 +110,6 @@ static inline void inet_twsk_reschedule(struct inet_timewait_sock *tw, int timeo
|
|||||||
|
|
||||||
void inet_twsk_deschedule_put(struct inet_timewait_sock *tw);
|
void inet_twsk_deschedule_put(struct inet_timewait_sock *tw);
|
||||||
|
|
||||||
void inet_twsk_purge(struct inet_hashinfo *hashinfo, int family);
|
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
struct net *twsk_net(const struct inet_timewait_sock *twsk)
|
struct net *twsk_net(const struct inet_timewait_sock *twsk)
|
||||||
{
|
{
|
||||||
|
@ -1030,15 +1030,9 @@ static void __net_exit dccp_v4_exit_net(struct net *net)
|
|||||||
inet_ctl_sock_destroy(pn->v4_ctl_sk);
|
inet_ctl_sock_destroy(pn->v4_ctl_sk);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __net_exit dccp_v4_exit_batch(struct list_head *net_exit_list)
|
|
||||||
{
|
|
||||||
inet_twsk_purge(&dccp_hashinfo, AF_INET);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pernet_operations dccp_v4_ops = {
|
static struct pernet_operations dccp_v4_ops = {
|
||||||
.init = dccp_v4_init_net,
|
.init = dccp_v4_init_net,
|
||||||
.exit = dccp_v4_exit_net,
|
.exit = dccp_v4_exit_net,
|
||||||
.exit_batch = dccp_v4_exit_batch,
|
|
||||||
.id = &dccp_v4_pernet_id,
|
.id = &dccp_v4_pernet_id,
|
||||||
.size = sizeof(struct dccp_v4_pernet),
|
.size = sizeof(struct dccp_v4_pernet),
|
||||||
};
|
};
|
||||||
|
@ -1115,15 +1115,9 @@ static void __net_exit dccp_v6_exit_net(struct net *net)
|
|||||||
inet_ctl_sock_destroy(pn->v6_ctl_sk);
|
inet_ctl_sock_destroy(pn->v6_ctl_sk);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __net_exit dccp_v6_exit_batch(struct list_head *net_exit_list)
|
|
||||||
{
|
|
||||||
inet_twsk_purge(&dccp_hashinfo, AF_INET6);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pernet_operations dccp_v6_ops = {
|
static struct pernet_operations dccp_v6_ops = {
|
||||||
.init = dccp_v6_init_net,
|
.init = dccp_v6_init_net,
|
||||||
.exit = dccp_v6_exit_net,
|
.exit = dccp_v6_exit_net,
|
||||||
.exit_batch = dccp_v6_exit_batch,
|
|
||||||
.id = &dccp_v6_pernet_id,
|
.id = &dccp_v6_pernet_id,
|
||||||
.size = sizeof(struct dccp_v6_pernet),
|
.size = sizeof(struct dccp_v6_pernet),
|
||||||
};
|
};
|
||||||
|
@ -255,50 +255,3 @@ void __inet_twsk_schedule(struct inet_timewait_sock *tw, int timeo, bool rearm)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(__inet_twsk_schedule);
|
EXPORT_SYMBOL_GPL(__inet_twsk_schedule);
|
||||||
|
|
||||||
void inet_twsk_purge(struct inet_hashinfo *hashinfo, int family)
|
|
||||||
{
|
|
||||||
struct inet_timewait_sock *tw;
|
|
||||||
struct sock *sk;
|
|
||||||
struct hlist_nulls_node *node;
|
|
||||||
unsigned int slot;
|
|
||||||
|
|
||||||
for (slot = 0; slot <= hashinfo->ehash_mask; slot++) {
|
|
||||||
struct inet_ehash_bucket *head = &hashinfo->ehash[slot];
|
|
||||||
restart_rcu:
|
|
||||||
cond_resched();
|
|
||||||
rcu_read_lock();
|
|
||||||
restart:
|
|
||||||
sk_nulls_for_each_rcu(sk, node, &head->chain) {
|
|
||||||
if (sk->sk_state != TCP_TIME_WAIT)
|
|
||||||
continue;
|
|
||||||
tw = inet_twsk(sk);
|
|
||||||
if ((tw->tw_family != family) ||
|
|
||||||
refcount_read(&twsk_net(tw)->ns.count))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (unlikely(!refcount_inc_not_zero(&tw->tw_refcnt)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (unlikely((tw->tw_family != family) ||
|
|
||||||
refcount_read(&twsk_net(tw)->ns.count))) {
|
|
||||||
inet_twsk_put(tw);
|
|
||||||
goto restart;
|
|
||||||
}
|
|
||||||
|
|
||||||
rcu_read_unlock();
|
|
||||||
local_bh_disable();
|
|
||||||
inet_twsk_deschedule_put(tw);
|
|
||||||
local_bh_enable();
|
|
||||||
goto restart_rcu;
|
|
||||||
}
|
|
||||||
/* If the nulls value we got at the end of this lookup is
|
|
||||||
* not the expected one, we must restart lookup.
|
|
||||||
* We probably met an item that was moved to another chain.
|
|
||||||
*/
|
|
||||||
if (get_nulls_value(node) != slot)
|
|
||||||
goto restart;
|
|
||||||
rcu_read_unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(inet_twsk_purge);
|
|
||||||
|
@ -3239,8 +3239,6 @@ static void __net_exit tcp_sk_exit_batch(struct list_head *net_exit_list)
|
|||||||
{
|
{
|
||||||
struct net *net;
|
struct net *net;
|
||||||
|
|
||||||
inet_twsk_purge(&tcp_hashinfo, AF_INET);
|
|
||||||
|
|
||||||
list_for_each_entry(net, net_exit_list, exit_list)
|
list_for_each_entry(net, net_exit_list, exit_list)
|
||||||
tcp_fastopen_ctx_destroy(net);
|
tcp_fastopen_ctx_destroy(net);
|
||||||
}
|
}
|
||||||
|
@ -2237,15 +2237,9 @@ static void __net_exit tcpv6_net_exit(struct net *net)
|
|||||||
inet_ctl_sock_destroy(net->ipv6.tcp_sk);
|
inet_ctl_sock_destroy(net->ipv6.tcp_sk);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __net_exit tcpv6_net_exit_batch(struct list_head *net_exit_list)
|
|
||||||
{
|
|
||||||
inet_twsk_purge(&tcp_hashinfo, AF_INET6);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct pernet_operations tcpv6_net_ops = {
|
static struct pernet_operations tcpv6_net_ops = {
|
||||||
.init = tcpv6_net_init,
|
.init = tcpv6_net_init,
|
||||||
.exit = tcpv6_net_exit,
|
.exit = tcpv6_net_exit,
|
||||||
.exit_batch = tcpv6_net_exit_batch,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int __init tcpv6_init(void)
|
int __init tcpv6_init(void)
|
||||||
|
Loading…
Reference in New Issue
Block a user