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

* [PATCH net-next 2/2] tun: rename generic_xdp to skb_xdp
  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 ` 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
  1 sibling, 1 reply; 4+ messages in thread
From: Jason Wang @ 2017-09-04  3:36 UTC (permalink / raw)
  To: netdev, linux-kernel; +Cc: mst, Jason Wang, Daniel Borkmann

Rename "generic_xdp" to "skb_xdp" to avoid confusing it with the
generic XDP which will be done at netif_receive_skb().

Cc: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 drivers/net/tun.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 80ac18f..3c9985f 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1267,7 +1267,7 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,
 				     struct tun_file *tfile,
 				     struct iov_iter *from,
 				     struct virtio_net_hdr *hdr,
-				     int len, int *generic_xdp)
+				     int len, int *skb_xdp)
 {
 	struct page_frag *alloc_frag = &current->task_frag;
 	struct sk_buff *skb;
@@ -1301,13 +1301,13 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,
 	 * we do XDP on skb in case the headroom is not enough.
 	 */
 	if (hdr->gso_type || !xdp_prog)
-		*generic_xdp = 1;
+		*skb_xdp = 1;
 	else
-		*generic_xdp = 0;
+		*skb_xdp = 0;
 
 	rcu_read_lock();
 	xdp_prog = rcu_dereference(tun->xdp_prog);
-	if (xdp_prog && !*generic_xdp) {
+	if (xdp_prog && !*skb_xdp) {
 		struct xdp_buff xdp;
 		void *orig_data;
 		u32 act;
@@ -1389,7 +1389,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
 	bool zerocopy = false;
 	int err;
 	u32 rxhash;
-	int generic_xdp = 1;
+	int skb_xdp = 1;
 
 	if (!(tun->dev->flags & IFF_UP))
 		return -EIO;
@@ -1448,7 +1448,11 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
 	}
 
 	if (tun_can_build_skb(tun, tfile, len, noblock, zerocopy)) {
-		skb = tun_build_skb(tun, tfile, from, &gso, len, &generic_xdp);
+		/* For the packet that is not easy to be processed
+		 * (e.g gso or jumbo packet), we will do it at after
+		 * skb was created with generic XDP routine.
+		 */
+		skb = tun_build_skb(tun, tfile, from, &gso, len, &skb_xdp);
 		if (IS_ERR(skb)) {
 			this_cpu_inc(tun->pcpu_stats->rx_dropped);
 			return PTR_ERR(skb);
@@ -1528,7 +1532,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
 	skb_reset_network_header(skb);
 	skb_probe_transport_header(skb, 0);
 
-	if (generic_xdp) {
+	if (skb_xdp) {
 		struct bpf_prog *xdp_prog;
 		int ret;
 
-- 
2.7.4

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

* Re: [PATCH net-next 1/2] tun: reserve extra headroom only when XDP is set
  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
  1 sibling, 0 replies; 4+ messages in thread
From: David Miller @ 2017-09-05 21:26 UTC (permalink / raw)
  To: jasowang; +Cc: netdev, linux-kernel, mst, kubakici

From: Jason Wang <jasowang@redhat.com>
Date: Mon,  4 Sep 2017 11:36:08 +0800

> 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>

Applied.

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

* Re: [PATCH net-next 2/2] tun: rename generic_xdp to skb_xdp
  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
  0 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2017-09-05 21:26 UTC (permalink / raw)
  To: jasowang; +Cc: netdev, linux-kernel, mst, daniel

From: Jason Wang <jasowang@redhat.com>
Date: Mon,  4 Sep 2017 11:36:09 +0800

> Rename "generic_xdp" to "skb_xdp" to avoid confusing it with the
> generic XDP which will be done at netif_receive_skb().
> 
> Cc: Daniel Borkmann <daniel@iogearbox.net>
> Signed-off-by: Jason Wang <jasowang@redhat.com>

Applied.

^ permalink raw reply	[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).