Re: [PATCH] hvc_console: fix dropping of characters when output byte channel is full
From: Timur Tabi <hidden>
Date: 2010-09-14 16:06:11
Also in:
lkml
Andrew, Would you please take a moment to review this patch I sent last month? I'd like for it to be incorporated into 2.6.37, but I'm having a hard time finding someone to consider it. Thanks. On Fri, Aug 20, 2010 at 1:45 PM, Timur Tabi [off-list ref] wrote:
hvc_console_print() calls the HVC client driver's put_chars() callback to write some characters to the console. =A0If the callback returns 0, th=
at
indicates that no characters were written (perhaps the output buffer is full), but hvc_console_print() treats that as an error and discards the rest of the buffer. So change hvc_console_print() to just loop and call put_chars() again if =
it
quoted hunk ↗ jump to hunk
returns a 0 return code. This change makes hvc_console_print() behave more like hvc_push(), which does check for a 0 return code and re-schedules itself. Signed-off-by: Timur Tabi <redacted> --- =A0drivers/char/hvc_console.c | =A0 19 ++++++++++++++++++- =A01 files changed, 18 insertions(+), 1 deletions(-)diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index fa27d16..b4deffd 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c@@ -3,6 +3,7 @@=A0* Copyright (C) 2001 Paul Mackerras [off-list ref], IBM =A0* Copyright (C) 2004 Benjamin Herrenschmidt [off-list ref]=
, IBM Corp.
quoted hunk ↗ jump to hunk
=A0* Copyright (C) 2004 IBM Corporation + * Copyright 2009 Freescale Semiconductor, Inc. =A0* =A0* Additional Author(s): =A0* =A0Ryan S. Arnold [off-list ref]@@ -141,6 +142,7 @@ static void hvc_console_print(struct console *co, con=
st char *b,
=A0 =A0 =A0 =A0char c[N_OUTBUF] __ALIGNED__; =A0 =A0 =A0 =A0unsigned i =3D 0, n =3D 0; =A0 =A0 =A0 =A0int r, donecr =3D 0, index =3D co->index; + =A0 =A0 =A0 unsigned int timeout =3D 1000000; /* Keep trying for up to =
one second */
=A0 =A0 =A0 =A0/* Console access attempt outside of acceptable console ra=
nge. */
quoted hunk ↗ jump to hunk
=A0 =A0 =A0 =A0if (index >=3D MAX_NR_HVC_CONSOLES)@@ -152,6 +154,10 @@ static void hvc_console_print(struct console *co, co=
nst char *b,
=A0 =A0 =A0 =A0while (count > 0 || i > 0) {
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (count > 0 && i < sizeof(c)) {
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* If the local buffer (c) =is not full, then copy some
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* bytes from the input b=
uffer to it. We stop when the
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* local buffer is full. =
\n is converted to \r\n.
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*/ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (b[n] =3D=3D '\n' && !d=
onecr) {=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0c[i++] =3D=
'\r';
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0donecr =3D=
1;
quoted hunk ↗ jump to hunk
@@ -162,14 +168,25 @@ static void hvc_console_print(struct console *co, c=
onst char *b,
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0}
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} else {
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0r =3D cons_ops[index]->put=_chars(vtermnos[index], c, i);
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (r <=3D 0) {
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (r < 0) {
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* throw a=way chars on error */
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0i =3D 0;
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} else if (r > 0) {
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0i -=3D r;
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (i > 0)
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ==A0 =A0memmove(c, c+r, i);
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 } else {
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* If r =3D==3D 0, then the client driver didn't do
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* anythi=
ng, so wait 1us and try again. =A0If we
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0* time o=
ut, then just exit.
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0*/ + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!--time=
out)
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
=A0 return;
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 udelay(1); + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue; =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Reset the timeout */ + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 timeout =3D 1000000; =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} =A0 =A0 =A0 =A0} =A0} -- 1.7.0.1 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
--=20 Timur Tabi Linux kernel developer at Freescale