On Mon, 2022-06-20 at 12:12 +0200, Eelco Chaudron wrote:
> 
> On 27 May 2022, at 11:00, Jianbo Liu wrote:
> 
> > Add API to offload meter to HW, and the corresponding functions to
> > call
> > the meter callbacks from all the registered flow API providers.
> > The interfaces are like those related to meter in dpif_class, in
> > order
> > to pass necessary info to HW.
> > 
> > Signed-off-by: Jianbo Liu <[email protected]>
> > ---
> >  lib/netdev-offload-provider.h | 19 +++++++++++++
> >  lib/netdev-offload.c          | 51
> > +++++++++++++++++++++++++++++++++++
> >  lib/netdev-offload.h          |  8 ++++++
> >  3 files changed, 78 insertions(+)
> > 
> > diff --git a/lib/netdev-offload-provider.h b/lib/netdev-offload-
> > provider.h
> > index 8ff2de983..c3028606b 100644
> > --- a/lib/netdev-offload-provider.h
> > +++ b/lib/netdev-offload-provider.h
> > @@ -94,6 +94,25 @@ struct netdev_flow_api {
> >       * takes ownership of a packet if errno != EOPNOTSUPP. */
> >      int (*hw_miss_packet_recover)(struct netdev *, struct dp_packet
> > *);
> 
> Your code seems to assume that the stats structure is already
> initialized, this includes setting up all the possible bands, the
> stats->n_bands is also set up and should be used in your code (see also
> my comments on patch  6). If this is true, you can remove the max_band
> variable from all your callback.
> 

I think yes, because you can see my last patch. I check the return
value of dpif_netlink_meter_set__() before calling meter_offload_set().

static int
dpif_netlink_meter_set(struct dpif *dpif_, ofproto_meter_id meter_id,
                        struct ofputil_meter_config *config)
{
    ....

    err = dpif_netlink_meter_set__(dpif_, meter_id, config);
    if (!err && netdev_is_flow_api_enabled()) {
        meter_offload_set(meter_id, config);
    }

    return err;
}

In dpif_netlink_meter_set__(), we will check the band type.
So, if no err is returned from dpif_netlink_meter_set__(), we can
asssume that there is a drop band in the meter.  

And you are right about the max_band. I will remove it.

> If this is not the case, you should change your patch 6, to use the
> max_bands value and increase/update the n_bands if it's currently not
> set to 1.
> 
> > +    /* Offloads or modifies the offloaded meter in HW with the
> > given 'meter_id'
> > +     * and the configuration in 'config'.
> > +     *
> > +     * The meter id specified through 'config->meter_id' is
> > ignored. */
> > +    int (*meter_set)(ofproto_meter_id meter_id,
> > +                     struct ofputil_meter_config *config);
> > +
> > +    /* Queries HW for meter stats with the given 'meter_id'.
> > +     * Store the stats of dropped packets to band 0. */
> > +    int (*meter_get)(ofproto_meter_id meter_id,
> > +                     struct ofputil_meter_stats *stats,
> > +                     uint16_t max_bands);
> > +
> > +    /* Removes meter 'meter_id' from HW. Stores meter statistics
> > if successful.
> > +     * 'stats' may be passed in as NULL if no stats are needed. */
> > +    int (*meter_del)(ofproto_meter_id meter_id,
> > +                     struct ofputil_meter_stats *stats,
> > +                     uint16_t max_bands);
> > +
> 
> I was hoping for some more details on the API, stats and return
> values.
> What about the following change?

Yes, I will change as you suggested. Thanks.

> 
> diff --git a/lib/netdev-offload-provider.h b/lib/netdev-offload-
> provider.h
> index c3028606b..9d78fd953 100644
> --- a/lib/netdev-offload-provider.h
> +++ b/lib/netdev-offload-provider.h
> @@ -95,20 +95,31 @@ struct netdev_flow_api {
>      int (*hw_miss_packet_recover)(struct netdev *, struct dp_packet
> *);
> 
>      /* Offloads or modifies the offloaded meter in HW with the given
> 'meter_id'
> -     * and the configuration in 'config'.
> +     * and the configuration in 'config'. On failure, a non-zero
> error code is
> +     * returned.
>       *
>       * The meter id specified through 'config->meter_id' is ignored.
> */
>      int (*meter_set)(ofproto_meter_id meter_id,
>                       struct ofputil_meter_config *config);
> 
> -    /* Queries HW for meter stats with the given 'meter_id'.
> -     * Store the stats of dropped packets to band 0. */
> +    /* Queries HW for meter stats with the given 'meter_id'. Store
> the stats
> +     * of dropped packets to band 0. On failure, a non-zero error
> code is
> +     * returned.
> +     *
> +     * Note that the 'stats' structure is already initialized, and
> only the
> +     * available statistics should be incremented, not replaced.
> Those fields
> +     * are packet_in_count, byte_in_count and band[]->byte_count and
> +     * band[]->packet_count. */
>      int (*meter_get)(ofproto_meter_id meter_id,
>                       struct ofputil_meter_stats *stats,
>                       uint16_t max_bands);
> 
> -    /* Removes meter 'meter_id' from HW. Stores meter statistics if
> successful.
> -     * 'stats' may be passed in as NULL if no stats are needed. */
> +    /* Removes meter 'meter_id' from HW. Store the stats of dropped
> packets to
> +     * band 0. On failure, a non-zero error code is returned.
> +     *
> +     * 'stats' may be passed in as NULL if no stats are needed, See
> the above
> +     * function for additional details on the 'stats' usage. */
>      int (*meter_del)(ofproto_meter_id meter_id,
>                       struct ofputil_meter_stats *stats,
>                       uint16_t max_bands);
> 
> >      /* Initializies the netdev flow api.
> >       * Return 0 if successful, otherwise returns a positive errno
> > value. */
> >      int (*init_flow_api)(struct netdev *);
> > diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c
> > index fb108c0d5..e853b4e2a 100644
> > --- a/lib/netdev-offload.c
> > +++ b/lib/netdev-offload.c
> > @@ -58,6 +58,7 @@
> >  VLOG_DEFINE_THIS_MODULE(netdev_offload);
> > 
> > 
> > +static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
> >  static bool netdev_flow_api_enabled = false;
> > 
> >  #define DEFAULT_OFFLOAD_THREAD_NB 1
> > @@ -195,6 +196,56 @@ netdev_assign_flow_api(struct netdev *netdev)
> >      return -1;
> >  }
> > 
> > +int
> > +meter_offload_set(ofproto_meter_id meter_id,
> > +                  struct ofputil_meter_config *config)
> > +{
> > +    struct netdev_registered_flow_api *rfa;
> > +
> > +    CMAP_FOR_EACH (rfa, cmap_node, &netdev_flow_apis) {
> > +        if (rfa->flow_api->meter_set) {
> > +            int ret = rfa->flow_api->meter_set(meter_id, config);
> > +            if (ret) {
> > +                VLOG_DBG_RL(&rl,
> > +                            "Failed setting meter for flow api %s,
> > error %d",
> > +                            rfa->flow_api->type, ret);
> 
> Thanks for adding this, assumed you would be adding it to the other
> two functions also.

Sure, will do. Thanks!

> In addition, I added the meter ID to the message. For example:
> diff --git a/lib/netdev-offload.c b/lib/netdev-offload.c
> index e853b4e2a..104870383 100644
> --- a/lib/netdev-offload.c
> +++ b/lib/netdev-offload.c
> @@ -206,9 +206,9 @@ meter_offload_set(ofproto_meter_id meter_id,
>          if (rfa->flow_api->meter_set) {
>              int ret = rfa->flow_api->meter_set(meter_id, config);
>              if (ret) {
> -                VLOG_DBG_RL(&rl,
> -                            "Failed setting meter for flow api %s,
> error %d",
> -                            rfa->flow_api->type, ret);
> +                VLOG_DBG_RL(&rl, "Failed setting meter %u for flow
> api %s, "
> +                            "error %d", meter_id.uint32, rfa-
> >flow_api->type,
> +                            ret);
>             }
>          }
>      }
> @@ -224,7 +224,12 @@ meter_offload_get(ofproto_meter_id meter_id,
> 
>      CMAP_FOR_EACH (rfa, cmap_node, &netdev_flow_apis) {
>          if (rfa->flow_api->meter_get) {
> -            rfa->flow_api->meter_get(meter_id, stats, max_bands);
> +            int ret = rfa->flow_api->meter_get(meter_id, stats,
> max_bands);
> +            if (ret) {
> +                VLOG_DBG_RL(&rl, "Failed getting meter %u for flow
> api %s, "
> +                            "error %d", meter_id.uint32, rfa-
> >flow_api->type,
> +                            ret);
> +           }
>          }
>      }
> 
> @@ -239,7 +244,12 @@ meter_offload_del(ofproto_meter_id meter_id,
> 
>      CMAP_FOR_EACH (rfa, cmap_node, &netdev_flow_apis) {
>          if (rfa->flow_api->meter_del) {
> -            rfa->flow_api->meter_del(meter_id, stats, max_bands);
> +            int ret = rfa->flow_api->meter_del(meter_id, stats,
> max_bands);
> +            if (ret) {
> +                VLOG_DBG_RL(&rl, "Failed deleting meter %u for flow
> api %s, "
> +                            "error %d", meter_id.uint32, rfa-
> >flow_api->type,
> +                            ret);
> +            }
>          }
>      }
> 
> 
> > +           }
> > +        }
> > +    }
> > +
> > +    return 0;
> > +}
> > +
> > +int
> > +meter_offload_get(ofproto_meter_id meter_id,
> > +                  struct ofputil_meter_stats *stats, uint16_t
> > max_bands)
> > +{
> > +    struct netdev_registered_flow_api *rfa;
> > +
> > +    CMAP_FOR_EACH (rfa, cmap_node, &netdev_flow_apis) {
> > +        if (rfa->flow_api->meter_get) {
> > +            rfa->flow_api->meter_get(meter_id, stats, max_bands);
> > +        }
> > +    }
> > +
> > +    return 0;
> > +}
> > +
> > +int
> > +meter_offload_del(ofproto_meter_id meter_id,
> > +                  struct ofputil_meter_stats *stats, uint16_t
> > max_bands)
> > +{
> > +    struct netdev_registered_flow_api *rfa;
> > +
> > +    CMAP_FOR_EACH (rfa, cmap_node, &netdev_flow_apis) {
> > +        if (rfa->flow_api->meter_del) {
> > +            rfa->flow_api->meter_del(meter_id, stats, max_bands);
> > +        }
> > +    }
> > +
> > +    return 0;
> > +}
> > +
> >  int
> >  netdev_flow_flush(struct netdev *netdev)
> >  {
> > diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h
> > index 8237a85dd..a6d4ba3cb 100644
> > --- a/lib/netdev-offload.h
> > +++ b/lib/netdev-offload.h
> > @@ -22,6 +22,7 @@
> >  #include "openvswitch/types.h"
> >  #include "ovs-rcu.h"
> >  #include "ovs-thread.h"
> > +#include "openvswitch/ofp-meter.h"
> >  #include "packets.h"
> >  #include "flow.h"
> > 
> > @@ -158,6 +159,13 @@ int netdev_ports_flow_get(const char
> > *dpif_type, struct match *match,
> >  int netdev_ports_get_n_flows(const char *dpif_type,
> >                               odp_port_t port_no, uint64_t
> > *n_flows);
> > 
> > +int meter_offload_set(ofproto_meter_id,
> > +                      struct ofputil_meter_config *);
> > +int meter_offload_get(ofproto_meter_id,
> > +                      struct ofputil_meter_stats *, uint16_t);
> > +int meter_offload_del(ofproto_meter_id,
> > +                      struct ofputil_meter_stats *, uint16_t);
> > +
> >  #ifdef  __cplusplus
> >  }
> >  #endif
> > -- 
> > 2.26.2
> 

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

Reply via email to