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