From: Jesper Dangaard Brouer <brouer@redhat.com>
To: netdev@vger.kernel.org, BjörnTöpel <bjorn.topel@intel.com>,
magnus.karlsson@intel.com
Cc: eugenia@mellanox.com, Jason Wang <jasowang@redhat.com>,
John Fastabend <john.fastabend@gmail.com>,
Eran Ben Elisha <eranbe@mellanox.com>,
Saeed Mahameed <saeedm@mellanox.com>,
galp@mellanox.com, Jesper Dangaard Brouer <brouer@redhat.com>,
Daniel Borkmann <borkmann@iogearbox.net>,
Alexei Starovoitov <alexei.starovoitov@gmail.com>,
Tariq Toukan <tariqt@mellanox.com>
Subject: [net-next V11 PATCH 07/17] virtio_net: convert to use generic xdp_frame and xdp_return_frame API
Date: Tue, 17 Apr 2018 16:45:52 +0200 [thread overview]
Message-ID: <152397635223.20272.1160784284834503782.stgit@firesoul> (raw)
In-Reply-To: <152397622657.20272.10121948713784224943.stgit@firesoul>
The virtio_net driver assumes XDP frames are always released based on
page refcnt (via put_page). Thus, is only queues the XDP data pointer
address and uses virt_to_head_page() to retrieve struct page.
Use the XDP return API to get away from such assumptions. Instead
queue an xdp_frame, which allow us to use the xdp_return_frame API,
when releasing the frame.
V8: Avoid endianness issues (found by kbuild test robot)
V9: Change __virtnet_xdp_xmit from bool to int return value (found by Dan Carpenter)
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
drivers/net/virtio_net.c | 54 +++++++++++++++++++++++++---------------------
1 file changed, 29 insertions(+), 25 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 7b187ec7411e..f50e1ad81ad4 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -415,38 +415,48 @@ static void virtnet_xdp_flush(struct net_device *dev)
virtqueue_kick(sq->vq);
}
-static bool __virtnet_xdp_xmit(struct virtnet_info *vi,
- struct xdp_buff *xdp)
+static int __virtnet_xdp_xmit(struct virtnet_info *vi,
+ struct xdp_buff *xdp)
{
struct virtio_net_hdr_mrg_rxbuf *hdr;
- unsigned int len;
+ struct xdp_frame *xdpf, *xdpf_sent;
struct send_queue *sq;
+ unsigned int len;
unsigned int qp;
- void *xdp_sent;
int err;
qp = vi->curr_queue_pairs - vi->xdp_queue_pairs + smp_processor_id();
sq = &vi->sq[qp];
/* Free up any pending old buffers before queueing new ones. */
- while ((xdp_sent = virtqueue_get_buf(sq->vq, &len)) != NULL) {
- struct page *sent_page = virt_to_head_page(xdp_sent);
+ while ((xdpf_sent = virtqueue_get_buf(sq->vq, &len)) != NULL)
+ xdp_return_frame(xdpf_sent->data, &xdpf_sent->mem);
- put_page(sent_page);
- }
+ xdpf = convert_to_xdp_frame(xdp);
+ if (unlikely(!xdpf))
+ return -EOVERFLOW;
+
+ /* virtqueue want to use data area in-front of packet */
+ if (unlikely(xdpf->metasize > 0))
+ return -EOPNOTSUPP;
- xdp->data -= vi->hdr_len;
+ if (unlikely(xdpf->headroom < vi->hdr_len))
+ return -EOVERFLOW;
+
+ /* Make room for virtqueue hdr (also change xdpf->headroom?) */
+ xdpf->data -= vi->hdr_len;
/* Zero header and leave csum up to XDP layers */
- hdr = xdp->data;
+ hdr = xdpf->data;
memset(hdr, 0, vi->hdr_len);
+ xdpf->len += vi->hdr_len;
- sg_init_one(sq->sg, xdp->data, xdp->data_end - xdp->data);
+ sg_init_one(sq->sg, xdpf->data, xdpf->len);
- err = virtqueue_add_outbuf(sq->vq, sq->sg, 1, xdp->data, GFP_ATOMIC);
+ err = virtqueue_add_outbuf(sq->vq, sq->sg, 1, xdpf, GFP_ATOMIC);
if (unlikely(err))
- return false; /* Caller handle free/refcnt */
+ return -ENOSPC; /* Caller handle free/refcnt */
- return true;
+ return 0;
}
static int virtnet_xdp_xmit(struct net_device *dev, struct xdp_buff *xdp)
@@ -454,7 +464,6 @@ static int virtnet_xdp_xmit(struct net_device *dev, struct xdp_buff *xdp)
struct virtnet_info *vi = netdev_priv(dev);
struct receive_queue *rq = vi->rq;
struct bpf_prog *xdp_prog;
- bool sent;
/* Only allow ndo_xdp_xmit if XDP is loaded on dev, as this
* indicate XDP resources have been successfully allocated.
@@ -463,10 +472,7 @@ static int virtnet_xdp_xmit(struct net_device *dev, struct xdp_buff *xdp)
if (!xdp_prog)
return -ENXIO;
- sent = __virtnet_xdp_xmit(vi, xdp);
- if (!sent)
- return -ENOSPC;
- return 0;
+ return __virtnet_xdp_xmit(vi, xdp);
}
static unsigned int virtnet_get_headroom(struct virtnet_info *vi)
@@ -555,7 +561,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
struct page *page = virt_to_head_page(buf);
unsigned int delta = 0;
struct page *xdp_page;
- bool sent;
int err;
len -= vi->hdr_len;
@@ -606,8 +611,8 @@ static struct sk_buff *receive_small(struct net_device *dev,
delta = orig_data - xdp.data;
break;
case XDP_TX:
- sent = __virtnet_xdp_xmit(vi, &xdp);
- if (unlikely(!sent)) {
+ err = __virtnet_xdp_xmit(vi, &xdp);
+ if (unlikely(err)) {
trace_xdp_exception(vi->dev, xdp_prog, act);
goto err_xdp;
}
@@ -690,7 +695,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
struct bpf_prog *xdp_prog;
unsigned int truesize;
unsigned int headroom = mergeable_ctx_to_headroom(ctx);
- bool sent;
int err;
head_skb = NULL;
@@ -762,8 +766,8 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
}
break;
case XDP_TX:
- sent = __virtnet_xdp_xmit(vi, &xdp);
- if (unlikely(!sent)) {
+ err = __virtnet_xdp_xmit(vi, &xdp);
+ if (unlikely(err)) {
trace_xdp_exception(vi->dev, xdp_prog, act);
if (unlikely(xdp_page != page))
put_page(xdp_page);
next prev parent reply other threads:[~2018-04-17 14:45 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-04-17 14:45 [net-next V11 PATCH 00/17] XDP redirect memory return API Jesper Dangaard Brouer
2018-04-17 14:45 ` [net-next V11 PATCH 01/17] mlx5: basic XDP_REDIRECT forward support Jesper Dangaard Brouer
2018-04-17 14:45 ` [net-next V11 PATCH 02/17] xdp: introduce xdp_return_frame API and use in cpumap Jesper Dangaard Brouer
2018-04-17 14:45 ` [net-next V11 PATCH 03/17] ixgbe: use xdp_return_frame API Jesper Dangaard Brouer
2018-04-17 14:45 ` [net-next V11 PATCH 04/17] xdp: move struct xdp_buff from filter.h to xdp.h Jesper Dangaard Brouer
2018-04-17 14:45 ` [net-next V11 PATCH 05/17] xdp: introduce a new xdp_frame type Jesper Dangaard Brouer
2018-04-17 14:45 ` [net-next V11 PATCH 06/17] tun: convert to use generic xdp_frame and xdp_return_frame API Jesper Dangaard Brouer
2018-04-17 14:45 ` Jesper Dangaard Brouer [this message]
2018-04-17 14:45 ` [net-next V11 PATCH 08/17] bpf: cpumap convert to use generic xdp_frame Jesper Dangaard Brouer
2018-04-17 14:46 ` [net-next V11 PATCH 09/17] i40e: convert to use generic xdp_frame and xdp_return_frame API Jesper Dangaard Brouer
2018-04-17 14:46 ` [net-next V11 PATCH 10/17] mlx5: register a memory model when XDP is enabled Jesper Dangaard Brouer
2018-04-17 14:46 ` [net-next V11 PATCH 11/17] xdp: rhashtable with allocator ID to pointer mapping Jesper Dangaard Brouer
2018-04-17 14:46 ` [net-next V11 PATCH 12/17] page_pool: refurbish version of page_pool code Jesper Dangaard Brouer
2018-04-17 14:46 ` [net-next V11 PATCH 13/17] xdp: allow page_pool as an allocator type in xdp_return_frame Jesper Dangaard Brouer
2018-04-17 14:46 ` [net-next V11 PATCH 14/17] mlx5: use page_pool for xdp_return_frame call Jesper Dangaard Brouer
2018-04-17 14:46 ` [net-next V11 PATCH 15/17] xdp: transition into using xdp_frame for return API Jesper Dangaard Brouer
2018-04-17 14:46 ` [net-next V11 PATCH 16/17] xdp: transition into using xdp_frame for ndo_xdp_xmit Jesper Dangaard Brouer
2018-04-17 14:46 ` [net-next V11 PATCH 17/17] xdp: avoid leaking info stored in frame data on page reuse Jesper Dangaard Brouer
2018-04-17 15:04 ` Daniel Borkmann
2018-04-17 14:48 ` [net-next V11 PATCH 00/17] XDP redirect memory return API Alexei Starovoitov
2018-04-17 15:18 ` David Miller
2018-04-17 15:24 ` Daniel Borkmann
2018-04-17 15:35 ` David Miller
2018-04-17 16:27 ` Jesper Dangaard Brouer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=152397635223.20272.1160784284834503782.stgit@firesoul \
--to=brouer@redhat.com \
--cc=alexei.starovoitov@gmail.com \
--cc=bjorn.topel@intel.com \
--cc=borkmann@iogearbox.net \
--cc=eranbe@mellanox.com \
--cc=eugenia@mellanox.com \
--cc=galp@mellanox.com \
--cc=jasowang@redhat.com \
--cc=john.fastabend@gmail.com \
--cc=magnus.karlsson@intel.com \
--cc=netdev@vger.kernel.org \
--cc=saeedm@mellanox.com \
--cc=tariqt@mellanox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox