Pull scheduler fixes from Borislav Petkov: "The most anticipated fix in this pull request is probably the horrible build fix for the RANDSTRUCT fail that didn't make -rc2. Also included is the cleanup that removes those BUILD_BUG_ON()s and replaces it with ugly unions. Also included is the try_to_wake_up() race fix that was first triggered by Paul's RCU-torture runs, but was independently hit by Dave Chinner's fstest runs as well" * tag 'sched_urgent_for_5.8_rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: sched/cfs: change initial value of runnable_avg smp, irq_work: Continue smp_call_function*() and irq_work*() integration sched/core: s/WF_ON_RQ/WQ_ON_CPU/ sched/core: Fix ttwu() race sched/core: Fix PI boosting between RT and DEADLINE tasks sched/deadline: Initialize ->dl_boosted sched/core: Check cpus_mask, not cpus_ptr in __set_cpus_allowed_ptr(), to fix mask corruption sched/core: Fix CONFIG_GCC_PLUGIN_RANDSTRUCT build fail
Showing the changes to include/linux (4 of 9 files). Show all
Unified · Split
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | #ifndef _LINUX_IRQ_WORK_H |
| 3 | 3 | #define _LINUX_IRQ_WORK_H |
| 4 | 4 | |
| 5 | −#include <linux/llist.h> | |
| 5 | +#include <linux/smp_types.h> | |
| 6 | 6 | |
| 7 | 7 | /* |
| 8 | 8 | * An entry can be in one of four states: |
| @@ -13,24 +13,14 @@ · 4 unmodified lines | ||
| 13 | 13 | * busy NULL, 2 -> {free, claimed} : callback in progress, can be claimed |
| 14 | 14 | */ |
| 15 | 15 | |
| 16 | −/* flags share CSD_FLAG_ space */ | |
| 17 | − | |
| 18 | −#define IRQ_WORK_PENDING BIT(0) | |
| 19 | −#define IRQ_WORK_BUSY BIT(1) | |
| 20 | − | |
| 21 | −/* Doesn't want IPI, wait for tick: */ | |
| 22 | −#define IRQ_WORK_LAZY BIT(2) | |
| 23 | −/* Run hard IRQ context, even on RT */ | |
| 24 | −#define IRQ_WORK_HARD_IRQ BIT(3) | |
| 25 | − | |
| 26 | −#define IRQ_WORK_CLAIMED (IRQ_WORK_PENDING | IRQ_WORK_BUSY) | |
| 27 | − | |
| 28 | −/* | |
| 29 | − * structure shares layout with single_call_data_t. | |
| 30 | − */ | |
| 31 | 16 | struct irq_work { |
| 32 | − struct llist_node llnode; | |
| 33 | − atomic_t flags; | |
| 17 | + union { | |
| 18 | + struct __call_single_node node; | |
| 19 | + struct { | |
| 20 | + struct llist_node llnode; | |
| 21 | + atomic_t flags; | |
| 22 | + }; | |
| 23 | + }; | |
| 34 | 24 | void (*func)(struct irq_work *); |
| 35 | 25 | }; |
| 36 | 26 | |
| @@ -654,9 +654,8 @@ struct task_struct { · 653 unmodified lines | ||
| 654 | 654 | unsigned int ptrace; |
| 655 | 655 | |
| 656 | 656 | #ifdef CONFIG_SMP |
| 657 | − struct llist_node wake_entry; | |
| 658 | − unsigned int wake_entry_type; | |
| 659 | 657 | int on_cpu; |
| 658 | + struct __call_single_node wake_entry; | |
| 660 | 659 | #ifdef CONFIG_THREAD_INFO_IN_TASK |
| 661 | 660 | /* Current CPU: */ |
| 662 | 661 | unsigned int cpu; |
| @@ -12,29 +12,22 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/list.h> |
| 13 | 13 | #include <linux/cpumask.h> |
| 14 | 14 | #include <linux/init.h> |
| 15 | −#include <linux/llist.h> | |
| 15 | +#include <linux/smp_types.h> | |
| 16 | 16 | |
| 17 | 17 | typedef void (*smp_call_func_t)(void *info); |
| 18 | 18 | typedef bool (*smp_cond_func_t)(int cpu, void *info); |
| 19 | 19 | |
| 20 | −enum { | |
| 21 | − CSD_FLAG_LOCK = 0x01, | |
| 22 | − | |
| 23 | − /* IRQ_WORK_flags */ | |
| 24 | − | |
| 25 | − CSD_TYPE_ASYNC = 0x00, | |
| 26 | − CSD_TYPE_SYNC = 0x10, | |
| 27 | − CSD_TYPE_IRQ_WORK = 0x20, | |
| 28 | − CSD_TYPE_TTWU = 0x30, | |
| 29 | − CSD_FLAG_TYPE_MASK = 0xF0, | |
| 30 | −}; | |
| 31 | − | |
| 32 | 20 | /* |
| 33 | 21 | * structure shares (partial) layout with struct irq_work |
| 34 | 22 | */ |
| 35 | 23 | struct __call_single_data { |
| 36 | − struct llist_node llist; | |
| 37 | − unsigned int flags; | |
| 24 | + union { | |
| 25 | + struct __call_single_node node; | |
| 26 | + struct { | |
| 27 | + struct llist_node llist; | |
| 28 | + unsigned int flags; | |
| 29 | + }; | |
| 30 | + }; | |
| 38 | 31 | smp_call_func_t func; |
| 39 | 32 | void *info; |
| 40 | 33 | }; |
| @@ -0,0 +1,66 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | +#ifndef __LINUX_SMP_TYPES_H | |
| 3 | +#define __LINUX_SMP_TYPES_H | |
| 4 | + | |
| 5 | +#include <linux/llist.h> | |
| 6 | + | |
| 7 | +enum { | |
| 8 | + CSD_FLAG_LOCK = 0x01, | |
| 9 | + | |
| 10 | + IRQ_WORK_PENDING = 0x01, | |
| 11 | + IRQ_WORK_BUSY = 0x02, | |
| 12 | + IRQ_WORK_LAZY = 0x04, /* No IPI, wait for tick */ | |
| 13 | + IRQ_WORK_HARD_IRQ = 0x08, /* IRQ context on PREEMPT_RT */ | |
| 14 | + | |
| 15 | + IRQ_WORK_CLAIMED = (IRQ_WORK_PENDING | IRQ_WORK_BUSY), | |
| 16 | + | |
| 17 | + CSD_TYPE_ASYNC = 0x00, | |
| 18 | + CSD_TYPE_SYNC = 0x10, | |
| 19 | + CSD_TYPE_IRQ_WORK = 0x20, | |
| 20 | + CSD_TYPE_TTWU = 0x30, | |
| 21 | + | |
| 22 | + CSD_FLAG_TYPE_MASK = 0xF0, | |
| 23 | +}; | |
| 24 | + | |
| 25 | +/* | |
| 26 | + * struct __call_single_node is the primary type on | |
| 27 | + * smp.c:call_single_queue. | |
| 28 | + * | |
| 29 | + * flush_smp_call_function_queue() only reads the type from | |
| 30 | + * __call_single_node::u_flags as a regular load, the above | |
| 31 | + * (anonymous) enum defines all the bits of this word. | |
| 32 | + * | |
| 33 | + * Other bits are not modified until the type is known. | |
| 34 | + * | |
| 35 | + * CSD_TYPE_SYNC/ASYNC: | |
| 36 | + * struct { | |
| 37 | + * struct llist_node node; | |
| 38 | + * unsigned int flags; | |
| 39 | + * smp_call_func_t func; | |
| 40 | + * void *info; | |
| 41 | + * }; | |
| 42 | + * | |
| 43 | + * CSD_TYPE_IRQ_WORK: | |
| 44 | + * struct { | |
| 45 | + * struct llist_node node; | |
| 46 | + * atomic_t flags; | |
| 47 | + * void (*func)(struct irq_work *); | |
| 48 | + * }; | |
| 49 | + * | |
| 50 | + * CSD_TYPE_TTWU: | |
| 51 | + * struct { | |
| 52 | + * struct llist_node node; | |
| 53 | + * unsigned int flags; | |
| 54 | + * }; | |
| 55 | + * | |
| 56 | + */ | |
| 57 | + | |
| 58 | +struct __call_single_node { | |
| 59 | + struct llist_node llist; | |
| 60 | + union { | |
| 61 | + unsigned int u_flags; | |
| 62 | + atomic_t a_flags; | |
| 63 | + }; | |
| 64 | +}; | |
| 65 | + | |
| 66 | +#endif /* __LINUX_SMP_TYPES_H */ | |