From: Vlad Buslov <vladbu@nvidia.com>
To: Baowen Zheng <baowen.zheng@corigine.com>
Cc: Simon Horman <simon.horman@corigine.com>,
"netdev@vger.kernel.org" <netdev@vger.kernel.org>,
Jamal Hadi Salim <jhs@mojatatu.com>, Roi Dayan <roid@nvidia.com>,
Ido Schimmel <idosch@nvidia.com>,
Cong Wang <xiyou.wangcong@gmail.com>,
Jiri Pirko <jiri@resnulli.us>,
Baowen Zheng <notifications@github.com>,
Louis Peens <louis.peens@corigine.com>,
oss-drivers <oss-drivers@corigine.com>
Subject: Re: [RFC/PATCH net-next v3 3/8] flow_offload: allow user to offload tc action to net device
Date: Mon, 1 Nov 2021 14:05:30 +0200 [thread overview]
Message-ID: <ygnh7dds9j3p.fsf@nvidia.com> (raw)
In-Reply-To: <DM5PR1301MB2172A5961718F4D57EDDAD82E78A9@DM5PR1301MB2172.namprd13.prod.outlook.com>
On Mon 01 Nov 2021 at 11:44, Baowen Zheng <baowen.zheng@corigine.com> wrote:
> Thanks for your review and sorry for delay in responding.
>
> On October 30, 2021 12:59 AM, Vlad Buslov <vladbu@nvidia.com> wrote:
>>On Thu 28 Oct 2021 at 14:06, Simon Horman <simon.horman@corigine.com>
>>wrote:
>>> From: Baowen Zheng <baowen.zheng@corigine.com>
>>>
>>> Use flow_indr_dev_register/flow_indr_dev_setup_offload to offload tc
>>> action.
>>>
>>> We need to call tc_cleanup_flow_action to clean up tc action entry
>>> since in tc_setup_action, some actions may hold dev refcnt, especially
>>> the mirror action.
>>>
>>> Signed-off-by: Baowen Zheng <baowen.zheng@corigine.com>
>>> Signed-off-by: Louis Peens <louis.peens@corigine.com>
>>> Signed-off-by: Simon Horman <simon.horman@corigine.com>
>>> ---
>>> include/linux/netdevice.h | 1 +
>>> include/net/act_api.h | 2 +-
>>> include/net/flow_offload.h | 17 ++++
>>> include/net/pkt_cls.h | 15 ++++
>>> net/core/flow_offload.c | 43 ++++++++--
>>> net/sched/act_api.c | 166
>>+++++++++++++++++++++++++++++++++++++
>>> net/sched/cls_api.c | 29 ++++++-
>>> 7 files changed, 260 insertions(+), 13 deletions(-)
>>>
>>> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
>>> index 3ec42495a43a..9815c3a058e9 100644
>>> --- a/include/linux/netdevice.h
>>> +++ b/include/linux/netdevice.h
>>> @@ -916,6 +916,7 @@ enum tc_setup_type {
>>> TC_SETUP_QDISC_TBF,
>>> TC_SETUP_QDISC_FIFO,
>>> TC_SETUP_QDISC_HTB,
>>> + TC_SETUP_ACT,
>>> };
>>>
>>> /* These structures hold the attributes of bpf state that are being
>>> passed diff --git a/include/net/act_api.h b/include/net/act_api.h
>>> index b5b624c7e488..9eb19188603c 100644
>>> --- a/include/net/act_api.h
>>> +++ b/include/net/act_api.h
>>> @@ -239,7 +239,7 @@ static inline void
>>> tcf_action_inc_overlimit_qstats(struct tc_action *a) void
>>tcf_action_update_stats(struct tc_action *a, u64 bytes, u64 packets,
>>> u64 drops, bool hw);
>>> int tcf_action_copy_stats(struct sk_buff *, struct tc_action *, int);
>>> -
>>> +int tcf_action_offload_del(struct tc_action *action);
>>
>>This doesn't seem to be used anywhere outside of act_api in this series, so
>>why is it exported?
> Thanks for bring this to us, we will fix this by moving the block of implement in act_api.c.
>>> int tcf_action_check_ctrlact(int action, struct tcf_proto *tp,
>>> struct tcf_chain **handle,
>>> struct netlink_ext_ack *newchain); diff --git
>>> a/include/net/flow_offload.h b/include/net/flow_offload.h index
>>> 3961461d9c8b..aa28592fccc0 100644
>>> --- a/include/net/flow_offload.h
>>> +++ b/include/net/flow_offload.h
>>> @@ -552,6 +552,23 @@ struct flow_cls_offload {
>>> u32 classid;
>>> };
>>>
>>> +enum flow_act_command {
>>> + FLOW_ACT_REPLACE,
>>> + FLOW_ACT_DESTROY,
>>> + FLOW_ACT_STATS,
>>> +};
>>> +
>>> +struct flow_offload_action {
>>> + struct netlink_ext_ack *extack; /* NULL in FLOW_ACT_STATS
>>process*/
>>> + enum flow_act_command command;
>>> + enum flow_action_id id;
>>> + u32 index;
>>> + struct flow_stats stats;
>>> + struct flow_action action;
>>> +};
>>> +
>>> +struct flow_offload_action *flow_action_alloc(unsigned int
>>> +num_actions);
>>> +
>>> static inline struct flow_rule *
>>> flow_cls_offload_flow_rule(struct flow_cls_offload *flow_cmd) { diff
>>> --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index
>>> 193f88ebf629..922775407257 100644
>>> --- a/include/net/pkt_cls.h
>>> +++ b/include/net/pkt_cls.h
>>> @@ -258,6 +258,9 @@ static inline void tcf_exts_put_net(struct tcf_exts
>>*exts)
>>> for (; 0; (void)(i), (void)(a), (void)(exts)) #endif
>>>
>>> +#define tcf_act_for_each_action(i, a, actions) \
>>> + for (i = 0; i < TCA_ACT_MAX_PRIO && ((a) = actions[i]); i++)
>>> +
>>> static inline void
>>> tcf_exts_stats_update(const struct tcf_exts *exts,
>>> u64 bytes, u64 packets, u64 drops, u64 lastuse, @@ -532,8
>>> +535,19 @@ tcf_match_indev(struct sk_buff *skb, int ifindex)
>>> return ifindex == skb->skb_iif;
>>> }
>>>
>>> +#ifdef CONFIG_NET_CLS_ACT
>>> int tc_setup_flow_action(struct flow_action *flow_action,
>>> const struct tcf_exts *exts);
>>
>>Why does existing cls_api function tc_setup_flow_action() now depend on
>>CONFIG_NET_CLS_ACT?
> Originally the function tc_setup_flow_action deal with the dependence of CONFIG_NET_CLS_ACT
> By calling the macro tcf_exts_for_each_action, now we change to call the function tc_setup_action
> Then tc_setup_flow_action will refer to exts->actions, so it will depend on CONFIG_NET_CLS_ACT explicitly.
> To fix this, we have to have the ifdef in tc_setup_flow_action declaration or in the implement in cls_api.c.
> Do you think if it makes sense?
Since we already have multiple of such ifdefs in cls_api I don't think
having more is an issue, but I also don't think we need to ifdef this
function in both pkt_cls.h and cls_api.c. Unless I'm missing something
you can either:
- Make tc_setup_flow_action() inline in pkt_cls.h and remove its
definition from cls_api.c since tc_setup_action() is also exported.
- Move ifdef check inside function definition in cls_api.c (return 0, if
config is not defined), which will allows you to remove ifdef from
pkt_cls.h.
WDYT?
>>> +#else
>>> +static inline int tc_setup_flow_action(struct flow_action *flow_action,
>>> + const struct tcf_exts *exts) {
>>> + return 0;
>>> +}
>>> +#endif
>>> +
>>> +int tc_setup_action(struct flow_action *flow_action,
>>> + struct tc_action *actions[]);
>>> void tc_cleanup_flow_action(struct flow_action *flow_action);
>>>
> ...
>>> #ifdef CONFIG_INET
>>> DEFINE_STATIC_KEY_FALSE(tcf_frag_xmit_count);
>>> @@ -148,6 +161,7 @@ static int __tcf_action_put(struct tc_action *p, bool
>>bind)
>>> idr_remove(&idrinfo->action_idr, p->tcfa_index);
>>> mutex_unlock(&idrinfo->lock);
>>>
>>> + tcf_action_offload_del(p);
>>> tcf_action_cleanup(p);
>>> return 1;
>>> }
>>> @@ -341,6 +355,7 @@ static int tcf_idr_release_unsafe(struct tc_action *p)
>>> return -EPERM;
>>>
>>> if (refcount_dec_and_test(&p->tcfa_refcnt)) {
>>> + tcf_action_offload_del(p);
>>> idr_remove(&p->idrinfo->action_idr, p->tcfa_index);
>>> tcf_action_cleanup(p);
>>> return ACT_P_DELETED;
>>> @@ -452,6 +467,7 @@ static int tcf_idr_delete_index(struct tcf_idrinfo
>>*idrinfo, u32 index)
>>> p->tcfa_index));
>>> mutex_unlock(&idrinfo->lock);
>>>
>>> + tcf_action_offload_del(p);
>>
>>tcf_action_offload_del() and tcf_action_cleanup() seem to be always called
>>together. Consider moving the call to tcf_action_offload_del() into
>>tcf_action_cleanup().
>>
> Thanks, we will consider to move tcf_action_offload_del() inside of tcf_action_cleanup.
>>> tcf_action_cleanup(p);
>>> module_put(owner);
>>> return 0;
>>> @@ -1061,6 +1077,154 @@ struct tc_action *tcf_action_init_1(struct net
>>*net, struct tcf_proto *tp,
>>> return ERR_PTR(err);
>>> }
>>>
> ...
>>> +/* offload the tc command after inserted */ static int
>>> +tcf_action_offload_add(struct tc_action *action,
>>> + struct netlink_ext_ack *extack) {
>>> + struct tc_action *actions[TCA_ACT_MAX_PRIO] = {
>>> + [0] = action,
>>> + };
>>> + struct flow_offload_action *fl_action;
>>> + int err = 0;
>>> +
>>> + fl_action = flow_action_alloc(tcf_act_num_actions_single(action));
>>> + if (!fl_action)
>>> + return -EINVAL;
>>
>>Failed alloc-like functions usually result -ENOMEM.
>>
> Thanks, we will fix this in V4 patch.
>>> +
>>> + err = flow_action_init(fl_action, action, FLOW_ACT_REPLACE, extack);
>>> + if (err)
>>> + goto fl_err;
>>> +
>>> + err = tc_setup_action(&fl_action->action, actions);
>>> + if (err) {
>>> + NL_SET_ERR_MSG_MOD(extack,
>>> + "Failed to setup tc actions for offload\n");
>>> + goto fl_err;
>>> + }
>>> +
>>> + err = tcf_action_offload_cmd(fl_action, extack);
>>> + tc_cleanup_flow_action(&fl_action->action);
>>> +
>>> +fl_err:
>>> + kfree(fl_action);
>>> +
>>> + return err;
>>> +}
>>> +
>>> +int tcf_action_offload_del(struct tc_action *action) {
>>> + struct flow_offload_action fl_act;
>>> + int err = 0;
>>> +
>>> + if (!action)
>>> + return -EINVAL;
>>> +
>>> + err = flow_action_init(&fl_act, action, FLOW_ACT_DESTROY, NULL);
>>> + if (err)
>>> + return err;
>>> +
>>> + return tcf_action_offload_cmd(&fl_act, NULL); }
>>> +
>>> /* Returns numbers of initialized actions or negative error. */
>>>
>>> int tcf_action_init(struct net *net, struct tcf_proto *tp, struct
>>> nlattr *nla, @@ -1103,6 +1267,8 @@ int tcf_action_init(struct net *net,
>>struct tcf_proto *tp, struct nlattr *nla,
>>> sz += tcf_action_fill_size(act);
>>> /* Start from index 0 */
>>> actions[i - 1] = act;
>>> + if (!(flags & TCA_ACT_FLAGS_BIND))
>>> + tcf_action_offload_add(act, extack);
>>> }
>>>
>>> /* We have to commit them all together, because if any error
>>> happened in diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
>>> index 2ef8f5a6205a..351d93988b8b 100644
>>> --- a/net/sched/cls_api.c
>>> +++ b/net/sched/cls_api.c
>>> @@ -3544,8 +3544,8 @@ static enum flow_action_hw_stats
>>tc_act_hw_stats(u8 hw_stats)
>>> return hw_stats;
>>> }
>>>
>>> -int tc_setup_flow_action(struct flow_action *flow_action,
>>> - const struct tcf_exts *exts)
>>> +int tc_setup_action(struct flow_action *flow_action,
>>> + struct tc_action *actions[])
>>> {
>>> struct tc_action *act;
>>> int i, j, k, err = 0;
>>> @@ -3554,11 +3554,11 @@ int tc_setup_flow_action(struct flow_action
>>*flow_action,
>>> BUILD_BUG_ON(TCA_ACT_HW_STATS_IMMEDIATE !=
>>FLOW_ACTION_HW_STATS_IMMEDIATE);
>>> BUILD_BUG_ON(TCA_ACT_HW_STATS_DELAYED !=
>>> FLOW_ACTION_HW_STATS_DELAYED);
>>>
>>> - if (!exts)
>>> + if (!actions)
>>> return 0;
>>>
>>> j = 0;
>>> - tcf_exts_for_each_action(i, act, exts) {
>>> + tcf_act_for_each_action(i, act, actions) {
>>> struct flow_action_entry *entry;
>>>
>>> entry = &flow_action->entries[j];
>>> @@ -3725,7 +3725,19 @@ int tc_setup_flow_action(struct flow_action
>>*flow_action,
>>> spin_unlock_bh(&act->tcfa_lock);
>>> goto err_out;
>>> }
>>> +EXPORT_SYMBOL(tc_setup_action);
>>> +
>>> +#ifdef CONFIG_NET_CLS_ACT
>>
>>Maybe just move tc_setup_action() to act_api and ifdef its definition in
>>pkt_cls.h instead of existing tc_setup_flow_action()?
> As explanation above, after the change, tc_setup_flow_action will call function of
> tc_setup_action and refer to exts->actions, so just move tc_setup_action can not
> fix this problem.
Got it.
>>> +int tc_setup_flow_action(struct flow_action *flow_action,
>>> + const struct tcf_exts *exts)
>>> +{
>>> + if (!exts)
>>> + return 0;
>>> +
>>> + return tc_setup_action(flow_action, exts->actions); }
>>> EXPORT_SYMBOL(tc_setup_flow_action);
>>> +#endif
>>>
>>> unsigned int tcf_exts_num_actions(struct tcf_exts *exts) { @@
>>> -3743,6 +3755,15 @@ unsigned int tcf_exts_num_actions(struct tcf_exts
>>> *exts) } EXPORT_SYMBOL(tcf_exts_num_actions);
>>>
>>> +unsigned int tcf_act_num_actions_single(struct tc_action *act) {
>>> + if (is_tcf_pedit(act))
>>> + return tcf_pedit_nkeys(act);
>>> + else
>>> + return 1;
>>> +}
>>> +EXPORT_SYMBOL(tcf_act_num_actions_single);
>>> +
>>> #ifdef CONFIG_NET_CLS_ACT
>>> static int tcf_qevent_parse_block_index(struct nlattr *block_index_attr,
>>> u32 *p_block_index,
next prev parent reply other threads:[~2021-11-01 12:05 UTC|newest]
Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-28 11:06 [RFC/PATCH net-next v3 0/8] allow user to offload tc action to net device Simon Horman
2021-10-28 11:06 ` [RFC/PATCH net-next v3 1/8] flow_offload: fill flags to action structure Simon Horman
2021-10-28 11:06 ` [RFC/PATCH net-next v3 2/8] flow_offload: reject to offload tc actions in offload drivers Simon Horman
2021-10-28 11:06 ` [RFC/PATCH net-next v3 3/8] flow_offload: allow user to offload tc action to net device Simon Horman
2021-10-29 16:59 ` Vlad Buslov
2021-11-01 9:44 ` Baowen Zheng
2021-11-01 12:05 ` Vlad Buslov [this message]
2021-11-02 1:38 ` Baowen Zheng
2021-10-31 9:50 ` Oz Shlomo
2021-11-01 2:30 ` Baowen Zheng
2021-11-01 10:07 ` Oz Shlomo
2021-11-01 10:27 ` Baowen Zheng
2021-10-28 11:06 ` [RFC/PATCH net-next v3 4/8] flow_offload: add skip_hw and skip_sw to control if offload the action Simon Horman
2021-10-28 11:06 ` [RFC/PATCH net-next v3 5/8] flow_offload: add process to update action stats from hardware Simon Horman
2021-10-29 17:11 ` Vlad Buslov
2021-11-01 10:07 ` Baowen Zheng
2021-10-28 11:06 ` [RFC/PATCH net-next v3 6/8] net: sched: save full flags for tc action Simon Horman
2021-10-28 11:06 ` [RFC/PATCH net-next v3 7/8] flow_offload: add reoffload process to update hw_count Simon Horman
2021-10-29 17:31 ` Vlad Buslov
2021-11-02 9:20 ` Baowen Zheng
2021-10-28 11:06 ` [RFC/PATCH net-next v3 8/8] flow_offload: validate flags of filter and actions Simon Horman
2021-10-28 19:12 ` kernel test robot
2021-10-29 18:01 ` Vlad Buslov
2021-10-30 10:54 ` Jamal Hadi Salim
2021-10-30 14:45 ` Vlad Buslov
[not found] ` <DM5PR1301MB21722A85B19EE97EFE27A5BBE7899@DM5PR1301MB2172.namprd13.prod.outlook.com>
2021-10-31 13:30 ` Jamal Hadi Salim
2021-11-01 3:29 ` Baowen Zheng
2021-11-01 7:38 ` Vlad Buslov
2021-11-02 12:39 ` Simon Horman
2021-11-03 7:57 ` Baowen Zheng
2021-11-03 10:13 ` Jamal Hadi Salim
2021-11-03 11:30 ` Baowen Zheng
2021-11-03 12:33 ` Jamal Hadi Salim
2021-11-03 13:33 ` Jamal Hadi Salim
2021-11-03 13:38 ` Simon Horman
2021-11-03 14:05 ` Jamal Hadi Salim
2021-11-03 14:03 ` Baowen Zheng
2021-11-03 14:16 ` Jamal Hadi Salim
2021-11-03 14:48 ` Baowen Zheng
2021-11-03 15:35 ` Jamal Hadi Salim
2021-11-03 13:37 ` Baowen Zheng
2021-11-04 2:30 ` Baowen Zheng
2021-11-04 5:51 ` Baowen Zheng
2021-11-04 9:07 ` Vlad Buslov
2021-11-04 11:15 ` Baowen Zheng
2021-10-28 14:23 ` [RFC/PATCH net-next v3 0/8] allow user to offload tc action to net device Jamal Hadi Salim
2021-10-28 14:39 ` Jamal Hadi Salim
2021-10-31 9:50 ` Oz Shlomo
2021-10-31 12:03 ` Dave Taht
2021-10-31 14:14 ` Jamal Hadi Salim
2021-10-31 14:19 ` Jamal Hadi Salim
2021-11-01 14:27 ` Dave Taht
2021-10-31 13:40 ` Jamal Hadi Salim
2021-11-01 8:01 ` Vlad Buslov
2021-11-02 12:51 ` Simon Horman
2021-11-02 15:33 ` Vlad Buslov
2021-11-02 16:15 ` Simon Horman
2021-11-03 10:56 ` Oz Shlomo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ygnh7dds9j3p.fsf@nvidia.com \
--to=vladbu@nvidia.com \
--cc=baowen.zheng@corigine.com \
--cc=idosch@nvidia.com \
--cc=jhs@mojatatu.com \
--cc=jiri@resnulli.us \
--cc=louis.peens@corigine.com \
--cc=netdev@vger.kernel.org \
--cc=notifications@github.com \
--cc=oss-drivers@corigine.com \
--cc=roid@nvidia.com \
--cc=simon.horman@corigine.com \
--cc=xiyou.wangcong@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.