From: Eric Dumazet Subject: [PATCH net-next] tun: use netdev_alloc_frag() in tun_napi_alloc_frags() Date: Sun, 18 Nov 2018 07:37:33 -0800 Message-ID: <20181118153733.163711-1-edumazet@google.com> Mime-Version: 1.0 Content-Transfer-Encoding: 8bit Cc: netdev , Eric Dumazet , Eric Dumazet , Petar Penkov , Mahesh Bandewar , Willem de Bruijn To: "David S . Miller" Return-path: Received: from mail-pg1-f193.google.com ([209.85.215.193]:37354 "EHLO mail-pg1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726643AbeKSB6N (ORCPT ); Sun, 18 Nov 2018 20:58:13 -0500 Received: by mail-pg1-f193.google.com with SMTP id 80so12688621pge.4 for ; Sun, 18 Nov 2018 07:37:37 -0800 (PST) Sender: netdev-owner@vger.kernel.org List-ID: 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 Cc: Petar Penkov Cc: Mahesh Bandewar Cc: Willem de Bruijn --- drivers/net/tun.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 36163a147d3950a5d7451abed96809c2af7c322f..1e9da697081d10e086a26deb1ab38e62f77436b5 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, skb->truesize += skb->data_len; for (i = 1; i < it->nr_segs; i++) { - struct page_frag *pfrag = ¤t->task_frag; size_t fragsz = it->iov[i].iov_len; + struct page *page; + void *frag; if (fragsz == 0 || fragsz > PAGE_SIZE) { err = -EINVAL; goto free; } - - if (!skb_page_frag_refill(fragsz, pfrag, GFP_KERNEL)) { + frag = netdev_alloc_frag(fragsz); + if (!frag) { err = -ENOMEM; goto free; } - - skb_fill_page_desc(skb, i - 1, pfrag->page, - pfrag->offset, fragsz); - page_ref_inc(pfrag->page); - pfrag->offset += fragsz; + page = virt_to_head_page(frag); + skb_fill_page_desc(skb, i - 1, page, + frag - page_address(page), fragsz); } return skb; -- 2.19.1.1215.g8438c0b245-goog