From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
To: Lai Jiangshan <laijs@cn.fujitsu.com>
Cc: akpm@linux-foundation.org, Ingo Molnar <mingo@elte.hu>,
linux-kernel@vger.kernel.org, paulmck@linux.vnet.ibm.com,
dipankar@in.ibm.com, josh@joshtriplett.org, dvhltc@us.ibm.com,
niv@us.ibm.com, tglx@linutronix.de, peterz@infradead.org,
rostedt@goodmis.org, Valdis.Kletnieks@vt.edu,
dhowells@redhat.com, eric.dumazet@gmail.com, adobriyan@gmail.com
Subject: Re: [RFC patch 2/3] tree/tiny rcu: Add debug RCU head objects (v3)
Date: Mon, 22 Mar 2010 10:22:11 -0400 [thread overview]
Message-ID: <20100322142211.GA32453@Krystal> (raw)
In-Reply-To: <4BA6E515.4040001@cn.fujitsu.com>
* Lai Jiangshan (laijs@cn.fujitsu.com) wrote:
> Very nice you do not touch struct rcu_head.
>
> Mathieu Desnoyers wrote:
>
> > +
> > +#ifdef CONFIG_DEBUG_OBJECTS_RCU_HEAD
> > +# define STATE_RCU_HEAD_READY 0
> > +# define STATE_RCU_HEAD_QUEUED 1
> > +
> > +extern struct debug_obj_descr rcuhead_debug_descr;
> > +
> > +static inline void debug_rcu_head_queue(struct rcu_head *head)
> > +{
> > + debug_object_activate(head, &rcuhead_debug_descr);
> > + debug_object_active_state(head, &rcuhead_debug_descr,
> > + STATE_RCU_HEAD_READY,
> > + STATE_RCU_HEAD_QUEUED);
> > +}
> > +
> > +static inline void debug_rcu_head_unqueue(struct rcu_head *head)
> > +{
> > + debug_object_active_state(head, &rcuhead_debug_descr,
> > + STATE_RCU_HEAD_QUEUED,
> > + STATE_RCU_HEAD_READY);
> > + debug_object_deactivate(head, &rcuhead_debug_descr);
> > +}
>
> I'm a little foolish. I don't know why we need
> STATE_RCU_HEAD_READY/QUEUED.
>
> 1) obj->astate does not be set to STATE_RCU_HEAD_READY in
> debug_object_activate/init().
Yes it is. astate is set to 0 upon activation, and STATE_RCU_HEAD_READY is 0.
This is the initial state of the state machine (and also the accepting state).
Maybe I could document it a little bit more. Will write:
+/*
+ * Active state:
+ * - Set at 0 upon initialization.
+ * - Must return to 0 before deactivation.
+ */
+extern void
+debug_object_active_state(void *addr, struct debug_obj_descr *descr,
+ unsigned int expect, unsigned int next);
+
>
> Maybe you need to add a function:
> debug_object_activate_with_astate(head, descr, init_astate);
> (the same as debug_object_activate(), but init obj->astate also)
>
> Or you need:
> @debugobjects.h
> # define DEBUG_OBJECT_ASTATE_INIT 0
> @rcupdate.c
> # define STATE_RCU_HEAD_READY DEBUG_OBJECT_ASTATE_INIT
> # define STATE_RCU_HEAD_QUEUED (STATE_RCU_HEAD_READY + 1)
>
> 2) In debug_rcu_head_queue(), debug_object_active_state()
> is always success when debug_object_activate() is success.
>
> In debug_rcu_head_unqueue(), debug_object_active_state()
> is always success if RCU subsystem is running correctly.
>
> (Correct me if I'm wrong) So we don't need debug_object_active_state()
> here if we just find racy users of call_rcu().
Yes, but this debug infrastructure also detects problems that may arise in the
RCU subsystem itself: e.g. a rcu head that would be executed on two CPUs, which
could be caused by races between cpu hotplug and the RCU subsystem. I'm not
saying that we have these races currently, but that the RCU subsystems is now so
tied to complex parts of the kernel (scheduler, cpu hotplug) that it's bound to
have nasty bugs eventually.
So without the state machine, what we don't have in debugobjects is the ability
to detect a second "deactivation": debugobjects considers that an object can be
deactivated more than once without error. But in this case, just one
deactivation should be allowed. I thought that this state machine scheme would
allow following an object life more closely than just the
init/activate/deactivate/destroy/free phases. Maybe there could be ways to
combine the calls ? But.. given that it's for debugging purposes, do we care
that much about performance that it's worth creating new API members, making the
API more obscure ?
>
> > + */
> > +static int rcuhead_fixup_init(void *addr, enum debug_obj_state state)
> > +{
> > + struct rcu_head *head = addr;
> > +
> > + switch (state) {
> > + case ODEBUG_STATE_ACTIVE:
> > + /*
> > + * Ensure that queued callbacks are all executed.
> > + * If we detect that we are nested in a RCU read-side critical
> > + * section, we should simply fail, otherwise we would deadlock.
> > + */
> > + if (rcu_preempt_depth() != 0 || preempt_count() != 0 ||
> > + irqs_disabled()) {
> > + WARN_ON(1);
> > + return 0;
> > + }
>
> preempt_count() != 0 ??? What happen when !CONFIG_PREEMPT?
Will change for:
#ifndef CONFIG_PREEMPT
WARN_ON(1);
return 0;
#else
if (rcu_preempt_depth() != 0 || preempt_count() != 0 ||
irqs_disabled()) {
WARN_ON(1);
return 0;
}
rcu_barrier();
rcu_barrier_sched();
rcu_barrier_bh();
debug_object_activate(head, &rcuhead_debug_descr);
return 1;
#endif
>
> > + rcu_barrier();
>
> We may need call rcu_barrier(), rcu_barrier_sched(), rcu_barrier_bh() together?
> rcu_barrier() does not ensure to flush callbacks of RCU_BH, RCU_SCHED.
Right, will do.
Thanks,
Mathieu
>
> > + debug_object_init(head, &rcuhead_debug_descr);
> > + return 1;
> > + default:
> > + return 0;
> > + }
> > +}
> > +
>
--
Mathieu Desnoyers
Operating System Efficiency R&D Consultant
EfficiOS Inc.
http://www.efficios.com
next prev parent reply other threads:[~2010-03-22 14:22 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-03-19 20:47 [RFC patch 0/3] RCU head debug objects Mathieu Desnoyers
2010-03-19 20:47 ` [RFC patch 1/3] Debugobjects transition check Mathieu Desnoyers
2010-03-19 20:47 ` [RFC patch 2/3] tree/tiny rcu: Add debug RCU head objects (v3) Mathieu Desnoyers
2010-03-19 22:10 ` Alexey Dobriyan
2010-03-19 22:49 ` Paul E. McKenney
2010-03-22 3:33 ` Lai Jiangshan
2010-03-22 14:22 ` Mathieu Desnoyers [this message]
2010-03-19 20:47 ` [RFC patch 3/3] kernel call_rcu usage: initialize rcu_head structures Mathieu Desnoyers
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=20100322142211.GA32453@Krystal \
--to=mathieu.desnoyers@efficios.com \
--cc=Valdis.Kletnieks@vt.edu \
--cc=adobriyan@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=dhowells@redhat.com \
--cc=dipankar@in.ibm.com \
--cc=dvhltc@us.ibm.com \
--cc=eric.dumazet@gmail.com \
--cc=josh@joshtriplett.org \
--cc=laijs@cn.fujitsu.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=niv@us.ibm.com \
--cc=paulmck@linux.vnet.ibm.com \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
--cc=tglx@linutronix.de \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox