Message ID | 20171002020618.23924-4-nicolas.pitre@linaro.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hello Nicolas, On Sun, Oct 01, 2017 at 10:06:18PM -0400, Nicolas Pitre wrote: > With printch() the console messages are sent out one character at a time > which is agonizingly slow especially with semihosting as the whole trap > intercept, remote byte access, and system resume danse is performed for s/danse/dance/ ? > every single character across a relatively slow remote debug connection. > Let's use printascii() to send a whole string at once. This is also going > to be more efficient, albeit to a quite lesser extent, with serial ports > as well. > > Signed-off-by: Nicolas Pitre <nico@linaro.org> > --- > arch/arm/kernel/early_printk.c | 16 ++++++++++------ > 1 file changed, 10 insertions(+), 6 deletions(-) > > diff --git a/arch/arm/kernel/early_printk.c b/arch/arm/kernel/early_printk.c > index 4307653696..9257736ec9 100644 > --- a/arch/arm/kernel/early_printk.c > +++ b/arch/arm/kernel/early_printk.c > @@ -11,16 +11,20 @@ > #include <linux/kernel.h> > #include <linux/console.h> > #include <linux/init.h> > +#include <linux/string.h> > > -extern void printch(int); > +extern void printascii(const char *); > > static void early_write(const char *s, unsigned n) > { > - while (n-- > 0) { > - if (*s == '\n') > - printch('\r'); > - printch(*s); > - s++; > + char buf[128]; > + while (n) { > + unsigned l = min(n, sizeof(buf)-1); > + memcpy(buf, s, l); > + buf[l] = 0; > + s += l; > + n -= l; > + printascii(buf); I wonder if it is a usual case that n < 128 and s[n] == '\0'. If so this could be tested for and then the memcpy could be dropped. (The downside of course is that s[n] might also be something completely different?) Best regards Uwe
On Mon, 2 Oct 2017, Uwe Kleine-König wrote: > Hello Nicolas, > > On Sun, Oct 01, 2017 at 10:06:18PM -0400, Nicolas Pitre wrote: > > With printch() the console messages are sent out one character at a time > > which is agonizingly slow especially with semihosting as the whole trap > > intercept, remote byte access, and system resume danse is performed for > > s/danse/dance/ ? > > > every single character across a relatively slow remote debug connection. > > Let's use printascii() to send a whole string at once. This is also going > > to be more efficient, albeit to a quite lesser extent, with serial ports > > as well. > > > > Signed-off-by: Nicolas Pitre <nico@linaro.org> > > --- > > arch/arm/kernel/early_printk.c | 16 ++++++++++------ > > 1 file changed, 10 insertions(+), 6 deletions(-) > > > > diff --git a/arch/arm/kernel/early_printk.c b/arch/arm/kernel/early_printk.c > > index 4307653696..9257736ec9 100644 > > --- a/arch/arm/kernel/early_printk.c > > +++ b/arch/arm/kernel/early_printk.c > > @@ -11,16 +11,20 @@ > > #include <linux/kernel.h> > > #include <linux/console.h> > > #include <linux/init.h> > > +#include <linux/string.h> > > > > -extern void printch(int); > > +extern void printascii(const char *); > > > > static void early_write(const char *s, unsigned n) > > { > > - while (n-- > 0) { > > - if (*s == '\n') > > - printch('\r'); > > - printch(*s); > > - s++; > > + char buf[128]; > > + while (n) { > > + unsigned l = min(n, sizeof(buf)-1); > > + memcpy(buf, s, l); > > + buf[l] = 0; > > + s += l; > > + n -= l; > > + printascii(buf); > > I wonder if it is a usual case that n < 128 and s[n] == '\0'. If so this > could be tested for and then the memcpy could be dropped. I did try it. Unfortunately the passed string is not null terminated. Nicolas
On Sunday, October 01, 2017 1, Nicolas Pitre wrote: > With printch() the console messages are sent out one character at a time > which is agonizingly slow especially with semihosting as the whole trap > intercept, remote byte access, and system resume danse is performed for > every single character across a relatively slow remote debug connection. > Let's use printascii() to send a whole string at once. This is also going > to be more efficient, albeit to a quite lesser extent, with serial ports > as well. > > Signed-off-by: Nicolas Pitre <nico@linaro.org> > --- > arch/arm/kernel/early_printk.c | 16 ++++++++++------ > 1 file changed, 10 insertions(+), 6 deletions(-) Now that this patch has hit -next, I'm noticing an issue with it. There are no carriage returns, just line feeds, which makes for a very ugly display. For example: Booting Linux... [ 0.000000] Booting Linux on physical CPU 0x0 [ 0.000000] Linux version 4.14.0-rc5-00014-g5689707d65e6 (chris@ubuntu) (gcc version 5.4.1 20161213 (Linaro GCC 5.4-2017.01)) #735 Mon Oct 30 12:59:37 EST 2017 [ 0.000000] CPU: ARMv7 Processor [413fc090] revision 0 (ARMv7), cr=58c53c7d [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache [ 0.000000] OF: fdt: Machine model: RSKRZA1 [ 0.000000] debug: ignoring loglevel setting. [ 0.000000] bootconsole [earlycon0] enabled [ 0.000000] Memory policy: Data cache writeback [ 0.000000] On node 0 totalpages: 8192 [ 0.000000] free_area_init_node: node 0, pgdat c003dfb4, node_mem_map c1fb8000 [ 0.000000] Normal zone: 64 pages used for memmap [ 0.000000] Normal zone: 0 pages reserved [ 0.000000] Normal zone: 8192 pages, LIFO batch:0 [ 0.000000] CPU: All CPU(s) started in SVC mode. Of course as soon as the normal console driver is loaded later it boot, everything looks fine again. But I use early_printk a lot, so I wonder if I could get my carriage returns back. Chris
On Tue, 31 Oct 2017, Chris Brandt wrote: > On Sunday, October 01, 2017 1, Nicolas Pitre wrote: > > With printch() the console messages are sent out one character at a time > > which is agonizingly slow especially with semihosting as the whole trap > > intercept, remote byte access, and system resume danse is performed for > > every single character across a relatively slow remote debug connection. > > Let's use printascii() to send a whole string at once. This is also going > > to be more efficient, albeit to a quite lesser extent, with serial ports > > as well. > > > > Signed-off-by: Nicolas Pitre <nico@linaro.org> > > --- > > arch/arm/kernel/early_printk.c | 16 ++++++++++------ > > 1 file changed, 10 insertions(+), 6 deletions(-) > > Now that this patch has hit -next, I'm noticing an issue with it. > > There are no carriage returns, just line feeds, which makes for a very > ugly display. Hmmm.... If you look at printascii in arch/arm/kernel/debug.S you'll find the following code: 1: waituart r2, r3 senduart r1, r3 busyuart r2, r3 teq r1, #'\n' moveq r1, #'\r' beq 1b Why is that not working for you? Are you using semihosting? Do you have another printascii implementation? Nicolas
On 31/10/17 16:22, Nicolas Pitre wrote: > On Tue, 31 Oct 2017, Chris Brandt wrote: > >> On Sunday, October 01, 2017 1, Nicolas Pitre wrote: >>> With printch() the console messages are sent out one character at a time >>> which is agonizingly slow especially with semihosting as the whole trap >>> intercept, remote byte access, and system resume danse is performed for >>> every single character across a relatively slow remote debug connection. >>> Let's use printascii() to send a whole string at once. This is also going >>> to be more efficient, albeit to a quite lesser extent, with serial ports >>> as well. >>> >>> Signed-off-by: Nicolas Pitre <nico@linaro.org> >>> --- >>> arch/arm/kernel/early_printk.c | 16 ++++++++++------ >>> 1 file changed, 10 insertions(+), 6 deletions(-) >> >> Now that this patch has hit -next, I'm noticing an issue with it. >> >> There are no carriage returns, just line feeds, which makes for a very >> ugly display. > > Hmmm.... > > If you look at printascii in arch/arm/kernel/debug.S you'll find the > following code: > > 1: waituart r2, r3 > senduart r1, r3 > busyuart r2, r3 > teq r1, #'\n' > moveq r1, #'\r' > beq 1b > > Why is that not working for you? By inspection, the removed early_write() code inserted the '\r' before the '\n' in the usual fashion; the printascii() code above ends up doing the reverse, and I can imagine the atypical "\n\r" sequence probably confuses some terminals trying to be clever with line ending detection. Robin. > > Are you using semihosting? > > Do you have another printascii implementation? > > > Nicolas > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel >
diff --git a/arch/arm/kernel/early_printk.c b/arch/arm/kernel/early_printk.c index 4307653696..9257736ec9 100644 --- a/arch/arm/kernel/early_printk.c +++ b/arch/arm/kernel/early_printk.c @@ -11,16 +11,20 @@ #include <linux/kernel.h> #include <linux/console.h> #include <linux/init.h> +#include <linux/string.h> -extern void printch(int); +extern void printascii(const char *); static void early_write(const char *s, unsigned n) { - while (n-- > 0) { - if (*s == '\n') - printch('\r'); - printch(*s); - s++; + char buf[128]; + while (n) { + unsigned l = min(n, sizeof(buf)-1); + memcpy(buf, s, l); + buf[l] = 0; + s += l; + n -= l; + printascii(buf); } }
With printch() the console messages are sent out one character at a time which is agonizingly slow especially with semihosting as the whole trap intercept, remote byte access, and system resume danse is performed for every single character across a relatively slow remote debug connection. Let's use printascii() to send a whole string at once. This is also going to be more efficient, albeit to a quite lesser extent, with serial ports as well. Signed-off-by: Nicolas Pitre <nico@linaro.org> --- arch/arm/kernel/early_printk.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)