From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
To: Vlad Buslov <vladbu@mellanox.com>
Cc: jiri@resnulli.us, netdev@vger.kernel.org, jhs@mojatatu.com,
xiyou.wangcong@gmail.com, davem@davemloft.net, ast@kernel.org,
daniel@iogearbox.net, kliteyn@mellanox.com
Subject: Re: [PATCH v3 04/11] net: sched: always take reference to action
Date: Mon, 28 May 2018 18:38:13 -0300 [thread overview]
Message-ID: <20180528213813.GJ3787@localhost.localdomain> (raw)
In-Reply-To: <1527455849-22327-5-git-send-email-vladbu@mellanox.com>
On Mon, May 28, 2018 at 12:17:22AM +0300, Vlad Buslov wrote:
> Without rtnl lock protection it is no longer safe to use pointer to tc
> action without holding reference to it. (it can be destroyed concurrently)
>
> Remove unsafe action idr lookup function. Instead of it, implement safe tcf
> idr check function that atomically looks up action in idr and increments
> its reference and bind counters. Implement both action search and check
> using new safe function
>
> Reference taken by idr check is temporal and should not be accounted by
> userspace clients (both logically and to preserver current API behavior).
> Subtract temporal reference when dumping action to userspace using existing
> tca_get_fill function arguments.
>
> Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
Reviewed-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
> ---
> Changes from V1 to V2:
> - Make __tcf_idr_check function static
> - Merge changes that take reference to action when performing lookup and
> changes that account for this additional reference when dumping action
> to user space into single patch.
>
> net/sched/act_api.c | 46 ++++++++++++++++++++--------------------------
> 1 file changed, 20 insertions(+), 26 deletions(-)
>
> diff --git a/net/sched/act_api.c b/net/sched/act_api.c
> index 256b0c93916c..aa304d36fee0 100644
> --- a/net/sched/act_api.c
> +++ b/net/sched/act_api.c
> @@ -284,44 +284,38 @@ int tcf_generic_walker(struct tc_action_net *tn, struct sk_buff *skb,
> }
> EXPORT_SYMBOL(tcf_generic_walker);
>
> -static struct tc_action *tcf_idr_lookup(u32 index, struct tcf_idrinfo *idrinfo)
> +static bool __tcf_idr_check(struct tc_action_net *tn, u32 index,
> + struct tc_action **a, int bind)
> {
> - struct tc_action *p = NULL;
> + struct tcf_idrinfo *idrinfo = tn->idrinfo;
> + struct tc_action *p;
>
> spin_lock(&idrinfo->lock);
> p = idr_find(&idrinfo->action_idr, index);
> + if (p) {
> + refcount_inc(&p->tcfa_refcnt);
> + if (bind)
> + atomic_inc(&p->tcfa_bindcnt);
> + }
> spin_unlock(&idrinfo->lock);
>
> - return p;
> + if (p) {
> + *a = p;
> + return true;
> + }
> + return false;
> }
>
> int tcf_idr_search(struct tc_action_net *tn, struct tc_action **a, u32 index)
> {
> - struct tcf_idrinfo *idrinfo = tn->idrinfo;
> - struct tc_action *p = tcf_idr_lookup(index, idrinfo);
> -
> - if (p) {
> - *a = p;
> - return 1;
> - }
> - return 0;
> + return __tcf_idr_check(tn, index, a, 0);
> }
> EXPORT_SYMBOL(tcf_idr_search);
>
> bool tcf_idr_check(struct tc_action_net *tn, u32 index, struct tc_action **a,
> int bind)
> {
> - struct tcf_idrinfo *idrinfo = tn->idrinfo;
> - struct tc_action *p = tcf_idr_lookup(index, idrinfo);
> -
> - if (index && p) {
> - if (bind)
> - atomic_inc(&p->tcfa_bindcnt);
> - refcount_inc(&p->tcfa_refcnt);
> - *a = p;
> - return true;
> - }
> - return false;
> + return __tcf_idr_check(tn, index, a, bind);
> }
> EXPORT_SYMBOL(tcf_idr_check);
>
> @@ -932,7 +926,7 @@ tcf_get_notify(struct net *net, u32 portid, struct nlmsghdr *n,
> if (!skb)
> return -ENOBUFS;
> if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, event,
> - 0, 0) <= 0) {
> + 0, 1) <= 0) {
> NL_SET_ERR_MSG(extack, "Failed to fill netlink attributes while adding TC action");
> kfree_skb(skb);
> return -EINVAL;
> @@ -1072,7 +1066,7 @@ tcf_del_notify(struct net *net, struct nlmsghdr *n, struct list_head *actions,
> return -ENOBUFS;
>
> if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, RTM_DELACTION,
> - 0, 1) <= 0) {
> + 0, 2) <= 0) {
> NL_SET_ERR_MSG(extack, "Failed to fill netlink TC action attributes");
> kfree_skb(skb);
> return -EINVAL;
> @@ -1131,14 +1125,14 @@ 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 */
> + cleanup_a(&actions, 1); /* lookup took reference */
> ret = tcf_del_notify(net, n, &actions, portid, attr_size, extack);
> if (ret)
> goto err;
> return ret;
> }
> err:
> - if (event != RTM_GETACTION)
> - tcf_action_destroy(&actions, 0);
> + tcf_action_destroy(&actions, 0);
> return ret;
> }
>
> --
> 2.7.5
>
next prev parent reply other threads:[~2018-05-28 21:38 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-27 16:41 [PATCH v2 00/11] Modify action API for implementing lockless actions Vlad Buslov
2018-05-27 16:41 ` [PATCH v2 01/11] net: sched: use rcu for action cookie update Vlad Buslov
2018-05-27 16:41 ` [PATCH v2 02/11] net: sched: change type of reference and bind counters Vlad Buslov
2018-05-27 16:41 ` [PATCH v2 03/11] net: sched: implement unlocked action init API Vlad Buslov
2018-05-27 16:41 ` [PATCH v2 04/11] net: sched: always take reference to action Vlad Buslov
2018-05-27 16:41 ` [PATCH v2 05/11] net: sched: implement action API that deletes action by index Vlad Buslov
2018-05-27 16:41 ` [PATCH v2 06/11] net: sched: add 'delete' function to action ops Vlad Buslov
2018-05-27 16:41 ` [PATCH v2 07/11] net: sched: implement reference counted action release Vlad Buslov
2018-05-27 16:41 ` [PATCH v2 08/11] net: sched: don't release reference on action overwrite Vlad Buslov
2018-05-27 16:41 ` [PATCH v2 09/11] net: sched: use reference counting action init Vlad Buslov
2018-05-27 16:41 ` [PATCH v2 10/11] net: sched: atomically check-allocate action Vlad Buslov
2018-05-27 16:41 ` [PATCH v2 11/11] net: sched: change action API to use array of pointers to actions Vlad Buslov
2018-05-27 17:57 ` [PATCH v2 00/11] Modify action API for implementing lockless actions Jiri Pirko
2018-05-27 21:17 ` [PATCH v3 " Vlad Buslov
2018-05-27 21:17 ` [PATCH v3 01/11] net: sched: use rcu for action cookie update Vlad Buslov
2018-05-28 21:37 ` Marcelo Ricardo Leitner
2018-05-27 21:17 ` [PATCH v3 02/11] net: sched: change type of reference and bind counters Vlad Buslov
2018-05-28 21:37 ` Marcelo Ricardo Leitner
2018-05-27 21:17 ` [PATCH v3 03/11] net: sched: implement unlocked action init API Vlad Buslov
2018-05-28 14:17 ` Jiri Pirko
2018-05-28 21:38 ` Marcelo Ricardo Leitner
2018-05-27 21:17 ` [PATCH v3 04/11] net: sched: always take reference to action Vlad Buslov
2018-05-28 14:19 ` Jiri Pirko
2018-05-28 21:38 ` Marcelo Ricardo Leitner [this message]
2018-05-27 21:17 ` [PATCH v3 05/11] net: sched: implement action API that deletes action by index Vlad Buslov
2018-05-28 14:21 ` Jiri Pirko
2018-05-28 21:38 ` Marcelo Ricardo Leitner
2018-05-27 21:17 ` [PATCH v3 06/11] net: sched: add 'delete' function to action ops Vlad Buslov
2018-05-28 14:21 ` Jiri Pirko
2018-05-28 21:38 ` Marcelo Ricardo Leitner
2018-05-27 21:17 ` [PATCH v3 07/11] net: sched: implement reference counted action release Vlad Buslov
2018-05-28 14:30 ` Jiri Pirko
2018-05-28 21:38 ` Marcelo Ricardo Leitner
2018-05-27 21:17 ` [PATCH v3 08/11] net: sched: don't release reference on action overwrite Vlad Buslov
2018-05-28 14:27 ` Jiri Pirko
2018-05-28 21:38 ` Marcelo Ricardo Leitner
2018-05-27 21:17 ` [PATCH v3 09/11] net: sched: use reference counting action init Vlad Buslov
2018-05-28 15:08 ` Jiri Pirko
2018-05-28 21:38 ` Marcelo Ricardo Leitner
2018-05-27 21:17 ` [PATCH v3 10/11] net: sched: atomically check-allocate action Vlad Buslov
2018-05-28 15:24 ` Jiri Pirko
2018-05-28 21:38 ` Marcelo Ricardo Leitner
2018-05-27 21:17 ` [PATCH v3 11/11] net: sched: change action API to use array of pointers to actions Vlad Buslov
2018-05-28 21:31 ` Marcelo Ricardo Leitner
2018-05-29 10:25 ` Vlad Buslov
2018-05-30 20:37 ` Jiri Pirko
2018-05-29 4:26 ` [PATCH v3 00/11] Modify action API for implementing lockless actions Cong Wang
2018-05-29 10:20 ` Vlad Buslov
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=20180528213813.GJ3787@localhost.localdomain \
--to=marcelo.leitner@gmail.com \
--cc=ast@kernel.org \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=jhs@mojatatu.com \
--cc=jiri@resnulli.us \
--cc=kliteyn@mellanox.com \
--cc=netdev@vger.kernel.org \
--cc=vladbu@mellanox.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.