> Subject: [PATCH] examples/l3fwd: add option to set refetch offset

I suppose it should be 'prefetch'.
 
> The prefetch window depending on the HW platform. It is difficult to
> measure the prefetch window of a HW platform. Therefore, the prefetch
> offset option is added to change the prefetch window. User can adjust
> the refetch offset to achieve the best prefetch effect.
> 
> In addition, this option is used only in the main loop.

I run few tests for fib,lpm,acl modes on my Intel ICX box.
Didn't notice any performance drop with that patch.

> 
> Signed-off-by: Dengdui Huang <huangdeng...@huawei.com>
> ---
>  examples/l3fwd/l3fwd.h               |  6 ++-
>  examples/l3fwd/l3fwd_acl_scalar.h    |  6 +--
>  examples/l3fwd/l3fwd_em.h            | 18 ++++-----
>  examples/l3fwd/l3fwd_em_hlm.h        |  9 +++--
>  examples/l3fwd/l3fwd_em_sequential.h | 60 ++++++++++++++++------------
>  examples/l3fwd/l3fwd_fib.c           | 21 +++++-----
>  examples/l3fwd/l3fwd_lpm.h           |  6 +--
>  examples/l3fwd/l3fwd_lpm_neon.h      | 45 ++++-----------------
>  examples/l3fwd/main.c                | 14 +++++++
>  9 files changed, 91 insertions(+), 94 deletions(-)
> 
> diff --git a/examples/l3fwd/l3fwd.h b/examples/l3fwd/l3fwd.h
> index 0cce3406ee..2272fb2870 100644
> --- a/examples/l3fwd/l3fwd.h
> +++ b/examples/l3fwd/l3fwd.h
> @@ -39,8 +39,7 @@
> 
>  #define NB_SOCKETS        8
> 
> -/* Configure how many packets ahead to prefetch, when reading packets */
> -#define PREFETCH_OFFSET        3
> +#define DEFAULT_PREFECH_OFFSET 4
> 
>  /* Used to mark destination port as 'invalid'. */
>  #define      BAD_PORT ((uint16_t)-1)
> @@ -119,6 +118,9 @@ extern uint32_t max_pkt_len;
>  extern uint32_t nb_pkt_per_burst;
>  extern uint32_t mb_mempool_cache_size;
> 
> +/* Prefetch offset of packets processed by the main loop. */
> +extern uint16_t prefetch_offset;
> +
>  /* Send burst of packets on an output interface */
>  static inline int
>  send_burst(struct lcore_conf *qconf, uint16_t n, uint16_t port)
> diff --git a/examples/l3fwd/l3fwd_acl_scalar.h 
> b/examples/l3fwd/l3fwd_acl_scalar.h
> index cb22bb49aa..d00730ff25 100644
> --- a/examples/l3fwd/l3fwd_acl_scalar.h
> +++ b/examples/l3fwd/l3fwd_acl_scalar.h
> @@ -72,14 +72,14 @@ l3fwd_acl_prepare_acl_parameter(struct rte_mbuf 
> **pkts_in, struct acl_search_t *
>       acl->num_ipv6 = 0;
> 
>       /* Prefetch first packets */
> -     for (i = 0; i < PREFETCH_OFFSET && i < nb_rx; i++) {
> +     for (i = 0; i < prefetch_offset && i < nb_rx; i++) {
>               rte_prefetch0(rte_pktmbuf_mtod(
>                               pkts_in[i], void *));
>       }
> 
> -     for (i = 0; i < (nb_rx - PREFETCH_OFFSET); i++) {
> +     for (i = 0; i < (nb_rx - prefetch_offset); i++) {
>               rte_prefetch0(rte_pktmbuf_mtod(pkts_in[
> -                             i + PREFETCH_OFFSET], void *));
> +                             i + prefetch_offset], void *));
>               l3fwd_acl_prepare_one_packet(pkts_in, acl, i);
>       }
> 
> diff --git a/examples/l3fwd/l3fwd_em.h b/examples/l3fwd/l3fwd_em.h
> index 1fee2e2e6c..3ef32c9053 100644
> --- a/examples/l3fwd/l3fwd_em.h
> +++ b/examples/l3fwd/l3fwd_em.h
> @@ -132,16 +132,16 @@ l3fwd_em_no_opt_send_packets(int nb_rx, struct rte_mbuf 
> **pkts_burst,
>       int32_t j;
> 
>       /* Prefetch first packets */
> -     for (j = 0; j < PREFETCH_OFFSET && j < nb_rx; j++)
> +     for (j = 0; j < prefetch_offset && j < nb_rx; j++)
>               rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[j], void *));
> 
>       /*
>        * Prefetch and forward already prefetched
>        * packets.
>        */
> -     for (j = 0; j < (nb_rx - PREFETCH_OFFSET); j++) {
> +     for (j = 0; j < (nb_rx - prefetch_offset); j++) {
>               rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[
> -                             j + PREFETCH_OFFSET], void *));
> +                             j + prefetch_offset], void *));
>               l3fwd_em_simple_forward(pkts_burst[j], portid, qconf);
>       }
> 
> @@ -161,16 +161,16 @@ l3fwd_em_no_opt_process_events(int nb_rx, struct 
> rte_event **events,
>       int32_t j;
> 
>       /* Prefetch first packets */
> -     for (j = 0; j < PREFETCH_OFFSET && j < nb_rx; j++)
> +     for (j = 0; j < prefetch_offset && j < nb_rx; j++)
>               rte_prefetch0(rte_pktmbuf_mtod(events[j]->mbuf, void *));
> 
>       /*
>        * Prefetch and forward already prefetched
>        * packets.
>        */
> -     for (j = 0; j < (nb_rx - PREFETCH_OFFSET); j++) {
> +     for (j = 0; j < (nb_rx - prefetch_offset); j++) {
>               rte_prefetch0(rte_pktmbuf_mtod(events[
> -                             j + PREFETCH_OFFSET]->mbuf, void *));
> +                             j + prefetch_offset]->mbuf, void *));
>               l3fwd_em_simple_process(events[j]->mbuf, qconf);
>       }
> 
> @@ -188,15 +188,15 @@ l3fwd_em_no_opt_process_event_vector(struct 
> rte_event_vector *vec,
>       int32_t i;
> 
>       /* Prefetch first packets */
> -     for (i = 0; i < PREFETCH_OFFSET && i < vec->nb_elem; i++)
> +     for (i = 0; i < prefetch_offset && i < vec->nb_elem; i++)
>               rte_prefetch0(rte_pktmbuf_mtod(mbufs[i], void *));
> 
>       /*
>        * Prefetch and forward already prefetched packets.
>        */
> -     for (i = 0; i < (vec->nb_elem - PREFETCH_OFFSET); i++) {
> +     for (i = 0; i < (vec->nb_elem - prefetch_offset); i++) {
>               rte_prefetch0(
> -                     rte_pktmbuf_mtod(mbufs[i + PREFETCH_OFFSET], void *));
> +                     rte_pktmbuf_mtod(mbufs[i + prefetch_offset], void *));
>               dst_ports[i] = l3fwd_em_simple_process(mbufs[i], qconf);
>       }
> 
> diff --git a/examples/l3fwd/l3fwd_em_hlm.h b/examples/l3fwd/l3fwd_em_hlm.h
> index c1d819997a..764527962b 100644
> --- a/examples/l3fwd/l3fwd_em_hlm.h
> +++ b/examples/l3fwd/l3fwd_em_hlm.h
> @@ -190,7 +190,7 @@ l3fwd_em_process_packets(int nb_rx, struct rte_mbuf 
> **pkts_burst,
>        */
>       int32_t n = RTE_ALIGN_FLOOR(nb_rx, EM_HASH_LOOKUP_COUNT);
> 
> -     for (j = 0; j < EM_HASH_LOOKUP_COUNT && j < nb_rx; j++) {
> +     for (j = 0; j < prefetch_offset && j < nb_rx; j++) {
>               rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[j],
>                                              struct rte_ether_hdr *) + 1);
>       }
> @@ -207,7 +207,7 @@ l3fwd_em_process_packets(int nb_rx, struct rte_mbuf 
> **pkts_burst,
>               l3_type = pkt_type & RTE_PTYPE_L3_MASK;
>               tcp_or_udp = pkt_type & (RTE_PTYPE_L4_TCP | RTE_PTYPE_L4_UDP);
> 
> -             for (i = 0, pos = j + EM_HASH_LOOKUP_COUNT;
> +             for (i = 0, pos = j + prefetch_offset;
>                    i < EM_HASH_LOOKUP_COUNT && pos < nb_rx; i++, pos++) {
>                       rte_prefetch0(rte_pktmbuf_mtod(
>                                       pkts_burst[pos],
> @@ -277,6 +277,9 @@ l3fwd_em_process_events(int nb_rx, struct rte_event **ev,
>       for (j = 0; j < nb_rx; j++)
>               pkts_burst[j] = ev[j]->mbuf;
> 
> +     for (i = 0; i < prefetch_offset && i < nb_rx; i++)
> +             rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i], struct 
> rte_ether_hdr *) + 1);
> +

If there are no prefetches right now, probably no need to add new.
Or if you feel strongly about it - make it as a new patch.

>       for (j = 0; j < n; j += EM_HASH_LOOKUP_COUNT) {
> 
>               uint32_t pkt_type = RTE_PTYPE_L3_MASK |
> @@ -289,7 +292,7 @@ l3fwd_em_process_events(int nb_rx, struct rte_event **ev,
>               l3_type = pkt_type & RTE_PTYPE_L3_MASK;
>               tcp_or_udp = pkt_type & (RTE_PTYPE_L4_TCP | RTE_PTYPE_L4_UDP);
> 
> -             for (i = 0, pos = j + EM_HASH_LOOKUP_COUNT;
> +             for (i = 0, pos = j + prefetch_offset;
>                    i < EM_HASH_LOOKUP_COUNT && pos < nb_rx; i++, pos++) {
>                       rte_prefetch0(rte_pktmbuf_mtod(
>                                       pkts_burst[pos],
> diff --git a/examples/l3fwd/l3fwd_em_sequential.h 
> b/examples/l3fwd/l3fwd_em_sequential.h
> index 3a40b2e434..f2c6ceb7c0 100644
> --- a/examples/l3fwd/l3fwd_em_sequential.h
> +++ b/examples/l3fwd/l3fwd_em_sequential.h
> @@ -81,20 +81,19 @@ l3fwd_em_send_packets(int nb_rx, struct rte_mbuf 
> **pkts_burst,
>       int32_t i, j;
>       uint16_t dst_port[SENDM_PORT_OVERHEAD(MAX_PKT_BURST)];
> 
> -     if (nb_rx > 0) {
> -             rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[0],
> +     for (i = 0; i < prefetch_offset && i < nb_rx; i++)
> +             rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i],
>                                              struct rte_ether_hdr *) + 1);
> -     }
> 
> -     for (i = 1, j = 0; j < nb_rx; i++, j++) {
> -             if (i < nb_rx) {
> -                     rte_prefetch0(rte_pktmbuf_mtod(
> -                                     pkts_burst[i],
> -                                     struct rte_ether_hdr *) + 1);
> -             }
> +     for (j = 0; j < nb_rx - prefetch_offset; j++) {
> +             rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[j + prefetch_offset],
> +                                            struct rte_ether_hdr *) + 1);
>               dst_port[j] = em_get_dst_port(qconf, pkts_burst[j], portid);
>       }
> 
> +     for (; j < nb_rx; j++)
> +             dst_port[j] = em_get_dst_port(qconf, pkts_burst[j], portid);
> +
>       send_packets_multi(qconf, pkts_burst, dst_port, nb_rx);
>  }
> 
> @@ -106,20 +105,26 @@ static inline void
>  l3fwd_em_process_events(int nb_rx, struct rte_event **events,
>                    struct lcore_conf *qconf)
>  {
> +     struct rte_mbuf *mbuf;
> +     uint16_t port;
>       int32_t i, j;
> 
> -     rte_prefetch0(rte_pktmbuf_mtod(events[0]->mbuf,
> -                   struct rte_ether_hdr *) + 1);
> +     for (i = 0; i < prefetch_offset && i < nb_rx; i++)
> +             rte_prefetch0(rte_pktmbuf_mtod(events[i]->mbuf, struct 
> rte_ether_hdr *) + 1);
> 
> -     for (i = 1, j = 0; j < nb_rx; i++, j++) {
> -             struct rte_mbuf *mbuf = events[j]->mbuf;
> -             uint16_t port;
> +     for (j = 0; j < nb_rx - prefetch_offset; j++) {
> +             rte_prefetch0(rte_pktmbuf_mtod(events[j + 
> prefetch_offset]->mbuf,
> +                                            struct rte_ether_hdr *) + 1);
> +             mbuf = events[j]->mbuf;
> +             port = mbuf->port;
> +             mbuf->port = em_get_dst_port(qconf, mbuf, mbuf->port);
> +             process_packet(mbuf, &mbuf->port);
> +             if (mbuf->port == BAD_PORT)
> +                     mbuf->port = port;
> +     }
> 
> -             if (i < nb_rx) {
> -                     rte_prefetch0(rte_pktmbuf_mtod(
> -                                     events[i]->mbuf,
> -                                     struct rte_ether_hdr *) + 1);
> -             }
> +     for (; j < nb_rx; j++) {
> +             mbuf = events[j]->mbuf;
>               port = mbuf->port;
>               mbuf->port = em_get_dst_port(qconf, mbuf, mbuf->port);
>               process_packet(mbuf, &mbuf->port);
> @@ -136,17 +141,22 @@ l3fwd_em_process_event_vector(struct rte_event_vector 
> *vec,
>       struct rte_mbuf **mbufs = vec->mbufs;
>       int32_t i, j;
> 
> -     rte_prefetch0(rte_pktmbuf_mtod(mbufs[0], struct rte_ether_hdr *) + 1);
> +     for (i = 0; i < prefetch_offset && i < vec->nb_elem; i++)
> +             rte_prefetch0(rte_pktmbuf_mtod(mbufs[i], struct rte_ether_hdr 
> *) + 1);
> 
> -     for (i = 0, j = 1; i < vec->nb_elem; i++, j++) {
> -             if (j < vec->nb_elem)
> -                     rte_prefetch0(rte_pktmbuf_mtod(mbufs[j],
> -                                                    struct rte_ether_hdr *) +
> -                                   1);
> +     for (i = 0; i < vec->nb_elem - prefetch_offset; i++) {
> +             rte_prefetch0(rte_pktmbuf_mtod(mbufs[i + prefetch_offset],
> +                                            struct rte_ether_hdr *) + 1);
>               dst_ports[i] = em_get_dst_port(qconf, mbufs[i],
>                                              attr_valid ? vec->port :
>                                                           mbufs[i]->port);
>       }
> +
> +     for (; i < vec->nb_elem; i++)
> +             dst_ports[i] = em_get_dst_port(qconf, mbufs[i],
> +                                            attr_valid ? vec->port :
> +                                                         mbufs[i]->port);
> +
>       j = RTE_ALIGN_FLOOR(vec->nb_elem, FWDSTEP);
> 
>       for (i = 0; i != j; i += FWDSTEP)
> diff --git a/examples/l3fwd/l3fwd_fib.c b/examples/l3fwd/l3fwd_fib.c
> index 82f1739df7..25192611c5 100644
> --- a/examples/l3fwd/l3fwd_fib.c
> +++ b/examples/l3fwd/l3fwd_fib.c
> @@ -24,9 +24,6 @@
>  #include "l3fwd_event.h"
>  #include "l3fwd_route.h"
> 
> -/* Configure how many packets ahead to prefetch for fib. */
> -#define FIB_PREFETCH_OFFSET 4
> -
>  /* A non-existent portid is needed to denote a default hop for fib. */
>  #define FIB_DEFAULT_HOP 999
> 
> @@ -130,14 +127,14 @@ fib_send_packets(int nb_rx, struct rte_mbuf 
> **pkts_burst,
>       int32_t i;
> 
>       /* Prefetch first packets. */
> -     for (i = 0; i < FIB_PREFETCH_OFFSET && i < nb_rx; i++)
> +     for (i = 0; i < prefetch_offset && i < nb_rx; i++)
>               rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i], void *));
> 
>       /* Parse packet info and prefetch. */
> -     for (i = 0; i < (nb_rx - FIB_PREFETCH_OFFSET); i++) {
> +     for (i = 0; i < (nb_rx - prefetch_offset); i++) {
>               /* Prefetch packet. */
>               rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[
> -                             i + FIB_PREFETCH_OFFSET], void *));
> +                             i + prefetch_offset], void *));
>               fib_parse_packet(pkts_burst[i],
>                               &ipv4_arr[ipv4_cnt], &ipv4_cnt,
>                               &ipv6_arr[ipv6_cnt], &ipv6_cnt,
> @@ -302,11 +299,11 @@ fib_event_loop(struct l3fwd_event_resources *evt_rsrc,
>               ipv6_arr_assem = 0;
> 
>               /* Prefetch first packets. */
> -             for (i = 0; i < FIB_PREFETCH_OFFSET && i < nb_deq; i++)
> +             for (i = 0; i < prefetch_offset && i < nb_deq; i++)
>                       rte_prefetch0(rte_pktmbuf_mtod(events[i].mbuf, void *));
> 
>               /* Parse packet info and prefetch. */
> -             for (i = 0; i < (nb_deq - FIB_PREFETCH_OFFSET); i++) {
> +             for (i = 0; i < (nb_deq - prefetch_offset); i++) {
>                       if (flags & L3FWD_EVENT_TX_ENQ) {
>                               events[i].queue_id = tx_q_id;
>                               events[i].op = RTE_EVENT_OP_FORWARD;
> @@ -318,7 +315,7 @@ fib_event_loop(struct l3fwd_event_resources *evt_rsrc,
> 
>                       /* Prefetch packet. */
>                       rte_prefetch0(rte_pktmbuf_mtod(events[
> -                                     i + FIB_PREFETCH_OFFSET].mbuf,
> +                                     i + prefetch_offset].mbuf,
>                                       void *));
> 
>                       fib_parse_packet(events[i].mbuf,
> @@ -455,12 +452,12 @@ fib_process_event_vector(struct rte_event_vector *vec, 
> uint8_t *type_arr,
>       ipv6_arr_assem = 0;
> 
>       /* Prefetch first packets. */
> -     for (i = 0; i < FIB_PREFETCH_OFFSET && i < vec->nb_elem; i++)
> +     for (i = 0; i < prefetch_offset && i < vec->nb_elem; i++)
>               rte_prefetch0(rte_pktmbuf_mtod(mbufs[i], void *));
> 
>       /* Parse packet info and prefetch. */
> -     for (i = 0; i < (vec->nb_elem - FIB_PREFETCH_OFFSET); i++) {
> -             rte_prefetch0(rte_pktmbuf_mtod(mbufs[i + FIB_PREFETCH_OFFSET],
> +     for (i = 0; i < (vec->nb_elem - prefetch_offset); i++) {
> +             rte_prefetch0(rte_pktmbuf_mtod(mbufs[i + prefetch_offset],
>                                              void *));
>               fib_parse_packet(mbufs[i], &ipv4_arr[ipv4_cnt], &ipv4_cnt,
>                                &ipv6_arr[ipv6_cnt], &ipv6_cnt, &type_arr[i]);
> diff --git a/examples/l3fwd/l3fwd_lpm.h b/examples/l3fwd/l3fwd_lpm.h
> index 4ee61e8d88..d81aa2efaf 100644
> --- a/examples/l3fwd/l3fwd_lpm.h
> +++ b/examples/l3fwd/l3fwd_lpm.h
> @@ -82,13 +82,13 @@ l3fwd_lpm_no_opt_send_packets(int nb_rx, struct rte_mbuf 
> **pkts_burst,
>       int32_t j;
> 
>       /* Prefetch first packets */
> -     for (j = 0; j < PREFETCH_OFFSET && j < nb_rx; j++)
> +     for (j = 0; j < prefetch_offset && j < nb_rx; j++)
>               rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[j], void *));
> 
>       /* Prefetch and forward already prefetched packets. */
> -     for (j = 0; j < (nb_rx - PREFETCH_OFFSET); j++) {
> +     for (j = 0; j < (nb_rx - prefetch_offset); j++) {
>               rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[
> -                             j + PREFETCH_OFFSET], void *));
> +                             j + prefetch_offset], void *));
>               l3fwd_lpm_simple_forward(pkts_burst[j], portid, qconf);
>       }
> 
> diff --git a/examples/l3fwd/l3fwd_lpm_neon.h b/examples/l3fwd/l3fwd_lpm_neon.h
> index 3c1f827424..5570a11687 100644
> --- a/examples/l3fwd/l3fwd_lpm_neon.h
> +++ b/examples/l3fwd/l3fwd_lpm_neon.h
> @@ -85,23 +85,20 @@ l3fwd_lpm_process_packets(int nb_rx, struct rte_mbuf 
> **pkts_burst,
>                         uint16_t portid, uint16_t *dst_port,
>                         struct lcore_conf *qconf, const uint8_t do_step3)
>  {
> -     int32_t i = 0, j = 0;
> +     int32_t i = 0, j = 0, pos = 0;
>       int32x4_t dip;
>       uint32_t ipv4_flag;
>       const int32_t k = RTE_ALIGN_FLOOR(nb_rx, FWDSTEP);
>       const int32_t m = nb_rx % FWDSTEP;
> 
>       if (k) {
> -             for (i = 0; i < FWDSTEP; i++) {
> -                     rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i],
> -                                                     void *));
> -             }
> -             for (j = 0; j != k - FWDSTEP; j += FWDSTEP) {
> -                     for (i = 0; i < FWDSTEP; i++) {
> -                             rte_prefetch0(rte_pktmbuf_mtod(
> -                                             pkts_burst[j + i + FWDSTEP],
> -                                             void *));
> -                     }
> +             for (i = 0; i < prefetch_offset && i < k; i++)
> +                     rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[i], void *));
> +
> +             for (j = 0; j != k; j += FWDSTEP) {
> +                     for (i = 0, pos = j + prefetch_offset;
> +                          i < FWDSTEP && pos < k; i++, pos++)
> +                             rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[pos], 
> void *));
> 
>                       processx4_step1(&pkts_burst[j], &dip, &ipv4_flag);
>                       processx4_step2(qconf, dip, ipv4_flag, portid,
> @@ -109,35 +106,9 @@ l3fwd_lpm_process_packets(int nb_rx, struct rte_mbuf 
> **pkts_burst,
>                       if (do_step3)
>                               processx4_step3(&pkts_burst[j], &dst_port[j]);
>               }
> -
> -             processx4_step1(&pkts_burst[j], &dip, &ipv4_flag);
> -             processx4_step2(qconf, dip, ipv4_flag, portid, &pkts_burst[j],
> -                             &dst_port[j]);
> -             if (do_step3)
> -                     processx4_step3(&pkts_burst[j], &dst_port[j]);
> -
> -             j += FWDSTEP;
>       }
> 
>       if (m) {
> -             /* Prefetch last up to 3 packets one by one */
> -             switch (m) {
> -             case 3:
> -                     rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[j],
> -                                                     void *));
> -                     j++;
> -                     /* fallthrough */
> -             case 2:
> -                     rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[j],
> -                                                     void *));
> -                     j++;
> -                     /* fallthrough */
> -             case 1:
> -                     rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[j],
> -                                                     void *));
> -                     j++;
> -             }
> -             j -= m;
>               /* Classify last up to 3 packets one by one */
>               switch (m) {
>               case 3:
> diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
> index 994b7dd8e5..0920c0b2f6 100644
> --- a/examples/l3fwd/main.c
> +++ b/examples/l3fwd/main.c
> @@ -59,6 +59,7 @@ uint16_t nb_rxd = RX_DESC_DEFAULT;
>  uint16_t nb_txd = TX_DESC_DEFAULT;
>  uint32_t nb_pkt_per_burst = DEFAULT_PKT_BURST;
>  uint32_t mb_mempool_cache_size = MEMPOOL_CACHE_SIZE;
> +uint16_t prefetch_offset = DEFAULT_PREFECH_OFFSET;
> 
>  /**< Ports set in promiscuous mode off by default. */
>  static int promiscuous_on;
> @@ -769,6 +770,7 @@ static const char short_options[] =
>  #define CMD_LINE_OPT_ALG "alg"
>  #define CMD_LINE_OPT_PKT_BURST "burst"
>  #define CMD_LINE_OPT_MB_CACHE_SIZE "mbcache"
> +#define CMD_PREFETCH_OFFSET "prefetch-offset"
> 
>  enum {
>       /* long options mapped to a short option */
> @@ -800,6 +802,7 @@ enum {
>       CMD_LINE_OPT_VECTOR_TMO_NS_NUM,
>       CMD_LINE_OPT_PKT_BURST_NUM,
>       CMD_LINE_OPT_MB_CACHE_SIZE_NUM,
> +     CMD_PREFETCH_OFFSET_NUM,
>  };
> 
>  static const struct option lgopts[] = {
> @@ -828,6 +831,7 @@ static const struct option lgopts[] = {
>       {CMD_LINE_OPT_ALG,   1, 0, CMD_LINE_OPT_ALG_NUM},
>       {CMD_LINE_OPT_PKT_BURST,   1, 0, CMD_LINE_OPT_PKT_BURST_NUM},
>       {CMD_LINE_OPT_MB_CACHE_SIZE,   1, 0, CMD_LINE_OPT_MB_CACHE_SIZE_NUM},
> +     {CMD_PREFETCH_OFFSET,   1, 0, CMD_PREFETCH_OFFSET_NUM},
>       {NULL, 0, 0, 0}
>  };
> 
> @@ -1017,6 +1021,9 @@ parse_args(int argc, char **argv)
>               case CMD_LINE_OPT_ALG_NUM:
>                       l3fwd_set_alg(optarg);
>                       break;
> +             case CMD_PREFETCH_OFFSET_NUM:
> +                     prefetch_offset = strtol(optarg, NULL, 10);

Hmm... might be something like parse_max_pkt_len() is doing, to be more robust?
In fact, probably can re-use the same function, might be just name it in a more 
generic way.
 

> +                     break;
>               default:
>                       print_usage(prgname);
>                       return -1;
> @@ -1054,6 +1061,13 @@ parse_args(int argc, char **argv)
>       }
>  #endif
> 
> +     if (prefetch_offset > nb_pkt_per_burst) {
> +             fprintf(stderr, "Prefetch offset (%u) cannot be greater than 
> burst size (%u). "
> +                     "Using burst size %u.\n",
> +                     prefetch_offset, nb_pkt_per_burst, nb_pkt_per_burst);
> +             prefetch_offset = nb_pkt_per_burst;

Might be just print err message and terminate gracefully? 

> +     }
> +
>       /*
>        * Nothing is selected, pick longest-prefix match
>        * as default match.
> --
> 2.33.0

Reply via email to