On 7/10/26 9:08 AM, David Marchand wrote:
> Let's allow growing a dp_packet_batch.
> This will help for software GSO as we can define a helper that
> will segment all packets and return them in the input batch.
> 
> To limit heap allocations, keep an embedded array of packets
> in the batch structure, and switch to heap allocated packets
> array when reaching the NETDEV_MAX_BURST previous limit.
> 
> The refill API becomes simpler, as the only operation needed now is to
> reset the count of packets when starting a refill loop.
> 
> ipf and GSO software helper are left untouched (keeping the
> behavior of accumulating up to NETDEV_MAX_BURST packets) and are updated
> in next commits.
> 
> At this point in time, no part of OVS should grow batches. Add a check
> in OVS_VSWITCHD_STOP, with a macro to simplify testing later commits.
> 
> Signed-off-by: David Marchand <[email protected]>
> ---
> Changes since v1:
> - introduced dp_packet_batch_capacity helper earlier in the series,
> 
> Changes since RFC v1:
> - renamed field as "capacity",
> 
> ---
>  lib/dp-packet-gso.c     |  6 ++--
>  lib/dp-packet.c         | 25 +++++++++++++++
>  lib/dp-packet.h         | 67 +++++++++++++++++------------------------
>  lib/dpif-netdev.c       |  6 ++--
>  lib/ipf.c               | 14 ++++-----
>  lib/netdev-dpdk.c       |  4 +--
>  lib/netdev.c            |  6 ++--
>  lib/odp-execute.c       |  2 +-
>  tests/ofproto-macros.at | 10 ++++++
>  tests/test-conntrack.c  |  4 +--
>  10 files changed, 84 insertions(+), 60 deletions(-)
> 
> diff --git a/lib/dp-packet-gso.c b/lib/dp-packet-gso.c
> index bceb851fb9..22e8a6cd18 100644
> --- a/lib/dp-packet-gso.c
> +++ b/lib/dp-packet-gso.c
> @@ -196,7 +196,7 @@ dp_packet_gso__(struct dp_packet *p, struct 
> dp_packet_batch **batches,
>  
>      /* Put back the first segment in the batch, it will be trimmed after
>       * all segments have been copied. */
> -    if (dp_packet_batch_is_full(curr_batch)) {
> +    if (dp_packet_batch_size(curr_batch) == NETDEV_MAX_BURST) {
>          curr_batch++;
>      }
>      dp_packet_batch_add(curr_batch, p);
> @@ -228,7 +228,7 @@ dp_packet_gso__(struct dp_packet *p, struct 
> dp_packet_batch **batches,
>          dp_packet_gso_update_segment(seg, i, n_segs, tso_segsz, udp_tnl,
>                                       gre_tnl);
>  
> -        if (dp_packet_batch_is_full(curr_batch)) {
> +        if (dp_packet_batch_size(curr_batch) == NETDEV_MAX_BURST) {
>              curr_batch++;
>          }
>          dp_packet_batch_add(curr_batch, seg);
> @@ -241,7 +241,7 @@ last_seg:
>      dp_packet_gso_update_segment(seg, n_segs - 1, n_segs, tso_segsz, udp_tnl,
>                                   gre_tnl);
>  
> -    if (dp_packet_batch_is_full(curr_batch)) {
> +    if (dp_packet_batch_size(curr_batch) == NETDEV_MAX_BURST) {
>          curr_batch++;
>      }
>      dp_packet_batch_add(curr_batch, seg);
> diff --git a/lib/dp-packet.c b/lib/dp-packet.c
> index ac8fbe3b97..fb52fec686 100644
> --- a/lib/dp-packet.c
> +++ b/lib/dp-packet.c
> @@ -18,6 +18,7 @@
>  #include <stdlib.h>
>  #include <string.h>
>  
> +#include "coverage.h"
>  #include "dp-packet.h"
>  #include "netdev-afxdp.h"
>  #include "netdev-dpdk.h"
> @@ -25,6 +26,8 @@
>  #include "openvswitch/dynamic-string.h"
>  #include "util.h"
>  
> +COVERAGE_DEFINE(dp_packet_batch_grow);
> +
>  static void
>  dp_packet_init__(struct dp_packet *b, size_t allocated, enum 
> dp_packet_source source)
>  {
> @@ -665,3 +668,25 @@ dp_packet_ol_send_prepare(struct dp_packet *p, uint64_t 
> flags)
>          }
>      }
>  }
> +
> +void
> +dp_packet_batch_grow(struct dp_packet_batch *batch, size_t count)
> +{
> +    struct dp_packet **old_packets;
> +
> +    COVERAGE_INC(dp_packet_batch_grow);
> +
> +    if (batch->packets == batch->embedded) {
> +        old_packets = NULL;
> +    } else {
> +        old_packets = batch->packets;
> +    }
> +
> +    batch->packets = xrealloc(old_packets,
> +                              (batch->capacity + count)
> +                              * sizeof *batch->packets);
> +    if (!old_packets) {
> +        memcpy(batch->packets, batch->embedded, sizeof batch->embedded);
> +    }
> +    batch->capacity += count;
> +}
> diff --git a/lib/dp-packet.h b/lib/dp-packet.h
> index e144cf8d75..fbb2320b3c 100644
> --- a/lib/dp-packet.h
> +++ b/lib/dp-packet.h
> @@ -862,7 +862,9 @@ enum { NETDEV_MAX_BURST = 32 }; /* Maximum number packets 
> in a batch. */
>  struct dp_packet_batch {
>      size_t count;
>      bool trunc; /* true if the batch needs truncate. */
> -    struct dp_packet *packets[NETDEV_MAX_BURST];
> +    struct dp_packet **packets;
> +    size_t capacity;
> +    struct dp_packet *embedded[NETDEV_MAX_BURST];
>  };
>  
>  static inline void
> @@ -876,40 +878,31 @@ static inline void
>  dp_packet_batch_init(struct dp_packet_batch *batch)
>  {
>      dp_packet_batch_reset(batch);
> +    batch->capacity = ARRAY_SIZE(batch->embedded);
> +    batch->packets = batch->embedded;
>  }
>  
> -static inline void
> -dp_packet_batch_add__(struct dp_packet_batch *batch,
> -                      struct dp_packet *packet, size_t limit)
> -{
> -    if (batch->count < limit) {
> -        batch->packets[batch->count++] = packet;
> -    } else {
> -        dp_packet_delete(packet);
> -    }
> -}
> +void dp_packet_batch_grow(struct dp_packet_batch *batch, size_t count);

nit: variable name for the batch is not needed.
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to