On 10 Dec 2025, at 17:39, Eli Britstein wrote:

>> -----Original Message-----
>> From: dev <[email protected]> On Behalf Of Eelco Chaudron
>> Sent: Tuesday, 2 December 2025 16:05
>> To: [email protected]
>> Subject: [ovs-dev] [PATCH v2 11/41] dpif-offload: Allow per-port offload
>> provider priority config.
>>
>> This patch adds support for configuring the priority of offload providers at 
>> a port
>> level.  When multiple providers exist and support the same port, the 'hw-
>> offload-priority'
>> option allows specifying the order in which they are tried.
>>
>> Signed-off-by: Eelco Chaudron <[email protected]>
>> ---
>>
>> v2 changes:
>>  - Fixed indentation problem in bridge_run().
>> ---
>> lib/dpif-offload.c   | 104 ++++++++++++++++++++++++++++++++++++-------
>> lib/dpif-offload.h   |   2 +-
>> vswitchd/bridge.c    |   5 ++-
>> vswitchd/vswitch.xml |  24 ++++++++++
>> 4 files changed, 116 insertions(+), 19 deletions(-)
>>
>> diff --git a/lib/dpif-offload.c b/lib/dpif-offload.c index 
>> 5c6b827c3..42055008e
>> 100644
>> --- a/lib/dpif-offload.c
>> +++ b/lib/dpif-offload.c
>> @@ -23,6 +23,8 @@
>> #include "netdev-provider.h"
>> #include "unixctl.h"
>> #include "util.h"
>> +#include "vswitch-idl.h"
>> +
>> #include "openvswitch/dynamic-string.h"
>> #include "openvswitch/shash.h"
>> #include "openvswitch/vlog.h"
>> @@ -55,6 +57,7 @@ static const struct dpif_offload_class
>> *base_dpif_offload_classes[] = {  static char
>> *dpif_offload_provider_priority_list = NULL;  static atomic_bool
>> dpif_offload_global_enabled = false;  static atomic_bool
>> dpif_offload_rebalance_policy = false;
>> +static struct smap port_order_cfg = SMAP_INITIALIZER(&port_order_cfg);
>>
>> static int
>> dpif_offload_register_provider__(const struct dpif_offload_class *class) @@ -
>> 428,34 +431,79 @@ dpif_offload_set_netdev_offload(struct netdev *netdev,
>>     ovsrcu_set(&netdev->dpif_offload, offload);  }
>>
>> +static bool
>> +dpif_offload_try_port_add(struct dpif_offload *offload, struct netdev
>> *netdev,
>> +                          odp_port_t port_no) {
>> +    if (offload->class->can_offload(offload, netdev)) {
>> +        int err = offload->class->port_add(offload, netdev, port_no);
> Blank line

ACK

>> +        if (!err) {
>> +            VLOG_DBG("netdev %s added to dpif-offload provider %s",
>> +                     netdev_get_name(netdev), dpif_offload_name(offload));
>> +            return true;
>> +        } else {
>> +            VLOG_ERR("Failed adding netdev %s to dpif-offload provider "
>> +                     "%s, error %s",
>> +                     netdev_get_name(netdev), dpif_offload_name(offload),
>> +                     ovs_strerror(err));
>> +        }
>> +    } else {
>> +        VLOG_DBG("netdev %s failed can_offload for dpif-offload provider 
>> %s",
>> +                 netdev_get_name(netdev), dpif_offload_name(offload));
>> +    }
>> +    return false;
>> +}
>> +
>> void
>> dpif_offload_port_add(struct dpif *dpif, struct netdev *netdev,
>>                       odp_port_t port_no)  {
>>     struct dp_offload *dp_offload = dpif_offload_get_dp_offload(dpif);
>> +    const char *port_priority = smap_get(&port_order_cfg,
>> +                                         netdev_get_name(netdev));
>>     struct dpif_offload *offload;
>>
>>     if (!dp_offload) {
>>         return;
>>     }
>>
>> -    LIST_FOR_EACH (offload, dpif_list_node, &dp_offload->offload_providers) 
>> {
>> -        if (offload->class->can_offload(offload, netdev)) {
>> -            int err = offload->class->port_add(offload, netdev, port_no);
>> -            if (!err) {
>> -                VLOG_DBG("netdev %s added to dpif-offload provider %s",
>> -                         netdev_get_name(netdev), 
>> dpif_offload_name(offload));
>> +    if (port_priority) {
>> +        char *tokens = xstrdup(port_priority);
>> +        char *saveptr;
>> +
>> +        VLOG_DBG("for netdev %s using port priority %s",
>> +                 netdev_get_name(netdev), port_priority);
>> +
>> +        for (char *name = strtok_r(tokens, ",", &saveptr);
>> +             name;
>> +             name = strtok_r(NULL, ",", &saveptr)) {
>> +            bool provider_added = false;
>> +
>> +            if (!strcmp("none", name)) {
>> +                break;
>> +            }
>> +
>> +            LIST_FOR_EACH (offload, dpif_list_node,
>> +                           &dp_offload->offload_providers) {
>> +                if (!strcmp(name, offload->class->type)) {
>> +
> Remove blank line

ACK
>> +                    provider_added = dpif_offload_try_port_add(offload, 
>> netdev,
>> +                                                               port_no);
>> +                    break;
>> +                }
>> +            }
>> +
>> +            if (provider_added) {
>> +                break;
>> +            }
>> +        }
>> +        free(tokens);
>> +    } else {
>> +        LIST_FOR_EACH (offload, dpif_list_node,
>> +                       &dp_offload->offload_providers) {
>> +            if (dpif_offload_try_port_add(offload, netdev, port_no)) {
>>                 break;
>> -            } else {
>> -                VLOG_ERR("Failed adding netdev %s to dpif-offload provider "
>> -                         "%s, error %s",
>> -                         netdev_get_name(netdev), 
>> dpif_offload_name(offload),
>> -                         ovs_strerror(err));
>>             }
>> -        } else {
>> -            VLOG_DBG(
>> -                "netdev %s failed can_offload for dpif-offload provider %s",
>> -                netdev_get_name(netdev), dpif_offload_name(offload));
>>         }
>>     }
>> }
>> @@ -569,13 +617,16 @@ dpif_offload_dump_done(struct dpif_offload_dump
>> *dump)  }
>>
>> void
>> -dpif_offload_set_global_cfg(const struct smap *other_cfg)
>> +dpif_offload_set_global_cfg(const struct ovsrec_open_vswitch *cfg)
>> {
>>     static struct ovsthread_once init_once = OVSTHREAD_ONCE_INITIALIZER;
>> -    const char *priority = smap_get(other_cfg, "hw-offload-priority");
>> +    const struct smap *other_cfg = &cfg->other_config;
>> +    const char *priority;
>>
>>     /* The 'hw-offload-priority' parameter can only be set at startup,
>>      * any successive change needs a restart. */
>> +    priority = smap_get(other_cfg, "hw-offload-priority");
>> +
>>     if (ovsthread_once_start(&init_once)) {
>>         /* Initialize the dpif-offload layer in case it's not yet initialized
>>          * at the first invocation of setting the configuration. */ @@ -629,6
>> +680,25 @@ dpif_offload_set_global_cfg(const struct smap *other_cfg)
>>             ovsthread_once_done(&once_enable);
>>         }
>>     }
>> +
>> +    /* Filter out the 'hw-offload-priority' per port setting we need it 
>> before
>> +     * ports are added, so we can assign the correct offload-provider.
>> +     * Note that we can safely rebuild the map here, as we only access this
>> +     * from the same (main) thread. */
>> +    smap_clear(&port_order_cfg);
>> +    for (int i = 0; i < cfg->n_bridges; i++) {
>> +        const struct ovsrec_bridge *br_cfg = cfg->bridges[i];
>> +
>> +        for (int j = 0; j < br_cfg->n_ports; j++) {
>> +            const struct ovsrec_port *port_cfg = br_cfg->ports[j];
>> +
>> +            priority = smap_get(&port_cfg->other_config,
>> +                                "hw-offload-priority");
>> +            if (priority) {
>> +                smap_add(&port_order_cfg, port_cfg->name, priority);
>> +            }
>> +        }
>> +    }
>> }
>>
>>
>>
>>
>> diff --git a/lib/dpif-offload.h b/lib/dpif-offload.h index 
>> f35f9b8a8..9cee3a8f4
>> 100644
>> --- a/lib/dpif-offload.h
>> +++ b/lib/dpif-offload.h
>> @@ -32,7 +32,7 @@ struct dpif_offload_dump {
>>
>>
>>
>>
>> /* Global functions. */
>> -void dpif_offload_set_global_cfg(const struct smap *other_cfg);
>> +void dpif_offload_set_global_cfg(const struct ovsrec_open_vswitch *);
>> bool dpif_offload_is_offload_enabled(void);
>> bool dpif_offload_is_offload_rebalance_policy_enabled(void);
>>
>> diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 62dec1391..10fcc49a7
>> 100644
>> --- a/vswitchd/bridge.c
>> +++ b/vswitchd/bridge.c
>> @@ -3395,8 +3395,11 @@ bridge_run(void)
>>     }
>>     cfg = ovsrec_open_vswitch_first(idl);
>>
>> +    if (cfg && ovsdb_idl_get_seqno(idl) != idl_seqno) {
>> +        dpif_offload_set_global_cfg(cfg);
>> +    }
>> +
>>     if (cfg) {
>> -        dpif_offload_set_global_cfg(&cfg->other_config);
>>         netdev_set_flow_api_enabled(&cfg->other_config);
>>         dpdk_init(&cfg->other_config);
>>         userspace_tso_init(&cfg->other_config);
>> diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index
>> 061d0a568..1c53a2859 100644
>> --- a/vswitchd/vswitch.xml
>> +++ b/vswitchd/vswitch.xml
>> @@ -2600,6 +2600,30 @@
>>         e.g. <code>fake-bridge-bridge-id</code>.
>>       </column>
>>
>> +      <column name="other_config" key="hw-offload-priority"
>> +              type='{"type": "string"}'>
>> +        <p>
>> +          This configuration sets an explicit list of hardware offload
>> +          providers to try on this port.  The argument should be a
>> +          comma-separated list of hardware offload provider names, or the
>> +          word <code>none</code>.
>> +        </p>
>> +        <p>
>> +          If <code>none</code> is encountered in the list, further trying of
>> +          offload providers is stopped. For example, if the list only 
>> contains
>> +          <code>none</code>, hardware offload is disabled on this port even 
>> if
>> +          it is globally enabled. Note that unknown hardware offload 
>> provider
>> +          names are ignored.
>> +        </p>
>> +        <p>
>> +          The default value is <code>none</code>, i.e., not set, which uses 
>> the
>> +          global
>> +          <ref table="Open_vSwitch" column="other_config" key="hw-offload-
>> priority"/>
>> +          configuration. Changing this value after offload enablement 
>> requires
>> +          restarting the daemon.
>> +        </p>
>> +      </column>
>> +
>>       <column name="other_config" key="transient"
>>               type='{"type": "boolean"}'>
>>         <p>

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

Reply via email to