From patchwork Fri May 20 06:15:55 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Dobriyan X-Patchwork-Id: 802202 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.3) with ESMTP id p4K6G0Zc018169 for ; Fri, 20 May 2011 06:16:01 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932819Ab1ETGP7 (ORCPT ); Fri, 20 May 2011 02:15:59 -0400 Received: from mail-fx0-f46.google.com ([209.85.161.46]:64512 "EHLO mail-fx0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932787Ab1ETGP6 (ORCPT ); Fri, 20 May 2011 02:15:58 -0400 Received: by fxm17 with SMTP id 17so2476346fxm.19 for ; Thu, 19 May 2011 23:15:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:date:from:to:cc:subject:message-id:mime-version :content-type:content-disposition:user-agent; bh=ZbHex5gkn+xWL2DyvdwNoq99KtLTPqS0E2EHgup4I6c=; b=GW2bBrjjMkucpmNDdAxTdMCZHcCXwo1Y/98nU3I3OebvrCwz6K7dtxrMSt6rXJFPIj EOXG7bIzXmF4WJWYUCTKyaToYXk7xajTgiM7nS1VmcmpH0ms85SGnxpmsDIQbPjmdBX9 uMLSZnO+fgGau830J7i+mhka5TKo8qJYc4H1A= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=date:from:to:cc:subject:message-id:mime-version:content-type :content-disposition:user-agent; b=ufi6FvsMOg75vYrtayPRsXs2m8kAJbpsl30w4CnQ8OvCx5kE7pleoC7PJqcrkMTFKc u/ywmCkh91fiMGBmRm3MNnamtd66Fw1j1s8l/XObiKfRyXTO/Gb5JaRhEHsrvdCcaNzj gQUvvmcwbPXJdfnmLWkMWTqihdb/C7hwWGfOw= Received: by 10.223.87.215 with SMTP id x23mr1950683fal.32.1305872156695; Thu, 19 May 2011 23:15:56 -0700 (PDT) Received: from p183 (vulture-nat-36.telecom.by [213.184.224.36]) by mx.google.com with ESMTPS id j12sm1314505fax.9.2011.05.19.23.15.54 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 19 May 2011 23:15:55 -0700 (PDT) Date: Fri, 20 May 2011 09:15:55 +0300 From: Alexey Dobriyan To: akpm@linux-foundation.org Cc: linux-kernel@vger.kernel.org, arnd@arndb.de, mmarek@suse.cz, linux-kbuild@vger.kernel.org Subject: [PATCH] kstrtox: drop kstrtol()/kstrtoul() when possible Message-ID: <20110520061259.GA13483@p183> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kbuild-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kbuild@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Fri, 20 May 2011 06:16:01 +0000 (UTC) If "long" and "long long" types are identical at runtime, kstrtol() can be aliased to kstrtoll(). Unfortunately, one can't write #if sizeof(long) == sizeof(long long) ... To solve this, generate header file with sizes and alignment of interesting types like we do with bounds.h and asm-offsets.h. Everything above applies to "unsigned long" and kstrtoul(). Signed-off-by: Alexey Dobriyan --- Kbuild | 45 +++++++++++++++++++++++++++++++++++++++------ include/linux/kernel.h | 27 ++++++++------------------- kernel/sizeof.c | 10 ++++++++++ lib/kstrtox.c | 19 +++++++++++++------ 4 files changed, 70 insertions(+), 31 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-kbuild" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html --- a/Kbuild +++ b/Kbuild @@ -5,13 +5,16 @@ # 2) Generate asm-offsets.h (may need bounds.h) # 3) Check for missing system calls +always := +targets := + ##### -# 1) Generate bounds.h +# Generate bounds.h bounds-file := include/generated/bounds.h -always := $(bounds-file) -targets := $(bounds-file) kernel/bounds.s +always += $(bounds-file) +targets += $(bounds-file) kernel/bounds.s quiet_cmd_bounds = GEN $@ define cmd_bounds @@ -39,8 +42,38 @@ $(obj)/$(bounds-file): kernel/bounds.s Kbuild $(Q)mkdir -p $(dir $@) $(call cmd,bounds) +# generated/sizeof.h +sizeof-file := include/generated/sizeof.h + +always += $(sizeof-file) +targets += $(sizeof-file) kernel/sizeof.s + +quiet_cmd_sizeof = GEN $@ +define cmd_sizeof + ( \ + set -e; \ + echo "#ifndef _LINUX_SIZEOF_H"; \ + echo "#define _LINUX_SIZEOF_H"; \ + echo "/*"; \ + echo " * This file is automatically generated from kernel/sizeof.c .";\ + echo " * Modifying is futile."; \ + echo " */"; \ + sed -ne $(sed-y) $<; \ + echo "#endif" \ + ) >$@ +endef + +# We use internal kbuild rules to avoid the "is up to date" message from make +kernel/sizeof.s: kernel/sizeof.c FORCE + $(Q)mkdir -p $(dir $@) + $(call if_changed_dep,cc_s_c) + +$(obj)/$(sizeof-file): kernel/sizeof.s Kbuild + $(Q)mkdir -p $(dir $@) + $(call cmd,sizeof) + ##### -# 2) Generate asm-offsets.h +# Generate asm-offsets.h # offsets-file := include/generated/asm-offsets.h @@ -85,7 +118,7 @@ $(obj)/$(offsets-file): arch/$(SRCARCH)/kernel/asm-offsets.s Kbuild $(call cmd,offsets) ##### -# 3) Check for missing system calls +# Check for missing system calls # quiet_cmd_syscalls = CALL $< @@ -96,4 +129,4 @@ missing-syscalls: scripts/checksyscalls.sh FORCE $(call cmd,syscalls) # Keep these two files during make clean -no-clean-files := $(bounds-file) $(offsets-file) +no-clean-files := $(bounds-file) $(offsets-file) $(sizeof-file) --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -8,6 +8,7 @@ #define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask)) #ifdef __KERNEL__ +#include #include #include @@ -194,32 +195,20 @@ int __must_check _kstrtol(const char *s, unsigned int base, long *res); int __must_check kstrtoull(const char *s, unsigned int base, unsigned long long *res); int __must_check kstrtoll(const char *s, unsigned int base, long long *res); +#if SIZEOF_LONG == SIZEOF_LONG_LONG && ALIGNOF_LONG == ALIGNOF_LONG_LONG static inline int __must_check kstrtoul(const char *s, unsigned int base, unsigned long *res) { - /* - * We want to shortcut function call, but - * __builtin_types_compatible_p(unsigned long, unsigned long long) = 0. - */ - if (sizeof(unsigned long) == sizeof(unsigned long long) && - __alignof__(unsigned long) == __alignof__(unsigned long long)) - return kstrtoull(s, base, (unsigned long long *)res); - else - return _kstrtoul(s, base, res); + return kstrtoull(s, base, (unsigned long long *)res); } static inline int __must_check kstrtol(const char *s, unsigned int base, long *res) { - /* - * We want to shortcut function call, but - * __builtin_types_compatible_p(long, long long) = 0. - */ - if (sizeof(long) == sizeof(long long) && - __alignof__(long) == __alignof__(long long)) - return kstrtoll(s, base, (long long *)res); - else - return _kstrtol(s, base, res); + return kstrtoll(s, base, (long long *)res); } - +#else +int __must_check kstrtoul(const char *s, unsigned int base, unsigned long *res); +int __must_check kstrtol(const char *s, unsigned int base, long *res); +#endif int __must_check kstrtouint(const char *s, unsigned int base, unsigned int *res); int __must_check kstrtoint(const char *s, unsigned int base, int *res); new file mode 100644 --- /dev/null +++ b/kernel/sizeof.c @@ -0,0 +1,10 @@ +#include + +void f(void) +{ + DEFINE(SIZEOF_LONG, sizeof(long)); + DEFINE(ALIGNOF_LONG, __alignof__(long)); + + DEFINE(SIZEOF_LONG_LONG, sizeof(long long)); + DEFINE(ALIGNOF_LONG_LONG, __alignof__(long long)); +} --- a/lib/kstrtox.c +++ b/lib/kstrtox.c @@ -11,6 +11,7 @@ * * If -E is returned, result is not touched. */ +#include #include #include #include @@ -101,8 +102,14 @@ int kstrtoll(const char *s, unsigned int base, long long *res) } EXPORT_SYMBOL(kstrtoll); -/* Internal, do not use. */ -int _kstrtoul(const char *s, unsigned int base, unsigned long *res) +#if SIZEOF_LONG == SIZEOF_LONG_LONG && ALIGNOF_LONG == ALIGNOF_LONG_LONG +/* + * Shortcut function call if types are indistinguishable at runtime. + * FYI, both __builtin_types_compatible_p(unsigned long, unsigned long long) + * and __builtin_types_compatible_p(long, long long) are always 0. + */ +#else +int kstrtoul(const char *s, unsigned int base, unsigned long *res) { unsigned long long tmp; int rv; @@ -115,10 +122,9 @@ int _kstrtoul(const char *s, unsigned int base, unsigned long *res) *res = tmp; return 0; } -EXPORT_SYMBOL(_kstrtoul); +EXPORT_SYMBOL(kstrtoul); -/* Internal, do not use. */ -int _kstrtol(const char *s, unsigned int base, long *res) +int kstrtol(const char *s, unsigned int base, long *res) { long long tmp; int rv; @@ -131,7 +137,8 @@ int _kstrtol(const char *s, unsigned int base, long *res) *res = tmp; return 0; } -EXPORT_SYMBOL(_kstrtol); +EXPORT_SYMBOL(kstrtol); +#endif int kstrtouint(const char *s, unsigned int base, unsigned int *res) {