[PATCH 5/6] examples/l3fwd-power: recheck Rx queues before sleeping
David Marchand
david.marchand at redhat.com
Fri Sep 4 11:20:13 CEST 2026
On Mon, 20 Jul 2026 at 10:01, Maxime Leroy <maxime at leroys.fr> wrote:
>
> After arming the Rx interrupts rx_interrupt_wait() sleeps in
> rte_epoll_wait(). A packet that arrived between the last poll and the arm
> can be missed on PMDs whose interrupt is edge-triggered on an empty to
> non-empty transition, such as dpaa2: arming a queue that is already
> non-empty raises no notification, so the lcore sleeps until the next
> packet.
>
> Before sleeping, check whether any queue already holds traffic and, if
> so, skip the wait and go back to polling. NICs with level-triggered
> interrupts are unaffected: a pending packet keeps the interrupt asserted,
> so rte_epoll_wait() would return immediately anyway.
>
> Signed-off-by: Maxime Leroy <maxime at leroys.fr>
> ---
> examples/l3fwd-power/main.c | 27 ++++++++++++++++++++++++++-
> 1 file changed, 26 insertions(+), 1 deletion(-)
>
> diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
> index fa64e28e5c..c423b0dba5 100644
> --- a/examples/l3fwd-power/main.c
> +++ b/examples/l3fwd-power/main.c
> @@ -949,6 +949,26 @@ static int event_register(struct lcore_conf *qconf)
> return 0;
> }
>
> +static bool
> +rx_queue_pending(struct lcore_conf *qconf)
> +{
> + struct lcore_rx_queue *rx_queue;
> + uint16_t queue_id;
> + uint16_t port_id;
> + int i;
> +
> + for (i = 0; i < qconf->n_rx_queue; ++i) {
> + rx_queue = &(qconf->rx_queue_list[i]);
> + port_id = rx_queue->port_id;
> + queue_id = rx_queue->queue_id;
> +
> + if (rte_eth_rx_queue_count(port_id, queue_id) > 0)
> + return true;
> + }
> +
> + return false;
> +}
> +
> static int
> rx_interrupt_wait(struct lcore_conf *qconf, int *intr_registered)
> {
> @@ -968,7 +988,12 @@ rx_interrupt_wait(struct lcore_conf *qconf, int *intr_registered)
> *intr_registered = 1;
> }
>
> - sleep_until_rx_interrupt(qconf->n_rx_queue, rte_lcore_id());
> + /*
> + * A packet that arrived during the arm window raises no new wakeup on
> + * edge-triggered PMDs, so skip the sleep if a queue already has traffic.
> + */
> + if (!rx_queue_pending(qconf))
> + sleep_until_rx_interrupt(qconf->n_rx_queue, rte_lcore_id());
> rx_intr_disable_all(qconf);
> return 0;
> }
I don't see how this solves the race.
There is stil a window between checking the queue count and sleeping.
Looks like a bug that should be solved in the driver.
--
David Marchand
More information about the dev
mailing list