From: Jarek Poplawski <jarkao2@gmail.com>
To: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Changli Gao <xiaosuo@gmail.com>,
David Miller <davem@davemloft.net>,
netdev <netdev@vger.kernel.org>,
Stephen Hemminger <shemminger@vyatta.com>,
Patrick McHardy <kaber@trash.net>
Subject: Re: [PATCH] pkt_sched: gen_kill_estimator() rcu fixes
Date: Wed, 9 Jun 2010 12:50:35 +0000 [thread overview]
Message-ID: <20100609125035.GD7308@ff.dom.local> (raw)
In-Reply-To: <1276085363.2442.125.camel@edumazet-laptop>
On Wed, Jun 09, 2010 at 02:09:23PM +0200, Eric Dumazet wrote:
> Le mercredi 09 juin 2010 ?? 10:41 +0000, Jarek Poplawski a écrit :
>
> > Spelling suggestion: xt_rateest_free_rcu?
> >
> > Since it's only 3 places I'd consider adding little comments,
> > who needs this call_rcu (like in qdisc_destroy).
> >
> > Anyway this patch looks OK to me.
> >
>
> Thanks for reviewing, you are right about typo and adding some comments.
>
> What about following ?
Very nice! (But let's remember these comments aren't very precise
wrt. bstats at the moment ;-)
Thanks,
Jarek P.
>
> [PATCH v2] pkt_sched: gen_kill_estimator() rcu fixes
>
> gen_kill_estimator() API is incomplete or not well documented, since
> caller should make sure an RCU grace period is respected before
> freeing stats_lock.
>
> This was partially addressed in commit 5d944c640b4
> (gen_estimator: deadlock fix), but same problem exist for all
> gen_kill_estimator() users, if lock they use is not already RCU
> protected.
>
> A code review shows xt_RATEEST.c, act_api.c, act_police.c have this
> problem. Other are ok because they use qdisc lock, already RCU
> protected.
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> ---
> include/net/act_api.h | 2 ++
> include/net/netfilter/xt_rateest.h | 1 +
> net/core/gen_estimator.c | 1 +
> net/netfilter/xt_RATEEST.c | 12 +++++++++++-
> net/sched/act_api.c | 11 ++++++++++-
> net/sched/act_police.c | 12 +++++++++++-
> 6 files changed, 36 insertions(+), 3 deletions(-)
>
> diff --git a/include/net/act_api.h b/include/net/act_api.h
> index c05fd71..bab385f 100644
> --- a/include/net/act_api.h
> +++ b/include/net/act_api.h
> @@ -20,6 +20,7 @@ struct tcf_common {
> struct gnet_stats_queue tcfc_qstats;
> struct gnet_stats_rate_est tcfc_rate_est;
> spinlock_t tcfc_lock;
> + struct rcu_head tcfc_rcu;
> };
> #define tcf_next common.tcfc_next
> #define tcf_index common.tcfc_index
> @@ -32,6 +33,7 @@ struct tcf_common {
> #define tcf_qstats common.tcfc_qstats
> #define tcf_rate_est common.tcfc_rate_est
> #define tcf_lock common.tcfc_lock
> +#define tcf_rcu common.tcfc_rcu
>
> struct tcf_police {
> struct tcf_common common;
> diff --git a/include/net/netfilter/xt_rateest.h b/include/net/netfilter/xt_rateest.h
> index ddbf37e..5e14277 100644
> --- a/include/net/netfilter/xt_rateest.h
> +++ b/include/net/netfilter/xt_rateest.h
> @@ -9,6 +9,7 @@ struct xt_rateest {
> struct gnet_estimator params;
> struct gnet_stats_rate_est rstats;
> struct gnet_stats_basic_packed bstats;
> + struct rcu_head rcu;
> };
>
> extern struct xt_rateest *xt_rateest_lookup(const char *name);
> diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c
> index 785e527..9fbe7f7 100644
> --- a/net/core/gen_estimator.c
> +++ b/net/core/gen_estimator.c
> @@ -263,6 +263,7 @@ static void __gen_kill_estimator(struct rcu_head *head)
> *
> * Removes the rate estimator specified by &bstats and &rate_est.
> *
> + * Note : Caller should respect an RCU grace period before freeing stats_lock
> */
> void gen_kill_estimator(struct gnet_stats_basic_packed *bstats,
> struct gnet_stats_rate_est *rate_est)
> diff --git a/net/netfilter/xt_RATEEST.c b/net/netfilter/xt_RATEEST.c
> index 69c01e1..de079ab 100644
> --- a/net/netfilter/xt_RATEEST.c
> +++ b/net/netfilter/xt_RATEEST.c
> @@ -60,13 +60,22 @@ struct xt_rateest *xt_rateest_lookup(const char *name)
> }
> EXPORT_SYMBOL_GPL(xt_rateest_lookup);
>
> +static void xt_rateest_free_rcu(struct rcu_head *head)
> +{
> + kfree(container_of(head, struct xt_rateest, rcu));
> +}
> +
> void xt_rateest_put(struct xt_rateest *est)
> {
> mutex_lock(&xt_rateest_mutex);
> if (--est->refcnt == 0) {
> hlist_del(&est->list);
> gen_kill_estimator(&est->bstats, &est->rstats);
> - kfree(est);
> + /*
> + * gen_estimator est_timer() might access est->lock or bstats,
> + * wait a RCU grace period before freeing 'est'
> + */
> + call_rcu(&est->rcu, xt_rateest_free_rcu);
> }
> mutex_unlock(&xt_rateest_mutex);
> }
> @@ -179,6 +188,7 @@ static int __init xt_rateest_tg_init(void)
> static void __exit xt_rateest_tg_fini(void)
> {
> xt_unregister_target(&xt_rateest_tg_reg);
> + rcu_barrier(); /* Wait for completion of call_rcu()'s (xt_rateest_free_rcu) */
> }
>
>
> diff --git a/net/sched/act_api.c b/net/sched/act_api.c
> index 972378f..23b25f8 100644
> --- a/net/sched/act_api.c
> +++ b/net/sched/act_api.c
> @@ -26,6 +26,11 @@
> #include <net/act_api.h>
> #include <net/netlink.h>
>
> +static void tcf_common_free_rcu(struct rcu_head *head)
> +{
> + kfree(container_of(head, struct tcf_common, tcfc_rcu));
> +}
> +
> void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo)
> {
> unsigned int h = tcf_hash(p->tcfc_index, hinfo->hmask);
> @@ -38,7 +43,11 @@ void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo)
> write_unlock_bh(hinfo->lock);
> gen_kill_estimator(&p->tcfc_bstats,
> &p->tcfc_rate_est);
> - kfree(p);
> + /*
> + * gen_estimator est_timer() might access p->tcfc_lock
> + * or bstats, wait a RCU grace period before freeing p
> + */
> + call_rcu(&p->tcfc_rcu, tcf_common_free_rcu);
> return;
> }
> }
> diff --git a/net/sched/act_police.c b/net/sched/act_police.c
> index 654f73d..537a487 100644
> --- a/net/sched/act_police.c
> +++ b/net/sched/act_police.c
> @@ -97,6 +97,11 @@ nla_put_failure:
> goto done;
> }
>
> +static void tcf_police_free_rcu(struct rcu_head *head)
> +{
> + kfree(container_of(head, struct tcf_police, tcf_rcu));
> +}
> +
> static void tcf_police_destroy(struct tcf_police *p)
> {
> unsigned int h = tcf_hash(p->tcf_index, POL_TAB_MASK);
> @@ -113,7 +118,11 @@ static void tcf_police_destroy(struct tcf_police *p)
> qdisc_put_rtab(p->tcfp_R_tab);
> if (p->tcfp_P_tab)
> qdisc_put_rtab(p->tcfp_P_tab);
> - kfree(p);
> + /*
> + * gen_estimator est_timer() might access p->tcf_lock
> + * or bstats, wait a RCU grace period before freeing p
> + */
> + call_rcu(&p->tcf_rcu, tcf_police_free_rcu);
> return;
> }
> }
> @@ -397,6 +406,7 @@ static void __exit
> police_cleanup_module(void)
> {
> tcf_unregister_action(&act_police_ops);
> + rcu_barrier(); /* Wait for completion of call_rcu()'s (tcf_police_free_rcu) */
> }
>
> module_init(police_init_module);
>
>
next prev parent reply other threads:[~2010-06-09 12:50 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-07 14:32 [PATCH net-next-2.6] pkt_sched: gen_estimator: kill est_lock rwlock Eric Dumazet
2010-06-07 14:53 ` Changli Gao
2010-06-07 15:30 ` Eric Dumazet
2010-06-07 15:55 ` Eric Dumazet
2010-06-07 16:56 ` [PATCH net-next-2.6 v2] " Eric Dumazet
2010-06-07 17:18 ` [PATCH net-2.6] pkt_sched: gen_estimator: add a new lock Eric Dumazet
2010-06-08 1:00 ` Changli Gao
2010-06-08 4:30 ` Eric Dumazet
2010-06-08 4:57 ` Changli Gao
2010-06-08 4:58 ` Eric Dumazet
2010-06-08 5:20 ` Changli Gao
2010-06-08 5:39 ` Eric Dumazet
2010-06-09 9:39 ` [PATCH net-2.6 v2] " Eric Dumazet
2010-06-09 11:33 ` Jarek Poplawski
2010-06-09 11:55 ` Eric Dumazet
2010-06-11 5:54 ` David Miller
2010-06-08 12:15 ` [PATCH net-next-2.6 v2] pkt_sched: gen_estimator: kill est_lock rwlock Jarek Poplawski
2010-06-08 12:27 ` Eric Dumazet
2010-06-08 12:40 ` Jarek Poplawski
2010-06-08 19:29 ` Jarek Poplawski
2010-06-08 19:45 ` Eric Dumazet
2010-06-08 20:24 ` Jarek Poplawski
2010-06-08 20:52 ` Eric Dumazet
2010-06-08 21:18 ` Jarek Poplawski
2010-06-09 6:13 ` pkt_sched: gen_estimator: more fuel for Jarek and Changli Eric Dumazet
2010-06-09 6:51 ` Jarek Poplawski
2010-06-09 7:36 ` Eric Dumazet
2010-06-09 8:14 ` Jarek Poplawski
2010-06-09 9:40 ` [PATCH] pkt_sched: gen_kill_estimator() rcu fixes Eric Dumazet
2010-06-09 9:56 ` Eric Dumazet
2010-06-09 10:41 ` Jarek Poplawski
2010-06-09 12:09 ` Eric Dumazet
2010-06-09 12:50 ` Jarek Poplawski [this message]
2010-06-09 13:05 ` Eric Dumazet
2010-06-12 1:39 ` David Miller
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=20100609125035.GD7308@ff.dom.local \
--to=jarkao2@gmail.com \
--cc=davem@davemloft.net \
--cc=eric.dumazet@gmail.com \
--cc=kaber@trash.net \
--cc=netdev@vger.kernel.org \
--cc=shemminger@vyatta.com \
--cc=xiaosuo@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.