2015-07-22 06:27:27

by Arun KS

[permalink] [raw]
Subject: Why linux console designed to work in polling mode?

forwarding email to LKML.
Please enlighten on this question. Googling doesn't helped so far.

Thanks,
Arun

From: Alexander <[email protected]>
Date: Sat, Jul 18, 2015 at 11:23 AM
Subject: Delegating printk work to UART interrupt
To: [email protected]


Hi!
When i checked how kernel printing works, i mentioned that it takes
messages from log_buffer in console_unlock and gives it to
call_console_drivers -> ...-> some uart bsp function. Basically, as i
see this BSP realization tries to flush all message chars in busyloop
... so it waits until FIFO_NOT_FULL bit will be dropped by UART and it
will be able to push the next byte. Basically, as i see userspace
printing do something different. It puts N_FIFO_BYTES and exits, next,
when FIFO will be freed - interrupt will be generated, and other
characters will be put into UART FIFO.
Can we do something similar for kernel printing? i.e. do not busyloop
sending char after char, but put N_FIFO chars and flush other in
interrupt. When panic will occur we can do busyloop printing again. Is
it reliable? Suppose we have several cores.

Thank you.

--
Alexander <[email protected]>

_______________________________________________


2015-07-22 06:53:20

by yalin wang

[permalink] [raw]
Subject: Re: Why linux console designed to work in polling mode?


> On Jul 22, 2015, at 14:27, Arun KS <[email protected]> wrote:
>
> When i checked how kernel printing works, i mentioned that it takes
> messages from log_buffer in console_unlock and gives it to
> call_console_drivers -> ...-> some uart bsp function. Basically, as i
> see this BSP realization tries to flush all message chars in busyloop
> ... so it waits until FIFO_NOT_FULL bit will be dropped by UART and it
> will be able to push the next byte. Basically, as i see userspace
> printing do something different. It puts N_FIFO_BYTES and exits, next,
> when FIFO will be freed - interrupt will be generated, and other
> characters will be put into UART FIFO.
> Can we do something similar for kernel printing? i.e. do not busyloop
> sending char after char, but put N_FIFO chars and flush other in
> interrupt. When panic will occur we can do busyloop printing again. Is
> it reliable? Suppose we have several cores.
>
>

i think it is because printk is very different from other printf function in user space,
printk() can be called in any context atomic / non- atomic / irq / soft-irq context ..

so your bsp->print function can’t be sleep, can’t call any sleep functions .

another reason is that in console_unlock() function, it call bas->print like this:
call_console_drivers(level, ext_text, ext_len, text, len);
print expect your bsp function print all the text as showed in parameters.
and it doesn’t check the return value ,
so if your driver doesn’t use POLL mode, you should only print N_FIFO_BYTES bytes,
this need prink to check return value or need your bsp function to use some special method
to send the remaining bytes after received FIFO empty interrupt.
it is not easy to implement in a context that you can’t call any sleep function.

Thanks-

2015-07-22 20:08:55

by Alex Yashchenko

[permalink] [raw]
Subject: Re: Why linux console designed to work in polling mode?

Hi. Thanks for respond.
Don't understand how this affects described logic (deferred printk).
Suppose you put bytes to UART FIFO in console_unlock() until you can,
after this up_console_sem and move forward. In UART interrupt you will
do the same thing: get char from log_buf, put into UART FIFO until it
will be full then break. How the fact that printk could be called from any context
interfere this? Other way round, this logic will eliminate busyloop
and decrease printk time significantly (including printk in interrupts etc)
> it is not easy to implement in a context that you can’t call any sleep function.
Deferred printing is done in UART interrupt, there is no need to sleep anywhere ...

On Wed, 22 Jul 2015 14:53:13 +0800
yalin wang <[email protected]> wrote:

>
> > On Jul 22, 2015, at 14:27, Arun KS <[email protected]> wrote:
> >
> > When i checked how kernel printing works, i mentioned that it takes
> > messages from log_buffer in console_unlock and gives it to
> > call_console_drivers -> ...-> some uart bsp function. Basically, as i
> > see this BSP realization tries to flush all message chars in busyloop
> > ... so it waits until FIFO_NOT_FULL bit will be dropped by UART and it
> > will be able to push the next byte. Basically, as i see userspace
> > printing do something different. It puts N_FIFO_BYTES and exits, next,
> > when FIFO will be freed - interrupt will be generated, and other
> > characters will be put into UART FIFO.
> > Can we do something similar for kernel printing? i.e. do not busyloop
> > sending char after char, but put N_FIFO chars and flush other in
> > interrupt. When panic will occur we can do busyloop printing again. Is
> > it reliable? Suppose we have several cores.
> >
> >
>
> i think it is because printk is very different from other printf function in user space,
> printk() can be called in any context atomic / non- atomic / irq / soft-irq context ..
>
> so your bsp->print function can’t be sleep, can’t call any sleep functions .
>
> another reason is that in console_unlock() function, it call bas->print like this:
> call_console_drivers(level, ext_text, ext_len, text, len);
> print expect your bsp function print all the text as showed in parameters.
> and it doesn’t check the return value ,
> so if your driver doesn’t use POLL mode, you should only print N_FIFO_BYTES bytes,
> this need prink to check return value or need your bsp function to use some special method
> to send the remaining bytes after received FIFO empty interrupt.
> it is not easy to implement in a context that you can’t call any sleep function.
>
> Thanks

--
Alexander <[email protected]>

2015-07-22 21:37:01

by Peter Hurley

[permalink] [raw]
Subject: Re: Why linux console designed to work in polling mode?

Hi Alexander,

On 07/22/2015 04:08 PM, Alexander wrote:
> Hi. Thanks for respond.
> Don't understand how this affects described logic (deferred printk).
> Suppose you put bytes to UART FIFO in console_unlock() until you can,
> after this up_console_sem and move forward. In UART interrupt you will
> do the same thing: get char from log_buf, put into UART FIFO until it
> will be full then break. How the fact that printk could be called from any context
> interfere this? Other way round, this logic will eliminate busyloop
> and decrease printk time significantly (including printk in interrupts etc)
>> it is not easy to implement in a context that you can’t call any sleep function.
> Deferred printing is done in UART interrupt, there is no need to sleep anywhere ...

Here's an example kernel crash report on the serial console with 'deferred'
serial output on typical 16550A h/w:

[76330.588297] B

That's not much to diagnose the crash with.

Regards,
Peter Hurley

> On Wed, 22 Jul 2015 14:53:13 +0800
> yalin wang <[email protected]> wrote:
>
>>
>>> On Jul 22, 2015, at 14:27, Arun KS <[email protected]> wrote:
>>>
>>> When i checked how kernel printing works, i mentioned that it takes
>>> messages from log_buffer in console_unlock and gives it to
>>> call_console_drivers -> ...-> some uart bsp function. Basically, as i
>>> see this BSP realization tries to flush all message chars in busyloop
>>> ... so it waits until FIFO_NOT_FULL bit will be dropped by UART and it
>>> will be able to push the next byte. Basically, as i see userspace
>>> printing do something different. It puts N_FIFO_BYTES and exits, next,
>>> when FIFO will be freed - interrupt will be generated, and other
>>> characters will be put into UART FIFO.
>>> Can we do something similar for kernel printing? i.e. do not busyloop
>>> sending char after char, but put N_FIFO chars and flush other in
>>> interrupt. When panic will occur we can do busyloop printing again. Is
>>> it reliable? Suppose we have several cores.
>>>
>>>
>>
>> i think it is because printk is very different from other printf function in user space,
>> printk() can be called in any context atomic / non- atomic / irq / soft-irq context ..
>>
>> so your bsp->print function can’t be sleep, can’t call any sleep functions .
>>
>> another reason is that in console_unlock() function, it call bas->print like this:
>> call_console_drivers(level, ext_text, ext_len, text, len);
>> print expect your bsp function print all the text as showed in parameters.
>> and it doesn’t check the return value ,
>> so if your driver doesn’t use POLL mode, you should only print N_FIFO_BYTES bytes,
>> this need prink to check return value or need your bsp function to use some special method
>> to send the remaining bytes after received FIFO empty interrupt.
>> it is not easy to implement in a context that you can’t call any sleep function.
>>
>> Thanks
>

2015-07-23 05:54:14

by Alex Yashchenko

[permalink] [raw]
Subject: Re: Why linux console designed to work in polling mode?

Hi Peter,
I always know the oops enter point(?). Why i can't just switch to old mode (per char
busyloop) in this case and do things like in old console unlock?
Actually, i suspect that there might be some reliability problems with this deferred
stuff, but, actually, i can't come up with a test case (the only one - stuck on all
CPUs with disabled interrupts).
Thank you for respond.

On Wed, 22 Jul 2015 17:36:56 -0400
Peter Hurley <[email protected]> wrote:

> Hi Alexander,
>
> On 07/22/2015 04:08 PM, Alexander wrote:
> > Hi. Thanks for respond.
> > Don't understand how this affects described logic (deferred printk).
> > Suppose you put bytes to UART FIFO in console_unlock() until you can,
> > after this up_console_sem and move forward. In UART interrupt you will
> > do the same thing: get char from log_buf, put into UART FIFO until it
> > will be full then break. How the fact that printk could be called from any context
> > interfere this? Other way round, this logic will eliminate busyloop
> > and decrease printk time significantly (including printk in interrupts etc)
> >> it is not easy to implement in a context that you can’t call any sleep function.
> > Deferred printing is done in UART interrupt, there is no need to sleep anywhere ...
>
> Here's an example kernel crash report on the serial console with 'deferred'
> serial output on typical 16550A h/w:
>
> [76330.588297] B
>
> That's not much to diagnose the crash with.
>
> Regards,
> Peter Hurley
>
> > On Wed, 22 Jul 2015 14:53:13 +0800
> > yalin wang <[email protected]> wrote:
> >
> >>
> >>> On Jul 22, 2015, at 14:27, Arun KS <[email protected]> wrote:
> >>>
> >>> When i checked how kernel printing works, i mentioned that it takes
> >>> messages from log_buffer in console_unlock and gives it to
> >>> call_console_drivers -> ...-> some uart bsp function. Basically, as i
> >>> see this BSP realization tries to flush all message chars in busyloop
> >>> ... so it waits until FIFO_NOT_FULL bit will be dropped by UART and it
> >>> will be able to push the next byte. Basically, as i see userspace
> >>> printing do something different. It puts N_FIFO_BYTES and exits, next,
> >>> when FIFO will be freed - interrupt will be generated, and other
> >>> characters will be put into UART FIFO.
> >>> Can we do something similar for kernel printing? i.e. do not busyloop
> >>> sending char after char, but put N_FIFO chars and flush other in
> >>> interrupt. When panic will occur we can do busyloop printing again. Is
> >>> it reliable? Suppose we have several cores.
> >>>
> >>>
> >>
> >> i think it is because printk is very different from other printf function in user space,
> >> printk() can be called in any context atomic / non- atomic / irq / soft-irq context ..
> >>
> >> so your bsp->print function can’t be sleep, can’t call any sleep functions .
> >>
> >> another reason is that in console_unlock() function, it call bas->print like this:
> >> call_console_drivers(level, ext_text, ext_len, text, len);
> >> print expect your bsp function print all the text as showed in parameters.
> >> and it doesn’t check the return value ,
> >> so if your driver doesn’t use POLL mode, you should only print N_FIFO_BYTES bytes,
> >> this need prink to check return value or need your bsp function to use some special method
> >> to send the remaining bytes after received FIFO empty interrupt.
> >> it is not easy to implement in a context that you can’t call any sleep function.
> >>
> >> Thanks
> >
>


--
Alexander <[email protected]>