From: Alexey Dobriyan <adobriyan@gmail.com>
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
Date: Fri, 20 May 2011 09:15:55 +0300 [thread overview]
Message-ID: <20110520061259.GA13483@p183> (raw)
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 <adobriyan@gmail.com>
---
Kbuild | 45 +++++++++++++++++++++++++++++++++++++++------
include/linux/kernel.h | 27 ++++++++-------------------
kernel/sizeof.c | 10 ++++++++++
lib/kstrtox.c | 19 +++++++++++++------
4 files changed, 70 insertions(+), 31 deletions(-)
--- 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 <generated/sizeof.h>
#include <stdarg.h>
#include <linux/linkage.h>
@@ -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 <linux/kbuild.h>
+
+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 <generated/sizeof.h>
#include <linux/ctype.h>
#include <linux/errno.h>
#include <linux/kernel.h>
@@ -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)
{
next reply other threads:[~2011-05-20 6:15 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-05-20 6:15 Alexey Dobriyan [this message]
2011-05-20 6:20 ` [PATCH] kstrtox: drop kstrtol()/kstrtoul() when possible Geert Uytterhoeven
2011-05-20 6:48 ` Alexey Dobriyan
2011-05-20 6:54 ` Andrew Morton
2011-05-20 7:21 ` Alexey Dobriyan
2011-05-20 7:54 ` Geert Uytterhoeven
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20110520061259.GA13483@p183 \
--to=adobriyan@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=arnd@arndb.de \
--cc=linux-kbuild@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mmarek@suse.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.