kernel/time/timeconst.h is moved to include/generated/ and generated
by the top level Kbuild. This allows using timeconst.h in an earlier
build stage.
Patch was build tested for:
arm - imx_v6_v7_defconfig, vexpress_defconfig
cris - etrax-100lx_v2_defconfig
m68k - multi_defconfig
mips32 - ar7_defconfig,
mips64 - loongson3_defconfig
powerpc - 44x/virtex5_defconfig
powerpc64 - powerpc64_defconfig
sh - se7780_defconfig,
sparc32 - sparc32_defconfig
sparc64 - sparc64_defconfig
x86 64 - x86_64_defconfig,
Patch is against 4.1-rc3 (localversion-next is -next-20150518)
Signed-off-by: Nicholas Mc Guire <[email protected]>
---
Thanks to Joe Perches <[email protected]> for suggesting this approach
and catching the unconditional rebuild (should be fixed here now
properly) as well as for his review comments on the first attempts.
V3: minor change in top level Kbuild to make mips64 build correctly
(timeconst.h added to dependency list of asm-offset.h)
Kbuild | 34 +++++++++++++++++++++++++++-------
kernel/time/Makefile | 17 +----------------
kernel/time/time.c | 2 +-
kernel/time/timeconst.bc | 3 ++-
4 files changed, 31 insertions(+), 25 deletions(-)
diff --git a/Kbuild b/Kbuild
index 6f0d82a..df99a5f 100644
--- a/Kbuild
+++ b/Kbuild
@@ -2,8 +2,9 @@
# Kbuild for top-level directory of the kernel
# This file takes care of the following:
# 1) Generate bounds.h
-# 2) Generate asm-offsets.h (may need bounds.h)
-# 3) Check for missing system calls
+# 2) Generate timeconst.h
+# 3) Generate asm-offsets.h (may need bounds.h and timeconst.h)
+# 4) Check for missing system calls
# Default sed regexp - multiline due to syntax constraints
define sed-y
@@ -47,7 +48,26 @@ $(obj)/$(bounds-file): kernel/bounds.s FORCE
$(call filechk,offsets,__LINUX_BOUNDS_H__)
#####
-# 2) Generate asm-offsets.h
+# 2) Generate timeconst.h
+
+timeconst-file := include/generated/timeconst.h
+
+#always += $(timeconst-file)
+targets += $(timeconst-file)
+
+quiet_cmd_gentimeconst = GEN $@
+define cmd_gentimeconst
+ (echo $(CONFIG_HZ) | bc -q $< ) > $@
+endef
+define filechk_gentimeconst
+ (echo $(CONFIG_HZ) | bc -q $< )
+endef
+
+$(obj)/$(timeconst-file): kernel/time/timeconst.bc FORCE
+ $(call filechk,gentimeconst)
+
+#####
+# 3) Generate asm-offsets.h
#
offsets-file := include/generated/asm-offsets.h
@@ -57,7 +77,7 @@ targets += arch/$(SRCARCH)/kernel/asm-offsets.s
# We use internal kbuild rules to avoid the "is up to date" message from make
arch/$(SRCARCH)/kernel/asm-offsets.s: arch/$(SRCARCH)/kernel/asm-offsets.c \
- $(obj)/$(bounds-file) FORCE
+ $(obj)/$(timeconst-file) $(obj)/$(bounds-file) FORCE
$(Q)mkdir -p $(dir $@)
$(call if_changed_dep,cc_s_c)
@@ -65,7 +85,7 @@ $(obj)/$(offsets-file): arch/$(SRCARCH)/kernel/asm-offsets.s FORCE
$(call filechk,offsets,__ASM_OFFSETS_H__)
#####
-# 3) Check for missing system calls
+# 4) Check for missing system calls
#
always += missing-syscalls
@@ -77,5 +97,5 @@ quiet_cmd_syscalls = CALL $<
missing-syscalls: scripts/checksyscalls.sh $(offsets-file) FORCE
$(call cmd,syscalls)
-# Keep these two files during make clean
-no-clean-files := $(bounds-file) $(offsets-file)
+# Keep these three files during make clean
+no-clean-files := $(bounds-file) $(offsets-file) $(timeconst-file)
diff --git a/kernel/time/Makefile b/kernel/time/Makefile
index 01f0312..ffc4cc3 100644
--- a/kernel/time/Makefile
+++ b/kernel/time/Makefile
@@ -13,19 +13,4 @@ obj-$(CONFIG_TIMER_STATS) += timer_stats.o
obj-$(CONFIG_DEBUG_FS) += timekeeping_debug.o
obj-$(CONFIG_TEST_UDELAY) += test_udelay.o
-$(obj)/time.o: $(obj)/timeconst.h
-
-quiet_cmd_hzfile = HZFILE $@
- cmd_hzfile = echo "hz=$(CONFIG_HZ)" > $@
-
-targets += hz.bc
-$(obj)/hz.bc: $(objtree)/include/config/hz.h FORCE
- $(call if_changed,hzfile)
-
-quiet_cmd_bc = BC $@
- cmd_bc = bc -q $(filter-out FORCE,$^) > $@
-
-targets += timeconst.h
-$(obj)/timeconst.h: $(obj)/hz.bc $(src)/timeconst.bc FORCE
- $(call if_changed,bc)
-
+$(obj)/time.o: $(objtree)/include/config/
diff --git a/kernel/time/time.c b/kernel/time/time.c
index 2c85b77..4fa1d26 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -41,7 +41,7 @@
#include <asm/uaccess.h>
#include <asm/unistd.h>
-#include "timeconst.h"
+#include <generated/timeconst.h>
#include "timekeeping.h"
/*
diff --git a/kernel/time/timeconst.bc b/kernel/time/timeconst.bc
index 511bdf2..c7388de 100644
--- a/kernel/time/timeconst.bc
+++ b/kernel/time/timeconst.bc
@@ -50,7 +50,7 @@ define timeconst(hz) {
print "#include <linux/types.h>\n\n"
print "#if HZ != ", hz, "\n"
- print "#error \qkernel/timeconst.h has the wrong HZ value!\q\n"
+ print "#error \qinclude/generated/timeconst.h has the wrong HZ value!\q\n"
print "#endif\n\n"
if (hz < 2) {
@@ -105,4 +105,5 @@ define timeconst(hz) {
halt
}
+hz = read();
timeconst(hz)
--
1.7.10.4
Refactor the msecs_to_jiffies conditional code part in time.c and
jiffies.h putting it into conditional functions rather than #ifdefs
to improve readability.
Patch was build tested for:
arm - imx_v6_v7_defconfig, vexpress_defconfig
cris - etrax-100lx_v2_defconfig
m68k - multi_defconfig
mips32 - ar7_defconfig,
mips64 - loongson3_defconfig
powerpc - 44x/virtex5_defconfig
powerpc64 - powerpc64_defconfig
sh - se7780_defconfig,
sparc32 - sparc32_defconfig
sparc64 - sparc64_defconfig
x86 64 - x86_64_defconfig,
and boot/run tested for
x86 64 - x86_64_defconfig on an i3
Patch is against 4.1-rc3 (localversion-next is -next-20150518)
Signed-off-by: Nicholas Mc Guire <[email protected]>
---
Thanks to Joe Perches <[email protected]> for suggesting this approach
and for his review comments on the first attempts and for his simple
test-case that helped after I confused my self with .lst files.
V3: refactoring of time.c/jiffies.h as requested by Thomas Gleixner
<[email protected]> without actually adding the builtin_constant_p()
check
include/linux/jiffies.h | 64 ++++++++++++++++++++++++++++++++++++++++++++++-
kernel/time/time.c | 59 ++++++++++++++-----------------------------
2 files changed, 82 insertions(+), 41 deletions(-)
diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index c367cbd..b41e026e 100644
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -7,6 +7,7 @@
#include <linux/time.h>
#include <linux/timex.h>
#include <asm/param.h> /* for HZ */
+#include <generated/timeconst.h>
/*
* The following defines establish the engineering parameters of the PLL
@@ -288,7 +289,68 @@ static inline u64 jiffies_to_nsecs(const unsigned long j)
return (u64)jiffies_to_usecs(j) * NSEC_PER_USEC;
}
-extern unsigned long msecs_to_jiffies(const unsigned int m);
+extern unsigned long __msecs_to_jiffies(const unsigned int m);
+#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
+/*
+ * HZ is equal to or smaller than 1000, and 1000 is a nice round
+ * multiple of HZ, divide with the factor between them, but round
+ * upwards:
+ */
+static inline unsigned long _msecs_to_jiffies(const unsigned int m)
+{
+ return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ);
+}
+#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
+/*
+ * HZ is larger than 1000, and HZ is a nice round multiple of 1000 -
+ * simply multiply with the factor between them.
+ *
+ * But first make sure the multiplication result cannot overflow:
+ */
+static inline unsigned long _msecs_to_jiffies(const unsigned int m)
+{
+ if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
+ return MAX_JIFFY_OFFSET;
+ return m * (HZ / MSEC_PER_SEC);
+}
+#else
+/*
+ * Generic case - multiply, round and divide. But first check that if
+ * we are doing a net multiplication, that we wouldn't overflow:
+ */
+static inline unsigned long _msecs_to_jiffies(const unsigned int m)
+{
+ if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
+ return MAX_JIFFY_OFFSET;
+
+ return (MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32)
+ >> MSEC_TO_HZ_SHR32;
+}
+#endif
+/**
+ * msecs_to_jiffies: - convert milliseconds to jiffies
+ * @m: time in milliseconds
+ *
+ * conversion is done as follows:
+ *
+ * - negative values mean 'infinite timeout' (MAX_JIFFY_OFFSET)
+ *
+ * - 'too large' values [that would result in larger than
+ * MAX_JIFFY_OFFSET values] mean 'infinite timeout' too.
+ *
+ * - all other values are converted to jiffies by either multiplying
+ * the input value by a factor or dividing it with a factor and
+ * handling any 32-bit overflows.
+ * for the details see __msecs_to_jiffies()
+ *
+ * the HZ range specific helpers _msecs_to_jiffies() are called from
+ * __msecs_to_jiffies().
+ */
+static inline unsigned long msecs_to_jiffies(const unsigned int m)
+{
+ return __msecs_to_jiffies(m);
+}
+
extern unsigned long usecs_to_jiffies(const unsigned int u);
extern unsigned long timespec_to_jiffies(const struct timespec *value);
extern void jiffies_to_timespec(const unsigned long jiffies,
diff --git a/kernel/time/time.c b/kernel/time/time.c
index 4fa1d26..884bb8e 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -483,9 +483,11 @@ struct timespec64 ns_to_timespec64(const s64 nsec)
}
EXPORT_SYMBOL(ns_to_timespec64);
#endif
-/*
- * When we convert to jiffies then we interpret incoming values
- * the following way:
+/**
+ * msecs_to_jiffies: - convert milliseconds to jiffies
+ * @m: time in milliseconds
+ *
+ * conversion is done as follows:
*
* - negative values mean 'infinite timeout' (MAX_JIFFY_OFFSET)
*
@@ -493,51 +495,28 @@ EXPORT_SYMBOL(ns_to_timespec64);
* MAX_JIFFY_OFFSET values] mean 'infinite timeout' too.
*
* - all other values are converted to jiffies by either multiplying
- * the input value by a factor or dividing it with a factor
- *
- * We must also be careful about 32-bit overflows.
+ * the input value by a factor or dividing it with a factor and
+ * handling any 32-bit overflows.
+ * for the details see __msecs_to_jiffies()
+ *
+ * msecs_to_jiffies() checks for the passed in value being a constant
+ * via __builtin_constant_p() allowing gcc to eliminate most of the
+ * code, __msecs_to_jiffies() is called if the value passed does not
+ * allow constant folding and the actual conversion must be done at
+ * runtime.
+ * the _msecs_to_jiffies helpers are the HZ dependent conversion
+ * routines found in include/linux/jiffies.h
*/
-unsigned long msecs_to_jiffies(const unsigned int m)
+unsigned long __msecs_to_jiffies(const unsigned int m)
{
/*
* Negative value, means infinite timeout:
*/
if ((int)m < 0)
return MAX_JIFFY_OFFSET;
-
-#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
- /*
- * HZ is equal to or smaller than 1000, and 1000 is a nice
- * round multiple of HZ, divide with the factor between them,
- * but round upwards:
- */
- return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ);
-#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
- /*
- * HZ is larger than 1000, and HZ is a nice round multiple of
- * 1000 - simply multiply with the factor between them.
- *
- * But first make sure the multiplication result cannot
- * overflow:
- */
- if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
- return MAX_JIFFY_OFFSET;
-
- return m * (HZ / MSEC_PER_SEC);
-#else
- /*
- * Generic case - multiply, round and divide. But first
- * check that if we are doing a net multiplication, that
- * we wouldn't overflow:
- */
- if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
- return MAX_JIFFY_OFFSET;
-
- return (MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32)
- >> MSEC_TO_HZ_SHR32;
-#endif
+ return _msecs_to_jiffies(m);
}
-EXPORT_SYMBOL(msecs_to_jiffies);
+EXPORT_SYMBOL(__msecs_to_jiffies);
unsigned long usecs_to_jiffies(const unsigned int u)
{
--
1.7.10.4
To allow constant folding in msecs_to_jiffies() conditionally calls
the HZ dependent _msecs_to_jiffies() helpers or, when gcc can not
figure out constant folding, __msecs_to_jiffies which is the renamed
original msecs_to_jiffies() function.
Patch was build tested for:
arm - imx_v6_v7_defconfig, vexpress_defconfig
cris - etrax-100lx_v2_defconfig
m68k - multi_defconfig
mips32 - ar7_defconfig,
mips64 - loongson3_defconfig
powerpc - 44x/virtex5_defconfig
powerpc64 - powerpc64_defconfig
sh - se7780_defconfig,
sparc32 - sparc32_defconfig
sparc64 - sparc64_defconfig
x86 64 - x86_64_defconfig,
boot and run testing:
x86 64 - x86_64_defconfig i3
Patch is against 4.1-rc3 (localversion-next is -next-20150518)
Signed-off-by: Nicholas Mc Guire <[email protected]>
---
Thanks to Joe Perches <[email protected]> for suggesting this approach
and for his review comments on the first attempts.
include/linux/jiffies.h | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index b41e026e..e96996a 100644
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -343,12 +343,24 @@ static inline unsigned long _msecs_to_jiffies(const unsigned int m)
* handling any 32-bit overflows.
* for the details see __msecs_to_jiffies()
*
- * the HZ range specific helpers _msecs_to_jiffies() are called from
- * __msecs_to_jiffies().
+ * msecs_to_jiffies() checks for the passed in value being a constant
+ * via __builtin_constant_p() allowing gcc to eliminate most of the
+ * code, __msecs_to_jiffies() is called if the value passed does not
+ * allow constant folding and the actual conversion must be done at
+ * runtime.
+ * the HZ range specific helpers _msecs_to_jiffies() are called both
+ * directly here and from __msecs_to_jiffies() in the case where
+ * constant folding is not possible.
*/
static inline unsigned long msecs_to_jiffies(const unsigned int m)
{
- return __msecs_to_jiffies(m);
+ if (__builtin_constant_p(m)) {
+ if ((int)m < 0)
+ return MAX_JIFFY_OFFSET;
+ return _msecs_to_jiffies(m);
+ } else {
+ return __msecs_to_jiffies(m);
+ }
}
extern unsigned long usecs_to_jiffies(const unsigned int u);
--
1.7.10.4
Commit-ID: 0a227985d4a993a322ff72ecbaeee2611d624216
Gitweb: http://git.kernel.org/tip/0a227985d4a993a322ff72ecbaeee2611d624216
Author: Nicholas Mc Guire <[email protected]>
AuthorDate: Mon, 18 May 2015 14:19:12 +0200
Committer: Thomas Gleixner <[email protected]>
CommitDate: Tue, 19 May 2015 15:13:45 +0200
time: Move timeconst.h into include/generated
kernel/time/timeconst.h is moved to include/generated/ and generated
by the top level Kbuild. This allows using timeconst.h in an earlier
build stage.
Signed-off-by: Nicholas Mc Guire <[email protected]>
Cc: Masahiro Yamada <[email protected]>
Cc: Sam Ravnborg <[email protected]>
Cc: Joe Perches <[email protected]>
Cc: John Stultz <[email protected]>
Cc: Andrew Hunter <[email protected]>
Cc: Paul Turner <[email protected]>
Cc: Michal Marek <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
Kbuild | 34 +++++++++++++++++++++++++++-------
kernel/time/Makefile | 17 +----------------
kernel/time/time.c | 2 +-
kernel/time/timeconst.bc | 3 ++-
4 files changed, 31 insertions(+), 25 deletions(-)
diff --git a/Kbuild b/Kbuild
index 6f0d82a..df99a5f 100644
--- a/Kbuild
+++ b/Kbuild
@@ -2,8 +2,9 @@
# Kbuild for top-level directory of the kernel
# This file takes care of the following:
# 1) Generate bounds.h
-# 2) Generate asm-offsets.h (may need bounds.h)
-# 3) Check for missing system calls
+# 2) Generate timeconst.h
+# 3) Generate asm-offsets.h (may need bounds.h and timeconst.h)
+# 4) Check for missing system calls
# Default sed regexp - multiline due to syntax constraints
define sed-y
@@ -47,7 +48,26 @@ $(obj)/$(bounds-file): kernel/bounds.s FORCE
$(call filechk,offsets,__LINUX_BOUNDS_H__)
#####
-# 2) Generate asm-offsets.h
+# 2) Generate timeconst.h
+
+timeconst-file := include/generated/timeconst.h
+
+#always += $(timeconst-file)
+targets += $(timeconst-file)
+
+quiet_cmd_gentimeconst = GEN $@
+define cmd_gentimeconst
+ (echo $(CONFIG_HZ) | bc -q $< ) > $@
+endef
+define filechk_gentimeconst
+ (echo $(CONFIG_HZ) | bc -q $< )
+endef
+
+$(obj)/$(timeconst-file): kernel/time/timeconst.bc FORCE
+ $(call filechk,gentimeconst)
+
+#####
+# 3) Generate asm-offsets.h
#
offsets-file := include/generated/asm-offsets.h
@@ -57,7 +77,7 @@ targets += arch/$(SRCARCH)/kernel/asm-offsets.s
# We use internal kbuild rules to avoid the "is up to date" message from make
arch/$(SRCARCH)/kernel/asm-offsets.s: arch/$(SRCARCH)/kernel/asm-offsets.c \
- $(obj)/$(bounds-file) FORCE
+ $(obj)/$(timeconst-file) $(obj)/$(bounds-file) FORCE
$(Q)mkdir -p $(dir $@)
$(call if_changed_dep,cc_s_c)
@@ -65,7 +85,7 @@ $(obj)/$(offsets-file): arch/$(SRCARCH)/kernel/asm-offsets.s FORCE
$(call filechk,offsets,__ASM_OFFSETS_H__)
#####
-# 3) Check for missing system calls
+# 4) Check for missing system calls
#
always += missing-syscalls
@@ -77,5 +97,5 @@ quiet_cmd_syscalls = CALL $<
missing-syscalls: scripts/checksyscalls.sh $(offsets-file) FORCE
$(call cmd,syscalls)
-# Keep these two files during make clean
-no-clean-files := $(bounds-file) $(offsets-file)
+# Keep these three files during make clean
+no-clean-files := $(bounds-file) $(offsets-file) $(timeconst-file)
diff --git a/kernel/time/Makefile b/kernel/time/Makefile
index 01f0312..ffc4cc3 100644
--- a/kernel/time/Makefile
+++ b/kernel/time/Makefile
@@ -13,19 +13,4 @@ obj-$(CONFIG_TIMER_STATS) += timer_stats.o
obj-$(CONFIG_DEBUG_FS) += timekeeping_debug.o
obj-$(CONFIG_TEST_UDELAY) += test_udelay.o
-$(obj)/time.o: $(obj)/timeconst.h
-
-quiet_cmd_hzfile = HZFILE $@
- cmd_hzfile = echo "hz=$(CONFIG_HZ)" > $@
-
-targets += hz.bc
-$(obj)/hz.bc: $(objtree)/include/config/hz.h FORCE
- $(call if_changed,hzfile)
-
-quiet_cmd_bc = BC $@
- cmd_bc = bc -q $(filter-out FORCE,$^) > $@
-
-targets += timeconst.h
-$(obj)/timeconst.h: $(obj)/hz.bc $(src)/timeconst.bc FORCE
- $(call if_changed,bc)
-
+$(obj)/time.o: $(objtree)/include/config/
diff --git a/kernel/time/time.c b/kernel/time/time.c
index 2c85b77..4fa1d26 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -41,7 +41,7 @@
#include <asm/uaccess.h>
#include <asm/unistd.h>
-#include "timeconst.h"
+#include <generated/timeconst.h>
#include "timekeeping.h"
/*
diff --git a/kernel/time/timeconst.bc b/kernel/time/timeconst.bc
index 511bdf2..c7388de 100644
--- a/kernel/time/timeconst.bc
+++ b/kernel/time/timeconst.bc
@@ -50,7 +50,7 @@ define timeconst(hz) {
print "#include <linux/types.h>\n\n"
print "#if HZ != ", hz, "\n"
- print "#error \qkernel/timeconst.h has the wrong HZ value!\q\n"
+ print "#error \qinclude/generated/timeconst.h has the wrong HZ value!\q\n"
print "#endif\n\n"
if (hz < 2) {
@@ -105,4 +105,5 @@ define timeconst(hz) {
halt
}
+hz = read();
timeconst(hz)
Commit-ID: ca42aaf0c8616cde6161ea4391dff364efeee46a
Gitweb: http://git.kernel.org/tip/ca42aaf0c8616cde6161ea4391dff364efeee46a
Author: Nicholas Mc Guire <[email protected]>
AuthorDate: Mon, 18 May 2015 14:19:13 +0200
Committer: Thomas Gleixner <[email protected]>
CommitDate: Tue, 19 May 2015 15:13:46 +0200
time: Refactor msecs_to_jiffies
Refactor the msecs_to_jiffies conditional code part in time.c and
jiffies.h putting it into conditional functions rather than #ifdefs
to improve readability.
[ tglx: Verified that there is no binary code change ]
Signed-off-by: Nicholas Mc Guire <[email protected]>
Cc: Masahiro Yamada <[email protected]>
Cc: Sam Ravnborg <[email protected]>
Cc: Joe Perches <[email protected]>
Cc: John Stultz <[email protected]>
Cc: Andrew Hunter <[email protected]>
Cc: Paul Turner <[email protected]>
Cc: Michal Marek <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
include/linux/jiffies.h | 64 ++++++++++++++++++++++++++++++++++++++++++++++++-
kernel/time/time.c | 59 +++++++++++++++------------------------------
2 files changed, 82 insertions(+), 41 deletions(-)
diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index c367cbd..9527ddb 100644
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -7,6 +7,7 @@
#include <linux/time.h>
#include <linux/timex.h>
#include <asm/param.h> /* for HZ */
+#include <generated/timeconst.h>
/*
* The following defines establish the engineering parameters of the PLL
@@ -288,7 +289,68 @@ static inline u64 jiffies_to_nsecs(const unsigned long j)
return (u64)jiffies_to_usecs(j) * NSEC_PER_USEC;
}
-extern unsigned long msecs_to_jiffies(const unsigned int m);
+extern unsigned long __msecs_to_jiffies(const unsigned int m);
+#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
+/*
+ * HZ is equal to or smaller than 1000, and 1000 is a nice round
+ * multiple of HZ, divide with the factor between them, but round
+ * upwards:
+ */
+static inline unsigned long _msecs_to_jiffies(const unsigned int m)
+{
+ return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ);
+}
+#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
+/*
+ * HZ is larger than 1000, and HZ is a nice round multiple of 1000 -
+ * simply multiply with the factor between them.
+ *
+ * But first make sure the multiplication result cannot overflow:
+ */
+static inline unsigned long _msecs_to_jiffies(const unsigned int m)
+{
+ if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
+ return MAX_JIFFY_OFFSET;
+ return m * (HZ / MSEC_PER_SEC);
+}
+#else
+/*
+ * Generic case - multiply, round and divide. But first check that if
+ * we are doing a net multiplication, that we wouldn't overflow:
+ */
+static inline unsigned long _msecs_to_jiffies(const unsigned int m)
+{
+ if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
+ return MAX_JIFFY_OFFSET;
+
+ return (MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32)
+ >> MSEC_TO_HZ_SHR32;
+}
+#endif
+/**
+ * msecs_to_jiffies: - convert milliseconds to jiffies
+ * @m: time in milliseconds
+ *
+ * conversion is done as follows:
+ *
+ * - negative values mean 'infinite timeout' (MAX_JIFFY_OFFSET)
+ *
+ * - 'too large' values [that would result in larger than
+ * MAX_JIFFY_OFFSET values] mean 'infinite timeout' too.
+ *
+ * - all other values are converted to jiffies by either multiplying
+ * the input value by a factor or dividing it with a factor and
+ * handling any 32-bit overflows.
+ * for the details see __msecs_to_jiffies()
+ *
+ * the HZ range specific helpers _msecs_to_jiffies() are called from
+ * __msecs_to_jiffies().
+ */
+static inline unsigned long msecs_to_jiffies(const unsigned int m)
+{
+ return __msecs_to_jiffies(m);
+}
+
extern unsigned long usecs_to_jiffies(const unsigned int u);
extern unsigned long timespec_to_jiffies(const struct timespec *value);
extern void jiffies_to_timespec(const unsigned long jiffies,
diff --git a/kernel/time/time.c b/kernel/time/time.c
index 4fa1d26..c42c2c3 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -483,9 +483,11 @@ struct timespec64 ns_to_timespec64(const s64 nsec)
}
EXPORT_SYMBOL(ns_to_timespec64);
#endif
-/*
- * When we convert to jiffies then we interpret incoming values
- * the following way:
+/**
+ * msecs_to_jiffies: - convert milliseconds to jiffies
+ * @m: time in milliseconds
+ *
+ * conversion is done as follows:
*
* - negative values mean 'infinite timeout' (MAX_JIFFY_OFFSET)
*
@@ -493,51 +495,28 @@ EXPORT_SYMBOL(ns_to_timespec64);
* MAX_JIFFY_OFFSET values] mean 'infinite timeout' too.
*
* - all other values are converted to jiffies by either multiplying
- * the input value by a factor or dividing it with a factor
- *
- * We must also be careful about 32-bit overflows.
+ * the input value by a factor or dividing it with a factor and
+ * handling any 32-bit overflows.
+ * for the details see __msecs_to_jiffies()
+ *
+ * msecs_to_jiffies() checks for the passed in value being a constant
+ * via __builtin_constant_p() allowing gcc to eliminate most of the
+ * code, __msecs_to_jiffies() is called if the value passed does not
+ * allow constant folding and the actual conversion must be done at
+ * runtime.
+ * the _msecs_to_jiffies helpers are the HZ dependent conversion
+ * routines found in include/linux/jiffies.h
*/
-unsigned long msecs_to_jiffies(const unsigned int m)
+unsigned long __msecs_to_jiffies(const unsigned int m)
{
/*
* Negative value, means infinite timeout:
*/
if ((int)m < 0)
return MAX_JIFFY_OFFSET;
-
-#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
- /*
- * HZ is equal to or smaller than 1000, and 1000 is a nice
- * round multiple of HZ, divide with the factor between them,
- * but round upwards:
- */
- return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ);
-#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
- /*
- * HZ is larger than 1000, and HZ is a nice round multiple of
- * 1000 - simply multiply with the factor between them.
- *
- * But first make sure the multiplication result cannot
- * overflow:
- */
- if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
- return MAX_JIFFY_OFFSET;
-
- return m * (HZ / MSEC_PER_SEC);
-#else
- /*
- * Generic case - multiply, round and divide. But first
- * check that if we are doing a net multiplication, that
- * we wouldn't overflow:
- */
- if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
- return MAX_JIFFY_OFFSET;
-
- return (MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32)
- >> MSEC_TO_HZ_SHR32;
-#endif
+ return _msecs_to_jiffies(m);
}
-EXPORT_SYMBOL(msecs_to_jiffies);
+EXPORT_SYMBOL(__msecs_to_jiffies);
unsigned long usecs_to_jiffies(const unsigned int u)
{
Commit-ID: daa67b4b70568a07fef3cffacb2055891bf42ddb
Gitweb: http://git.kernel.org/tip/daa67b4b70568a07fef3cffacb2055891bf42ddb
Author: Nicholas Mc Guire <[email protected]>
AuthorDate: Mon, 18 May 2015 14:19:14 +0200
Committer: Thomas Gleixner <[email protected]>
CommitDate: Tue, 19 May 2015 15:14:16 +0200
time: Allow gcc to fold constants when possible
To allow constant folding in msecs_to_jiffies() conditionally calls
the HZ dependent _msecs_to_jiffies() helpers or, when gcc can not
figure out constant folding, __msecs_to_jiffies which is the renamed
original msecs_to_jiffies() function.
Signed-off-by: Nicholas Mc Guire <[email protected]>
Cc: Masahiro Yamada <[email protected]>
Cc: Sam Ravnborg <[email protected]>
Cc: Joe Perches <[email protected]>
Cc: John Stultz <[email protected]>
Cc: Andrew Hunter <[email protected]>
Cc: Paul Turner <[email protected]>
Cc: Michal Marek <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
include/linux/jiffies.h | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index 9527ddb..5e75af6 100644
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -343,12 +343,24 @@ static inline unsigned long _msecs_to_jiffies(const unsigned int m)
* handling any 32-bit overflows.
* for the details see __msecs_to_jiffies()
*
- * the HZ range specific helpers _msecs_to_jiffies() are called from
- * __msecs_to_jiffies().
+ * msecs_to_jiffies() checks for the passed in value being a constant
+ * via __builtin_constant_p() allowing gcc to eliminate most of the
+ * code, __msecs_to_jiffies() is called if the value passed does not
+ * allow constant folding and the actual conversion must be done at
+ * runtime.
+ * the HZ range specific helpers _msecs_to_jiffies() are called both
+ * directly here and from __msecs_to_jiffies() in the case where
+ * constant folding is not possible.
*/
static inline unsigned long msecs_to_jiffies(const unsigned int m)
{
- return __msecs_to_jiffies(m);
+ if (__builtin_constant_p(m)) {
+ if ((int)m < 0)
+ return MAX_JIFFY_OFFSET;
+ return _msecs_to_jiffies(m);
+ } else {
+ return __msecs_to_jiffies(m);
+ }
}
extern unsigned long usecs_to_jiffies(const unsigned int u);
On Tue, 2015-05-19 at 06:36 -0700, tip-bot for Nicholas Mc Guire wrote:
> Refactor the msecs_to_jiffies conditional code part in time.c and
> jiffies.h putting it into conditional functions rather than #ifdefs
> to improve readability.
[]
> diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
[]
> +static inline unsigned long _msecs_to_jiffies(const unsigned int m)
> +{
> + return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ);
> +}
> +#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
> +/*
> + * HZ is larger than 1000, and HZ is a nice round multiple of 1000 -
> + * simply multiply with the factor between them.
> + *
> + * But first make sure the multiplication result cannot overflow:
> + */
> +static inline unsigned long _msecs_to_jiffies(const unsigned int m)
> +{
> + if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
> + return MAX_JIFFY_OFFSET;
> + return m * (HZ / MSEC_PER_SEC);
> +}
> +#else
> +/*
> + * Generic case - multiply, round and divide. But first check that if
> + * we are doing a net multiplication, that we wouldn't overflow:
> + */
> +static inline unsigned long _msecs_to_jiffies(const unsigned int m)
> +{
> + if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
> + return MAX_JIFFY_OFFSET;
> +
> + return (MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32)
> + >> MSEC_TO_HZ_SHR32;
> +}
> +#endif
It'd be nicer to remove 1 level of unnecessary tab indentation in
all the _msecs_to_jiffies functions here.
On Tue, 19 May 2015, Joe Perches wrote:
> On Tue, 2015-05-19 at 06:36 -0700, tip-bot for Nicholas Mc Guire wrote:
> > Refactor the msecs_to_jiffies conditional code part in time.c and
> > jiffies.h putting it into conditional functions rather than #ifdefs
> > to improve readability.
> []
> > diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
> []
> > +static inline unsigned long _msecs_to_jiffies(const unsigned int m)
> > +{
> > + return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ);
> > +}
> > +#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
> > +/*
> > + * HZ is larger than 1000, and HZ is a nice round multiple of 1000 -
> > + * simply multiply with the factor between them.
> > + *
> > + * But first make sure the multiplication result cannot overflow:
> > + */
> > +static inline unsigned long _msecs_to_jiffies(const unsigned int m)
> > +{
> > + if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
> > + return MAX_JIFFY_OFFSET;
> > + return m * (HZ / MSEC_PER_SEC);
> > +}
> > +#else
> > +/*
> > + * Generic case - multiply, round and divide. But first check that if
> > + * we are doing a net multiplication, that we wouldn't overflow:
> > + */
> > +static inline unsigned long _msecs_to_jiffies(const unsigned int m)
> > +{
> > + if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
> > + return MAX_JIFFY_OFFSET;
> > +
> > + return (MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32)
> > + >> MSEC_TO_HZ_SHR32;
> > +}
> > +#endif
>
> It'd be nicer to remove 1 level of unnecessary tab indentation in
> all the _msecs_to_jiffies functions here.
>
oops - sorry - no idea how I did that - will fix up and resend
thx!
hofrat
On Tue, 19 May 2015, Joe Perches wrote:
> On Tue, 2015-05-19 at 06:36 -0700, tip-bot for Nicholas Mc Guire wrote:
> > Refactor the msecs_to_jiffies conditional code part in time.c and
> > jiffies.h putting it into conditional functions rather than #ifdefs
> > to improve readability.
> []
> > diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
> []
> > +static inline unsigned long _msecs_to_jiffies(const unsigned int m)
> > +{
> > + return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ);
> > +}
> > +#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
> > +/*
> > + * HZ is larger than 1000, and HZ is a nice round multiple of 1000 -
> > + * simply multiply with the factor between them.
> > + *
> > + * But first make sure the multiplication result cannot overflow:
> > + */
> > +static inline unsigned long _msecs_to_jiffies(const unsigned int m)
> > +{
> > + if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
> > + return MAX_JIFFY_OFFSET;
> > + return m * (HZ / MSEC_PER_SEC);
> > +}
> > +#else
> > +/*
> > + * Generic case - multiply, round and divide. But first check that if
> > + * we are doing a net multiplication, that we wouldn't overflow:
> > + */
> > +static inline unsigned long _msecs_to_jiffies(const unsigned int m)
> > +{
> > + if (HZ > MSEC_PER_SEC && m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
> > + return MAX_JIFFY_OFFSET;
> > +
> > + return (MSEC_TO_HZ_MUL32 * m + MSEC_TO_HZ_ADJ32)
> > + >> MSEC_TO_HZ_SHR32;
> > +}
> > +#endif
>
> It'd be nicer to remove 1 level of unnecessary tab indentation in
> all the _msecs_to_jiffies functions here.
Indeed. I wanted to fix that up before applying and then forgot
again....
Thanks,
tglx
On Tue, 19 May 2015, Nicholas Mc Guire wrote:
> >
> oops - sorry - no idea how I did that - will fix up and resend
No. It's applied already, so we need to fix it with a delta patch,
which I pushed out already.
Thanks,
tglx
On Tue, 19 May 2015, Thomas Gleixner wrote:
> On Tue, 19 May 2015, Nicholas Mc Guire wrote:
> > >
> > oops - sorry - no idea how I did that - will fix up and resend
>
> No. It's applied already, so we need to fix it with a delta patch,
> which I pushed out already.
>
ok - many thanks for cleaning this up.
thx!
hofrat
On 05/19/2015 06:36 AM, tip-bot for Nicholas Mc Guire wrote:
> Commit-ID: 0a227985d4a993a322ff72ecbaeee2611d624216
> Gitweb: http://git.kernel.org/tip/0a227985d4a993a322ff72ecbaeee2611d624216
> Author: Nicholas Mc Guire <[email protected]>
> AuthorDate: Mon, 18 May 2015 14:19:12 +0200
> Committer: Thomas Gleixner <[email protected]>
> CommitDate: Tue, 19 May 2015 15:13:45 +0200
>
> time: Move timeconst.h into include/generated
>
> kernel/time/timeconst.h is moved to include/generated/ and generated
> by the top level Kbuild. This allows using timeconst.h in an earlier
> build stage.
>
> Signed-off-by: Nicholas Mc Guire <[email protected]>
> Cc: Masahiro Yamada <[email protected]>
> Cc: Sam Ravnborg <[email protected]>
> Cc: Joe Perches <[email protected]>
> Cc: John Stultz <[email protected]>
> Cc: Andrew Hunter <[email protected]>
> Cc: Paul Turner <[email protected]>
> Cc: Michal Marek <[email protected]>
> Link: http://lkml.kernel.org/r/[email protected]
> Signed-off-by: Thomas Gleixner <[email protected]>
> ---
This patch seems to cause kernel/time/time.c to always need to be
recompiled and the vmlinux to be relinked even if nothing has changed.
make V=2 shows
CC kernel/time/time.o - due to: include/config/
> diff --git a/Kbuild b/Kbuild
> index 6f0d82a..df99a5f 100644
> --- a/Kbuild
> +++ b/Kbuild
> @@ -2,8 +2,9 @@
> # Kbuild for top-level directory of the kernel
> # This file takes care of the following:
> # 1) Generate bounds.h
> -# 2) Generate asm-offsets.h (may need bounds.h)
> -# 3) Check for missing system calls
> +# 2) Generate timeconst.h
> +# 3) Generate asm-offsets.h (may need bounds.h and timeconst.h)
> +# 4) Check for missing system calls
>
> # Default sed regexp - multiline due to syntax constraints
> define sed-y
> @@ -47,7 +48,26 @@ $(obj)/$(bounds-file): kernel/bounds.s FORCE
> $(call filechk,offsets,__LINUX_BOUNDS_H__)
>
> #####
> -# 2) Generate asm-offsets.h
> +# 2) Generate timeconst.h
> +
> +timeconst-file := include/generated/timeconst.h
> +
> +#always += $(timeconst-file)
Is there a reason this is commented out instead of removed?
> +targets += $(timeconst-file)
> +
> +quiet_cmd_gentimeconst = GEN $@
> +define cmd_gentimeconst
> [...]
> diff --git a/kernel/time/Makefile b/kernel/time/Makefile
> index 01f0312..ffc4cc3 100644
> --- a/kernel/time/Makefile
> +++ b/kernel/time/Makefile
> @@ -13,19 +13,4 @@ obj-$(CONFIG_TIMER_STATS) += timer_stats.o
> obj-$(CONFIG_DEBUG_FS) += timekeeping_debug.o
> obj-$(CONFIG_TEST_UDELAY) += test_udelay.o
>
> -$(obj)/time.o: $(obj)/timeconst.h
> -
> -quiet_cmd_hzfile = HZFILE $@
> - cmd_hzfile = echo "hz=$(CONFIG_HZ)" > $@
> -
> -targets += hz.bc
> -$(obj)/hz.bc: $(objtree)/include/config/hz.h FORCE
> - $(call if_changed,hzfile)
> -
> -quiet_cmd_bc = BC $@
> - cmd_bc = bc -q $(filter-out FORCE,$^) > $@
> -
> -targets += timeconst.h
> -$(obj)/timeconst.h: $(obj)/hz.bc $(src)/timeconst.bc FORCE
> - $(call if_changed,bc)
> -
> +$(obj)/time.o: $(objtree)/include/config/
It looks like it has to recompile because of this dependency. Can't we
just remove this line?
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
On Mon, 29 Jun 2015, Stephen Boyd wrote:
> On 05/19/2015 06:36 AM, tip-bot for Nicholas Mc Guire wrote:
> > Commit-ID: 0a227985d4a993a322ff72ecbaeee2611d624216
> > Gitweb: http://git.kernel.org/tip/0a227985d4a993a322ff72ecbaeee2611d624216
> > Author: Nicholas Mc Guire <[email protected]>
> > AuthorDate: Mon, 18 May 2015 14:19:12 +0200
> > Committer: Thomas Gleixner <[email protected]>
> > CommitDate: Tue, 19 May 2015 15:13:45 +0200
> >
> > time: Move timeconst.h into include/generated
> >
> > kernel/time/timeconst.h is moved to include/generated/ and generated
> > by the top level Kbuild. This allows using timeconst.h in an earlier
> > build stage.
> >
> > Signed-off-by: Nicholas Mc Guire <[email protected]>
> > Cc: Masahiro Yamada <[email protected]>
> > Cc: Sam Ravnborg <[email protected]>
> > Cc: Joe Perches <[email protected]>
> > Cc: John Stultz <[email protected]>
> > Cc: Andrew Hunter <[email protected]>
> > Cc: Paul Turner <[email protected]>
> > Cc: Michal Marek <[email protected]>
> > Link: http://lkml.kernel.org/r/[email protected]
> > Signed-off-by: Thomas Gleixner <[email protected]>
> > ---
>
> This patch seems to cause kernel/time/time.c to always need to be
> recompiled and the vmlinux to be relinked even if nothing has changed.
>
> make V=2 shows
>
> CC kernel/time/time.o - due to: include/config/
>
>
> > diff --git a/Kbuild b/Kbuild
> > index 6f0d82a..df99a5f 100644
> > --- a/Kbuild
> > +++ b/Kbuild
> > @@ -2,8 +2,9 @@
> > # Kbuild for top-level directory of the kernel
> > # This file takes care of the following:
> > # 1) Generate bounds.h
> > -# 2) Generate asm-offsets.h (may need bounds.h)
> > -# 3) Check for missing system calls
> > +# 2) Generate timeconst.h
> > +# 3) Generate asm-offsets.h (may need bounds.h and timeconst.h)
> > +# 4) Check for missing system calls
> >
> > # Default sed regexp - multiline due to syntax constraints
> > define sed-y
> > @@ -47,7 +48,26 @@ $(obj)/$(bounds-file): kernel/bounds.s FORCE
> > $(call filechk,offsets,__LINUX_BOUNDS_H__)
> >
> > #####
> > -# 2) Generate asm-offsets.h
> > +# 2) Generate timeconst.h
> > +
> > +timeconst-file := include/generated/timeconst.h
> > +
> > +#always += $(timeconst-file)
>
> Is there a reason this is commented out instead of removed?
negligence on my side - should have been removed
>
> > +targets += $(timeconst-file)
> > +
> > +quiet_cmd_gentimeconst = GEN $@
> > +define cmd_gentimeconst
> > [...]
> > diff --git a/kernel/time/Makefile b/kernel/time/Makefile
> > index 01f0312..ffc4cc3 100644
> > --- a/kernel/time/Makefile
> > +++ b/kernel/time/Makefile
> > @@ -13,19 +13,4 @@ obj-$(CONFIG_TIMER_STATS) += timer_stats.o
> > obj-$(CONFIG_DEBUG_FS) += timekeeping_debug.o
> > obj-$(CONFIG_TEST_UDELAY) += test_udelay.o
> >
> > -$(obj)/time.o: $(obj)/timeconst.h
> > -
> > -quiet_cmd_hzfile = HZFILE $@
> > - cmd_hzfile = echo "hz=$(CONFIG_HZ)" > $@
> > -
> > -targets += hz.bc
> > -$(obj)/hz.bc: $(objtree)/include/config/hz.h FORCE
> > - $(call if_changed,hzfile)
> > -
> > -quiet_cmd_bc = BC $@
> > - cmd_bc = bc -q $(filter-out FORCE,$^) > $@
> > -
> > -targets += timeconst.h
> > -$(obj)/timeconst.h: $(obj)/hz.bc $(src)/timeconst.bc FORCE
> > - $(call if_changed,bc)
> > -
> > +$(obj)/time.o: $(objtree)/include/config/
>
> It looks like it has to recompile because of this dependency. Can't we
> just remove this line?
>
yup - thats ok to drop as well - sorry that should have gone out
after build testing.
thx!
hofrat