Closed matttbe closed 3 years ago
@pabeni
Hi Paolo,
Thanks for your advice for this issue. I tried the two solutions you mentioned yesterday, they all works well.
This is the patch for the first solution, adding nested annotation:
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 5dbeae3ad666..8aa064c362f1 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -2984,13 +2984,14 @@ void mptcp_subflow_process_delegated(struct sock *ssk)
{
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
struct sock *sk = subflow->conn;
+ unsigned long flags;
- mptcp_data_lock(sk);
+ spin_lock_irqsave_nested(&sk->sk_lock.slock, flags, SINGLE_DEPTH_NESTING);
if (!sock_owned_by_user(sk))
__mptcp_subflow_push_pending(sk, ssk);
else
set_bit(MPTCP_PUSH_PENDING, &mptcp_sk(sk)->flags);
- mptcp_data_unlock(sk);
+ spin_unlock_irqrestore(&sk->sk_lock.slock, flags);
mptcp_subflow_delegated_done(subflow);
}
And this is the patch for the second solution, changing the lockdep class:
diff --git a/include/net/sock.h b/include/net/sock.h
index bdc4323ce53c..f79ce454b0e9 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1666,6 +1666,8 @@ static inline bool sock_allow_reclassification(const struct sock *csk)
return !sk->sk_lock.owned && !spin_is_locked(&sk->sk_lock.slock);
}
+void sock_lock_reclassify_user(struct sock *sk);
+
struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
struct proto *prot, int kern);
void sk_free(struct sock *sk);
diff --git a/net/core/sock.c b/net/core/sock.c
index bbcd4b97eddd..26e25864631a 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1646,6 +1646,19 @@ static inline void sock_lock_init(struct sock *sk)
af_family_keys + sk->sk_family);
}
+void sock_lock_reclassify_user(struct sock *sk)
+{
+ if (WARN_ON_ONCE(!sock_allow_reclassification(sk)))
+ return;
+
+ lockdep_set_class_and_name(&sk->sk_lock.slock,
+ af_family_slock_keys + sk->sk_family,
+ af_family_slock_key_strings[sk->sk_family]);
+ lockdep_init_map(&sk->sk_lock.dep_map,
+ af_family_key_strings[sk->sk_family],
+ af_family_keys + sk->sk_family, 0);
+}
+
/*
* Copy all fields from osk to nsk but nsk->sk_refcnt must not change yet,
* even temporarly, because of RCU lookups. sk_node should also be left as is.
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 39998c521133..93614929d931 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -716,6 +716,8 @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
if (err)
return err;
+ sock_lock_reclassify_user(entry->lsk->sk);
+
msk = mptcp_sk(entry->lsk->sk);
if (!msk) {
err = -EINVAL;
I think the first one is better, and I had sent it to the ML. Please review it for me. Thanks.
Hi Paolo,
Here is the third patch for skipping lsk in mptcp_subflow_process_delegated:
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 39998c521133..06e38ffeeeb9 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -705,6 +705,7 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
struct mptcp_pm_addr_entry *entry)
{
+ struct mptcp_subflow_context *subflow;
struct sockaddr_storage addr;
struct mptcp_sock *msk;
struct socket *ssock;
@@ -728,6 +729,9 @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
goto out;
}
+ subflow = mptcp_subflow_ctx(ssock->sk);
+ subflow->lsk = 1;
+
mptcp_info2sockaddr(&entry->addr, &addr, entry->addr.family);
err = kernel_bind(ssock, (struct sockaddr *)&addr,
sizeof(struct sockaddr_in));
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 5dbeae3ad666..6e6260f05423 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -2985,6 +2985,9 @@ void mptcp_subflow_process_delegated(struct sock *ssk)
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
struct sock *sk = subflow->conn;
+ if (subflow->lsk)
+ return;
+
mptcp_data_lock(sk);
if (!sock_owned_by_user(sk))
__mptcp_subflow_push_pending(sk, ssk);
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index a0d321dcaeb4..2fc621606934 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -406,6 +406,7 @@ struct mptcp_subflow_context {
mpc_map : 1,
backup : 1,
send_mp_prio : 1,
+ lsk : 1,
rx_eof : 1,
can_ack : 1, /* only after processing the remote a key */
disposable : 1; /* ctx can be free at ulp release time */
Fixed thanks to @pabeni 's patch: 870abbfb3a63: "squashed" in "mptcp: implement delegated actions" Thanks @geliangtang for having tried the different solutions!
With a debug kernel, I get this warning when executing
mptcp_join.sh
tests:It looks like it was introduced by ADD_ADDR: ports support (allowing incoming connections on a different port) series.
cc: @geliangtang