The mptcp_sched_find() function must be called with the RCU read lock held, as it accesses RCU-protected data structures. This requirement was not properly enforced in the mptcp_init_sock() function, leading to a RCU list traversal in a non-reader section error when CONFIG_PROVE_RCU_LIST is enabled. net/mptcp/sched.c:44 RCU-list traversed in non-reader section!! Fix it by acquiring the RCU read lock before calling the mptcp_sched_find() function. This ensures that the function is invoked with the necessary RCU protection in place, as it accesses RCU-protected data structures. Additionally, the patch breaks down the mptcp_init_sched() call into smaller parts, with the RCU read lock only covering the specific call to mptcp_sched_find(). This helps minimize the critical section, reducing the time during which RCU grace periods are blocked. The mptcp_sched_list_lock is not held in this case, and it is not clear if it is necessary. Signed-off-by: Breno Leitao <leitao@xxxxxxxxxx> Fixes: 1730b2b2c5a5 ("mptcp: add sched in mptcp_sock") Cc: stable@xxxxxxxxxxxxxxx --- net/mptcp/protocol.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 6d0e201c3eb2..8ece630f80d4 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2854,6 +2854,7 @@ static void mptcp_ca_reset(struct sock *sk) static int mptcp_init_sock(struct sock *sk) { struct net *net = sock_net(sk); + struct mptcp_sched_ops *sched; int ret; __mptcp_init_sock(sk); @@ -2864,8 +2865,10 @@ static int mptcp_init_sock(struct sock *sk) if (unlikely(!net->mib.mptcp_statistics) && !mptcp_mib_alloc(net)) return -ENOMEM; - ret = mptcp_init_sched(mptcp_sk(sk), - mptcp_sched_find(mptcp_get_scheduler(net))); + rcu_read_lock(); + sched = mptcp_sched_find(mptcp_get_scheduler(net)); + rcu_read_unlock(); + ret = mptcp_init_sched(mptcp_sk(sk), sched); if (ret) return ret; -- 2.43.5