Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1640627 > unrolled thread
| Started by | Steven Rostedt <rostedt@goodmis.org> |
|---|---|
| First post | 2017-05-12 19:30 +0200 |
| Last post | 2017-05-13 02:30 +0200 |
| Articles | 6 — 3 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[RFC][PATCH 2/5] cpu-hotplug: Allow get_online_cpus() to nest Steven Rostedt <rostedt@goodmis.org> - 2017-05-12 19:30 +0200
Re: [RFC][PATCH 2/5] cpu-hotplug: Allow get_online_cpus() to nest "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> - 2017-05-12 20:40 +0200
Re: [RFC][PATCH 2/5] cpu-hotplug: Allow get_online_cpus() to nest Steven Rostedt <rostedt@goodmis.org> - 2017-05-12 20:50 +0200
Re: [RFC][PATCH 2/5] cpu-hotplug: Allow get_online_cpus() to nest "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> - 2017-05-12 21:00 +0200
Re: [RFC][PATCH 2/5] cpu-hotplug: Allow get_online_cpus() to nest Thomas Gleixner <tglx@linutronix.de> - 2017-05-13 00:20 +0200
Re: [RFC][PATCH 2/5] cpu-hotplug: Allow get_online_cpus() to nest Steven Rostedt <rostedt@goodmis.org> - 2017-05-13 02:30 +0200
| From | Steven Rostedt <rostedt@goodmis.org> |
|---|---|
| Date | 2017-05-12 19:30 +0200 |
| Subject | [RFC][PATCH 2/5] cpu-hotplug: Allow get_online_cpus() to nest |
| Message-ID | <tGmy5-7Uc-1@gated-at.bofh.it> |
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
Allow get_online_cpus() to be recursive. If a lock is taken while under
"get_online_cpus()", it can call get_online_cpus() as well, just as long as
it is never held without being under get_online_cpus(), but then calling it.
GOC() -> Lock(X) -> GOC()
is OK, as long as
Lock(X) -> GOC()
does not exist.
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
include/linux/sched.h | 1 +
kernel/cpu.c | 9 +++++++++
kernel/fork.c | 1 +
3 files changed, 11 insertions(+)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 993e7e25a3a5..8f272ab57685 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -813,6 +813,7 @@ struct task_struct {
unsigned int lockdep_recursion;
struct held_lock held_locks[MAX_LOCK_DEPTH];
gfp_t lockdep_reclaim_gfp;
+ int goc_depth;
#endif
#ifdef CONFIG_UBSAN
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 983163ef36ee..0dbdf1e69715 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -209,12 +209,21 @@ DEFINE_STATIC_PERCPU_RWSEM(cpu_hotplug_lock);
void get_online_cpus(void)
{
+#ifdef CONFIG_LOCKDEP
+ if (current->goc_depth++)
+ return;
+#endif
percpu_down_read(&cpu_hotplug_lock);
}
EXPORT_SYMBOL_GPL(get_online_cpus);
void put_online_cpus(void)
{
+#ifdef CONFIG_LOCKDEP
+ WARN_ON_ONCE(current->goc_depth < 1);
+ if (--current->goc_depth)
+ return;
+#endif
percpu_up_read(&cpu_hotplug_lock);
}
EXPORT_SYMBOL_GPL(put_online_cpus);
diff --git a/kernel/fork.c b/kernel/fork.c
index dd5a371c392a..8aedcd011ccc 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1658,6 +1658,7 @@ static __latent_entropy struct task_struct *copy_process(
p->lockdep_depth = 0; /* no locks held yet */
p->curr_chain_key = 0;
p->lockdep_recursion = 0;
+ p->goc_depth = 0;
#endif
#ifdef CONFIG_DEBUG_MUTEXES
--
2.10.2
[toc] | [next] | [standalone]
| From | "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> |
|---|---|
| Date | 2017-05-12 20:40 +0200 |
| Message-ID | <tGnDQ-cz-19@gated-at.bofh.it> |
| In reply to | #1640627 |
On Fri, May 12, 2017 at 01:15:46PM -0400, Steven Rostedt wrote:
> From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
>
> Allow get_online_cpus() to be recursive. If a lock is taken while under
> "get_online_cpus()", it can call get_online_cpus() as well, just as long as
> it is never held without being under get_online_cpus(), but then calling it.
>
> GOC() -> Lock(X) -> GOC()
>
> is OK, as long as
>
> Lock(X) -> GOC()
>
> does not exist.
>
> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Does ->goc_depth also need to be initialized in include/linux/init_task.h?
It seems like C-language initialization-to-zero would cover this,
but there is a lot of initialization to zero values in init_task.h
(including but not limited to some RCU stuff).
Other than that, this does look like it might ease use of get_online_cpus()
in combination with CPU-hotplug notifiers, although it would not have
made any difference in any of the RCU use cases.
Thanx, Paul
> ---
> include/linux/sched.h | 1 +
> kernel/cpu.c | 9 +++++++++
> kernel/fork.c | 1 +
> 3 files changed, 11 insertions(+)
>
> diff --git a/include/linux/sched.h b/include/linux/sched.h
> index 993e7e25a3a5..8f272ab57685 100644
> --- a/include/linux/sched.h
> +++ b/include/linux/sched.h
> @@ -813,6 +813,7 @@ struct task_struct {
> unsigned int lockdep_recursion;
> struct held_lock held_locks[MAX_LOCK_DEPTH];
> gfp_t lockdep_reclaim_gfp;
> + int goc_depth;
> #endif
>
> #ifdef CONFIG_UBSAN
> diff --git a/kernel/cpu.c b/kernel/cpu.c
> index 983163ef36ee..0dbdf1e69715 100644
> --- a/kernel/cpu.c
> +++ b/kernel/cpu.c
> @@ -209,12 +209,21 @@ DEFINE_STATIC_PERCPU_RWSEM(cpu_hotplug_lock);
>
> void get_online_cpus(void)
> {
> +#ifdef CONFIG_LOCKDEP
> + if (current->goc_depth++)
> + return;
> +#endif
> percpu_down_read(&cpu_hotplug_lock);
> }
> EXPORT_SYMBOL_GPL(get_online_cpus);
>
> void put_online_cpus(void)
> {
> +#ifdef CONFIG_LOCKDEP
> + WARN_ON_ONCE(current->goc_depth < 1);
> + if (--current->goc_depth)
> + return;
> +#endif
> percpu_up_read(&cpu_hotplug_lock);
> }
> EXPORT_SYMBOL_GPL(put_online_cpus);
> diff --git a/kernel/fork.c b/kernel/fork.c
> index dd5a371c392a..8aedcd011ccc 100644
> --- a/kernel/fork.c
> +++ b/kernel/fork.c
> @@ -1658,6 +1658,7 @@ static __latent_entropy struct task_struct *copy_process(
> p->lockdep_depth = 0; /* no locks held yet */
> p->curr_chain_key = 0;
> p->lockdep_recursion = 0;
> + p->goc_depth = 0;
> #endif
>
> #ifdef CONFIG_DEBUG_MUTEXES
> --
> 2.10.2
>
>
[toc] | [prev] | [next] | [standalone]
| From | Steven Rostedt <rostedt@goodmis.org> |
|---|---|
| Date | 2017-05-12 20:50 +0200 |
| Message-ID | <tGnNv-gZ-7@gated-at.bofh.it> |
| In reply to | #1640680 |
On Fri, 12 May 2017 11:35:59 -0700 "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> wrote: > On Fri, May 12, 2017 at 01:15:46PM -0400, Steven Rostedt wrote: > > From: "Steven Rostedt (VMware)" <rostedt@goodmis.org> > > > > Allow get_online_cpus() to be recursive. If a lock is taken while under > > "get_online_cpus()", it can call get_online_cpus() as well, just as long as > > it is never held without being under get_online_cpus(), but then calling it. > > > > GOC() -> Lock(X) -> GOC() > > > > is OK, as long as > > > > Lock(X) -> GOC() > > > > does not exist. > > > > Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> > > Does ->goc_depth also need to be initialized in include/linux/init_task.h? > > It seems like C-language initialization-to-zero would cover this, > but there is a lot of initialization to zero values in init_task.h > (including but not limited to some RCU stuff). I assumed that it would just initialize it to zero. OK, I need to add this: -- Steve diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index fffe49f..be7f71b 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -375,7 +375,7 @@ extern struct pin_cookie lock_pin_lock(struct lockdep_map *lock); extern void lock_repin_lock(struct lockdep_map *lock, struct pin_cookie); extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie); -# define INIT_LOCKDEP .lockdep_recursion = 0, .lockdep_reclaim_gfp = 0, +# define INIT_LOCKDEP .lockdep_recursion = 0, .lockdep_reclaim_gfp = 0, .goc_depth = 0, #define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0)
[toc] | [prev] | [next] | [standalone]
| From | "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> |
|---|---|
| Date | 2017-05-12 21:00 +0200 |
| Message-ID | <tGnXb-lv-5@gated-at.bofh.it> |
| In reply to | #1640684 |
On Fri, May 12, 2017 at 02:40:27PM -0400, Steven Rostedt wrote: > On Fri, 12 May 2017 11:35:59 -0700 > "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> wrote: > > > On Fri, May 12, 2017 at 01:15:46PM -0400, Steven Rostedt wrote: > > > From: "Steven Rostedt (VMware)" <rostedt@goodmis.org> > > > > > > Allow get_online_cpus() to be recursive. If a lock is taken while under > > > "get_online_cpus()", it can call get_online_cpus() as well, just as long as > > > it is never held without being under get_online_cpus(), but then calling it. > > > > > > GOC() -> Lock(X) -> GOC() > > > > > > is OK, as long as > > > > > > Lock(X) -> GOC() > > > > > > does not exist. > > > > > > Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> > > > > Does ->goc_depth also need to be initialized in include/linux/init_task.h? > > > > It seems like C-language initialization-to-zero would cover this, > > but there is a lot of initialization to zero values in init_task.h > > (including but not limited to some RCU stuff). > > I assumed that it would just initialize it to zero. > > OK, I need to add this: > > -- Steve > > diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h > index fffe49f..be7f71b 100644 > --- a/include/linux/lockdep.h > +++ b/include/linux/lockdep.h > @@ -375,7 +375,7 @@ extern struct pin_cookie lock_pin_lock(struct lockdep_map *lock); > extern void lock_repin_lock(struct lockdep_map *lock, struct pin_cookie); > extern void lock_unpin_lock(struct lockdep_map *lock, struct pin_cookie); > > -# define INIT_LOCKDEP .lockdep_recursion = 0, .lockdep_reclaim_gfp = 0, > +# define INIT_LOCKDEP .lockdep_recursion = 0, .lockdep_reclaim_gfp = 0, .goc_depth = 0, > > #define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0) Or maybe we should remove a bunch of zero-initialization from that file. But if it is needed, then that addition to the patch looks good to me. Given how much zero-initialization there is, I suspect that it is needed for some strange boot-up reason. Hard to believe that someone would not have gotten rid of it otherwise. Thanx, Paul
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2017-05-13 00:20 +0200 |
| Message-ID | <tGr4K-2RP-11@gated-at.bofh.it> |
| In reply to | #1640627 |
On Fri, 12 May 2017, Steven Rostedt wrote:
> void get_online_cpus(void)
> {
> +#ifdef CONFIG_LOCKDEP
> + if (current->goc_depth++)
> + return;
This must be unconditional and not depend on lockdep. The percpu rwsem is
going to deadlock silently otherwise when a writer is waiting ....
Thanks,
tglx
[toc] | [prev] | [next] | [standalone]
| From | Steven Rostedt <rostedt@goodmis.org> |
|---|---|
| Date | 2017-05-13 02:30 +0200 |
| Message-ID | <tGt6y-4nt-5@gated-at.bofh.it> |
| In reply to | #1640789 |
On Sat, 13 May 2017 00:15:03 +0200 (CEST)
Thomas Gleixner <tglx@linutronix.de> wrote:
> On Fri, 12 May 2017, Steven Rostedt wrote:
> > void get_online_cpus(void)
> > {
> > +#ifdef CONFIG_LOCKDEP
> > + if (current->goc_depth++)
> > + return;
>
> This must be unconditional and not depend on lockdep. The percpu rwsem is
> going to deadlock silently otherwise when a writer is waiting ....
>
After I sent the updated changes to Paul, I realized this. But didn't
update it as I turned my attention to seeing if we can still get it
done without it.
But I'm not convinced that we can yet. I'll reply to Peter's email
again later.
-- Steve
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web