diff options
| author | Nicolai Buchwitz <nb@tipi-net.de> | 2026-10-15 10:16:38 +0200 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-10-20 11:28:49 -0700 |
| commit | 258c3ae4a4af0c7948a3d99e7262701aaa350d31 (patch) | |
| tree | 72bf57248ac6f0724ed7b86ec3ee31cd7b0ce00d /include/linux | |
| parent | 985e3250586b966d6c26d88b6aa09877746af313 (diff) | |
net: rename skb_unshare() to skb_unclone_full()
skb_unshare() only copies cloned skbs. A shared skb that is not a clone
comes back unchanged, which the name doesn't suggest. The loopback
selftest hooks got caught by this and hit BUG_ON(skb_shared()).
Rename it to skb_unclone_full(). Like skb_unclone() it only acts on
clones, but it copies the whole skb, not just the head.
Suggested-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com> # dpaa2
Link: https://patch.msgid.link/20261015-nb-skb-unclone-full-v1-1-0dfbf01f60f2@tipi-net.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/if_vlan.h | 16 | ||||
| -rw-r--r-- | include/linux/skbuff.h | 11 |
2 files changed, 15 insertions, 12 deletions
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 975892367136..c863cdf60f01 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -427,8 +427,8 @@ static inline int __vlan_insert_tag(struct sk_buff *skb, * Inserts the VLAN tag into @skb as part of the payload at offset mac_len * Returns a VLAN tagged skb. This might change skb->head. * - * Following the skb_unshare() example, in case of error, the calling function - * doesn't have to worry about freeing the original skb. + * Following the skb_unclone_full() example, in case of error, the calling + * function doesn't have to worry about freeing the original skb. * * Does not change skb->protocol so this function can be used during receive. * @@ -458,8 +458,8 @@ static inline struct sk_buff *vlan_insert_inner_tag(struct sk_buff *skb, * Inserts the VLAN tag into @skb as part of the payload * Returns a VLAN tagged skb. This might change skb->head. * - * Following the skb_unshare() example, in case of error, the calling function - * doesn't have to worry about freeing the original skb. + * Following the skb_unclone_full() example, in case of error, the calling + * function doesn't have to worry about freeing the original skb. * * Does not change skb->protocol so this function can be used during receive. * @@ -480,8 +480,8 @@ static inline struct sk_buff *vlan_insert_tag(struct sk_buff *skb, * Inserts the VLAN tag into @skb as part of the payload * Returns a VLAN tagged skb. This might change skb->head. * - * Following the skb_unshare() example, in case of error, the calling function - * doesn't have to worry about freeing the original skb. + * Following the skb_unclone_full() example, in case of error, the calling + * function doesn't have to worry about freeing the original skb. * * Return: modified @skb on success, NULL on error (@skb is freed). */ @@ -524,8 +524,8 @@ static inline void __vlan_hwaccel_copy_tag(struct sk_buff *dst, const struct sk_ * * Pushes the VLAN tag from @skb->vlan_tci inside to the payload. * - * Following the skb_unshare() example, in case of error, the calling function - * doesn't have to worry about freeing the original skb. + * Following the skb_unclone_full() example, in case of error, the calling + * function doesn't have to worry about freeing the original skb. */ static inline struct sk_buff *__vlan_hwaccel_push_inside(struct sk_buff *skb) { diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index af1cbc2799b7..5079335f7aae 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2131,14 +2131,14 @@ static inline struct sk_buff *skb_share_check(struct sk_buff *skb, gfp_t pri) } /* - * Copy shared buffers into a new sk_buff. We effectively do COW on + * Copy cloned buffers into a new sk_buff. We effectively do COW on * packets to handle cases where we have a local reader and forward * and a couple of other messy ones. The normal one is tcpdumping * a packet that's being forwarded. */ /** - * skb_unshare - make a copy of a shared buffer + * skb_unclone_full - make a private copy of a cloned buffer * @skb: buffer to check * @pri: priority for memory allocation * @@ -2148,10 +2148,13 @@ static inline struct sk_buff *skb_share_check(struct sk_buff *skb, gfp_t pri) * the original buffer is returned. When called with a spinlock held or * from interrupt state @pri must be %GFP_ATOMIC * + * Unlike skb_unclone(), the paged data is copied as well. A buffer with + * skb->users > 1 that is not a clone is returned as is, use + * skb_share_check() for that case. + * * %NULL is returned on a memory allocation failure. */ -static inline struct sk_buff *skb_unshare(struct sk_buff *skb, - gfp_t pri) +static inline struct sk_buff *skb_unclone_full(struct sk_buff *skb, gfp_t pri) { might_sleep_if(gfpflags_allow_blocking(pri)); if (skb_cloned(skb)) { |
