[v3,7/7] vga: Optimise console scrolling
diff mbox

Message ID 20170324161318.18718-8-willy@infradead.org
State New, archived
Headers show

Commit Message

Matthew Wilcox March 24, 2017, 4:13 p.m. UTC
From: Matthew Wilcox <mawilcox@microsoft.com>

Where possible, call memset16(), memmove() or memcpy() instead of using
open-coded loops.  If an architecture doesn't define VT_BUF_HAVE_RW,
we can do that from the generic code.  For the architectures which do
have special RW routines, usually we can do the special thing (pointer
test or byteswap) once (and then use a mem* call) instead of each time
around a loop.  Alpha is the only architecture missing a scr_memmovew()
definition (because it's non-trivial to write).

I don't like the calling convention that uses a byte count instead of
a count of u16s, but it's a little late to change that.  Reduces code
size of fbcon.o by almost 400 bytes on my laptop build.

Signed-off-by: Matthew Wilcox <mawilcox@microsoft.com>
---
 arch/mips/include/asm/vga.h    |  6 ++++++
 arch/powerpc/include/asm/vga.h |  8 ++++++++
 arch/sparc/include/asm/vga.h   | 24 ++++++++++++++++++++++++
 include/linux/vt_buffer.h      | 12 ++++++++++++
 4 files changed, 50 insertions(+)

Comments

kernel test robot March 26, 2017, 8:45 a.m. UTC | #1
Hi Matthew,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.11-rc3 next-20170324]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Matthew-Wilcox/Add-memsetN-functions/20170326-140108
config: sparc-allyesconfig (attached as .config)
compiler: sparc64-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
        wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=sparc 

All error/warnings (new ones prefixed by >>):

   In file included from include/video/vga.h:22:0,
                    from include/linux/vgaarb.h:34,
                    from drivers/gpu//drm/amd/amdgpu/amdgpu_device.c:35:
   arch/sparc/include/asm/vga.h: In function 'scr_memsetw':
>> arch/sparc/include/asm/vga.h:39:11: error: 's' undeclared (first use in this function)
     memset16(s, cpu_to_le16(v), n / 2);
              ^
   arch/sparc/include/asm/vga.h:39:11: note: each undeclared identifier is reported only once for each function it appears in
--
   In file included from include/video/vga.h:22:0,
                    from include/linux/vgaarb.h:34,
                    from drivers/gpu//drm/nouveau/nouveau_vga.c:1:
   arch/sparc/include/asm/vga.h: In function 'scr_memsetw':
>> arch/sparc/include/asm/vga.h:39:2: error: implicit declaration of function 'memset16' [-Werror=implicit-function-declaration]
     memset16(s, cpu_to_le16(v), n / 2);
     ^~~~~~~~
>> arch/sparc/include/asm/vga.h:39:11: error: 's' undeclared (first use in this function)
     memset16(s, cpu_to_le16(v), n / 2);
              ^
   arch/sparc/include/asm/vga.h:39:11: note: each undeclared identifier is reported only once for each function it appears in
   arch/sparc/include/asm/vga.h: In function 'scr_memcpyw':
>> arch/sparc/include/asm/vga.h:46:2: error: implicit declaration of function 'memcpy' [-Werror=implicit-function-declaration]
     memcpy(d, s, n);
     ^~~~~~
>> arch/sparc/include/asm/vga.h:46:2: warning: incompatible implicit declaration of built-in function 'memcpy'
   arch/sparc/include/asm/vga.h:46:2: note: include '<string.h>' or provide a declaration of 'memcpy'
   arch/sparc/include/asm/vga.h: In function 'scr_memmovew':
>> arch/sparc/include/asm/vga.h:53:2: error: implicit declaration of function 'memmove' [-Werror=implicit-function-declaration]
     memmove(d, s, n);
     ^~~~~~~
>> arch/sparc/include/asm/vga.h:53:2: warning: incompatible implicit declaration of built-in function 'memmove'
   arch/sparc/include/asm/vga.h:53:2: note: include '<string.h>' or provide a declaration of 'memmove'
   In file included from include/uapi/linux/uuid.h:21:0,
                    from include/linux/uuid.h:19,
                    from include/linux/mod_devicetable.h:12,
                    from include/linux/i2c.h:29,
                    from include/uapi/linux/fb.h:5,
                    from include/linux/fb.h:5,
                    from include/linux/vga_switcheroo.h:34,
                    from drivers/gpu//drm/nouveau/nouveau_vga.c:2:
   include/linux/string.h: At top level:
>> include/linux/string.h:104:14: error: conflicting types for 'memset16'
    extern void *memset16(uint16_t *, uint16_t, __kernel_size_t);
                 ^~~~~~~~
   In file included from include/video/vga.h:22:0,
                    from include/linux/vgaarb.h:34,
                    from drivers/gpu//drm/nouveau/nouveau_vga.c:1:
   arch/sparc/include/asm/vga.h:39:2: note: previous implicit declaration of 'memset16' was here
     memset16(s, cpu_to_le16(v), n / 2);
     ^~~~~~~~
   cc1: some warnings being treated as errors

vim +/s +39 arch/sparc/include/asm/vga.h

    33	}
    34	
    35	static inline void scr_memsetw(u16 *p, u16 v, unsigned int n)
    36	{
    37		BUG_ON((long) p >= 0);
    38	
  > 39		memset16(s, cpu_to_le16(v), n / 2);
    40	}
    41	
    42	static inline void scr_memcpyw(u16 *d, u16 *s, unsigned int n)
    43	{
    44		BUG_ON((long) d >= 0);
    45	
  > 46		memcpy(d, s, n);
    47	}
    48	
    49	static inline void scr_memmovew(u16 *d, u16 *s, unsigned int n)
    50	{
    51		BUG_ON((long) d >= 0);
    52	
  > 53		memmove(d, s, n);
    54	}
    55	
    56	#define VGA_MAP_MEM(x,s) (x)

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
kernel test robot March 26, 2017, 9:53 a.m. UTC | #2
Hi Matthew,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.11-rc3 next-20170324]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Matthew-Wilcox/Add-memsetN-functions/20170326-140108
config: mips-defconfig (attached as .config)
compiler: mips-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
        wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=mips 

All errors (new ones prefixed by >>):

   In file included from include/linux/selection.h:11:0,
                    from drivers/video/console/newport_con.c:16:
   include/linux/vt_buffer.h: In function 'scr_memsetw':
>> include/linux/vt_buffer.h:34:2: error: implicit declaration of function 'memset16' [-Werror=implicit-function-declaration]
     memset16(s, c, count / 2);
     ^~~~~~~~
   include/linux/vt_buffer.h: In function 'scr_memcpyw':
>> include/linux/vt_buffer.h:47:2: error: implicit declaration of function 'memcpy' [-Werror=implicit-function-declaration]
     memcpy(d, s, count);
     ^~~~~~
   include/linux/vt_buffer.h: In function 'scr_memmovew':
>> include/linux/vt_buffer.h:66:2: error: implicit declaration of function 'memmove' [-Werror=implicit-function-declaration]
     memmove(d, s, count);
     ^~~~~~~
   In file included from include/linux/string.h:18:0,
                    from include/linux/bitmap.h:8,
                    from include/linux/cpumask.h:11,
                    from arch/mips/include/asm/processor.h:15,
                    from arch/mips/include/asm/thread_info.h:15,
                    from include/linux/thread_info.h:25,
                    from include/asm-generic/preempt.h:4,
                    from ./arch/mips/include/generated/asm/preempt.h:1,
                    from include/linux/preempt.h:80,
                    from include/linux/spinlock.h:50,
                    from include/linux/wait.h:8,
                    from include/linux/fs.h:5,
                    from include/linux/tty.h:4,
                    from include/linux/vt_kern.h:11,
                    from drivers/video/console/newport_con.c:18:
   arch/mips/include/asm/string.h: At top level:
>> arch/mips/include/asm/string.h:138:14: error: conflicting types for 'memcpy'
    extern void *memcpy(void *__to, __const__ void *__from, size_t __n);
                 ^~~~~~
   In file included from include/linux/selection.h:11:0,
                    from drivers/video/console/newport_con.c:16:
   include/linux/vt_buffer.h:47:2: note: previous implicit declaration of 'memcpy' was here
     memcpy(d, s, count);
     ^~~~~~
   In file included from include/linux/string.h:18:0,
                    from include/linux/bitmap.h:8,
                    from include/linux/cpumask.h:11,
                    from arch/mips/include/asm/processor.h:15,
                    from arch/mips/include/asm/thread_info.h:15,
                    from include/linux/thread_info.h:25,
                    from include/asm-generic/preempt.h:4,
                    from ./arch/mips/include/generated/asm/preempt.h:1,
                    from include/linux/preempt.h:80,
                    from include/linux/spinlock.h:50,
                    from include/linux/wait.h:8,
                    from include/linux/fs.h:5,
                    from include/linux/tty.h:4,
                    from include/linux/vt_kern.h:11,
                    from drivers/video/console/newport_con.c:18:
>> arch/mips/include/asm/string.h:141:14: error: conflicting types for 'memmove'
    extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
                 ^~~~~~~
   In file included from include/linux/selection.h:11:0,
                    from drivers/video/console/newport_con.c:16:
   include/linux/vt_buffer.h:66:2: note: previous implicit declaration of 'memmove' was here
     memmove(d, s, count);
     ^~~~~~~
   In file included from include/linux/bitmap.h:8:0,
                    from include/linux/cpumask.h:11,
                    from arch/mips/include/asm/processor.h:15,
                    from arch/mips/include/asm/thread_info.h:15,
                    from include/linux/thread_info.h:25,
                    from include/asm-generic/preempt.h:4,
                    from ./arch/mips/include/generated/asm/preempt.h:1,
                    from include/linux/preempt.h:80,
                    from include/linux/spinlock.h:50,
                    from include/linux/wait.h:8,
                    from include/linux/fs.h:5,
                    from include/linux/tty.h:4,
                    from include/linux/vt_kern.h:11,
                    from drivers/video/console/newport_con.c:18:
   include/linux/string.h:104:14: error: conflicting types for 'memset16'
    extern void *memset16(uint16_t *, uint16_t, __kernel_size_t);
                 ^~~~~~~~
   In file included from include/linux/selection.h:11:0,
                    from drivers/video/console/newport_con.c:16:
   include/linux/vt_buffer.h:34:2: note: previous implicit declaration of 'memset16' was here
     memset16(s, c, count / 2);
     ^~~~~~~~
   cc1: some warnings being treated as errors

vim +/memset16 +34 include/linux/vt_buffer.h

    28	{
    29	#ifdef VT_BUF_HAVE_RW
    30		count /= 2;
    31		while (count--)
    32			scr_writew(c, s++);
    33	#else
  > 34		memset16(s, c, count / 2);
    35	#endif
    36	}
    37	#endif
    38	
    39	#ifndef VT_BUF_HAVE_MEMCPYW
    40	static inline void scr_memcpyw(u16 *d, const u16 *s, unsigned int count)
    41	{
    42	#ifdef VT_BUF_HAVE_RW
    43		count /= 2;
    44		while (count--)
    45			scr_writew(scr_readw(s++), d++);
    46	#else
  > 47		memcpy(d, s, count);
    48	#endif
    49	}
    50	#endif
    51	
    52	#ifndef VT_BUF_HAVE_MEMMOVEW
    53	static inline void scr_memmovew(u16 *d, const u16 *s, unsigned int count)
    54	{
    55	#ifdef VT_BUF_HAVE_RW
    56		if (d < s)
    57			scr_memcpyw(d, s, count);
    58		else {
    59			count /= 2;
    60			d += count;
    61			s += count;
    62			while (count--)
    63				scr_writew(scr_readw(--s), --d);
    64		}
    65	#else
  > 66		memmove(d, s, count);
    67	#endif
    68	}
    69	#endif

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

Patch
diff mbox

diff --git a/arch/mips/include/asm/vga.h b/arch/mips/include/asm/vga.h
index f82c83749a08..7510f406e1e1 100644
--- a/arch/mips/include/asm/vga.h
+++ b/arch/mips/include/asm/vga.h
@@ -40,9 +40,15 @@  static inline u16 scr_readw(volatile const u16 *addr)
 	return le16_to_cpu(*addr);
 }
 
+static inline void scr_memsetw(u16 *s, u16 v, unsigned int count)
+{
+	memset16(s, cpu_to_le16(v), count / 2);
+}
+
 #define scr_memcpyw(d, s, c) memcpy(d, s, c)
 #define scr_memmovew(d, s, c) memmove(d, s, c)
 #define VT_BUF_HAVE_MEMCPYW
 #define VT_BUF_HAVE_MEMMOVEW
+#define VT_BUF_HAVE_MEMSETW
 
 #endif /* _ASM_VGA_H */
diff --git a/arch/powerpc/include/asm/vga.h b/arch/powerpc/include/asm/vga.h
index ab3acd2f2786..7a7b541b7493 100644
--- a/arch/powerpc/include/asm/vga.h
+++ b/arch/powerpc/include/asm/vga.h
@@ -33,8 +33,16 @@  static inline u16 scr_readw(volatile const u16 *addr)
 	return le16_to_cpu(*addr);
 }
 
+#define VT_BUF_HAVE_MEMSETW
+static inline void scr_memsetw(u16 *s, u16 v, unsigned int n)
+{
+	memset16(s, cpu_to_le16(v), n / 2);
+}
+
 #define VT_BUF_HAVE_MEMCPYW
+#define VT_BUF_HAVE_MEMMOVEW
 #define scr_memcpyw	memcpy
+#define scr_memmovew	memmove
 
 #endif /* !CONFIG_VGA_CONSOLE && !CONFIG_MDA_CONSOLE */
 
diff --git a/arch/sparc/include/asm/vga.h b/arch/sparc/include/asm/vga.h
index ec0e9967d93d..1fab92b110d9 100644
--- a/arch/sparc/include/asm/vga.h
+++ b/arch/sparc/include/asm/vga.h
@@ -11,6 +11,9 @@ 
 #include <asm/types.h>
 
 #define VT_BUF_HAVE_RW
+#define VT_BUF_HAVE_MEMSETW
+#define VT_BUF_HAVE_MEMCPYW
+#define VT_BUF_HAVE_MEMMOVEW
 
 #undef scr_writew
 #undef scr_readw
@@ -29,6 +32,27 @@  static inline u16 scr_readw(const u16 *addr)
 	return *addr;
 }
 
+static inline void scr_memsetw(u16 *p, u16 v, unsigned int n)
+{
+	BUG_ON((long) p >= 0);
+
+	memset16(s, cpu_to_le16(v), n / 2);
+}
+
+static inline void scr_memcpyw(u16 *d, u16 *s, unsigned int n)
+{
+	BUG_ON((long) d >= 0);
+
+	memcpy(d, s, n);
+}
+
+static inline void scr_memmovew(u16 *d, u16 *s, unsigned int n)
+{
+	BUG_ON((long) d >= 0);
+
+	memmove(d, s, n);
+}
+
 #define VGA_MAP_MEM(x,s) (x)
 
 #endif
diff --git a/include/linux/vt_buffer.h b/include/linux/vt_buffer.h
index f38c10ba3ff5..31b92fcd8f03 100644
--- a/include/linux/vt_buffer.h
+++ b/include/linux/vt_buffer.h
@@ -26,24 +26,33 @@ 
 #ifndef VT_BUF_HAVE_MEMSETW
 static inline void scr_memsetw(u16 *s, u16 c, unsigned int count)
 {
+#ifdef VT_BUF_HAVE_RW
 	count /= 2;
 	while (count--)
 		scr_writew(c, s++);
+#else
+	memset16(s, c, count / 2);
+#endif
 }
 #endif
 
 #ifndef VT_BUF_HAVE_MEMCPYW
 static inline void scr_memcpyw(u16 *d, const u16 *s, unsigned int count)
 {
+#ifdef VT_BUF_HAVE_RW
 	count /= 2;
 	while (count--)
 		scr_writew(scr_readw(s++), d++);
+#else
+	memcpy(d, s, count);
+#endif
 }
 #endif
 
 #ifndef VT_BUF_HAVE_MEMMOVEW
 static inline void scr_memmovew(u16 *d, const u16 *s, unsigned int count)
 {
+#ifdef VT_BUF_HAVE_RW
 	if (d < s)
 		scr_memcpyw(d, s, count);
 	else {
@@ -53,6 +62,9 @@  static inline void scr_memmovew(u16 *d, const u16 *s, unsigned int count)
 		while (count--)
 			scr_writew(scr_readw(--s), --d);
 	}
+#else
+	memmove(d, s, count);
+#endif
 }
 #endif