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 8e75003d62f6..38e612e66da5 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 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 4b1b083f219c..1e9a6cbc3689 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 3975470caf4f..978537809d84 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 5576c2841496..99a67e662b3c 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 d74257fd0fe7..55efaf742346 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 0d4a127dd9b3..6ce1e3b6a52c 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 5b54758e2afb..e33c179089db 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 fd6af199247b..6b49797980c4 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 8df2f91e6d98..12dceb27ff20 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 f5f3ad8b62ff..eb6791188cf5 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 987acfafeb83..145dec5267c9 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 af3e5817de98..0b660118ed91 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 26baa620e95b..c646df91a2f7 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 b1c177307677..f2fa60c59343 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 b5257725daad..e26278576b31 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 9676617b4486..80b9c76d436a 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 5b4919191778..3ea24907d52e 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 53bff4c8452b..42f4f55c9458 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 b4801f51b607..6805453c18e7 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 d903959ad695..91ca09fbf6f9 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 4bd75a73ba00..0cbfc0b4398f 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 9b8b89458c4c..6948a6692fc4 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 f879033d9822..cce4f3cd14b3 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 f352cc42f4f8..6bc04aab6ec7 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 e11db26f8ae5..66d0ee8b7776 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 51d5ae210244..6540d657dca4 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 3c79d50814cf..b7d81ba143d1 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 ed055b297c81..4a3b776356c8 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 fd355a99327c..fc2eeb7cb2ea 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 ada922a808e6..2c08f36862eb 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 864fc5ea398c..4527e751b5e0 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 da053313ee5c..ae7d50b05764 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 da4e2ad74b68..0c9216c48762 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 753880a5440c..9c0a1d70fbe8 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 9c4233b23783..ae0de80c1c88 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 573d6068a42e..0874e41609a6 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 c33d7a18d635..21dee7c19afd 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 e66e9b632617..6baabebda11a 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 b1dd3e7d88cb..c3615eab0cc3 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 10b5cfcacf6b..b9c8de461e9e 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 b8029a5583ff..c7a1f0b6a78a 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 700cff77a387..8221b3d2fbf0 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 507a22fab738..7aae0f2a5e0a 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 c777180e1f2f..958a3c15923c 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 a8408b6cacdf..4226dfeb5178 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 dcbaaef6cf11..c43410084838 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 dc63d0818394..3e69c2b66c94 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 fc3545a32771..938bde5876ac 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 c96d500577de..40e03ea2a967 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 3ed247b80662..d326da3976f5 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 a16be19a1305..d4175565dc2c 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 f2393c21fe85..7e0d6a58fc83 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 410aa1189b13..8337e1b9bb8d 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 4ceb05d772ae..63a7f2ebbd01 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 1de509a159c8..1df191e04a24 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 503f087382a4..4c0d0e51d49e 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 5f3eacdd6178..525d160d44f0 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 dc4a86341f91..26df13e43ccd 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 ab431d4cc970..dd4ece372699 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 058935ef3975..9c6c9379da0a 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 a4f7067f72fa..58710eefeac8 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 191176a43e9a..93287c60099b 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 8fadd7cef46c..52a6fe6387de 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 8e75003d62f6..7f29bfce8402 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -17,7 +17,7 @@ */ #include -#include +#include /* for KSYM_SYMBOL_LEN */ #include #include #include -- cgit 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 ac446114cd48..6a0c62d6e442 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 aa242dc99373..7d19816c4cc9 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 f2085b541a24..3e140add5360 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 44f1514b00ba..5bba42c99448 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 38e612e66da5..385c40291cdb 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