diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 4f77bd862e957..c733c57616fcd 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -4854,6 +4854,8 @@ void tcp_done(struct sock *sk)
 	 */
 	req = rcu_dereference_protected(tcp_sk(sk)->fastopen_rsk, 1);
 
+	WARN_ON_ONCE(sk->sk_state == TCP_CLOSE);
+
 	if (sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV)
 		TCP_INC_STATS(sock_net(sk), TCP_MIB_ATTEMPTFAILS);
 
diff --git a/net/mptcp/Kconfig b/net/mptcp/Kconfig
index 20328920f6ed1..b755fc9b6660e 100644
--- a/net/mptcp/Kconfig
+++ b/net/mptcp/Kconfig
@@ -36,4 +36,13 @@ config MPTCP_KUNIT_TEST
 
 	  If unsure, say N.
 
+config GCOV_PROFILE_MPTCP
+	bool "Enable GCOV profiling on MPTCP"
+	depends on GCOV_KERNEL
+	help
+	  Enable GCOV profiling on MPTCP for checking which functions/lines
+	  are executed.
+
+	  If unsure, say N.
+
 endif
diff --git a/net/mptcp/Makefile b/net/mptcp/Makefile
index bcf1dbf3a432f..5dbc37d38d7a4 100644
--- a/net/mptcp/Makefile
+++ b/net/mptcp/Makefile
@@ -13,3 +13,8 @@ mptcp_token_test-objs := token_test.o
 obj-$(CONFIG_MPTCP_KUNIT_TEST) += mptcp_crypto_test.o mptcp_token_test.o
 
 obj-$(CONFIG_BPF_SYSCALL) += bpf.o
+
+# for GCOV coverage profiling
+ifdef CONFIG_GCOV_PROFILE_MPTCP
+GCOV_PROFILE := y
+endif
diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index 1603b3702e220..ad22622843a28 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -983,7 +983,8 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk,
 		WRITE_ONCE(msk->pm.remote_deny_join_id0, true);
 
 	if (unlikely(!READ_ONCE(msk->pm.server_side)))
-		pr_warn_once("bogus mpc option on established client sk");
+		/* DO-NOT-MERGE: use WARN i/o pr_warn: only for MPTCP export */
+		WARN_ONCE(1, "bogus mpc option on established client sk");
 
 set_fully_established:
 	mptcp_data_lock((struct sock *)msk);