DPDK patches and discussions
 help / color / mirror / Atom feed
From: David Marchand <david.marchand@redhat.com>
To: Ori Kam <orika@nvidia.com>
Cc: "dev@dpdk.org" <dev@dpdk.org>,
	 "NBU-Contact-Thomas Monjalon (EXTERNAL)" <thomas@monjalon.net>,
	"i.maximets@ovn.org" <i.maximets@ovn.org>,
	 Aman Singh <aman.deep.singh@intel.com>,
	Yuying Zhang <yuying.zhang@intel.com>,
	 Matan Azrad <matan@nvidia.com>,
	Slava Ovsiienko <viacheslavo@nvidia.com>,
	 Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>,
	Ferruh Yigit <ferruh.yigit@amd.com>
Subject: Re: [RFC PATCH] ethdev: advertise flow restore in mbuf
Date: Wed, 24 May 2023 20:44:54 +0200	[thread overview]
Message-ID: <CAJFAV8xqBfzZFS5_qgS51T-RRNORiEZaEk=zzMCFKmROe2vfsg@mail.gmail.com> (raw)
In-Reply-To: <MW2PR12MB4666959A1BDA60D39B91AB6CD6419@MW2PR12MB4666.namprd12.prod.outlook.com>

Hello Ori,

On Wed, May 24, 2023 at 6:00 PM Ori Kam <orika@nvidia.com> wrote:
> > As reported by Ilya [1], unconditionally calling
> > rte_flow_get_restore_info() impacts an application performance for drivers
> > that do not provide this ops.
> > It could also impact processing of packets that require no call to
> > rte_flow_get_restore_info() at all.
> >
> > Advertise in mbuf (via a dynamic flag) whether the driver has more
> > metadata to provide via rte_flow_get_restore_info().
> > The application can then call it only when required.
> >
> > Link: http://inbox.dpdk.org/dev/5248c2ca-f2a6-3fb0-38b8-
> > 7f659bfa40de@ovn.org/
> > Signed-off-by: David Marchand <david.marchand@redhat.com>
> > ---
> > Note: I did not test this RFC patch yet but I hope we can resume and
> > maybe conclude on the discussion for the tunnel offloading API.
> >
>
> I think your approach has a good base but what happens if
> it is not relevant for all flows? In this case your solution will not work.

Sorry, I am not following.
Could you develop?


>
> In any case I think there are some issues with the implementation.
>
>
> > ---
> >  app/test-pmd/util.c              |  9 +++++----
> >  drivers/net/mlx5/linux/mlx5_os.c | 14 ++++++++++----
> >  drivers/net/mlx5/mlx5.h          |  3 ++-
> >  drivers/net/mlx5/mlx5_flow.c     | 26 ++++++++++++++++++++------
> >  drivers/net/mlx5/mlx5_rx.c       |  2 +-
> >  drivers/net/mlx5/mlx5_rx.h       |  1 +
> >  drivers/net/mlx5/mlx5_trigger.c  |  4 ++--
> >  drivers/net/sfc/sfc_dp.c         |  9 ++-------
> >  lib/ethdev/ethdev_driver.h       |  8 ++++++++
> >  lib/ethdev/rte_flow.c            | 29 +++++++++++++++++++++++++++++
> >  lib/ethdev/rte_flow.h            | 19 ++++++++++++++++++-
> >  lib/ethdev/version.map           |  4 ++++
> >  12 files changed, 102 insertions(+), 26 deletions(-)
> >
> > diff --git a/app/test-pmd/util.c b/app/test-pmd/util.c
> > index f9df5f69ef..5aa69ed545 100644
> > --- a/app/test-pmd/util.c
> > +++ b/app/test-pmd/util.c
> > @@ -88,18 +88,20 @@ dump_pkt_burst(uint16_t port_id, uint16_t queue,
> > struct rte_mbuf *pkts[],
> >       char print_buf[MAX_STRING_LEN];
> >       size_t buf_size = MAX_STRING_LEN;
> >       size_t cur_len = 0;
> > +     uint64_t restore_info_dynflag;
> >
> >       if (!nb_pkts)
> >               return;
> > +     restore_info_dynflag = rte_flow_restore_info_dynflag();
> >       MKDUMPSTR(print_buf, buf_size, cur_len,
> >                 "port %u/queue %u: %s %u packets\n", port_id, queue,
> >                 is_rx ? "received" : "sent", (unsigned int) nb_pkts);
> >       for (i = 0; i < nb_pkts; i++) {
> > -             int ret;
> >               struct rte_flow_error error;
> >               struct rte_flow_restore_info info = { 0, };
> >
> >               mb = pkts[i];
> > +             ol_flags = mb->ol_flags;
> >               if (rxq_share > 0)
> >                       MKDUMPSTR(print_buf, buf_size, cur_len, "port %u, ",
> >                                 mb->port);
> > @@ -107,8 +109,8 @@ dump_pkt_burst(uint16_t port_id, uint16_t queue,
> > struct rte_mbuf *pkts[],
> >               eth_type = RTE_BE_TO_CPU_16(eth_hdr->ether_type);
> >               packet_type = mb->packet_type;
> >               is_encapsulation = RTE_ETH_IS_TUNNEL_PKT(packet_type);
> > -             ret = rte_flow_get_restore_info(port_id, mb, &info, &error);
> > -             if (!ret) {
> > +             if ((ol_flags & restore_info_dynflag) != 0 &&
> > +                             rte_flow_get_restore_info(port_id, mb, &info,
> > &error) == 0) {
> >                       MKDUMPSTR(print_buf, buf_size, cur_len,
> >                                 "restore info:");
> >                       if (info.flags & RTE_FLOW_RESTORE_INFO_TUNNEL) {
> > @@ -153,7 +155,6 @@ dump_pkt_burst(uint16_t port_id, uint16_t queue,
> > struct rte_mbuf *pkts[],
> >                         " - pool=%s - type=0x%04x - length=%u -
> > nb_segs=%d",
> >                         mb->pool->name, eth_type, (unsigned int) mb-
> > >pkt_len,
> >                         (int)mb->nb_segs);
> > -             ol_flags = mb->ol_flags;
> >               if (ol_flags & RTE_MBUF_F_RX_RSS_HASH) {
> >                       MKDUMPSTR(print_buf, buf_size, cur_len,
> >                                 " - RSS hash=0x%x",
> > diff --git a/drivers/net/mlx5/linux/mlx5_os.c
> > b/drivers/net/mlx5/linux/mlx5_os.c
> > index 980234e2ac..e6e3784013 100644
> > --- a/drivers/net/mlx5/linux/mlx5_os.c
> > +++ b/drivers/net/mlx5/linux/mlx5_os.c
> > @@ -575,11 +575,17 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv)
> >               goto error;
> >       }
> >  #endif
> > -     if (!sh->tunnel_hub && sh->config.dv_miss_info)
> > +     if (!sh->tunnel_hub && sh->config.dv_miss_info) {
> > +             err = mlx5_flow_restore_info_register();
> > +             if (err) {
> > +                     DRV_LOG(ERR, "Could not register mbuf dynflag for
> > rte_flow_get_restore_info");
> > +                     goto error;
> > +             }
> >               err = mlx5_alloc_tunnel_hub(sh);
> > -     if (err) {
> > -             DRV_LOG(ERR, "mlx5_alloc_tunnel_hub failed err=%d", err);
> > -             goto error;
> > +             if (err) {
> > +                     DRV_LOG(ERR, "mlx5_alloc_tunnel_hub failed
> > err=%d", err);
> > +                     goto error;
> > +             }
> >       }
> >       if (sh->config.reclaim_mode == MLX5_RCM_AGGR) {
> >               mlx5_glue->dr_reclaim_domain_memory(sh->rx_domain, 1);
> > diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
> > index 9eae692037..77cdc802da 100644
> > --- a/drivers/net/mlx5/mlx5.h
> > +++ b/drivers/net/mlx5/mlx5.h
> > @@ -2116,7 +2116,8 @@ int mlx5_flow_query_counter(struct rte_eth_dev
> > *dev, struct rte_flow *flow,
> >  int mlx5_flow_dev_dump_ipool(struct rte_eth_dev *dev, struct rte_flow
> > *flow,
> >               FILE *file, struct rte_flow_error *error);
> >  #endif
> > -void mlx5_flow_rxq_dynf_metadata_set(struct rte_eth_dev *dev);
> > +int mlx5_flow_restore_info_register(void);
> > +void mlx5_flow_rxq_dynf_set(struct rte_eth_dev *dev);
> >  int mlx5_flow_get_aged_flows(struct rte_eth_dev *dev, void **contexts,
> >                       uint32_t nb_contexts, struct rte_flow_error *error);
> >  int mlx5_validate_action_ct(struct rte_eth_dev *dev,
> > diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
> > index d0275fdd00..715b7d327d 100644
> > --- a/drivers/net/mlx5/mlx5_flow.c
> > +++ b/drivers/net/mlx5/mlx5_flow.c
> > @@ -1779,6 +1779,20 @@ flow_rxq_flags_clear(struct rte_eth_dev *dev)
> >       priv->sh->shared_mark_enabled = 0;
> >  }
> >
> > +static uint64_t mlx5_restore_info_dynflag;
> > +
> > +int
> > +mlx5_flow_restore_info_register(void)
> > +{
> > +     int err = 0;
> > +
> > +     if (mlx5_restore_info_dynflag == 0) {
> > +             if
> > (rte_flow_restore_info_dynflag_register(&mlx5_restore_info_dynflag) < 0)
> > +                     err = ENOMEM;
> > +     }
> > +     return err;
> > +}
> > +
> >  /**
> >   * Set the Rx queue dynamic metadata (mask and offset) for a flow
> >   *
> > @@ -1786,7 +1800,7 @@ flow_rxq_flags_clear(struct rte_eth_dev *dev)
> >   *   Pointer to the Ethernet device structure.
> >   */
> >  void
> > -mlx5_flow_rxq_dynf_metadata_set(struct rte_eth_dev *dev)
> > +mlx5_flow_rxq_dynf_set(struct rte_eth_dev *dev)
>
> Why did you change the name?

This helper now prepares multiple dynamic flags.
If you have a better name.. ?


>
> >  {
> >       struct mlx5_priv *priv = dev->data->dev_private;
> >       unsigned int i;
> > @@ -1809,6 +1823,9 @@ mlx5_flow_rxq_dynf_metadata_set(struct
> > rte_eth_dev *dev)
> >                       data->flow_meta_offset =
> > rte_flow_dynf_metadata_offs;
> >                       data->flow_meta_port_mask = priv->sh-
> > >dv_meta_mask;
> >               }
> > +             data->mark_flag = RTE_MBUF_F_RX_FDIR_ID;
> > +             if (is_tunnel_offload_active(dev))
> > +                     data->mark_flag |= mlx5_restore_info_dynflag;
> >       }
> >  }
> >
> > @@ -11453,11 +11470,8 @@ mlx5_flow_tunnel_get_restore_info(struct
> > rte_eth_dev *dev,
> >       const struct mlx5_flow_tbl_data_entry *tble;
> >       const uint64_t mask = RTE_MBUF_F_RX_FDIR |
> > RTE_MBUF_F_RX_FDIR_ID;
> >
> > -     if (!is_tunnel_offload_active(dev)) {
> > -             info->flags = 0;
> > -             return 0;
> > -     }
> > -
> > +     if ((ol_flags & mlx5_restore_info_dynflag) == 0)
> > +             goto err;
> >       if ((ol_flags & mask) != mask)
> >               goto err;
> >       tble = tunnel_mark_decode(dev, m->hash.fdir.hi);
> > diff --git a/drivers/net/mlx5/mlx5_rx.c b/drivers/net/mlx5/mlx5_rx.c
> > index a2be523e9e..71c4638251 100644
> > --- a/drivers/net/mlx5/mlx5_rx.c
> > +++ b/drivers/net/mlx5/mlx5_rx.c
> > @@ -857,7 +857,7 @@ rxq_cq_to_mbuf(struct mlx5_rxq_data *rxq, struct
> > rte_mbuf *pkt,
> >               if (MLX5_FLOW_MARK_IS_VALID(mark)) {
> >                       pkt->ol_flags |= RTE_MBUF_F_RX_FDIR;
> >                       if (mark != RTE_BE32(MLX5_FLOW_MARK_DEFAULT)) {
> > -                             pkt->ol_flags |= RTE_MBUF_F_RX_FDIR_ID;
> > +                             pkt->ol_flags |= rxq->mark_flag;
> >                               pkt->hash.fdir.hi =
> > mlx5_flow_mark_get(mark);
> >                       }
> >               }
> > diff --git a/drivers/net/mlx5/mlx5_rx.h b/drivers/net/mlx5/mlx5_rx.h
> > index 52c35c83f8..3514edd84e 100644
> > --- a/drivers/net/mlx5/mlx5_rx.h
> > +++ b/drivers/net/mlx5/mlx5_rx.h
> > @@ -136,6 +136,7 @@ struct mlx5_rxq_data {
> >       struct mlx5_uar_data uar_data; /* CQ doorbell. */
> >       uint32_t cqn; /* CQ number. */
> >       uint8_t cq_arm_sn; /* CQ arm seq number. */
> > +     uint64_t mark_flag; /* ol_flags to set with marks. */
> >       uint32_t tunnel; /* Tunnel information. */
> >       int timestamp_offset; /* Dynamic mbuf field for timestamp. */
> >       uint64_t timestamp_rx_flag; /* Dynamic mbuf flag for timestamp. */
> > diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
> > index bbaa7d2aa0..7bdb897612 100644
> > --- a/drivers/net/mlx5/mlx5_trigger.c
> > +++ b/drivers/net/mlx5/mlx5_trigger.c
> > @@ -1282,8 +1282,8 @@ mlx5_dev_start(struct rte_eth_dev *dev)
> >                       dev->data->port_id);
> >               goto error;
> >       }
> > -     /* Set a mask and offset of dynamic metadata flows into Rx queues.
> > */
> > -     mlx5_flow_rxq_dynf_metadata_set(dev);
> > +     /* Set dynamic fields and flags into Rx queues. */
> > +     mlx5_flow_rxq_dynf_set(dev);
> >       /* Set flags and context to convert Rx timestamps. */
> >       mlx5_rxq_timestamp_set(dev);
> >       /* Set a mask and offset of scheduling on timestamp into Tx queues.
> > */
> > diff --git a/drivers/net/sfc/sfc_dp.c b/drivers/net/sfc/sfc_dp.c
> > index 9f2093b353..8b2dbea325 100644
> > --- a/drivers/net/sfc/sfc_dp.c
> > +++ b/drivers/net/sfc/sfc_dp.c
> > @@ -11,6 +11,7 @@
> >  #include <string.h>
> >  #include <errno.h>
> >
> > +#include <ethdev_driver.h>
> >  #include <rte_log.h>
> >  #include <rte_mbuf_dyn.h>
> >
> > @@ -135,12 +136,8 @@ sfc_dp_ft_ctx_id_register(void)
> >               .size = sizeof(uint8_t),
> >               .align = __alignof__(uint8_t),
> >       };
> > -     static const struct rte_mbuf_dynflag ft_ctx_id_valid = {
> > -             .name = "rte_net_sfc_dynflag_ft_ctx_id_valid",
> > -     };
> >
> >       int field_offset;
> > -     int flag;
> >
> >       SFC_GENERIC_LOG(INFO, "%s() entry", __func__);
> >
> > @@ -156,15 +153,13 @@ sfc_dp_ft_ctx_id_register(void)
> >               return -1;
> >       }
> >
> > -     flag = rte_mbuf_dynflag_register(&ft_ctx_id_valid);
> > -     if (flag < 0) {
> > +     if (rte_flow_restore_info_dynflag_register(&sfc_dp_ft_ctx_id_valid) <
> > 0) {
> >               SFC_GENERIC_LOG(ERR, "%s() failed to register ft_ctx_id
> > dynflag",
> >                               __func__);
> >               return -1;
> >       }
> >
> >       sfc_dp_ft_ctx_id_offset = field_offset;
> > -     sfc_dp_ft_ctx_id_valid = UINT64_C(1) << flag;
> >
> >       SFC_GENERIC_LOG(INFO, "%s() done", __func__);
> >
> > diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
> > index 2c9d615fb5..6c17d84d1b 100644
> > --- a/lib/ethdev/ethdev_driver.h
> > +++ b/lib/ethdev/ethdev_driver.h
> > @@ -1949,6 +1949,14 @@ __rte_internal
> >  int
> >  rte_eth_ip_reassembly_dynfield_register(int *field_offset, int *flag);
> >
> > +/**
> > + * @internal
> > + * Register mbuf dynamic flag for rte_flow_get_restore_info.
> > + */
> > +__rte_internal
> > +int
> > +rte_flow_restore_info_dynflag_register(uint64_t *flag);
> > +
> >
> >  /*
> >   * Legacy ethdev API used internally by drivers.
> > diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
> > index 69e6e749f7..10cd9d12ba 100644
> > --- a/lib/ethdev/rte_flow.c
> > +++ b/lib/ethdev/rte_flow.c
> > @@ -1401,6 +1401,35 @@ rte_flow_get_restore_info(uint16_t port_id,
> >                                 NULL, rte_strerror(ENOTSUP));
> >  }
> >
> > +static struct {
> > +     const struct rte_mbuf_dynflag desc;
> > +     uint64_t value;
> > +} flow_restore_info_dynflag = {
> > +     .desc = { .name = "RTE_MBUF_F_RX_RESTORE_INFO", },
> > +};
>
> Why not have this structure in the register function?

The dynamic flag value is resolved once, at register time.
The accessor below uses this symbol to skip a lookup.


>
> > +
> > +uint64_t
> > +rte_flow_restore_info_dynflag(void)
> > +{
> > +     return flow_restore_info_dynflag.value;
> > +}
> > +
> > +int
> > +rte_flow_restore_info_dynflag_register(uint64_t *flag)
> > +{
> > +     if (flow_restore_info_dynflag.value == 0) {
> > +             int offset =
> > rte_mbuf_dynflag_register(&flow_restore_info_dynflag.desc);
> > +
> > +             if (offset < 0)
> > +                     return -1;
> > +             flow_restore_info_dynflag.value = RTE_BIT64(offset);
> > +     }
> > +     if (*flag)
> > +             *flag = rte_flow_restore_info_dynflag();
> > +
> > +     return 0;
> > +}
> > +
> >  int
> >  rte_flow_tunnel_action_decap_release(uint16_t port_id,
> >                                    struct rte_flow_action *actions,

-- 
David Marchand


  reply	other threads:[~2023-05-24 18:45 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-05 10:31 David Marchand
2023-05-24 12:57 ` David Marchand
2023-05-24 16:00 ` Ori Kam
2023-05-24 18:44   ` David Marchand [this message]
2023-06-01  8:48     ` David Marchand
2023-06-01  9:31       ` Ori Kam
2023-06-01  9:43         ` David Marchand
2023-06-01 10:02           ` Ori Kam
2023-06-01 10:03             ` David Marchand
2023-06-14 16:46 ` Slava Ovsiienko
2023-06-15  8:00   ` David Marchand
2023-06-15 13:47 ` [RFC PATCH v2] " David Marchand
2023-06-19 12:20   ` Andrew Rybchenko
2023-06-19 13:57   ` Slava Ovsiienko
2023-06-20 10:04   ` Ali Alnubani
2023-06-20 11:10 ` [RFC PATCH v3] " David Marchand
2023-06-20 16:43   ` Slava Ovsiienko
2023-06-21  7:43     ` David Marchand
2023-06-21 12:53     ` Ori Kam
2023-06-21  7:47   ` Ali Alnubani
2023-06-21 14:43 ` [PATCH v4] " David Marchand
2023-06-21 18:52   ` Ferruh Yigit
2023-07-31 20:41   ` Ilya Maximets
2023-09-26  9:17     ` David Marchand
2023-09-26 19:49       ` Ilya Maximets

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAJFAV8xqBfzZFS5_qgS51T-RRNORiEZaEk=zzMCFKmROe2vfsg@mail.gmail.com' \
    --to=david.marchand@redhat.com \
    --cc=aman.deep.singh@intel.com \
    --cc=andrew.rybchenko@oktetlabs.ru \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@amd.com \
    --cc=i.maximets@ovn.org \
    --cc=matan@nvidia.com \
    --cc=orika@nvidia.com \
    --cc=thomas@monjalon.net \
    --cc=viacheslavo@nvidia.com \
    --cc=yuying.zhang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).