From: "Paul E. McKenney" <paulmck@us.ibm.com>
To: Dipankar Sarma <dipankar@in.ibm.com>
Cc: Andrew Morton <akpm@osdl.org>,
linux-kernel@vger.kernel.org, Ingo Molnar <mingo@elte.hu>
Subject: Re: [-mm PATCH] RCU: debug sleep check
Date: Mon, 25 Sep 2006 11:08:05 -0700 [thread overview]
Message-ID: <20060925180805.GF1292@us.ibm.com> (raw)
In-Reply-To: <20060924183509.GB22448@in.ibm.com>
On Mon, Sep 25, 2006 at 12:05:09AM +0530, Dipankar Sarma wrote:
> This adds an overhead of a function call and local_irq_save/restore
> in the rcu reader path when CONFIG_DEBUG_SPINLOCK_SLEEP is set.
> Hopefully that is not much of a concern. Comments are welcome.
> Applies on top of my earlier patches. The full patchset is
> at http://www.hill9.org/linux/kernel/patches/2.6.18-mm1/.
>
> Add a debug check for rcu read-side critical section code calling
> a function that might sleep which is illegal. The check is enabled only
> if CONFIG_DEBUG_SPINLOCK_SLEEP is set.
Useful for non-CONFIG_PREEMPT kernels!
Acked-by: Paul E. McKenney <paulmck@us.ibm.com>
> Signed-off-by: Dipankar Sarma <dipankar@in.ibm.com>
> ---
>
>
> include/linux/rcupdate.h | 34 ++++++++++++++++++++++++++++++----
> kernel/rcupdate.c | 33 +++++++++++++++++++++++++++++++++
> kernel/sched.c | 2 +-
> 3 files changed, 64 insertions(+), 5 deletions(-)
>
> diff -puN include/linux/rcupdate.h~rcu-reader-sleep-check include/linux/rcupdate.h
> --- linux-2.6.18-mm1-rcu/include/linux/rcupdate.h~rcu-reader-sleep-check 2006-09-24 23:18:35.000000000 +0530
> +++ linux-2.6.18-mm1-rcu-dipankar/include/linux/rcupdate.h 2006-09-24 23:18:35.000000000 +0530
> @@ -64,6 +64,16 @@ struct rcu_head {
> (ptr)->next = NULL; (ptr)->func = NULL; \
> } while (0)
>
> +#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
> +extern int rcu_read_in_atomic(void);
> +extern void rcu_add_read_count(void);
> +extern void rcu_sub_read_count(void);
> +#else
> +static inline int rcu_read_in_atomic(void) { return 0;}
> +static inline void rcu_add_read_count(void) {}
> +static inline void rcu_sub_read_count(void) {}
> +#endif
> +
> /**
> * rcu_read_lock - mark the beginning of an RCU read-side critical section.
> *
> @@ -93,14 +103,22 @@ struct rcu_head {
> *
> * It is illegal to block while in an RCU read-side critical section.
> */
> -#define rcu_read_lock() __rcu_read_lock()
> +#define rcu_read_lock() \
> + do { \
> + rcu_add_read_count(); \
> + __rcu_read_lock(); \
> + } while (0)
>
> /**
> * rcu_read_unlock - marks the end of an RCU read-side critical section.
> *
> * See rcu_read_lock() for more information.
> */
> -#define rcu_read_unlock() __rcu_read_unlock()
> +#define rcu_read_unlock() \
> + do { \
> + __rcu_read_unlock(); \
> + rcu_sub_read_count(); \
> + } while (0)
>
> /*
> * So where is rcu_write_lock()? It does not exist, as there is no
> @@ -123,14 +141,22 @@ struct rcu_head {
> * can use just rcu_read_lock().
> *
> */
> -#define rcu_read_lock_bh() __rcu_read_lock_bh()
> +#define rcu_read_lock_bh() \
> + do { \
> + rcu_add_read_count(); \
> + __rcu_read_lock_bh(); \
> + } while (0)
>
> /**
> * rcu_read_unlock_bh - marks the end of a softirq-only RCU critical section
> *
> * See rcu_read_lock_bh() for more information.
> */
> -#define rcu_read_unlock_bh() __rcu_read_unlock_bh()
> +#define rcu_read_unlock_bh() \
> + do { \
> + __rcu_read_unlock_bh(); \
> + rcu_sub_read_count(); \
> + } while (0)
>
> /**
> * rcu_dereference - fetch an RCU-protected pointer in an
> diff -puN kernel/rcupdate.c~rcu-reader-sleep-check kernel/rcupdate.c
> --- linux-2.6.18-mm1-rcu/kernel/rcupdate.c~rcu-reader-sleep-check 2006-09-24 23:18:35.000000000 +0530
> +++ linux-2.6.18-mm1-rcu-dipankar/kernel/rcupdate.c 2006-09-24 23:18:35.000000000 +0530
> @@ -127,5 +127,38 @@ void __init rcu_init(void)
> __rcu_init();
> }
>
> +#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP
> +DEFINE_PER_CPU(int, rcu_read_count);
> +int rcu_read_in_atomic(void)
> +{
> + int val;
> + int cpu = get_cpu();
> + val = per_cpu(rcu_read_count, cpu);
> + put_cpu();
> + return val;
> +}
> +
> +void rcu_add_read_count(void)
> +{
> + int cpu, flags;
> + local_irq_save(flags);
> + cpu = smp_processor_id();
> + per_cpu(rcu_read_count, cpu)++;
> + local_irq_restore(flags);
> +}
> +
> +void rcu_sub_read_count(void)
> +{
> + int cpu, flags;
> + local_irq_save(flags);
> + cpu = smp_processor_id();
> + per_cpu(rcu_read_count, cpu)--;
> + local_irq_restore(flags);
> +}
> +EXPORT_SYMBOL_GPL(rcu_read_in_atomic);
> +EXPORT_SYMBOL_GPL(rcu_add_read_count);
> +EXPORT_SYMBOL_GPL(rcu_sub_read_count);
> +#endif
> +
> EXPORT_SYMBOL_GPL(rcu_barrier);
> EXPORT_SYMBOL_GPL(synchronize_rcu);
> diff -puN kernel/sched.c~rcu-reader-sleep-check kernel/sched.c
> --- linux-2.6.18-mm1-rcu/kernel/sched.c~rcu-reader-sleep-check 2006-09-24 23:18:35.000000000 +0530
> +++ linux-2.6.18-mm1-rcu-dipankar/kernel/sched.c 2006-09-24 23:18:35.000000000 +0530
> @@ -6974,7 +6974,7 @@ void __might_sleep(char *file, int line)
> #ifdef in_atomic
> static unsigned long prev_jiffy; /* ratelimiting */
>
> - if ((in_atomic() || irqs_disabled()) &&
> + if ((in_atomic() || irqs_disabled() || rcu_read_in_atomic()) &&
> system_state == SYSTEM_RUNNING && !oops_in_progress) {
> if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
> return;
>
> _
prev parent reply other threads:[~2006-09-25 18:07 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-09-23 15:29 [-mm PATCH] RCU: various patches Dipankar Sarma
2006-09-23 15:31 ` [-mm PATCH 1/4] RCU: split classic rcu Dipankar Sarma
2006-09-25 16:54 ` Christoph Hellwig
2006-09-27 16:32 ` Paul E. McKenney
2006-09-28 14:26 ` Christoph Hellwig
2006-09-28 14:44 ` Dipankar Sarma
2006-09-23 15:34 ` [-mm PATCH 2/4]RCU: softirq for RCU Dipankar Sarma
2006-09-23 15:35 ` [-mm PATCH 3/4] RCU: preemptible RCU Dipankar Sarma
2006-09-23 15:36 ` [-mm PATCH 4/4] RCU: preempt rcu trace Dipankar Sarma
2006-09-23 18:56 ` [-mm PATCH] RCU: various patches Dipankar Sarma
2006-09-24 3:01 ` Dipankar Sarma
2006-09-24 14:38 ` Dipankar Sarma
2006-09-24 18:35 ` [-mm PATCH] RCU: debug sleep check Dipankar Sarma
2006-09-24 18:56 ` Andrew Morton
2006-09-24 21:35 ` Dipankar Sarma
2006-09-24 21:44 ` Andrew Morton
2006-09-24 21:58 ` Dipankar Sarma
2006-09-25 18:08 ` Paul E. McKenney [this message]
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=20060925180805.GF1292@us.ibm.com \
--to=paulmck@us.ibm.com \
--cc=akpm@osdl.org \
--cc=dipankar@in.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
/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.