diff options
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r-- | drivers/net/virtio_net.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index ede0a80045b3..f5207ef21a91 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -82,6 +82,16 @@ static void give_a_page(struct virtnet_info *vi, struct page *page) | |||
82 | vi->pages = page; | 82 | vi->pages = page; |
83 | } | 83 | } |
84 | 84 | ||
85 | static void trim_pages(struct virtnet_info *vi, struct sk_buff *skb) | ||
86 | { | ||
87 | unsigned int i; | ||
88 | |||
89 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) | ||
90 | give_a_page(vi, skb_shinfo(skb)->frags[i].page); | ||
91 | skb_shinfo(skb)->nr_frags = 0; | ||
92 | skb->data_len = 0; | ||
93 | } | ||
94 | |||
85 | static struct page *get_a_page(struct virtnet_info *vi, gfp_t gfp_mask) | 95 | static struct page *get_a_page(struct virtnet_info *vi, gfp_t gfp_mask) |
86 | { | 96 | { |
87 | struct page *p = vi->pages; | 97 | struct page *p = vi->pages; |
@@ -121,15 +131,8 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb, | |||
121 | } | 131 | } |
122 | len -= sizeof(struct virtio_net_hdr); | 132 | len -= sizeof(struct virtio_net_hdr); |
123 | 133 | ||
124 | if (len <= MAX_PACKET_LEN) { | 134 | if (len <= MAX_PACKET_LEN) |
125 | unsigned int i; | 135 | trim_pages(netdev_priv(dev), skb); |
126 | |||
127 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) | ||
128 | give_a_page(netdev_priv(dev), | ||
129 | skb_shinfo(skb)->frags[i].page); | ||
130 | skb->data_len = 0; | ||
131 | skb_shinfo(skb)->nr_frags = 0; | ||
132 | } | ||
133 | 136 | ||
134 | err = pskb_trim(skb, len); | 137 | err = pskb_trim(skb, len); |
135 | if (err) { | 138 | if (err) { |
@@ -233,6 +236,7 @@ static void try_fill_recv(struct virtnet_info *vi) | |||
233 | err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, num, skb); | 236 | err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, num, skb); |
234 | if (err) { | 237 | if (err) { |
235 | skb_unlink(skb, &vi->recv); | 238 | skb_unlink(skb, &vi->recv); |
239 | trim_pages(vi, skb); | ||
236 | kfree_skb(skb); | 240 | kfree_skb(skb); |
237 | break; | 241 | break; |
238 | } | 242 | } |