Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

virtio-net: xsk: Support wakeup on RX side

When XDP_USE_NEED_WAKEUP is used and the fill ring is empty so no buffer
is allocated on RX side, allow RX NAPI to be descheduled. This avoids
wasting CPU cycles on polling. Users will be notified and they need to
make a wakeup call after refilling the ring.

Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
Signed-off-by: Bui Quang Minh <minhquangbui99@gmail.com>
Link: https://patch.msgid.link/20260304154317.7506-1-minhquangbui99@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Bui Quang Minh and committed by
Jakub Kicinski
e3f8800a 21c0dc7c

+30 -9
+30 -9
drivers/net/virtio_net.c
··· 1454 1454 xsk_buffs = rq->xsk_buffs; 1455 1455 1456 1456 num = xsk_buff_alloc_batch(pool, xsk_buffs, rq->vq->num_free); 1457 - if (!num) 1457 + if (!num) { 1458 + if (xsk_uses_need_wakeup(pool)) { 1459 + xsk_set_rx_need_wakeup(pool); 1460 + /* Return 0 instead of -ENOMEM so that NAPI is 1461 + * descheduled. 1462 + */ 1463 + return 0; 1464 + } 1465 + 1458 1466 return -ENOMEM; 1467 + } else { 1468 + xsk_clear_rx_need_wakeup(pool); 1469 + } 1459 1470 1460 1471 len = xsk_pool_get_rx_frame_size(pool) + vi->hdr_len; 1461 1472 ··· 1599 1588 return sent; 1600 1589 } 1601 1590 1602 - static void xsk_wakeup(struct send_queue *sq) 1591 + static void xsk_wakeup(struct napi_struct *napi, struct virtqueue *vq) 1603 1592 { 1604 - if (napi_if_scheduled_mark_missed(&sq->napi)) 1593 + if (napi_if_scheduled_mark_missed(napi)) 1605 1594 return; 1606 1595 1607 1596 local_bh_disable(); 1608 - virtqueue_napi_schedule(&sq->napi, sq->vq); 1597 + virtqueue_napi_schedule(napi, vq); 1609 1598 local_bh_enable(); 1610 1599 } 1611 1600 1612 1601 static int virtnet_xsk_wakeup(struct net_device *dev, u32 qid, u32 flag) 1613 1602 { 1614 1603 struct virtnet_info *vi = netdev_priv(dev); 1615 - struct send_queue *sq; 1616 1604 1617 1605 if (!netif_running(dev)) 1618 1606 return -ENETDOWN; ··· 1619 1609 if (qid >= vi->curr_queue_pairs) 1620 1610 return -EINVAL; 1621 1611 1622 - sq = &vi->sq[qid]; 1612 + if (flag & XDP_WAKEUP_TX) { 1613 + struct send_queue *sq = &vi->sq[qid]; 1623 1614 1624 - xsk_wakeup(sq); 1615 + xsk_wakeup(&sq->napi, sq->vq); 1616 + } 1617 + 1618 + if (flag & XDP_WAKEUP_RX) { 1619 + struct receive_queue *rq = &vi->rq[qid]; 1620 + 1621 + xsk_wakeup(&rq->napi, rq->vq); 1622 + } 1623 + 1625 1624 return 0; 1626 1625 } 1627 1626 ··· 1642 1623 * wakeup the tx napi to consume the xsk tx queue, because the tx 1643 1624 * interrupt may not be triggered. 1644 1625 */ 1645 - xsk_wakeup(sq); 1626 + xsk_wakeup(&sq->napi, sq->vq); 1646 1627 } 1647 1628 1648 1629 static int __virtnet_xdp_xmit_one(struct virtnet_info *vi, ··· 2835 2816 } 2836 2817 2837 2818 /* 2838 - * Returns false if we couldn't fill entirely (OOM). 2819 + * Returns false if we couldn't fill entirely (OOM) and need to retry. 2820 + * In XSK mode, it's when the receive buffer is not allocated and 2821 + * xsk_use_need_wakeup is not set. 2839 2822 * 2840 2823 * Normally run in the receive path, but can also be run from ndo_open 2841 2824 * before we're receiving packets, or from refill_work which is