From: Stanislav Fomichev <stfomichev@gmail.com>
To: Mina Almasry <almasrymina@google.com>
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-kselftest@vger.kernel.org,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>,
Jesper Dangaard Brouer <hawk@kernel.org>,
Ilias Apalodimas <ilias.apalodimas@linaro.org>,
Shuah Khan <shuah@kernel.org>, Yi Lai <yi1.lai@linux.intel.com>
Subject: Re: [PATCH net-next v1 6/7] net: fix SO_DEVMEM_DONTNEED looping too long
Date: Wed, 30 Oct 2024 07:33:40 -0700 [thread overview]
Message-ID: <ZyJDxK5stZ_RF71O@mini-arch> (raw)
In-Reply-To: <20241029205524.1306364-2-almasrymina@google.com>
On 10/29, Mina Almasry wrote:
> Check we're going to free a reasonable number of frags in token_count
> before starting the loop, to prevent looping too long.
>
> Also minor code cleanups:
> - Flip checks to reduce indentation.
> - Use sizeof(*tokens) everywhere for consistentcy.
>
> Cc: Yi Lai <yi1.lai@linux.intel.com>
>
> Signed-off-by: Mina Almasry <almasrymina@google.com>
>
> ---
> net/core/sock.c | 46 ++++++++++++++++++++++++++++------------------
> 1 file changed, 28 insertions(+), 18 deletions(-)
>
> diff --git a/net/core/sock.c b/net/core/sock.c
> index 7f398bd07fb7..8603b8d87f2e 100644
> --- a/net/core/sock.c
> +++ b/net/core/sock.c
> @@ -1047,11 +1047,12 @@ static int sock_reserve_memory(struct sock *sk, int bytes)
>
> #ifdef CONFIG_PAGE_POOL
>
> -/* This is the number of tokens that the user can SO_DEVMEM_DONTNEED in
> +/* This is the number of frags that the user can SO_DEVMEM_DONTNEED in
> * 1 syscall. The limit exists to limit the amount of memory the kernel
> - * allocates to copy these tokens.
> + * allocates to copy these tokens, and to prevent looping over the frags for
> + * too long.
> */
> -#define MAX_DONTNEED_TOKENS 128
> +#define MAX_DONTNEED_FRAGS 1024
>
> static noinline_for_stack int
> sock_devmem_dontneed(struct sock *sk, sockptr_t optval, unsigned int optlen)
> @@ -1059,43 +1060,52 @@ sock_devmem_dontneed(struct sock *sk, sockptr_t optval, unsigned int optlen)
> unsigned int num_tokens, i, j, k, netmem_num = 0;
> struct dmabuf_token *tokens;
> netmem_ref netmems[16];
> + u64 num_frags = 0;
> int ret = 0;
>
> if (!sk_is_tcp(sk))
> return -EBADF;
>
> - if (optlen % sizeof(struct dmabuf_token) ||
> - optlen > sizeof(*tokens) * MAX_DONTNEED_TOKENS)
> + if (optlen % sizeof(*tokens) ||
> + optlen > sizeof(*tokens) * MAX_DONTNEED_FRAGS)
> return -EINVAL;
>
> - tokens = kvmalloc_array(optlen, sizeof(*tokens), GFP_KERNEL);
> + num_tokens = optlen / sizeof(*tokens);
> + tokens = kvmalloc_array(num_tokens, sizeof(*tokens), GFP_KERNEL);
> if (!tokens)
> return -ENOMEM;
>
> - num_tokens = optlen / sizeof(struct dmabuf_token);
> if (copy_from_sockptr(tokens, optval, optlen)) {
> kvfree(tokens);
> return -EFAULT;
> }
>
> + for (i = 0; i < num_tokens; i++) {
> + num_frags += tokens[i].token_count;
> + if (num_frags > MAX_DONTNEED_FRAGS) {
> + kvfree(tokens);
> + return -E2BIG;
> + }
> + }
> +
> xa_lock_bh(&sk->sk_user_frags);
> for (i = 0; i < num_tokens; i++) {
> for (j = 0; j < tokens[i].token_count; j++) {
> netmem_ref netmem = (__force netmem_ref)__xa_erase(
> &sk->sk_user_frags, tokens[i].token_start + j);
>
> - if (netmem &&
> - !WARN_ON_ONCE(!netmem_is_net_iov(netmem))) {
> - netmems[netmem_num++] = netmem;
> - if (netmem_num == ARRAY_SIZE(netmems)) {
> - xa_unlock_bh(&sk->sk_user_frags);
> - for (k = 0; k < netmem_num; k++)
> - WARN_ON_ONCE(!napi_pp_put_page(netmems[k]));
> - netmem_num = 0;
> - xa_lock_bh(&sk->sk_user_frags);
> - }
> - ret++;
[..]
> + if (!netmem || WARN_ON_ONCE(!netmem_is_net_iov(netmem)))
> + continue;
Any reason we are not returning explicit error to the callers here?
That probably needs some mechanism to signal which particular one failed
so the users can restart?
next prev parent reply other threads:[~2024-10-30 14:33 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-29 20:55 [PATCH net-next v1 0/7] devmem TCP fixes Mina Almasry
2024-10-29 20:55 ` [PATCH net-next v1 6/7] net: fix SO_DEVMEM_DONTNEED looping too long Mina Almasry
2024-10-30 14:33 ` Stanislav Fomichev [this message]
2024-10-30 14:46 ` Mina Almasry
2024-10-30 15:06 ` Stanislav Fomichev
2024-11-05 21:28 ` Mina Almasry
2024-11-05 21:46 ` Stanislav Fomichev
2024-11-05 23:43 ` Mina Almasry
2024-11-06 0:13 ` Stanislav Fomichev
2024-10-29 20:55 ` [PATCH net-next v1 7/7] ncdevmem: add test for too many token_count Mina Almasry
2024-11-01 2:41 ` [PATCH net-next v1 0/7] devmem TCP fixes Jakub Kicinski
2024-11-01 13:14 ` Mina Almasry
2024-11-02 2:27 ` Jakub Kicinski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZyJDxK5stZ_RF71O@mini-arch \
--to=stfomichev@gmail.com \
--cc=almasrymina@google.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=hawk@kernel.org \
--cc=horms@kernel.org \
--cc=ilias.apalodimas@linaro.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=shuah@kernel.org \
--cc=yi1.lai@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).