Re: [net-next v1 14/16] net: add SO_DEVMEM_DONTNEED setsockopt to release RX frags

From: Simon Horman
Date: Tue Dec 12 2023 - 14:08:23 EST


On Thu, Dec 07, 2023 at 04:52:45PM -0800, Mina Almasry wrote:
> Add an interface for the user to notify the kernel that it is done
> reading the devmem dmabuf frags returned as cmsg. The kernel will
> drop the reference on the frags to make them available for re-use.
>
> Signed-off-by: Willem de Bruijn <willemb@xxxxxxxxxx>
> Signed-off-by: Kaiyuan Zhang <kaiyuanz@xxxxxxxxxx>
> Signed-off-by: Mina Almasry <almasrymina@xxxxxxxxxx>

...

> diff --git a/net/core/sock.c b/net/core/sock.c
> index fef349dd72fa..521bdc4ff260 100644
> --- a/net/core/sock.c
> +++ b/net/core/sock.c
> @@ -1051,6 +1051,41 @@ static int sock_reserve_memory(struct sock *sk, int bytes)
> return 0;
> }
>
> +static noinline_for_stack int
> +sock_devmem_dontneed(struct sock *sk, sockptr_t optval, unsigned int optlen)
> +{
> + struct dmabuf_token tokens[128];

Hi Mina,

I am guessing it is mostly due to the line above,
but on x86 32bit builds I see:

warning: the frame size of 1048 bytes is larger than 1024 bytes [-Wframe-larger-than

> + unsigned int num_tokens, i, j;
> + int ret;
> +
> + if (sk->sk_type != SOCK_STREAM || sk->sk_protocol != IPPROTO_TCP)
> + return -EBADF;
> +
> + if (optlen % sizeof(struct dmabuf_token) || optlen > sizeof(tokens))
> + return -EINVAL;
> +
> + num_tokens = optlen / sizeof(struct dmabuf_token);
> + if (copy_from_sockptr(tokens, optval, optlen))
> + return -EFAULT;
> +
> + ret = 0;
> + for (i = 0; i < num_tokens; i++) {
> + for (j = 0; j < tokens[i].token_count; j++) {
> + struct page *page = xa_erase(&sk->sk_user_pages,
> + tokens[i].token_start + j);
> +
> + if (page) {
> + if (WARN_ON_ONCE(!napi_pp_put_page(page,
> + false)))
> + page_pool_page_put_many(page, 1);
> + ret++;
> + }
> + }
> + }
> +
> + return ret;
> +}
> +
> void sockopt_lock_sock(struct sock *sk)
> {
> /* When current->bpf_ctx is set, the setsockopt is called from

...