[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210109024950.4043819-3-charlie@charlie.bz>
Date: Sat, 9 Jan 2021 13:49:50 +1100
From: Charlie Somerville <charlie@...rlie.bz>
To: davem@...emloft.net, kuba@...nel.org, mst@...hat.com,
jasowang@...hat.com
Cc: netdev@...r.kernel.org, Charlie Somerville <charlie@...rlie.bz>
Subject: [PATCH net-next 2/2] virtio_net: Implement XDP_FLAGS_NO_TX support
No send queues will be allocated for XDP filters. Attempts to transmit
packets when no XDP send queues exist will fail with EOPNOTSUPP.
Signed-off-by: Charlie Somerville <charlie@...rlie.bz>
---
drivers/net/virtio_net.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 508408fbe78f..ed08998765e0 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -485,6 +485,10 @@ static struct send_queue *virtnet_xdp_sq(struct virtnet_info *vi)
{
unsigned int qp;
+ /* If no queue pairs are allocated for XDP use, return NULL */
+ if (vi->xdp_queue_pairs == 0)
+ return NULL;
+
qp = vi->curr_queue_pairs - vi->xdp_queue_pairs + smp_processor_id();
return &vi->sq[qp];
}
@@ -514,6 +518,11 @@ static int virtnet_xdp_xmit(struct net_device *dev,
sq = virtnet_xdp_sq(vi);
+ /* No send queue exists if program was attached with XDP_NO_TX */
+ if (unlikely(!sq)) {
+ return -EOPNOTSUPP;
+ }
+
if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK)) {
ret = -EINVAL;
drops = n;
@@ -1464,7 +1473,7 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
if (xdp_xmit & VIRTIO_XDP_TX) {
sq = virtnet_xdp_sq(vi);
- if (virtqueue_kick_prepare(sq->vq) && virtqueue_notify(sq->vq)) {
+ if (sq && virtqueue_kick_prepare(sq->vq) && virtqueue_notify(sq->vq)) {
u64_stats_update_begin(&sq->stats.syncp);
sq->stats.kicks++;
u64_stats_update_end(&sq->stats.syncp);
@@ -2388,7 +2397,7 @@ static int virtnet_restore_guest_offloads(struct virtnet_info *vi)
}
static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
- struct netlink_ext_ack *extack)
+ struct netlink_ext_ack *extack, u32 flags)
{
unsigned long int max_sz = PAGE_SIZE - sizeof(struct padded_vnet_hdr);
struct virtnet_info *vi = netdev_priv(dev);
@@ -2418,7 +2427,7 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
}
curr_qp = vi->curr_queue_pairs - vi->xdp_queue_pairs;
- if (prog)
+ if (prog && !(flags & XDP_FLAGS_NO_TX))
xdp_qp = nr_cpu_ids;
/* XDP requires extra queues for XDP_TX */
@@ -2502,7 +2511,7 @@ static int virtnet_xdp(struct net_device *dev, struct netdev_bpf *xdp)
{
switch (xdp->command) {
case XDP_SETUP_PROG:
- return virtnet_xdp_set(dev, xdp->prog, xdp->extack);
+ return virtnet_xdp_set(dev, xdp->prog, xdp->extack, xdp->flags);
default:
return -EINVAL;
}
--
2.30.0
Powered by blists - more mailing lists