On 26 May 2023, at 10:19, Chris Mi wrote:
> On 5/10/2023 8:20 PM, Eelco Chaudron wrote:
>> 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.
> Done.
Thanks
>>>>> + } 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.
>>> 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