Message ID | 20231218024024.3516870-13-almasrymina@google.com (mailing list archive) |
---|---|
State | RFC |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | Device Memory TCP | expand |
Context | Check | Description |
---|---|---|
netdev/tree_selection | success | Clearly marked for net-next, async |
netdev/apply | fail | Patch does not apply to net-next |
Hi Mina, On 12/18/23 03:40, 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@google.com> > Signed-off-by: Kaiyuan Zhang <kaiyuanz@google.com> > Signed-off-by: Mina Almasry <almasrymina@google.com> > > --- > > Changes in v1: > - devmemtoken -> dmabuf_token (David). > - Use napi_pp_put_page() for refcounting (Yunsheng). > - Fix build error with missing socket options on other asms. > > --- > arch/alpha/include/uapi/asm/socket.h | 8 ++++- > arch/mips/include/uapi/asm/socket.h | 6 ++++ > arch/parisc/include/uapi/asm/socket.h | 6 ++++ > arch/sparc/include/uapi/asm/socket.h | 6 ++++ > include/uapi/asm-generic/socket.h | 1 + > include/uapi/linux/uio.h | 4 +++ > net/core/sock.c | 45 +++++++++++++++++++++++++++ > 7 files changed, 75 insertions(+), 1 deletion(-) > ... > diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h > index be264c2b1a11..6b8674399363 100644 > --- a/arch/parisc/include/uapi/asm/socket.h > +++ b/arch/parisc/include/uapi/asm/socket.h > @@ -132,6 +132,12 @@ > #define SO_PASSPIDFD 0x404A > #define SO_PEERPIDFD 0x404B > > +#define SO_DEVMEM_DONTNEED 0x404C > +#define SO_DEVMEM_LINEAR 0x404D > +#define SCM_DEVMEM_LINEAR SO_DEVMEM_LINEAR > +#define SO_DEVMEM_DMABUF 0x404E > +#define SCM_DEVMEM_DMABUF SO_DEVMEM_DMABUF Could you please change this ^^ for parisc to use the same constants as the generic version below (97-99). Although 0x404c is the logical successor, I'd prefer to be in sync with other generic code if possible... Thanks! Helge ... > diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h > index 25a2f5255f52..1acb77780f10 100644 > --- a/include/uapi/asm-generic/socket.h > +++ b/include/uapi/asm-generic/socket.h > @@ -135,6 +135,7 @@ > #define SO_PASSPIDFD 76 > #define SO_PEERPIDFD 77 > > +#define SO_DEVMEM_DONTNEED 97 > #define SO_DEVMEM_LINEAR 98 > #define SCM_DEVMEM_LINEAR SO_DEVMEM_LINEAR > #define SO_DEVMEM_DMABUF 99
diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h index e94f621903fe..00146c243037 100644 --- a/arch/alpha/include/uapi/asm/socket.h +++ b/arch/alpha/include/uapi/asm/socket.h @@ -10,7 +10,7 @@ * Note: we only bother about making the SOL_SOCKET options * same as OSF/1, as that's all that "normal" programs are * likely to set. We don't necessarily want to be binary - * compatible with _everything_. + * compatible with _everything_. */ #define SOL_SOCKET 0xffff @@ -140,6 +140,12 @@ #define SO_PASSPIDFD 76 #define SO_PEERPIDFD 77 +#define SO_DEVMEM_DONTNEED 78 +#define SO_DEVMEM_LINEAR 79 +#define SCM_DEVMEM_LINEAR SO_DEVMEM_LINEAR +#define SO_DEVMEM_DMABUF 80 +#define SCM_DEVMEM_DMABUF SO_DEVMEM_DMABUF + #if !defined(__KERNEL__) #if __BITS_PER_LONG == 64 diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h index 60ebaed28a4c..9a71ee8f36db 100644 --- a/arch/mips/include/uapi/asm/socket.h +++ b/arch/mips/include/uapi/asm/socket.h @@ -151,6 +151,12 @@ #define SO_PASSPIDFD 76 #define SO_PEERPIDFD 77 +#define SO_DEVMEM_DONTNEED 78 +#define SO_DEVMEM_LINEAR 79 +#define SCM_DEVMEM_LINEAR SO_DEVMEM_LINEAR +#define SO_DEVMEM_DMABUF 80 +#define SCM_DEVMEM_DMABUF SO_DEVMEM_DMABUF + #if !defined(__KERNEL__) #if __BITS_PER_LONG == 64 diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h index be264c2b1a11..6b8674399363 100644 --- a/arch/parisc/include/uapi/asm/socket.h +++ b/arch/parisc/include/uapi/asm/socket.h @@ -132,6 +132,12 @@ #define SO_PASSPIDFD 0x404A #define SO_PEERPIDFD 0x404B +#define SO_DEVMEM_DONTNEED 0x404C +#define SO_DEVMEM_LINEAR 0x404D +#define SCM_DEVMEM_LINEAR SO_DEVMEM_LINEAR +#define SO_DEVMEM_DMABUF 0x404E +#define SCM_DEVMEM_DMABUF SO_DEVMEM_DMABUF + #if !defined(__KERNEL__) #if __BITS_PER_LONG == 64 diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h index 682da3714686..ecfc8bfa9fe0 100644 --- a/arch/sparc/include/uapi/asm/socket.h +++ b/arch/sparc/include/uapi/asm/socket.h @@ -133,6 +133,12 @@ #define SO_PASSPIDFD 0x0055 #define SO_PEERPIDFD 0x0056 +#define SO_DEVMEM_DONTNEED 0x0057 +#define SO_DEVMEM_LINEAR 0x0058 +#define SCM_DEVMEM_LINEAR SO_DEVMEM_LINEAR +#define SO_DEVMEM_DMABUF 0x0059 +#define SCM_DEVMEM_DMABUF SO_DEVMEM_DMABUF + #if !defined(__KERNEL__) diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h index 25a2f5255f52..1acb77780f10 100644 --- a/include/uapi/asm-generic/socket.h +++ b/include/uapi/asm-generic/socket.h @@ -135,6 +135,7 @@ #define SO_PASSPIDFD 76 #define SO_PEERPIDFD 77 +#define SO_DEVMEM_DONTNEED 97 #define SO_DEVMEM_LINEAR 98 #define SCM_DEVMEM_LINEAR SO_DEVMEM_LINEAR #define SO_DEVMEM_DMABUF 99 diff --git a/include/uapi/linux/uio.h b/include/uapi/linux/uio.h index ad92e37699da..65f33178a601 100644 --- a/include/uapi/linux/uio.h +++ b/include/uapi/linux/uio.h @@ -30,6 +30,10 @@ struct dmabuf_cmsg { __u32 dmabuf_id; /* dmabuf id this frag belongs to. */ }; +struct dmabuf_token { + __u32 token_start; + __u32 token_count; +}; /* * UIO_MAXIOV shall be at least 16 1003.1g (5.4.1.1) */ diff --git a/net/core/sock.c b/net/core/sock.c index 446e945f736b..77497dbb9022 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1047,6 +1047,46 @@ static int sock_reserve_memory(struct sock *sk, int bytes) return 0; } +#ifdef CONFIG_PAGE_POOL +static noinline_for_stack int +sock_devmem_dontneed(struct sock *sk, sockptr_t optval, unsigned int optlen) +{ + unsigned int num_tokens, i, j; + struct dmabuf_token *tokens; + int ret; + + if (sk->sk_type != SOCK_STREAM || sk->sk_protocol != IPPROTO_TCP) + return -EBADF; + + if (optlen % sizeof(struct dmabuf_token) || optlen > sizeof(*tokens) * 128) + return -EINVAL; + + tokens = kvmalloc_array(128, sizeof(*tokens), GFP_KERNEL); + if (!tokens) + return -ENOMEM; + + 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 netmem *netmem = xa_erase(&sk->sk_user_frags, + tokens[i].token_start + j); + + if (netmem && !WARN_ON_ONCE(!netmem_is_net_iov(netmem))) { + WARN_ON_ONCE(!napi_pp_put_page(netmem, false)); + ret++; + } + } + } + + kvfree(tokens); + return ret; +} +#endif + void sockopt_lock_sock(struct sock *sk) { /* When current->bpf_ctx is set, the setsockopt is called from @@ -1534,6 +1574,11 @@ int sk_setsockopt(struct sock *sk, int level, int optname, break; } +#ifdef CONFIG_PAGE_POOL + case SO_DEVMEM_DONTNEED: + ret = sock_devmem_dontneed(sk, optval, optlen); + break; +#endif default: ret = -ENOPROTOOPT; break;