Skip to content

Commit 70ddb63

Browse files
Joonwoo Parkwildea01
Joonwoo Park
authored andcommitted
arm64: optimize memcpy_{from,to}io() and memset_io()
Optimize memcpy_{from,to}io() and memset_io() by transferring in 64 bit as much as possible with minimized barrier usage. This simplest optimization brings faster throughput compare to current byte-by-byte read and write with barrier in the loop. Code's skeleton is taken from the powerpc. Link: http://lkml.kernel.org/p/[email protected] Reviewed-by: Catalin Marinas <[email protected]> Reviewed-by: Trilok Soni <[email protected]> Signed-off-by: Joonwoo Park <[email protected]> Signed-off-by: Will Deacon <[email protected]>
1 parent 4ee2098 commit 70ddb63

File tree

1 file changed

+56
-10
lines changed
  • arch/arm64/kernel

1 file changed

+56
-10
lines changed

arch/arm64/kernel/io.c

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,26 @@
2525
*/
2626
void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
2727
{
28-
unsigned char *t = to;
29-
while (count) {
28+
while (count && (!IS_ALIGNED((unsigned long)from, 8) ||
29+
!IS_ALIGNED((unsigned long)to, 8))) {
30+
*(u8 *)to = __raw_readb(from);
31+
from++;
32+
to++;
3033
count--;
31-
*t = readb(from);
32-
t++;
34+
}
35+
36+
while (count >= 8) {
37+
*(u64 *)to = __raw_readq(from);
38+
from += 8;
39+
to += 8;
40+
count -= 8;
41+
}
42+
43+
while (count) {
44+
*(u8 *)to = __raw_readb(from);
3345
from++;
46+
to++;
47+
count--;
3448
}
3549
}
3650
EXPORT_SYMBOL(__memcpy_fromio);
@@ -40,12 +54,26 @@ EXPORT_SYMBOL(__memcpy_fromio);
4054
*/
4155
void __memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
4256
{
43-
const unsigned char *f = from;
44-
while (count) {
57+
while (count && (!IS_ALIGNED((unsigned long)to, 8) ||
58+
!IS_ALIGNED((unsigned long)from, 8))) {
59+
__raw_writeb(*(volatile u8 *)from, to);
60+
from++;
61+
to++;
4562
count--;
46-
writeb(*f, to);
47-
f++;
63+
}
64+
65+
while (count >= 8) {
66+
__raw_writeq(*(volatile u64 *)from, to);
67+
from += 8;
68+
to += 8;
69+
count -= 8;
70+
}
71+
72+
while (count) {
73+
__raw_writeb(*(volatile u8 *)from, to);
74+
from++;
4875
to++;
76+
count--;
4977
}
5078
}
5179
EXPORT_SYMBOL(__memcpy_toio);
@@ -55,10 +83,28 @@ EXPORT_SYMBOL(__memcpy_toio);
5583
*/
5684
void __memset_io(volatile void __iomem *dst, int c, size_t count)
5785
{
58-
while (count) {
86+
u64 qc = (u8)c;
87+
88+
qc |= qc << 8;
89+
qc |= qc << 16;
90+
qc |= qc << 32;
91+
92+
while (count && !IS_ALIGNED((unsigned long)dst, 8)) {
93+
__raw_writeb(c, dst);
94+
dst++;
5995
count--;
60-
writeb(c, dst);
96+
}
97+
98+
while (count >= 8) {
99+
__raw_writeq(qc, dst);
100+
dst += 8;
101+
count -= 8;
102+
}
103+
104+
while (count) {
105+
__raw_writeb(c, dst);
61106
dst++;
107+
count--;
62108
}
63109
}
64110
EXPORT_SYMBOL(__memset_io);

0 commit comments

Comments
 (0)