Re: [PATCH] tcp: Pass lockdep expression to RCU lists
From: Eric Dumazet <hidden>
Date: 2020-02-19 19:35:29
Also in:
linux-kernel-mentees, lkml
On 2/19/20 2:05 AM, Amol Grover wrote:
tcp_cong_list is traversed using list_for_each_entry_rcu outside an RCU read-side critical section but under the protection of tcp_cong_list_lock.
This is not true. There are cases where RCU read lock is held, and others where the tcp_cong_list_lock is held. I believe you need to be more precise in the changelog. If there was a bug, net tree would be the target for this patch, with a required Fixes: tag. Otherwise, if net-next tree is the intended target, you have to signal it, as instructed in Documentation/networking/netdev-FAQ.rst Thanks.
quoted hunk ↗ jump to hunk
Hence, add corresponding lockdep expression to silence false-positive warnings, and harden RCU lists. Signed-off-by: Amol Grover <redacted> --- net/ipv4/tcp_cong.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index 3737ec096650..8d4446ed309e 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c@@ -25,7 +25,8 @@ static struct tcp_congestion_ops *tcp_ca_find(const char *name) { struct tcp_congestion_ops *e; - list_for_each_entry_rcu(e, &tcp_cong_list, list) { + list_for_each_entry_rcu(e, &tcp_cong_list, list, + lockdep_is_held(&tcp_cong_list_lock)) { if (strcmp(e->name, name) == 0) return e; }@@ -55,7 +56,8 @@ struct tcp_congestion_ops *tcp_ca_find_key(u32 key) { struct tcp_congestion_ops *e; - list_for_each_entry_rcu(e, &tcp_cong_list, list) { + list_for_each_entry_rcu(e, &tcp_cong_list, list, + lockdep_is_held(&tcp_cong_list_lock)) { if (e->key == key) return e; }@@ -317,7 +319,8 @@ int tcp_set_allowed_congestion_control(char *val) } /* pass 2 clear old values */ - list_for_each_entry_rcu(ca, &tcp_cong_list, list) + list_for_each_entry_rcu(ca, &tcp_cong_list, list, + lockdep_is_held(&tcp_cong_list_lock)) ca->flags &= ~TCP_CONG_NON_RESTRICTED; /* pass 3 mark as allowed */