Commit graph

9 commits

Author SHA1 Message Date
Christophe Leroy
7e9ab144c1 powerpc/mem: Use kmap_local_page() in flushing functions
Flushing functions don't rely on preemption being disabled, so
use kmap_local_page() instead of kmap_atomic().

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/b6a880ea0ec7886b51edbb4979c188be549231c0.1617895813.git.christophe.leroy@csgroup.eu
2021-04-14 23:04:19 +10:00
Christophe Leroy
6c96020882 powerpc/mem: Inline flush_dcache_page()
flush_dcache_page() is only a few lines, it is worth
inlining.

ia64, csky, mips, openrisc and riscv have a similar
flush_dcache_page() and inline it.

On pmac32_defconfig, we get a small size reduction.
On ppc64_defconfig, we get a very small size increase.

In both case that's in the noise (less than 0.1%).

text		data	bss	dec		hex	filename
18991155	5934744	1497624	26423523	19330e3	vmlinux64.before
18994829	5936732	1497624	26429185	1934701	vmlinux64.after
9150963		2467502	 184548	11803013	 b41985	vmlinux32.before
9149689		2467302	 184548	11801539	 b413c3	vmlinux32.after

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/21c417488b70b7629dae316539fb7bb8bdef4fdd.1617895813.git.christophe.leroy@csgroup.eu
2021-04-14 23:04:19 +10:00
Christophe Leroy
67b8e6af19 powerpc/mem: Help GCC realise __flush_dcache_icache() flushes single pages
'And' the given page address with PAGE_MASK to help GCC.

With the patch:

	00000024 <__flush_dcache_icache>:
	  24:	54 63 00 26 	rlwinm  r3,r3,0,0,19
	  28:	39 40 00 40 	li      r10,64
	  2c:	7c 69 1b 78 	mr      r9,r3
	  30:	7d 49 03 a6 	mtctr   r10
	  34:	7c 00 48 6c 	dcbst   0,r9
	  38:	39 29 00 20 	addi    r9,r9,32
	  3c:	7c 00 48 6c 	dcbst   0,r9
	  40:	39 29 00 20 	addi    r9,r9,32
	  44:	42 00 ff f0 	bdnz    34 <__flush_dcache_icache+0x10>
	  48:	7c 00 04 ac 	hwsync
	  4c:	39 20 00 40 	li      r9,64
	  50:	7d 29 03 a6 	mtctr   r9
	  54:	7c 00 1f ac 	icbi    0,r3
	  58:	38 63 00 20 	addi    r3,r3,32
	  5c:	7c 00 1f ac 	icbi    0,r3
	  60:	38 63 00 20 	addi    r3,r3,32
	  64:	42 00 ff f0 	bdnz    54 <__flush_dcache_icache+0x30>
	  68:	7c 00 04 ac 	hwsync
	  6c:	4c 00 01 2c 	isync
	  70:	4e 80 00 20 	blr

Without the patch:

	00000024 <__flush_dcache_icache>:
	  24:	54 6a 00 34 	rlwinm  r10,r3,0,0,26
	  28:	39 23 10 1f 	addi    r9,r3,4127
	  2c:	7d 2a 48 50 	subf    r9,r10,r9
	  30:	55 29 d9 7f 	rlwinm. r9,r9,27,5,31
	  34:	41 82 00 94 	beq     c8 <__flush_dcache_icache+0xa4>
	  38:	71 28 00 01 	andi.   r8,r9,1
	  3c:	38 c9 ff ff 	addi    r6,r9,-1
	  40:	7d 48 53 78 	mr      r8,r10
	  44:	7d 27 4b 78 	mr      r7,r9
	  48:	40 82 00 6c 	bne     b4 <__flush_dcache_icache+0x90>
	  4c:	54 e7 f8 7e 	rlwinm  r7,r7,31,1,31
	  50:	7c e9 03 a6 	mtctr   r7
	  54:	7c 00 40 6c 	dcbst   0,r8
	  58:	39 08 00 20 	addi    r8,r8,32
	  5c:	7c 00 40 6c 	dcbst   0,r8
	  60:	39 08 00 20 	addi    r8,r8,32
	  64:	42 00 ff f0 	bdnz    54 <__flush_dcache_icache+0x30>
	  68:	7c 00 04 ac 	hwsync
	  6c:	71 28 00 01 	andi.   r8,r9,1
	  70:	39 09 ff ff 	addi    r8,r9,-1
	  74:	40 82 00 2c 	bne     a0 <__flush_dcache_icache+0x7c>
	  78:	55 29 f8 7e 	rlwinm  r9,r9,31,1,31
	  7c:	7d 29 03 a6 	mtctr   r9
	  80:	7c 00 57 ac 	icbi    0,r10
	  84:	39 4a 00 20 	addi    r10,r10,32
	  88:	7c 00 57 ac 	icbi    0,r10
	  8c:	39 4a 00 20 	addi    r10,r10,32
	  90:	42 00 ff f0 	bdnz    80 <__flush_dcache_icache+0x5c>
	  94:	7c 00 04 ac 	hwsync
	  98:	4c 00 01 2c 	isync
	  9c:	4e 80 00 20 	blr
	  a0:	7c 00 57 ac 	icbi    0,r10
	  a4:	2c 08 00 00 	cmpwi   r8,0
	  a8:	39 4a 00 20 	addi    r10,r10,32
	  ac:	40 82 ff cc 	bne     78 <__flush_dcache_icache+0x54>
	  b0:	4b ff ff e4 	b       94 <__flush_dcache_icache+0x70>
	  b4:	7c 00 50 6c 	dcbst   0,r10
	  b8:	2c 06 00 00 	cmpwi   r6,0
	  bc:	39 0a 00 20 	addi    r8,r10,32
	  c0:	40 82 ff 8c 	bne     4c <__flush_dcache_icache+0x28>
	  c4:	4b ff ff a4 	b       68 <__flush_dcache_icache+0x44>
	  c8:	7c 00 04 ac 	hwsync
	  cc:	7c 00 04 ac 	hwsync
	  d0:	4c 00 01 2c 	isync
	  d4:	4e 80 00 20 	blr

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/23030822ea5cd0a122948b10226abe56602dc027.1617895813.git.christophe.leroy@csgroup.eu
2021-04-14 23:04:18 +10:00
Christophe Leroy
52d490437f powerpc/mem: flush_dcache_icache_phys() is for HIGHMEM pages only
__flush_dcache_icache() is usable for non HIGHMEM pages on
every platform.

It is only for HIGHMEM pages that BOOKE needs kmap() and
BOOK3S needs flush_dcache_icache_phys().

So make flush_dcache_icache_phys() dependent on CONFIG_HIGHMEM and
call it only when it is a HIGHMEM page.

We could make flush_dcache_icache_phys() available at all time,
but as it is declared NOKPROBE_SYMBOL(), GCC doesn't optimise
it out when it is not used.

So define a stub for !CONFIG_HIGHMEM in order to remove the #ifdef in
flush_dcache_icache_page() and use IS_ENABLED() instead.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/79ed5d7914f497cd5fcd681ca2f4d50a91719455.1617895813.git.christophe.leroy@csgroup.eu
2021-04-14 23:04:18 +10:00
Christophe Leroy
cd97d9e8b5 powerpc/mem: Optimise flush_dcache_icache_hugepage()
flush_dcache_icache_hugepage() is a static function, with
only one caller. That caller calls it when PageCompound() is true,
so bugging on !PageCompound() is useless if we can trust the
compiler a little. Remove the BUG_ON(!PageCompound()).

The number of elements of a page won't change over time, but
GCC doesn't know about it, so it gets the value at every iteration.

To avoid that, call compound_nr() outside the loop and save it in
a local variable.

Whether the page is a HIGHMEM page or not doesn't change over time.

But GCC doesn't know it so it does the test on every iteration.

Do the test outside the loop.

When the page is not a HIGHMEM page, page_address() will fallback on
lowmem_page_address(), so call lowmem_page_address() directly and
don't suffer the call to page_address() on every iteration.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/ab03712b70105fccfceef095aa03007de9295a40.1617895813.git.christophe.leroy@csgroup.eu
2021-04-14 23:04:18 +10:00
Christophe Leroy
e618c7aea1 powerpc/mem: Call flush_coherent_icache() at higher level
flush_coherent_icache() doesn't need the address anymore,
so it can be called immediately when entering the public
functions and doesn't need to be disseminated among
lower level functions.

And use page_to_phys() instead of open coding the calculation
of phys address to call flush_dcache_icache_phys().

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/5f063986e325d2efdd404b8f8c5f4bcbd4eb11a6.1617895813.git.christophe.leroy@csgroup.eu
2021-04-14 23:04:18 +10:00
Christophe Leroy
131637a17d powerpc/mem: Remove address argument to flush_coherent_icache()
flush_coherent_icache() can use any valid address as mentionned
by the comment.

Use PAGE_OFFSET as base address. This allows removing the
user access stuff.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/742b6360ae4f344a1c6ecfadcf3b6645f443fa7a.1617895813.git.christophe.leroy@csgroup.eu
2021-04-14 23:04:18 +10:00
Christophe Leroy
bf26e0bbd2 powerpc/mem: Declare __flush_dcache_icache() static
__flush_dcache_icache() is only used in mem.c.

Move it before the functions that use it and declare it static.

And also fix the name of the parameter in the comment.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/3fa903eb5a10b2bc7d99a8c559ffdaa05452d8e0.1617895813.git.christophe.leroy@csgroup.eu
2021-04-14 23:04:18 +10:00
Christophe Leroy
b26e8f2725 powerpc/mem: Move cache flushing functions into mm/cacheflush.c
Cache flushing functions are in the middle of completely
unrelated stuff in mm/mem.c

Create a dedicated mm/cacheflush.c for those functions.

Also cleanup the list of included headers.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/7bf6f1600acad146e541a4e220940062f2e5b03d.1617895813.git.christophe.leroy@csgroup.eu
2021-04-14 23:04:17 +10:00