From 5756b76e4db643d8f75174a9a50038523d4b9e32 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 5 Mar 2012 16:49:24 +0000 Subject: vsprintf: make %pV handling compatible with kasprintf() kasprintf() (and potentially other functions that I didn't run across so far) want to evaluate argument lists twice. Caring to do so for the primary list is obviously their job, but they can't reasonably be expected to check the format string for instances of %pV, which however need special handling too: On architectures like x86-64 (as opposed to e.g. ix86), using the same argument list twice doesn't produce the expected results, as an internally managed cursor gets updated during the first run. Fix the problem by always acting on a copy of the original list when handling %pV. Signed-off-by: Jan Beulich Signed-off-by: Linus Torvalds --- lib/vsprintf.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'lib/vsprintf.c') diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 8e75003d62f..38e612e66da 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -891,9 +891,15 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, case 'U': return uuid_string(buf, end, ptr, spec, fmt); case 'V': - return buf + vsnprintf(buf, end > buf ? end - buf : 0, - ((struct va_format *)ptr)->fmt, - *(((struct va_format *)ptr)->va)); + { + va_list va; + + va_copy(va, *((struct va_format *)ptr)->va); + buf += vsnprintf(buf, end > buf ? end - buf : 0, + ((struct va_format *)ptr)->fmt, va); + va_end(va); + return buf; + } case 'K': /* * %pK cannot be used in IRQ context because its test -- cgit v1.2.3-70-g09d2 From 8bc3bcc93a2b4e47d5d410146f6546bca6171663 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Wed, 16 Nov 2011 21:29:17 -0500 Subject: lib: reduce the use of module.h wherever possible For files only using THIS_MODULE and/or EXPORT_SYMBOL, map them onto including export.h -- or if the file isn't even using those, then just delete the include. Fix up any implicit include dependencies that were being masked by module.h along the way. Signed-off-by: Paul Gortmaker --- lib/argv_split.c | 2 +- lib/atomic64.c | 2 +- lib/average.c | 3 ++- lib/bcd.c | 2 +- lib/bitmap.c | 3 ++- lib/bsearch.c | 2 +- lib/check_signature.c | 2 +- lib/checksum.c | 2 +- lib/cmdline.c | 2 +- lib/cpu_rmap.c | 2 +- lib/cpumask.c | 2 +- lib/ctype.c | 3 ++- lib/debug_locks.c | 2 +- lib/dec_and_lock.c | 2 +- lib/devres.c | 2 +- lib/div64.c | 3 ++- lib/dump_stack.c | 2 +- lib/fault-inject.c | 2 +- lib/find_last_bit.c | 2 +- lib/find_next_bit.c | 2 +- lib/flex_array.c | 2 +- lib/gcd.c | 2 +- lib/genalloc.c | 2 +- lib/halfmd4.c | 2 +- lib/hexdump.c | 2 +- lib/hweight.c | 2 +- lib/idr.c | 2 +- lib/int_sqrt.c | 2 +- lib/iomap.c | 2 +- lib/iomap_copy.c | 2 +- lib/iommu-helper.c | 2 +- lib/ioremap.c | 2 +- lib/irq_regs.c | 3 ++- lib/kasprintf.c | 2 +- lib/klist.c | 2 +- lib/kobject.c | 2 +- lib/kobject_uevent.c | 3 ++- lib/kstrtox.c | 2 +- lib/lcm.c | 2 +- lib/list_debug.c | 3 ++- lib/llist.c | 2 +- lib/locking-selftest.c | 1 - lib/md5.c | 2 +- lib/nlattr.c | 2 +- lib/parser.c | 3 ++- lib/radix-tree.c | 2 +- lib/random32.c | 2 +- lib/ratelimit.c | 2 +- lib/rational.c | 3 ++- lib/rbtree.c | 2 +- lib/rwsem-spinlock.c | 2 +- lib/rwsem.c | 2 +- lib/scatterlist.c | 2 +- lib/sha1.c | 2 +- lib/smp_processor_id.c | 2 +- lib/spinlock_debug.c | 2 +- lib/string.c | 5 ++++- lib/string_helpers.c | 2 +- lib/swiotlb.c | 2 +- lib/syscall.c | 2 +- lib/timerqueue.c | 2 +- lib/uuid.c | 2 +- lib/vsprintf.c | 2 +- 63 files changed, 74 insertions(+), 63 deletions(-) (limited to 'lib/vsprintf.c') diff --git a/lib/argv_split.c b/lib/argv_split.c index 4b1b083f219..1e9a6cbc368 100644 --- a/lib/argv_split.c +++ b/lib/argv_split.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include static const char *skip_arg(const char *cp) { diff --git a/lib/atomic64.c b/lib/atomic64.c index 3975470caf4..978537809d8 100644 --- a/lib/atomic64.c +++ b/lib/atomic64.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include /* diff --git a/lib/average.c b/lib/average.c index 5576c284149..99a67e662b3 100644 --- a/lib/average.c +++ b/lib/average.c @@ -5,8 +5,9 @@ * Version 2. See the file COPYING for more details. */ -#include +#include #include +#include #include #include diff --git a/lib/bcd.c b/lib/bcd.c index d74257fd0fe..55efaf74234 100644 --- a/lib/bcd.c +++ b/lib/bcd.c @@ -1,5 +1,5 @@ #include -#include +#include unsigned bcd2bin(unsigned char val) { diff --git a/lib/bitmap.c b/lib/bitmap.c index 0d4a127dd9b..6ce1e3b6a52 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c @@ -5,7 +5,8 @@ * This source code is licensed under the GNU General Public License, * Version 2. See the file COPYING for more details. */ -#include +#include +#include #include #include #include diff --git a/lib/bsearch.c b/lib/bsearch.c index 5b54758e2af..e33c179089d 100644 --- a/lib/bsearch.c +++ b/lib/bsearch.c @@ -9,7 +9,7 @@ * published by the Free Software Foundation; version 2. */ -#include +#include #include /* diff --git a/lib/check_signature.c b/lib/check_signature.c index fd6af199247..6b49797980c 100644 --- a/lib/check_signature.c +++ b/lib/check_signature.c @@ -1,5 +1,5 @@ #include -#include +#include /** * check_signature - find BIOS signatures diff --git a/lib/checksum.c b/lib/checksum.c index 8df2f91e6d9..12dceb27ff2 100644 --- a/lib/checksum.c +++ b/lib/checksum.c @@ -32,7 +32,7 @@ /* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most of the assembly has to go. */ -#include +#include #include #include diff --git a/lib/cmdline.c b/lib/cmdline.c index f5f3ad8b62f..eb6791188cf 100644 --- a/lib/cmdline.c +++ b/lib/cmdline.c @@ -12,7 +12,7 @@ * */ -#include +#include #include #include diff --git a/lib/cpu_rmap.c b/lib/cpu_rmap.c index 987acfafeb8..145dec5267c 100644 --- a/lib/cpu_rmap.c +++ b/lib/cpu_rmap.c @@ -11,7 +11,7 @@ #ifdef CONFIG_GENERIC_HARDIRQS #include #endif -#include +#include /* * These functions maintain a mapping from CPUs to some ordered set of diff --git a/lib/cpumask.c b/lib/cpumask.c index af3e5817de9..0b660118ed9 100644 --- a/lib/cpumask.c +++ b/lib/cpumask.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include int __first_cpu(const cpumask_t *srcp) diff --git a/lib/ctype.c b/lib/ctype.c index 26baa620e95..c646df91a2f 100644 --- a/lib/ctype.c +++ b/lib/ctype.c @@ -5,7 +5,8 @@ */ #include -#include +#include +#include const unsigned char _ctype[] = { _C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ diff --git a/lib/debug_locks.c b/lib/debug_locks.c index b1c17730767..f2fa60c5934 100644 --- a/lib/debug_locks.c +++ b/lib/debug_locks.c @@ -10,7 +10,7 @@ */ #include #include -#include +#include #include #include diff --git a/lib/dec_and_lock.c b/lib/dec_and_lock.c index b5257725daa..e26278576b3 100644 --- a/lib/dec_and_lock.c +++ b/lib/dec_and_lock.c @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/lib/devres.c b/lib/devres.c index 9676617b448..80b9c76d436 100644 --- a/lib/devres.c +++ b/lib/devres.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include void devm_ioremap_release(struct device *dev, void *res) { diff --git a/lib/div64.c b/lib/div64.c index 5b491919177..3ea24907d52 100644 --- a/lib/div64.c +++ b/lib/div64.c @@ -16,7 +16,8 @@ * assembly versions such as arch/ppc/lib/div64.S and arch/sh/lib/div64.S. */ -#include +#include +#include #include /* Not needed on 64bit architectures */ diff --git a/lib/dump_stack.c b/lib/dump_stack.c index 53bff4c8452..42f4f55c945 100644 --- a/lib/dump_stack.c +++ b/lib/dump_stack.c @@ -4,7 +4,7 @@ */ #include -#include +#include void dump_stack(void) { diff --git a/lib/fault-inject.c b/lib/fault-inject.c index b4801f51b60..6805453c18e 100644 --- a/lib/fault-inject.c +++ b/lib/fault-inject.c @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/lib/find_last_bit.c b/lib/find_last_bit.c index d903959ad69..91ca09fbf6f 100644 --- a/lib/find_last_bit.c +++ b/lib/find_last_bit.c @@ -11,7 +11,7 @@ */ #include -#include +#include #include #include diff --git a/lib/find_next_bit.c b/lib/find_next_bit.c index 4bd75a73ba0..0cbfc0b4398 100644 --- a/lib/find_next_bit.c +++ b/lib/find_next_bit.c @@ -10,7 +10,7 @@ */ #include -#include +#include #include #include diff --git a/lib/flex_array.c b/lib/flex_array.c index 9b8b89458c4..6948a6692fc 100644 --- a/lib/flex_array.c +++ b/lib/flex_array.c @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include struct flex_array_part { diff --git a/lib/gcd.c b/lib/gcd.c index f879033d982..cce4f3cd14b 100644 --- a/lib/gcd.c +++ b/lib/gcd.c @@ -1,6 +1,6 @@ #include #include -#include +#include /* Greatest common divisor */ unsigned long gcd(unsigned long a, unsigned long b) diff --git a/lib/genalloc.c b/lib/genalloc.c index f352cc42f4f..6bc04aab6ec 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -29,7 +29,7 @@ */ #include -#include +#include #include #include #include diff --git a/lib/halfmd4.c b/lib/halfmd4.c index e11db26f8ae..66d0ee8b777 100644 --- a/lib/halfmd4.c +++ b/lib/halfmd4.c @@ -1,5 +1,5 @@ #include -#include +#include #include /* F, G and H are basic MD4 functions: selection, majority, parity */ diff --git a/lib/hexdump.c b/lib/hexdump.c index 51d5ae21024..6540d657dca 100644 --- a/lib/hexdump.c +++ b/lib/hexdump.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include const char hex_asc[] = "0123456789abcdef"; EXPORT_SYMBOL(hex_asc); diff --git a/lib/hweight.c b/lib/hweight.c index 3c79d50814c..b7d81ba143d 100644 --- a/lib/hweight.c +++ b/lib/hweight.c @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/lib/idr.c b/lib/idr.c index ed055b297c8..4a3b776356c 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -29,7 +29,7 @@ #ifndef TEST // to test in user space... #include #include -#include +#include #endif #include #include diff --git a/lib/int_sqrt.c b/lib/int_sqrt.c index fd355a99327..fc2eeb7cb2e 100644 --- a/lib/int_sqrt.c +++ b/lib/int_sqrt.c @@ -1,6 +1,6 @@ #include -#include +#include /** * int_sqrt - rough approximation to sqrt diff --git a/lib/iomap.c b/lib/iomap.c index ada922a808e..2c08f36862e 100644 --- a/lib/iomap.c +++ b/lib/iomap.c @@ -6,7 +6,7 @@ #include #include -#include +#include /* * Read/write from/to an (offsettable) iomem cookie. It might be a PIO diff --git a/lib/iomap_copy.c b/lib/iomap_copy.c index 864fc5ea398..4527e751b5e 100644 --- a/lib/iomap_copy.c +++ b/lib/iomap_copy.c @@ -15,7 +15,7 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include +#include #include /** diff --git a/lib/iommu-helper.c b/lib/iommu-helper.c index da053313ee5..ae7d50b0576 100644 --- a/lib/iommu-helper.c +++ b/lib/iommu-helper.c @@ -2,7 +2,7 @@ * IOMMU helper functions for the free area management */ -#include +#include #include int iommu_is_span_boundary(unsigned int index, unsigned int nr, diff --git a/lib/ioremap.c b/lib/ioremap.c index da4e2ad74b6..0c9216c4876 100644 --- a/lib/ioremap.c +++ b/lib/ioremap.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include diff --git a/lib/irq_regs.c b/lib/irq_regs.c index 753880a5440..9c0a1d70fbe 100644 --- a/lib/irq_regs.c +++ b/lib/irq_regs.c @@ -8,7 +8,8 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ -#include +#include +#include #include #ifndef ARCH_HAS_OWN_IRQ_REGS diff --git a/lib/kasprintf.c b/lib/kasprintf.c index 9c4233b2378..ae0de80c1c8 100644 --- a/lib/kasprintf.c +++ b/lib/kasprintf.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include #include diff --git a/lib/klist.c b/lib/klist.c index 573d6068a42..0874e41609a 100644 --- a/lib/klist.c +++ b/lib/klist.c @@ -35,7 +35,7 @@ */ #include -#include +#include #include /* diff --git a/lib/kobject.c b/lib/kobject.c index c33d7a18d63..21dee7c19af 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index e66e9b63261..6baabebda11 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c @@ -17,7 +17,8 @@ #include #include #include -#include +#include +#include #include #include #include diff --git a/lib/kstrtox.c b/lib/kstrtox.c index b1dd3e7d88c..c3615eab0cc 100644 --- a/lib/kstrtox.c +++ b/lib/kstrtox.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include "kstrtox.h" diff --git a/lib/lcm.c b/lib/lcm.c index 10b5cfcacf6..b9c8de461e9 100644 --- a/lib/lcm.c +++ b/lib/lcm.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include /* Lowest common multiple */ diff --git a/lib/list_debug.c b/lib/list_debug.c index b8029a5583f..c7a1f0b6a78 100644 --- a/lib/list_debug.c +++ b/lib/list_debug.c @@ -6,8 +6,9 @@ * DEBUG_LIST. */ -#include +#include #include +#include /* * Insert a new entry between two known consecutive entries. diff --git a/lib/llist.c b/lib/llist.c index 700cff77a38..8221b3d2fbf 100644 --- a/lib/llist.c +++ b/lib/llist.c @@ -23,7 +23,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include +#include #include #include diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c index 507a22fab73..7aae0f2a5e0 100644 --- a/lib/locking-selftest.c +++ b/lib/locking-selftest.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/lib/md5.c b/lib/md5.c index c777180e1f2..958a3c15923 100644 --- a/lib/md5.c +++ b/lib/md5.c @@ -1,5 +1,5 @@ #include -#include +#include #include #define F1(x, y, z) (z ^ (x & (y ^ z))) diff --git a/lib/nlattr.c b/lib/nlattr.c index a8408b6cacd..4226dfeb517 100644 --- a/lib/nlattr.c +++ b/lib/nlattr.c @@ -5,7 +5,7 @@ * Alexey Kuznetsov */ -#include +#include #include #include #include diff --git a/lib/parser.c b/lib/parser.c index dcbaaef6cf1..c4341008483 100644 --- a/lib/parser.c +++ b/lib/parser.c @@ -6,7 +6,8 @@ */ #include -#include +#include +#include #include #include #include diff --git a/lib/radix-tree.c b/lib/radix-tree.c index dc63d081839..3e69c2b66c9 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/lib/random32.c b/lib/random32.c index fc3545a3277..938bde5876a 100644 --- a/lib/random32.c +++ b/lib/random32.c @@ -35,7 +35,7 @@ #include #include -#include +#include #include #include diff --git a/lib/ratelimit.c b/lib/ratelimit.c index c96d500577d..40e03ea2a96 100644 --- a/lib/ratelimit.c +++ b/lib/ratelimit.c @@ -11,7 +11,7 @@ #include #include -#include +#include /* * __ratelimit - rate limiting diff --git a/lib/rational.c b/lib/rational.c index 3ed247b8066..d326da3976f 100644 --- a/lib/rational.c +++ b/lib/rational.c @@ -7,7 +7,8 @@ */ #include -#include +#include +#include /* * calculate best rational approximation for a given fraction diff --git a/lib/rbtree.c b/lib/rbtree.c index a16be19a130..d4175565dc2 100644 --- a/lib/rbtree.c +++ b/lib/rbtree.c @@ -21,7 +21,7 @@ */ #include -#include +#include static void __rb_rotate_left(struct rb_node *node, struct rb_root *root) { diff --git a/lib/rwsem-spinlock.c b/lib/rwsem-spinlock.c index f2393c21fe8..7e0d6a58fc8 100644 --- a/lib/rwsem-spinlock.c +++ b/lib/rwsem-spinlock.c @@ -7,7 +7,7 @@ */ #include #include -#include +#include struct rwsem_waiter { struct list_head list; diff --git a/lib/rwsem.c b/lib/rwsem.c index 410aa1189b1..8337e1b9bb8 100644 --- a/lib/rwsem.c +++ b/lib/rwsem.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include /* * Initialize an rwsem: diff --git a/lib/scatterlist.c b/lib/scatterlist.c index 4ceb05d772a..63a7f2ebbd0 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c @@ -6,7 +6,7 @@ * This source code is licensed under the GNU General Public License, * Version 2. See the file COPYING for more details. */ -#include +#include #include #include #include diff --git a/lib/sha1.c b/lib/sha1.c index 1de509a159c..1df191e04a2 100644 --- a/lib/sha1.c +++ b/lib/sha1.c @@ -6,7 +6,7 @@ */ #include -#include +#include #include #include #include diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c index 503f087382a..4c0d0e51d49 100644 --- a/lib/smp_processor_id.c +++ b/lib/smp_processor_id.c @@ -3,7 +3,7 @@ * * DEBUG_PREEMPT variant of smp_processor_id(). */ -#include +#include #include #include diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c index 5f3eacdd617..525d160d44f 100644 --- a/lib/spinlock_debug.c +++ b/lib/spinlock_debug.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include void __raw_spin_lock_init(raw_spinlock_t *lock, const char *name, struct lock_class_key *key) diff --git a/lib/string.c b/lib/string.c index dc4a86341f9..26df13e43cc 100644 --- a/lib/string.c +++ b/lib/string.c @@ -22,7 +22,10 @@ #include #include #include -#include +#include +#include +#include +#include #ifndef __HAVE_ARCH_STRNICMP /** diff --git a/lib/string_helpers.c b/lib/string_helpers.c index ab431d4cc97..dd4ece37269 100644 --- a/lib/string_helpers.c +++ b/lib/string_helpers.c @@ -5,7 +5,7 @@ */ #include #include -#include +#include #include /** diff --git a/lib/swiotlb.c b/lib/swiotlb.c index 058935ef397..9c6c9379da0 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/lib/syscall.c b/lib/syscall.c index a4f7067f72f..58710eefeac 100644 --- a/lib/syscall.c +++ b/lib/syscall.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include static int collect_syscall(struct task_struct *target, long *callno, diff --git a/lib/timerqueue.c b/lib/timerqueue.c index 191176a43e9..93287c60099 100644 --- a/lib/timerqueue.c +++ b/lib/timerqueue.c @@ -24,7 +24,7 @@ #include #include -#include +#include /** * timerqueue_add - Adds timer to timerqueue. diff --git a/lib/uuid.c b/lib/uuid.c index 8fadd7cef46..52a6fe6387d 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -19,7 +19,7 @@ */ #include -#include +#include #include #include diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 8e75003d62f..7f29bfce840 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -17,7 +17,7 @@ */ #include -#include +#include /* for KSYM_SYMBOL_LEN */ #include #include #include -- cgit v1.2.3-70-g09d2 From 1ac101a5d675aca2426c5cd460c73fb95acb8391 Mon Sep 17 00:00:00 2001 From: KAMEZAWA Hiroyuki Date: Fri, 23 Mar 2012 15:02:54 -0700 Subject: procfs: add num_to_str() to speed up /proc/stat == stat_check.py num = 0 with open("/proc/stat") as f: while num < 1000 : data = f.read() f.seek(0, 0) num = num + 1 == perf shows 20.39% stat_check.py [kernel.kallsyms] [k] format_decode 13.41% stat_check.py [kernel.kallsyms] [k] number 12.61% stat_check.py [kernel.kallsyms] [k] vsnprintf 10.85% stat_check.py [kernel.kallsyms] [k] memcpy 4.85% stat_check.py [kernel.kallsyms] [k] radix_tree_lookup 4.43% stat_check.py [kernel.kallsyms] [k] seq_printf This patch removes most of calls to vsnprintf() by adding num_to_str() and seq_print_decimal_ull(), which prints decimal numbers without rich functions provided by printf(). On my 8cpu box. == Before patch == [root@bluextal test]# time ./stat_check.py real 0m0.150s user 0m0.026s sys 0m0.121s == After patch == [root@bluextal test]# time ./stat_check.py real 0m0.055s user 0m0.022s sys 0m0.030s [akpm@linux-foundation.org: remove incorrect comment, use less statck in num_to_str(), move comment from .h to .c, simplify seq_put_decimal_ull()] [andrea@betterlinux.com: avoid breaking the ABI in /proc/stat] Signed-off-by: KAMEZAWA Hiroyuki Signed-off-by: Andrea Righi Cc: Eric Dumazet Cc: Glauber Costa Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Paul Turner Cc: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/proc/stat.c | 55 ++++++++++++++++++++++++------------------------ fs/seq_file.c | 33 +++++++++++++++++++++++++++++ include/linux/kernel.h | 2 ++ include/linux/seq_file.h | 3 ++- lib/vsprintf.c | 20 ++++++++++++++++++ 5 files changed, 84 insertions(+), 29 deletions(-) (limited to 'lib/vsprintf.c') diff --git a/fs/proc/stat.c b/fs/proc/stat.c index ac446114cd4..6a0c62d6e44 100644 --- a/fs/proc/stat.c +++ b/fs/proc/stat.c @@ -89,18 +89,19 @@ static int show_stat(struct seq_file *p, void *v) } sum += arch_irq_stat(); - seq_printf(p, "cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu " - "%llu\n", - (unsigned long long)cputime64_to_clock_t(user), - (unsigned long long)cputime64_to_clock_t(nice), - (unsigned long long)cputime64_to_clock_t(system), - (unsigned long long)cputime64_to_clock_t(idle), - (unsigned long long)cputime64_to_clock_t(iowait), - (unsigned long long)cputime64_to_clock_t(irq), - (unsigned long long)cputime64_to_clock_t(softirq), - (unsigned long long)cputime64_to_clock_t(steal), - (unsigned long long)cputime64_to_clock_t(guest), - (unsigned long long)cputime64_to_clock_t(guest_nice)); + seq_puts(p, "cpu "); + seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(user)); + seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(nice)); + seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(system)); + seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(idle)); + seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(iowait)); + seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(irq)); + seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(softirq)); + seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(steal)); + seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest)); + seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest_nice)); + seq_putc(p, '\n'); + for_each_online_cpu(i) { /* Copy values here to work around gcc-2.95.3, gcc-2.96 */ user = kcpustat_cpu(i).cpustat[CPUTIME_USER]; @@ -113,26 +114,24 @@ static int show_stat(struct seq_file *p, void *v) steal = kcpustat_cpu(i).cpustat[CPUTIME_STEAL]; guest = kcpustat_cpu(i).cpustat[CPUTIME_GUEST]; guest_nice = kcpustat_cpu(i).cpustat[CPUTIME_GUEST_NICE]; - seq_printf(p, - "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu %llu " - "%llu\n", - i, - (unsigned long long)cputime64_to_clock_t(user), - (unsigned long long)cputime64_to_clock_t(nice), - (unsigned long long)cputime64_to_clock_t(system), - (unsigned long long)cputime64_to_clock_t(idle), - (unsigned long long)cputime64_to_clock_t(iowait), - (unsigned long long)cputime64_to_clock_t(irq), - (unsigned long long)cputime64_to_clock_t(softirq), - (unsigned long long)cputime64_to_clock_t(steal), - (unsigned long long)cputime64_to_clock_t(guest), - (unsigned long long)cputime64_to_clock_t(guest_nice)); + seq_printf(p, "cpu%d", i); + seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(user)); + seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(nice)); + seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(system)); + seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(idle)); + seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(iowait)); + seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(irq)); + seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(softirq)); + seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(steal)); + seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest)); + seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest_nice)); + seq_putc(p, '\n'); } seq_printf(p, "intr %llu", (unsigned long long)sum); /* sum again ? it could be updated? */ for_each_irq_nr(j) - seq_printf(p, " %u", kstat_irqs(j)); + seq_put_decimal_ull(p, ' ', kstat_irqs(j)); seq_printf(p, "\nctxt %llu\n" @@ -149,7 +148,7 @@ static int show_stat(struct seq_file *p, void *v) seq_printf(p, "softirq %llu", (unsigned long long)sum_softirq); for (i = 0; i < NR_SOFTIRQS; i++) - seq_printf(p, " %u", per_softirq_sums[i]); + seq_put_decimal_ull(p, ' ', per_softirq_sums[i]); seq_putc(p, '\n'); return 0; diff --git a/fs/seq_file.c b/fs/seq_file.c index aa242dc9937..7d19816c4cc 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -644,6 +644,39 @@ int seq_puts(struct seq_file *m, const char *s) } EXPORT_SYMBOL(seq_puts); +/* + * A helper routine for putting decimal numbers without rich format of printf(). + * only 'unsigned long long' is supported. + * This routine will put one byte delimiter + number into seq_file. + * This routine is very quick when you show lots of numbers. + * In usual cases, it will be better to use seq_printf(). It's easier to read. + */ +int seq_put_decimal_ull(struct seq_file *m, char delimiter, + unsigned long long num) +{ + int len; + + if (m->count + 2 >= m->size) /* we'll write 2 bytes at least */ + goto overflow; + + m->buf[m->count++] = delimiter; + + if (num < 10) { + m->buf[m->count++] = num + '0'; + return 0; + } + + len = num_to_str(m->buf + m->count, m->size - m->count, num); + if (!len) + goto overflow; + m->count += len; + return 0; +overflow: + m->count = m->size; + return -1; +} +EXPORT_SYMBOL(seq_put_decimal_ull); + /** * seq_write - write arbitrary data to buffer * @seq: seq_file identifying the buffer to which data should be written diff --git a/include/linux/kernel.h b/include/linux/kernel.h index f2085b541a2..3e140add536 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -312,6 +312,8 @@ extern long long simple_strtoll(const char *,char **,unsigned int); #define strict_strtoull kstrtoull #define strict_strtoll kstrtoll +extern int num_to_str(char *buf, int size, unsigned long long num); + /* lib/printf utilities */ extern __printf(2, 3) int sprintf(char *buf, const char * fmt, ...); diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index 44f1514b00b..5bba42c9944 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h @@ -121,9 +121,10 @@ int single_release(struct inode *, struct file *); void *__seq_open_private(struct file *, const struct seq_operations *, int); int seq_open_private(struct file *, const struct seq_operations *, int); int seq_release_private(struct inode *, struct file *); +int seq_put_decimal_ull(struct seq_file *m, char delimiter, + unsigned long long num); #define SEQ_START_TOKEN ((void *)1) - /* * Helpers for iteration over list_head-s in seq_files */ diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 38e612e66da..385c40291cd 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -212,6 +212,26 @@ char *put_dec(char *buf, unsigned long long num) } } +/* + * Convert passed number to decimal string. + * Returns the length of string. On buffer overflow, returns 0. + * + * If speed is not important, use snprintf(). It's easy to read the code. + */ +int num_to_str(char *buf, int size, unsigned long long num) +{ + char tmp[21]; /* Enough for 2^64 in decimal */ + int idx, len; + + len = put_dec(tmp, num) - tmp; + + if (len > size) + return 0; + for (idx = 0; idx < len; ++idx) + buf[idx] = tmp[len - idx - 1]; + return len; +} + #define ZEROPAD 1 /* pad with zero */ #define SIGN 2 /* unsigned/signed long */ #define PLUS 4 /* show plus */ -- cgit v1.2.3-70-g09d2