From: Petr Mladek <pmladek@suse.com>
To: John Ogness <john.ogness@linutronix.de>
Cc: Sergey Senozhatsky <senozhatsky@chromium.org>,
Steven Rostedt <rostedt@goodmis.org>,
Thomas Gleixner <tglx@linutronix.de>,
linux-kernel@vger.kernel.org,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Subject: Re: port lock: was: Re: [PATCH printk v1 11/18] printk: nobkl: Introduce printer threads
Date: Fri, 21 Apr 2023 18:15:22 +0200 [thread overview]
Message-ID: <ZEK2mu9ikDhDeVvu@alley> (raw)
In-Reply-To: <ZEE_ERSc_jHaVVe9@alley>
On Thu 2023-04-20 15:33:10, Petr Mladek wrote:
> On Thu 2023-04-20 12:39:31, John Ogness wrote:
> I know. And the hostile takeover is not my concern.
>
> My concern are races between write_atomic() in emergency context
> and other driver code serialized only by the port->lock.
>
> We need an API that will make sure that any code serialized
> by port->lock is properly serialized against write->atomic()
> when the console is registered.
I though more about it. My idea is the following:
A. The nbcon side might have basically four modes
for taking the new nbcon lock. It might have four interfaces:
nbcon_trylock(struct console *con,
enum cons_prio prio);
nbcon_trylock_emergency(struct console *con,
enum cons_prio prio);
nbcon_trylock_panic(struct console *con,
enum cons_prio prio);
nbcon_lock(struct console *con,
enum cons_prio prio);
, where
+ nbcon_trylock() would use the current approach for
the printk kthread. It means that it would try to get
the lock with a timeout. But it would never try to
steel the lock.
+ nbcon_trylock_emergency() would use the current approach
used in emergency context. It would busy wait and
then try to steel the lock. But it would take over the lock
only when it is in safe context.
+ nbcon_trylock_panic() would behave the same way as
nbcon_trylock_emergency(). But it would allow to
take over the lock even when it is unsafe. It might
still fail when it is not called on the CPU that
handles the panic().
+ nbcon_lock() would wait until the lock is really
available.
and
enum cons_prio would be one of the four priorities.
The API should disable cpu migration to make sure that
it will stay the same until the lock is released.
The caller should rememner the priority somewhere,
e,g. in struct cons_ctxt.
B. The port->lock side would switch to the new nbcon lock
when the console is registered. There are two big questions
that come to my mind:
1. The original code does not expect that it might lose
the lock.
It should be enough to mark the entire section .unsafe.
In that case, only the final panic() call might steel
the lock.
2. The console registration must be done a safe way
to make sure that all callers will use the same
real lock (port->lock or nbcon_lock).
IMHO, the uart_port part might look like:
void uart_port_lock_irqsafe(struct uart_port *port,
int *cookie,
unsigned long &flags)
{
struct console *con;
try_again:
/* Synchrnonization against console registration. */
*cookie = console_srcu_read_lock();
con = rcu_access_pointer(nbcon->cons);
if (!can_use_nbcon_lock(con)) {
/* Only the port lock is available. */
spin_lock_irqsafe(&port->lock, *flags);
port->locked = LOCKED_BY_PORT_LOCK;
return;
}
/*
* The nbcon lock is available. Take it instead of
* the port->lock. The only exception is when
* there is registration in progress. In this case,
* port->lock has to be taken as well.
*
* It will always be taken only with the normal priority.
* when called from the port lock side.
*/
nbcon_lock(con, CON_PRIO_NORMAL);
local_irq_save(*flags);
if (cons->registration_in_progress) {
spin_lock(&port->lock);
port->locked = LOCKED_BY_BOTH_LOCKS;
} else {
port->locked = LOCKED_BY_NBCON_LOCK;
}
/*
* Makes sure that only nbcon_lock_panic() would
* be able to steel this lock.
*/
if (!nbcon_enter_unsafe(con, CON_PRIO_NORMAL)) {
revert locks;
goto try_again;
}
}
void uart_port_unlock_irqrestore(struct uart_port *port,
int *cookie, unsigned long *flags)
{
struct console *con;
con = rcu_access_pointer(nbcon->cons);
switch (port->locked) {
LOCKED_BY_PORT_LOCK:
spin_unlock_irqrestore(&port->lock, *flags);
break;
LOCKED_BY_BOTH_LOCKS:
spin_unlock(&port->lock);
fallthrough;
LOCKED_BY_NBCON_LOCK:
nbcon_exit_unsafe(con, CON_PRIO_NORMAL);
local_irq_restore(*flags);
nbcon_unlock(con, CON_PRIO_NORMAL);
};
console_srcu_unlock(*cookie);
}
and finally the registration:
void register_console(struct console *newcon)
{
[...]
if (con->flags & CON_NBCON) {
nbcon_lock(con);
nbcon->regisration_in_progress = true;
nbcon_unlock(con);
/*
* Make sure that callers are locked by both
* nbcon_lock() and port->lock()
*/
synchronize_srcu();
}
/* Insert the console into console_list */
if (con->flags & CON_NBCON) {
nbcon_lock(con);
nbcon->regisration_in_progress = false;
nbcon_unlock(con);
}
[...]
}
and similar thing in uregister_console().
I am not sure if I should send this on Friday evening. But I reworked
it many times and I do not longer see any obvious reason why it
could not work.
My relief is that it builds on top of your code. It basically just
adds the port_lock interface. I hope that it would actually simplify
things a lot.
Well, a huge challenge might be to replace all spin_lock(port->lock)
calls with the new API. There is a lot of code shared between various
consoles and we wanted to migrate them one-by-one.
On the other hand, the new port_lock() API should behave as simple
spin lock when port->cons is a legacy console.
Best Regards,
Petr
next prev parent reply other threads:[~2023-04-21 16:15 UTC|newest]
Thread overview: 92+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-02 19:56 [PATCH printk v1 00/18] threaded/atomic console support John Ogness
2023-03-02 19:56 ` [PATCH printk v1 01/18] kdb: do not assume write() callback available John Ogness
2023-03-07 14:57 ` Petr Mladek
2023-03-07 16:34 ` Doug Anderson
2023-03-09 10:52 ` Daniel Thompson
2023-03-09 11:26 ` Petr Mladek
2023-03-09 11:30 ` Daniel Thompson
2023-03-02 19:56 ` [PATCH printk v1 02/18] printk: Add NMI check to down_trylock_console_sem() John Ogness
2023-03-07 16:05 ` Petr Mladek
2023-03-17 11:37 ` John Ogness
2023-04-13 13:42 ` Petr Mladek
2023-03-02 19:56 ` [PATCH printk v1 03/18] printk: Consolidate console deferred printing John Ogness
2023-03-08 13:15 ` Petr Mladek
2023-03-17 13:05 ` John Ogness
2023-04-13 15:15 ` Petr Mladek
2023-03-02 19:56 ` [PATCH printk v1 04/18] printk: Add per-console suspended state John Ogness
2023-03-08 14:40 ` Petr Mladek
2023-03-17 13:22 ` John Ogness
2023-04-14 9:56 ` Petr Mladek
2023-03-02 19:56 ` [PATCH printk v1 05/18] printk: Add non-BKL console basic infrastructure John Ogness
2023-03-09 14:08 ` global states: was: " Petr Mladek
2023-03-17 13:29 ` John Ogness
2023-03-09 15:32 ` naming: " Petr Mladek
2023-03-17 13:39 ` John Ogness
2023-03-21 16:04 ` union: was: " Petr Mladek
2023-03-27 16:28 ` John Ogness
2023-03-28 8:20 ` Petr Mladek
2023-03-28 9:42 ` John Ogness
2023-03-28 12:52 ` Petr Mladek
2023-03-28 13:47 ` Steven Rostedt
2023-03-02 19:56 ` [PATCH printk v1 06/18] printk: nobkl: Add acquire/release logic John Ogness
2023-03-06 9:07 ` Dan Carpenter
2023-03-06 9:39 ` John Ogness
2023-03-13 16:07 ` Petr Mladek
2023-03-17 14:56 ` John Ogness
2023-03-20 16:10 ` Petr Mladek
2023-03-17 17:34 ` simplify: was: " Petr Mladek
2023-03-21 15:36 ` Petr Mladek
2023-04-02 18:39 ` John Ogness
2023-03-02 19:56 ` [PATCH printk v1 07/18] printk: nobkl: Add buffer management John Ogness
2023-03-21 16:38 ` Petr Mladek
2023-03-23 13:38 ` John Ogness
2023-03-23 15:25 ` Petr Mladek
2023-03-02 19:56 ` [PATCH printk v1 08/18] printk: nobkl: Add sequence handling John Ogness
2023-03-27 15:45 ` Petr Mladek
2023-03-02 19:56 ` [PATCH printk v1 09/18] printk: nobkl: Add print state functions John Ogness
2023-03-29 13:58 ` buffer write race: " Petr Mladek
2023-03-29 14:33 ` John Ogness
2023-03-30 11:54 ` Petr Mladek
2023-03-29 14:05 ` misc details: was: " Petr Mladek
2023-03-02 19:56 ` [PATCH printk v1 10/18] printk: nobkl: Add emit function and callback functions for atomic printing John Ogness
2023-03-03 0:19 ` kernel test robot
2023-03-03 10:55 ` John Ogness
2023-03-31 10:29 ` dropped handling: was: " Petr Mladek
2023-03-31 10:36 ` semantic: " Petr Mladek
[not found] ` <87edp29kvq.fsf@jogness.linutronix.de>
[not found] ` <ZCraqrkqFtsfLWuP@alley>
[not found] ` <87ilecsrvl.fsf@jogness.linutronix.de>
2023-04-04 14:09 ` Petr Mladek
2023-03-02 19:56 ` [PATCH printk v1 11/18] printk: nobkl: Introduce printer threads John Ogness
2023-03-03 1:23 ` kernel test robot
2023-03-03 10:56 ` John Ogness
2023-04-05 10:48 ` boot console: was: " Petr Mladek
2023-04-06 8:09 ` wakeup synchronization: " Petr Mladek
2023-04-06 9:46 ` port lock: " Petr Mladek
2023-04-20 9:55 ` Petr Mladek
2023-04-20 10:33 ` John Ogness
2023-04-20 13:33 ` Petr Mladek
2023-04-21 16:15 ` Petr Mladek [this message]
2023-04-06 13:19 ` misc: " Petr Mladek
2023-04-13 13:28 ` (k)thread: " Petr Mladek
2023-03-02 19:56 ` [PATCH printk v1 12/18] printk: nobkl: Add printer thread wakeups John Ogness
2023-04-12 9:38 ` Petr Mladek
2023-03-02 19:56 ` [PATCH printk v1 13/18] printk: nobkl: Add write context storage for atomic writes John Ogness
2023-03-02 19:56 ` [PATCH printk v1 14/18] printk: nobkl: Provide functions for atomic write enforcement John Ogness
2023-04-12 14:53 ` Petr Mladek
2023-03-02 19:56 ` [PATCH printk v1 15/18] printk: nobkl: Stop threads on shutdown/reboot John Ogness
2023-04-13 9:03 ` Petr Mladek
2023-03-02 19:56 ` [PATCH printk v1 16/18] kernel/panic: Add atomic write enforcement to warn/panic John Ogness
2023-04-13 10:08 ` Petr Mladek
2023-04-13 12:13 ` John Ogness
2023-04-14 10:10 ` Petr Mladek
2023-03-02 19:56 ` [PATCH printk v1 17/18] rcu: Add atomic write enforcement for rcu stalls John Ogness
2023-04-13 12:10 ` Petr Mladek
2023-03-02 19:56 ` [PATCH printk v1 18/18] printk: Perform atomic flush in console_flush_on_panic() John Ogness
2023-04-13 12:20 ` Petr Mladek
2023-03-02 19:58 ` [PATCH printk v1 00/18] serial: 8250: implement non-BKL console John Ogness
2023-03-28 13:33 ` locking API: was: " Petr Mladek
2023-03-28 13:57 ` John Ogness
2023-03-28 15:10 ` Petr Mladek
2023-03-28 21:47 ` John Ogness
2023-03-29 8:03 ` Petr Mladek
2023-03-28 13:59 ` [PATCH printk v1 00/18] POC: serial: 8250: implement nbcon console John Ogness
2023-03-09 10:55 ` [PATCH printk v1 00/18] threaded/atomic console support Daniel Thompson
2023-03-09 11:14 ` John Ogness
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=ZEK2mu9ikDhDeVvu@alley \
--to=pmladek@suse.com \
--cc=gregkh@linuxfoundation.org \
--cc=john.ogness@linutronix.de \
--cc=linux-kernel@vger.kernel.org \
--cc=rostedt@goodmis.org \
--cc=senozhatsky@chromium.org \
--cc=tglx@linutronix.de \
/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.