diff options
Diffstat (limited to 'drivers/net/xen-netfront.c')
| -rw-r--r-- | drivers/net/xen-netfront.c | 31 | 
1 files changed, 13 insertions, 18 deletions
| diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index ff7f111fffee..36808bf25677 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -286,8 +286,7 @@ no_skb:  			break;  		} -		__skb_fill_page_desc(skb, 0, page, 0, 0); -		skb_shinfo(skb)->nr_frags = 1; +		skb_add_rx_frag(skb, 0, page, 0, 0, PAGE_SIZE);  		__skb_queue_tail(&np->rx_batch, skb);  	} @@ -831,7 +830,6 @@ static RING_IDX xennet_fill_frags(struct netfront_info *np,  				  struct sk_buff_head *list)  {  	struct skb_shared_info *shinfo = skb_shinfo(skb); -	int nr_frags = shinfo->nr_frags;  	RING_IDX cons = np->rx.rsp_cons;  	struct sk_buff *nskb; @@ -840,19 +838,21 @@ static RING_IDX xennet_fill_frags(struct netfront_info *np,  			RING_GET_RESPONSE(&np->rx, ++cons);  		skb_frag_t *nfrag = &skb_shinfo(nskb)->frags[0]; -		__skb_fill_page_desc(skb, nr_frags, -				     skb_frag_page(nfrag), -				     rx->offset, rx->status); +		if (shinfo->nr_frags == MAX_SKB_FRAGS) { +			unsigned int pull_to = NETFRONT_SKB_CB(skb)->pull_to; -		skb->data_len += rx->status; +			BUG_ON(pull_to <= skb_headlen(skb)); +			__pskb_pull_tail(skb, pull_to - skb_headlen(skb)); +		} +		BUG_ON(shinfo->nr_frags >= MAX_SKB_FRAGS); + +		skb_add_rx_frag(skb, shinfo->nr_frags, skb_frag_page(nfrag), +				rx->offset, rx->status, PAGE_SIZE);  		skb_shinfo(nskb)->nr_frags = 0;  		kfree_skb(nskb); - -		nr_frags++;  	} -	shinfo->nr_frags = nr_frags;  	return cons;  } @@ -933,7 +933,8 @@ static int handle_incoming_queue(struct net_device *dev,  	while ((skb = __skb_dequeue(rxq)) != NULL) {  		int pull_to = NETFRONT_SKB_CB(skb)->pull_to; -		__pskb_pull_tail(skb, pull_to - skb_headlen(skb)); +		if (pull_to > skb_headlen(skb)) +			__pskb_pull_tail(skb, pull_to - skb_headlen(skb));  		/* Ethernet work: Delayed to here as it peeks the header. */  		skb->protocol = eth_type_trans(skb, dev); @@ -1019,16 +1020,10 @@ err:  		skb_shinfo(skb)->frags[0].page_offset = rx->offset;  		skb_frag_size_set(&skb_shinfo(skb)->frags[0], rx->status);  		skb->data_len = rx->status; +		skb->len += rx->status;  		i = xennet_fill_frags(np, skb, &tmpq); -		/* -                 * Truesize is the actual allocation size, even if the -                 * allocation is only partially used. -                 */ -		skb->truesize += PAGE_SIZE * skb_shinfo(skb)->nr_frags; -		skb->len += skb->data_len; -  		if (rx->flags & XEN_NETRXF_csum_blank)  			skb->ip_summed = CHECKSUM_PARTIAL;  		else if (rx->flags & XEN_NETRXF_data_validated) |