Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

futex: FLAGS_STRICT

The current semantics for futex_wake() are a bit loose, specifically
asking for 0 futexes to be woken actually gets you 1.

Adding a !nr check to sys_futex_wake() makes that it would return 0
for unaligned futex words, because that check comes in the shared
futex_wake() function. Adding the !nr check there, would affect the
legacy sys_futex() semantics.

Hence frob a flag :-(

Suggested-by: André Almeida <andrealmeid@igalia.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20230921105248.048643656@noisy.programming.kicks-ass.net

+15 -11
+11 -10
kernel/futex/futex.h
··· 17 17 * Futex flags used to encode options to functions and preserve them across 18 18 * restarts. 19 19 */ 20 - #define FLAGS_SIZE_8 0x00 21 - #define FLAGS_SIZE_16 0x01 22 - #define FLAGS_SIZE_32 0x02 23 - #define FLAGS_SIZE_64 0x03 20 + #define FLAGS_SIZE_8 0x0000 21 + #define FLAGS_SIZE_16 0x0001 22 + #define FLAGS_SIZE_32 0x0002 23 + #define FLAGS_SIZE_64 0x0003 24 24 25 - #define FLAGS_SIZE_MASK 0x03 25 + #define FLAGS_SIZE_MASK 0x0003 26 26 27 27 #ifdef CONFIG_MMU 28 - # define FLAGS_SHARED 0x10 28 + # define FLAGS_SHARED 0x0010 29 29 #else 30 30 /* 31 31 * NOMMU does not have per process address space. Let the compiler optimize 32 32 * code away. 33 33 */ 34 - # define FLAGS_SHARED 0x00 34 + # define FLAGS_SHARED 0x0000 35 35 #endif 36 - #define FLAGS_CLOCKRT 0x20 37 - #define FLAGS_HAS_TIMEOUT 0x40 38 - #define FLAGS_NUMA 0x80 36 + #define FLAGS_CLOCKRT 0x0020 37 + #define FLAGS_HAS_TIMEOUT 0x0040 38 + #define FLAGS_NUMA 0x0080 39 + #define FLAGS_STRICT 0x0100 39 40 40 41 /* FUTEX_ to FLAGS_ */ 41 42 static inline unsigned int futex_to_flags(unsigned int op)
+1 -1
kernel/futex/syscalls.c
··· 333 333 if (!futex_validate_input(flags, mask)) 334 334 return -EINVAL; 335 335 336 - return futex_wake(uaddr, flags, nr, mask); 336 + return futex_wake(uaddr, FLAGS_STRICT | flags, nr, mask); 337 337 } 338 338 339 339 #ifdef CONFIG_COMPAT
+3
kernel/futex/waitwake.c
··· 155 155 if (unlikely(ret != 0)) 156 156 return ret; 157 157 158 + if ((flags & FLAGS_STRICT) && !nr_wake) 159 + return 0; 160 + 158 161 hb = futex_hash(&key); 159 162 160 163 /* Make sure we really have tasks to wakeup */