+    } 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.
But offload_sample_clone() is only called by sgid_alloc(), I'm a little 
confused why we need a flag.
Actually my below change is straightforward. In netdev_tc_flow_put(), the 
next_actions doesn't have
a nla header, we just need to add a header for it. So sflow can get output 
tunnel info from it..
The main problem I have with your solution below is that you add the 
next_actions field only to pass it on to the clone action, it is not really 
used later on.

The solution I gave above is cleaner, and the only reason for 
steal_userspace_actions flag is to be sure that the clone API is not really 
doing a clone for this one parameter. The compiler will optimize all of this 
out, but we have a clean API implementation.

My preference is to either use my approach or find a cleaner way without miss 
using the offload_sample structure to pass a variable around which is not 
really needed in the sample processing.
OK, I see. Will send v27 for review.

Thanks,
Chris

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