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
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev