| From: Alexey Dobriyan <adobriyan@gmail.com> |
| Subject: kstrtox: uninline everything |
| |
| I've made a mistake of looking into lib/kstrtox.o code generation. |
| |
| The only function remotely performance critical is _parse_integer() |
| (via /proc/*/map_files/*), everything else is not. |
| |
| Uninline everything, shrink lib/kstrtox.o by ~20 % ! |
| |
| Space savings on x86_64: |
| |
| add/remove: 0/0 grow/shrink: 0/23 up/down: 0/-1269 (-1269 !!!) |
| Function old new delta |
| kstrtoull 16 13 -3 |
| kstrtouint 59 48 -11 |
| kstrtou8 60 49 -11 |
| kstrtou16 61 50 -11 |
| _kstrtoul 46 35 -11 |
| kstrtoull_from_user 95 83 -12 |
| kstrtoul_from_user 95 83 -12 |
| kstrtoll 93 80 -13 |
| kstrtouint_from_user 124 83 -41 |
| kstrtou8_from_user 125 83 -42 |
| kstrtou16_from_user 126 83 -43 |
| kstrtos8 101 50 -51 |
| kstrtos16 102 51 -51 |
| kstrtoint 100 49 -51 |
| _kstrtol 93 35 -58 |
| kstrtobool_from_user 156 75 -81 |
| kstrtoll_from_user 165 83 -82 |
| kstrtol_from_user 165 83 -82 |
| kstrtoint_from_user 172 83 -89 |
| kstrtos8_from_user 173 83 -90 |
| kstrtos16_from_user 174 83 -91 |
| _parse_integer 136 10 -126 |
| _kstrtoull 308 101 -207 |
| Total: Before=3421236, After=3419967, chg -0.04% |
| |
| Link: https://lkml.kernel.org/r/YZDsFDhHst4m2Pnt@localhost.localdomain |
| Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| lib/kstrtox.c | 12 ++++++++++++ |
| 1 file changed, 12 insertions(+) |
| |
| --- a/lib/kstrtox.c~kstrtox-uninline-everything |
| +++ a/lib/kstrtox.c |
| @@ -22,6 +22,7 @@ |
| |
| #include "kstrtox.h" |
| |
| +noinline |
| const char *_parse_integer_fixup_radix(const char *s, unsigned int *base) |
| { |
| if (*base == 0) { |
| @@ -47,6 +48,7 @@ const char *_parse_integer_fixup_radix(c |
| * |
| * Don't you dare use this function. |
| */ |
| +noinline |
| unsigned int _parse_integer_limit(const char *s, unsigned int base, unsigned long long *p, |
| size_t max_chars) |
| { |
| @@ -85,6 +87,7 @@ unsigned int _parse_integer_limit(const |
| return rv; |
| } |
| |
| +noinline |
| unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *p) |
| { |
| return _parse_integer_limit(s, base, p, INT_MAX); |
| @@ -125,6 +128,7 @@ static int _kstrtoull(const char *s, uns |
| * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error. |
| * Preferred over simple_strtoull(). Return code must be checked. |
| */ |
| +noinline |
| int kstrtoull(const char *s, unsigned int base, unsigned long long *res) |
| { |
| if (s[0] == '+') |
| @@ -148,6 +152,7 @@ EXPORT_SYMBOL(kstrtoull); |
| * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error. |
| * Preferred over simple_strtoll(). Return code must be checked. |
| */ |
| +noinline |
| int kstrtoll(const char *s, unsigned int base, long long *res) |
| { |
| unsigned long long tmp; |
| @@ -219,6 +224,7 @@ EXPORT_SYMBOL(_kstrtol); |
| * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error. |
| * Preferred over simple_strtoul(). Return code must be checked. |
| */ |
| +noinline |
| int kstrtouint(const char *s, unsigned int base, unsigned int *res) |
| { |
| unsigned long long tmp; |
| @@ -249,6 +255,7 @@ EXPORT_SYMBOL(kstrtouint); |
| * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error. |
| * Preferred over simple_strtol(). Return code must be checked. |
| */ |
| +noinline |
| int kstrtoint(const char *s, unsigned int base, int *res) |
| { |
| long long tmp; |
| @@ -264,6 +271,7 @@ int kstrtoint(const char *s, unsigned in |
| } |
| EXPORT_SYMBOL(kstrtoint); |
| |
| +noinline |
| int kstrtou16(const char *s, unsigned int base, u16 *res) |
| { |
| unsigned long long tmp; |
| @@ -279,6 +287,7 @@ int kstrtou16(const char *s, unsigned in |
| } |
| EXPORT_SYMBOL(kstrtou16); |
| |
| +noinline |
| int kstrtos16(const char *s, unsigned int base, s16 *res) |
| { |
| long long tmp; |
| @@ -294,6 +303,7 @@ int kstrtos16(const char *s, unsigned in |
| } |
| EXPORT_SYMBOL(kstrtos16); |
| |
| +noinline |
| int kstrtou8(const char *s, unsigned int base, u8 *res) |
| { |
| unsigned long long tmp; |
| @@ -309,6 +319,7 @@ int kstrtou8(const char *s, unsigned int |
| } |
| EXPORT_SYMBOL(kstrtou8); |
| |
| +noinline |
| int kstrtos8(const char *s, unsigned int base, s8 *res) |
| { |
| long long tmp; |
| @@ -333,6 +344,7 @@ EXPORT_SYMBOL(kstrtos8); |
| * [oO][NnFf] for "on" and "off". Otherwise it will return -EINVAL. Value |
| * pointed to by res is updated upon finding a match. |
| */ |
| +noinline |
| int kstrtobool(const char *s, bool *res) |
| { |
| if (!s) |
| _ |