git: fef73ef9c2e0 - releng/13.1 - LinuxKPI: skbuff: fix skb_queue_splice_init()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 30 Mar 2022 15:49:46 UTC
The branch releng/13.1 has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=fef73ef9c2e04fab3ccd07b16a657754744d6319 commit fef73ef9c2e04fab3ccd07b16a657754744d6319 Author: Bjoern A. Zeeb <bz@FreeBSD.org> AuthorDate: 2022-03-23 17:05:43 +0000 Commit: Bjoern A. Zeeb <bz@FreeBSD.org> CommitDate: 2022-03-30 15:47:25 +0000 LinuxKPI: skbuff: fix skb_queue_splice_init() In skb_queue_splice_init() we set a next value and then used that new value to further update the remaining linking rather than the original value. Introduce another temporary variable 'n' to hold the original value and use that. While here rename q and h to from and to as otherwise it was too confusing to read. Also initialize skb->prev and skb->next to point to skb itself if for nothing else at least to aid debugging. Approved by: re (gjb) Reported by: phk (panic in iwl_txq_reclaim) Sponsored by: The FreeBSD Foundation (cherry picked from commit 6a8973c3324c0c6c270ae4ad371e50c0ec5761da) (cherry picked from commit 32d1d7fee61328e65ae944836d1027335ccb979c) --- sys/compat/linuxkpi/common/include/linux/skbuff.h | 25 ++++++++++++----------- sys/compat/linuxkpi/common/src/linux_skbuff.c | 2 ++ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/sys/compat/linuxkpi/common/include/linux/skbuff.h b/sys/compat/linuxkpi/common/include/linux/skbuff.h index be93032c7561..21ea7ee560e2 100644 --- a/sys/compat/linuxkpi/common/include/linux/skbuff.h +++ b/sys/compat/linuxkpi/common/include/linux/skbuff.h @@ -762,26 +762,27 @@ skb_mark_not_on_list(struct sk_buff *skb) } static inline void -skb_queue_splice_init(struct sk_buff_head *q, struct sk_buff_head *h) +skb_queue_splice_init(struct sk_buff_head *from, struct sk_buff_head *to) { - struct sk_buff *b, *e; + struct sk_buff *b, *e, *n; - SKB_TRACE2(q, h); + SKB_TRACE2(from, to); - if (skb_queue_empty(q)) + if (skb_queue_empty(from)) return; /* XXX do we need a barrier around this? */ - b = q->next; - e = q->prev; + b = from->next; + e = from->prev; + n = to->next; - b->prev = (struct sk_buff *)h; - h->next = b; - e->next = h->next; - h->next->prev = e; + b->prev = (struct sk_buff *)to; + to->next = b; + e->next = n; + n->prev = e; - h->qlen += q->qlen; - __skb_queue_head_init(q); + to->qlen += from->qlen; + __skb_queue_head_init(from); } static inline void diff --git a/sys/compat/linuxkpi/common/src/linux_skbuff.c b/sys/compat/linuxkpi/common/src/linux_skbuff.c index 0a4974d74d9d..efb97fa2f126 100644 --- a/sys/compat/linuxkpi/common/src/linux_skbuff.c +++ b/sys/compat/linuxkpi/common/src/linux_skbuff.c @@ -86,6 +86,8 @@ linuxkpi_alloc_skb(size_t size, gfp_t gfp) skb->head = skb->data = skb->tail = (uint8_t *)(skb+1); skb->end = skb->head + size; + skb->prev = skb->next = skb; + skb->shinfo = (struct skb_shared_info *)(skb->end); SKB_TRACE_FMT(skb, "data %p size %zu", skb->data, size);