From nobody Thu Apr 2 01:29:27 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 77C3E3ED128 for ; Tue, 31 Mar 2026 10:28:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774952926; cv=none; b=bG6idNZ+rEKtT9X3jpzOFreH07ORu5CX4a+eufCgDgwyvPjqA2KvK+Y4mSYNdsEZlfLrfT1hDhozwNxCXS3MHaiYois9lZAJsfd8lK0dokxa1BVS0wFKIDGMqXGus+LC2XyutMFozr+I/nyH9N0Io/LsUHXjseUuwHRFL+OoG7I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774952926; c=relaxed/simple; bh=WNGyQP0yiyg2l5WSpsWeNaSyG2Y9MPeEGVueFkXO1oI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dgnSVS6pycyCn3TS0rVfsUar25lFy0bxCRM400npcg5dEbLERBotEL57lF/sJQOZcZou5CQpFXThL3I24QSlimO3lBsSDuTe/uuj5bECwdd24vuyJ7gvq+CiOkvplgR/qP94jnWuNt5KL4aZSZtiSHc5ZzOM+LhwmDSgWFD2YLs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=TcIDfIcI; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="TcIDfIcI" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A4E66C19423; Tue, 31 Mar 2026 10:28:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1774952926; bh=WNGyQP0yiyg2l5WSpsWeNaSyG2Y9MPeEGVueFkXO1oI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TcIDfIcId1xmft2B374wNaSca98OorjLA9SIEUj6M7aNV8pM81fFRpwNw1nmTfac1 b507keFFeGdg+J3s6C7Szp8Ypi69NZSxBeYZp5cUnvi0HRsI2cPKAH7RUabmong77e kumWSzqjx1asixiYqX2prrgC6n/QZM4ECBhi8jIsDRhgVd8ugtkdsS/Zcocm8T9Pyo Ot93KwIgyKHSpicArZ3dEljh+d88WXcVHWdARj6IeaQ+GitEx7UJe+VTsY8PV3JkZ0 IJgLIeCACCkagsDw+WSxbT9I1WKlS3ReWpjXer1HXckkOw6uJvc6YOorvGotwSQLsP gYcIYnq28xxhw== From: Geliang Tang To: mptcp@lists.linux.dev Cc: Geliang Tang , Hannes Reinecke , zhenwei pi , Hui Zhu , Gang Yan Subject: [RFC mptcp-next v7 4/7] nvme-tcp: define host tcp_sockops struct Date: Tue, 31 Mar 2026 18:28:28 +0800 Message-ID: X-Mailer: git-send-email 2.51.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Geliang Tang To add MPTCP support in "NVMe over TCP", the host side needs to pass IPPROTO_MPTCP to sock_create_kern() instead of IPPROTO_TCP to create an MPTCP socket. Similar to the target-side nvmet_tcp_sockops, this patch defines the host-side nvme_tcp_sockops structure, which contains the protocol of the socket and a set of function pointers for socket operations. The only difference is that it defines .set_syncnt instead of .set_reuseaddr. A TCP-specific version of this structure is defined, and a sockops field is added to nvme_tcp_ctrl. When the transport string is "tcp", it is assigned to ctrl->sockops. All locations that previously called TCP setsockopt functions are updated to call the corresponding function pointers in the nvme_tcp_sockops structure. Cc: Hannes Reinecke Co-developed-by: zhenwei pi Signed-off-by: zhenwei pi Co-developed-by: Hui Zhu Signed-off-by: Hui Zhu Co-developed-by: Gang Yan Signed-off-by: Gang Yan Signed-off-by: Geliang Tang --- drivers/nvme/host/tcp.c | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 243dab830dc8..1f45f388b9c1 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -182,6 +182,15 @@ struct nvme_tcp_queue { void (*write_space)(struct sock *); }; =20 +struct nvme_tcp_sockops { + int proto; + int (*set_syncnt)(struct sock *sk, int val); + void (*set_nodelay)(struct sock *sk); + void (*no_linger)(struct sock *sk); + void (*set_priority)(struct sock *sk, u32 priority); + void (*set_tos)(struct sock *sk, int val); +}; + struct nvme_tcp_ctrl { /* read only in the hot path */ struct nvme_tcp_queue *queues; @@ -198,6 +207,8 @@ struct nvme_tcp_ctrl { struct delayed_work connect_work; struct nvme_tcp_request async_req; u32 io_queues[HCTX_MAX_TYPES]; + + const struct nvme_tcp_sockops *sockops; }; =20 static LIST_HEAD(nvme_tcp_ctrl_list); @@ -1785,7 +1796,7 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nct= rl, int qid, =20 ret =3D sock_create_kern(current->nsproxy->net_ns, ctrl->addr.ss_family, SOCK_STREAM, - IPPROTO_TCP, &queue->sock); + ctrl->sockops->proto, &queue->sock); if (ret) { dev_err(nctrl->device, "failed to create socket: %d\n", ret); @@ -1802,24 +1813,24 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *n= ctrl, int qid, nvme_tcp_reclassify_socket(queue->sock); =20 /* Single syn retry */ - tcp_sock_set_syncnt(queue->sock->sk, 1); + ctrl->sockops->set_syncnt(queue->sock->sk, 1); =20 /* Set TCP no delay */ - tcp_sock_set_nodelay(queue->sock->sk); + ctrl->sockops->set_nodelay(queue->sock->sk); =20 /* * Cleanup whatever is sitting in the TCP transmit queue on socket * close. This is done to prevent stale data from being sent should * the network connection be restored before TCP times out. */ - sock_no_linger(queue->sock->sk); + ctrl->sockops->no_linger(queue->sock->sk); =20 if (so_priority > 0) - sock_set_priority(queue->sock->sk, so_priority); + ctrl->sockops->set_priority(queue->sock->sk, so_priority); =20 /* Set socket type of service */ if (nctrl->opts->tos >=3D 0) - ip_sock_set_tos(queue->sock->sk, nctrl->opts->tos); + ctrl->sockops->set_tos(queue->sock->sk, nctrl->opts->tos); =20 /* Set 10 seconds timeout for icresp recvmsg */ queue->sock->sk->sk_rcvtimeo =3D 10 * HZ; @@ -2886,6 +2897,15 @@ nvme_tcp_existing_controller(struct nvmf_ctrl_option= s *opts) return found; } =20 +static const struct nvme_tcp_sockops nvme_tcp_sockops =3D { + .proto =3D IPPROTO_TCP, + .set_syncnt =3D tcp_sock_set_syncnt, + .set_nodelay =3D tcp_sock_set_nodelay, + .no_linger =3D sock_no_linger, + .set_priority =3D sock_set_priority, + .set_tos =3D ip_sock_set_tos, +}; + static struct nvme_tcp_ctrl *nvme_tcp_alloc_ctrl(struct device *dev, struct nvmf_ctrl_options *opts) { @@ -2950,6 +2970,13 @@ static struct nvme_tcp_ctrl *nvme_tcp_alloc_ctrl(str= uct device *dev, goto out_free_ctrl; } =20 + if (!strcmp(ctrl->ctrl.opts->transport, "tcp")) { + ctrl->sockops =3D &nvme_tcp_sockops; + } else { + ret =3D -EINVAL; + goto out_free_ctrl; + } + ctrl->queues =3D kzalloc_objs(*ctrl->queues, ctrl->ctrl.queue_count); if (!ctrl->queues) { ret =3D -ENOMEM; --=20 2.51.0