On 6/24/26 5:45 PM, David Marchand wrote:
> In preparation for batches larger than NETDEV_MAX_BURST,
> split big batches into "small" NETDEV_MAX_BURST batches for recirculation,
> as some dpif-netdev input operations (flow extraction and dpcls lookups)
> are using arrays (on the stack) sized for NETDEV_MAX_BURST burst of
> packets.
> 
> Add one coverage counter so that next changes can test this code.
> 
> Signed-off-by: David Marchand <[email protected]>
> ---
>  lib/dp-packet.h   | 16 ++++++++++++++++
>  lib/dpif-netdev.c | 23 +++++++++++++++++++++++
>  2 files changed, 39 insertions(+)
> 
> diff --git a/lib/dp-packet.h b/lib/dp-packet.h
> index d92b9d4730..16b9afbc36 100644
> --- a/lib/dp-packet.h
> +++ b/lib/dp-packet.h
> @@ -890,6 +890,22 @@ dp_packet_batch_add(struct dp_packet_batch *batch, 
> struct dp_packet *packet)
>      dp_packet_batch_add__(batch, packet, NETDEV_MAX_BURST);
>  }
>  
> +static inline void
> +dp_packet_batch_add_array(struct dp_packet_batch *batch,
> +                          struct dp_packet *packets[], size_t n)
> +{
> +    size_t count = MIN(n, NETDEV_MAX_BURST - batch->count);
> +
> +    if (count) {
> +        memcpy(&batch->packets[batch->count], packets,
> +               count * sizeof packets[0]);
> +        batch->count += count;
> +    }
> +    for (size_t i = count; i < n; i++) {
> +        dp_packet_delete(packets[i]);
> +    }
> +}
> +
>  static inline size_t
>  dp_packet_batch_size(const struct dp_packet_batch *batch)
>  {
> diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
> index 2dc1dd5d4c..0b8daab052 100644
> --- a/lib/dpif-netdev.c
> +++ b/lib/dpif-netdev.c
> @@ -123,6 +123,8 @@ COVERAGE_DEFINE(datapath_drop_rx_invalid_packet);
>  COVERAGE_DEFINE(datapath_drop_hw_post_process);
>  COVERAGE_DEFINE(datapath_drop_hw_post_process_consumed);
>  
> +COVERAGE_DEFINE(dpif_netdev_recirc_big_batch);
> +
>  /* Protects against changes to 'dp_netdevs'. */
>  static struct ovs_mutex dp_netdev_mutex = OVS_MUTEX_INITIALIZER;
>  
> @@ -7686,6 +7688,27 @@ static void
>  dp_netdev_recirculate(struct dp_netdev_pmd_thread *pmd,
>                        struct dp_packet_batch *packets)
>  {
> +    if (dp_packet_batch_size(packets) > NETDEV_MAX_BURST) {
> +        struct dp_packet_batch smaller_batch;
> +        size_t batch_cnt;
> +        size_t sent = 0;

nit: 'sent' may not be the best term here.  Maybe 'processed'?

> +
> +        COVERAGE_INC(dpif_netdev_recirc_big_batch);
> +        batch_cnt = dp_packet_batch_size(packets);
> +        dp_packet_batch_init(&smaller_batch);
> +        do {
> +            size_t count = MIN(batch_cnt - sent, NETDEV_MAX_BURST);
> +
> +            smaller_batch.trunc = packets->trunc;
> +            smaller_batch.count = 0;
> +            dp_packet_batch_add_array(&smaller_batch, 
> &packets->packets[sent],
> +                                      count);
> +            dp_netdev_input__(pmd, &smaller_batch, true, 0);
> +            sent += count;
> +        } while (sent < batch_cnt);

nit: A little crowded in here. I'd add some empty lines around the loop.

> +        return;
> +    }
> +
>      dp_netdev_input__(pmd, packets, true, 0);
>  }
>  

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to