* [PATCH 0/4] rcu: Make new RCU dynticks API work with nohz cpusets
@ 2011-11-28 21:24 Frederic Weisbecker
2011-11-28 21:24 ` [PATCH 1/4] rcu: Don't check irq nesting from rcu idle entry/exit Frederic Weisbecker
` (4 more replies)
0 siblings, 5 replies; 22+ messages in thread
From: Frederic Weisbecker @ 2011-11-28 21:24 UTC (permalink / raw)
To: Paul E. McKenney; +Cc: LKML, Frederic Weisbecker, Josh Triplett
Hi Paul,
This is an attempt to make the current RCU dynticks API
working with the nohz cpusets.
I believe the two first patches could be pushed in your trees.
Patches 3 and 4 are rather something I plan to apply in mine,
given they are not needed upstream yet.
Waiting for your comments.
Thanks.
Frederic Weisbecker (4):
rcu: Don't check irq nesting from rcu idle entry/exit
rcu: Irq nesting is always 0 on rcu_enter_idle_common
rcu: New rcu_user_enter() and rcu_user_exit() APIs
rcu: New rcu_user_enter_irq() and rcu_user_exit_irq() APIs
kernel/rcutree.c | 117 ++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 88 insertions(+), 29 deletions(-)
--
1.7.5.4
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 1/4] rcu: Don't check irq nesting from rcu idle entry/exit
2011-11-28 21:24 [PATCH 0/4] rcu: Make new RCU dynticks API work with nohz cpusets Frederic Weisbecker
@ 2011-11-28 21:24 ` Frederic Weisbecker
2011-11-29 0:22 ` Paul E. McKenney
2011-11-28 21:24 ` [PATCH 2/4] rcu: Irq nesting is always 0 on rcu_enter_idle_common Frederic Weisbecker
` (3 subsequent siblings)
4 siblings, 1 reply; 22+ messages in thread
From: Frederic Weisbecker @ 2011-11-28 21:24 UTC (permalink / raw)
To: Paul E. McKenney; +Cc: LKML, Frederic Weisbecker, Josh Triplett
rcu_idle_enter() and rcu_idle_exit() don't need to check
the irq nesting as they are not called from irq.
Only check dyntick_nesting from rcu_irq_enter() and
rcu_irq_exit().
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Josh Triplett <josh@joshtriplett.org>
---
kernel/rcutree.c | 18 ++++++++----------
1 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 28f8f92..c2aaadf 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -350,10 +350,6 @@ static int rcu_implicit_offline_qs(struct rcu_data *rdp)
*/
static void rcu_idle_enter_common(struct rcu_dynticks *rdtp)
{
- if (rdtp->dynticks_nesting) {
- trace_rcu_dyntick("--=", rdtp->dynticks_nesting);
- return;
- }
trace_rcu_dyntick("Start", rdtp->dynticks_nesting);
if (!idle_cpu(smp_processor_id())) {
WARN_ON_ONCE(1); /* must be idle task! */
@@ -417,7 +413,10 @@ void rcu_irq_exit(void)
rdtp = &__get_cpu_var(rcu_dynticks);
rdtp->dynticks_nesting--;
WARN_ON_ONCE(rdtp->dynticks_nesting < 0);
- rcu_idle_enter_common(rdtp);
+ if (rdtp->dynticks_nesting)
+ trace_rcu_dyntick("--=", rdtp->dynticks_nesting);
+ else
+ rcu_idle_enter_common(rdtp);
local_irq_restore(flags);
}
@@ -430,10 +429,6 @@ void rcu_irq_exit(void)
*/
static void rcu_idle_exit_common(struct rcu_dynticks *rdtp, long long oldval)
{
- if (oldval) {
- trace_rcu_dyntick("++=", rdtp->dynticks_nesting);
- return;
- }
smp_mb__before_atomic_inc(); /* Force ordering w/previous sojourn. */
atomic_inc(&rdtp->dynticks);
/* CPUs seeing atomic_inc() must see later RCU read-side crit sects */
@@ -503,7 +498,10 @@ void rcu_irq_enter(void)
oldval = rdtp->dynticks_nesting;
rdtp->dynticks_nesting++;
WARN_ON_ONCE(rdtp->dynticks_nesting == 0);
- rcu_idle_exit_common(rdtp, oldval);
+ if (oldval)
+ trace_rcu_dyntick("++=", rdtp->dynticks_nesting);
+ else
+ rcu_idle_exit_common(rdtp, oldval);
local_irq_restore(flags);
}
--
1.7.5.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 2/4] rcu: Irq nesting is always 0 on rcu_enter_idle_common
2011-11-28 21:24 [PATCH 0/4] rcu: Make new RCU dynticks API work with nohz cpusets Frederic Weisbecker
2011-11-28 21:24 ` [PATCH 1/4] rcu: Don't check irq nesting from rcu idle entry/exit Frederic Weisbecker
@ 2011-11-28 21:24 ` Frederic Weisbecker
2011-11-29 0:29 ` Paul E. McKenney
2011-11-28 21:24 ` [PATCH 3/4 RFC] rcu: New rcu_user_enter() and rcu_user_exit() APIs Frederic Weisbecker
` (2 subsequent siblings)
4 siblings, 1 reply; 22+ messages in thread
From: Frederic Weisbecker @ 2011-11-28 21:24 UTC (permalink / raw)
To: Paul E. McKenney; +Cc: LKML, Frederic Weisbecker, Josh Triplett
So pass 0 directly as a nesting value on the tracing calls.
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Josh Triplett <josh@joshtriplett.org>
---
kernel/rcutree.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index c2aaadf..b80cb41 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -350,11 +350,10 @@ static int rcu_implicit_offline_qs(struct rcu_data *rdp)
*/
static void rcu_idle_enter_common(struct rcu_dynticks *rdtp)
{
- trace_rcu_dyntick("Start", rdtp->dynticks_nesting);
+ trace_rcu_dyntick("Start", 0);
if (!idle_cpu(smp_processor_id())) {
WARN_ON_ONCE(1); /* must be idle task! */
- trace_rcu_dyntick("Error on entry: not idle task",
- rdtp->dynticks_nesting);
+ trace_rcu_dyntick("Error on entry: not idle task", 0);
ftrace_dump(DUMP_ALL);
}
/* CPUs seeing atomic_inc() must see prior RCU read-side crit sects */
--
1.7.5.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 3/4 RFC] rcu: New rcu_user_enter() and rcu_user_exit() APIs
2011-11-28 21:24 [PATCH 0/4] rcu: Make new RCU dynticks API work with nohz cpusets Frederic Weisbecker
2011-11-28 21:24 ` [PATCH 1/4] rcu: Don't check irq nesting from rcu idle entry/exit Frederic Weisbecker
2011-11-28 21:24 ` [PATCH 2/4] rcu: Irq nesting is always 0 on rcu_enter_idle_common Frederic Weisbecker
@ 2011-11-28 21:24 ` Frederic Weisbecker
2011-11-28 21:24 ` [PATCH 4/4 RFC] rcu: New rcu_user_enter_irq() and rcu_user_exit_irq() APIs Frederic Weisbecker
2011-11-29 5:22 ` [PATCH 0/4] rcu: Make new RCU dynticks API work with nohz cpusets Josh Triplett
4 siblings, 0 replies; 22+ messages in thread
From: Frederic Weisbecker @ 2011-11-28 21:24 UTC (permalink / raw)
To: Paul E. McKenney; +Cc: LKML, Frederic Weisbecker, Josh Triplett
These two APIs are provided to help the implementation
of an adaptive tickless kernel (cf: nohz cpusets). We need
to run into RCU extended quiescent state when we are in
userland so that a tickless CPU is not involved in the
global RCU state machine and can shutdown its tick safely.
These APIs are called from syscall and exception entry/exit
points and can't be called from interrupt.
They are essentially the same than rcu_idle_enter() and
rcu_idle_exit() minus the checks that ensure the CPU is
running the idle task.
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Josh Triplett <josh@joshtriplett.org>
---
kernel/rcutree.c | 98 +++++++++++++++++++++++++++++++++++++----------------
1 files changed, 68 insertions(+), 30 deletions(-)
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index b80cb41..00a9fba 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -341,6 +341,15 @@ static int rcu_implicit_offline_qs(struct rcu_data *rdp)
#endif /* #ifdef CONFIG_SMP */
+static void rcu_check_idle_enter(void)
+{
+ if (!idle_cpu(smp_processor_id())) {
+ WARN_ON_ONCE(1); /* must be idle task! */
+ trace_rcu_dyntick("Error on entry: not idle task", 0);
+ ftrace_dump(DUMP_ALL);
+ }
+}
+
/*
* rcu_idle_enter_common - inform RCU that current CPU is moving towards idle
*
@@ -351,11 +360,6 @@ static int rcu_implicit_offline_qs(struct rcu_data *rdp)
static void rcu_idle_enter_common(struct rcu_dynticks *rdtp)
{
trace_rcu_dyntick("Start", 0);
- if (!idle_cpu(smp_processor_id())) {
- WARN_ON_ONCE(1); /* must be idle task! */
- trace_rcu_dyntick("Error on entry: not idle task", 0);
- ftrace_dump(DUMP_ALL);
- }
/* CPUs seeing atomic_inc() must see prior RCU read-side crit sects */
smp_mb__before_atomic_inc(); /* See above. */
atomic_inc(&rdtp->dynticks);
@@ -363,6 +367,18 @@ static void rcu_idle_enter_common(struct rcu_dynticks *rdtp)
WARN_ON_ONCE(atomic_read(&rdtp->dynticks) & 0x1);
}
+static void __rcu_idle_enter(void)
+{
+ unsigned long flags;
+ struct rcu_dynticks *rdtp;
+
+ local_irq_save(flags);
+ rdtp = &__get_cpu_var(rcu_dynticks);
+ rdtp->dynticks_nesting = 0;
+ rcu_idle_enter_common(rdtp);
+ local_irq_restore(flags);
+}
+
/**
* rcu_idle_enter - inform RCU that current CPU is entering idle
*
@@ -377,14 +393,13 @@ static void rcu_idle_enter_common(struct rcu_dynticks *rdtp)
*/
void rcu_idle_enter(void)
{
- unsigned long flags;
- struct rcu_dynticks *rdtp;
+ __rcu_idle_enter();
+ rcu_check_idle_enter();
+}
- local_irq_save(flags);
- rdtp = &__get_cpu_var(rcu_dynticks);
- rdtp->dynticks_nesting = 0;
- rcu_idle_enter_common(rdtp);
- local_irq_restore(flags);
+void rcu_user_enter(void)
+{
+ __rcu_idle_enter();
}
/**
@@ -412,13 +427,24 @@ void rcu_irq_exit(void)
rdtp = &__get_cpu_var(rcu_dynticks);
rdtp->dynticks_nesting--;
WARN_ON_ONCE(rdtp->dynticks_nesting < 0);
- if (rdtp->dynticks_nesting)
+ if (rdtp->dynticks_nesting) {
trace_rcu_dyntick("--=", rdtp->dynticks_nesting);
- else
+ } else {
rcu_idle_enter_common(rdtp);
+ rcu_check_idle_enter();
+ }
local_irq_restore(flags);
}
+static void rcu_check_idle_exit(long long oldval)
+{
+ if (!idle_cpu(smp_processor_id())) {
+ WARN_ON_ONCE(1); /* must be idle task! */
+ trace_rcu_dyntick("Error on exit: not idle task", oldval);
+ ftrace_dump(DUMP_ALL);
+ }
+}
+
/*
* rcu_idle_exit_common - inform RCU that current CPU is moving away from idle
*
@@ -434,11 +460,23 @@ static void rcu_idle_exit_common(struct rcu_dynticks *rdtp, long long oldval)
smp_mb__after_atomic_inc(); /* See above. */
WARN_ON_ONCE(!(atomic_read(&rdtp->dynticks) & 0x1));
trace_rcu_dyntick("End", oldval);
- if (!idle_cpu(smp_processor_id())) {
- WARN_ON_ONCE(1); /* must be idle task! */
- trace_rcu_dyntick("Error on exit: not idle task", oldval);
- ftrace_dump(DUMP_ALL);
- }
+}
+
+static long long __rcu_idle_exit(void)
+{
+ unsigned long flags;
+ struct rcu_dynticks *rdtp;
+ long long oldval;
+
+ local_irq_save(flags);
+ rdtp = &__get_cpu_var(rcu_dynticks);
+ oldval = rdtp->dynticks_nesting;
+ WARN_ON_ONCE(oldval != 0);
+ rdtp->dynticks_nesting = LLONG_MAX / 2;
+ rcu_idle_exit_common(rdtp, oldval);
+ local_irq_restore(flags);
+
+ return oldval;
}
/**
@@ -454,17 +492,15 @@ static void rcu_idle_exit_common(struct rcu_dynticks *rdtp, long long oldval)
*/
void rcu_idle_exit(void)
{
- unsigned long flags;
- struct rcu_dynticks *rdtp;
long long oldval;
- local_irq_save(flags);
- rdtp = &__get_cpu_var(rcu_dynticks);
- oldval = rdtp->dynticks_nesting;
- WARN_ON_ONCE(oldval != 0);
- rdtp->dynticks_nesting = LLONG_MAX / 2;
- rcu_idle_exit_common(rdtp, oldval);
- local_irq_restore(flags);
+ oldval = __rcu_idle_exit();
+ rcu_check_idle_exit(oldval);
+}
+
+void rcu_user_exit(void)
+{
+ __rcu_idle_exit();
}
/**
@@ -497,10 +533,12 @@ void rcu_irq_enter(void)
oldval = rdtp->dynticks_nesting;
rdtp->dynticks_nesting++;
WARN_ON_ONCE(rdtp->dynticks_nesting == 0);
- if (oldval)
+ if (oldval) {
trace_rcu_dyntick("++=", rdtp->dynticks_nesting);
- else
+ } else {
+ rcu_check_idle_exit(oldval);
rcu_idle_exit_common(rdtp, oldval);
+ }
local_irq_restore(flags);
}
--
1.7.5.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 4/4 RFC] rcu: New rcu_user_enter_irq() and rcu_user_exit_irq() APIs
2011-11-28 21:24 [PATCH 0/4] rcu: Make new RCU dynticks API work with nohz cpusets Frederic Weisbecker
` (2 preceding siblings ...)
2011-11-28 21:24 ` [PATCH 3/4 RFC] rcu: New rcu_user_enter() and rcu_user_exit() APIs Frederic Weisbecker
@ 2011-11-28 21:24 ` Frederic Weisbecker
2011-11-28 21:53 ` Josh Triplett
2011-11-29 5:22 ` [PATCH 0/4] rcu: Make new RCU dynticks API work with nohz cpusets Josh Triplett
4 siblings, 1 reply; 22+ messages in thread
From: Frederic Weisbecker @ 2011-11-28 21:24 UTC (permalink / raw)
To: Paul E. McKenney; +Cc: LKML, Frederic Weisbecker, Josh Triplett
A CPU running in adaptive tickless mode wants to enter into
RCU extended quiescent state while running in userspace. This
way we can shut down the tick that is usually needed on each
CPU for the needs of RCU.
Typically, RCU enters the extended quiescent state when we resume
to userspace through a syscall or exception exit, this is done
using rcu_user_enter(). Then RCU exit this state by calling
rcu_user_exit() from syscall or exception entry.
However there are two other points where we may want to enter
or exit this state. Some remote CPU may require a tickless CPU
to restart its tick for any reason and send it an IPI for
this purpose. As we restart the tick, we don't want to resume
from the IPI in RCU extended quiescent state anymore.
Similarly we may stop the tick from an interrupt in userspace and
we need to be able to enter RCU extended quiescent state when we
resume from this interrupt to userspace.
To these ends, we provide two new APIs:
- rcu_user_enter_irq(). This must be called from a non-nesting
interrupt betwenn rcu_irq_enter() and rcu_irq_exit().
After the irq calls rcu_irq_exit(), we'll run into RCU extended
quiescent state.
- rcu_user_exit_irq(). This must be called from a non-nesting
interrupt, interrupting an RCU extended quiescent state, and
between rcu_irq_enter() and rcu_irq_exit(). After the irq calls
rcu_irq_exit(), we'll prevent from resuming the RCU extended
quiescent.
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Josh Triplett <josh@joshtriplett.org>
---
kernel/rcutree.c | 24 ++++++++++++++++++++++++
1 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 00a9fba..a7906c9 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -402,6 +402,18 @@ void rcu_user_enter(void)
__rcu_idle_enter();
}
+void rcu_user_enter_irq(void)
+{
+ unsigned long flags;
+ struct rcu_dynticks *rdtp;
+
+ local_irq_save(flags);
+ rdtp = &__get_cpu_var(rcu_dynticks);
+ WARN_ON_ONCE(rdtp->dynticks_nesting == 1);
+ rdtp->dynticks_nesting = 1;
+ local_irq_restore(flags);
+}
+
/**
* rcu_irq_exit - inform RCU that current CPU is exiting irq towards idle
*
@@ -503,6 +515,18 @@ void rcu_user_exit(void)
__rcu_idle_exit();
}
+void rcu_user_exit_irq(void)
+{
+ unsigned long flags;
+ struct rcu_dynticks *rdtp;
+
+ local_irq_save(flags);
+ rdtp = &__get_cpu_var(rcu_dynticks);
+ WARN_ON_ONCE(rdtp->dynticks_nesting != 1);
+ rdtp->dynticks_nesting = (LLONG_MAX / 2) + 1;
+ local_irq_restore(flags);
+}
+
/**
* rcu_irq_enter - inform RCU that current CPU is entering irq away from idle
*
--
1.7.5.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 4/4 RFC] rcu: New rcu_user_enter_irq() and rcu_user_exit_irq() APIs
2011-11-28 21:24 ` [PATCH 4/4 RFC] rcu: New rcu_user_enter_irq() and rcu_user_exit_irq() APIs Frederic Weisbecker
@ 2011-11-28 21:53 ` Josh Triplett
2011-11-29 1:00 ` Paul E. McKenney
2011-11-29 13:53 ` Frederic Weisbecker
0 siblings, 2 replies; 22+ messages in thread
From: Josh Triplett @ 2011-11-28 21:53 UTC (permalink / raw)
To: Frederic Weisbecker; +Cc: Paul E. McKenney, LKML
On Mon, Nov 28, 2011 at 10:24:47PM +0100, Frederic Weisbecker wrote:
> A CPU running in adaptive tickless mode wants to enter into
> RCU extended quiescent state while running in userspace. This
> way we can shut down the tick that is usually needed on each
> CPU for the needs of RCU.
Very awesome. I've wanted to see this change for a long time. Thanks!
> Typically, RCU enters the extended quiescent state when we resume
> to userspace through a syscall or exception exit, this is done
> using rcu_user_enter(). Then RCU exit this state by calling
> rcu_user_exit() from syscall or exception entry.
>
> However there are two other points where we may want to enter
> or exit this state. Some remote CPU may require a tickless CPU
> to restart its tick for any reason and send it an IPI for
> this purpose. As we restart the tick, we don't want to resume
> from the IPI in RCU extended quiescent state anymore.
> Similarly we may stop the tick from an interrupt in userspace and
> we need to be able to enter RCU extended quiescent state when we
> resume from this interrupt to userspace.
>
> To these ends, we provide two new APIs:
>
> - rcu_user_enter_irq(). This must be called from a non-nesting
> interrupt betwenn rcu_irq_enter() and rcu_irq_exit().
> After the irq calls rcu_irq_exit(), we'll run into RCU extended
> quiescent state.
>
> - rcu_user_exit_irq(). This must be called from a non-nesting
> interrupt, interrupting an RCU extended quiescent state, and
> between rcu_irq_enter() and rcu_irq_exit(). After the irq calls
> rcu_irq_exit(), we'll prevent from resuming the RCU extended
> quiescent.
It would help to see the corresponding patches making use of this new
API.
> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
> Cc: Josh Triplett <josh@joshtriplett.org>
> ---
> kernel/rcutree.c | 24 ++++++++++++++++++++++++
> 1 files changed, 24 insertions(+), 0 deletions(-)
>
> diff --git a/kernel/rcutree.c b/kernel/rcutree.c
> index 00a9fba..a7906c9 100644
> --- a/kernel/rcutree.c
> +++ b/kernel/rcutree.c
> @@ -402,6 +402,18 @@ void rcu_user_enter(void)
> __rcu_idle_enter();
> }
>
> +void rcu_user_enter_irq(void)
> +{
> + unsigned long flags;
> + struct rcu_dynticks *rdtp;
> +
> + local_irq_save(flags);
> + rdtp = &__get_cpu_var(rcu_dynticks);
> + WARN_ON_ONCE(rdtp->dynticks_nesting == 1);
> + rdtp->dynticks_nesting = 1;
> + local_irq_restore(flags);
> +}
> +
> /**
> * rcu_irq_exit - inform RCU that current CPU is exiting irq towards idle
> *
> @@ -503,6 +515,18 @@ void rcu_user_exit(void)
> __rcu_idle_exit();
> }
>
> +void rcu_user_exit_irq(void)
> +{
> + unsigned long flags;
> + struct rcu_dynticks *rdtp;
> +
> + local_irq_save(flags);
> + rdtp = &__get_cpu_var(rcu_dynticks);
> + WARN_ON_ONCE(rdtp->dynticks_nesting != 1);
> + rdtp->dynticks_nesting = (LLONG_MAX / 2) + 1;
> + local_irq_restore(flags);
> +}
> +
Any chance that either of these two needs a memory barrier of some kind,
to prevent leakage of operations from between them? Or can you count on
no RCU-protected operations occurring during (or leaking into) the
extended quiescent state?
- Josh Triplett
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 1/4] rcu: Don't check irq nesting from rcu idle entry/exit
2011-11-28 21:24 ` [PATCH 1/4] rcu: Don't check irq nesting from rcu idle entry/exit Frederic Weisbecker
@ 2011-11-29 0:22 ` Paul E. McKenney
2011-11-29 0:26 ` Frederic Weisbecker
0 siblings, 1 reply; 22+ messages in thread
From: Paul E. McKenney @ 2011-11-29 0:22 UTC (permalink / raw)
To: Frederic Weisbecker; +Cc: LKML, Josh Triplett
On Mon, Nov 28, 2011 at 10:24:44PM +0100, Frederic Weisbecker wrote:
> rcu_idle_enter() and rcu_idle_exit() don't need to check
> the irq nesting as they are not called from irq.
>
> Only check dyntick_nesting from rcu_irq_enter() and
> rcu_irq_exit().
>
> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
> Cc: Josh Triplett <josh@joshtriplett.org>
> ---
> kernel/rcutree.c | 18 ++++++++----------
> 1 files changed, 8 insertions(+), 10 deletions(-)
I have queued this. I had to update it to deal with a recent conflicting
update, please see below for the new version.
Thanx, Paul
------------------------------------------------------------------------
rcu: Don't check irq nesting from rcu idle entry/exit
Because tasks do not nest, rcu_idle_enter() and rcu_idle_exit() do
not need to check for nesting. This commit therefore moves nesting
checks from rcu_idle_enter_common() to rcu_irq_exit() and from
rcu_idle_exit_common() to rcu_irq_enter().
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index bf085d7..54d9b4f 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -350,10 +350,6 @@ static int rcu_implicit_offline_qs(struct rcu_data *rdp)
*/
static void rcu_idle_enter_common(struct rcu_dynticks *rdtp, long long oldval)
{
- if (rdtp->dynticks_nesting) {
- trace_rcu_dyntick("--=", oldval, rdtp->dynticks_nesting);
- return;
- }
trace_rcu_dyntick("Start", oldval, rdtp->dynticks_nesting);
if (!is_idle_task(current)) {
struct task_struct *idle = idle_task(smp_processor_id());
@@ -426,7 +422,10 @@ void rcu_irq_exit(void)
oldval = rdtp->dynticks_nesting;
rdtp->dynticks_nesting--;
WARN_ON_ONCE(rdtp->dynticks_nesting < 0);
- rcu_idle_enter_common(rdtp, oldval);
+ if (rdtp->dynticks_nesting)
+ trace_rcu_dyntick("--=", oldval, rdtp->dynticks_nesting);
+ else
+ rcu_idle_enter_common(rdtp, oldval);
local_irq_restore(flags);
}
@@ -439,10 +438,6 @@ void rcu_irq_exit(void)
*/
static void rcu_idle_exit_common(struct rcu_dynticks *rdtp, long long oldval)
{
- if (oldval) {
- trace_rcu_dyntick("++=", oldval, rdtp->dynticks_nesting);
- return;
- }
smp_mb__before_atomic_inc(); /* Force ordering w/previous sojourn. */
atomic_inc(&rdtp->dynticks);
/* CPUs seeing atomic_inc() must see later RCU read-side crit sects */
@@ -519,6 +514,10 @@ void rcu_irq_enter(void)
rdtp->dynticks_nesting++;
WARN_ON_ONCE(rdtp->dynticks_nesting == 0);
rcu_idle_exit_common(rdtp, oldval);
+ if (oldval)
+ trace_rcu_dyntick("++=", oldval, rdtp->dynticks_nesting);
+ else
+ rcu_idle_exit_common(rdtp, oldval);
local_irq_restore(flags);
}
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 1/4] rcu: Don't check irq nesting from rcu idle entry/exit
2011-11-29 0:22 ` Paul E. McKenney
@ 2011-11-29 0:26 ` Frederic Weisbecker
2011-11-29 0:39 ` Paul E. McKenney
0 siblings, 1 reply; 22+ messages in thread
From: Frederic Weisbecker @ 2011-11-29 0:26 UTC (permalink / raw)
To: Paul E. McKenney; +Cc: LKML, Josh Triplett
On Mon, Nov 28, 2011 at 04:22:44PM -0800, Paul E. McKenney wrote:
> On Mon, Nov 28, 2011 at 10:24:44PM +0100, Frederic Weisbecker wrote:
> > rcu_idle_enter() and rcu_idle_exit() don't need to check
> > the irq nesting as they are not called from irq.
> >
> > Only check dyntick_nesting from rcu_irq_enter() and
> > rcu_irq_exit().
> >
> > Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
> > Cc: Josh Triplett <josh@joshtriplett.org>
> > ---
> > kernel/rcutree.c | 18 ++++++++----------
> > 1 files changed, 8 insertions(+), 10 deletions(-)
>
> I have queued this. I had to update it to deal with a recent conflicting
> update, please see below for the new version.
>
> Thanx, Paul
Hmm, seems there is a problem. Look below:
>
> ------------------------------------------------------------------------
>
> rcu: Don't check irq nesting from rcu idle entry/exit
>
> Because tasks do not nest, rcu_idle_enter() and rcu_idle_exit() do
> not need to check for nesting. This commit therefore moves nesting
> checks from rcu_idle_enter_common() to rcu_irq_exit() and from
> rcu_idle_exit_common() to rcu_irq_enter().
>
> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
> Cc: Josh Triplett <josh@joshtriplett.org>
> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
>
> diff --git a/kernel/rcutree.c b/kernel/rcutree.c
> index bf085d7..54d9b4f 100644
> --- a/kernel/rcutree.c
> +++ b/kernel/rcutree.c
> @@ -350,10 +350,6 @@ static int rcu_implicit_offline_qs(struct rcu_data *rdp)
> */
> static void rcu_idle_enter_common(struct rcu_dynticks *rdtp, long long oldval)
> {
> - if (rdtp->dynticks_nesting) {
> - trace_rcu_dyntick("--=", oldval, rdtp->dynticks_nesting);
> - return;
> - }
> trace_rcu_dyntick("Start", oldval, rdtp->dynticks_nesting);
> if (!is_idle_task(current)) {
> struct task_struct *idle = idle_task(smp_processor_id());
> @@ -426,7 +422,10 @@ void rcu_irq_exit(void)
> oldval = rdtp->dynticks_nesting;
> rdtp->dynticks_nesting--;
> WARN_ON_ONCE(rdtp->dynticks_nesting < 0);
> - rcu_idle_enter_common(rdtp, oldval);
> + if (rdtp->dynticks_nesting)
> + trace_rcu_dyntick("--=", oldval, rdtp->dynticks_nesting);
> + else
> + rcu_idle_enter_common(rdtp, oldval);
> local_irq_restore(flags);
> }
>
> @@ -439,10 +438,6 @@ void rcu_irq_exit(void)
> */
> static void rcu_idle_exit_common(struct rcu_dynticks *rdtp, long long oldval)
> {
> - if (oldval) {
> - trace_rcu_dyntick("++=", oldval, rdtp->dynticks_nesting);
> - return;
> - }
> smp_mb__before_atomic_inc(); /* Force ordering w/previous sojourn. */
> atomic_inc(&rdtp->dynticks);
> /* CPUs seeing atomic_inc() must see later RCU read-side crit sects */
> @@ -519,6 +514,10 @@ void rcu_irq_enter(void)
> rdtp->dynticks_nesting++;
> WARN_ON_ONCE(rdtp->dynticks_nesting == 0);
> rcu_idle_exit_common(rdtp, oldval);
It's now calling rcu_idle_exit_common twice?
> + if (oldval)
> + trace_rcu_dyntick("++=", oldval, rdtp->dynticks_nesting);
> + else
> + rcu_idle_exit_common(rdtp, oldval);
> local_irq_restore(flags);
> }
>
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/4] rcu: Irq nesting is always 0 on rcu_enter_idle_common
2011-11-28 21:24 ` [PATCH 2/4] rcu: Irq nesting is always 0 on rcu_enter_idle_common Frederic Weisbecker
@ 2011-11-29 0:29 ` Paul E. McKenney
2011-11-29 1:00 ` Frederic Weisbecker
0 siblings, 1 reply; 22+ messages in thread
From: Paul E. McKenney @ 2011-11-29 0:29 UTC (permalink / raw)
To: Frederic Weisbecker; +Cc: LKML, Josh Triplett
On Mon, Nov 28, 2011 at 10:24:45PM +0100, Frederic Weisbecker wrote:
> So pass 0 directly as a nesting value on the tracing calls.
>
> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
> Cc: Josh Triplett <josh@joshtriplett.org>
> ---
> kernel/rcutree.c | 5 ++---
> 1 files changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/kernel/rcutree.c b/kernel/rcutree.c
> index c2aaadf..b80cb41 100644
> --- a/kernel/rcutree.c
> +++ b/kernel/rcutree.c
> @@ -350,11 +350,10 @@ static int rcu_implicit_offline_qs(struct rcu_data *rdp)
> */
> static void rcu_idle_enter_common(struct rcu_dynticks *rdtp)
> {
> - trace_rcu_dyntick("Start", rdtp->dynticks_nesting);
> + trace_rcu_dyntick("Start", 0);
> if (!idle_cpu(smp_processor_id())) {
> WARN_ON_ONCE(1); /* must be idle task! */
> - trace_rcu_dyntick("Error on entry: not idle task",
> - rdtp->dynticks_nesting);
> + trace_rcu_dyntick("Error on entry: not idle task", 0);
> ftrace_dump(DUMP_ALL);
> }
> /* CPUs seeing atomic_inc() must see prior RCU read-side crit sects */
Queued, again updating to work around the mid-air collision.
Thanx, Paul
------------------------------------------------------------------------
rcu: Irq nesting is always 0 on rcu_enter_idle_common
Because tasks don't nest, the ->dyntick_nesting must always be zero upon
entry to rcu_idle_enter_common(). Therefore, pass "0" rather than the
counter itself.
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 54d9b4f..e0f5072 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -350,12 +350,11 @@ static int rcu_implicit_offline_qs(struct rcu_data *rdp)
*/
static void rcu_idle_enter_common(struct rcu_dynticks *rdtp, long long oldval)
{
- trace_rcu_dyntick("Start", oldval, rdtp->dynticks_nesting);
+ trace_rcu_dyntick("Start", oldval, 0);
if (!is_idle_task(current)) {
struct task_struct *idle = idle_task(smp_processor_id());
- trace_rcu_dyntick("Error on entry: not idle task",
- oldval, rdtp->dynticks_nesting);
+ trace_rcu_dyntick("Error on entry: not idle task", oldval, 0);
ftrace_dump(DUMP_ALL);
WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s",
current->pid, current->comm,
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 1/4] rcu: Don't check irq nesting from rcu idle entry/exit
2011-11-29 0:26 ` Frederic Weisbecker
@ 2011-11-29 0:39 ` Paul E. McKenney
2011-11-29 0:58 ` Frederic Weisbecker
0 siblings, 1 reply; 22+ messages in thread
From: Paul E. McKenney @ 2011-11-29 0:39 UTC (permalink / raw)
To: Frederic Weisbecker; +Cc: LKML, Josh Triplett
On Tue, Nov 29, 2011 at 01:26:01AM +0100, Frederic Weisbecker wrote:
> On Mon, Nov 28, 2011 at 04:22:44PM -0800, Paul E. McKenney wrote:
> > On Mon, Nov 28, 2011 at 10:24:44PM +0100, Frederic Weisbecker wrote:
> > > rcu_idle_enter() and rcu_idle_exit() don't need to check
> > > the irq nesting as they are not called from irq.
> > >
> > > Only check dyntick_nesting from rcu_irq_enter() and
> > > rcu_irq_exit().
> > >
> > > Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
> > > Cc: Josh Triplett <josh@joshtriplett.org>
> > > ---
> > > kernel/rcutree.c | 18 ++++++++----------
> > > 1 files changed, 8 insertions(+), 10 deletions(-)
> >
> > I have queued this. I had to update it to deal with a recent conflicting
> > update, please see below for the new version.
> >
> > Thanx, Paul
>
> Hmm, seems there is a problem. Look below:
Good eyes! How about the following instead?
------------------------------------------------------------------------
rcu: Don't check irq nesting from rcu idle entry/exit
Because tasks do not nest, rcu_idle_enter() and rcu_idle_exit() do
not need to check for nesting. This commit therefore moves nesting
checks from rcu_idle_enter_common() to rcu_irq_exit() and from
rcu_idle_exit_common() to rcu_irq_enter().
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Josh Triplett <josh@joshtriplett.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index bf085d7..860c02c 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -350,10 +350,6 @@ static int rcu_implicit_offline_qs(struct rcu_data *rdp)
*/
static void rcu_idle_enter_common(struct rcu_dynticks *rdtp, long long oldval)
{
- if (rdtp->dynticks_nesting) {
- trace_rcu_dyntick("--=", oldval, rdtp->dynticks_nesting);
- return;
- }
trace_rcu_dyntick("Start", oldval, rdtp->dynticks_nesting);
if (!is_idle_task(current)) {
struct task_struct *idle = idle_task(smp_processor_id());
@@ -426,7 +422,10 @@ void rcu_irq_exit(void)
oldval = rdtp->dynticks_nesting;
rdtp->dynticks_nesting--;
WARN_ON_ONCE(rdtp->dynticks_nesting < 0);
- rcu_idle_enter_common(rdtp, oldval);
+ if (rdtp->dynticks_nesting)
+ trace_rcu_dyntick("--=", oldval, rdtp->dynticks_nesting);
+ else
+ rcu_idle_enter_common(rdtp, oldval);
local_irq_restore(flags);
}
@@ -439,10 +438,6 @@ void rcu_irq_exit(void)
*/
static void rcu_idle_exit_common(struct rcu_dynticks *rdtp, long long oldval)
{
- if (oldval) {
- trace_rcu_dyntick("++=", oldval, rdtp->dynticks_nesting);
- return;
- }
smp_mb__before_atomic_inc(); /* Force ordering w/previous sojourn. */
atomic_inc(&rdtp->dynticks);
/* CPUs seeing atomic_inc() must see later RCU read-side crit sects */
@@ -518,7 +513,10 @@ void rcu_irq_enter(void)
oldval = rdtp->dynticks_nesting;
rdtp->dynticks_nesting++;
WARN_ON_ONCE(rdtp->dynticks_nesting == 0);
- rcu_idle_exit_common(rdtp, oldval);
+ if (oldval)
+ trace_rcu_dyntick("++=", oldval, rdtp->dynticks_nesting);
+ else
+ rcu_idle_exit_common(rdtp, oldval);
local_irq_restore(flags);
}
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 1/4] rcu: Don't check irq nesting from rcu idle entry/exit
2011-11-29 0:39 ` Paul E. McKenney
@ 2011-11-29 0:58 ` Frederic Weisbecker
0 siblings, 0 replies; 22+ messages in thread
From: Frederic Weisbecker @ 2011-11-29 0:58 UTC (permalink / raw)
To: Paul E. McKenney; +Cc: LKML, Josh Triplett
On Mon, Nov 28, 2011 at 04:39:31PM -0800, Paul E. McKenney wrote:
> On Tue, Nov 29, 2011 at 01:26:01AM +0100, Frederic Weisbecker wrote:
> > On Mon, Nov 28, 2011 at 04:22:44PM -0800, Paul E. McKenney wrote:
> > > On Mon, Nov 28, 2011 at 10:24:44PM +0100, Frederic Weisbecker wrote:
> > > > rcu_idle_enter() and rcu_idle_exit() don't need to check
> > > > the irq nesting as they are not called from irq.
> > > >
> > > > Only check dyntick_nesting from rcu_irq_enter() and
> > > > rcu_irq_exit().
> > > >
> > > > Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
> > > > Cc: Josh Triplett <josh@joshtriplett.org>
> > > > ---
> > > > kernel/rcutree.c | 18 ++++++++----------
> > > > 1 files changed, 8 insertions(+), 10 deletions(-)
> > >
> > > I have queued this. I had to update it to deal with a recent conflicting
> > > update, please see below for the new version.
> > >
> > > Thanx, Paul
> >
> > Hmm, seems there is a problem. Look below:
>
> Good eyes!
A real falcon!
> How about the following instead?
Yeah looks good.
Thanks!
>
> ------------------------------------------------------------------------
>
> rcu: Don't check irq nesting from rcu idle entry/exit
>
> Because tasks do not nest, rcu_idle_enter() and rcu_idle_exit() do
> not need to check for nesting. This commit therefore moves nesting
> checks from rcu_idle_enter_common() to rcu_irq_exit() and from
> rcu_idle_exit_common() to rcu_irq_enter().
>
> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
> Cc: Josh Triplett <josh@joshtriplett.org>
> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
>
> diff --git a/kernel/rcutree.c b/kernel/rcutree.c
> index bf085d7..860c02c 100644
> --- a/kernel/rcutree.c
> +++ b/kernel/rcutree.c
> @@ -350,10 +350,6 @@ static int rcu_implicit_offline_qs(struct rcu_data *rdp)
> */
> static void rcu_idle_enter_common(struct rcu_dynticks *rdtp, long long oldval)
> {
> - if (rdtp->dynticks_nesting) {
> - trace_rcu_dyntick("--=", oldval, rdtp->dynticks_nesting);
> - return;
> - }
> trace_rcu_dyntick("Start", oldval, rdtp->dynticks_nesting);
> if (!is_idle_task(current)) {
> struct task_struct *idle = idle_task(smp_processor_id());
> @@ -426,7 +422,10 @@ void rcu_irq_exit(void)
> oldval = rdtp->dynticks_nesting;
> rdtp->dynticks_nesting--;
> WARN_ON_ONCE(rdtp->dynticks_nesting < 0);
> - rcu_idle_enter_common(rdtp, oldval);
> + if (rdtp->dynticks_nesting)
> + trace_rcu_dyntick("--=", oldval, rdtp->dynticks_nesting);
> + else
> + rcu_idle_enter_common(rdtp, oldval);
> local_irq_restore(flags);
> }
>
> @@ -439,10 +438,6 @@ void rcu_irq_exit(void)
> */
> static void rcu_idle_exit_common(struct rcu_dynticks *rdtp, long long oldval)
> {
> - if (oldval) {
> - trace_rcu_dyntick("++=", oldval, rdtp->dynticks_nesting);
> - return;
> - }
> smp_mb__before_atomic_inc(); /* Force ordering w/previous sojourn. */
> atomic_inc(&rdtp->dynticks);
> /* CPUs seeing atomic_inc() must see later RCU read-side crit sects */
> @@ -518,7 +513,10 @@ void rcu_irq_enter(void)
> oldval = rdtp->dynticks_nesting;
> rdtp->dynticks_nesting++;
> WARN_ON_ONCE(rdtp->dynticks_nesting == 0);
> - rcu_idle_exit_common(rdtp, oldval);
> + if (oldval)
> + trace_rcu_dyntick("++=", oldval, rdtp->dynticks_nesting);
> + else
> + rcu_idle_exit_common(rdtp, oldval);
> local_irq_restore(flags);
> }
>
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 4/4 RFC] rcu: New rcu_user_enter_irq() and rcu_user_exit_irq() APIs
2011-11-28 21:53 ` Josh Triplett
@ 2011-11-29 1:00 ` Paul E. McKenney
2011-11-29 5:21 ` Josh Triplett
2011-11-29 14:05 ` Frederic Weisbecker
2011-11-29 13:53 ` Frederic Weisbecker
1 sibling, 2 replies; 22+ messages in thread
From: Paul E. McKenney @ 2011-11-29 1:00 UTC (permalink / raw)
To: Josh Triplett; +Cc: Frederic Weisbecker, LKML
On Mon, Nov 28, 2011 at 01:53:23PM -0800, Josh Triplett wrote:
> On Mon, Nov 28, 2011 at 10:24:47PM +0100, Frederic Weisbecker wrote:
> > A CPU running in adaptive tickless mode wants to enter into
> > RCU extended quiescent state while running in userspace. This
> > way we can shut down the tick that is usually needed on each
> > CPU for the needs of RCU.
>
> Very awesome. I've wanted to see this change for a long time. Thanks!
I am a fan, also. ;-)
[ . . . ]
> > @@ -503,6 +515,18 @@ void rcu_user_exit(void)
> > __rcu_idle_exit();
> > }
> >
> > +void rcu_user_exit_irq(void)
> > +{
> > + unsigned long flags;
> > + struct rcu_dynticks *rdtp;
> > +
> > + local_irq_save(flags);
> > + rdtp = &__get_cpu_var(rcu_dynticks);
> > + WARN_ON_ONCE(rdtp->dynticks_nesting != 1);
> > + rdtp->dynticks_nesting = (LLONG_MAX / 2) + 1;
> > + local_irq_restore(flags);
> > +}
> > +
>
> Any chance that either of these two needs a memory barrier of some kind,
> to prevent leakage of operations from between them? Or can you count on
> no RCU-protected operations occurring during (or leaking into) the
> extended quiescent state?
There is no need for a memory barrier on rdtp->dynticks_nesting because
it is used (aside from state dumping) only by the local CPU. In contrast,
changes to ->dynticks are visible to other CPUs, hence the memory barriers
around changes to ->dynticks.
Information flows within the CPU from ->dynticks_nesting to ->dynticks,
which is externally visible.
Frederic, given my hamhandedness on the first patch and given that you
mentioned its being less time critical, I will let you forward port
patches #3 and #4. I have pushed the first two patches to -rcu, branch
rcu/dyntick. I will be testing over the evening.
Thanx, Paul
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/4] rcu: Irq nesting is always 0 on rcu_enter_idle_common
2011-11-29 0:29 ` Paul E. McKenney
@ 2011-11-29 1:00 ` Frederic Weisbecker
0 siblings, 0 replies; 22+ messages in thread
From: Frederic Weisbecker @ 2011-11-29 1:00 UTC (permalink / raw)
To: Paul E. McKenney; +Cc: LKML, Josh Triplett
On Mon, Nov 28, 2011 at 04:29:14PM -0800, Paul E. McKenney wrote:
> On Mon, Nov 28, 2011 at 10:24:45PM +0100, Frederic Weisbecker wrote:
> > So pass 0 directly as a nesting value on the tracing calls.
> >
> > Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
> > Cc: Josh Triplett <josh@joshtriplett.org>
> > ---
> > kernel/rcutree.c | 5 ++---
> > 1 files changed, 2 insertions(+), 3 deletions(-)
> >
> > diff --git a/kernel/rcutree.c b/kernel/rcutree.c
> > index c2aaadf..b80cb41 100644
> > --- a/kernel/rcutree.c
> > +++ b/kernel/rcutree.c
> > @@ -350,11 +350,10 @@ static int rcu_implicit_offline_qs(struct rcu_data *rdp)
> > */
> > static void rcu_idle_enter_common(struct rcu_dynticks *rdtp)
> > {
> > - trace_rcu_dyntick("Start", rdtp->dynticks_nesting);
> > + trace_rcu_dyntick("Start", 0);
> > if (!idle_cpu(smp_processor_id())) {
> > WARN_ON_ONCE(1); /* must be idle task! */
> > - trace_rcu_dyntick("Error on entry: not idle task",
> > - rdtp->dynticks_nesting);
> > + trace_rcu_dyntick("Error on entry: not idle task", 0);
> > ftrace_dump(DUMP_ALL);
> > }
> > /* CPUs seeing atomic_inc() must see prior RCU read-side crit sects */
>
> Queued, again updating to work around the mid-air collision.
>
> Thanx, Paul
>
> ------------------------------------------------------------------------
>
> rcu: Irq nesting is always 0 on rcu_enter_idle_common
>
> Because tasks don't nest, the ->dyntick_nesting must always be zero upon
> entry to rcu_idle_enter_common(). Therefore, pass "0" rather than the
> counter itself.
And with a better changelog.
Thanks!
>
> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
> Cc: Josh Triplett <josh@joshtriplett.org>
> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
>
> diff --git a/kernel/rcutree.c b/kernel/rcutree.c
> index 54d9b4f..e0f5072 100644
> --- a/kernel/rcutree.c
> +++ b/kernel/rcutree.c
> @@ -350,12 +350,11 @@ static int rcu_implicit_offline_qs(struct rcu_data *rdp)
> */
> static void rcu_idle_enter_common(struct rcu_dynticks *rdtp, long long oldval)
> {
> - trace_rcu_dyntick("Start", oldval, rdtp->dynticks_nesting);
> + trace_rcu_dyntick("Start", oldval, 0);
> if (!is_idle_task(current)) {
> struct task_struct *idle = idle_task(smp_processor_id());
>
> - trace_rcu_dyntick("Error on entry: not idle task",
> - oldval, rdtp->dynticks_nesting);
> + trace_rcu_dyntick("Error on entry: not idle task", oldval, 0);
> ftrace_dump(DUMP_ALL);
> WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s",
> current->pid, current->comm,
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 4/4 RFC] rcu: New rcu_user_enter_irq() and rcu_user_exit_irq() APIs
2011-11-29 1:00 ` Paul E. McKenney
@ 2011-11-29 5:21 ` Josh Triplett
2011-11-29 14:05 ` Frederic Weisbecker
1 sibling, 0 replies; 22+ messages in thread
From: Josh Triplett @ 2011-11-29 5:21 UTC (permalink / raw)
To: Paul E. McKenney; +Cc: Frederic Weisbecker, LKML
On Mon, Nov 28, 2011 at 05:00:36PM -0800, Paul E. McKenney wrote:
> On Mon, Nov 28, 2011 at 01:53:23PM -0800, Josh Triplett wrote:
> > On Mon, Nov 28, 2011 at 10:24:47PM +0100, Frederic Weisbecker wrote:
> > > A CPU running in adaptive tickless mode wants to enter into
> > > RCU extended quiescent state while running in userspace. This
> > > way we can shut down the tick that is usually needed on each
> > > CPU for the needs of RCU.
> >
> > Very awesome. I've wanted to see this change for a long time. Thanks!
>
> I am a fan, also. ;-)
>
> [ . . . ]
>
> > > @@ -503,6 +515,18 @@ void rcu_user_exit(void)
> > > __rcu_idle_exit();
> > > }
> > >
> > > +void rcu_user_exit_irq(void)
> > > +{
> > > + unsigned long flags;
> > > + struct rcu_dynticks *rdtp;
> > > +
> > > + local_irq_save(flags);
> > > + rdtp = &__get_cpu_var(rcu_dynticks);
> > > + WARN_ON_ONCE(rdtp->dynticks_nesting != 1);
> > > + rdtp->dynticks_nesting = (LLONG_MAX / 2) + 1;
> > > + local_irq_restore(flags);
> > > +}
> > > +
> >
> > Any chance that either of these two needs a memory barrier of some kind,
> > to prevent leakage of operations from between them? Or can you count on
> > no RCU-protected operations occurring during (or leaking into) the
> > extended quiescent state?
>
> There is no need for a memory barrier on rdtp->dynticks_nesting because
> it is used (aside from state dumping) only by the local CPU. In contrast,
> changes to ->dynticks are visible to other CPUs, hence the memory barriers
> around changes to ->dynticks.
>
> Information flows within the CPU from ->dynticks_nesting to ->dynticks,
> which is externally visible.
Thanks for the clarification; just wanted to make sure I understood the
various data involved here.
Now that I understand that:
Reviewed-by: Josh Triplett <josh@joshtriplett.org>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/4] rcu: Make new RCU dynticks API work with nohz cpusets
2011-11-28 21:24 [PATCH 0/4] rcu: Make new RCU dynticks API work with nohz cpusets Frederic Weisbecker
` (3 preceding siblings ...)
2011-11-28 21:24 ` [PATCH 4/4 RFC] rcu: New rcu_user_enter_irq() and rcu_user_exit_irq() APIs Frederic Weisbecker
@ 2011-11-29 5:22 ` Josh Triplett
2011-11-29 5:43 ` Paul E. McKenney
4 siblings, 1 reply; 22+ messages in thread
From: Josh Triplett @ 2011-11-29 5:22 UTC (permalink / raw)
To: Frederic Weisbecker; +Cc: Paul E. McKenney, LKML
On Mon, Nov 28, 2011 at 10:24:43PM +0100, Frederic Weisbecker wrote:
> Hi Paul,
>
> This is an attempt to make the current RCU dynticks API
> working with the nohz cpusets.
>
> I believe the two first patches could be pushed in your trees.
> Patches 3 and 4 are rather something I plan to apply in mine,
> given they are not needed upstream yet.
>
> Waiting for your comments.
>
> Thanks.
>
> Frederic Weisbecker (4):
> rcu: Don't check irq nesting from rcu idle entry/exit
> rcu: Irq nesting is always 0 on rcu_enter_idle_common
> rcu: New rcu_user_enter() and rcu_user_exit() APIs
> rcu: New rcu_user_enter_irq() and rcu_user_exit_irq() APIs
For the whole series:
Reviewed-by: Josh Triplett <josh@joshtriplett.org>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/4] rcu: Make new RCU dynticks API work with nohz cpusets
2011-11-29 5:22 ` [PATCH 0/4] rcu: Make new RCU dynticks API work with nohz cpusets Josh Triplett
@ 2011-11-29 5:43 ` Paul E. McKenney
2011-11-29 8:48 ` Josh Triplett
0 siblings, 1 reply; 22+ messages in thread
From: Paul E. McKenney @ 2011-11-29 5:43 UTC (permalink / raw)
To: Josh Triplett; +Cc: Frederic Weisbecker, LKML
On Mon, Nov 28, 2011 at 09:22:25PM -0800, Josh Triplett wrote:
> On Mon, Nov 28, 2011 at 10:24:43PM +0100, Frederic Weisbecker wrote:
> > Hi Paul,
> >
> > This is an attempt to make the current RCU dynticks API
> > working with the nohz cpusets.
> >
> > I believe the two first patches could be pushed in your trees.
> > Patches 3 and 4 are rather something I plan to apply in mine,
> > given they are not needed upstream yet.
> >
> > Waiting for your comments.
> >
> > Thanks.
> >
> > Frederic Weisbecker (4):
> > rcu: Don't check irq nesting from rcu idle entry/exit
> > rcu: Irq nesting is always 0 on rcu_enter_idle_common
> > rcu: New rcu_user_enter() and rcu_user_exit() APIs
> > rcu: New rcu_user_enter_irq() and rcu_user_exit_irq() APIs
>
> For the whole series:
>
> Reviewed-by: Josh Triplett <josh@joshtriplett.org>
Thank you, Josh!
Does that cover the conflict-resolved versions of the first two?
o https://lkml.org/lkml/2011/11/28/626
o https://lkml.org/lkml/2011/11/28/624
Thanx, Paul
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/4] rcu: Make new RCU dynticks API work with nohz cpusets
2011-11-29 5:43 ` Paul E. McKenney
@ 2011-11-29 8:48 ` Josh Triplett
2011-11-29 17:44 ` Paul E. McKenney
0 siblings, 1 reply; 22+ messages in thread
From: Josh Triplett @ 2011-11-29 8:48 UTC (permalink / raw)
To: Paul E. McKenney; +Cc: Frederic Weisbecker, LKML
On Mon, Nov 28, 2011 at 09:43:42PM -0800, Paul E. McKenney wrote:
> On Mon, Nov 28, 2011 at 09:22:25PM -0800, Josh Triplett wrote:
> > On Mon, Nov 28, 2011 at 10:24:43PM +0100, Frederic Weisbecker wrote:
> > > Hi Paul,
> > >
> > > This is an attempt to make the current RCU dynticks API
> > > working with the nohz cpusets.
> > >
> > > I believe the two first patches could be pushed in your trees.
> > > Patches 3 and 4 are rather something I plan to apply in mine,
> > > given they are not needed upstream yet.
> > >
> > > Waiting for your comments.
> > >
> > > Thanks.
> > >
> > > Frederic Weisbecker (4):
> > > rcu: Don't check irq nesting from rcu idle entry/exit
> > > rcu: Irq nesting is always 0 on rcu_enter_idle_common
> > > rcu: New rcu_user_enter() and rcu_user_exit() APIs
> > > rcu: New rcu_user_enter_irq() and rcu_user_exit_irq() APIs
> >
> > For the whole series:
> >
> > Reviewed-by: Josh Triplett <josh@joshtriplett.org>
>
> Thank you, Josh!
>
> Does that cover the conflict-resolved versions of the first two?
>
> o https://lkml.org/lkml/2011/11/28/626
> o https://lkml.org/lkml/2011/11/28/624
Yes, for the ones with Frederic's further eagle-eyed fix.
- Josh
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 4/4 RFC] rcu: New rcu_user_enter_irq() and rcu_user_exit_irq() APIs
2011-11-28 21:53 ` Josh Triplett
2011-11-29 1:00 ` Paul E. McKenney
@ 2011-11-29 13:53 ` Frederic Weisbecker
1 sibling, 0 replies; 22+ messages in thread
From: Frederic Weisbecker @ 2011-11-29 13:53 UTC (permalink / raw)
To: Josh Triplett; +Cc: Paul E. McKenney, LKML
On Mon, Nov 28, 2011 at 01:53:23PM -0800, Josh Triplett wrote:
> On Mon, Nov 28, 2011 at 10:24:47PM +0100, Frederic Weisbecker wrote:
> > A CPU running in adaptive tickless mode wants to enter into
> > RCU extended quiescent state while running in userspace. This
> > way we can shut down the tick that is usually needed on each
> > CPU for the needs of RCU.
>
> Very awesome. I've wanted to see this change for a long time. Thanks!
:-)
>
> > Typically, RCU enters the extended quiescent state when we resume
> > to userspace through a syscall or exception exit, this is done
> > using rcu_user_enter(). Then RCU exit this state by calling
> > rcu_user_exit() from syscall or exception entry.
> >
> > However there are two other points where we may want to enter
> > or exit this state. Some remote CPU may require a tickless CPU
> > to restart its tick for any reason and send it an IPI for
> > this purpose. As we restart the tick, we don't want to resume
> > from the IPI in RCU extended quiescent state anymore.
> > Similarly we may stop the tick from an interrupt in userspace and
> > we need to be able to enter RCU extended quiescent state when we
> > resume from this interrupt to userspace.
> >
> > To these ends, we provide two new APIs:
> >
> > - rcu_user_enter_irq(). This must be called from a non-nesting
> > interrupt betwenn rcu_irq_enter() and rcu_irq_exit().
> > After the irq calls rcu_irq_exit(), we'll run into RCU extended
> > quiescent state.
> >
> > - rcu_user_exit_irq(). This must be called from a non-nesting
> > interrupt, interrupting an RCU extended quiescent state, and
> > between rcu_irq_enter() and rcu_irq_exit(). After the irq calls
> > rcu_irq_exit(), we'll prevent from resuming the RCU extended
> > quiescent.
>
> It would help to see the corresponding patches making use of this new
> API.
Right, so I plan to use it in my nohz cpuset patchset that can be found at:
git://github.com/fweisbec/linux-dynticks.git
nohz/cpuset-v1
I haven't yet integrated these patches to this tree. I first need to do a big
rebase against all the changes made against dynticks API in -rcu.
I'll do that soon.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 4/4 RFC] rcu: New rcu_user_enter_irq() and rcu_user_exit_irq() APIs
2011-11-29 1:00 ` Paul E. McKenney
2011-11-29 5:21 ` Josh Triplett
@ 2011-11-29 14:05 ` Frederic Weisbecker
2011-11-29 18:23 ` Paul E. McKenney
1 sibling, 1 reply; 22+ messages in thread
From: Frederic Weisbecker @ 2011-11-29 14:05 UTC (permalink / raw)
To: Paul E. McKenney; +Cc: Josh Triplett, LKML
On Mon, Nov 28, 2011 at 05:00:36PM -0800, Paul E. McKenney wrote:
> On Mon, Nov 28, 2011 at 01:53:23PM -0800, Josh Triplett wrote:
> > On Mon, Nov 28, 2011 at 10:24:47PM +0100, Frederic Weisbecker wrote:
> > > A CPU running in adaptive tickless mode wants to enter into
> > > RCU extended quiescent state while running in userspace. This
> > > way we can shut down the tick that is usually needed on each
> > > CPU for the needs of RCU.
> >
> > Very awesome. I've wanted to see this change for a long time. Thanks!
>
> I am a fan, also. ;-)
>
> [ . . . ]
>
> > > @@ -503,6 +515,18 @@ void rcu_user_exit(void)
> > > __rcu_idle_exit();
> > > }
> > >
> > > +void rcu_user_exit_irq(void)
> > > +{
> > > + unsigned long flags;
> > > + struct rcu_dynticks *rdtp;
> > > +
> > > + local_irq_save(flags);
> > > + rdtp = &__get_cpu_var(rcu_dynticks);
> > > + WARN_ON_ONCE(rdtp->dynticks_nesting != 1);
> > > + rdtp->dynticks_nesting = (LLONG_MAX / 2) + 1;
> > > + local_irq_restore(flags);
> > > +}
> > > +
> >
> > Any chance that either of these two needs a memory barrier of some kind,
> > to prevent leakage of operations from between them? Or can you count on
> > no RCU-protected operations occurring during (or leaking into) the
> > extended quiescent state?
>
> There is no need for a memory barrier on rdtp->dynticks_nesting because
> it is used (aside from state dumping) only by the local CPU. In contrast,
> changes to ->dynticks are visible to other CPUs, hence the memory barriers
> around changes to ->dynticks.
>
> Information flows within the CPU from ->dynticks_nesting to ->dynticks,
> which is externally visible.
>
> Frederic, given my hamhandedness on the first patch and given that you
> mentioned its being less time critical, I will let you forward port
> patches #3 and #4. I have pushed the first two patches to -rcu, branch
> rcu/dyntick. I will be testing over the evening.
Sure. Also #3 and #4 are not used upstream, so I should probably rather
carry these in my tree once I do a rebase against yours.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/4] rcu: Make new RCU dynticks API work with nohz cpusets
2011-11-29 8:48 ` Josh Triplett
@ 2011-11-29 17:44 ` Paul E. McKenney
2011-11-29 18:07 ` Frederic Weisbecker
0 siblings, 1 reply; 22+ messages in thread
From: Paul E. McKenney @ 2011-11-29 17:44 UTC (permalink / raw)
To: Josh Triplett; +Cc: Frederic Weisbecker, LKML
On Tue, Nov 29, 2011 at 12:48:31AM -0800, Josh Triplett wrote:
> On Mon, Nov 28, 2011 at 09:43:42PM -0800, Paul E. McKenney wrote:
> > On Mon, Nov 28, 2011 at 09:22:25PM -0800, Josh Triplett wrote:
> > > On Mon, Nov 28, 2011 at 10:24:43PM +0100, Frederic Weisbecker wrote:
> > > > Hi Paul,
> > > >
> > > > This is an attempt to make the current RCU dynticks API
> > > > working with the nohz cpusets.
> > > >
> > > > I believe the two first patches could be pushed in your trees.
> > > > Patches 3 and 4 are rather something I plan to apply in mine,
> > > > given they are not needed upstream yet.
> > > >
> > > > Waiting for your comments.
> > > >
> > > > Thanks.
> > > >
> > > > Frederic Weisbecker (4):
> > > > rcu: Don't check irq nesting from rcu idle entry/exit
> > > > rcu: Irq nesting is always 0 on rcu_enter_idle_common
> > > > rcu: New rcu_user_enter() and rcu_user_exit() APIs
> > > > rcu: New rcu_user_enter_irq() and rcu_user_exit_irq() APIs
> > >
> > > For the whole series:
> > >
> > > Reviewed-by: Josh Triplett <josh@joshtriplett.org>
> >
> > Thank you, Josh!
> >
> > Does that cover the conflict-resolved versions of the first two?
> >
> > o https://lkml.org/lkml/2011/11/28/626
> > o https://lkml.org/lkml/2011/11/28/624
>
> Yes, for the ones with Frederic's further eagle-eyed fix.
Right, https://lkml.org/lkml/2011/11/28/626 above rather than my
erroneous https://lkml.org/lkml/2011/11/28/621.
Though I thought it was falcon-eyed rather than eagle-eyed. ;-)
Thanx, Paul
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/4] rcu: Make new RCU dynticks API work with nohz cpusets
2011-11-29 17:44 ` Paul E. McKenney
@ 2011-11-29 18:07 ` Frederic Weisbecker
0 siblings, 0 replies; 22+ messages in thread
From: Frederic Weisbecker @ 2011-11-29 18:07 UTC (permalink / raw)
To: Paul E. McKenney; +Cc: Josh Triplett, LKML
On Tue, Nov 29, 2011 at 09:44:48AM -0800, Paul E. McKenney wrote:
> On Tue, Nov 29, 2011 at 12:48:31AM -0800, Josh Triplett wrote:
> > On Mon, Nov 28, 2011 at 09:43:42PM -0800, Paul E. McKenney wrote:
> > > On Mon, Nov 28, 2011 at 09:22:25PM -0800, Josh Triplett wrote:
> > > > On Mon, Nov 28, 2011 at 10:24:43PM +0100, Frederic Weisbecker wrote:
> > > > > Hi Paul,
> > > > >
> > > > > This is an attempt to make the current RCU dynticks API
> > > > > working with the nohz cpusets.
> > > > >
> > > > > I believe the two first patches could be pushed in your trees.
> > > > > Patches 3 and 4 are rather something I plan to apply in mine,
> > > > > given they are not needed upstream yet.
> > > > >
> > > > > Waiting for your comments.
> > > > >
> > > > > Thanks.
> > > > >
> > > > > Frederic Weisbecker (4):
> > > > > rcu: Don't check irq nesting from rcu idle entry/exit
> > > > > rcu: Irq nesting is always 0 on rcu_enter_idle_common
> > > > > rcu: New rcu_user_enter() and rcu_user_exit() APIs
> > > > > rcu: New rcu_user_enter_irq() and rcu_user_exit_irq() APIs
> > > >
> > > > For the whole series:
> > > >
> > > > Reviewed-by: Josh Triplett <josh@joshtriplett.org>
> > >
> > > Thank you, Josh!
> > >
> > > Does that cover the conflict-resolved versions of the first two?
> > >
> > > o https://lkml.org/lkml/2011/11/28/626
> > > o https://lkml.org/lkml/2011/11/28/624
> >
> > Yes, for the ones with Frederic's further eagle-eyed fix.
>
> Right, https://lkml.org/lkml/2011/11/28/626 above rather than my
> erroneous https://lkml.org/lkml/2011/11/28/621.
>
> Though I thought it was falcon-eyed rather than eagle-eyed. ;-)
Peregrine falcon-eyed more precisely. Then I can stoop over 300 km/h
right to the bug!
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 4/4 RFC] rcu: New rcu_user_enter_irq() and rcu_user_exit_irq() APIs
2011-11-29 14:05 ` Frederic Weisbecker
@ 2011-11-29 18:23 ` Paul E. McKenney
0 siblings, 0 replies; 22+ messages in thread
From: Paul E. McKenney @ 2011-11-29 18:23 UTC (permalink / raw)
To: Frederic Weisbecker; +Cc: Josh Triplett, LKML
On Tue, Nov 29, 2011 at 03:05:23PM +0100, Frederic Weisbecker wrote:
> On Mon, Nov 28, 2011 at 05:00:36PM -0800, Paul E. McKenney wrote:
> > On Mon, Nov 28, 2011 at 01:53:23PM -0800, Josh Triplett wrote:
> > > On Mon, Nov 28, 2011 at 10:24:47PM +0100, Frederic Weisbecker wrote:
> > > > A CPU running in adaptive tickless mode wants to enter into
> > > > RCU extended quiescent state while running in userspace. This
> > > > way we can shut down the tick that is usually needed on each
> > > > CPU for the needs of RCU.
> > >
> > > Very awesome. I've wanted to see this change for a long time. Thanks!
> >
> > I am a fan, also. ;-)
> >
> > [ . . . ]
> >
> > > > @@ -503,6 +515,18 @@ void rcu_user_exit(void)
> > > > __rcu_idle_exit();
> > > > }
> > > >
> > > > +void rcu_user_exit_irq(void)
> > > > +{
> > > > + unsigned long flags;
> > > > + struct rcu_dynticks *rdtp;
> > > > +
> > > > + local_irq_save(flags);
> > > > + rdtp = &__get_cpu_var(rcu_dynticks);
> > > > + WARN_ON_ONCE(rdtp->dynticks_nesting != 1);
> > > > + rdtp->dynticks_nesting = (LLONG_MAX / 2) + 1;
> > > > + local_irq_restore(flags);
> > > > +}
> > > > +
> > >
> > > Any chance that either of these two needs a memory barrier of some kind,
> > > to prevent leakage of operations from between them? Or can you count on
> > > no RCU-protected operations occurring during (or leaking into) the
> > > extended quiescent state?
> >
> > There is no need for a memory barrier on rdtp->dynticks_nesting because
> > it is used (aside from state dumping) only by the local CPU. In contrast,
> > changes to ->dynticks are visible to other CPUs, hence the memory barriers
> > around changes to ->dynticks.
> >
> > Information flows within the CPU from ->dynticks_nesting to ->dynticks,
> > which is externally visible.
> >
> > Frederic, given my hamhandedness on the first patch and given that you
> > mentioned its being less time critical, I will let you forward port
> > patches #3 and #4. I have pushed the first two patches to -rcu, branch
> > rcu/dyntick. I will be testing over the evening.
>
> Sure. Also #3 and #4 are not used upstream, so I should probably rather
> carry these in my tree once I do a rebase against yours.
Works for me! I am hoping that my dyntick-idle work is near an end.
For this round, anyway. (Fifth or sixth rework!)
Thanx, Paul
^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2011-11-29 18:27 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-28 21:24 [PATCH 0/4] rcu: Make new RCU dynticks API work with nohz cpusets Frederic Weisbecker
2011-11-28 21:24 ` [PATCH 1/4] rcu: Don't check irq nesting from rcu idle entry/exit Frederic Weisbecker
2011-11-29 0:22 ` Paul E. McKenney
2011-11-29 0:26 ` Frederic Weisbecker
2011-11-29 0:39 ` Paul E. McKenney
2011-11-29 0:58 ` Frederic Weisbecker
2011-11-28 21:24 ` [PATCH 2/4] rcu: Irq nesting is always 0 on rcu_enter_idle_common Frederic Weisbecker
2011-11-29 0:29 ` Paul E. McKenney
2011-11-29 1:00 ` Frederic Weisbecker
2011-11-28 21:24 ` [PATCH 3/4 RFC] rcu: New rcu_user_enter() and rcu_user_exit() APIs Frederic Weisbecker
2011-11-28 21:24 ` [PATCH 4/4 RFC] rcu: New rcu_user_enter_irq() and rcu_user_exit_irq() APIs Frederic Weisbecker
2011-11-28 21:53 ` Josh Triplett
2011-11-29 1:00 ` Paul E. McKenney
2011-11-29 5:21 ` Josh Triplett
2011-11-29 14:05 ` Frederic Weisbecker
2011-11-29 18:23 ` Paul E. McKenney
2011-11-29 13:53 ` Frederic Weisbecker
2011-11-29 5:22 ` [PATCH 0/4] rcu: Make new RCU dynticks API work with nohz cpusets Josh Triplett
2011-11-29 5:43 ` Paul E. McKenney
2011-11-29 8:48 ` Josh Triplett
2011-11-29 17:44 ` Paul E. McKenney
2011-11-29 18:07 ` Frederic Weisbecker
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox