* Re: [PATCH next v1 1/2] serial: 8250: Switch to nbcon console
2024-09-05 13:47 ` [PATCH next v1 1/2] serial: 8250: Switch to nbcon console John Ogness
@ 2024-09-05 14:15 ` Andy Shevchenko
2024-09-05 19:23 ` John Ogness
2024-09-06 10:10 ` Greg Kroah-Hartman
` (4 subsequent siblings)
5 siblings, 1 reply; 22+ messages in thread
From: Andy Shevchenko @ 2024-09-05 14:15 UTC (permalink / raw)
To: John Ogness
Cc: Greg Kroah-Hartman, Jiri Slaby, Petr Mladek, Sergey Senozhatsky,
Steven Rostedt, Thomas Gleixner, linux-serial, linux-kernel,
Tony Lindgren, Paul E. McKenney, Uwe Kleine-König,
Ilpo Järvinen, Serge Semin, Rengarajan S, Wolfram Sang
On Thu, Sep 05, 2024 at 03:53:18PM +0206, John Ogness wrote:
> Implement the necessary callbacks to switch the 8250 console driver
> to perform as an nbcon console.
>
> Add implementations for the nbcon console callbacks (write_atomic,
> write_thread, device_lock, device_unlock) and add CON_NBCON to the
> initial flags.
>
> The legacy code is kept in order to easily switch back to legacy mode
> by defining USE_SERIAL_8250_LEGACY_CONSOLE.
...
> static struct console univ8250_console = {
> .name = "ttyS",
> +#ifdef USE_SERIAL_8250_LEGACY_CONSOLE
Can it be done at run-time (theoretically or even practically)?
(Note that we have already knob to disable / enable consoles.)
> .write = univ8250_console_write,
> + .flags = CON_PRINTBUFFER | CON_ANYTIME,
> +#else
> + .write_atomic = univ8250_console_write_atomic,
> + .write_thread = univ8250_console_write_thread,
> + .device_lock = univ8250_console_device_lock,
> + .device_unlock = univ8250_console_device_unlock,
> + .flags = CON_PRINTBUFFER | CON_ANYTIME | CON_NBCON,
> +#endif
> .device = uart_console_device,
> .setup = univ8250_console_setup,
> .exit = univ8250_console_exit,
> .match = univ8250_console_match,
> - .flags = CON_PRINTBUFFER | CON_ANYTIME,
> .index = -1,
> .data = &serial8250_reg,
> };
I would arrange this slightly differently, but not a big deal.
static struct console univ8250_console = {
.name = "ttyS",
.device = uart_console_device,
#ifndef USE_SERIAL_8250_LEGACY_CONSOLE
.flags = CON_PRINTBUFFER | CON_ANYTIME | CON_NBCON,
.write_atomic = univ8250_console_write_atomic,
.write_thread = univ8250_console_write_thread,
.device_lock = univ8250_console_device_lock,
.device_unlock = univ8250_console_device_unlock,
#else
.flags = CON_PRINTBUFFER | CON_ANYTIME,
.write = univ8250_console_write,
#endif
.setup = univ8250_console_setup,
.exit = univ8250_console_exit,
.match = univ8250_console_match,
.index = -1,
.data = &serial8250_reg,
};
...
> + if (nbcon_exit_unsafe(wctxt)) {
> + int len = READ_ONCE(wctxt->len);
> + int i;
unsigned ?
> + /*
> + * Write out the message. Toggle unsafe for each byte in order
> + * to give another (higher priority) context the opportunity
> + * for a friendly takeover. If such a takeover occurs, this
> + * must abort writing since wctxt->outbuf and wctxt->len are
> + * no longer valid.
> + */
> + for (i = 0; i < len; i++) {
> + if (!nbcon_enter_unsafe(wctxt))
> + break;
> +
> + uart_console_write(port, wctxt->outbuf + i, 1, serial8250_console_putchar);
> +
> + if (!nbcon_exit_unsafe(wctxt))
> + break;
> + }
> + }
...
> + /* Finally, wait for transmitter to become empty and restore IER. */
> + wait_for_xmitr(up, UART_LSR_BOTH_EMPTY);
> + if (em485) {
> + mdelay(port->rs485.delay_rts_after_send);
> + if (em485->tx_stopped)
> + up->rs485_stop_tx(up);
> + }
> + serial_port_out(port, UART_IER, ier);
> +
> + /*
> + * The receive handling will happen properly because the receive ready
> + * bit will still be set; it is not cleared on read. However, modem
> + * control will not, we must call it if we have saved something in the
> + * saved flags while processing with interrupts off.
> + */
> + if (up->msr_saved_flags)
> + serial8250_modem_status(up);
(1)
...
> + /* Atomic console not supported for rs485 mode. */
RS485
...
> + /*
> + * First save IER then disable the interrupts. The special variant to
> + * clear IER is used because atomic printing may occur without holding
> + * the port lock.
> + */
> + ier = serial_port_in(port, UART_IER);
> + __serial8250_clear_IER(up);
> +
> + /* Check scratch reg if port powered off during system sleep. */
> + if (up->canary && (up->canary != serial_port_in(port, UART_SCR))) {
> + serial8250_console_restore(up);
> + up->canary = 0;
> + }
> +
> + if (up->console_newline_needed)
> + uart_console_write(port, "\n", 1, serial8250_console_putchar);
> + uart_console_write(port, wctxt->outbuf, wctxt->len, serial8250_console_putchar);
> +
> + /* Finally, wait for transmitter to become empty and restore IER. */
> + wait_for_xmitr(up, UART_LSR_BOTH_EMPTY);
> + serial_port_out(port, UART_IER, ier);
(2)
Feels like parts (1) and (2) duplicates existing pieces of code. May it be
refactored to minimize the duplication?
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH next v1 1/2] serial: 8250: Switch to nbcon console
2024-09-05 14:15 ` Andy Shevchenko
@ 2024-09-05 19:23 ` John Ogness
2024-09-05 19:30 ` Andy Shevchenko
0 siblings, 1 reply; 22+ messages in thread
From: John Ogness @ 2024-09-05 19:23 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Greg Kroah-Hartman, Jiri Slaby, Petr Mladek, Sergey Senozhatsky,
Steven Rostedt, Thomas Gleixner, linux-serial, linux-kernel,
Tony Lindgren, Paul E. McKenney, Uwe Kleine-König,
Ilpo Järvinen, Serge Semin, Rengarajan S, Wolfram Sang
On 2024-09-05, Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
> On Thu, Sep 05, 2024 at 03:53:18PM +0206, John Ogness wrote:
>> Implement the necessary callbacks to switch the 8250 console driver
>> to perform as an nbcon console.
>>
>> Add implementations for the nbcon console callbacks (write_atomic,
>> write_thread, device_lock, device_unlock) and add CON_NBCON to the
>> initial flags.
>>
>> The legacy code is kept in order to easily switch back to legacy mode
>> by defining USE_SERIAL_8250_LEGACY_CONSOLE.
>
> ...
>
>> static struct console univ8250_console = {
>> .name = "ttyS",
>> +#ifdef USE_SERIAL_8250_LEGACY_CONSOLE
>
> Can it be done at run-time (theoretically or even practically)?
> (Note that we have already knob to disable / enable consoles.)
We don't want to maintain the legacy variant and really people should
not be using it either. NBCON is the way forward for all console
drivers.
I will just remove it for v2. If someone wants to use the old code, they
will need to revert the patch.
>> + if (nbcon_exit_unsafe(wctxt)) {
>> + int len = READ_ONCE(wctxt->len);
>
>> + int i;
>
> unsigned ?
ACK.
>> + /* Atomic console not supported for rs485 mode. */
>
> RS485
ACK.
> Feels like parts (1) and (2) duplicates existing pieces of code. May it be
> refactored to minimize the duplication?
When I remove the unused legacy code, the duplication
disappears. write_thread() and write_atomic() have very little in
common.
John Ogness
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH next v1 1/2] serial: 8250: Switch to nbcon console
2024-09-05 19:23 ` John Ogness
@ 2024-09-05 19:30 ` Andy Shevchenko
0 siblings, 0 replies; 22+ messages in thread
From: Andy Shevchenko @ 2024-09-05 19:30 UTC (permalink / raw)
To: John Ogness
Cc: Greg Kroah-Hartman, Jiri Slaby, Petr Mladek, Sergey Senozhatsky,
Steven Rostedt, Thomas Gleixner, linux-serial, linux-kernel,
Tony Lindgren, Paul E. McKenney, Uwe Kleine-König,
Ilpo Järvinen, Serge Semin, Rengarajan S, Wolfram Sang
On Thu, Sep 05, 2024 at 09:29:06PM +0206, John Ogness wrote:
> On 2024-09-05, Andy Shevchenko <andriy.shevchenko@linux.intel.com> wrote:
> > On Thu, Sep 05, 2024 at 03:53:18PM +0206, John Ogness wrote:
...
> >> +#ifdef USE_SERIAL_8250_LEGACY_CONSOLE
> >
> > Can it be done at run-time (theoretically or even practically)?
> > (Note that we have already knob to disable / enable consoles.)
>
> We don't want to maintain the legacy variant and really people should
> not be using it either. NBCON is the way forward for all console
> drivers.
>
> I will just remove it for v2. If someone wants to use the old code, they
> will need to revert the patch.
This is even better!
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH next v1 1/2] serial: 8250: Switch to nbcon console
2024-09-05 13:47 ` [PATCH next v1 1/2] serial: 8250: Switch to nbcon console John Ogness
2024-09-05 14:15 ` Andy Shevchenko
@ 2024-09-06 10:10 ` Greg Kroah-Hartman
2024-09-06 12:37 ` Petr Mladek
` (3 subsequent siblings)
5 siblings, 0 replies; 22+ messages in thread
From: Greg Kroah-Hartman @ 2024-09-06 10:10 UTC (permalink / raw)
To: John Ogness
Cc: Jiri Slaby, Petr Mladek, Sergey Senozhatsky, Steven Rostedt,
Thomas Gleixner, linux-serial, linux-kernel, Andy Shevchenko,
Tony Lindgren, Paul E. McKenney, Uwe Kleine-König,
Ilpo Järvinen, Serge Semin, Rengarajan S, Wolfram Sang
On Thu, Sep 05, 2024 at 03:53:18PM +0206, John Ogness wrote:
> Implement the necessary callbacks to switch the 8250 console driver
> to perform as an nbcon console.
>
> Add implementations for the nbcon console callbacks (write_atomic,
> write_thread, device_lock, device_unlock) and add CON_NBCON to the
> initial flags.
>
> The legacy code is kept in order to easily switch back to legacy mode
> by defining USE_SERIAL_8250_LEGACY_CONSOLE.
define it where?
And ick, having #ifdef like this is rough to maintain, why is it needed?
If this is working well, let's just switch over to the new stuff and not
look back!
thanks,
greg k-h
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH next v1 1/2] serial: 8250: Switch to nbcon console
2024-09-05 13:47 ` [PATCH next v1 1/2] serial: 8250: Switch to nbcon console John Ogness
2024-09-05 14:15 ` Andy Shevchenko
2024-09-06 10:10 ` Greg Kroah-Hartman
@ 2024-09-06 12:37 ` Petr Mladek
2024-09-06 13:35 ` John Ogness
2024-09-07 19:55 ` kernel test robot
` (2 subsequent siblings)
5 siblings, 1 reply; 22+ messages in thread
From: Petr Mladek @ 2024-09-06 12:37 UTC (permalink / raw)
To: John Ogness
Cc: Greg Kroah-Hartman, Jiri Slaby, Sergey Senozhatsky,
Steven Rostedt, Thomas Gleixner, linux-serial, linux-kernel,
Andy Shevchenko, Tony Lindgren, Paul E. McKenney,
Uwe Kleine-König, Ilpo Järvinen, Serge Semin,
Rengarajan S, Wolfram Sang
On Thu 2024-09-05 15:53:18, John Ogness wrote:
> Implement the necessary callbacks to switch the 8250 console driver
> to perform as an nbcon console.
>
> Add implementations for the nbcon console callbacks (write_atomic,
> write_thread, device_lock, device_unlock) and add CON_NBCON to the
> initial flags.
>
> The legacy code is kept in order to easily switch back to legacy mode
> by defining USE_SERIAL_8250_LEGACY_CONSOLE.
>
> --- a/drivers/tty/serial/8250/8250_core.c
> +++ b/drivers/tty/serial/8250/8250_core.c
> @@ -388,6 +388,7 @@ void __init serial8250_register_ports(struct uart_driver *drv, struct device *de
>
> #ifdef CONFIG_SERIAL_8250_CONSOLE
>
> +#ifdef USE_SERIAL_8250_LEGACY_CONSOLE
Just for record. I agree that it is better to simply remove the
obsolete legacy code.
Or maybe, we would need to keep it for the rs485 consoles, see below.
> static void univ8250_console_write(struct console *co, const char *s,
> unsigned int count)
> {
> --- a/drivers/tty/serial/8250/8250_port.c
> +++ b/drivers/tty/serial/8250/8250_port.c
> @@ -546,6 +546,13 @@ static int serial8250_em485_init(struct uart_8250_port *p)
> if (!p->em485)
> return -ENOMEM;
>
> +#ifndef USE_SERIAL_8250_LEGACY_CONSOLE
> + if (uart_console(&p->port)) {
> + dev_warn(p->port.dev, "no atomic printing for rs485 consoles\n");
> + p->port.cons->write_atomic = NULL;
> + }
Wait! This makes the rs485 consoles much less usable for debugging.
They might have troubles to see the emergency and panic messages.
Or do I miss anything, please?
Is this acceptable? Why?
Why is this limitation exactly needed?
Is is because the following code is not safe enough for the write_atomic
variant when it is guarded only by the nbcon context ownership?
void serial8250_console_write_thread(struct uart_8250_port *up,
struct nbcon_write_context *wctxt)
{
[...]
if (em485) {
if (em485->tx_stopped)
up->rs485_start_tx(up);
mdelay(port->rs485.delay_rts_before_send);
}
[...]
if (em485) {
mdelay(port->rs485.delay_rts_after_send);
if (em485->tx_stopped)
up->rs485_stop_tx(up);
}
[...]
Would it break even the nbcon console context it taken over the safe
way? Or only by "unsafe" takeover?
IMHO, we should risk the "unsafe" takeover. We still would be
in a better situation than the legacy code which ignores
the port->lock during panic() all the time (after bust_
> +#endif
> +
> hrtimer_init(&p->em485->stop_tx_timer, CLOCK_MONOTONIC,
> HRTIMER_MODE_REL);
> hrtimer_init(&p->em485->start_tx_timer, CLOCK_MONOTONIC,
> @@ -3269,6 +3285,11 @@ static void serial8250_console_putchar(struct uart_port *port, unsigned char ch)
>
> wait_for_xmitr(up, UART_LSR_THRE);
> serial_port_out(port, UART_TX, ch);
> +
> + if (ch == '\n')
> + up->console_newline_needed = false;
> + else
> + up->console_newline_needed = true;
I might be just dumb but this code confused me. I missed that the
variable was actually set after printing the character. I inverted
the logic in my head and it did not make sense.
I vote for adding a comment. Or better make the code more
straightforward by renaming the variable and inverting the logic:
if (ch == '\n')
up->console_line_ended = true;
else
up->console_line_ended = false;
> }
>
> /*
> @@ -3421,6 +3443,125 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s,
> if (locked)
> uart_port_unlock_irqrestore(port, flags);
> }
> +#else
> +void serial8250_console_write_thread(struct uart_8250_port *up,
> + struct nbcon_write_context *wctxt)
> +{
> + struct uart_8250_em485 *em485 = up->em485;
> + struct uart_port *port = &up->port;
> + unsigned int ier;
> +
> + touch_nmi_watchdog();
This should not be needed in the write_thread() variant because
it allows to schedule after emitting one record.
> + if (!nbcon_enter_unsafe(wctxt))
> + return;
> +
The rest looks good.
Best Regards,
Petr
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH next v1 1/2] serial: 8250: Switch to nbcon console
2024-09-06 12:37 ` Petr Mladek
@ 2024-09-06 13:35 ` John Ogness
2024-09-06 16:38 ` John Ogness
0 siblings, 1 reply; 22+ messages in thread
From: John Ogness @ 2024-09-06 13:35 UTC (permalink / raw)
To: Petr Mladek
Cc: Greg Kroah-Hartman, Jiri Slaby, Sergey Senozhatsky,
Steven Rostedt, Thomas Gleixner, linux-serial, linux-kernel,
Andy Shevchenko, Tony Lindgren, Paul E. McKenney,
Uwe Kleine-König, Ilpo Järvinen, Serge Semin,
Rengarajan S, Wolfram Sang
On 2024-09-06, Petr Mladek <pmladek@suse.com> wrote:
>> +#ifdef USE_SERIAL_8250_LEGACY_CONSOLE
>
> Just for record. I agree that it is better to simply remove the
> obsolete legacy code.
Agreed. I will be removing it for v2.
>> +#ifndef USE_SERIAL_8250_LEGACY_CONSOLE
>> + if (uart_console(&p->port)) {
>> + dev_warn(p->port.dev, "no atomic printing for rs485 consoles\n");
>> + p->port.cons->write_atomic = NULL;
>> + }
>
> Wait! This makes the rs485 consoles much less usable for debugging.
> They might have troubles to see the emergency and panic messages.
> Or do I miss anything, please?
>
> Is this acceptable? Why?
It is not acceptable. I am looking into making the atomic part work for
RS485 as well. My main problem is testing since I will need to get my
hands or real RS485 hardware.
>> wait_for_xmitr(up, UART_LSR_THRE);
>> serial_port_out(port, UART_TX, ch);
>> +
>> + if (ch == '\n')
>> + up->console_newline_needed = false;
>> + else
>> + up->console_newline_needed = true;
>
> I might be just dumb but this code confused me. I missed that the
> variable was actually set after printing the character. I inverted
> the logic in my head and it did not make sense.
>
> I vote for adding a comment. Or better make the code more
> straightforward by renaming the variable and inverting the logic:
>
> if (ch == '\n')
> up->console_line_ended = true;
> else
> up->console_line_ended = false;
OK. I will add a comment, rename the variable, and invert the logic.
>> +void serial8250_console_write_thread(struct uart_8250_port *up,
>> + struct nbcon_write_context *wctxt)
>> +{
>> + struct uart_8250_em485 *em485 = up->em485;
>> + struct uart_port *port = &up->port;
>> + unsigned int ier;
>> +
>> + touch_nmi_watchdog();
>
> This should not be needed in the write_thread() variant because
> it allows to schedule after emitting one record.
Agreed.
Thanks.
John
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH next v1 1/2] serial: 8250: Switch to nbcon console
2024-09-06 13:35 ` John Ogness
@ 2024-09-06 16:38 ` John Ogness
2024-09-07 20:39 ` Thomas Gleixner
2024-09-09 9:50 ` Andy Shevchenko
0 siblings, 2 replies; 22+ messages in thread
From: John Ogness @ 2024-09-06 16:38 UTC (permalink / raw)
To: Petr Mladek
Cc: Greg Kroah-Hartman, Jiri Slaby, Sergey Senozhatsky,
Steven Rostedt, Thomas Gleixner, linux-serial, linux-kernel,
Andy Shevchenko, Tony Lindgren, Paul E. McKenney,
Uwe Kleine-König, Ilpo Järvinen, Serge Semin,
Rengarajan S, Wolfram Sang
On 2024-09-06, John Ogness <john.ogness@linutronix.de> wrote:
>> Wait! This makes the rs485 consoles much less usable for debugging.
>> They might have troubles to see the emergency and panic messages.
>>
>> Is this acceptable? Why?
>
> It is not acceptable. I am looking into making the atomic part work for
> RS485 as well.
So there are 2 things _not_ supported by the write_atomic() callback:
1. RS485 mode. This is due to the need to start up TX for the
write, which can lead to:
up->rs485_start_tx()
serial8250_em485_start_tx()
serial8250_stop_rx()
serial8250_rpm_get()
pm_runtime_get_sync()
__pm_runtime_resume()
spin_lock_irqsave()
Taking a spin lock is not safe from NMI and thus disqualifies this call
chain for write_atomic().
If UART_CAP_RPM is not set, the pm_runtime_get_sync() is avoided. So I
could only disable atomic RS485 if UART_CAP_RPM is set. But the OMAP
variant of the 8250 does set this capability.
2. Modem control. This is due to waiting for inputs, which can lead to:
serial8250_modem_status()
wake_up_interruptible()
Performing wakes is not safe from scheduler or NMI and thus disqualifies
this call chain for write_atomic().
It would probably be acceptable to move serial8250_modem_status() into
an irq_work.
I would be grateful for any insights on how best to handle these 2
issues if we want full write_atomic() support for all 8250 variants.
John
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH next v1 1/2] serial: 8250: Switch to nbcon console
2024-09-06 16:38 ` John Ogness
@ 2024-09-07 20:39 ` Thomas Gleixner
2024-09-09 9:53 ` Andy Shevchenko
2024-09-09 9:50 ` Andy Shevchenko
1 sibling, 1 reply; 22+ messages in thread
From: Thomas Gleixner @ 2024-09-07 20:39 UTC (permalink / raw)
To: John Ogness, Petr Mladek
Cc: Greg Kroah-Hartman, Jiri Slaby, Sergey Senozhatsky,
Steven Rostedt, linux-serial, linux-kernel, Andy Shevchenko,
Tony Lindgren, Paul E. McKenney, Uwe Kleine-König,
Ilpo Järvinen, Serge Semin, Rengarajan S, Wolfram Sang,
Sebastian Andrzej Siewior
On Fri, Sep 06 2024 at 18:44, John Ogness wrote:
> So there are 2 things _not_ supported by the write_atomic() callback:
>
> 1. RS485 mode. This is due to the need to start up TX for the
> write, which can lead to:
>
> up->rs485_start_tx()
> serial8250_em485_start_tx()
> serial8250_stop_rx()
> serial8250_rpm_get()
> pm_runtime_get_sync()
> __pm_runtime_resume()
> spin_lock_irqsave()
>
> Taking a spin lock is not safe from NMI and thus disqualifies this call
> chain for write_atomic().
Correct. __pm_runtime_resume() can sleep as well :)
> If UART_CAP_RPM is not set, the pm_runtime_get_sync() is avoided. So I
> could only disable atomic RS485 if UART_CAP_RPM is set. But the OMAP
> variant of the 8250 does set this capability.
Sure, but none of this makes sense. What's so special about that em485
muck that serial8250_stop_rx() needs to do that PM dance?
It writes the IER register, which serial8250_console_write() just wrote
to in serial8250_clear_IER() without doing this PM dance. So for the
console write path this stop part is not required at all. That said,
serial8250_em485_stop_tx() doesn't have this PM dance either.
I'm 100% that this is just a problem of blindly sharing this with the
regular uart code and not because there is a requirement. See what
serial8250_console_setup() does at the end:
if (port->dev)
pm_runtime_get_sync(port->dev);
The corresponding put() is in serial8250_console_exit(). So there is
absolutely zero reason for power management in the console write
functions. It's the usual voodoo programming which nobody noticed
because it did not immediately blow up in their face.
There is another minor issue in that em485 muck. One code path arms a
hrtimer, which does not work from NMI like contexts, but that is only
taken when the transmitter is not empty, so probably a non-issue
because the console write code waits for it to be drained.
There are also a few lockdep_assert_held_once(port->lock) in that code
which will trigger when called from the nbcon write functions. They are
already broken today when oops_in_progress is set and the trylock of
port::lock fails...
So splitting this up into a clean and lean set for the console write
functions will make all these horrors just go away. The current sharing
is just fragile as hell and makes no sense at all.
> 2. Modem control. This is due to waiting for inputs, which can lead to:
>
> serial8250_modem_status()
> wake_up_interruptible()
>
> Performing wakes is not safe from scheduler or NMI and thus disqualifies
> this call chain for write_atomic().
>
> It would probably be acceptable to move serial8250_modem_status() into
> an irq_work.
Yes, but serial8250_modem_status() has more problems than that:
See uart_handle_dcd_change() and uart_handle_cts_change(). They call
into the tty layer and do their own wakeups.
So no, serial8250_modem_status() cannot be invoked there at all.
You have to defer this whole status dance to irq work and this really
needs to be done inside the write_atomic() callback. Otherwise a status
change could get lost, which is bad in non-panic situations.
That needs a bit of thought vs. port->msr_saved_flags, because in a
hostile takeover situation that needs to take into account that the
interrupted context might be fiddling with msr_saved_flags too, which
might on resume overwrite the write_atomic() modifications due to RMW.
Shouldn't be hard.
That brings me to that USE_SERIAL_8250_LEGACY_CONSOLE #ifdeffery, which
started this conversation.
The nbcon conversion does not make things worse than they are today. Any
problem which happens in the atomic_write() callback has existed before
already. So just get rid of the legacy code and be done with it.
At some point you have to bite the bullet and deal with the fallout when
it's reported. Remember, perfect is the enemy of good and you will never
reach perfect.
Thanks,
tglx
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH next v1 1/2] serial: 8250: Switch to nbcon console
2024-09-07 20:39 ` Thomas Gleixner
@ 2024-09-09 9:53 ` Andy Shevchenko
2024-09-09 12:13 ` Thomas Gleixner
0 siblings, 1 reply; 22+ messages in thread
From: Andy Shevchenko @ 2024-09-09 9:53 UTC (permalink / raw)
To: Thomas Gleixner
Cc: John Ogness, Petr Mladek, Greg Kroah-Hartman, Jiri Slaby,
Sergey Senozhatsky, Steven Rostedt, linux-serial, linux-kernel,
Tony Lindgren, Paul E. McKenney, Uwe Kleine-König,
Ilpo Järvinen, Serge Semin, Rengarajan S, Wolfram Sang,
Sebastian Andrzej Siewior
On Sat, Sep 07, 2024 at 10:39:00PM +0200, Thomas Gleixner wrote:
> On Fri, Sep 06 2024 at 18:44, John Ogness wrote:
...
> I'm 100% that this is just a problem of blindly sharing this with the
> regular uart code and not because there is a requirement. See what
> serial8250_console_setup() does at the end:
>
> if (port->dev)
> pm_runtime_get_sync(port->dev);
>
> The corresponding put() is in serial8250_console_exit(). So there is
> absolutely zero reason for power management in the console write
> functions. It's the usual voodoo programming which nobody noticed
> because it did not immediately blow up in their face.
It might be historical, but yes, the above is for a reason.
And if somebody needs a kernel console to be shutdown, they should remove
it from the active consoles.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH next v1 1/2] serial: 8250: Switch to nbcon console
2024-09-09 9:53 ` Andy Shevchenko
@ 2024-09-09 12:13 ` Thomas Gleixner
0 siblings, 0 replies; 22+ messages in thread
From: Thomas Gleixner @ 2024-09-09 12:13 UTC (permalink / raw)
To: Andy Shevchenko
Cc: John Ogness, Petr Mladek, Greg Kroah-Hartman, Jiri Slaby,
Sergey Senozhatsky, Steven Rostedt, linux-serial, linux-kernel,
Tony Lindgren, Paul E. McKenney, Uwe Kleine-König,
Ilpo Järvinen, Serge Semin, Rengarajan S, Wolfram Sang,
Sebastian Andrzej Siewior
On Mon, Sep 09 2024 at 12:53, Andy Shevchenko wrote:
> On Sat, Sep 07, 2024 at 10:39:00PM +0200, Thomas Gleixner wrote:
>> On Fri, Sep 06 2024 at 18:44, John Ogness wrote:
>
> ...
>
>> I'm 100% that this is just a problem of blindly sharing this with the
>> regular uart code and not because there is a requirement. See what
>> serial8250_console_setup() does at the end:
>>
>> if (port->dev)
>> pm_runtime_get_sync(port->dev);
>>
>> The corresponding put() is in serial8250_console_exit(). So there is
>> absolutely zero reason for power management in the console write
>> functions. It's the usual voodoo programming which nobody noticed
>> because it did not immediately blow up in their face.
>
> It might be historical, but yes, the above is for a reason.
> And if somebody needs a kernel console to be shutdown, they should remove
> it from the active consoles.
Correct, because you cant do PM from arbitrary contexts.
Ergo the code which does PM in the context of the console write function
is bogus.
Thanks,
tglx
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH next v1 1/2] serial: 8250: Switch to nbcon console
2024-09-06 16:38 ` John Ogness
2024-09-07 20:39 ` Thomas Gleixner
@ 2024-09-09 9:50 ` Andy Shevchenko
1 sibling, 0 replies; 22+ messages in thread
From: Andy Shevchenko @ 2024-09-09 9:50 UTC (permalink / raw)
To: John Ogness
Cc: Petr Mladek, Greg Kroah-Hartman, Jiri Slaby, Sergey Senozhatsky,
Steven Rostedt, Thomas Gleixner, linux-serial, linux-kernel,
Tony Lindgren, Paul E. McKenney, Uwe Kleine-König,
Ilpo Järvinen, Serge Semin, Rengarajan S, Wolfram Sang
On Fri, Sep 06, 2024 at 06:44:41PM +0206, John Ogness wrote:
> On 2024-09-06, John Ogness <john.ogness@linutronix.de> wrote:
> >> Wait! This makes the rs485 consoles much less usable for debugging.
> >> They might have troubles to see the emergency and panic messages.
> >>
> >> Is this acceptable? Why?
> >
> > It is not acceptable. I am looking into making the atomic part work for
> > RS485 as well.
>
> So there are 2 things _not_ supported by the write_atomic() callback:
>
> 1. RS485 mode. This is due to the need to start up TX for the
> write, which can lead to:
>
> up->rs485_start_tx()
> serial8250_em485_start_tx()
> serial8250_stop_rx()
> serial8250_rpm_get()
> pm_runtime_get_sync()
> __pm_runtime_resume()
> spin_lock_irqsave()
>
> Taking a spin lock is not safe from NMI and thus disqualifies this call
> chain for write_atomic().
>
> If UART_CAP_RPM is not set, the pm_runtime_get_sync() is avoided. So I
> could only disable atomic RS485 if UART_CAP_RPM is set. But the OMAP
> variant of the 8250 does set this capability.
Please, don't add a new code which relies on UART_CAP_RPM.
The idea is to enable runtime PM for all users who provides respective
callbacks. Rather, you should ask runtime PM for this information.
> 2. Modem control. This is due to waiting for inputs, which can lead to:
>
> serial8250_modem_status()
> wake_up_interruptible()
>
> Performing wakes is not safe from scheduler or NMI and thus disqualifies
> this call chain for write_atomic().
>
> It would probably be acceptable to move serial8250_modem_status() into
> an irq_work.
>
> I would be grateful for any insights on how best to handle these 2
> issues if we want full write_atomic() support for all 8250 variants.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH next v1 1/2] serial: 8250: Switch to nbcon console
2024-09-05 13:47 ` [PATCH next v1 1/2] serial: 8250: Switch to nbcon console John Ogness
` (2 preceding siblings ...)
2024-09-06 12:37 ` Petr Mladek
@ 2024-09-07 19:55 ` kernel test robot
2024-09-08 1:45 ` kernel test robot
2024-09-08 6:26 ` kernel test robot
5 siblings, 0 replies; 22+ messages in thread
From: kernel test robot @ 2024-09-07 19:55 UTC (permalink / raw)
To: John Ogness; +Cc: llvm, oe-kbuild-all
Hi John,
kernel test robot noticed the following build errors:
[auto build test ERROR on f1ec92a066b2608e7c971dfce28ebe2d2cdb056e]
url: https://github.com/intel-lab-lkp/linux/commits/John-Ogness/serial-8250-Switch-to-nbcon-console/20240905-214915
base: f1ec92a066b2608e7c971dfce28ebe2d2cdb056e
patch link: https://lore.kernel.org/r/20240905134719.142554-2-john.ogness%40linutronix.de
patch subject: [PATCH next v1 1/2] serial: 8250: Switch to nbcon console
config: x86_64-randconfig-015-20240907 (https://download.01.org/0day-ci/archive/20240908/202409080329.h0HqFuzd-lkp@intel.com/config)
compiler: clang version 18.1.5 (https://github.com/llvm/llvm-project 617a15a9eac96088ae5e9134248d8236e34b91b1)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240908/202409080329.h0HqFuzd-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202409080329.h0HqFuzd-lkp@intel.com/
All errors (new ones prefixed by >>):
>> drivers/tty/serial/8250/8250_core.c:420:2: error: call to undeclared function '__uart_port_lock_irqsave'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
420 | __uart_port_lock_irqsave(up, flags);
| ^
drivers/tty/serial/8250/8250_core.c:420:2: note: did you mean 'uart_port_lock_irqsave'?
include/linux/serial_core.h:616:20: note: 'uart_port_lock_irqsave' declared here
616 | static inline void uart_port_lock_irqsave(struct uart_port *up, unsigned long *flags)
| ^
>> drivers/tty/serial/8250/8250_core.c:427:2: error: call to undeclared function '__uart_port_unlock_irqrestore'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
427 | __uart_port_unlock_irqrestore(up, flags);
| ^
drivers/tty/serial/8250/8250_core.c:427:2: note: did you mean 'uart_port_unlock_irqrestore'?
include/linux/serial_core.h:667:20: note: 'uart_port_unlock_irqrestore' declared here
667 | static inline void uart_port_unlock_irqrestore(struct uart_port *up, unsigned long flags)
| ^
>> drivers/tty/serial/8250/8250_core.c:533:18: error: incompatible function pointer types initializing 'bool (*)(struct console *, struct nbcon_write_context *)' (aka '_Bool (*)(struct console *, struct nbcon_write_context *)') with an expression of type 'void (struct console *, struct nbcon_write_context *)' [-Wincompatible-function-pointer-types]
533 | .write_atomic = univ8250_console_write_atomic,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/tty/serial/8250/8250_core.c:534:3: error: field designator 'write_thread' does not refer to any field in type 'struct console'
534 | .write_thread = univ8250_console_write_thread,
| ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/tty/serial/8250/8250_core.c:535:3: error: field designator 'device_lock' does not refer to any field in type 'struct console'
535 | .device_lock = univ8250_console_device_lock,
| ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/tty/serial/8250/8250_core.c:536:3: error: field designator 'device_unlock' does not refer to any field in type 'struct console'
536 | .device_unlock = univ8250_console_device_unlock,
| ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6 errors generated.
--
>> drivers/tty/serial/8250/8250_port.c:3502:3: error: call to undeclared function 'nbcon_reacquire_nobuf'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
3502 | nbcon_reacquire_nobuf(wctxt);
| ^
1 error generated.
vim +/__uart_port_lock_irqsave +420 drivers/tty/serial/8250/8250_core.c
415
416 static void univ8250_console_device_lock(struct console *con, unsigned long *flags)
417 {
418 struct uart_port *up = &serial8250_ports[con->index].port;
419
> 420 __uart_port_lock_irqsave(up, flags);
421 }
422
423 static void univ8250_console_device_unlock(struct console *con, unsigned long flags)
424 {
425 struct uart_port *up = &serial8250_ports[con->index].port;
426
> 427 __uart_port_unlock_irqrestore(up, flags);
428 }
429 #endif /* USE_SERIAL_8250_LEGACY_CONSOLE */
430
431 static int univ8250_console_setup(struct console *co, char *options)
432 {
433 struct uart_8250_port *up;
434 struct uart_port *port;
435 int retval, i;
436
437 /*
438 * Check whether an invalid uart number has been specified, and
439 * if so, search for the first available port that does have
440 * console support.
441 */
442 if (co->index < 0 || co->index >= UART_NR)
443 co->index = 0;
444
445 /*
446 * If the console is past the initial isa ports, init more ports up to
447 * co->index as needed and increment nr_uarts accordingly.
448 */
449 for (i = nr_uarts; i <= co->index; i++) {
450 up = serial8250_setup_port(i);
451 if (!up)
452 return -ENODEV;
453 nr_uarts++;
454 }
455
456 port = &serial8250_ports[co->index].port;
457 /* link port to console */
458 port->cons = co;
459
460 retval = serial8250_console_setup(port, options, false);
461 if (retval != 0)
462 port->cons = NULL;
463 return retval;
464 }
465
466 static int univ8250_console_exit(struct console *co)
467 {
468 struct uart_port *port;
469
470 port = &serial8250_ports[co->index].port;
471 return serial8250_console_exit(port);
472 }
473
474 /**
475 * univ8250_console_match - non-standard console matching
476 * @co: registering console
477 * @name: name from console command line
478 * @idx: index from console command line
479 * @options: ptr to option string from console command line
480 *
481 * Only attempts to match console command lines of the form:
482 * console=uart[8250],io|mmio|mmio16|mmio32,<addr>[,<options>]
483 * console=uart[8250],0x<addr>[,<options>]
484 * This form is used to register an initial earlycon boot console and
485 * replace it with the serial8250_console at 8250 driver init.
486 *
487 * Performs console setup for a match (as required by interface)
488 * If no <options> are specified, then assume the h/w is already setup.
489 *
490 * Returns 0 if console matches; otherwise non-zero to use default matching
491 */
492 static int univ8250_console_match(struct console *co, char *name, int idx,
493 char *options)
494 {
495 char match[] = "uart"; /* 8250-specific earlycon name */
496 unsigned char iotype;
497 resource_size_t addr;
498 int i;
499
500 if (strncmp(name, match, 4) != 0)
501 return -ENODEV;
502
503 if (uart_parse_earlycon(options, &iotype, &addr, &options))
504 return -ENODEV;
505
506 /* try to match the port specified on the command line */
507 for (i = 0; i < nr_uarts; i++) {
508 struct uart_port *port = &serial8250_ports[i].port;
509
510 if (port->iotype != iotype)
511 continue;
512 if ((iotype == UPIO_MEM || iotype == UPIO_MEM16 ||
513 iotype == UPIO_MEM32 || iotype == UPIO_MEM32BE)
514 && (port->mapbase != addr))
515 continue;
516 if (iotype == UPIO_PORT && port->iobase != addr)
517 continue;
518
519 co->index = i;
520 port->cons = co;
521 return serial8250_console_setup(port, options, true);
522 }
523
524 return -ENODEV;
525 }
526
527 static struct console univ8250_console = {
528 .name = "ttyS",
529 #ifdef USE_SERIAL_8250_LEGACY_CONSOLE
530 .write = univ8250_console_write,
531 .flags = CON_PRINTBUFFER | CON_ANYTIME,
532 #else
> 533 .write_atomic = univ8250_console_write_atomic,
> 534 .write_thread = univ8250_console_write_thread,
> 535 .device_lock = univ8250_console_device_lock,
> 536 .device_unlock = univ8250_console_device_unlock,
537 .flags = CON_PRINTBUFFER | CON_ANYTIME | CON_NBCON,
538 #endif
539 .device = uart_console_device,
540 .setup = univ8250_console_setup,
541 .exit = univ8250_console_exit,
542 .match = univ8250_console_match,
543 .index = -1,
544 .data = &serial8250_reg,
545 };
546
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH next v1 1/2] serial: 8250: Switch to nbcon console
2024-09-05 13:47 ` [PATCH next v1 1/2] serial: 8250: Switch to nbcon console John Ogness
` (3 preceding siblings ...)
2024-09-07 19:55 ` kernel test robot
@ 2024-09-08 1:45 ` kernel test robot
2024-09-08 6:26 ` kernel test robot
5 siblings, 0 replies; 22+ messages in thread
From: kernel test robot @ 2024-09-08 1:45 UTC (permalink / raw)
To: John Ogness; +Cc: oe-kbuild-all
Hi John,
kernel test robot noticed the following build errors:
[auto build test ERROR on f1ec92a066b2608e7c971dfce28ebe2d2cdb056e]
url: https://github.com/intel-lab-lkp/linux/commits/John-Ogness/serial-8250-Switch-to-nbcon-console/20240905-214915
base: f1ec92a066b2608e7c971dfce28ebe2d2cdb056e
patch link: https://lore.kernel.org/r/20240905134719.142554-2-john.ogness%40linutronix.de
patch subject: [PATCH next v1 1/2] serial: 8250: Switch to nbcon console
config: x86_64-randconfig-003-20240908 (https://download.01.org/0day-ci/archive/20240908/202409080947.VYdltLWR-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-12) 11.3.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240908/202409080947.VYdltLWR-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202409080947.VYdltLWR-lkp@intel.com/
All error/warnings (new ones prefixed by >>):
drivers/tty/serial/8250/8250_core.c: In function 'univ8250_console_device_lock':
>> drivers/tty/serial/8250/8250_core.c:420:9: error: implicit declaration of function '__uart_port_lock_irqsave'; did you mean 'uart_port_lock_irqsave'? [-Werror=implicit-function-declaration]
420 | __uart_port_lock_irqsave(up, flags);
| ^~~~~~~~~~~~~~~~~~~~~~~~
| uart_port_lock_irqsave
drivers/tty/serial/8250/8250_core.c: In function 'univ8250_console_device_unlock':
>> drivers/tty/serial/8250/8250_core.c:427:9: error: implicit declaration of function '__uart_port_unlock_irqrestore'; did you mean 'uart_port_unlock_irqrestore'? [-Werror=implicit-function-declaration]
427 | __uart_port_unlock_irqrestore(up, flags);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| uart_port_unlock_irqrestore
drivers/tty/serial/8250/8250_core.c: At top level:
>> drivers/tty/serial/8250/8250_core.c:533:27: error: initialization of 'bool (*)(struct console *, struct nbcon_write_context *)' {aka '_Bool (*)(struct console *, struct nbcon_write_context *)'} from incompatible pointer type 'void (*)(struct console *, struct nbcon_write_context *)' [-Werror=incompatible-pointer-types]
533 | .write_atomic = univ8250_console_write_atomic,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/tty/serial/8250/8250_core.c:533:27: note: (near initialization for 'univ8250_console.write_atomic')
>> drivers/tty/serial/8250/8250_core.c:534:10: error: 'struct console' has no member named 'write_thread'
534 | .write_thread = univ8250_console_write_thread,
| ^~~~~~~~~~~~
>> drivers/tty/serial/8250/8250_core.c:534:27: warning: initialization of 'int' from 'void (*)(struct console *, struct nbcon_write_context *)' makes integer from pointer without a cast [-Wint-conversion]
534 | .write_thread = univ8250_console_write_thread,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/tty/serial/8250/8250_core.c:534:27: note: (near initialization for 'univ8250_console.nbcon_state.counter')
>> drivers/tty/serial/8250/8250_core.c:534:27: error: initializer element is not computable at load time
drivers/tty/serial/8250/8250_core.c:534:27: note: (near initialization for 'univ8250_console.nbcon_state.counter')
>> drivers/tty/serial/8250/8250_core.c:535:10: error: 'struct console' has no member named 'device_lock'
535 | .device_lock = univ8250_console_device_lock,
| ^~~~~~~~~~~
>> drivers/tty/serial/8250/8250_core.c:535:27: warning: initialization of 'long long int' from 'void (*)(struct console *, long unsigned int *)' makes integer from pointer without a cast [-Wint-conversion]
535 | .device_lock = univ8250_console_device_lock,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/tty/serial/8250/8250_core.c:535:27: note: (near initialization for 'univ8250_console.nbcon_seq.counter')
>> drivers/tty/serial/8250/8250_core.c:536:10: error: 'struct console' has no member named 'device_unlock'
536 | .device_unlock = univ8250_console_device_unlock,
| ^~~~~~~~~~~~~
>> drivers/tty/serial/8250/8250_core.c:536:27: error: initialization of 'struct printk_buffers *' from incompatible pointer type 'void (*)(struct console *, long unsigned int)' [-Werror=incompatible-pointer-types]
536 | .device_unlock = univ8250_console_device_unlock,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/tty/serial/8250/8250_core.c:536:27: note: (near initialization for 'univ8250_console.pbufs')
>> drivers/tty/serial/8250/8250_core.c:527:42: warning: missing braces around initializer [-Wmissing-braces]
527 | static struct console univ8250_console = {
| ^
......
534 | .write_thread = univ8250_console_write_thread,
| { }
535 | .device_lock = univ8250_console_device_lock,
| { }
cc1: some warnings being treated as errors
--
drivers/tty/serial/8250/8250_port.c: In function 'serial8250_console_write_thread':
>> drivers/tty/serial/8250/8250_port.c:3502:17: error: implicit declaration of function 'nbcon_reacquire_nobuf' [-Werror=implicit-function-declaration]
3502 | nbcon_reacquire_nobuf(wctxt);
| ^~~~~~~~~~~~~~~~~~~~~
cc1: some warnings being treated as errors
vim +420 drivers/tty/serial/8250/8250_core.c
415
416 static void univ8250_console_device_lock(struct console *con, unsigned long *flags)
417 {
418 struct uart_port *up = &serial8250_ports[con->index].port;
419
> 420 __uart_port_lock_irqsave(up, flags);
421 }
422
423 static void univ8250_console_device_unlock(struct console *con, unsigned long flags)
424 {
425 struct uart_port *up = &serial8250_ports[con->index].port;
426
> 427 __uart_port_unlock_irqrestore(up, flags);
428 }
429 #endif /* USE_SERIAL_8250_LEGACY_CONSOLE */
430
431 static int univ8250_console_setup(struct console *co, char *options)
432 {
433 struct uart_8250_port *up;
434 struct uart_port *port;
435 int retval, i;
436
437 /*
438 * Check whether an invalid uart number has been specified, and
439 * if so, search for the first available port that does have
440 * console support.
441 */
442 if (co->index < 0 || co->index >= UART_NR)
443 co->index = 0;
444
445 /*
446 * If the console is past the initial isa ports, init more ports up to
447 * co->index as needed and increment nr_uarts accordingly.
448 */
449 for (i = nr_uarts; i <= co->index; i++) {
450 up = serial8250_setup_port(i);
451 if (!up)
452 return -ENODEV;
453 nr_uarts++;
454 }
455
456 port = &serial8250_ports[co->index].port;
457 /* link port to console */
458 port->cons = co;
459
460 retval = serial8250_console_setup(port, options, false);
461 if (retval != 0)
462 port->cons = NULL;
463 return retval;
464 }
465
466 static int univ8250_console_exit(struct console *co)
467 {
468 struct uart_port *port;
469
470 port = &serial8250_ports[co->index].port;
471 return serial8250_console_exit(port);
472 }
473
474 /**
475 * univ8250_console_match - non-standard console matching
476 * @co: registering console
477 * @name: name from console command line
478 * @idx: index from console command line
479 * @options: ptr to option string from console command line
480 *
481 * Only attempts to match console command lines of the form:
482 * console=uart[8250],io|mmio|mmio16|mmio32,<addr>[,<options>]
483 * console=uart[8250],0x<addr>[,<options>]
484 * This form is used to register an initial earlycon boot console and
485 * replace it with the serial8250_console at 8250 driver init.
486 *
487 * Performs console setup for a match (as required by interface)
488 * If no <options> are specified, then assume the h/w is already setup.
489 *
490 * Returns 0 if console matches; otherwise non-zero to use default matching
491 */
492 static int univ8250_console_match(struct console *co, char *name, int idx,
493 char *options)
494 {
495 char match[] = "uart"; /* 8250-specific earlycon name */
496 unsigned char iotype;
497 resource_size_t addr;
498 int i;
499
500 if (strncmp(name, match, 4) != 0)
501 return -ENODEV;
502
503 if (uart_parse_earlycon(options, &iotype, &addr, &options))
504 return -ENODEV;
505
506 /* try to match the port specified on the command line */
507 for (i = 0; i < nr_uarts; i++) {
508 struct uart_port *port = &serial8250_ports[i].port;
509
510 if (port->iotype != iotype)
511 continue;
512 if ((iotype == UPIO_MEM || iotype == UPIO_MEM16 ||
513 iotype == UPIO_MEM32 || iotype == UPIO_MEM32BE)
514 && (port->mapbase != addr))
515 continue;
516 if (iotype == UPIO_PORT && port->iobase != addr)
517 continue;
518
519 co->index = i;
520 port->cons = co;
521 return serial8250_console_setup(port, options, true);
522 }
523
524 return -ENODEV;
525 }
526
> 527 static struct console univ8250_console = {
528 .name = "ttyS",
529 #ifdef USE_SERIAL_8250_LEGACY_CONSOLE
530 .write = univ8250_console_write,
531 .flags = CON_PRINTBUFFER | CON_ANYTIME,
532 #else
> 533 .write_atomic = univ8250_console_write_atomic,
> 534 .write_thread = univ8250_console_write_thread,
> 535 .device_lock = univ8250_console_device_lock,
> 536 .device_unlock = univ8250_console_device_unlock,
537 .flags = CON_PRINTBUFFER | CON_ANYTIME | CON_NBCON,
538 #endif
539 .device = uart_console_device,
540 .setup = univ8250_console_setup,
541 .exit = univ8250_console_exit,
542 .match = univ8250_console_match,
543 .index = -1,
544 .data = &serial8250_reg,
545 };
546
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH next v1 1/2] serial: 8250: Switch to nbcon console
2024-09-05 13:47 ` [PATCH next v1 1/2] serial: 8250: Switch to nbcon console John Ogness
` (4 preceding siblings ...)
2024-09-08 1:45 ` kernel test robot
@ 2024-09-08 6:26 ` kernel test robot
5 siblings, 0 replies; 22+ messages in thread
From: kernel test robot @ 2024-09-08 6:26 UTC (permalink / raw)
To: John Ogness; +Cc: oe-kbuild-all
Hi John,
kernel test robot noticed the following build warnings:
[auto build test WARNING on f1ec92a066b2608e7c971dfce28ebe2d2cdb056e]
url: https://github.com/intel-lab-lkp/linux/commits/John-Ogness/serial-8250-Switch-to-nbcon-console/20240905-214915
base: f1ec92a066b2608e7c971dfce28ebe2d2cdb056e
patch link: https://lore.kernel.org/r/20240905134719.142554-2-john.ogness%40linutronix.de
patch subject: [PATCH next v1 1/2] serial: 8250: Switch to nbcon console
config: i386-randconfig-001-20240908 (https://download.01.org/0day-ci/archive/20240908/202409081005.JY8QAN41-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240908/202409081005.JY8QAN41-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202409081005.JY8QAN41-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/tty/serial/8250/8250_core.c: In function 'univ8250_console_device_lock':
drivers/tty/serial/8250/8250_core.c:420:9: error: implicit declaration of function '__uart_port_lock_irqsave'; did you mean 'uart_port_lock_irqsave'? [-Werror=implicit-function-declaration]
420 | __uart_port_lock_irqsave(up, flags);
| ^~~~~~~~~~~~~~~~~~~~~~~~
| uart_port_lock_irqsave
drivers/tty/serial/8250/8250_core.c: In function 'univ8250_console_device_unlock':
drivers/tty/serial/8250/8250_core.c:427:9: error: implicit declaration of function '__uart_port_unlock_irqrestore'; did you mean 'uart_port_unlock_irqrestore'? [-Werror=implicit-function-declaration]
427 | __uart_port_unlock_irqrestore(up, flags);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| uart_port_unlock_irqrestore
drivers/tty/serial/8250/8250_core.c: At top level:
drivers/tty/serial/8250/8250_core.c:533:27: error: initialization of 'bool (*)(struct console *, struct nbcon_write_context *)' {aka '_Bool (*)(struct console *, struct nbcon_write_context *)'} from incompatible pointer type 'void (*)(struct console *, struct nbcon_write_context *)' [-Werror=incompatible-pointer-types]
533 | .write_atomic = univ8250_console_write_atomic,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/tty/serial/8250/8250_core.c:533:27: note: (near initialization for 'univ8250_console.write_atomic')
drivers/tty/serial/8250/8250_core.c:534:10: error: 'struct console' has no member named 'write_thread'
534 | .write_thread = univ8250_console_write_thread,
| ^~~~~~~~~~~~
drivers/tty/serial/8250/8250_core.c:534:27: warning: initialization of 'int' from 'void (*)(struct console *, struct nbcon_write_context *)' makes integer from pointer without a cast [-Wint-conversion]
534 | .write_thread = univ8250_console_write_thread,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/tty/serial/8250/8250_core.c:534:27: note: (near initialization for 'univ8250_console.nbcon_state.counter')
drivers/tty/serial/8250/8250_core.c:535:10: error: 'struct console' has no member named 'device_lock'
535 | .device_lock = univ8250_console_device_lock,
| ^~~~~~~~~~~
>> drivers/tty/serial/8250/8250_core.c:535:27: warning: initialization of 'int' from 'void (*)(struct console *, long unsigned int *)' makes integer from pointer without a cast [-Wint-conversion]
535 | .device_lock = univ8250_console_device_lock,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/tty/serial/8250/8250_core.c:535:27: note: (near initialization for 'univ8250_console.nbcon_seq.counter')
drivers/tty/serial/8250/8250_core.c:536:10: error: 'struct console' has no member named 'device_unlock'
536 | .device_unlock = univ8250_console_device_unlock,
| ^~~~~~~~~~~~~
drivers/tty/serial/8250/8250_core.c:536:27: error: initialization of 'struct printk_buffers *' from incompatible pointer type 'void (*)(struct console *, long unsigned int)' [-Werror=incompatible-pointer-types]
536 | .device_unlock = univ8250_console_device_unlock,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/tty/serial/8250/8250_core.c:536:27: note: (near initialization for 'univ8250_console.pbufs')
drivers/tty/serial/8250/8250_core.c:527:42: warning: missing braces around initializer [-Wmissing-braces]
527 | static struct console univ8250_console = {
| ^
......
534 | .write_thread = univ8250_console_write_thread,
| { }
535 | .device_lock = univ8250_console_device_lock,
| { }
cc1: some warnings being treated as errors
vim +535 drivers/tty/serial/8250/8250_core.c
526
527 static struct console univ8250_console = {
528 .name = "ttyS",
529 #ifdef USE_SERIAL_8250_LEGACY_CONSOLE
530 .write = univ8250_console_write,
531 .flags = CON_PRINTBUFFER | CON_ANYTIME,
532 #else
533 .write_atomic = univ8250_console_write_atomic,
534 .write_thread = univ8250_console_write_thread,
> 535 .device_lock = univ8250_console_device_lock,
536 .device_unlock = univ8250_console_device_unlock,
537 .flags = CON_PRINTBUFFER | CON_ANYTIME | CON_NBCON,
538 #endif
539 .device = uart_console_device,
540 .setup = univ8250_console_setup,
541 .exit = univ8250_console_exit,
542 .match = univ8250_console_match,
543 .index = -1,
544 .data = &serial8250_reg,
545 };
546
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 22+ messages in thread