Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
Checking mergeability… Don't worry, you can still create the pull request.
  • 4 commits
  • 33 files changed
  • 0 commit comments
  • 3 contributors
Commits on May 22, 2012
Peter Zijlstra math128: Introduce various 128bit primitives
Grow rudimentary u128 support without relying on gcc/libgcc.

Cc: Ingo Molnar <mingo@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/n/tip-pppjsy9fz2v57x98hsts2cj3@git.kernel.org
004d99c
Peter Zijlstra math128, x86_64: Implement {mul,add}_u128 in 64bit asm
Enable __int128 usage when available, if not, provide asm versions of
mul_u64_u64 and add_u128.

Cc: Ingo Molnar <mingo@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/n/tip-67zk6v8agsi8m7k1bdcd0srw@git.kernel.org
f12a071
@jlelli sched-dl: use u128 ops inside dl_entity_overflow. 50e6dbd
@fchecconi fchecconi sched-dl: doc typos fixed. 8e2aa26
Showing with 312 additions and 10 deletions.
  1. +14 −5 Documentation/scheduler/sched-deadline.txt
  2. +1 −0  arch/alpha/include/asm/Kbuild
  3. +1 −0  arch/arm/include/asm/Kbuild
  4. +1 −0  arch/avr32/include/asm/Kbuild
  5. +1 −0  arch/blackfin/include/asm/Kbuild
  6. +1 −0  arch/c6x/include/asm/Kbuild
  7. +1 −0  arch/cris/include/asm/Kbuild
  8. +1 −0  arch/frv/include/asm/Kbuild
  9. +1 −0  arch/h8300/include/asm/Kbuild
  10. +1 −0  arch/hexagon/include/asm/Kbuild
  11. +1 −0  arch/ia64/include/asm/Kbuild
  12. +1 −0  arch/m32r/include/asm/Kbuild
  13. +1 −0  arch/m68k/include/asm/Kbuild
  14. +1 −0  arch/microblaze/include/asm/Kbuild
  15. +1 −0  arch/mips/include/asm/Kbuild
  16. +1 −0  arch/mn10300/include/asm/Kbuild
  17. +1 −0  arch/openrisc/include/asm/Kbuild
  18. +1 −0  arch/parisc/include/asm/Kbuild
  19. +1 −0  arch/powerpc/include/asm/Kbuild
  20. +1 −0  arch/s390/include/asm/Kbuild
  21. +1 −0  arch/score/include/asm/Kbuild
  22. +1 −0  arch/sh/include/asm/Kbuild
  23. +1 −0  arch/sparc/include/asm/Kbuild
  24. +1 −0  arch/tile/include/asm/Kbuild
  25. +1 −0  arch/um/include/asm/Kbuild
  26. +1 −0  arch/unicore32/include/asm/Kbuild
  27. +39 −0 arch/x86/include/asm/math128.h
  28. +1 −0  arch/xtensa/include/asm/Kbuild
  29. +4 −0 include/asm-generic/math128.h
  30. +180 −0 include/linux/math128.h
  31. +8 −4 kernel/sched/dl.c
  32. +1 −1  lib/Makefile
  33. +40 −0 lib/math128.c
View
19 Documentation/scheduler/sched-deadline.txt
@@ -35,12 +35,12 @@ CONTENTS
2. Task scheduling
==================
- The typical -deadline task will be made up of a computation phase (instance)
+ The typical -deadline task is composed of a computation phase (instance)
which is activated on a periodic or sporadic fashion. The expected (maximum)
duration of such computation is called the task's runtime; the time interval
by which each instance needs to be completed is called the task's relative
deadline. The task's absolute deadline is dynamically calculated as the
- time instant a task (better, an instance) activates plus the relative
+ time instant a task (or, more properly) activates plus the relative
deadline.
The EDF[1] algorithm selects the task with the smallest absolute deadline as
@@ -147,9 +147,18 @@ someone must call sched_setscheduler2() on it, or it won't even start.
3. Future plans
===============
-Still Missing:
+Still missing:
- refinements to deadline inheritance, especially regarding the possibility
of retaining bandwidth isolation among non-interacting tasks. This is
- being studied from both theoretical and practical point of views, and
- hopefully we can have some demonstrative code soon.
+ being studied from both theoretical and practical points of view, and
+ hopefully we should be able to produce some demonstrative code soon.
+ - (c)group based bandwidth management, and maybe scheduling;
+ - access control for non-root users (and related security concerns to
+ address), which is the best way to allow unprivileged use of the mechanisms
+ and how to prevent non-root users "cheat" the system?
+
+As already discussed, we are planning also to merge this work with the EDF
+throttling patches [https://lkml.org/lkml/2010/2/23/239] but we still are in
+the preliminary phases of the merge and we really seek feedback that would help us
+decide on the direction it should take.
View
1  arch/alpha/include/asm/Kbuild
@@ -8,3 +8,4 @@ header-y += pal.h
header-y += reg.h
header-y += regdef.h
header-y += sysinfo.h
+generic-y += math128.h
View
1  arch/arm/include/asm/Kbuild
@@ -18,3 +18,4 @@ generic-y += resource.h
generic-y += sections.h
generic-y += siginfo.h
generic-y += sizes.h
+generic-y += math128.h
View
1  arch/avr32/include/asm/Kbuild
@@ -1,3 +1,4 @@
include include/asm-generic/Kbuild.asm
header-y += cachectl.h
+generic-y += math128.h
View
1  arch/blackfin/include/asm/Kbuild
@@ -47,3 +47,4 @@ generic-y += xor.h
header-y += bfin_sport.h
header-y += cachectl.h
header-y += fixed_code.h
+generic-y += math128.h
View
1  arch/c6x/include/asm/Kbuild
@@ -51,3 +51,4 @@ generic-y += types.h
generic-y += ucontext.h
generic-y += user.h
generic-y += vga.h
+generic-y += math128.h
View
1  arch/cris/include/asm/Kbuild
@@ -8,3 +8,4 @@ header-y += etraxgpio.h
header-y += rs485.h
header-y += rtc.h
header-y += sync_serial.h
+generic-y += math128.h
View
1  arch/frv/include/asm/Kbuild
@@ -2,3 +2,4 @@ include include/asm-generic/Kbuild.asm
header-y += registers.h
header-y += termios.h
+generic-y += math128.h
View
1  arch/h8300/include/asm/Kbuild
@@ -1 +1,2 @@
include include/asm-generic/Kbuild.asm
+generic-y += math128.h
View
1  arch/hexagon/include/asm/Kbuild
@@ -56,3 +56,4 @@ generic-y += types.h
generic-y += ucontext.h
generic-y += unaligned.h
generic-y += xor.h
+generic-y += math128.h
View
1  arch/ia64/include/asm/Kbuild
@@ -12,3 +12,4 @@ header-y += ptrace_offsets.h
header-y += rse.h
header-y += ucontext.h
header-y += ustack.h
+generic-y += math128.h
View
1  arch/m32r/include/asm/Kbuild
@@ -1 +1,2 @@
include include/asm-generic/Kbuild.asm
+generic-y += math128.h
View
1  arch/m68k/include/asm/Kbuild
@@ -1,2 +1,3 @@
include include/asm-generic/Kbuild.asm
header-y += cachectl.h
+generic-y += math128.h
View
1  arch/microblaze/include/asm/Kbuild
@@ -1,3 +1,4 @@
include include/asm-generic/Kbuild.asm
header-y += elf.h
+generic-y += math128.h
View
1  arch/mips/include/asm/Kbuild
@@ -3,3 +3,4 @@ include include/asm-generic/Kbuild.asm
header-y += cachectl.h
header-y += sgidefs.h
header-y += sysmips.h
+generic-y += math128.h
View
1  arch/mn10300/include/asm/Kbuild
@@ -1 +1,2 @@
include include/asm-generic/Kbuild.asm
+generic-y += math128.h
View
1  arch/openrisc/include/asm/Kbuild
@@ -65,3 +65,4 @@ generic-y += topology.h
generic-y += types.h
generic-y += ucontext.h
generic-y += user.h
+generic-y += math128.h
View
1  arch/parisc/include/asm/Kbuild
@@ -1,3 +1,4 @@
include include/asm-generic/Kbuild.asm
header-y += pdc.h
+generic-y += math128.h
View
1  arch/powerpc/include/asm/Kbuild
@@ -36,3 +36,4 @@ header-y += ucontext.h
header-y += unistd.h
generic-y += rwsem.h
+generic-y += math128.h
View
1  arch/s390/include/asm/Kbuild
@@ -13,3 +13,4 @@ header-y += tape390.h
header-y += ucontext.h
header-y += vtoc.h
header-y += zcrypt.h
+generic-y += math128.h
View
1  arch/score/include/asm/Kbuild
@@ -1,3 +1,4 @@
include include/asm-generic/Kbuild.asm
header-y +=
+generic-y += math128.h
View
1  arch/sh/include/asm/Kbuild
@@ -9,3 +9,4 @@ header-y += ptrace_32.h
header-y += ptrace_64.h
header-y += unistd_32.h
header-y += unistd_64.h
+generic-y += math128.h
View
1  arch/sparc/include/asm/Kbuild
@@ -21,3 +21,4 @@ generic-y += div64.h
generic-y += local64.h
generic-y += irq_regs.h
generic-y += local.h
+generic-y += math128.h
View
1  arch/tile/include/asm/Kbuild
@@ -42,3 +42,4 @@ generic-y += termios.h
generic-y += types.h
generic-y += ucontext.h
generic-y += xor.h
+generic-y += math128.h
View
1  arch/um/include/asm/Kbuild
@@ -2,3 +2,4 @@ generic-y += bug.h cputime.h device.h emergency-restart.h futex.h hardirq.h
generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h
generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h exec.h
generic-y += switch_to.h
+generic-y += math128.h
View
1  arch/unicore32/include/asm/Kbuild
@@ -58,3 +58,4 @@ generic-y += unaligned.h
generic-y += user.h
generic-y += vga.h
generic-y += xor.h
+generic-y += math128.h
View
39 arch/x86/include/asm/math128.h
@@ -0,0 +1,39 @@
+#ifndef _ASM_MATH128_H
+#define _ASM_MATH128_H
+
+#ifdef CONFIG_X86_64
+
+#ifdef __SIZEOF_INT128__
+#define ARCH_HAS_INT128
+#endif
+
+#ifndef ARCH_HAS_INT128
+
+static inline u128 mul_u64_u64(u64 a, u64 b)
+{
+ u128 res;
+
+ asm("mulq %2"
+ : "=a" (res.lo), "=d" (res.hi)
+ : "rm" (b), "0" (a));
+
+ return res;
+}
+#define mul_u64_u64 mul_u64_u64
+
+static inline u128 add_u128(u128 a, u128 b)
+{
+ u128 res;
+
+ asm("addq %2,%0;\n"
+ "adcq %3,%1;\n"
+ : "=rm" (res.lo), "=rm" (res.hi)
+ : "r" (b.lo), "r" (b.hi), "0" (a.lo), "1" (a.hi));
+
+ return res;
+}
+#define add_u128 add_u128
+
+#endif /* ARCH_HAS_INT128 */
+#endif /* CONFIG_X86_64 */
+#endif /* _ASM_MATH128_H */
View
1  arch/xtensa/include/asm/Kbuild
@@ -1 +1,2 @@
include include/asm-generic/Kbuild.asm
+generic-y += math128.h
View
4 include/asm-generic/math128.h
@@ -0,0 +1,4 @@
+#ifndef _ASM_GENERIC_MATH128_H
+#define _ASM_GENERIC_MATH128_H
+
+#endif /*_ASM_GENERIC_MATH128_H */
View
180 include/linux/math128.h
@@ -0,0 +1,180 @@
+#ifndef _LINUX_MATH128_H
+#define _LINUX_MATH128_H
+
+#include <linux/types.h>
+
+typedef union {
+ struct {
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ u64 lo, hi;
+#else
+ u64 hi, lo;
+#endif
+ };
+#ifdef __SIZEOF_INT128__ /* gcc-4.6+ */
+ unsigned __int128 val;
+#endif
+} u128;
+
+#define U128_INIT(_hi, _lo) (u128){{ .hi = (_hi), .lo = (_lo) }}
+
+#include <asm/math128.h>
+
+/*
+ * Make usage of __int128 dependent on arch code so they can
+ * judge if gcc is doing the right thing for them and can over-ride
+ * any funnies.
+ */
+
+#ifndef ARCH_HAS_INT128
+
+#ifndef add_u128
+static inline u128 add_u128(u128 a, u128 b)
+{
+ a.hi += b.hi;
+ a.lo += b.lo;
+ if (a.lo < b.lo)
+ a.hi++;
+
+ return a;
+}
+#endif /* add_u128 */
+
+#ifndef mul_u64_u64
+extern u128 mul_u64_u64(u64 a, u64 b);
+#endif
+
+#ifndef mul_u64_u32_shr
+static inline u64 mul_u64_u32_shr(u64 a, u32 mul, unsigned int shift)
+{
+ u32 ah, al;
+ u64 t1, t2;
+
+ ah = a >> 32;
+ al = a;
+
+ t1 = ((u64)al * mul) >> shift;
+ t2 = ((u64)ah * mul) << (32 - shift);
+
+ return t1 + t2;
+}
+#endif /* mul_u64_u32_shr */
+
+#ifndef shl_u128
+static inline u128 shl_u128(u128 x, unsigned int n)
+{
+ u128 res;
+
+ if (!n)
+ return x;
+
+ if (n < 64) {
+ res.hi = x.hi << n;
+ res.hi |= x.lo >> (64 - n);
+ res.lo = x.lo << n;
+ } else {
+ res.lo = 0;
+ res.hi = x.lo << (n - 64);
+ }
+
+ return res;
+}
+#endif /* shl_u128 */
+
+#ifndef shr_u128
+static inline u128 shr_u128(u128 x, unsigned int n)
+{
+ u128 res;
+
+ if (!n)
+ return x;
+
+ if (n < 64) {
+ res.lo = x.lo >> n;
+ res.lo |= x.hi << (64 - n);
+ res.hi = x.hi >> n;
+ } else {
+ res.hi = 0;
+ res.lo = x.hi >> (n - 64);
+ }
+
+ return res;
+}
+#endif /* shr_u128 */
+
+#ifndef cmp_u128
+static inline int cmp_u128(u128 a, u128 b)
+{
+ if (a.hi > b.hi)
+ return 1;
+ if (a.hi < b.hi)
+ return -1;
+ if (a.lo > b.lo)
+ return 1;
+ if (a.lo < b.lo)
+ return -1;
+
+ return 0;
+}
+#endif /* cmp_u128 */
+
+#else /* ARCH_HAS_INT128 */
+
+#ifndef add_u128
+static inline u128 add_u128(u128 a, u128 b)
+{
+ a.val += b.val;
+ return a;
+}
+#endif /* add_u128 */
+
+#ifndef mul_u64_u64
+static inline u128 mul_u64_u64(u64 a, u64 b)
+{
+ u128 res;
+
+ res.val = a;
+ res.val *= b;
+
+ return res;
+}
+#define mul_u64_u64 mul_u64_u64
+#endif
+
+#ifndef mul_u64_u32_shr
+static inline u64 mul_u64_u32_shr(u64 a, u32 mul, unsigned int shift)
+{
+ return (u64)(((unsigned __int128)a * mul) >> shift);
+}
+#endif /* mul_u64_u32_shr */
+
+#ifndef shl_u128
+static inline u128 shl_u128(u128 x, unsigned int n)
+{
+ x.val <<= n;
+ return x;
+}
+#endif /* shl_u128 */
+
+#ifndef shr_u128
+static inline u128 shr_u128(u128 x, unsigned int n)
+{
+ x.val >>= n;
+ return x;
+}
+#endif /* shr_u128 */
+
+#ifndef cmp_u128
+static inline int cmp_u128(u128 a, u128 b)
+{
+ if (a.val < b.val)
+ return -1;
+ if (a.val > b.val)
+ return 1;
+ return 0;
+}
+#endif /* cmp_u128 */
+
+#endif /* ARCH_HAS_INT128 */
+
+#endif /* _LINUX_MATH128_H */
View
12 kernel/sched/dl.c
@@ -14,6 +14,7 @@
* Michael Trimarchi <michael@amarulasolutions.com>,
* Fabio Checconi <fabio@gandalf.sssup.it>
*/
+#include <linux/math128.h>
#include "sched.h"
struct dl_bandwidth def_dl_bandwidth;
@@ -363,7 +364,7 @@ static void replenish_dl_entity(struct sched_dl_entity *dl_se,
static bool dl_entity_overflow(struct sched_dl_entity *dl_se,
struct sched_dl_entity *pi_se, u64 t)
{
- u64 left, right;
+ u128 left, right;
/*
* left and right are the two sides of the equation above,
@@ -378,10 +379,13 @@ static bool dl_entity_overflow(struct sched_dl_entity *dl_se,
* to the (absolute) deadline. Therefore, overflowing the u64
* type is very unlikely to occur in both cases.
*/
- left = pi_se->dl_deadline * dl_se->runtime;
- right = (dl_se->deadline - t) * pi_se->dl_runtime;
+ left = mul_u64_u64(pi_se->dl_period, dl_se->runtime);
+ right = mul_u64_u64((dl_se->deadline - t), pi_se->dl_runtime);
- return dl_time_before(right, left);
+ if (cmp_u128(left, right) > 0)
+ return true;
+
+ return false;
}
/*
View
2  lib/Makefile
@@ -12,7 +12,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
idr.o int_sqrt.o extable.o prio_tree.o \
sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \
proportions.o prio_heap.o ratelimit.o show_mem.o \
- is_single_threaded.o plist.o decompress.o
+ is_single_threaded.o plist.o decompress.o math128.o
lib-$(CONFIG_MMU) += ioremap.o
lib-$(CONFIG_SMP) += cpumask.o
View
40 lib/math128.c
@@ -0,0 +1,40 @@
+#include <linux/math128.h>
+
+#ifndef mul_u64_u64
+/*
+ * a * b = (ah * 2^32 + al) * (bh * 2^32 + bl) =
+ * ah*bh * 2^64 + (ah*bl + bh*al) * 2^32 + al*bl
+ */
+u128 mul_u64_u64(u64 a, u64 b)
+{
+ u128 t1, t2, t3, t4;
+ u32 ah, al;
+ u32 bh, bl;
+
+ ah = a >> 32;
+ al = a;
+
+ bh = b >> 32;
+ bl = b;
+
+ t1.lo = 0;
+ t1.hi = (u64)ah * bh;
+
+ t2.lo = (u64)ah * bl;
+ t2.hi = t2.lo >> 32;
+ t2.lo <<= 32;
+
+ t3.lo = (u64)al * bh;
+ t3.hi = t3.lo >> 32;
+ t3.lo <<= 32;
+
+ t4.lo = (u64)al * bl;
+ t4.hi = 0;
+
+ t1 = add_u128(t1, t2);
+ t1 = add_u128(t1, t3);
+ t1 = add_u128(t1, t4);
+
+ return t1;
+}
+#endif /* mul_u64_u64 */

No commit comments for this range

Something went wrong with that request. Please try again.