On 26 Apr 2023, at 4:44, Chris Mi wrote:

<SNIP>

>>> +
>>> +static int
>>> +offload_sample_init(struct offload_sample *sample,
>>> +                    const struct nlattr *next_actions,
>>> +                    size_t next_actions_len, bool tunnel,
>>> +                    const struct flow_tnl *tnl)
>>> +{
>>> +    memset(sample, 0, sizeof *sample);
>>> +    if (tunnel) {
>>> +        sample->tunnel = CONST_CAST(struct flow_tnl *, tnl);
>> See previous comment on flow_tnl_copy__(), i.e. is the structure properly 
>> initialized?
> So shall we make flow_tnl_copy__() and related functions public?

I think so, as it’s in an include already, we just need to remove the trailing 
__ and use it.

>>> +    } else {
>> Are you sure we should either include one or the other? Should we not always 
>> present userspace_actions if present? Can you explain why not?
> The original intention is to avoid unnecessary memcpy. I think it is right to 
> always set it.

Ok, also because if we use this API for other stuff (like sent to userspace) we 
might need it.

>>> +        sample->userspace_actions = xmalloc(next_actions_len + NLA_HDRLEN);
>> I think doing the malloc, copy, and doing this again in the clone actions 
>> does not make sense, especially as the data is not used up until the clone.
>> Maybe you can think about another solution without the additional 
>> malloc/copy, and we can discuss it before you send the next revisions...
> Actually we should not copy here. We only need to copy it in 
> offload_sample_clone(). How about change it like this:

This looks ugly, as now we use the offload_sample structure to pass parameters 
around.

I have not given this much thought, but what about a flag to clone that steals 
the user_space actions (needs fixing in parse_userspace_action() and 
parse_sample_action() error handling)?

diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
index 14e5b2b60..5fb770bf4 100644
--- a/lib/netdev-offload-tc.c
+++ b/lib/netdev-offload-tc.c
@@ -170,14 +170,19 @@ sample_find(uint32_t id)

 static void
 offload_sample_clone(struct offload_sample *new,
-                     const struct offload_sample *old)
+                     const struct offload_sample *old,
+                     bool steal_userspace_actions)
 {
     new->type = old->type;
     new->action = xmemdup(old->action, old->action->nla_len);
-    new->userspace_actions = old->userspace_actions
-                             ? xmemdup(old->userspace_actions,
-                                       old->userspace_actions->nla_len)
-                             : NULL;
+    if (steal_userspace_actions) {
+        new->userspace_action = old->userspace_actions;
+    } else {
+        new->userspace_actions = old->userspace_actions
+            ? xmemdup(old->userspace_actions,
+                      old->userspace_actions->nla_len)
+            : NULL;
+    }
     new->userdata = xmemdup(old->userdata, old->userdata->nla_len);
     new->tunnel = old->tunnel
                   ? xmemdup(old->tunnel, sizeof *old->tunnel)
@@ -191,7 +196,7 @@ sgid_alloc(const struct offload_sample *sample)
 {
     struct sgid_node *node = xzalloc(sizeof *node);

-    offload_sample_clone(&node->sample, sample);
+    offload_sample_clone(&node->sample, sample, true);
     ovs_mutex_lock(&sgid_lock);
     if (!id_pool_alloc_id(sample_group_ids, &node->id)) {
         VLOG_ERR("Can't find a free sample group ID");


This is also not the nicest solution, maybe you should give this some more 
thought. Maybe there is a nicer way of doing this.

>
> diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
> index c3eb8fefc..e54a3de34 100644
> --- a/lib/netdev-offload-tc.c
> +++ b/lib/netdev-offload-tc.c
> @@ -117,6 +117,9 @@ struct offload_sample {
>      struct nlattr *action;             /* Sample action. Used in flow_get. */
>      struct nlattr *userdata;           /* Struct user_action_cookie. */
>      struct nlattr *userspace_actions;  /* All actions to get output tunnel. 
> */
> +    const struct nlattr *next_actions; /* All actions pointer without nla
>                                           header. */
> +    size_t next_actions_len /* All actions pointer without nla
>                                           header Length. */
>      struct flow_tnl *tunnel;           /* Input tunnel. */
>  };
>
> @@ -182,10 +185,14 @@ offload_sample_clone(struct offload_sample *dst,
>      dst->type = src->type;
>      dst->action = src->action ? xmemdup(src->action, src->action->nla_len)
>                                : NULL;
> -    dst->userspace_actions = src->userspace_actions
> -                             ? xmemdup(src->userspace_actions,
> - src->userspace_actions->nla_len)
> -                             : NULL;
> +    if (src->next_actions) {
> +        uint16_t len = src->next_actions_len;
> +
> +        dst->userspace_actions = xmalloc(len + NLA_HDRLEN);
> +        nullable_memcpy((char *) dst->userspace_actions + NLA_HDRLEN,
> +                        src->next_actions, len);
> +        dst->userspace_actions->nla_len = len + NLA_HDRLEN;
> +    }
>      dst->userdata = src->userdata
>                      ? xmemdup(src->userdata, src->userdata->nla_len)
>                      : NULL;
> @@ -2096,12 +2103,9 @@ offload_sample_init(struct offload_sample *sample,
>      memset(sample, 0, sizeof *sample);
>      if (tunnel) {
>          sample->tunnel = CONST_CAST(struct flow_tnl *, tnl);
> -    } else {
> -        sample->userspace_actions = xmalloc(next_actions_len + NLA_HDRLEN);
> -        nullable_memcpy((char *) sample->userspace_actions + NLA_HDRLEN,
> -                        next_actions, next_actions_len);
> -        sample->userspace_actions->nla_len = next_actions_len + NLA_HDRLEN;
>      }
> +    sample->next_actions = next_actions;
> +    sample->next_actions_len = next_actions_len;
>
>      return 0;
>  }
>>> +        nullable_memcpy((char *) sample->userspace_actions + NLA_HDRLEN,
>>> +                        next_actions, next_actions_len);
>>> +        sample->userspace_actions->nla_len = next_actions_len + NLA_HDRLEN;
>>> +    }
>>> +
>>> +    return 0;
>>> +}

<SNIP>

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

Reply via email to