Charlie Somerville <char...@charlie.bz> writes:

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 <char...@charlie.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)) {

Is this addition needed ? Seems like we don't set VIRTIO_XDP_TX bit in case of virtnet_xdp_xmit() failure, so the surrounding 'if' won't be taken.

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


Reply via email to