diff options
Diffstat (limited to 'drivers/net/tap.c')
| -rw-r--r-- | drivers/net/tap.c | 14 | 
1 files changed, 6 insertions, 8 deletions
| diff --git a/drivers/net/tap.c b/drivers/net/tap.c index a6d63665ad03..1f4bdd94407a 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -341,6 +341,7 @@ rx_handler_result_t tap_handle_frame(struct sk_buff **pskb)  		features |= tap->tap_features;  	if (netif_needs_gso(skb, features)) {  		struct sk_buff *segs = __skb_gso_segment(skb, features, false); +		struct sk_buff *next;  		if (IS_ERR(segs))  			goto drop; @@ -352,16 +353,13 @@ rx_handler_result_t tap_handle_frame(struct sk_buff **pskb)  		}  		consume_skb(skb); -		while (segs) { -			struct sk_buff *nskb = segs->next; - -			segs->next = NULL; -			if (ptr_ring_produce(&q->ring, segs)) { -				kfree_skb(segs); -				kfree_skb_list(nskb); +		skb_list_walk_safe(segs, skb, next) { +			skb_mark_not_on_list(skb); +			if (ptr_ring_produce(&q->ring, skb)) { +				kfree_skb(skb); +				kfree_skb_list(next);  				break;  			} -			segs = nskb;  		}  	} else {  		/* If we receive a partial checksum and the tap side | 
