All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vlad Buslov <vladbu@nvidia.com>
To: Simon Horman <simon.horman@corigine.com>
Cc: David Miller <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>,
	Jamal Hadi Salim <jhs@mojatatu.com>,
	Cong Wang <xiyou.wangcong@gmail.com>,
	Jiri Pirko <jiri@mellanox.com>, <netdev@vger.kernel.org>,
	<oss-drivers@corigine.com>,
	Baowen Zheng <baowen.zheng@corigine.com>,
	"Louis Peens" <louis.peens@corigine.com>
Subject: Re: [PATCH net-next 2/3] flow_offload: add process to delete offloaded actions from net device
Date: Thu, 22 Jul 2021 17:25:13 +0300	[thread overview]
Message-ID: <ygnhfsw6qvcm.fsf@nvidia.com> (raw)
In-Reply-To: <20210722091938.12956-3-simon.horman@corigine.com>

On Thu 22 Jul 2021 at 12:19, Simon Horman <simon.horman@corigine.com> wrote:
> From: Baowen Zheng <baowen.zheng@corigine.com>
>
> Add a basic process to delete offloaded actions from net device.
>
> Should not remove the offloaded action entries if the action
> fails to delete in tcf_del_notify.
>
> 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/net/pkt_cls.h |   1 +
>  net/sched/act_api.c   | 112 +++++++++++++++++++++++++++++++++++-------
>  net/sched/cls_api.c   |  14 ++++--
>  3 files changed, 106 insertions(+), 21 deletions(-)
>
> diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
> index cd4cf6b10f5d..03dae225d64f 100644
> --- a/include/net/pkt_cls.h
> +++ b/include/net/pkt_cls.h
> @@ -573,6 +573,7 @@ int tc_setup_cb_reoffload(struct tcf_block *block, struct tcf_proto *tp,
>  			  void *cb_priv, u32 *flags, unsigned int *in_hw_count);
>  unsigned int tcf_exts_num_actions(struct tcf_exts *exts);
>  unsigned int tcf_act_num_actions(struct tc_action *actions[]);
> +unsigned int tcf_act_num_actions_single(struct tc_action *act);
>  
>  #ifdef CONFIG_NET_CLS_ACT
>  int tcf_qevent_init(struct tcf_qevent *qe, struct Qdisc *sch,
> diff --git a/net/sched/act_api.c b/net/sched/act_api.c
> index 185f17ea60d5..23a4538916af 100644
> --- a/net/sched/act_api.c
> +++ b/net/sched/act_api.c
> @@ -1060,36 +1060,109 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
>  	return ERR_PTR(err);
>  }
>  
> -/* offload the tc command after inserted */
> -int tcf_action_offload_cmd(struct tc_action *actions[],
> -			   struct netlink_ext_ack *extack)
> +int tcf_action_offload_cmd_pre(struct tc_action *actions[],
> +			       enum flow_act_command cmd,
> +			       struct netlink_ext_ack *extack,
> +			       struct flow_offload_action **fl_act)
>  {
> -	struct flow_offload_action *fl_act;
> +	struct flow_offload_action *fl_act_p;
>  	int err = 0;
>  
> -	fl_act = flow_action_alloc(tcf_act_num_actions(actions));
> -	if (!fl_act)
> +	fl_act_p = flow_action_alloc(tcf_act_num_actions(actions));
> +	if (!fl_act_p)
>  		return -ENOMEM;
>  
> -	fl_act->extack = extack;
> -	err = tc_setup_action(&fl_act->action, actions);
> +	fl_act_p->extack = extack;
> +	fl_act_p->command = cmd;
> +	err = tc_setup_action(&fl_act_p->action, actions);
>  	if (err) {
>  		NL_SET_ERR_MSG_MOD(extack,
>  				   "Failed to setup tc actions for offload\n");
>  		goto err_out;
>  	}
> -	fl_act->command = FLOW_ACT_REPLACE;
> +	*fl_act = fl_act_p;
> +	return 0;
> +err_out:
> +	kfree(fl_act_p);
> +	return err;
> +}
> +EXPORT_SYMBOL(tcf_action_offload_cmd_pre);

This doesn't seem be used anywhere outside this file.

> +
> +int tcf_action_offload_cmd_post(struct flow_offload_action *fl_act,
> +				struct netlink_ext_ack *extack)
> +{
> +	if (IS_ERR(fl_act))
> +		return PTR_ERR(fl_act);
>  
>  	flow_indr_dev_setup_offload(NULL, NULL, TC_SETUP_ACT, fl_act, NULL, NULL);
>  
>  	tc_cleanup_flow_action(&fl_act->action);
> -
> -err_out:
>  	kfree(fl_act);
> -	return err;
> +	return 0;
> +}

This one is not exported, by is non-static.

> +
> +/* offload the tc command after inserted */
> +int tcf_action_offload_cmd(struct tc_action *actions[],
> +			   struct netlink_ext_ack *extack)
> +{
> +	struct flow_offload_action *fl_act;
> +	int err = 0;
> +
> +	err = tcf_action_offload_cmd_pre(actions,
> +					 FLOW_ACT_REPLACE,
> +					 extack,
> +					 &fl_act);
> +	if (err)
> +		return err;
> +
> +	return tcf_action_offload_cmd_post(fl_act, extack);
>  }
>  EXPORT_SYMBOL(tcf_action_offload_cmd);
>  
> +/* offload the tc command after deleted */
> +int tcf_action_offload_del_post(struct flow_offload_action *fl_act,
> +				struct tc_action *actions[],
> +				struct netlink_ext_ack *extack,
> +				int fallback_num)
> +{
> +	int fallback_entries = 0;
> +	struct tc_action *act;
> +	int total_entries = 0;
> +	int i;
> +
> +	if (!fl_act)
> +		return -EINVAL;
> +
> +	if (fallback_num) {
> +		/* for each the actions to fallback the action entries remain in the actions */
> +		for (i = 0; i < TCA_ACT_MAX_PRIO; i++) {
> +			act = actions[i];
> +			if (!act)
> +				continue;
> +
> +			fallback_entries += tcf_act_num_actions_single(act);
> +		}
> +		fallback_entries += fallback_num;
> +	}
> +	total_entries = fl_act->action.num_entries;
> +	if (total_entries > fallback_entries) {
> +		/* just offload the actions that is not fallback and start with the actions */
> +		fl_act->action.num_entries -= fallback_entries;
> +		flow_indr_dev_setup_offload(NULL, NULL, TC_SETUP_ACT, fl_act, NULL, NULL);
> +
> +		/* recovery num_entries for cleanup */
> +		fl_act->action.num_entries = total_entries;
> +	} else {
> +		NL_SET_ERR_MSG(extack, "no entries to offload when deleting the tc actions");
> +	}
> +
> +	tc_cleanup_flow_action(&fl_act->action);
> +
> +	kfree(fl_act);
> +	return 0;
> +}
> +EXPORT_SYMBOL(tcf_action_offload_del_post);
> +
>  /* Returns numbers of initialized actions or negative error. */
>  
>  int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
> @@ -1393,7 +1466,7 @@ static int tca_action_flush(struct net *net, struct nlattr *nla,
>  	return err;
>  }
>  
> -static int tcf_action_delete(struct net *net, struct tc_action *actions[])
> +static int tcf_action_delete(struct net *net, struct tc_action *actions[], int *fallbacknum)
>  {
>  	int i;
>  
> @@ -1407,6 +1480,7 @@ static int tcf_action_delete(struct net *net, struct tc_action *actions[])
>  		u32 act_index = a->tcfa_index;
>  
>  		actions[i] = NULL;
> +		*fallbacknum = tcf_act_num_actions_single(a);
>  		if (tcf_action_put(a)) {
>  			/* last reference, action was deleted concurrently */
>  			module_put(ops->owner);
> @@ -1419,12 +1493,13 @@ static int tcf_action_delete(struct net *net, struct tc_action *actions[])
>  				return ret;
>  		}
>  	}
> +	*fallbacknum = 0;
>  	return 0;
>  }
>  
>  static int
>  tcf_del_notify(struct net *net, struct nlmsghdr *n, struct tc_action *actions[],
> -	       u32 portid, size_t attr_size, struct netlink_ext_ack *extack)
> +	       u32 portid, size_t attr_size, struct netlink_ext_ack *extack, int *fallbacknum)
>  {
>  	int ret;
>  	struct sk_buff *skb;
> @@ -1442,7 +1517,7 @@ tcf_del_notify(struct net *net, struct nlmsghdr *n, struct tc_action *actions[],
>  	}
>  
>  	/* now do the delete */
> -	ret = tcf_action_delete(net, actions);
> +	ret = tcf_action_delete(net, actions, fallbacknum);
>  	if (ret < 0) {
>  		NL_SET_ERR_MSG(extack, "Failed to delete TC action");
>  		kfree_skb(skb);
> @@ -1458,11 +1533,12 @@ static int
>  tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
>  	      u32 portid, int event, struct netlink_ext_ack *extack)
>  {
> -	int i, ret;
>  	struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
>  	struct tc_action *act;
>  	size_t attr_size = 0;
>  	struct tc_action *actions[TCA_ACT_MAX_PRIO] = {};
> +	struct flow_offload_action *fl_act;
> +	int i, ret, fallback_num;
>  
>  	ret = nla_parse_nested_deprecated(tb, TCA_ACT_MAX_PRIO, nla, NULL,
>  					  extack);
> @@ -1492,7 +1568,9 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
>  	if (event == RTM_GETACTION)
>  		ret = tcf_get_notify(net, portid, n, actions, event, extack);
>  	else { /* delete */
> -		ret = tcf_del_notify(net, n, actions, portid, attr_size, extack);
> +		tcf_action_offload_cmd_pre(actions, FLOW_ACT_DESTROY, extack, &fl_act);
> +		ret = tcf_del_notify(net, n, actions, portid, attr_size, extack, &fallback_num);
> +		tcf_action_offload_del_post(fl_act, actions, extack, fallback_num);

This tcf_action_offload_cmd_{pre|post}() approach looks slightly
complicated, especially with fallback_num calculations. I would suggest
to simplify it by only initializing action cookies in
flow_action->entries[] (I assume you don't really need all the action
data just to delete it, right?) for DEL/STATS and do one of the
following:

- Unoffload actions one-by-one after every deletion in
  tcf_actions_delete(), perhaps reusing the same flow_offload_action of
  size 1 by only changing the cookie on each iteration.

- If you really want to send the whole batch to the driver, save cookies
  for all successfully deleted actions in an array and initialize
  compound flow_offload_action from the array.

This would remove the need for whole pre/post thing, which otherwise
gets even more complicated in following patch by 'keep_fl_act' arg.

>  		if (ret)
>  			goto err;
>  		return 0;
> diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
> index 9b9770dab5e8..23ce021f07f8 100644
> --- a/net/sched/cls_api.c
> +++ b/net/sched/cls_api.c
> @@ -3755,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);
> +
>  unsigned int tcf_act_num_actions(struct tc_action *actions[])
>  {
>  	unsigned int num_acts = 0;
> @@ -3762,10 +3771,7 @@ unsigned int tcf_act_num_actions(struct tc_action *actions[])
>  	int i;
>  
>  	tcf_act_for_each_action(i, act, actions) {
> -		if (is_tcf_pedit(act))
> -			num_acts += tcf_pedit_nkeys(act);
> -		else
> -			num_acts++;
> +		num_acts += tcf_act_num_actions_single(act);
>  	}
>  	return num_acts;
>  }


  reply	other threads:[~2021-07-22 14:25 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-22  9:19 [PATCH net-next 0/3] flow_offload: hardware offload of TC actions Simon Horman
2021-07-22  9:19 ` [PATCH net-next 1/3] flow_offload: allow user to offload tc action to net device Simon Horman
2021-07-22 12:24   ` Roi Dayan
2021-07-22 13:19     ` Simon Horman
2021-07-22 13:29   ` Vlad Buslov
2021-07-22 13:33     ` Jamal Hadi Salim
2021-07-27 13:04       ` Simon Horman
2021-07-27 14:38         ` Vlad Buslov
2021-07-27 16:13           ` Jamal Hadi Salim
2021-07-27 16:47             ` Vlad Buslov
2021-07-28  7:46               ` Simon Horman
2021-07-28  8:05                 ` Vlad Buslov
2021-07-28 13:51                 ` Jamal Hadi Salim
2021-07-28 14:46                   ` Simon Horman
2021-07-30 10:17                     ` Jamal Hadi Salim
2021-07-30 11:40                       ` Vlad Buslov
2021-08-03  9:57                         ` Jamal Hadi Salim
2021-08-03 12:02                           ` tc offload debug-ability Jamal Hadi Salim
2021-08-03 12:14                             ` Vlad Buslov
2021-08-03 12:50                               ` Jamal Hadi Salim
2021-08-03 13:34                                 ` Ido Schimmel
2021-07-30 13:20                       ` [PATCH net-next 1/3] flow_offload: allow user to offload tc action to net device Simon Horman
2021-08-03 10:14                         ` Jamal Hadi Salim
2021-08-03 11:36                           ` Simon Horman
2021-08-03 11:45                             ` Jamal Hadi Salim
2021-08-03 12:31                               ` Simon Horman
2021-08-03 13:01                                 ` Jamal Hadi Salim
2021-08-03 14:46                                   ` Simon Horman
2021-07-22 13:57   ` kernel test robot
2021-07-22 13:57     ` kernel test robot
2021-07-22 15:31   ` kernel test robot
2021-07-22 15:31     ` kernel test robot
2021-08-03 10:50   ` Jamal Hadi Salim
2021-08-03 11:05   ` Jamal Hadi Salim
2021-08-03 11:31     ` Simon Horman
2021-07-22  9:19 ` [PATCH net-next 2/3] flow_offload: add process to delete offloaded actions from " Simon Horman
2021-07-22 14:25   ` Vlad Buslov [this message]
2021-07-22 14:50   ` kernel test robot
2021-07-22 14:50     ` kernel test robot
2021-07-22 17:07   ` kernel test robot
2021-07-22 17:07     ` kernel test robot
2021-08-03 10:59   ` Jamal Hadi Salim
2021-07-22  9:19 ` [PATCH net-next 3/3] flow_offload: add process to update action stats from hardware Simon Horman
2021-07-22 14:55   ` Vlad Buslov
2021-08-03 11:24   ` Jamal Hadi Salim
2021-08-03 11:35     ` Simon Horman

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=ygnhfsw6qvcm.fsf@nvidia.com \
    --to=vladbu@nvidia.com \
    --cc=baowen.zheng@corigine.com \
    --cc=davem@davemloft.net \
    --cc=jhs@mojatatu.com \
    --cc=jiri@mellanox.com \
    --cc=kuba@kernel.org \
    --cc=louis.peens@corigine.com \
    --cc=netdev@vger.kernel.org \
    --cc=oss-drivers@corigine.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.