On Fri, Jun 28, 2024 at 2:33 AM Mina Almasry almasrymina@google.com 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 reuse.
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
v10:
- Fix leak of tokens (Nikolay).
v7:
- Updated SO_DEVMEM_* uapi to use the next available entry (Arnd).
v6:
- Squash in locking optimizations from edumazet@google.com. With his changes we lock the xarray once per sock_devmem_dontneed operation rather than once per frag.
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 | 1 + arch/mips/include/uapi/asm/socket.h | 1 + arch/parisc/include/uapi/asm/socket.h | 1 + arch/sparc/include/uapi/asm/socket.h | 1 + include/uapi/asm-generic/socket.h | 1 + include/uapi/linux/uio.h | 4 ++ net/core/sock.c | 61 +++++++++++++++++++++++++++ 7 files changed, 70 insertions(+)
+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 9abc4fe259535..040c66ac26244 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -124,6 +124,7 @@ #include <linux/netdevice.h> #include <net/protocol.h> #include <linux/skbuff.h> +#include <linux/skbuff_ref.h> #include <net/net_namespace.h> #include <net/request_sock.h> #include <net/sock.h> @@ -1049,6 +1050,62 @@ 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, k, netmem_num = 0;
struct dmabuf_token *tokens;
netmem_ref netmems[16];
int ret = 0;
if (sk->sk_type != SOCK_STREAM || sk->sk_protocol != IPPROTO_TCP)
return -EBADF;
This might use sk_is_tcp() helper.
if (optlen % sizeof(struct dmabuf_token) ||
optlen > sizeof(*tokens) * 128)
return -EINVAL;
tokens = kvmalloc_array(128, sizeof(*tokens), GFP_KERNEL);
This allocates 8192 bytes even for small optlen ?
Probably no big deal, no need to send a new version.
Reviewed-by: Eric Dumazet edumazet@google.com