From: Lai Jiangshan <laijs@cn.fujitsu.com>
To: paulmck@linux.vnet.ibm.com
Cc: linux-kernel@vger.kernel.org, mingo@elte.hu, rjw@sisk.pl,
dipankar@in.ibm.com, tglx@linuxtronix.de, andi@firstfloor.org
Subject: Re: [PATCH] rudimentary tracing for Classic RCU
Date: Thu, 09 Oct 2008 14:20:22 +0800 [thread overview]
Message-ID: <48EDA2A6.9070707@cn.fujitsu.com> (raw)
In-Reply-To: <20081009010846.GA10188@linux.vnet.ibm.com>
Paul E. McKenney wrote:
> Hello!
>
> This is a tracing patch for Classic RCU, which creates an "rcu/rcucb"
> file in debugfs. This patch can be handy when you need to work out
> why RCU is refusing to end the current grace period.
>
> Reading from the file results in something like the following:
>
> rcu: cur=1129 completed=1128 np=0 s=0
> 0,3,7
> rcu_bh: cur=-287 completed=-287 np=0 s=0
>
> online: 0-7
>
> The first two lines are for rcu, the second two for rcu_bh.
> The cur= is the current grace-period number, and the completed=
> is the number of the last completed grace period. If these two
> numbers are equal, the corresponding flavor of RCU is idle.
> The np= is a flag indicating that an additional RCU grace period
> beyond the current one will be required. The s=, if non-zero,
> indicates that a round of reschedule IPIs has been send to
> attempt to expedite the current grace period.
>
> The second and fourth lines are a comma/dash-separated list of
> the CPUs that have not yet reported a quiescent state for the
> current grace period (CPUs 0, 3, and 7 for "rcu" above).
>
> The last line lists the online CPUs.
>
> Tested on x86 and Power.
>
> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> ---
>
> include/linux/rcuclassic.h | 3 +
> kernel/Kconfig.preempt | 1
> kernel/Makefile | 2
> kernel/rcuclassic.c | 4 -
> kernel/rcuclassic_trace.c | 126 +++++++++++++++++++++++++++++++++++++++++++++
> 5 files changed, 133 insertions(+), 3 deletions(-)
>
> diff --git a/include/linux/rcuclassic.h b/include/linux/rcuclassic.h
> index 4ab8436..061a272 100644
> --- a/include/linux/rcuclassic.h
> +++ b/include/linux/rcuclassic.h
> @@ -54,6 +54,9 @@ struct rcu_ctrlblk {
> /* for current batch to proceed. */
> } ____cacheline_internodealigned_in_smp;
>
> +extern struct rcu_ctrlblk rcu_ctrlblk;
> +extern struct rcu_ctrlblk rcu_bh_ctrlblk;
> +
> /* Is batch a before batch b ? */
> static inline int rcu_batch_before(long a, long b)
> {
> diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt
> index 9fdba03..ba32338 100644
> --- a/kernel/Kconfig.preempt
> +++ b/kernel/Kconfig.preempt
> @@ -68,7 +68,6 @@ config PREEMPT_RCU
>
> config RCU_TRACE
> bool "Enable tracing for RCU - currently stats in debugfs"
> - depends on PREEMPT_RCU
> select DEBUG_FS
> default y
> help
I think that we can move it to lib/Kconfig.debug.
> diff --git a/kernel/Makefile b/kernel/Makefile
> index 4e1d7df..e0bfce7 100644
> --- a/kernel/Makefile
> +++ b/kernel/Makefile
> @@ -77,6 +77,8 @@ obj-$(CONFIG_CLASSIC_RCU) += rcuclassic.o
> obj-$(CONFIG_PREEMPT_RCU) += rcupreempt.o
> ifeq ($(CONFIG_PREEMPT_RCU),y)
> obj-$(CONFIG_RCU_TRACE) += rcupreempt_trace.o
> +else
> +obj-$(CONFIG_RCU_TRACE) += rcuclassic_trace.o
> endif
> obj-$(CONFIG_RELAY) += relay.o
> obj-$(CONFIG_SYSCTL) += utsname_sysctl.o
> diff --git a/kernel/rcuclassic.c b/kernel/rcuclassic.c
> index aad93cd..517eaa9 100644
> --- a/kernel/rcuclassic.c
> +++ b/kernel/rcuclassic.c
> @@ -57,13 +57,13 @@ EXPORT_SYMBOL_GPL(rcu_lock_map);
>
>
> /* Definition for rcupdate control block. */
> -static struct rcu_ctrlblk rcu_ctrlblk = {
> +struct rcu_ctrlblk rcu_ctrlblk = {
> .cur = -300,
> .completed = -300,
> .lock = __SPIN_LOCK_UNLOCKED(&rcu_ctrlblk.lock),
> .cpumask = CPU_MASK_NONE,
> };
> -static struct rcu_ctrlblk rcu_bh_ctrlblk = {
> +struct rcu_ctrlblk rcu_bh_ctrlblk = {
> .cur = -300,
> .completed = -300,
> .lock = __SPIN_LOCK_UNLOCKED(&rcu_bh_ctrlblk.lock),
> diff --git a/kernel/rcuclassic_trace.c b/kernel/rcuclassic_trace.c
> new file mode 100644
> index 0000000..f8b9313
> --- /dev/null
> +++ b/kernel/rcuclassic_trace.c
> @@ -0,0 +1,126 @@
> +/*
> + * Read-Copy Update tracing for classic implementation
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
> + *
> + * Copyright IBM Corporation, 2008
> + *
> + * Papers: http://www.rdrop.com/users/paulmck/RCU
> + *
> + * For detailed explanation of Read-Copy Update mechanism see -
> + * Documentation/RCU
> + *
> + */
> +#include <linux/types.h>
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/spinlock.h>
> +#include <linux/smp.h>
> +#include <linux/rcupdate.h>
> +#include <linux/interrupt.h>
> +#include <linux/sched.h>
> +#include <asm/atomic.h>
> +#include <linux/bitops.h>
> +#include <linux/module.h>
> +#include <linux/completion.h>
> +#include <linux/moduleparam.h>
> +#include <linux/percpu.h>
> +#include <linux/notifier.h>
> +#include <linux/cpu.h>
> +#include <linux/mutex.h>
> +#include <linux/debugfs.h>
> +
> +static DEFINE_MUTEX(rcuclassic_trace_mutex);
> +static char *rcuclassic_trace_buf;
> +#define RCUCLASSIC_TRACE_BUF_SIZE (20*NR_CPUS + 100)
> +
> +static int print_one_rcu_ctrlblk(struct rcu_ctrlblk *rcp, char *buf, char *ebuf)
> +{
> + int cnt = 0;
> +
> + cnt += snprintf(&buf[cnt], ebuf - &buf[cnt], "cur=%ld completed=%ld "
> + "np=%d s=%d\n\t",
> + rcp->cur, rcp->completed,
> + rcp->next_pending, rcp->signaled);
> + cnt += cpulist_scnprintf(&buf[cnt], ebuf - &buf[cnt], rcp->cpumask);
> + cnt += snprintf(&buf[cnt], ebuf - &buf[cnt], "\n");
> + return cnt;
> +}
> +
> +static ssize_t rcucb_read(struct file *filp, char __user *buffer,
> + size_t count, loff_t *ppos)
> +{
> + ssize_t bcount;
> + char *buf = rcuclassic_trace_buf;
> + char *ebuf = &rcuclassic_trace_buf[RCUCLASSIC_TRACE_BUF_SIZE];
> +
> + mutex_lock(&rcuclassic_trace_mutex);
> + buf += snprintf(buf, ebuf - buf, "rcu: ");
> + buf += print_one_rcu_ctrlblk(&rcu_ctrlblk, buf, ebuf);
> + buf += snprintf(buf, ebuf - buf, "rcu_bh: ");
> + buf += print_one_rcu_ctrlblk(&rcu_bh_ctrlblk, buf, ebuf);
> + buf += snprintf(buf, ebuf - buf, "online: ");
> + buf += cpulist_scnprintf(buf, ebuf - buf, cpu_online_map);
> + buf += snprintf(buf, ebuf - buf, "\n");
> + bcount = simple_read_from_buffer(buffer, count, ppos,
> + rcuclassic_trace_buf, strlen(rcuclassic_trace_buf));
> + mutex_unlock(&rcuclassic_trace_mutex);
> + return bcount;
> +}
> +
> +static struct file_operations rcucb_fops = {
> + .owner = THIS_MODULE,
> + .read = rcucb_read,
> +};
> +
> +static struct dentry *rcudir, *cbdir;
> +static int rcuclassic_debugfs_init(void)
add __init:
static int __init rcuclassic_debugfs_init(void)
> +{
> + rcudir = debugfs_create_dir("rcu", NULL);
> + if (!rcudir)
> + goto out;
> + cbdir = debugfs_create_file("rcucb", 0444, rcudir, NULL, &rcucb_fops);
> + if (!cbdir)
> + goto free_out;
> + return 0;
> +free_out:
> + debugfs_remove(rcudir);
> +out:
> + return 1;
> +}
> +
> +static int __init rcuclassic_trace_init(void)
> +{
> + int ret;
> +
> + rcuclassic_trace_buf = kmalloc(RCUCLASSIC_TRACE_BUF_SIZE, GFP_KERNEL);
I'm wondering about this.
rcuclassic_trace_buf is kmalloc-ed when init module.
In this case, why not define it as:
static char buf[20*NR_CPUS + 100];
and use it like:
pos += snprintf(buf + cnt, sizeof(buf) - cnt, ...);
> + if (!rcuclassic_trace_buf)
> + return 1;
> + ret = rcuclassic_debugfs_init();
> + if (ret)
> + kfree(rcuclassic_trace_buf);
> + return ret;
> +}
> +
> +static void __exit rcuclassic_trace_cleanup(void)
> +{
> + debugfs_remove(cbdir);
> + debugfs_remove(rcudir);
> + kfree(rcuclassic_trace_buf);
> +}
> +
> +
> +module_init(rcuclassic_trace_init);
> +module_exit(rcuclassic_trace_cleanup);
I think this trace file shows too little vars for classic rcu.
It is better that this trace file shows more data.
such as some data in struct rcu_data(quiescent state handling fields, batch, qlen).
or add new files: rcu/rcu_data<cpu#>
Thanks, Lai
next prev parent reply other threads:[~2008-10-09 6:22 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-10-06 14:12 scheduler hang on cpu re-hotplug with 2.6.27rc8 Andi Kleen
2008-10-06 23:28 ` RCU " Andi Kleen
2008-10-07 3:08 ` Paul E. McKenney
2008-10-07 7:15 ` Andi Kleen
2008-10-07 15:26 ` Paul E. McKenney
2008-10-07 15:49 ` Andi Kleen
2008-10-07 16:34 ` Paul E. McKenney
2008-10-07 21:09 ` Andi Kleen
2008-10-07 21:22 ` Paul E. McKenney
2008-10-09 1:08 ` [PATCH] rudimentary tracing for Classic RCU Paul E. McKenney
2008-10-09 6:20 ` Lai Jiangshan [this message]
2008-10-09 6:55 ` Andi Kleen
2008-10-09 7:05 ` Lai Jiangshan
2008-10-09 7:14 ` KOSAKI Motohiro
2008-10-09 7:26 ` Lai Jiangshan
2008-10-09 8:06 ` Andi Kleen
2008-10-10 11:48 ` Paul E. McKenney
2008-10-09 11:50 ` Paul E. McKenney
2008-10-09 11:50 ` Paul E. McKenney
2008-10-09 10:23 ` Frédéric Weisbecker
2008-10-09 10:53 ` Andi Kleen
2008-10-09 11:44 ` Frédéric Weisbecker
2008-10-09 11:54 ` Paul E. McKenney
2008-10-09 13:01 ` Frédéric Weisbecker
2008-10-10 3:44 ` [PATCH] v2 " Paul E. McKenney
2008-10-13 23:09 ` [PATCH] v3 " Paul E. McKenney
2008-10-14 3:53 ` Lai Jiangshan
2008-10-14 14:35 ` Paul E. McKenney
2008-10-23 11:12 ` Lai Jiangshan
2008-10-26 21:59 ` Paul E. McKenney
2008-10-27 21:50 ` Paul E. McKenney
2008-10-27 23:57 ` Paul E. McKenney
2008-10-29 1:16 ` Paul E. McKenney
2008-10-29 1:31 ` Lai Jiangshan
2008-10-30 15:52 ` Paul E. McKenney
2008-10-09 1:33 ` RCU hang on cpu re-hotplug with 2.6.27rc8 Paul E. McKenney
2008-10-09 4:56 ` Andi Kleen
2008-10-09 7:24 ` Thomas Gleixner
2008-10-09 8:22 ` Andi Kleen
2008-10-09 11:44 ` Paul E. McKenney
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=48EDA2A6.9070707@cn.fujitsu.com \
--to=laijs@cn.fujitsu.com \
--cc=andi@firstfloor.org \
--cc=dipankar@in.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=paulmck@linux.vnet.ibm.com \
--cc=rjw@sisk.pl \
--cc=tglx@linuxtronix.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 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.