Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 789871bb authored by Vlad Buslov's avatar Vlad Buslov Committed by David S. Miller
Browse files

net: sched: implement unlocked action init API



Add additional 'rtnl_held' argument to act API init functions. It is
required to implement actions that need to release rtnl lock before loading
kernel module and reacquire if afterwards.

Reviewed-by: default avatarMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: default avatarVlad Buslov <vladbu@mellanox.com>
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 036bb443
Loading
Loading
Loading
Loading
+4 −2
Original line number Original line Diff line number Diff line
@@ -92,7 +92,8 @@ struct tc_action_ops {
			  struct netlink_ext_ack *extack);
			  struct netlink_ext_ack *extack);
	int     (*init)(struct net *net, struct nlattr *nla,
	int     (*init)(struct net *net, struct nlattr *nla,
			struct nlattr *est, struct tc_action **act, int ovr,
			struct nlattr *est, struct tc_action **act, int ovr,
			int bind, struct netlink_ext_ack *extack);
			int bind, bool rtnl_held,
			struct netlink_ext_ack *extack);
	int     (*walk)(struct net *, struct sk_buff *,
	int     (*walk)(struct net *, struct sk_buff *,
			struct netlink_callback *, int,
			struct netlink_callback *, int,
			const struct tc_action_ops *,
			const struct tc_action_ops *,
@@ -168,10 +169,11 @@ int tcf_action_exec(struct sk_buff *skb, struct tc_action **actions,
int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
		    struct nlattr *est, char *name, int ovr, int bind,
		    struct nlattr *est, char *name, int ovr, int bind,
		    struct list_head *actions, size_t *attr_size,
		    struct list_head *actions, size_t *attr_size,
		    struct netlink_ext_ack *extack);
		    bool rtnl_held, struct netlink_ext_ack *extack);
struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
				    struct nlattr *nla, struct nlattr *est,
				    struct nlattr *nla, struct nlattr *est,
				    char *name, int ovr, int bind,
				    char *name, int ovr, int bind,
				    bool rtnl_held,
				    struct netlink_ext_ack *extack);
				    struct netlink_ext_ack *extack);
int tcf_action_dump(struct sk_buff *skb, struct list_head *, int, int);
int tcf_action_dump(struct sk_buff *skb, struct list_head *, int, int);
int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int);
int tcf_action_dump_old(struct sk_buff *skb, struct tc_action *a, int, int);
+11 −7
Original line number Original line Diff line number Diff line
@@ -671,6 +671,7 @@ static struct tc_cookie *nla_memdup_cookie(struct nlattr **tb)
struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
				    struct nlattr *nla, struct nlattr *est,
				    struct nlattr *nla, struct nlattr *est,
				    char *name, int ovr, int bind,
				    char *name, int ovr, int bind,
				    bool rtnl_held,
				    struct netlink_ext_ack *extack)
				    struct netlink_ext_ack *extack)
{
{
	struct tc_action *a;
	struct tc_action *a;
@@ -721,8 +722,10 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
	a_o = tc_lookup_action_n(act_name);
	a_o = tc_lookup_action_n(act_name);
	if (a_o == NULL) {
	if (a_o == NULL) {
#ifdef CONFIG_MODULES
#ifdef CONFIG_MODULES
		if (rtnl_held)
			rtnl_unlock();
			rtnl_unlock();
		request_module("act_%s", act_name);
		request_module("act_%s", act_name);
		if (rtnl_held)
			rtnl_lock();
			rtnl_lock();


		a_o = tc_lookup_action_n(act_name);
		a_o = tc_lookup_action_n(act_name);
@@ -746,9 +749,10 @@ struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp,
	/* backward compatibility for policer */
	/* backward compatibility for policer */
	if (name == NULL)
	if (name == NULL)
		err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, &a, ovr, bind,
		err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, &a, ovr, bind,
				extack);
				rtnl_held, extack);
	else
	else
		err = a_o->init(net, nla, est, &a, ovr, bind, extack);
		err = a_o->init(net, nla, est, &a, ovr, bind, rtnl_held,
				extack);
	if (err < 0)
	if (err < 0)
		goto err_mod;
		goto err_mod;


@@ -800,7 +804,7 @@ static void cleanup_a(struct list_head *actions, int ovr)
int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,
		    struct nlattr *est, char *name, int ovr, int bind,
		    struct nlattr *est, char *name, int ovr, int bind,
		    struct list_head *actions, size_t *attr_size,
		    struct list_head *actions, size_t *attr_size,
		    struct netlink_ext_ack *extack)
		    bool rtnl_held, struct netlink_ext_ack *extack)
{
{
	struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
	struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
	struct tc_action *act;
	struct tc_action *act;
@@ -814,7 +818,7 @@ int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla,


	for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
	for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
		act = tcf_action_init_1(net, tp, tb[i], est, name, ovr, bind,
		act = tcf_action_init_1(net, tp, tb[i], est, name, ovr, bind,
					extack);
					rtnl_held, extack);
		if (IS_ERR(act)) {
		if (IS_ERR(act)) {
			err = PTR_ERR(act);
			err = PTR_ERR(act);
			goto err;
			goto err;
@@ -1173,7 +1177,7 @@ static int tcf_action_add(struct net *net, struct nlattr *nla,
	LIST_HEAD(actions);
	LIST_HEAD(actions);


	ret = tcf_action_init(net, NULL, nla, NULL, NULL, ovr, 0, &actions,
	ret = tcf_action_init(net, NULL, nla, NULL, NULL, ovr, 0, &actions,
			      &attr_size, extack);
			      &attr_size, true, extack);
	if (ret)
	if (ret)
		return ret;
		return ret;


+2 −1
Original line number Original line Diff line number Diff line
@@ -276,7 +276,8 @@ static void tcf_bpf_prog_fill_cfg(const struct tcf_bpf *prog,


static int tcf_bpf_init(struct net *net, struct nlattr *nla,
static int tcf_bpf_init(struct net *net, struct nlattr *nla,
			struct nlattr *est, struct tc_action **act,
			struct nlattr *est, struct tc_action **act,
			int replace, int bind, struct netlink_ext_ack *extack)
			int replace, int bind, bool rtnl_held,
			struct netlink_ext_ack *extack)
{
{
	struct tc_action_net *tn = net_generic(net, bpf_net_id);
	struct tc_action_net *tn = net_generic(net, bpf_net_id);
	struct nlattr *tb[TCA_ACT_BPF_MAX + 1];
	struct nlattr *tb[TCA_ACT_BPF_MAX + 1];
+1 −1
Original line number Original line Diff line number Diff line
@@ -96,7 +96,7 @@ static const struct nla_policy connmark_policy[TCA_CONNMARK_MAX + 1] = {


static int tcf_connmark_init(struct net *net, struct nlattr *nla,
static int tcf_connmark_init(struct net *net, struct nlattr *nla,
			     struct nlattr *est, struct tc_action **a,
			     struct nlattr *est, struct tc_action **a,
			     int ovr, int bind,
			     int ovr, int bind, bool rtnl_held,
			     struct netlink_ext_ack *extack)
			     struct netlink_ext_ack *extack)
{
{
	struct tc_action_net *tn = net_generic(net, connmark_net_id);
	struct tc_action_net *tn = net_generic(net, connmark_net_id);
+2 −1
Original line number Original line Diff line number Diff line
@@ -46,7 +46,8 @@ static struct tc_action_ops act_csum_ops;


static int tcf_csum_init(struct net *net, struct nlattr *nla,
static int tcf_csum_init(struct net *net, struct nlattr *nla,
			 struct nlattr *est, struct tc_action **a, int ovr,
			 struct nlattr *est, struct tc_action **a, int ovr,
			 int bind, struct netlink_ext_ack *extack)
			 int bind, bool rtnl_held,
			 struct netlink_ext_ack *extack)
{
{
	struct tc_action_net *tn = net_generic(net, csum_net_id);
	struct tc_action_net *tn = net_generic(net, csum_net_id);
	struct tcf_csum_params *params_old, *params_new;
	struct tcf_csum_params *params_old, *params_new;
Loading