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
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 */ | |
| @@ -1637,7 +1637,7 @@ static int __set_cpus_allowed_ptr(struct task_struct *p, · 1636 unmodified lines | ||
| 1637 | 1637 | goto out; |
| 1638 | 1638 | } |
| 1639 | 1639 | |
| 1640 | − if (cpumask_equal(p->cpus_ptr, new_mask)) | |
| 1640 | + if (cpumask_equal(&p->cpus_mask, new_mask)) | |
| 1641 | 1641 | goto out; |
| 1642 | 1642 | |
| 1643 | 1643 | /* |
| @@ -2293,8 +2293,15 @@ void sched_ttwu_pending(void *arg) · 649 unmodified lines | ||
| 2293 | 2293 | rq_lock_irqsave(rq, &rf); |
| 2294 | 2294 | update_rq_clock(rq); |
| 2295 | 2295 | |
| 2296 | − llist_for_each_entry_safe(p, t, llist, wake_entry) | |
| 2296 | + llist_for_each_entry_safe(p, t, llist, wake_entry.llist) { | |
| 2297 | + if (WARN_ON_ONCE(p->on_cpu)) | |
| 2298 | + smp_cond_load_acquire(&p->on_cpu, !VAL); | |
| 2299 | + | |
| 2300 | + if (WARN_ON_ONCE(task_cpu(p) != cpu_of(rq))) | |
| 2301 | + set_task_cpu(p, cpu_of(rq)); | |
| 2302 | + | |
| 2297 | 2303 | ttwu_do_activate(rq, p, p->sched_remote_wakeup ? WF_MIGRATED : 0, &rf); |
| 2304 | + } | |
| 2298 | 2305 | |
| 2299 | 2306 | rq_unlock_irqrestore(rq, &rf); |
| 2300 | 2307 | } |
| @@ -2322,7 +2329,7 @@ static void __ttwu_queue_wakelist(struct task_struct *p, int cpu, int wake_flags · 21 unmodified lines | ||
| 2322 | 2329 | p->sched_remote_wakeup = !!(wake_flags & WF_MIGRATED); |
| 2323 | 2330 | |
| 2324 | 2331 | WRITE_ONCE(rq->ttwu_pending, 1); |
| 2325 | − __smp_call_single_queue(cpu, &p->wake_entry); | |
| 2332 | + __smp_call_single_queue(cpu, &p->wake_entry.llist); | |
| 2326 | 2333 | } |
| 2327 | 2334 | |
| 2328 | 2335 | void wake_up_if_idle(int cpu) |
| @@ -2369,7 +2376,7 @@ static inline bool ttwu_queue_cond(int cpu, int wake_flags) · 40 unmodified lines | ||
| 2369 | 2376 | * the soon-to-be-idle CPU as the current CPU is likely busy. |
| 2370 | 2377 | * nr_running is checked to avoid unnecessary task stacking. |
| 2371 | 2378 | */ |
| 2372 | − if ((wake_flags & WF_ON_RQ) && cpu_rq(cpu)->nr_running <= 1) | |
| 2379 | + if ((wake_flags & WF_ON_CPU) && cpu_rq(cpu)->nr_running <= 1) | |
| 2373 | 2380 | return true; |
| 2374 | 2381 | |
| 2375 | 2382 | return false; |
| @@ -2378,6 +2385,9 @@ static inline bool ttwu_queue_cond(int cpu, int wake_flags) · 2 unmodified lines | ||
| 2378 | 2385 | static bool ttwu_queue_wakelist(struct task_struct *p, int cpu, int wake_flags) |
| 2379 | 2386 | { |
| 2380 | 2387 | if (sched_feat(TTWU_QUEUE) && ttwu_queue_cond(cpu, wake_flags)) { |
| 2388 | + if (WARN_ON_ONCE(cpu == smp_processor_id())) | |
| 2389 | + return false; | |
| 2390 | + | |
| 2381 | 2391 | sched_clock_cpu(cpu); /* Sync clocks across CPUs */ |
| 2382 | 2392 | __ttwu_queue_wakelist(p, cpu, wake_flags); |
| 2383 | 2393 | return true; |
| @@ -2528,7 +2538,6 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) · 144 unmodified lines | ||
| 2528 | 2538 | goto out; |
| 2529 | 2539 | |
| 2530 | 2540 | success = 1; |
| 2531 | − cpu = task_cpu(p); | |
| 2532 | 2541 | trace_sched_waking(p); |
| 2533 | 2542 | p->state = TASK_RUNNING; |
| 2534 | 2543 | trace_sched_wakeup(p); |
| @@ -2550,7 +2559,6 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) · 15 unmodified lines | ||
| 2550 | 2559 | |
| 2551 | 2560 | /* We're going to change ->state: */ |
| 2552 | 2561 | success = 1; |
| 2553 | − cpu = task_cpu(p); | |
| 2554 | 2562 | |
| 2555 | 2563 | /* |
| 2556 | 2564 | * Ensure we load p->on_rq _after_ p->state, otherwise it would |
| @@ -2614,8 +2622,21 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) · 57 unmodified lines | ||
| 2614 | 2622 | * which potentially sends an IPI instead of spinning on p->on_cpu to |
| 2615 | 2623 | * let the waker make forward progress. This is safe because IRQs are |
| 2616 | 2624 | * disabled and the IPI will deliver after on_cpu is cleared. |
| 2625 | + * | |
| 2626 | + * Ensure we load task_cpu(p) after p->on_cpu: | |
| 2627 | + * | |
| 2628 | + * set_task_cpu(p, cpu); | |
| 2629 | + * STORE p->cpu = @cpu | |
| 2630 | + * __schedule() (switch to task 'p') | |
| 2631 | + * LOCK rq->lock | |
| 2632 | + * smp_mb__after_spin_lock() smp_cond_load_acquire(&p->on_cpu) | |
| 2633 | + * STORE p->on_cpu = 1 LOAD p->cpu | |
| 2634 | + * | |
| 2635 | + * to ensure we observe the correct CPU on which the task is currently | |
| 2636 | + * scheduling. | |
| 2617 | 2637 | */ |
| 2618 | − if (READ_ONCE(p->on_cpu) && ttwu_queue_wakelist(p, cpu, wake_flags | WF_ON_RQ)) | |
| 2638 | + if (smp_load_acquire(&p->on_cpu) && | |
| 2639 | + ttwu_queue_wakelist(p, task_cpu(p), wake_flags | WF_ON_CPU)) | |
| 2619 | 2640 | goto unlock; |
| 2620 | 2641 | |
| 2621 | 2642 | /* |
| @@ -2635,6 +2656,8 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) · 13 unmodified lines | ||
| 2635 | 2656 | psi_ttwu_dequeue(p); |
| 2636 | 2657 | set_task_cpu(p, cpu); |
| 2637 | 2658 | } |
| 2659 | +#else | |
| 2660 | + cpu = task_cpu(p); | |
| 2638 | 2661 | #endif /* CONFIG_SMP */ |
| 2639 | 2662 | |
| 2640 | 2663 | ttwu_queue(p, cpu, wake_flags); |
| @@ -2642,7 +2665,7 @@ unlock: · 1 unmodified line | ||
| 2642 | 2665 | raw_spin_unlock_irqrestore(&p->pi_lock, flags); |
| 2643 | 2666 | out: |
| 2644 | 2667 | if (success) |
| 2645 | − ttwu_stat(p, cpu, wake_flags); | |
| 2668 | + ttwu_stat(p, task_cpu(p), wake_flags); | |
| 2646 | 2669 | preempt_enable(); |
| 2647 | 2670 | |
| 2648 | 2671 | return success; |
| @@ -2763,7 +2786,7 @@ static void __sched_fork(unsigned long clone_flags, struct task_struct *p) · 114 unmodified lines | ||
| 2763 | 2786 | #endif |
| 2764 | 2787 | init_numa_balancing(clone_flags, p); |
| 2765 | 2788 | #ifdef CONFIG_SMP |
| 2766 | − p->wake_entry_type = CSD_TYPE_TTWU; | |
| 2789 | + p->wake_entry.u_flags = CSD_TYPE_TTWU; | |
| 2767 | 2790 | #endif |
| 2768 | 2791 | } |
| 2769 | 2792 | |
| @@ -4533,7 +4556,8 @@ void rt_mutex_setprio(struct task_struct *p, struct task_struct *pi_task) · 1763 unmodified lines | ||
| 4533 | 4556 | */ |
| 4534 | 4557 | if (dl_prio(prio)) { |
| 4535 | 4558 | if (!dl_prio(p->normal_prio) || |
| 4536 | − (pi_task && dl_entity_preempt(&pi_task->dl, &p->dl))) { | |
| 4559 | + (pi_task && dl_prio(pi_task->prio) && | |
| 4560 | + dl_entity_preempt(&pi_task->dl, &p->dl))) { | |
| 4537 | 4561 | p->dl.dl_boosted = 1; |
| 4538 | 4562 | queue_flag |= ENQUEUE_REPLENISH; |
| 4539 | 4563 | } else |
| @@ -2692,6 +2692,7 @@ void __dl_clear_params(struct task_struct *p) · 2691 unmodified lines | ||
| 2692 | 2692 | dl_se->dl_bw = 0; |
| 2693 | 2693 | dl_se->dl_density = 0; |
| 2694 | 2694 | |
| 2695 | + dl_se->dl_boosted = 0; | |
| 2695 | 2696 | dl_se->dl_throttled = 0; |
| 2696 | 2697 | dl_se->dl_yielded = 0; |
| 2697 | 2698 | dl_se->dl_non_contending = 0; |
| @@ -806,7 +806,7 @@ void post_init_entity_util_avg(struct task_struct *p) · 805 unmodified lines | ||
| 806 | 806 | } |
| 807 | 807 | } |
| 808 | 808 | |
| 809 | − sa->runnable_avg = cpu_scale; | |
| 809 | + sa->runnable_avg = sa->util_avg; | |
| 810 | 810 | |
| 811 | 811 | if (p->sched_class != &fair_sched_class) { |
| 812 | 812 | /* |
| @@ -1682,7 +1682,7 @@ static inline int task_on_rq_migrating(struct task_struct *p) · 1681 unmodified lines | ||
| 1682 | 1682 | #define WF_SYNC 0x01 /* Waker goes to sleep after wakeup */ |
| 1683 | 1683 | #define WF_FORK 0x02 /* Child wakeup after fork */ |
| 1684 | 1684 | #define WF_MIGRATED 0x04 /* Internal use, task got migrated */ |
| 1685 | −#define WF_ON_RQ 0x08 /* Wakee is on_rq */ | |
| 1685 | +#define WF_ON_CPU 0x08 /* Wakee is on_cpu */ | |
| 1686 | 1686 | |
| 1687 | 1687 | /* |
| 1688 | 1688 | * To aid in avoiding the subversion of "niceness" due to uneven distribution |
| @@ -669,24 +669,6 @@ void __init smp_init(void) · 668 unmodified lines | ||
| 669 | 669 | { |
| 670 | 670 | int num_nodes, num_cpus; |
| 671 | 671 | |
| 672 | − /* | |
| 673 | − * Ensure struct irq_work layout matches so that | |
| 674 | − * flush_smp_call_function_queue() can do horrible things. | |
| 675 | − */ | |
| 676 | − BUILD_BUG_ON(offsetof(struct irq_work, llnode) != | |
| 677 | − offsetof(struct __call_single_data, llist)); | |
| 678 | − BUILD_BUG_ON(offsetof(struct irq_work, func) != | |
| 679 | − offsetof(struct __call_single_data, func)); | |
| 680 | − BUILD_BUG_ON(offsetof(struct irq_work, flags) != | |
| 681 | − offsetof(struct __call_single_data, flags)); | |
| 682 | − | |
| 683 | − /* | |
| 684 | − * Assert the CSD_TYPE_TTWU layout is similar enough | |
| 685 | − * for task_struct to be on the @call_single_queue. | |
| 686 | − */ | |
| 687 | − BUILD_BUG_ON(offsetof(struct task_struct, wake_entry_type) - offsetof(struct task_struct, wake_entry) != | |
| 688 | − offsetof(struct __call_single_data, flags) - offsetof(struct __call_single_data, llist)); | |
| 689 | − | |
| 690 | 672 | idle_threads_init(); |
| 691 | 673 | cpuhp_threads_init(); |
| 692 | 674 | |