Commit 9d99d6e9 authored by Paolo Abeni's avatar Paolo Abeni Committed by Geliang Tang
Browse files

mptcp: use copy_from_iter helpers on transmit

mainline inclusion
from mainline-v6.7-rc1
commit 0ffe8e74904027aa48d1f8bd52675c6f0a4c88d1
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I9VYQ9
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/commit/?id=0ffe8e74904027aa48d1f8bd52675c6f0a4c88d1



--------------------------------

The perf traces show an high cost for the MPTCP transmit path memcpy.

It turn out that the helper currently in use carries quite a bit
of unneeded overhead, e.g. to map/unmap the memory pages.

Moving to the 'copy_from_iter' variant removes such overhead and
additionally gains the no-cache support.

Reviewed-by: default avatarMat Martineau <martineau@kernel.org>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Signed-off-by: default avatarMat Martineau <martineau@kernel.org>
Link: https://lore.kernel.org/r/20231023-send-net-next-20231023-2-v1-6-9dc60939d371@kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Reviewed-by: default avatarJackie Liu <liuyun01@kylinos.cn>
Signed-off-by: default avatarGeliang Tang <tanggeliang@kylinos.cn>
parent 94fd1a2a
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -1756,6 +1756,18 @@ static int mptcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg,
	return ret;
}

static int do_copy_data_nocache(struct sock *sk, int copy,
				struct iov_iter *from, char *to)
{
	if (sk->sk_route_caps & NETIF_F_NOCACHE_COPY) {
		if (!copy_from_iter_full_nocache(to, copy, from))
			return -EFAULT;
	} else if (!copy_from_iter_full(to, copy, from)) {
		return -EFAULT;
	}
	return 0;
}

static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
{
	struct mptcp_sock *msk = mptcp_sk(sk);
@@ -1829,11 +1841,10 @@ static int mptcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
		if (!sk_wmem_schedule(sk, total_ts))
			goto wait_for_memory;

		if (copy_page_from_iter(dfrag->page, offset, psize,
					&msg->msg_iter) != psize) {
			ret = -EFAULT;
		ret = do_copy_data_nocache(sk, psize, &msg->msg_iter,
					   page_address(dfrag->page) + offset);
		if (ret)
			goto do_error;
		}

		/* data successfully copied into the write queue */
		sk_forward_alloc_add(sk, -total_ts);