aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2018-11-18 10:37:33 -0500
committerDavid S. Miller <davem@davemloft.net>2018-11-18 22:01:11 -0500
commitaa6daacaa113cda96760c8d3157bae937908f6e3 (patch)
treed685971689336d09beeedd37662ca44f0f038a86
parent05b0e1d6980f9d76a6e5c6184854141bc26c2b13 (diff)
tun: use netdev_alloc_frag() in tun_napi_alloc_frags()
In order to cook skbs in the same way than Ethernet drivers, it is probably better to not use GFP_KERNEL, but rather use the GFP_ATOMIC and PFMEMALLOC mechanisms provided by netdev_alloc_frag(). This would allow to use tun driver even in memory stress situations, especially if swap is used over this tun channel. Fixes: 90e33d459407 ("tun: enable napi_gro_frags() for TUN/TAP driver") Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Petar Penkov <peterpenkov96@gmail.com> Cc: Mahesh Bandewar <maheshb@google.com> Cc: Willem de Bruijn <willemb@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/tun.c15
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 = &current->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;