[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20231102062836.19074-1-lirongqing@baidu.com>
Date: Thu, 2 Nov 2023 14:28:35 +0800
From: Li RongQing <lirongqing@...du.com>
To: netdev@...r.kernel.org
Subject: [PATCH 1/2][net-next] skbuff: move netlink_large_alloc_large_skb() to skbuff.c
move netlink_alloc_large_skb and netlink_skb_destructor to skbuff.c
and rename them more generic, so they can be used elsewhere large
non-contiguous physical memory is needed
Signed-off-by: Li RongQing <lirongqing@...du.com>
---
include/linux/skbuff.h | 3 +++
net/core/skbuff.c | 40 ++++++++++++++++++++++++++++++++++++++++
net/netlink/af_netlink.c | 41 ++---------------------------------------
3 files changed, 45 insertions(+), 39 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 4174c4b..774a401 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -5063,5 +5063,8 @@ static inline void skb_mark_for_recycle(struct sk_buff *skb)
ssize_t skb_splice_from_iter(struct sk_buff *skb, struct iov_iter *iter,
ssize_t maxsize, gfp_t gfp);
+
+void large_skb_destructor(struct sk_buff *skb);
+struct sk_buff *alloc_large_skb(unsigned int size, int broadcast);
#endif /* __KERNEL__ */
#endif /* _LINUX_SKBUFF_H */
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 4570705..20ffcd5 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -6917,3 +6917,43 @@ ssize_t skb_splice_from_iter(struct sk_buff *skb, struct iov_iter *iter,
return spliced ?: ret;
}
EXPORT_SYMBOL(skb_splice_from_iter);
+
+void large_skb_destructor(struct sk_buff *skb)
+{
+ if (is_vmalloc_addr(skb->head)) {
+ if (!skb->cloned ||
+ !atomic_dec_return(&(skb_shinfo(skb)->dataref)))
+ vfree(skb->head);
+
+ skb->head = NULL;
+ }
+ if (skb->sk)
+ sock_rfree(skb);
+}
+EXPORT_SYMBOL(large_skb_destructor);
+
+struct sk_buff *alloc_large_skb(unsigned int size,
+ int broadcast)
+{
+ struct sk_buff *skb;
+ void *data;
+
+ if (size <= NLMSG_GOODSIZE || broadcast)
+ return alloc_skb(size, GFP_KERNEL);
+
+ size = SKB_DATA_ALIGN(size) +
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+
+ data = vmalloc(size);
+ if (!data)
+ return NULL;
+
+ skb = __build_skb(data, size);
+ if (!skb)
+ vfree(data);
+ else
+ skb->destructor = large_skb_destructor;
+
+ return skb;
+}
+EXPORT_SYMBOL(alloc_large_skb);
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 642b9d3..1d50b68 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -369,24 +369,11 @@ static void netlink_rcv_wake(struct sock *sk)
wake_up_interruptible(&nlk->wait);
}
-static void netlink_skb_destructor(struct sk_buff *skb)
-{
- if (is_vmalloc_addr(skb->head)) {
- if (!skb->cloned ||
- !atomic_dec_return(&(skb_shinfo(skb)->dataref)))
- vfree(skb->head);
-
- skb->head = NULL;
- }
- if (skb->sk != NULL)
- sock_rfree(skb);
-}
-
static void netlink_skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
{
WARN_ON(skb->sk != NULL);
skb->sk = sk;
- skb->destructor = netlink_skb_destructor;
+ skb->destructor = large_skb_destructor;
atomic_add(skb->truesize, &sk->sk_rmem_alloc);
sk_mem_charge(sk, skb->truesize);
}
@@ -1204,30 +1191,6 @@ struct sock *netlink_getsockbyfilp(struct file *filp)
return sock;
}
-static struct sk_buff *netlink_alloc_large_skb(unsigned int size,
- int broadcast)
-{
- struct sk_buff *skb;
- void *data;
-
- if (size <= NLMSG_GOODSIZE || broadcast)
- return alloc_skb(size, GFP_KERNEL);
-
- size = SKB_DATA_ALIGN(size) +
- SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
-
- data = vmalloc(size);
- if (data == NULL)
- return NULL;
-
- skb = __build_skb(data, size);
- if (skb == NULL)
- vfree(data);
- else
- skb->destructor = netlink_skb_destructor;
-
- return skb;
-}
/*
* Attach a skb to a netlink socket.
@@ -1882,7 +1845,7 @@ static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
if (len > sk->sk_sndbuf - 32)
goto out;
err = -ENOBUFS;
- skb = netlink_alloc_large_skb(len, dst_group);
+ skb = alloc_large_skb(len, dst_group);
if (skb == NULL)
goto out;
--
2.9.4
Powered by blists - more mailing lists