diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-17 09:04:38 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-17 09:04:38 -0400 |
| commit | 54e514b91b95d6441c12a7955addfb9f9d2afc65 (patch) | |
| tree | 8b73d901bd2a6ec5a31f34a8954e5ea92216dd6c /lib | |
| parent | 4fc8adcfec3da639da76e8314c9ccefe5bf9a045 (diff) | |
| parent | 6c8c90319c0bb1c9e0b68e721359b89ae4f28465 (diff) | |
Merge branch 'akpm' (patches from Andrew)
Merge third patchbomb from Andrew Morton:
- various misc things
- a couple of lib/ optimisations
- provide DIV_ROUND_CLOSEST_ULL()
- checkpatch updates
- rtc tree
- befs, nilfs2, hfs, hfsplus, fatfs, adfs, affs, bfs
- ptrace fixes
- fork() fixes
- seccomp cleanups
- more mmap_sem hold time reductions from Davidlohr
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (138 commits)
proc: show locks in /proc/pid/fdinfo/X
docs: add missing and new /proc/PID/status file entries, fix typos
drivers/rtc/rtc-at91rm9200.c: make IO endian agnostic
Documentation/spi/spidev_test.c: fix warning
drivers/rtc/rtc-s5m.c: allow usage on device type different than main MFD type
.gitignore: ignore *.tar
MAINTAINERS: add Mediatek SoC mailing list
tomoyo: reduce mmap_sem hold for mm->exe_file
powerpc/oprofile: reduce mmap_sem hold for exe_file
oprofile: reduce mmap_sem hold for mm->exe_file
mips: ip32: add platform data hooks to use DS1685 driver
lib/Kconfig: fix up HAVE_ARCH_BITREVERSE help text
x86: switch to using asm-generic for seccomp.h
sparc: switch to using asm-generic for seccomp.h
powerpc: switch to using asm-generic for seccomp.h
parisc: switch to using asm-generic for seccomp.h
mips: switch to using asm-generic for seccomp.h
microblaze: use asm-generic for seccomp.h
arm: use asm-generic for seccomp.h
seccomp: allow COMPAT sigreturn overrides
...
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Kconfig | 5 | ||||
| -rw-r--r-- | lib/Makefile | 2 | ||||
| -rw-r--r-- | lib/bitmap.c | 30 | ||||
| -rw-r--r-- | lib/cpumask.c | 9 | ||||
| -rw-r--r-- | lib/dma-debug.c | 2 | ||||
| -rw-r--r-- | lib/find_bit.c | 193 | ||||
| -rw-r--r-- | lib/find_last_bit.c | 36 | ||||
| -rw-r--r-- | lib/find_next_bit.c | 285 | ||||
| -rw-r--r-- | lib/vsprintf.c | 244 |
9 files changed, 342 insertions, 464 deletions
diff --git a/lib/Kconfig b/lib/Kconfig index 87da53bb1fef..f5440221d929 100644 --- a/lib/Kconfig +++ b/lib/Kconfig | |||
| @@ -18,9 +18,8 @@ config HAVE_ARCH_BITREVERSE | |||
| 18 | default n | 18 | default n |
| 19 | depends on BITREVERSE | 19 | depends on BITREVERSE |
| 20 | help | 20 | help |
| 21 | This option provides an config for the architecture which have instruction | 21 | This option enables the use of hardware bit-reversal instructions on |
| 22 | can do bitreverse operation, we use the hardware instruction if the architecture | 22 | architectures which support such operations. |
| 23 | have this capability. | ||
| 24 | 23 | ||
| 25 | config RATIONAL | 24 | config RATIONAL |
| 26 | bool | 25 | bool |
diff --git a/lib/Makefile b/lib/Makefile index 58f74d2dd396..da6116b21555 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
| @@ -25,7 +25,7 @@ obj-y += lockref.o | |||
| 25 | obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ | 25 | obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ |
| 26 | bust_spinlocks.o kasprintf.o bitmap.o scatterlist.o \ | 26 | bust_spinlocks.o kasprintf.o bitmap.o scatterlist.o \ |
| 27 | gcd.o lcm.o list_sort.o uuid.o flex_array.o iov_iter.o clz_ctz.o \ | 27 | gcd.o lcm.o list_sort.o uuid.o flex_array.o iov_iter.o clz_ctz.o \ |
| 28 | bsearch.o find_last_bit.o find_next_bit.o llist.o memweight.o kfifo.o \ | 28 | bsearch.o find_bit.o llist.o memweight.o kfifo.o \ |
| 29 | percpu-refcount.o percpu_ida.o rhashtable.o reciprocal_div.o | 29 | percpu-refcount.o percpu_ida.o rhashtable.o reciprocal_div.o |
| 30 | obj-y += string_helpers.o | 30 | obj-y += string_helpers.o |
| 31 | obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o | 31 | obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o |
diff --git a/lib/bitmap.c b/lib/bitmap.c index d456f4c15a9f..64c0926f5dd8 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c | |||
| @@ -42,36 +42,6 @@ | |||
| 42 | * for the best explanations of this ordering. | 42 | * for the best explanations of this ordering. |
| 43 | */ | 43 | */ |
| 44 | 44 | ||
| 45 | int __bitmap_empty(const unsigned long *bitmap, unsigned int bits) | ||
| 46 | { | ||
| 47 | unsigned int k, lim = bits/BITS_PER_LONG; | ||
| 48 | for (k = 0; k < lim; ++k) | ||
| 49 | if (bitmap[k]) | ||
| 50 | return 0; | ||
| 51 | |||
| 52 | if (bits % BITS_PER_LONG) | ||
| 53 | if (bitmap[k] & BITMAP_LAST_WORD_MASK(bits)) | ||
| 54 | return 0; | ||
| 55 | |||
| 56 | return 1; | ||
| 57 | } | ||
| 58 | EXPORT_SYMBOL(__bitmap_empty); | ||
| 59 | |||
| 60 | int __bitmap_full(const unsigned long *bitmap, unsigned int bits) | ||
| 61 | { | ||
| 62 | unsigned int k, lim = bits/BITS_PER_LONG; | ||
| 63 | for (k = 0; k < lim; ++k) | ||
| 64 | if (~bitmap[k]) | ||
| 65 | return 0; | ||
| 66 | |||
| 67 | if (bits % BITS_PER_LONG) | ||
| 68 | if (~bitmap[k] & BITMAP_LAST_WORD_MASK(bits)) | ||
| 69 | return 0; | ||
| 70 | |||
| 71 | return 1; | ||
| 72 | } | ||
| 73 | EXPORT_SYMBOL(__bitmap_full); | ||
| 74 | |||
| 75 | int __bitmap_equal(const unsigned long *bitmap1, | 45 | int __bitmap_equal(const unsigned long *bitmap1, |
| 76 | const unsigned long *bitmap2, unsigned int bits) | 46 | const unsigned long *bitmap2, unsigned int bits) |
| 77 | { | 47 | { |
diff --git a/lib/cpumask.c b/lib/cpumask.c index b6513a9f2892..5ab1553fd076 100644 --- a/lib/cpumask.c +++ b/lib/cpumask.c | |||
| @@ -37,10 +37,11 @@ EXPORT_SYMBOL(__next_cpu_nr); | |||
| 37 | int cpumask_next_and(int n, const struct cpumask *src1p, | 37 | int cpumask_next_and(int n, const struct cpumask *src1p, |
| 38 | const struct cpumask *src2p) | 38 | const struct cpumask *src2p) |
| 39 | { | 39 | { |
| 40 | while ((n = cpumask_next(n, src1p)) < nr_cpu_ids) | 40 | struct cpumask tmp; |
| 41 | if (cpumask_test_cpu(n, src2p)) | 41 | |
| 42 | break; | 42 | if (cpumask_and(&tmp, src1p, src2p)) |
| 43 | return n; | 43 | return cpumask_next(n, &tmp); |
| 44 | return nr_cpu_ids; | ||
| 44 | } | 45 | } |
| 45 | EXPORT_SYMBOL(cpumask_next_and); | 46 | EXPORT_SYMBOL(cpumask_next_and); |
| 46 | 47 | ||
diff --git a/lib/dma-debug.c b/lib/dma-debug.c index 9722bd2dbc9b..ae4b65e17e64 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c | |||
| @@ -361,7 +361,7 @@ static struct dma_debug_entry *bucket_find_contain(struct hash_bucket **bucket, | |||
| 361 | unsigned int range = 0; | 361 | unsigned int range = 0; |
| 362 | 362 | ||
| 363 | while (range <= max_range) { | 363 | while (range <= max_range) { |
| 364 | entry = __hash_bucket_find(*bucket, &index, containing_match); | 364 | entry = __hash_bucket_find(*bucket, ref, containing_match); |
| 365 | 365 | ||
| 366 | if (entry) | 366 | if (entry) |
| 367 | return entry; | 367 | return entry; |
diff --git a/lib/find_bit.c b/lib/find_bit.c new file mode 100644 index 000000000000..18072ea9c20e --- /dev/null +++ b/lib/find_bit.c | |||
| @@ -0,0 +1,193 @@ | |||
| 1 | /* bit search implementation | ||
| 2 | * | ||
| 3 | * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. | ||
| 4 | * Written by David Howells (dhowells@redhat.com) | ||
| 5 | * | ||
| 6 | * Copyright (C) 2008 IBM Corporation | ||
| 7 | * 'find_last_bit' is written by Rusty Russell <rusty@rustcorp.com.au> | ||
| 8 | * (Inspired by David Howell's find_next_bit implementation) | ||
| 9 | * | ||
| 10 | * Rewritten by Yury Norov <yury.norov@gmail.com> to decrease | ||
| 11 | * size and improve performance, 2015. | ||
| 12 | * | ||
| 13 | * This program is free software; you can redistribute it and/or | ||
| 14 | * modify it under the terms of the GNU General Public License | ||
| 15 | * as published by the Free Software Foundation; either version | ||
| 16 | * 2 of the License, or (at your option) any later version. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/bitops.h> | ||
| 20 | #include <linux/bitmap.h> | ||
| 21 | #include <linux/export.h> | ||
| 22 | #include <linux/kernel.h> | ||
| 23 | |||
| 24 | #if !defined(find_next_bit) || !defined(find_next_zero_bit) | ||
| 25 | |||
| 26 | /* | ||
| 27 | * This is a common helper function for find_next_bit and | ||
| 28 | * find_next_zero_bit. The difference is the "invert" argument, which | ||
| 29 | * is XORed with each fetched word before searching it for one bits. | ||
| 30 | */ | ||
| 31 | static unsigned long _find_next_bit(const unsigned long *addr, | ||
| 32 | unsigned long nbits, unsigned long start, unsigned long invert) | ||
| 33 | { | ||
| 34 | unsigned long tmp; | ||
| 35 | |||
| 36 | if (!nbits || start >= nbits) | ||
| 37 | return nbits; | ||
| 38 | |||
| 39 | tmp = addr[start / BITS_PER_LONG] ^ invert; | ||
| 40 | |||
| 41 | /* Handle 1st word. */ | ||
| 42 | tmp &= BITMAP_FIRST_WORD_MASK(start); | ||
| 43 | start = round_down(start, BITS_PER_LONG); | ||
| 44 | |||
| 45 | while (!tmp) { | ||
| 46 | start += BITS_PER_LONG; | ||
| 47 | if (start >= nbits) | ||
| 48 | return nbits; | ||
| 49 | |||
| 50 | tmp = addr[start / BITS_PER_LONG] ^ invert; | ||
| 51 | } | ||
| 52 | |||
| 53 | return min(start + __ffs(tmp), nbits); | ||
| 54 | } | ||
| 55 | #endif | ||
| 56 | |||
| 57 | #ifndef find_next_bit | ||
| 58 | /* | ||
| 59 | * Find the next set bit in a memory region. | ||
| 60 | */ | ||
| 61 | unsigned long find_next_bit(const unsigned long *addr, unsigned long size, | ||
| 62 | unsigned long offset) | ||
| 63 | { | ||
| 64 | return _find_next_bit(addr, size, offset, 0UL); | ||
| 65 | } | ||
| 66 | EXPORT_SYMBOL(find_next_bit); | ||
| 67 | #endif | ||
| 68 | |||
| 69 | #ifndef find_next_zero_bit | ||
| 70 | unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, | ||
| 71 | unsigned long offset) | ||
| 72 | { | ||
| 73 | return _find_next_bit(addr, size, offset, ~0UL); | ||
| 74 | } | ||
| 75 | EXPORT_SYMBOL(find_next_zero_bit); | ||
| 76 | #endif | ||
| 77 | |||
| 78 | #ifndef find_first_bit | ||
| 79 | /* | ||
| 80 | * Find the first set bit in a memory region. | ||
| 81 | */ | ||
| 82 | unsigned long find_first_bit(const unsigned long *addr, unsigned long size) | ||
| 83 | { | ||
| 84 | unsigned long idx; | ||
| 85 | |||
| 86 | for (idx = 0; idx * BITS_PER_LONG < size; idx++) { | ||
| 87 | if (addr[idx]) | ||
| 88 | return min(idx * BITS_PER_LONG + __ffs(addr[idx]), size); | ||
| 89 | } | ||
| 90 | |||
| 91 | return size; | ||
| 92 | } | ||
| 93 | EXPORT_SYMBOL(find_first_bit); | ||
| 94 | #endif | ||
| 95 | |||
| 96 | #ifndef find_first_zero_bit | ||
| 97 | /* | ||
| 98 | * Find the first cleared bit in a memory region. | ||
| 99 | */ | ||
| 100 | unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size) | ||
| 101 | { | ||
| 102 | unsigned long idx; | ||
| 103 | |||
| 104 | for (idx = 0; idx * BITS_PER_LONG < size; idx++) { | ||
| 105 | if (addr[idx] != ~0UL) | ||
| 106 | return min(idx * BITS_PER_LONG + ffz(addr[idx]), size); | ||
| 107 | } | ||
| 108 | |||
| 109 | return size; | ||
| 110 | } | ||
| 111 | EXPORT_SYMBOL(find_first_zero_bit); | ||
| 112 | #endif | ||
| 113 | |||
| 114 | #ifndef find_last_bit | ||
| 115 | unsigned long find_last_bit(const unsigned long *addr, unsigned long size) | ||
| 116 | { | ||
| 117 | if (size) { | ||
| 118 | unsigned long val = BITMAP_LAST_WORD_MASK(size); | ||
| 119 | unsigned long idx = (size-1) / BITS_PER_LONG; | ||
| 120 | |||
| 121 | do { | ||
| 122 | val &= addr[idx]; | ||
| 123 | if (val) | ||
| 124 | return idx * BITS_PER_LONG + __fls(val); | ||
| 125 | |||
| 126 | val = ~0ul; | ||
| 127 | } while (idx--); | ||
| 128 | } | ||
| 129 | return size; | ||
| 130 | } | ||
| 131 | EXPORT_SYMBOL(find_last_bit); | ||
| 132 | #endif | ||
| 133 | |||
| 134 | #ifdef __BIG_ENDIAN | ||
| 135 | |||
| 136 | /* include/linux/byteorder does not support "unsigned long" type */ | ||
| 137 | static inline unsigned long ext2_swab(const unsigned long y) | ||
| 138 | { | ||
| 139 | #if BITS_PER_LONG == 64 | ||
| 140 | return (unsigned long) __swab64((u64) y); | ||
| 141 | #elif BITS_PER_LONG == 32 | ||
| 142 | return (unsigned long) __swab32((u32) y); | ||
| 143 | #else | ||
| 144 | #error BITS_PER_LONG not defined | ||
| 145 | #endif | ||
| 146 | } | ||
| 147 | |||
| 148 | #if !defined(find_next_bit_le) || !defined(find_next_zero_bit_le) | ||
| 149 | static unsigned long _find_next_bit_le(const unsigned long *addr, | ||
| 150 | unsigned long nbits, unsigned long start, unsigned long invert) | ||
| 151 | { | ||
| 152 | unsigned long tmp; | ||
| 153 | |||
| 154 | if (!nbits || start >= nbits) | ||
| 155 | return nbits; | ||
| 156 | |||
| 157 | tmp = addr[start / BITS_PER_LONG] ^ invert; | ||
| 158 | |||
| 159 | /* Handle 1st word. */ | ||
| 160 | tmp &= ext2_swab(BITMAP_FIRST_WORD_MASK(start)); | ||
| 161 | start = round_down(start, BITS_PER_LONG); | ||
| 162 | |||
| 163 | while (!tmp) { | ||
| 164 | start += BITS_PER_LONG; | ||
| 165 | if (start >= nbits) | ||
| 166 | return nbits; | ||
| 167 | |||
| 168 | tmp = addr[start / BITS_PER_LONG] ^ invert; | ||
| 169 | } | ||
| 170 | |||
| 171 | return min(start + __ffs(ext2_swab(tmp)), nbits); | ||
| 172 | } | ||
| 173 | #endif | ||
| 174 | |||
| 175 | #ifndef find_next_zero_bit_le | ||
| 176 | unsigned long find_next_zero_bit_le(const void *addr, unsigned | ||
| 177 | long size, unsigned long offset) | ||
| 178 | { | ||
| 179 | return _find_next_bit_le(addr, size, offset, ~0UL); | ||
| 180 | } | ||
| 181 | EXPORT_SYMBOL(find_next_zero_bit_le); | ||
| 182 | #endif | ||
| 183 | |||
| 184 | #ifndef find_next_bit_le | ||
| 185 | unsigned long find_next_bit_le(const void *addr, unsigned | ||
| 186 | long size, unsigned long offset) | ||
| 187 | { | ||
| 188 | return _find_next_bit_le(addr, size, offset, 0UL); | ||
| 189 | } | ||
| 190 | EXPORT_SYMBOL(find_next_bit_le); | ||
| 191 | #endif | ||
| 192 | |||
| 193 | #endif /* __BIG_ENDIAN */ | ||
diff --git a/lib/find_last_bit.c b/lib/find_last_bit.c index 91ca09fbf6f9..3e3be40c6a6e 100644 --- a/lib/find_last_bit.c +++ b/lib/find_last_bit.c | |||
| @@ -4,6 +4,9 @@ | |||
| 4 | * Written by Rusty Russell <rusty@rustcorp.com.au> | 4 | * Written by Rusty Russell <rusty@rustcorp.com.au> |
| 5 | * (Inspired by David Howell's find_next_bit implementation) | 5 | * (Inspired by David Howell's find_next_bit implementation) |
| 6 | * | 6 | * |
| 7 | * Rewritten by Yury Norov <yury.norov@gmail.com> to decrease | ||
| 8 | * size and improve performance, 2015. | ||
| 9 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | 10 | * This program is free software; you can redistribute it and/or |
| 8 | * modify it under the terms of the GNU General Public License | 11 | * modify it under the terms of the GNU General Public License |
| 9 | * as published by the Free Software Foundation; either version | 12 | * as published by the Free Software Foundation; either version |
| @@ -11,37 +14,26 @@ | |||
| 11 | */ | 14 | */ |
| 12 | 15 | ||
| 13 | #include <linux/bitops.h> | 16 | #include <linux/bitops.h> |
| 17 | #include <linux/bitmap.h> | ||
| 14 | #include <linux/export.h> | 18 | #include <linux/export.h> |
| 15 | #include <asm/types.h> | 19 | #include <linux/kernel.h> |
| 16 | #include <asm/byteorder.h> | ||
| 17 | 20 | ||
| 18 | #ifndef find_last_bit | 21 | #ifndef find_last_bit |
| 19 | 22 | ||
| 20 | unsigned long find_last_bit(const unsigned long *addr, unsigned long size) | 23 | unsigned long find_last_bit(const unsigned long *addr, unsigned long size) |
| 21 | { | 24 | { |
| 22 | unsigned long words; | 25 | if (size) { |
| 23 | unsigned long tmp; | 26 | unsigned long val = BITMAP_LAST_WORD_MASK(size); |
| 24 | 27 | unsigned long idx = (size-1) / BITS_PER_LONG; | |
| 25 | /* Start at final word. */ | ||
| 26 | words = size / BITS_PER_LONG; | ||
| 27 | 28 | ||
| 28 | /* Partial final word? */ | 29 | do { |
| 29 | if (size & (BITS_PER_LONG-1)) { | 30 | val &= addr[idx]; |
| 30 | tmp = (addr[words] & (~0UL >> (BITS_PER_LONG | 31 | if (val) |
| 31 | - (size & (BITS_PER_LONG-1))))); | 32 | return idx * BITS_PER_LONG + __fls(val); |
| 32 | if (tmp) | ||
| 33 | goto found; | ||
| 34 | } | ||
| 35 | 33 | ||
| 36 | while (words) { | 34 | val = ~0ul; |
| 37 | tmp = addr[--words]; | 35 | } while (idx--); |
| 38 | if (tmp) { | ||
| 39 | found: | ||
| 40 | return words * BITS_PER_LONG + __fls(tmp); | ||
| 41 | } | ||
| 42 | } | 36 | } |
| 43 | |||
| 44 | /* Not found */ | ||
| 45 | return size; | 37 | return size; |
| 46 | } | 38 | } |
| 47 | EXPORT_SYMBOL(find_last_bit); | 39 | EXPORT_SYMBOL(find_last_bit); |
diff --git a/lib/find_next_bit.c b/lib/find_next_bit.c deleted file mode 100644 index 0cbfc0b4398f..000000000000 --- a/lib/find_next_bit.c +++ /dev/null | |||
| @@ -1,285 +0,0 @@ | |||
| 1 | /* find_next_bit.c: fallback find next bit implementation | ||
| 2 | * | ||
| 3 | * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. | ||
| 4 | * Written by David Howells (dhowells@redhat.com) | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation; either version | ||
| 9 | * 2 of the License, or (at your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/bitops.h> | ||
| 13 | #include <linux/export.h> | ||
| 14 | #include <asm/types.h> | ||
| 15 | #include <asm/byteorder.h> | ||
| 16 | |||
| 17 | #define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) | ||
| 18 | |||
| 19 | #ifndef find_next_bit | ||
| 20 | /* | ||
| 21 | * Find the next set bit in a memory region. | ||
| 22 | */ | ||
| 23 | unsigned long find_next_bit(const unsigned long *addr, unsigned long size, | ||
| 24 | unsigned long offset) | ||
| 25 | { | ||
| 26 | const unsigned long *p = addr + BITOP_WORD(offset); | ||
| 27 | unsigned long result = offset & ~(BITS_PER_LONG-1); | ||
| 28 | unsigned long tmp; | ||
| 29 | |||
| 30 | if (offset >= size) | ||
| 31 | return size; | ||
| 32 | size -= result; | ||
| 33 | offset %= BITS_PER_LONG; | ||
| 34 | if (offset) { | ||
| 35 | tmp = *(p++); | ||
| 36 | tmp &= (~0UL << offset); | ||
| 37 | if (size < BITS_PER_LONG) | ||
| 38 | goto found_first; | ||
| 39 | if (tmp) | ||
| 40 | goto found_middle; | ||
| 41 | size -= BITS_PER_LONG; | ||
| 42 | result += BITS_PER_LONG; | ||
| 43 | } | ||
| 44 | while (size & ~(BITS_PER_LONG-1)) { | ||
| 45 | if ((tmp = *(p++))) | ||
| 46 | goto found_middle; | ||
| 47 | result += BITS_PER_LONG; | ||
| 48 | size -= BITS_PER_LONG; | ||
| 49 | } | ||
| 50 | if (!size) | ||
| 51 | return result; | ||
| 52 | tmp = *p; | ||
| 53 | |||
| 54 | found_first: | ||
| 55 | tmp &= (~0UL >> (BITS_PER_LONG - size)); | ||
| 56 | if (tmp == 0UL) /* Are any bits set? */ | ||
| 57 | return result + size; /* Nope. */ | ||
| 58 | found_middle: | ||
| 59 | return result + __ffs(tmp); | ||
| 60 | } | ||
| 61 | EXPORT_SYMBOL(find_next_bit); | ||
| 62 | #endif | ||
| 63 | |||
| 64 | #ifndef find_next_zero_bit | ||
| 65 | /* | ||
| 66 | * This implementation of find_{first,next}_zero_bit was stolen from | ||
| 67 | * Linus' asm-alpha/bitops.h. | ||
| 68 | */ | ||
| 69 | unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, | ||
| 70 | unsigned long offset) | ||
| 71 | { | ||
| 72 | const unsigned long *p = addr + BITOP_WORD(offset); | ||
| 73 | unsigned long result = offset & ~(BITS_PER_LONG-1); | ||
| 74 | unsigned long tmp; | ||
| 75 | |||
| 76 | if (offset >= size) | ||
| 77 | return size; | ||
| 78 | size -= result; | ||
| 79 | offset %= BITS_PER_LONG; | ||
| 80 | if (offset) { | ||
| 81 | tmp = *(p++); | ||
| 82 | tmp |= ~0UL >> (BITS_PER_LONG - offset); | ||
| 83 | if (size < BITS_PER_LONG) | ||
| 84 | goto found_first; | ||
| 85 | if (~tmp) | ||
| 86 | goto found_middle; | ||
| 87 | size -= BITS_PER_LONG; | ||
| 88 | result += BITS_PER_LONG; | ||
| 89 | } | ||
| 90 | while (size & ~(BITS_PER_LONG-1)) { | ||
| 91 | if (~(tmp = *(p++))) | ||
| 92 | goto found_middle; | ||
| 93 | result += BITS_PER_LONG; | ||
| 94 | size -= BITS_PER_LONG; | ||
| 95 | } | ||
| 96 | if (!size) | ||
| 97 | return result; | ||
| 98 | tmp = *p; | ||
| 99 | |||
| 100 | found_first: | ||
| 101 | tmp |= ~0UL << size; | ||
| 102 | if (tmp == ~0UL) /* Are any bits zero? */ | ||
| 103 | return result + size; /* Nope. */ | ||
| 104 | found_middle: | ||
| 105 | return result + ffz(tmp); | ||
| 106 | } | ||
| 107 | EXPORT_SYMBOL(find_next_zero_bit); | ||
| 108 | #endif | ||
| 109 | |||
| 110 | #ifndef find_first_bit | ||
| 111 | /* | ||
| 112 | * Find the first set bit in a memory region. | ||
| 113 | */ | ||
| 114 | unsigned long find_first_bit(const unsigned long *addr, unsigned long size) | ||
| 115 | { | ||
| 116 | const unsigned long *p = addr; | ||
| 117 | unsigned long result = 0; | ||
| 118 | unsigned long tmp; | ||
| 119 | |||
| 120 | while (size & ~(BITS_PER_LONG-1)) { | ||
| 121 | if ((tmp = *(p++))) | ||
| 122 | goto found; | ||
| 123 | result += BITS_PER_LONG; | ||
| 124 | size -= BITS_PER_LONG; | ||
| 125 | } | ||
| 126 | if (!size) | ||
| 127 | return result; | ||
| 128 | |||
| 129 | tmp = (*p) & (~0UL >> (BITS_PER_LONG - size)); | ||
| 130 | if (tmp == 0UL) /* Are any bits set? */ | ||
| 131 | return result + size; /* Nope. */ | ||
| 132 | found: | ||
| 133 | return result + __ffs(tmp); | ||
| 134 | } | ||
| 135 | EXPORT_SYMBOL(find_first_bit); | ||
| 136 | #endif | ||
| 137 | |||
| 138 | #ifndef find_first_zero_bit | ||
| 139 | /* | ||
| 140 | * Find the first cleared bit in a memory region. | ||
| 141 | */ | ||
| 142 | unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size) | ||
| 143 | { | ||
| 144 | const unsigned long *p = addr; | ||
| 145 | unsigned long result = 0; | ||
| 146 | unsigned long tmp; | ||
| 147 | |||
| 148 | while (size & ~(BITS_PER_LONG-1)) { | ||
| 149 | if (~(tmp = *(p++))) | ||
| 150 | goto found; | ||
| 151 | result += BITS_PER_LONG; | ||
| 152 | size -= BITS_PER_LONG; | ||
| 153 | } | ||
| 154 | if (!size) | ||
| 155 | return result; | ||
| 156 | |||
| 157 | tmp = (*p) | (~0UL << size); | ||
| 158 | if (tmp == ~0UL) /* Are any bits zero? */ | ||
| 159 | return result + size; /* Nope. */ | ||
| 160 | found: | ||
| 161 | return result + ffz(tmp); | ||
| 162 | } | ||
| 163 | EXPORT_SYMBOL(find_first_zero_bit); | ||
| 164 | #endif | ||
| 165 | |||
| 166 | #ifdef __BIG_ENDIAN | ||
| 167 | |||
| 168 | /* include/linux/byteorder does not support "unsigned long" type */ | ||
| 169 | static inline unsigned long ext2_swabp(const unsigned long * x) | ||
| 170 | { | ||
| 171 | #if BITS_PER_LONG == 64 | ||
| 172 | return (unsigned long) __swab64p((u64 *) x); | ||
| 173 | #elif BITS_PER_LONG == 32 | ||
| 174 | return (unsigned long) __swab32p((u32 *) x); | ||
| 175 | #else | ||
| 176 | #error BITS_PER_LONG not defined | ||
| 177 | #endif | ||
| 178 | } | ||
| 179 | |||
| 180 | /* include/linux/byteorder doesn't support "unsigned long" type */ | ||
| 181 | static inline unsigned long ext2_swab(const unsigned long y) | ||
| 182 | { | ||
| 183 | #if BITS_PER_LONG == 64 | ||
| 184 | return (unsigned long) __swab64((u64) y); | ||
| 185 | #elif BITS_PER_LONG == 32 | ||
| 186 | return (unsigned long) __swab32((u32) y); | ||
| 187 | #else | ||
| 188 | #error BITS_PER_LONG not defined | ||
| 189 | #endif | ||
| 190 | } | ||
| 191 | |||
| 192 | #ifndef find_next_zero_bit_le | ||
| 193 | unsigned long find_next_zero_bit_le(const void *addr, unsigned | ||
| 194 | long size, unsigned long offset) | ||
| 195 | { | ||
| 196 | const unsigned long *p = addr; | ||
| 197 | unsigned long result = offset & ~(BITS_PER_LONG - 1); | ||
| 198 | unsigned long tmp; | ||
| 199 | |||
| 200 | if (offset >= size) | ||
| 201 | return size; | ||
| 202 | p += BITOP_WORD(offset); | ||
| 203 | size -= result; | ||
| 204 | offset &= (BITS_PER_LONG - 1UL); | ||
| 205 | if (offset) { | ||
| 206 | tmp = ext2_swabp(p++); | ||
| 207 | tmp |= (~0UL >> (BITS_PER_LONG - offset)); | ||
| 208 | if (size < BITS_PER_LONG) | ||
| 209 | goto found_first; | ||
| 210 | if (~tmp) | ||
| 211 | goto found_middle; | ||
| 212 | size -= BITS_PER_LONG; | ||
| 213 | result += BITS_PER_LONG; | ||
| 214 | } | ||
| 215 | |||
| 216 | while (size & ~(BITS_PER_LONG - 1)) { | ||
| 217 | if (~(tmp = *(p++))) | ||
| 218 | goto found_middle_swap; | ||
| 219 | result += BITS_PER_LONG; | ||
| 220 | size -= BITS_PER_LONG; | ||
| 221 | } | ||
| 222 | if (!size) | ||
| 223 | return result; | ||
| 224 | tmp = ext2_swabp(p); | ||
| 225 | found_first: | ||
| 226 | tmp |= ~0UL << size; | ||
| 227 | if (tmp == ~0UL) /* Are any bits zero? */ | ||
| 228 | return result + size; /* Nope. Skip ffz */ | ||
| 229 | found_middle: | ||
| 230 | return result + ffz(tmp); | ||
| 231 | |||
| 232 | found_middle_swap: | ||
| 233 | return result + ffz(ext2_swab(tmp)); | ||
| 234 | } | ||
| 235 | EXPORT_SYMBOL(find_next_zero_bit_le); | ||
| 236 | #endif | ||
| 237 | |||
| 238 | #ifndef find_next_bit_le | ||
| 239 | unsigned long find_next_bit_le(const void *addr, unsigned | ||
| 240 | long size, unsigned long offset) | ||
| 241 | { | ||
| 242 | const unsigned long *p = addr; | ||
| 243 | unsigned long result = offset & ~(BITS_PER_LONG - 1); | ||
| 244 | unsigned long tmp; | ||
| 245 | |||
| 246 | if (offset >= size) | ||
| 247 | return size; | ||
| 248 | p += BITOP_WORD(offset); | ||
| 249 | size -= result; | ||
| 250 | offset &= (BITS_PER_LONG - 1UL); | ||
| 251 | if (offset) { | ||
| 252 | tmp = ext2_swabp(p++); | ||
| 253 | tmp &= (~0UL << offset); | ||
| 254 | if (size < BITS_PER_LONG) | ||
| 255 | goto found_first; | ||
| 256 | if (tmp) | ||
| 257 | goto found_middle; | ||
| 258 | size -= BITS_PER_LONG; | ||
| 259 | result += BITS_PER_LONG; | ||
| 260 | } | ||
| 261 | |||
| 262 | while (size & ~(BITS_PER_LONG - 1)) { | ||
| 263 | tmp = *(p++); | ||
| 264 | if (tmp) | ||
| 265 | goto found_middle_swap; | ||
| 266 | result += BITS_PER_LONG; | ||
| 267 | size -= BITS_PER_LONG; | ||
| 268 | } | ||
| 269 | if (!size) | ||
| 270 | return result; | ||
| 271 | tmp = ext2_swabp(p); | ||
| 272 | found_first: | ||
| 273 | tmp &= (~0UL >> (BITS_PER_LONG - size)); | ||
| 274 | if (tmp == 0UL) /* Are any bits set? */ | ||
| 275 | return result + size; /* Nope. */ | ||
| 276 | found_middle: | ||
| 277 | return result + __ffs(tmp); | ||
| 278 | |||
| 279 | found_middle_swap: | ||
| 280 | return result + __ffs(ext2_swab(tmp)); | ||
| 281 | } | ||
| 282 | EXPORT_SYMBOL(find_next_bit_le); | ||
| 283 | #endif | ||
| 284 | |||
| 285 | #endif /* __BIG_ENDIAN */ | ||
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 3a1e0843f9a2..da39c608a28c 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | 33 | ||
| 34 | #include <asm/page.h> /* for PAGE_SIZE */ | 34 | #include <asm/page.h> /* for PAGE_SIZE */ |
| 35 | #include <asm/sections.h> /* for dereference_function_descriptor() */ | 35 | #include <asm/sections.h> /* for dereference_function_descriptor() */ |
| 36 | #include <asm/byteorder.h> /* cpu_to_le16 */ | ||
| 36 | 37 | ||
| 37 | #include <linux/string_helpers.h> | 38 | #include <linux/string_helpers.h> |
| 38 | #include "kstrtox.h" | 39 | #include "kstrtox.h" |
| @@ -122,142 +123,145 @@ int skip_atoi(const char **s) | |||
| 122 | return i; | 123 | return i; |
| 123 | } | 124 | } |
| 124 | 125 | ||
| 125 | /* Decimal conversion is by far the most typical, and is used | 126 | /* |
| 126 | * for /proc and /sys data. This directly impacts e.g. top performance | 127 | * Decimal conversion is by far the most typical, and is used for |
| 127 | * with many processes running. We optimize it for speed | 128 | * /proc and /sys data. This directly impacts e.g. top performance |
| 128 | * using ideas described at <http://www.cs.uiowa.edu/~jones/bcd/divide.html> | 129 | * with many processes running. We optimize it for speed by emitting |
| 129 | * (with permission from the author, Douglas W. Jones). | 130 | * two characters at a time, using a 200 byte lookup table. This |
| 131 | * roughly halves the number of multiplications compared to computing | ||
| 132 | * the digits one at a time. Implementation strongly inspired by the | ||
| 133 | * previous version, which in turn used ideas described at | ||
| 134 | * <http://www.cs.uiowa.edu/~jones/bcd/divide.html> (with permission | ||
| 135 | * from the author, Douglas W. Jones). | ||
| 136 | * | ||
| 137 | * It turns out there is precisely one 26 bit fixed-point | ||
| 138 | * approximation a of 64/100 for which x/100 == (x * (u64)a) >> 32 | ||
| 139 | * holds for all x in [0, 10^8-1], namely a = 0x28f5c29. The actual | ||
| 140 | * range happens to be somewhat larger (x <= 1073741898), but that's | ||
| 141 | * irrelevant for our purpose. | ||
| 142 | * | ||
| 143 | * For dividing a number in the range [10^4, 10^6-1] by 100, we still | ||
| 144 | * need a 32x32->64 bit multiply, so we simply use the same constant. | ||
| 145 | * | ||
| 146 | * For dividing a number in the range [100, 10^4-1] by 100, there are | ||
| 147 | * several options. The simplest is (x * 0x147b) >> 19, which is valid | ||
| 148 | * for all x <= 43698. | ||
| 130 | */ | 149 | */ |
| 131 | 150 | ||
| 132 | #if BITS_PER_LONG != 32 || BITS_PER_LONG_LONG != 64 | 151 | static const u16 decpair[100] = { |
| 133 | /* Formats correctly any integer in [0, 999999999] */ | 152 | #define _(x) (__force u16) cpu_to_le16(((x % 10) | ((x / 10) << 8)) + 0x3030) |
| 153 | _( 0), _( 1), _( 2), _( 3), _( 4), _( 5), _( 6), _( 7), _( 8), _( 9), | ||
| 154 | _(10), _(11), _(12), _(13), _(14), _(15), _(16), _(17), _(18), _(19), | ||
| 155 | _(20), _(21), _(22), _(23), _(24), _(25), _(26), _(27), _(28), _(29), | ||
| 156 | _(30), _(31), _(32), _(33), _(34), _(35), _(36), _(37), _(38), _(39), | ||
| 157 | _(40), _(41), _(42), _(43), _(44), _(45), _(46), _(47), _(48), _(49), | ||
| 158 | _(50), _(51), _(52), _(53), _(54), _(55), _(56), _(57), _(58), _(59), | ||
| 159 | _(60), _(61), _(62), _(63), _(64), _(65), _(66), _(67), _(68), _(69), | ||
| 160 | _(70), _(71), _(72), _(73), _(74), _(75), _(76), _(77), _(78), _(79), | ||
| 161 | _(80), _(81), _(82), _(83), _(84), _(85), _(86), _(87), _(88), _(89), | ||
| 162 | _(90), _(91), _(92), _(93), _(94), _(95), _(96), _(97), _(98), _(99), | ||
| 163 | #undef _ | ||
| 164 | }; | ||
| 165 | |||
| 166 | /* | ||
| 167 | * This will print a single '0' even if r == 0, since we would | ||
| 168 | * immediately jump to out_r where two 0s would be written but only | ||
| 169 | * one of them accounted for in buf. This is needed by ip4_string | ||
| 170 | * below. All other callers pass a non-zero value of r. | ||
| 171 | */ | ||
| 134 | static noinline_for_stack | 172 | static noinline_for_stack |
| 135 | char *put_dec_full9(char *buf, unsigned q) | 173 | char *put_dec_trunc8(char *buf, unsigned r) |
| 136 | { | 174 | { |
| 137 | unsigned r; | 175 | unsigned q; |
| 138 | 176 | ||
| 139 | /* | 177 | /* 1 <= r < 10^8 */ |
| 140 | * Possible ways to approx. divide by 10 | 178 | if (r < 100) |
| 141 | * (x * 0x1999999a) >> 32 x < 1073741829 (multiply must be 64-bit) | 179 | goto out_r; |
| 142 | * (x * 0xcccd) >> 19 x < 81920 (x < 262149 when 64-bit mul) | 180 | |
| 143 | * (x * 0x6667) >> 18 x < 43699 | 181 | /* 100 <= r < 10^8 */ |
| 144 | * (x * 0x3334) >> 17 x < 16389 | 182 | q = (r * (u64)0x28f5c29) >> 32; |
| 145 | * (x * 0x199a) >> 16 x < 16389 | 183 | *((u16 *)buf) = decpair[r - 100*q]; |
| 146 | * (x * 0x0ccd) >> 15 x < 16389 | 184 | buf += 2; |
| 147 | * (x * 0x0667) >> 14 x < 2739 | 185 | |
| 148 | * (x * 0x0334) >> 13 x < 1029 | 186 | /* 1 <= q < 10^6 */ |
| 149 | * (x * 0x019a) >> 12 x < 1029 | 187 | if (q < 100) |
| 150 | * (x * 0x00cd) >> 11 x < 1029 shorter code than * 0x67 (on i386) | 188 | goto out_q; |
| 151 | * (x * 0x0067) >> 10 x < 179 | 189 | |
| 152 | * (x * 0x0034) >> 9 x < 69 same | 190 | /* 100 <= q < 10^6 */ |
| 153 | * (x * 0x001a) >> 8 x < 69 same | 191 | r = (q * (u64)0x28f5c29) >> 32; |
| 154 | * (x * 0x000d) >> 7 x < 69 same, shortest code (on i386) | 192 | *((u16 *)buf) = decpair[q - 100*r]; |
| 155 | * (x * 0x0007) >> 6 x < 19 | 193 | buf += 2; |
| 156 | * See <http://www.cs.uiowa.edu/~jones/bcd/divide.html> | 194 | |
| 157 | */ | 195 | /* 1 <= r < 10^4 */ |
| 158 | r = (q * (uint64_t)0x1999999a) >> 32; | 196 | if (r < 100) |
| 159 | *buf++ = (q - 10 * r) + '0'; /* 1 */ | 197 | goto out_r; |
| 160 | q = (r * (uint64_t)0x1999999a) >> 32; | 198 | |
| 161 | *buf++ = (r - 10 * q) + '0'; /* 2 */ | 199 | /* 100 <= r < 10^4 */ |
| 162 | r = (q * (uint64_t)0x1999999a) >> 32; | 200 | q = (r * 0x147b) >> 19; |
| 163 | *buf++ = (q - 10 * r) + '0'; /* 3 */ | 201 | *((u16 *)buf) = decpair[r - 100*q]; |
| 164 | q = (r * (uint64_t)0x1999999a) >> 32; | 202 | buf += 2; |
| 165 | *buf++ = (r - 10 * q) + '0'; /* 4 */ | 203 | out_q: |
| 166 | r = (q * (uint64_t)0x1999999a) >> 32; | 204 | /* 1 <= q < 100 */ |
| 167 | *buf++ = (q - 10 * r) + '0'; /* 5 */ | 205 | r = q; |
| 168 | /* Now value is under 10000, can avoid 64-bit multiply */ | 206 | out_r: |
| 169 | q = (r * 0x199a) >> 16; | 207 | /* 1 <= r < 100 */ |
| 170 | *buf++ = (r - 10 * q) + '0'; /* 6 */ | 208 | *((u16 *)buf) = decpair[r]; |
| 171 | r = (q * 0xcd) >> 11; | 209 | buf += r < 10 ? 1 : 2; |
| 172 | *buf++ = (q - 10 * r) + '0'; /* 7 */ | ||
| 173 | q = (r * 0xcd) >> 11; | ||
| 174 | *buf++ = (r - 10 * q) + '0'; /* 8 */ | ||
| 175 | *buf++ = q + '0'; /* 9 */ | ||
| 176 | return buf; | 210 | return buf; |
| 177 | } | 211 | } |
| 178 | #endif | ||
| 179 | 212 | ||
| 180 | /* Similar to above but do not pad with zeros. | 213 | #if BITS_PER_LONG == 64 && BITS_PER_LONG_LONG == 64 |
| 181 | * Code can be easily arranged to print 9 digits too, but our callers | ||
| 182 | * always call put_dec_full9() instead when the number has 9 decimal digits. | ||
| 183 | */ | ||
| 184 | static noinline_for_stack | 214 | static noinline_for_stack |
| 185 | char *put_dec_trunc8(char *buf, unsigned r) | 215 | char *put_dec_full8(char *buf, unsigned r) |
| 186 | { | 216 | { |
| 187 | unsigned q; | 217 | unsigned q; |
| 188 | 218 | ||
| 189 | /* Copy of previous function's body with added early returns */ | 219 | /* 0 <= r < 10^8 */ |
| 190 | while (r >= 10000) { | 220 | q = (r * (u64)0x28f5c29) >> 32; |
| 191 | q = r + '0'; | 221 | *((u16 *)buf) = decpair[r - 100*q]; |
| 192 | r = (r * (uint64_t)0x1999999a) >> 32; | 222 | buf += 2; |
| 193 | *buf++ = q - 10*r; | ||
| 194 | } | ||
| 195 | 223 | ||
| 196 | q = (r * 0x199a) >> 16; /* r <= 9999 */ | 224 | /* 0 <= q < 10^6 */ |
| 197 | *buf++ = (r - 10 * q) + '0'; | 225 | r = (q * (u64)0x28f5c29) >> 32; |
| 198 | if (q == 0) | 226 | *((u16 *)buf) = decpair[q - 100*r]; |
| 199 | return buf; | 227 | buf += 2; |
| 200 | r = (q * 0xcd) >> 11; /* q <= 999 */ | ||
| 201 | *buf++ = (q - 10 * r) + '0'; | ||
| 202 | if (r == 0) | ||
| 203 | return buf; | ||
| 204 | q = (r * 0xcd) >> 11; /* r <= 99 */ | ||
| 205 | *buf++ = (r - 10 * q) + '0'; | ||
| 206 | if (q == 0) | ||
| 207 | return buf; | ||
| 208 | *buf++ = q + '0'; /* q <= 9 */ | ||
| 209 | return buf; | ||
| 210 | } | ||
| 211 | 228 | ||
| 212 | /* There are two algorithms to print larger numbers. | 229 | /* 0 <= r < 10^4 */ |
| 213 | * One is generic: divide by 1000000000 and repeatedly print | 230 | q = (r * 0x147b) >> 19; |
| 214 | * groups of (up to) 9 digits. It's conceptually simple, | 231 | *((u16 *)buf) = decpair[r - 100*q]; |
| 215 | * but requires a (unsigned long long) / 1000000000 division. | 232 | buf += 2; |
| 216 | * | ||
| 217 | * Second algorithm splits 64-bit unsigned long long into 16-bit chunks, | ||
| 218 | * manipulates them cleverly and generates groups of 4 decimal digits. | ||
| 219 | * It so happens that it does NOT require long long division. | ||
| 220 | * | ||
| 221 | * If long is > 32 bits, division of 64-bit values is relatively easy, | ||
| 222 | * and we will use the first algorithm. | ||
| 223 | * If long long is > 64 bits (strange architecture with VERY large long long), | ||
| 224 | * second algorithm can't be used, and we again use the first one. | ||
| 225 | * | ||
| 226 | * Else (if long is 32 bits and long long is 64 bits) we use second one. | ||
| 227 | */ | ||
| 228 | 233 | ||
| 229 | #if BITS_PER_LONG != 32 || BITS_PER_LONG_LONG != 64 | 234 | /* 0 <= q < 100 */ |
| 230 | 235 | *((u16 *)buf) = decpair[q]; | |
| 231 | /* First algorithm: generic */ | 236 | buf += 2; |
| 237 | return buf; | ||
| 238 | } | ||
| 232 | 239 | ||
| 233 | static | 240 | static noinline_for_stack |
| 234 | char *put_dec(char *buf, unsigned long long n) | 241 | char *put_dec(char *buf, unsigned long long n) |
| 235 | { | 242 | { |
| 236 | if (n >= 100*1000*1000) { | 243 | if (n >= 100*1000*1000) |
| 237 | while (n >= 1000*1000*1000) | 244 | buf = put_dec_full8(buf, do_div(n, 100*1000*1000)); |
| 238 | buf = put_dec_full9(buf, do_div(n, 1000*1000*1000)); | 245 | /* 1 <= n <= 1.6e11 */ |
| 239 | if (n >= 100*1000*1000) | 246 | if (n >= 100*1000*1000) |
| 240 | return put_dec_full9(buf, n); | 247 | buf = put_dec_full8(buf, do_div(n, 100*1000*1000)); |
| 241 | } | 248 | /* 1 <= n < 1e8 */ |
| 242 | return put_dec_trunc8(buf, n); | 249 | return put_dec_trunc8(buf, n); |
| 243 | } | 250 | } |
| 244 | 251 | ||
| 245 | #else | 252 | #elif BITS_PER_LONG == 32 && BITS_PER_LONG_LONG == 64 |
| 246 | 253 | ||
| 247 | /* Second algorithm: valid only for 64-bit long longs */ | 254 | static void |
| 248 | 255 | put_dec_full4(char *buf, unsigned r) | |
| 249 | /* See comment in put_dec_full9 for choice of constants */ | ||
| 250 | static noinline_for_stack | ||
| 251 | void put_dec_full4(char *buf, unsigned q) | ||
| 252 | { | 256 | { |
| 253 | unsigned r; | 257 | unsigned q; |
| 254 | r = (q * 0xccd) >> 15; | 258 | |
| 255 | buf[0] = (q - 10 * r) + '0'; | 259 | /* 0 <= r < 10^4 */ |
| 256 | q = (r * 0xcd) >> 11; | 260 | q = (r * 0x147b) >> 19; |
| 257 | buf[1] = (r - 10 * q) + '0'; | 261 | *((u16 *)buf) = decpair[r - 100*q]; |
| 258 | r = (q * 0xcd) >> 11; | 262 | buf += 2; |
| 259 | buf[2] = (q - 10 * r) + '0'; | 263 | /* 0 <= q < 100 */ |
| 260 | buf[3] = r + '0'; | 264 | *((u16 *)buf) = decpair[q]; |
| 261 | } | 265 | } |
| 262 | 266 | ||
| 263 | /* | 267 | /* |
| @@ -265,9 +269,9 @@ void put_dec_full4(char *buf, unsigned q) | |||
| 265 | * The approximation x/10000 == (x * 0x346DC5D7) >> 43 | 269 | * The approximation x/10000 == (x * 0x346DC5D7) >> 43 |
| 266 | * holds for all x < 1,128,869,999. The largest value this | 270 | * holds for all x < 1,128,869,999. The largest value this |
| 267 | * helper will ever be asked to convert is 1,125,520,955. | 271 | * helper will ever be asked to convert is 1,125,520,955. |
| 268 | * (d1 in the put_dec code, assuming n is all-ones). | 272 | * (second call in the put_dec code, assuming n is all-ones). |
| 269 | */ | 273 | */ |
| 270 | static | 274 | static noinline_for_stack |
| 271 | unsigned put_dec_helper4(char *buf, unsigned x) | 275 | unsigned put_dec_helper4(char *buf, unsigned x) |
| 272 | { | 276 | { |
| 273 | uint32_t q = (x * (uint64_t)0x346DC5D7) >> 43; | 277 | uint32_t q = (x * (uint64_t)0x346DC5D7) >> 43; |
| @@ -294,6 +298,8 @@ char *put_dec(char *buf, unsigned long long n) | |||
| 294 | d2 = (h ) & 0xffff; | 298 | d2 = (h ) & 0xffff; |
| 295 | d3 = (h >> 16); /* implicit "& 0xffff" */ | 299 | d3 = (h >> 16); /* implicit "& 0xffff" */ |
| 296 | 300 | ||
| 301 | /* n = 2^48 d3 + 2^32 d2 + 2^16 d1 + d0 | ||
| 302 | = 281_4749_7671_0656 d3 + 42_9496_7296 d2 + 6_5536 d1 + d0 */ | ||
| 297 | q = 656 * d3 + 7296 * d2 + 5536 * d1 + ((uint32_t)n & 0xffff); | 303 | q = 656 * d3 + 7296 * d2 + 5536 * d1 + ((uint32_t)n & 0xffff); |
| 298 | q = put_dec_helper4(buf, q); | 304 | q = put_dec_helper4(buf, q); |
| 299 | 305 | ||
| @@ -323,7 +329,8 @@ char *put_dec(char *buf, unsigned long long n) | |||
| 323 | */ | 329 | */ |
| 324 | int num_to_str(char *buf, int size, unsigned long long num) | 330 | int num_to_str(char *buf, int size, unsigned long long num) |
| 325 | { | 331 | { |
| 326 | char tmp[sizeof(num) * 3]; | 332 | /* put_dec requires 2-byte alignment of the buffer. */ |
| 333 | char tmp[sizeof(num) * 3] __aligned(2); | ||
| 327 | int idx, len; | 334 | int idx, len; |
| 328 | 335 | ||
| 329 | /* put_dec() may work incorrectly for num = 0 (generate "", not "0") */ | 336 | /* put_dec() may work incorrectly for num = 0 (generate "", not "0") */ |
| @@ -384,7 +391,8 @@ static noinline_for_stack | |||
| 384 | char *number(char *buf, char *end, unsigned long long num, | 391 | char *number(char *buf, char *end, unsigned long long num, |
| 385 | struct printf_spec spec) | 392 | struct printf_spec spec) |
| 386 | { | 393 | { |
| 387 | char tmp[3 * sizeof(num)]; | 394 | /* put_dec requires 2-byte alignment of the buffer. */ |
| 395 | char tmp[3 * sizeof(num)] __aligned(2); | ||
| 388 | char sign; | 396 | char sign; |
| 389 | char locase; | 397 | char locase; |
| 390 | int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10); | 398 | int need_pfx = ((spec.flags & SPECIAL) && spec.base != 10); |
| @@ -944,7 +952,7 @@ char *ip4_string(char *p, const u8 *addr, const char *fmt) | |||
| 944 | break; | 952 | break; |
| 945 | } | 953 | } |
| 946 | for (i = 0; i < 4; i++) { | 954 | for (i = 0; i < 4; i++) { |
| 947 | char temp[3]; /* hold each IP quad in reverse order */ | 955 | char temp[4] __aligned(2); /* hold each IP quad in reverse order */ |
| 948 | int digits = put_dec_trunc8(temp, addr[index]) - temp; | 956 | int digits = put_dec_trunc8(temp, addr[index]) - temp; |
| 949 | if (leading_zeros) { | 957 | if (leading_zeros) { |
| 950 | if (digits < 3) | 958 | if (digits < 3) |
