diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2017-05-03 09:15:07 +0200 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2017-05-09 10:43:24 +0200 |
commit | f5c8b9601036869e162cb278aaafbf003dc4e5a0 (patch) | |
tree | 7e2919e64adf6b4f5b3da7ac77803b52f46ec6e7 | |
parent | db55947dd2d09cd3e6f722d1205934fec793ee63 (diff) | |
download | op-kernel-dev-f5c8b9601036869e162cb278aaafbf003dc4e5a0.zip op-kernel-dev-f5c8b9601036869e162cb278aaafbf003dc4e5a0.tar.gz |
s390/uaccess: use sane length for __strncpy_from_user()
The average string that is copied from user space to kernel space is
rather short. E.g. booting a system involves about 50.000
strncpy_from_user() calls where the NULL terminated string has an
average size of 27 bytes.
By default our s390 specific strncpy_from_user() implementation
however copies up to 4096 bytes, which is a waste of cpu cycles and
cache lines. Therefore reduce the default length to L1_CACHE_BYTES
(256 bytes), which also reduces the average execution time of
strncpy_from_user() by 30-40%.
Alternatively we could have switched to the generic
strncpy_from_user() implementation, however it turned out that that
variant would be slower than the now optimized s390 variant.
Reported-by: Al Viro <viro@ZenIV.linux.org.uk>
Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Reviewed-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r-- | arch/s390/lib/uaccess.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/s390/lib/uaccess.c b/arch/s390/lib/uaccess.c index 1e5bb2b..b3bd3f2 100644 --- a/arch/s390/lib/uaccess.c +++ b/arch/s390/lib/uaccess.c @@ -337,8 +337,8 @@ long __strncpy_from_user(char *dst, const char __user *src, long size) return 0; done = 0; do { - offset = (size_t)src & ~PAGE_MASK; - len = min(size - done, PAGE_SIZE - offset); + offset = (size_t)src & (L1_CACHE_BYTES - 1); + len = min(size - done, L1_CACHE_BYTES - offset); if (copy_from_user(dst, src, len)) return -EFAULT; len_str = strnlen(dst, len); |