diff options
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r-- | drivers/net/tun.c | 15 |
1 files changed, 7 insertions, 8 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 36163a147d39..1e9da697081d 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -1478,23 +1478,22 @@ static struct sk_buff *tun_napi_alloc_frags(struct tun_file *tfile, | |||
1478 | skb->truesize += skb->data_len; | 1478 | skb->truesize += skb->data_len; |
1479 | 1479 | ||
1480 | for (i = 1; i < it->nr_segs; i++) { | 1480 | for (i = 1; i < it->nr_segs; i++) { |
1481 | struct page_frag *pfrag = ¤t->task_frag; | ||
1482 | size_t fragsz = it->iov[i].iov_len; | 1481 | size_t fragsz = it->iov[i].iov_len; |
1482 | struct page *page; | ||
1483 | void *frag; | ||
1483 | 1484 | ||
1484 | if (fragsz == 0 || fragsz > PAGE_SIZE) { | 1485 | if (fragsz == 0 || fragsz > PAGE_SIZE) { |
1485 | err = -EINVAL; | 1486 | err = -EINVAL; |
1486 | goto free; | 1487 | goto free; |
1487 | } | 1488 | } |
1488 | 1489 | frag = netdev_alloc_frag(fragsz); | |
1489 | if (!skb_page_frag_refill(fragsz, pfrag, GFP_KERNEL)) { | 1490 | if (!frag) { |
1490 | err = -ENOMEM; | 1491 | err = -ENOMEM; |
1491 | goto free; | 1492 | goto free; |
1492 | } | 1493 | } |
1493 | 1494 | page = virt_to_head_page(frag); | |
1494 | skb_fill_page_desc(skb, i - 1, pfrag->page, | 1495 | skb_fill_page_desc(skb, i - 1, page, |
1495 | pfrag->offset, fragsz); | 1496 | frag - page_address(page), fragsz); |
1496 | page_ref_inc(pfrag->page); | ||
1497 | pfrag->offset += fragsz; | ||
1498 | } | 1497 | } |
1499 | 1498 | ||
1500 | return skb; | 1499 | return skb; |