All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ranko Zivojnovic <ranko@spidernet.net>
To: Jarek Poplawski <jarkao2@o2.pl>
Cc: Patrick McHardy <kaber@trash.net>,
	akpm@linux-foundation.org, netdev@vger.kernel.org
Subject: Re: + gen_estimator-fix-locking-and-timer-related-bugs.patch added to -mm tree
Date: Tue, 10 Jul 2007 13:09:07 +0300	[thread overview]
Message-ID: <1184062147.11966.37.camel@localhost.localdomain> (raw)
In-Reply-To: <20070710073447.GA1870@ff.dom.local>

On Tue, 2007-07-10 at 09:34 +0200, Jarek Poplawski wrote:
> On Mon, Jul 09, 2007 at 07:43:40PM +0300, Ranko Zivojnovic wrote:
> > On Mon, 2007-07-09 at 15:52 +0200, Patrick McHardy wrote:
> > > Ranko Zivojnovic wrote:
> > > > Patrick, I've taken liberty to try and implement this myself. Attached
> > > > is the whole new gen_estimator-fix-locking-and-timer-related-bugs.patch
> > > > that is RCU lists based. Please be kind to review.
> ...
> 
> I've some doubts/suggestions too:
> 
> > --- a/net/core/gen_estimator.c	2007-06-25 02:21:48.000000000 +0300
> > +++ b/net/core/gen_estimator.c	2007-07-09 19:08:06.801544963 +0300
> ...
> > @@ -173,20 +172,24 @@
> >  	est->last_packets = bstats->packets;
> >  	est->avpps = rate_est->pps<<10;
> >  
> > -	est->next = elist[est->interval].list;
> > -	if (est->next == NULL) {
> > -		init_timer(&elist[est->interval].timer);
> > -		elist[est->interval].timer.data = est->interval;
> > -		elist[est->interval].timer.expires = jiffies + ((HZ<<est->interval)/4);
> > -		elist[est->interval].timer.function = est_timer;
> > -		add_timer(&elist[est->interval].timer);
> > +	if (!elist[idx].timer.function) {
> > +		INIT_LIST_HEAD(&elist[idx].list);
> > +		setup_timer(&elist[idx].timer, est_timer, est->interval);
> 
> s/est->interval/idx/ here and below.

Agree - will do by final submission.

> 
> >  	}
> > -	write_lock_bh(&est_lock);
> > -	elist[est->interval].list = est;
> > -	write_unlock_bh(&est_lock);
> > +		
> > +	if (list_empty(&elist[est->interval].list))
> > +		mod_timer(&elist[idx].timer, jiffies + ((HZ<<idx)/4));
> > +
> > +	list_add_rcu(&est->list, &elist[idx].list);
> >  	return 0;
> >  }
> >  
> > +static void __gen_kill_estimator(struct rcu_head *head)
> > +{
> > +	struct gen_estimator *e = container_of(head, struct gen_estimator, e_rcu);
> > +	kfree(e);
> > +}
> > +
> >  /**
> >   * gen_kill_estimator - remove a rate estimator
> >   * @bstats: basic statistics
> > @@ -199,26 +202,21 @@
> >  	struct gnet_stats_rate_est *rate_est)
> >  {
> ...
> > +		list_for_each_entry_safe(e, n, &elist[idx].list, list) {
> 
> IMHO, at least for readability list_for_each_entry_rcu() is better here.

Should not hurt - however functionality wise not necessary as the list
is protected by rtnl_mutex from being altered - also, for correctness,
it should be list_for_each_safe_rcu() as there is a list_del_rcu in the
loop... 

However I decided not to use _rcu based iteration neither the
rcu_read_lock() after going through the RCU documentation and a bunch of
examples in kernel that iterate through the lists using non _rcu macros
and do list_del_rcu() just fine.

For readability, the reference to list_del_rcu as well as call_rcu, I
believe, should be enough of the indication. Please do correct me if I
am wrong here.

> 
> > +			if (e->rate_est != rate_est || e->bstats != bstats)
> > +				continue;
> >  
> > -			kfree(est);
> > -			killed++;
> > +			list_del_rcu(&e->list);
> > +			call_rcu(&e->e_rcu, __gen_kill_estimator);
> 
> I think a race is possible here: e.g. a timer could be running
> after return from this function yet, and trying to use *bstats,
> *rate_est and maybe even stats_lock after their destruction.
> 

That will not happen because est_timer protects the loop with
rcu_read_lock() as well as the iteration is done using
list_for_each_entry_rcu(). The destruction callback is deferred and will
happen only after the outermost rcu_read_unlock() is called. Well - that
is at least what the documentation says...

> BTW, I think, rcu_read_lock/unlock are recommended around e.g.
> rcu lists traversals, even if the current implementation doesn't
> use them now.

I am afraid I do not understand what that the current implementation is
not using right now... The whole concept and the implementation of the
RCU, as I understand it, depends on rcu_read_lock/unlock to protect the
read-side critical sections...

Please be kind to elaborate...

R.


  reply	other threads:[~2007-07-10 10:10 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-06-27 19:21 + gen_estimator-fix-locking-and-timer-related-bugs.patch added to -mm tree akpm
     [not found] ` <1183642800.3789.11.camel@ranko-fc2.spidernet.net>
     [not found]   ` <20070705142135.GG4759@ff.dom.local>
     [not found]     ` <1183646029.4069.11.camel@ranko-fc2.spidernet.net>
     [not found]       ` <1183651165.4069.26.camel@ranko-fc2.spidernet.net>
2007-07-06  6:14         ` Jarek Poplawski
2007-07-06  6:20           ` Fwd: " Jarek Poplawski
2007-07-06  6:26           ` Jarek Poplawski
2007-07-06  6:45             ` Jarek Poplawski
2007-07-06 12:47               ` Jarek Poplawski
2007-07-06 13:16                 ` Ranko Zivojnovic
2007-07-09  8:25                   ` Jarek Poplawski
2007-07-06 13:14               ` Ranko Zivojnovic
2007-07-06 13:27                 ` Patrick McHardy
2007-07-06 13:59                   ` Ranko Zivojnovic
2007-07-06 14:21                 ` Patrick McHardy
2007-07-06 14:55                   ` Ranko Zivojnovic
2007-07-07  7:55                     ` Ranko Zivojnovic
2007-07-07 15:10                       ` Patrick McHardy
2007-07-09  7:47                         ` Jarek Poplawski
2007-07-09 12:41                         ` Ranko Zivojnovic
2007-07-09 13:52                           ` Patrick McHardy
2007-07-09 16:43                             ` Ranko Zivojnovic
2007-07-09 16:54                               ` Patrick McHardy
2007-07-10  7:34                               ` Jarek Poplawski
2007-07-10 10:09                                 ` Ranko Zivojnovic [this message]
2007-07-10 12:17                                   ` Jarek Poplawski
2007-07-10 12:20                                     ` Patrick McHardy
2007-07-10 13:10                                       ` Jarek Poplawski
2007-07-10 13:51                                         ` Jarek Poplawski

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=1184062147.11966.37.camel@localhost.localdomain \
    --to=ranko@spidernet.net \
    --cc=akpm@linux-foundation.org \
    --cc=jarkao2@o2.pl \
    --cc=kaber@trash.net \
    --cc=netdev@vger.kernel.org \
    /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.