From: Sven Joachim <svenjoac@gmx.de>
To: Peter Zijlstra <peterz@infradead.org>
Cc: rjw@rjwysocki.net, bp@alien8.de, x86@kernel.org,
tony.luck@intel.com, lenb@kernel.org, daniel.lezcano@linaro.org,
linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org,
linux-pm@vger.kernel.org, ulf.hansson@linaro.org,
paulmck@kernel.org, tglx@linutronix.de,
naresh.kamboju@linaro.org
Subject: Re: [RFC][PATCH 4/4] acpi: Take over RCU-idle for C3-BM idle
Date: Mon, 21 Sep 2020 11:12:33 +0200 [thread overview]
Message-ID: <87wo0npk72.fsf@turtle.gmx.de> (raw)
In-Reply-To: <20200915103806.479637218@infradead.org> (Peter Zijlstra's message of "Tue, 15 Sep 2020 12:32:01 +0200")
On 2020-09-15 12:32 +0200, Peter Zijlstra wrote:
> The C3 BusMaster idle code takes lock in a number of places, some deep
> inside the ACPI code. Instead of wrapping it all in RCU_NONIDLE, have
> the driver take over RCU-idle duty and avoid flipping RCU state back
> and forth a lot.
>
> ( by marking 'C3 && bm_check' as RCU_IDLE, we _must_ call enter_bm() for
> that combination, otherwise we'll loose RCU-idle, this requires
> shuffling some code around )
>
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
I got modpost errors in 5.9-rc6 after this patch:
ERROR: modpost: "rcu_idle_enter" [drivers/acpi/processor.ko] undefined!
ERROR: modpost: "rcu_idle_exit" [drivers/acpi/processor.ko] undefined!
Reverting commit 1fecfdbb7acc made them go away. Notably my
configuration had CONFIG_ACPI_PROCESSOR=m, changing that
to CONFIG_ACPI_PROCESSOR=y let the build succeed as well.
Cheers,
Sven
> ---
> drivers/acpi/processor_idle.c | 69 +++++++++++++++++++++++++++++-------------
> 1 file changed, 49 insertions(+), 20 deletions(-)
>
> --- a/drivers/acpi/processor_idle.c
> +++ b/drivers/acpi/processor_idle.c
> @@ -558,22 +558,43 @@ static DEFINE_RAW_SPINLOCK(c3_lock);
>
> /**
> * acpi_idle_enter_bm - enters C3 with proper BM handling
> + * @drv: cpuidle driver
> * @pr: Target processor
> * @cx: Target state context
> + * @index: index of target state
> */
> -static void acpi_idle_enter_bm(struct acpi_processor *pr,
> - struct acpi_processor_cx *cx)
> +static int acpi_idle_enter_bm(struct cpuidle_driver *drv,
> + struct acpi_processor *pr,
> + struct acpi_processor_cx *cx,
> + int index)
> {
> + static struct acpi_processor_cx safe_cx = {
> + .entry_method = ACPI_CSTATE_HALT,
> + };
> +
> /*
> * disable bus master
> * bm_check implies we need ARB_DIS
> * bm_control implies whether we can do ARB_DIS
> *
> - * That leaves a case where bm_check is set and bm_control is
> - * not set. In that case we cannot do much, we enter C3
> - * without doing anything.
> + * That leaves a case where bm_check is set and bm_control is not set.
> + * In that case we cannot do much, we enter C3 without doing anything.
> */
> - if (pr->flags.bm_control) {
> + bool dis_bm = pr->flags.bm_control;
> +
> + /* If we can skip BM, demote to a safe state. */
> + if (!cx->bm_sts_skip && acpi_idle_bm_check()) {
> + dis_bm = false;
> + index = drv->safe_state_index;
> + if (index >= 0) {
> + cx = this_cpu_read(acpi_cstate[index]);
> + } else {
> + cx = &safe_cx;
> + index = -EBUSY;
> + }
> + }
> +
> + if (dis_bm) {
> raw_spin_lock(&c3_lock);
> c3_cpu_count++;
> /* Disable bus master arbitration when all CPUs are in C3 */
> @@ -582,15 +603,21 @@ static void acpi_idle_enter_bm(struct ac
> raw_spin_unlock(&c3_lock);
> }
>
> + rcu_idle_enter();
> +
> acpi_idle_do_entry(cx);
>
> + rcu_idle_exit();
> +
> /* Re-enable bus master arbitration */
> - if (pr->flags.bm_control) {
> + if (dis_bm) {
> raw_spin_lock(&c3_lock);
> acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
> c3_cpu_count--;
> raw_spin_unlock(&c3_lock);
> }
> +
> + return index;
> }
>
> static int acpi_idle_enter(struct cpuidle_device *dev,
> @@ -604,20 +631,13 @@ static int acpi_idle_enter(struct cpuidl
> return -EINVAL;
>
> if (cx->type != ACPI_STATE_C1) {
> + if (cx->type == ACPI_STATE_C3 && pr->flags.bm_check)
> + return acpi_idle_enter_bm(drv, pr, cx, index);
> +
> + /* C2 to C1 demotion. */
> if (acpi_idle_fallback_to_c1(pr) && num_online_cpus() > 1) {
> index = ACPI_IDLE_STATE_START;
> cx = per_cpu(acpi_cstate[index], dev->cpu);
> - } else if (cx->type == ACPI_STATE_C3 && pr->flags.bm_check) {
> - if (cx->bm_sts_skip || !acpi_idle_bm_check()) {
> - acpi_idle_enter_bm(pr, cx);
> - return index;
> - } else if (drv->safe_state_index >= 0) {
> - index = drv->safe_state_index;
> - cx = per_cpu(acpi_cstate[index], dev->cpu);
> - } else {
> - acpi_safe_halt();
> - return -EBUSY;
> - }
> }
> }
>
> @@ -641,7 +661,13 @@ static int acpi_idle_enter_s2idle(struct
> return 0;
>
> if (pr->flags.bm_check) {
> - acpi_idle_enter_bm(pr, cx);
> + u8 bm_sts_skip = cx->bm_sts_skip;
> +
> + /* Don't check BM_STS, do an unconditional ARB_DIS for S2IDLE */
> + cx->bm_sts_skip = 1;
> + acpi_idle_enter_bm(drv, pr, cx, index);
> + cx->bm_sts_skip = bm_sts_skip;
> +
> return 0;
> } else {
> ACPI_FLUSH_CPU_CACHE();
> @@ -674,8 +700,11 @@ static int acpi_processor_setup_cpuidle_
> if (lapic_timer_needs_broadcast(pr, cx))
> state->flags |= CPUIDLE_FLAG_TIMER_STOP;
>
> - if (cx->type == ACPI_STATE_C3)
> + if (cx->type == ACPI_STATE_C3) {
> state->flags |= CPUIDLE_FLAG_TLB_FLUSHED;
> + if (pr->flags.bm_check)
> + state->flags |= CPUIDLE_FLAG_RCU_IDLE;
> + }
>
> count++;
> if (count == CPUIDLE_STATE_MAX)
next prev parent reply other threads:[~2020-09-21 9:18 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-15 10:31 [RFC][PATCH 0/4] Fix up ACPI processor idle vs RCU Peter Zijlstra
2020-09-15 10:31 ` [RFC][PATCH 1/4] acpi: Use CPUIDLE_FLAG_TIMER_STOP Peter Zijlstra
2020-09-15 16:26 ` Rafael J. Wysocki
2020-09-16 15:42 ` peterz
2020-09-16 16:01 ` Borislav Petkov
2020-09-16 17:38 ` Rafael J. Wysocki
2020-09-16 17:38 ` Rafael J. Wysocki
2020-09-22 3:26 ` Guenter Roeck
2020-09-22 19:03 ` Rafael J. Wysocki
2020-09-15 10:31 ` [RFC][PATCH 2/4] acpi: Use CPUIDLE_FLAG_TLB_FLUSHED Peter Zijlstra
2020-09-15 10:32 ` [RFC][PATCH 3/4] cpuidle: Allow cpuidle drivers to take over RCU-idle Peter Zijlstra
2020-09-15 13:20 ` Ulf Hansson
2020-09-15 10:32 ` [RFC][PATCH 4/4] acpi: Take over RCU-idle for C3-BM idle Peter Zijlstra
2020-09-21 9:12 ` Sven Joachim [this message]
2020-09-21 10:37 ` [PATCH] rcu/tree: Export rcu_idle_{enter,exit} to module Borislav Petkov
2020-09-21 12:15 ` Rafael J. Wysocki
2020-09-21 13:32 ` Paul E. McKenney
2020-09-21 13:38 ` Rafael J. Wysocki
2020-09-25 15:20 ` [RFC][PATCH 4/4] acpi: Take over RCU-idle for C3-BM idle Guenter Roeck
2020-09-25 15:24 ` Rafael J. Wysocki
2020-09-25 15:29 ` Paul E. McKenney
2020-09-15 18:31 ` [RFC][PATCH 0/4] Fix up ACPI processor idle vs RCU Borislav Petkov
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=87wo0npk72.fsf@turtle.gmx.de \
--to=svenjoac@gmx.de \
--cc=bp@alien8.de \
--cc=daniel.lezcano@linaro.org \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=naresh.kamboju@linaro.org \
--cc=paulmck@kernel.org \
--cc=peterz@infradead.org \
--cc=rjw@rjwysocki.net \
--cc=tglx@linutronix.de \
--cc=tony.luck@intel.com \
--cc=ulf.hansson@linaro.org \
--cc=x86@kernel.org \
/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.