On 15 Mar 2024, at 18:59, Eric Garver wrote:

> On Fri, Mar 15, 2024 at 12:37:54PM -0400, Eric Garver wrote:
>> On Fri, Mar 15, 2024 at 04:55:50PM +0100, Eelco Chaudron wrote:
>>>
>>>
>>> On 11 Mar 2024, at 18:51, Eric Garver wrote:
>>>
>>>> Kernel support has been added for this action. As such, we need to probe
>>>> the datapath for support.
>>>>
>>>> Signed-off-by: Eric Garver <e...@garver.life>
>>>
>>> Thanks for submitting the changes requested. Some comments below.
>>>
>>> Cheers,
>>>
>>> Eelco
>>>
>>>
>>>> ---
>>>>  include/linux/openvswitch.h |  2 +-
>>>>  lib/dpif.c                  |  6 ++-
>>>>  lib/dpif.h                  |  2 +-
>>>>  ofproto/ofproto-dpif.c      | 77 ++++++++++++++++++++++++++++++++++---
>>>>  ofproto/ofproto-dpif.h      |  4 +-
>>>>  5 files changed, 81 insertions(+), 10 deletions(-)
>>>>
>>>> diff --git a/include/linux/openvswitch.h b/include/linux/openvswitch.h
>>>> index a265e05ad253..fce6456f47c8 100644
>>>> --- a/include/linux/openvswitch.h
>>>> +++ b/include/linux/openvswitch.h
>>>> @@ -1086,11 +1086,11 @@ enum ovs_action_attr {
>>>>    OVS_ACTION_ATTR_CHECK_PKT_LEN, /* Nested OVS_CHECK_PKT_LEN_ATTR_*. */
>>>>    OVS_ACTION_ATTR_ADD_MPLS,     /* struct ovs_action_add_mpls. */
>>>>    OVS_ACTION_ATTR_DEC_TTL,      /* Nested OVS_DEC_TTL_ATTR_*. */
>>>> +  OVS_ACTION_ATTR_DROP,         /* u32 xlate_error. */
>>>>
>>>>  #ifndef __KERNEL__
>>>>    OVS_ACTION_ATTR_TUNNEL_PUSH,   /* struct ovs_action_push_tnl*/
>>>>    OVS_ACTION_ATTR_TUNNEL_POP,    /* u32 port number. */
>>>> -  OVS_ACTION_ATTR_DROP,          /* u32 xlate_error. */
>>>>    OVS_ACTION_ATTR_LB_OUTPUT,     /* u32 bond-id. */
>>>>  #endif
>>>>    __OVS_ACTION_ATTR_MAX,        /* Nothing past this will be accepted
>>>> diff --git a/lib/dpif.c b/lib/dpif.c
>>>> index 0f480bec48d0..23eb18495a66 100644
>>>> --- a/lib/dpif.c
>>>> +++ b/lib/dpif.c
>>>> @@ -28,6 +28,7 @@
>>>>  #include "dpctl.h"
>>>>  #include "dpif-netdev.h"
>>>>  #include "flow.h"
>>>> +#include "netdev-offload.h"
>>>>  #include "netdev-provider.h"
>>>>  #include "netdev.h"
>>>>  #include "netlink.h"
>>>> @@ -1935,9 +1936,10 @@ dpif_supports_tnl_push_pop(const struct dpif *dpif)
>>>>  }
>>>>
>>>>  bool
>>>> -dpif_supports_explicit_drop_action(const struct dpif *dpif)
>>>> +dpif_may_support_explicit_drop_action(const struct dpif *dpif)
>>>>  {
>>>> -    return dpif_is_netdev(dpif);
>>>> +    /* TC does not support offloading this action. */
>>>> +    return dpif_is_netdev(dpif) || !netdev_is_flow_api_enabled();
>>>>  }
>>>>
>>>>  bool
>>>> diff --git a/lib/dpif.h b/lib/dpif.h
>>>> index 0f2dc2ef3c55..a764e8a592bd 100644
>>>> --- a/lib/dpif.h
>>>> +++ b/lib/dpif.h
>>>> @@ -940,7 +940,7 @@ int dpif_get_pmds_for_port(const struct dpif * dpif, 
>>>> odp_port_t port_no,
>>>>
>>>>  char *dpif_get_dp_version(const struct dpif *);
>>>>  bool dpif_supports_tnl_push_pop(const struct dpif *);
>>>> -bool dpif_supports_explicit_drop_action(const struct dpif *);
>>>> +bool dpif_may_support_explicit_drop_action(const struct dpif *);
>>>>  bool dpif_synced_dp_layers(struct dpif *);
>>>>
>>>>  /* Log functions. */
>>>> diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
>>>> index 2ec1cd1854ab..7bacd2120c78 100644
>>>> --- a/ofproto/ofproto-dpif.c
>>>> +++ b/ofproto/ofproto-dpif.c
>>>> @@ -221,6 +221,7 @@ static void ct_zone_config_init(struct dpif_backer 
>>>> *backer);
>>>>  static void ct_zone_config_uninit(struct dpif_backer *backer);
>>>>  static void ct_zone_timeout_policy_sweep(struct dpif_backer *backer);
>>>>  static void ct_zone_limits_commit(struct dpif_backer *backer);
>>>> +static bool recheck_support_explicit_drop_action(struct dpif_backer 
>>>> *backer);
>>>>
>>>>  static inline struct ofproto_dpif *
>>>>  ofproto_dpif_cast(const struct ofproto *ofproto)
>>>> @@ -391,6 +392,10 @@ type_run(const char *type)
>>>>          udpif_set_threads(backer->udpif, n_handlers, n_revalidators);
>>>>      }
>>>>
>>>> +    if (recheck_support_explicit_drop_action(backer)) {
>>>> +        backer->need_revalidate = REV_RECONFIGURE;
>>>> +    }
>>>> +
>>>>      if (backer->need_revalidate) {
>>>>          struct ofproto_dpif *ofproto;
>>>>          struct simap_node *node;
>>>> @@ -807,6 +812,7 @@ open_dpif_backer(const char *type, struct dpif_backer 
>>>> **backerp)
>>>>
>>>>      shash_add(&all_dpif_backers, type, backer);
>>>>
>>>> +    atomic_init(&backer->rt_support.explicit_drop_action, false);
>>>>      check_support(backer);
>>>>      atomic_count_init(&backer->tnl_count, 0);
>>>>
>>>> @@ -855,7 +861,10 @@ ovs_native_tunneling_is_on(struct ofproto_dpif 
>>>> *ofproto)
>>>>  bool
>>>>  ovs_explicit_drop_action_supported(struct ofproto_dpif *ofproto)
>>>>  {
>>>> -    return ofproto->backer->rt_support.explicit_drop_action;
>>>> +    bool value;
>>>
>>> nit: I would add a new line here.
>>
>> ACK.
>>
>>>> +    atomic_read_relaxed(&ofproto->backer->rt_support.explicit_drop_action,
>>>> +                        &value);
>>>> +    return value;
>>>>  }
>>>>
>>>>  bool
>>>> @@ -1379,6 +1388,41 @@ check_ct_timeout_policy(struct dpif_backer *backer)
>>>>      return !error;
>>>>  }
>>>>
>>>> +/* Tests whether backer's datapath supports the OVS_ACTION_ATTR_DROP 
>>>> action. */
>>>> +static bool
>>>> +check_drop_action(struct dpif_backer *backer)
>>>> +{
>>>> +    struct odputil_keybuf keybuf;
>>>> +    uint8_t actbuf[NL_A_U32_SIZE];
>>>> +    struct ofpbuf actions;
>>>> +    struct ofpbuf key;
>>>> +    struct flow flow;
>>>> +    bool supported;
>>>> +    bool hw_offload;
>>>> +
>>>> +    struct odp_flow_key_parms odp_parms = {
>>>> +        .flow = &flow,
>>>> +        .probe = true,
>>>> +    };
>>>> +
>>>> +    memset(&flow, 0, sizeof flow);
>>>> +    ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
>>>> +    odp_flow_key_from_flow(&odp_parms, &key);
>>>> +
>>>> +    ofpbuf_use_stack(&actions, &actbuf, sizeof actbuf);
>>>> +    nl_msg_put_u32(&actions, OVS_ACTION_ATTR_DROP, XLATE_OK);
>>>> +
>>>> +    supported = dpif_probe_feature(backer->dpif, "drop", &key, &actions, 
>>>> NULL);
>>>> +    hw_offload = !dpif_may_support_explicit_drop_action(backer->dpif);
>>>
>>> The use case of this function seems odd here. This since 
>>> dpif_may_support_explicit_drop_action() doesn't imply that we're 
>>> specifically checking for HW offload being the issue. If someone updates 
>>> the function with another reason for it not being supported we will break 
>>> the implementation here. What do you think?
>>
>> The reason it was changed to user
>> dpif_may_support_explicit_drop_action() was because it was suggested to
>> avoid calling dpif_is_netdev() from ofproto. I assume it's similar for
>> netdev_is_flow_api_enabled().
>>
>> "hw_offload" is probably a bad variable name. Maybe we completely avoid
>> mentioning hw_offload here and in the log. Instead we do:
>>
>> +    supported = dpif_may_support_explicit_drop_action(backer->dpif)
>>                  && dpif_probe_feature(backer->dpif, "drop", &key, &actions, 
>> NULL);
>>
>>
>> Is this agreeable?
>>
>>>> +
>>>> +    VLOG_INFO("%s: Datapath %s explicit drop action%s",
>>>> +              dpif_name(backer->dpif),
>>>> +              (supported) ? "supports" : "does not support",
>>>> +              (hw_offload) ? ", but not enabled due to hardware offload" 
>>>> : "");
>>
>> We would simply remove the log mentioning hardware offload.
>>
>>>> +
>>>> +    return supported && !hw_offload;
>>>> +}
>>>> +
>>>>  /* Tests whether 'backer''s datapath supports the all-zero SNAT case. */
>>>>  static bool
>>>>  dpif_supports_ct_zero_snat(struct dpif_backer *backer)
>>>> @@ -1649,8 +1693,8 @@ check_support(struct dpif_backer *backer)
>>>>      backer->rt_support.max_hash_alg = check_max_dp_hash_alg(backer);
>>>>      backer->rt_support.check_pkt_len = check_check_pkt_len(backer);
>>>>      backer->rt_support.ct_timeout = check_ct_timeout_policy(backer);
>>>> -    backer->rt_support.explicit_drop_action =
>>>> -        dpif_supports_explicit_drop_action(backer->dpif);
>>>> +    atomic_store_relaxed(&backer->rt_support.explicit_drop_action,
>>>> +                         check_drop_action(backer));
>>>>      backer->rt_support.lb_output_action =
>>>>          dpif_supports_lb_output_action(backer->dpif);
>>>>      backer->rt_support.ct_zero_snat = dpif_supports_ct_zero_snat(backer);
>>>> @@ -1667,6 +1711,27 @@ check_support(struct dpif_backer *backer)
>>>>      backer->rt_support.odp.nd_ext = check_nd_extensions(backer);
>>>>  }
>>>>
>>>> +/* For TC, if vswitchd started with other_config:hw-offload set to 
>>>> "false", and
>>>> + * the configuration is now "true", then we need to re-probe datapath 
>>>> support
>>>> + * for the "drop" action. */
>>>> +static bool
>>>> +recheck_support_explicit_drop_action(struct dpif_backer *backer)
>>>> +{
>>>> +    bool explicit_drop_action;
>>>> +
>>>> +    atomic_read_relaxed(&backer->rt_support.explicit_drop_action,
>>>> +                        &explicit_drop_action);
>>>> +
>>>> +    if (explicit_drop_action
>>>> +        && !dpif_may_support_explicit_drop_action(backer->dpif)
>>>> +        && !check_drop_action(backer)) {
>>>> +        atomic_store_relaxed(&backer->rt_support.explicit_drop_action, 
>>>> false);
>>>> +        return true;
>>>
>>> This should probably also work in the reverse direction. If it´s enabled on 
>>> startup, but now disabled?
>>
>> I'll make the change.
>>
>> IIRC, unsetting "hw-offload" requires a restart. Setting it does not.
>> Even though it's documented that a restart is required.
>>
>>        other_config : hw-offload: optional string, either true or false
>>               Set this value to true to enable netdev flow offload.
>>
>>               The  default  value  is  false.  Changing  this  value  
>> requires
>>               restarting the daemon
>>        [..]
>>
>> https://www.openvswitch.org/support/dist-docs/ovs-vswitchd.conf.db.5.html
>
> Testing and code inspection, i.e. netdev_set_flow_api_enabled(), confirm
> that we don't support setting hw-offload=false without a restart. We
> only support false --> true at runtime.
>
> As such, I won't add support for this here.

ACK, was not aware of this... Thanks, no I know ;)

>>>> +    }
>>>> +
>>>> +    return false;
>>>> +}
>>>> +
>>>>  static int
>>>>  construct(struct ofproto *ofproto_)
>>>>  {
>>>> @@ -5708,6 +5773,7 @@ ct_zone_limit_protection_update(const char 
>>>> *datapath_type, bool protected)
>>>>  static void
>>>>  get_datapath_cap(const char *datapath_type, struct smap *cap)
>>>>  {
>>>> +    bool explicit_drop_action;
>>>>      struct dpif_backer_support *s;
>>>>      struct dpif_backer *backer = shash_find_data(&all_dpif_backers,
>>>>                                                   datapath_type);
>>>> @@ -5743,8 +5809,9 @@ get_datapath_cap(const char *datapath_type, struct 
>>>> smap *cap)
>>>>      smap_add_format(cap, "max_hash_alg", "%"PRIuSIZE, s->max_hash_alg);
>>>>      smap_add(cap, "check_pkt_len", s->check_pkt_len ? "true" : "false");
>>>>      smap_add(cap, "ct_timeout", s->ct_timeout ? "true" : "false");
>>>> +    atomic_read_relaxed(&s->explicit_drop_action, &explicit_drop_action);
>>>>      smap_add(cap, "explicit_drop_action",
>>>> -             s->explicit_drop_action ? "true" :"false");
>>>> +             explicit_drop_action ? "true" :"false");
>>>>      smap_add(cap, "lb_output_action", s->lb_output_action ? "true" : 
>>>> "false");
>>>>      smap_add(cap, "ct_zero_snat", s->ct_zero_snat ? "true" : "false");
>>>>      smap_add(cap, "add_mpls", s->add_mpls ? "true" : "false");
>>>> @@ -6273,7 +6340,7 @@ show_dp_feature_bool(struct ds *ds, const char 
>>>> *feature, const bool *b)
>>>>      ds_put_format(ds, "%s: %s\n", feature, *b ? "Yes" : "No");
>>>>  }
>>>>
>>>> -static void OVS_UNUSED
>>>> +static void
>>>>  show_dp_feature_atomic_bool(struct ds *ds, const char *feature,
>>>>                              const atomic_bool *b)
>>>>  {
>>>> diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h
>>>> index 92d33aa64709..d33f73df8aed 100644
>>>> --- a/ofproto/ofproto-dpif.h
>>>> +++ b/ofproto/ofproto-dpif.h
>>>> @@ -51,6 +51,7 @@
>>>>  #include "hmapx.h"
>>>>  #include "odp-util.h"
>>>>  #include "id-pool.h"
>>>> +#include "ovs-atomic.h"
>>>>  #include "ovs-thread.h"
>>>>  #include "ofproto-provider.h"
>>>>  #include "util.h"
>>>> @@ -202,7 +203,8 @@ struct group_dpif *group_dpif_lookup(struct 
>>>> ofproto_dpif *,
>>>>      DPIF_SUPPORT_FIELD(bool, ct_timeout, "Conntrack timeout policy")      
>>>>   \
>>>>                                                                            
>>>>   \
>>>>      /* True if the datapath supports explicit drop action. */             
>>>>   \
>>>> -    DPIF_SUPPORT_FIELD(bool, explicit_drop_action, "Explicit Drop 
>>>> action")  \
>>>> +    DPIF_SUPPORT_FIELD(atomic_bool, explicit_drop_action,                 
>>>>   \
>>>> +                       "Explicit Drop action")                            
>>>>   \
>>>>                                                                            
>>>>   \
>>>>      /* True if the datapath supports balance_tcp optimization */          
>>>>   \
>>>>      DPIF_SUPPORT_FIELD(bool, lb_output_action, "Optimized Balance TCP 
>>>> mode")\
>>>> -- 
>>>> 2.43.0
>>>>
>>>> _______________________________________________
>>>> dev mailing list
>>>> d...@openvswitch.org
>>>> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>>>
>>> _______________________________________________
>>> dev mailing list
>>> d...@openvswitch.org
>>> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>>
>> _______________________________________________
>> dev mailing list
>> d...@openvswitch.org
>> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>>

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to