tcp_metrics: Rewrite tcp_metrics_flush_all
Rewrite tcp_metrics_flush_all so that it can cope with entries from different network namespaces on it's hash chain. This is based on the logic in tcp_metrics_nl_cmd_del for deleting a selection of entries from a tcp metrics hash chain. Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
8a4bff714f
commit
04f721c671
|
@ -1051,18 +1051,19 @@ static void tcp_metrics_flush_all(struct net *net)
|
||||||
unsigned int row;
|
unsigned int row;
|
||||||
|
|
||||||
for (row = 0; row < max_rows; row++, hb++) {
|
for (row = 0; row < max_rows; row++, hb++) {
|
||||||
|
struct tcp_metrics_block __rcu **pp;
|
||||||
spin_lock_bh(&tcp_metrics_lock);
|
spin_lock_bh(&tcp_metrics_lock);
|
||||||
tm = deref_locked_genl(hb->chain);
|
pp = &hb->chain;
|
||||||
if (tm)
|
for (tm = deref_locked_genl(*pp); tm;
|
||||||
hb->chain = NULL;
|
tm = deref_locked_genl(*pp)) {
|
||||||
spin_unlock_bh(&tcp_metrics_lock);
|
if (net_eq(tm_net(tm), net)) {
|
||||||
while (tm) {
|
*pp = tm->tcpm_next;
|
||||||
struct tcp_metrics_block *next;
|
kfree_rcu(tm, rcu_head);
|
||||||
|
} else {
|
||||||
next = deref_genl(tm->tcpm_next);
|
pp = &tm->tcpm_next;
|
||||||
kfree_rcu(tm, rcu_head);
|
}
|
||||||
tm = next;
|
|
||||||
}
|
}
|
||||||
|
spin_unlock_bh(&tcp_metrics_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue