|
@@ -892,10 +892,14 @@ static void tcp_metrics_flush_all(struct net *net)
|
|
|
|
|
|
for (row = 0; row < max_rows; row++, hb++) {
|
|
|
struct tcp_metrics_block __rcu **pp;
|
|
|
+ bool match;
|
|
|
+
|
|
|
spin_lock_bh(&tcp_metrics_lock);
|
|
|
pp = &hb->chain;
|
|
|
for (tm = deref_locked(*pp); tm; tm = deref_locked(*pp)) {
|
|
|
- if (net_eq(tm_net(tm), net)) {
|
|
|
+ match = net ? net_eq(tm_net(tm), net) :
|
|
|
+ !atomic_read(&tm_net(tm)->count);
|
|
|
+ if (match) {
|
|
|
*pp = tm->tcpm_next;
|
|
|
kfree_rcu(tm, rcu_head);
|
|
|
} else {
|
|
@@ -1018,14 +1022,14 @@ static int __net_init tcp_net_metrics_init(struct net *net)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static void __net_exit tcp_net_metrics_exit(struct net *net)
|
|
|
+static void __net_exit tcp_net_metrics_exit_batch(struct list_head *net_exit_list)
|
|
|
{
|
|
|
- tcp_metrics_flush_all(net);
|
|
|
+ tcp_metrics_flush_all(NULL);
|
|
|
}
|
|
|
|
|
|
static __net_initdata struct pernet_operations tcp_net_metrics_ops = {
|
|
|
- .init = tcp_net_metrics_init,
|
|
|
- .exit = tcp_net_metrics_exit,
|
|
|
+ .init = tcp_net_metrics_init,
|
|
|
+ .exit_batch = tcp_net_metrics_exit_batch,
|
|
|
};
|
|
|
|
|
|
void __init tcp_metrics_init(void)
|