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.

Reported by:	phk (panic in iwl_txq_reclaim)
Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
This commit is contained in:
Bjoern A. Zeeb 2022-03-23 17:05:43 +00:00
parent 1babcad6bc
commit 6a8973c332
2 changed files with 15 additions and 12 deletions

View File

@ -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

View File

@ -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);