netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 1/2] tun: reserve extra headroom only when XDP is set
@ 2017-09-04  3:36 Jason Wang
  2017-09-04  3:36 ` [PATCH net-next 2/2] tun: rename generic_xdp to skb_xdp Jason Wang
  2017-09-05 21:26 ` [PATCH net-next 1/2] tun: reserve extra headroom only when XDP is set David Miller
  0 siblings, 2 replies; 4+ messages in thread
From: Jason Wang @ 2017-09-04  3:36 UTC (permalink / raw)
  To: netdev, linux-kernel; +Cc: mst, Jason Wang, Jakub Kicinski

We reserve headroom unconditionally which could cause unnecessary
stress on socket memory accounting because of increased trusesize. Fix
this by only reserve extra headroom when XDP is set.

Cc: Jakub Kicinski <kubakici@wp.pl>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 drivers/net/tun.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 06e8f0b..80ac18f 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -108,7 +108,7 @@ do {								\
 #endif
 
 #define TUN_HEADROOM 256
-#define TUN_RX_PAD (NET_IP_ALIGN + NET_SKB_PAD + TUN_HEADROOM)
+#define TUN_RX_PAD (NET_IP_ALIGN + NET_SKB_PAD)
 
 /* TUN device flags */
 
@@ -1272,25 +1272,35 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,
 	struct page_frag *alloc_frag = &current->task_frag;
 	struct sk_buff *skb;
 	struct bpf_prog *xdp_prog;
-	int buflen = SKB_DATA_ALIGN(len + TUN_RX_PAD) +
-		     SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+	int buflen = SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 	unsigned int delta = 0;
 	char *buf;
 	size_t copied;
 	bool xdp_xmit = false;
-	int err;
+	int err, pad = TUN_RX_PAD;
+
+	rcu_read_lock();
+	xdp_prog = rcu_dereference(tun->xdp_prog);
+	if (xdp_prog)
+		pad += TUN_HEADROOM;
+	buflen += SKB_DATA_ALIGN(len + pad);
+	rcu_read_unlock();
 
 	if (unlikely(!skb_page_frag_refill(buflen, alloc_frag, GFP_KERNEL)))
 		return ERR_PTR(-ENOMEM);
 
 	buf = (char *)page_address(alloc_frag->page) + alloc_frag->offset;
 	copied = copy_page_from_iter(alloc_frag->page,
-				     alloc_frag->offset + TUN_RX_PAD,
+				     alloc_frag->offset + pad,
 				     len, from);
 	if (copied != len)
 		return ERR_PTR(-EFAULT);
 
-	if (hdr->gso_type)
+	/* There's a small window that XDP may be set after the check
+	 * of xdp_prog above, this should be rare and for simplicity
+	 * we do XDP on skb in case the headroom is not enough.
+	 */
+	if (hdr->gso_type || !xdp_prog)
 		*generic_xdp = 1;
 	else
 		*generic_xdp = 0;
@@ -1303,7 +1313,7 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,
 		u32 act;
 
 		xdp.data_hard_start = buf;
-		xdp.data = buf + TUN_RX_PAD;
+		xdp.data = buf + pad;
 		xdp.data_end = xdp.data + len;
 		orig_data = xdp.data;
 		act = bpf_prog_run_xdp(xdp_prog, &xdp);
@@ -1339,7 +1349,7 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,
 		return ERR_PTR(-ENOMEM);
 	}
 
-	skb_reserve(skb, TUN_RX_PAD - delta);
+	skb_reserve(skb, pad - delta);
 	skb_put(skb, len + delta);
 	get_page(alloc_frag->page);
 	alloc_frag->offset += buflen;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2017-09-05 21:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-09-04  3:36 [PATCH net-next 1/2] tun: reserve extra headroom only when XDP is set Jason Wang
2017-09-04  3:36 ` [PATCH net-next 2/2] tun: rename generic_xdp to skb_xdp Jason Wang
2017-09-05 21:26   ` David Miller
2017-09-05 21:26 ` [PATCH net-next 1/2] tun: reserve extra headroom only when XDP is set David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).