From: Nathan Lynch <nathanl@linux.ibm.com>
To: linuxppc-dev@lists.ozlabs.org
Cc: ldufour@linux.ibm.com, ajd@linux.ibm.com, npiggin@gmail.com
Subject: [PATCH v2 4/4] powerpc/rtas: upgrade internal arch spinlocks
Date: Tue, 24 Jan 2023 08:04:48 -0600 [thread overview]
Message-ID: <20230124140448.45938-5-nathanl@linux.ibm.com> (raw)
In-Reply-To: <20230124140448.45938-1-nathanl@linux.ibm.com>
At the time commit f97bb36f705d ("powerpc/rtas: Turn rtas lock into a
raw spinlock") was written, the spinlock lockup detection code called
__delay(), which will not make progress if the timebase is not
advancing. Since the interprocessor timebase synchronization sequence
for chrp, cell, and some now-unsupported Power models can temporarily
freeze the timebase through an RTAS function (freeze-time-base), the
lock that serializes most RTAS calls was converted to arch_spinlock_t
to prevent kernel hangs in the lockup detection code.
However, commit bc88c10d7e69 ("locking/spinlock/debug: Remove spinlock
lockup detection code") removed that inconvenient property from the
lock debug code several years ago. So now it should be safe to
reintroduce generic locks into the RTAS support code, primarily to
increase lockdep coverage.
Making rtas_lock a spinlock_t would violate lock type nesting rules
because it can be acquired while holding raw locks, e.g. pci_lock and
irq_desc->lock. So convert it to raw_spinlock_t. There's no apparent
reason not to upgrade timebase_lock as well.
Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
---
arch/powerpc/kernel/rtas.c | 52 ++++++++++----------------------------
1 file changed, 14 insertions(+), 38 deletions(-)
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 0059bb2a8f04..c02edec3c860 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -69,7 +69,7 @@ struct rtas_t rtas;
* Exceptions to the RTAS serialization requirement (e.g. stop-self)
* must use a separate rtas_args structure.
*/
-static arch_spinlock_t rtas_lock = __ARCH_SPIN_LOCK_UNLOCKED;
+static DEFINE_RAW_SPINLOCK(rtas_lock);
static struct rtas_args rtas_args;
DEFINE_SPINLOCK(rtas_data_buf_lock);
@@ -87,28 +87,6 @@ unsigned long rtas_rmo_buf;
void (*rtas_flash_term_hook)(int);
EXPORT_SYMBOL_GPL(rtas_flash_term_hook);
-/* RTAS use home made raw locking instead of spin_lock_irqsave
- * because those can be called from within really nasty contexts
- * such as having the timebase stopped which would lockup with
- * normal locks and spinlock debugging enabled
- */
-static unsigned long lock_rtas(void)
-{
- unsigned long flags;
-
- local_irq_save(flags);
- preempt_disable();
- arch_spin_lock(&rtas_lock);
- return flags;
-}
-
-static void unlock_rtas(unsigned long flags)
-{
- arch_spin_unlock(&rtas_lock);
- local_irq_restore(flags);
- preempt_enable();
-}
-
/*
* call_rtas_display_status and call_rtas_display_status_delay
* are designed only for very early low-level debugging, which
@@ -116,14 +94,14 @@ static void unlock_rtas(unsigned long flags)
*/
static void call_rtas_display_status(unsigned char c)
{
- unsigned long s;
+ unsigned long flags;
if (!rtas.base)
return;
- s = lock_rtas();
+ raw_spin_lock_irqsave(&rtas_lock, flags);
rtas_call_unlocked(&rtas_args, 10, 1, 1, NULL, c);
- unlock_rtas(s);
+ raw_spin_unlock_irqrestore(&rtas_lock, flags);
}
static void call_rtas_display_status_delay(char c)
@@ -541,7 +519,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...)
{
va_list list;
int i;
- unsigned long s;
+ unsigned long flags;
struct rtas_args *args;
char *buff_copy = NULL;
int ret;
@@ -564,8 +542,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...)
return -1;
}
- s = lock_rtas();
-
+ raw_spin_lock_irqsave(&rtas_lock, flags);
/* We use the global rtas args buffer */
args = &rtas_args;
@@ -583,7 +560,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...)
outputs[i] = be32_to_cpu(args->rets[i + 1]);
ret = (nret > 0) ? be32_to_cpu(args->rets[0]) : 0;
- unlock_rtas(s);
+ raw_spin_unlock_irqrestore(&rtas_lock, flags);
if (buff_copy) {
log_error(buff_copy, ERR_TYPE_RTAS_LOG, 0);
@@ -1275,7 +1252,7 @@ SYSCALL_DEFINE1(rtas, struct rtas_args __user *, uargs)
buff_copy = get_errorlog_buffer();
- flags = lock_rtas();
+ raw_spin_lock_irqsave(&rtas_lock, flags);
rtas_args = args;
do_enter_rtas(__pa(&rtas_args));
@@ -1286,7 +1263,7 @@ SYSCALL_DEFINE1(rtas, struct rtas_args __user *, uargs)
if (be32_to_cpu(args.rets[0]) == -1)
errbuf = __fetch_rtas_last_error(buff_copy);
- unlock_rtas(flags);
+ raw_spin_unlock_irqrestore(&rtas_lock, flags);
if (buff_copy) {
if (errbuf)
@@ -1408,19 +1385,18 @@ int __init early_init_dt_scan_rtas(unsigned long node,
return 1;
}
-static arch_spinlock_t timebase_lock;
+static DEFINE_RAW_SPINLOCK(timebase_lock);
static u64 timebase = 0;
void rtas_give_timebase(void)
{
unsigned long flags;
- local_irq_save(flags);
+ raw_spin_lock_irqsave(&timebase_lock, flags);
hard_irq_disable();
- arch_spin_lock(&timebase_lock);
rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL);
timebase = get_tb();
- arch_spin_unlock(&timebase_lock);
+ raw_spin_unlock(&timebase_lock);
while (timebase)
barrier();
@@ -1432,8 +1408,8 @@ void rtas_take_timebase(void)
{
while (!timebase)
barrier();
- arch_spin_lock(&timebase_lock);
+ raw_spin_lock(&timebase_lock);
set_tb(timebase >> 32, timebase & 0xffffffff);
timebase = 0;
- arch_spin_unlock(&timebase_lock);
+ raw_spin_unlock(&timebase_lock);
}
--
2.37.1
next prev parent reply other threads:[~2023-01-24 14:09 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-24 14:04 [PATCH v2 0/4] powerpc/rtas: exports and locking Nathan Lynch
2023-01-24 14:04 ` [PATCH v2 1/4] powerpc/rtas: unexport 'rtas' symbol Nathan Lynch
2023-02-02 3:55 ` Andrew Donnellan
2023-01-24 14:04 ` [PATCH v2 2/4] powerpc/rtas: make all exports GPL Nathan Lynch
2023-01-24 16:18 ` Laurent Dufour
2023-02-02 4:00 ` Andrew Donnellan
2023-01-24 14:04 ` [PATCH v2 3/4] powerpc/rtas: remove lock and args fields from global rtas struct Nathan Lynch
2023-01-24 16:21 ` Laurent Dufour
2023-02-02 4:25 ` Andrew Donnellan
2023-01-24 14:04 ` Nathan Lynch [this message]
2023-02-02 7:15 ` [PATCH v2 4/4] powerpc/rtas: upgrade internal arch spinlocks Andrew Donnellan
2023-01-24 17:23 ` [PATCH v2 0/4] powerpc/rtas: exports and locking Nathan Lynch
2023-02-05 0:47 ` Michael Ellerman
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=20230124140448.45938-5-nathanl@linux.ibm.com \
--to=nathanl@linux.ibm.com \
--cc=ajd@linux.ibm.com \
--cc=ldufour@linux.ibm.com \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=npiggin@gmail.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).