On 7 Jan 2026, at 20:29, Aaron Conole wrote:

> Eelco Chaudron via dev <[email protected]> writes:
>
>> This patch adds support for configuring the priority of
>> offload providers.  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]>
>> ---

[...]

>>  static int
>>  dpif_offload_attach_providers_(struct dpif *dpif)
>>      OVS_REQUIRES(dpif_offload_mutex)
>>  {
>> +    struct ovs_list provider_list = OVS_LIST_INITIALIZER(&provider_list);
>>      const char *dpif_type_str = dpif_normalize_type(dpif_type(dpif));
>>      struct dp_offload *dp_offload;
>> +    struct dpif_offload *offload;
>>      struct shash_node *node;
>> +    char *tokens, *saveptr;
>>
>>      /* Allocate and attach dp_offload to dpif. */
>>      dp_offload = xmalloc(sizeof *dp_offload);
>> @@ -206,37 +241,51 @@ dpif_offload_attach_providers_(struct dpif *dpif)
>>      ovs_list_init(&dp_offload->offload_providers);
>>      shash_add(&dpif_offload_providers, dp_offload->dpif_name, dp_offload);
>>
>> -    /* Attach all the providers supporting this dpif type. */
>> +    /* Open all the providers supporting this dpif type. */
>>      SHASH_FOR_EACH (node, &dpif_offload_classes) {
>>          const struct dpif_offload_class *class = node->data;
>>
>>          for (size_t i = 0; class->supported_dpif_types[i] != NULL; i++) {
>>              if (!strcmp(class->supported_dpif_types[i], dpif_type_str)) {
>> -                struct dpif_offload *offload;
>> -                int error;
>> -
>> -                error = class->open(class, dpif, &offload);
>> -                if (!error) {
>> -                    error = dpif_offload_attach_provider_to_dp_offload(
>> -                        dp_offload, offload);
>> -                    if (error) {
>> -                        VLOG_WARN("failed to add dpif offload provider "
>> -                                  "%s to %s: %s",
>> -                                  class->type, dpif_name(dpif),
>> -                                  ovs_strerror(error));
>> -                        class->close(offload);
>> -                    }
>> -                } else {
>> +                int error = class->open(class, dpif, &offload);
>> +
>> +                if (error) {
>>                      VLOG_WARN("failed to initialize dpif offload provider "
>>                                "%s for %s: %s",
>>                                class->type, dpif_name(dpif),
>>                                ovs_strerror(error));
>> +                } else {
>> +                    ovs_list_push_back(&provider_list,
>> +                                       &offload->dpif_list_node);
>>                  }
>>                  break;
>
> Weird - I must be misunderstanding, but I would expect that this
> wouldn't actually properly seek through the list, because the first
> match would land on this break.  Did I miss something?

Let me put the actual code here, as the diff is hard to read :)

    /* Open all the providers supporting this dpif type. */
    SHASH_FOR_EACH (node, &dpif_offload_classes) {
        const struct dpif_offload_class *class = node->data;

        for (size_t i = 0; class->supported_dpif_types[i] != NULL; i++) {
            if (!strcmp(class->supported_dpif_types[i], dpif_type_str)) {
                int error = class->open(class, dpif, &offload);

                if (error) {
                    VLOG_WARN("failed to initialize dpif offload provider "
                              "%s for %s: %s",
                              class->type, dpif_name(dpif),
                              ovs_strerror(error));
                } else {
                    ovs_list_push_back(&provider_list,
                                       &offload->dpif_list_node);
                }
                break;
            }
        }
    }

An offload provider can support multiple dpif types. Here we are looking for a
specific dpif type by name, so once we find a match with strcmp(), we only
need to process that one and can safely ignore the rest, hence the break.

Hope this clears it up.

>>>>>              }

[...]

>>>>> +void
>> +dpif_offload_set_global_cfg(const struct smap *other_cfg)
>> +{
>> +    static struct ovsthread_once init_once = OVSTHREAD_ONCE_INITIALIZER;
>> +    const char *priority = smap_get(other_cfg, "hw-offload-priority");
>> +
>> +    /* The 'hw-offload-priority' parameter can only be set at startup,
>> +     * any successive change needs a restart. */
>> +    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. */
>> +        dp_offload_initialize();
>> +
>> +        /* If priority is not set keep the default value. */
>> +        if (priority) {
>> +            char *tokens = xstrdup(priority);
>> +            char *saveptr;
>> +
>> +            free(dpif_offload_provider_priority_list);
>> +            dpif_offload_provider_priority_list = xstrdup(priority);
>> +
>> +            /* Log a warning for unknown offload providers. */
>> +            for (char *name = strtok_r(tokens, ",", &saveptr);
>> +                 name;
>> +                 name = strtok_r(NULL, ",", &saveptr)) {
>> +
>> +                if (!shash_find(&dpif_offload_classes, name)) {
>> +                    VLOG_WARN("'hw-offload-priority' configuration has an "
>> +                              "unknown type; %s", name);
>
> If a weird config gets into this, maybe it's better to also remove it
> from the in-memory list.  WDYT?

Yes, we could. It would slightly speed up the creation of new dpifs; however,
it would require us to keep two copies (the original and a modified one),
otherwise the VLOG below would be triggered each time.

My preference is to keep this as-is and not store the additional configuration
string. Let me know your thoughts.

>> +                }
>> +            }
>> +            free(tokens);
>> +        }
>> +        ovsthread_once_done(&init_once);
>> +    } else {
>> +        if (priority && strcmp(priority,
>> +                               dpif_offload_provider_priority_list)) {
>> +            VLOG_INFO_ONCE("'hw-offload-priority' configuration changed; "
>> +                           "restart required");
>> +        }
>> +    }
>> +}

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

Reply via email to