diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2017-10-17 17:13:28 +0200 |
---|---|---|
committer | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2017-10-17 17:13:28 +0200 |
commit | 4aca7bf0252fb2fd2017ac18d3997776162a99c0 (patch) | |
tree | ce0b44cfbff890448774f7878e962870f354bd7c | |
parent | 163c99cd5cc3ffff6f0ac886236223e72ae989fb (diff) | |
download | linux-rt-4.13.7-rt1-patches.tar.gz |
[ANNOUNCE] v4.13.7-rt1v4.13.7-rt1-patches
Dear RT folks!
I'm pleased to announce the v4.13.7-rt1 patch set.
Changes since v4.11.12-rt16:
- Rebase to v4.13.7
- We have now only the reader bias version of RWLOCK. In v4.11 it was
possible to choose between both implementations but since the reader
bias version makes no problems it is now the only implementation.
- The lockdep self test is now disabled. While it produced some false
positives on v4.11 it now completly locks up the system and needs
investigation before re-enabling.
Known issues
None
You can get this release via the git tree at:
git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git v4.13.7-rt1
The RT patch against v4.13.7 can be found here:
https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.13/older/patch-4.13.7-rt1.patch.xz
The split quilt queue is available at:
https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.13/older/patches-4.13.7-rt1.tar.xz
Sebastian
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
373 files changed, 4964 insertions, 17713 deletions
diff --git a/patches/0001-cpu-hotplug-Provide-cpus_read-write_-un-lock.patch b/patches/0001-cpu-hotplug-Provide-cpus_read-write_-un-lock.patch deleted file mode 100644 index f877950a3716..000000000000 --- a/patches/0001-cpu-hotplug-Provide-cpus_read-write_-un-lock.patch +++ /dev/null @@ -1,232 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 24 May 2017 10:15:12 +0200 -Subject: [PATCH 01/32] cpu/hotplug: Provide cpus_read|write_[un]lock() - -The counting 'rwsem' hackery of get|put_online_cpus() is going to be -replaced by percpu rwsem. - -Rename the functions to make it clear that it's locking and not some -refcount style interface. These new functions will be used for the -preparatory patches which make the code ready for the percpu rwsem -conversion. - -Rename all instances in the cpu hotplug code while at it. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Tested-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Acked-by: Ingo Molnar <mingo@kernel.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Steven Rostedt <rostedt@goodmis.org> -Link: http://lkml.kernel.org/r/20170524081547.080397752@linutronix.de ---- - include/linux/cpu.h | 32 ++++++++++++++++++-------------- - kernel/cpu.c | 36 ++++++++++++++++++------------------ - 2 files changed, 36 insertions(+), 32 deletions(-) - ---- a/include/linux/cpu.h -+++ b/include/linux/cpu.h -@@ -99,26 +99,30 @@ static inline void cpu_maps_update_done( - extern struct bus_type cpu_subsys; - - #ifdef CONFIG_HOTPLUG_CPU --/* Stop CPUs going up and down. */ -- --extern void cpu_hotplug_begin(void); --extern void cpu_hotplug_done(void); --extern void get_online_cpus(void); --extern void put_online_cpus(void); -+extern void cpus_write_lock(void); -+extern void cpus_write_unlock(void); -+extern void cpus_read_lock(void); -+extern void cpus_read_unlock(void); - extern void cpu_hotplug_disable(void); - extern void cpu_hotplug_enable(void); - void clear_tasks_mm_cpumask(int cpu); - int cpu_down(unsigned int cpu); - --#else /* CONFIG_HOTPLUG_CPU */ -+#else /* CONFIG_HOTPLUG_CPU */ -+ -+static inline void cpus_write_lock(void) { } -+static inline void cpus_write_unlock(void) { } -+static inline void cpus_read_lock(void) { } -+static inline void cpus_read_unlock(void) { } -+static inline void cpu_hotplug_disable(void) { } -+static inline void cpu_hotplug_enable(void) { } -+#endif /* !CONFIG_HOTPLUG_CPU */ - --static inline void cpu_hotplug_begin(void) {} --static inline void cpu_hotplug_done(void) {} --#define get_online_cpus() do { } while (0) --#define put_online_cpus() do { } while (0) --#define cpu_hotplug_disable() do { } while (0) --#define cpu_hotplug_enable() do { } while (0) --#endif /* CONFIG_HOTPLUG_CPU */ -+/* Wrappers which go away once all code is converted */ -+static inline void cpu_hotplug_begin(void) { cpus_write_lock(); } -+static inline void cpu_hotplug_done(void) { cpus_write_unlock(); } -+static inline void get_online_cpus(void) { cpus_read_lock(); } -+static inline void put_online_cpus(void) { cpus_read_unlock(); } - - #ifdef CONFIG_PM_SLEEP_SMP - extern int freeze_secondary_cpus(int primary); ---- a/kernel/cpu.c -+++ b/kernel/cpu.c -@@ -235,7 +235,7 @@ static struct { - #define cpuhp_lock_release() lock_map_release(&cpu_hotplug.dep_map) - - --void get_online_cpus(void) -+void cpus_read_lock(void) - { - might_sleep(); - if (cpu_hotplug.active_writer == current) -@@ -245,9 +245,9 @@ void get_online_cpus(void) - atomic_inc(&cpu_hotplug.refcount); - mutex_unlock(&cpu_hotplug.lock); - } --EXPORT_SYMBOL_GPL(get_online_cpus); -+EXPORT_SYMBOL_GPL(cpus_read_lock); - --void put_online_cpus(void) -+void cpus_read_unlock(void) - { - int refcount; - -@@ -264,7 +264,7 @@ void put_online_cpus(void) - cpuhp_lock_release(); - - } --EXPORT_SYMBOL_GPL(put_online_cpus); -+EXPORT_SYMBOL_GPL(cpus_read_unlock); - - /* - * This ensures that the hotplug operation can begin only when the -@@ -288,7 +288,7 @@ EXPORT_SYMBOL_GPL(put_online_cpus); - * get_online_cpus() not an api which is called all that often. - * - */ --void cpu_hotplug_begin(void) -+void cpus_write_lock(void) - { - DEFINE_WAIT(wait); - -@@ -306,7 +306,7 @@ void cpu_hotplug_begin(void) - finish_wait(&cpu_hotplug.wq, &wait); - } - --void cpu_hotplug_done(void) -+void cpus_write_unlock(void) - { - cpu_hotplug.active_writer = NULL; - mutex_unlock(&cpu_hotplug.lock); -@@ -783,7 +783,7 @@ static int __ref _cpu_down(unsigned int - if (!cpu_present(cpu)) - return -EINVAL; - -- cpu_hotplug_begin(); -+ cpus_write_lock(); - - cpuhp_tasks_frozen = tasks_frozen; - -@@ -821,7 +821,7 @@ static int __ref _cpu_down(unsigned int - } - - out: -- cpu_hotplug_done(); -+ cpus_write_unlock(); - return ret; - } - -@@ -892,7 +892,7 @@ static int _cpu_up(unsigned int cpu, int - struct task_struct *idle; - int ret = 0; - -- cpu_hotplug_begin(); -+ cpus_write_lock(); - - if (!cpu_present(cpu)) { - ret = -EINVAL; -@@ -940,7 +940,7 @@ static int _cpu_up(unsigned int cpu, int - target = min((int)target, CPUHP_BRINGUP_CPU); - ret = cpuhp_up_callbacks(cpu, st, target); - out: -- cpu_hotplug_done(); -+ cpus_write_unlock(); - return ret; - } - -@@ -1423,7 +1423,7 @@ int __cpuhp_state_add_instance(enum cpuh - if (sp->multi_instance == false) - return -EINVAL; - -- get_online_cpus(); -+ cpus_read_lock(); - mutex_lock(&cpuhp_state_mutex); - - if (!invoke || !sp->startup.multi) -@@ -1452,7 +1452,7 @@ int __cpuhp_state_add_instance(enum cpuh - hlist_add_head(node, &sp->list); - unlock: - mutex_unlock(&cpuhp_state_mutex); -- put_online_cpus(); -+ cpus_read_unlock(); - return ret; - } - EXPORT_SYMBOL_GPL(__cpuhp_state_add_instance); -@@ -1485,7 +1485,7 @@ int __cpuhp_setup_state(enum cpuhp_state - if (cpuhp_cb_check(state) || !name) - return -EINVAL; - -- get_online_cpus(); -+ cpus_read_lock(); - mutex_lock(&cpuhp_state_mutex); - - ret = cpuhp_store_callbacks(state, name, startup, teardown, -@@ -1521,7 +1521,7 @@ int __cpuhp_setup_state(enum cpuhp_state - } - out: - mutex_unlock(&cpuhp_state_mutex); -- put_online_cpus(); -+ cpus_read_unlock(); - /* - * If the requested state is CPUHP_AP_ONLINE_DYN, return the - * dynamically allocated state in case of success. -@@ -1543,7 +1543,7 @@ int __cpuhp_state_remove_instance(enum c - if (!sp->multi_instance) - return -EINVAL; - -- get_online_cpus(); -+ cpus_read_lock(); - mutex_lock(&cpuhp_state_mutex); - - if (!invoke || !cpuhp_get_teardown_cb(state)) -@@ -1564,7 +1564,7 @@ int __cpuhp_state_remove_instance(enum c - remove: - hlist_del(node); - mutex_unlock(&cpuhp_state_mutex); -- put_online_cpus(); -+ cpus_read_unlock(); - - return 0; - } -@@ -1586,7 +1586,7 @@ void __cpuhp_remove_state(enum cpuhp_sta - - BUG_ON(cpuhp_cb_check(state)); - -- get_online_cpus(); -+ cpus_read_lock(); - - mutex_lock(&cpuhp_state_mutex); - if (sp->multi_instance) { -@@ -1614,7 +1614,7 @@ void __cpuhp_remove_state(enum cpuhp_sta - remove: - cpuhp_store_callbacks(state, NULL, NULL, NULL, false); - mutex_unlock(&cpuhp_state_mutex); -- put_online_cpus(); -+ cpus_read_unlock(); - } - EXPORT_SYMBOL(__cpuhp_remove_state); - diff --git a/patches/0001-futex-Avoid-freeing-an-active-timer.patch b/patches/0001-futex-Avoid-freeing-an-active-timer.patch deleted file mode 100644 index edc05daba767..000000000000 --- a/patches/0001-futex-Avoid-freeing-an-active-timer.patch +++ /dev/null @@ -1,50 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Mon, 10 Apr 2017 18:03:36 +0200 -Subject: [PATCH 1/4] futex: Avoid freeing an active timer - -Alexander reported a hrtimer debug_object splat: - - ODEBUG: free active (active state 0) object type: hrtimer hint: hrtimer_wakeup (kernel/time/hrtimer.c:1423) - - debug_object_free (lib/debugobjects.c:603) - destroy_hrtimer_on_stack (kernel/time/hrtimer.c:427) - futex_lock_pi (kernel/futex.c:2740) - do_futex (kernel/futex.c:3399) - SyS_futex (kernel/futex.c:3447 kernel/futex.c:3415) - do_syscall_64 (arch/x86/entry/common.c:284) - entry_SYSCALL64_slow_path (arch/x86/entry/entry_64.S:249) - -Which was caused by commit: - - cfafcd117da0 ("futex: Rework futex_lock_pi() to use rt_mutex_*_proxy_lock()") - -... losing the hrtimer_cancel() in the shuffle. Where previously the -hrtimer_cancel() was done by rt_mutex_slowlock() we now need to do it -manually. - -Reported-by: Alexander Levin <alexander.levin@verizon.com> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: Linus Torvalds <torvalds@linux-foundation.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Fixes: cfafcd117da0 ("futex: Rework futex_lock_pi() to use rt_mutex_*_proxy_lock()") -Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1704101802370.2906@nanos -Signed-off-by: Ingo Molnar <mingo@kernel.org> ---- - kernel/futex.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - ---- a/kernel/futex.c -+++ b/kernel/futex.c -@@ -2736,8 +2736,10 @@ static int futex_lock_pi(u32 __user *uad - out_put_key: - put_futex_key(&q.key); - out: -- if (to) -+ if (to) { -+ hrtimer_cancel(&to->timer); - destroy_hrtimer_on_stack(&to->timer); -+ } - return ret != -EINTR ? ret : -ERESTARTNOINTR; - - uaddr_faulted: diff --git a/patches/0001-futex-Cleanup-variable-names-for-futex_top_waiter.patch b/patches/0001-futex-Cleanup-variable-names-for-futex_top_waiter.patch deleted file mode 100644 index 90911b152235..000000000000 --- a/patches/0001-futex-Cleanup-variable-names-for-futex_top_waiter.patch +++ /dev/null @@ -1,117 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Wed, 22 Mar 2017 11:35:48 +0100 -Subject: [PATCH] futex: Cleanup variable names for futex_top_waiter() - -Upstream commit 499f5aca2cdd5e958b27e2655e7e7f82524f46b1 - -futex_top_waiter() returns the top-waiter on the pi_mutex. Assinging -this to a variable 'match' totally obscures the code. - -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: juri.lelli@arm.com -Cc: bigeasy@linutronix.de -Cc: xlpang@redhat.com -Cc: rostedt@goodmis.org -Cc: mathieu.desnoyers@efficios.com -Cc: jdesfossez@efficios.com -Cc: dvhart@infradead.org -Cc: bristot@redhat.com -Link: http://lkml.kernel.org/r/20170322104151.554710645@infradead.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/futex.c | 30 +++++++++++++++--------------- - 1 file changed, 15 insertions(+), 15 deletions(-) - ---- a/kernel/futex.c -+++ b/kernel/futex.c -@@ -1122,14 +1122,14 @@ static int attach_to_pi_owner(u32 uval, - static int lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, - union futex_key *key, struct futex_pi_state **ps) - { -- struct futex_q *match = futex_top_waiter(hb, key); -+ struct futex_q *top_waiter = futex_top_waiter(hb, key); - - /* - * If there is a waiter on that futex, validate it and - * attach to the pi_state when the validation succeeds. - */ -- if (match) -- return attach_to_pi_state(uval, match->pi_state, ps); -+ if (top_waiter) -+ return attach_to_pi_state(uval, top_waiter->pi_state, ps); - - /* - * We are the first waiter - try to look up the owner based on -@@ -1176,7 +1176,7 @@ static int futex_lock_pi_atomic(u32 __us - struct task_struct *task, int set_waiters) - { - u32 uval, newval, vpid = task_pid_vnr(task); -- struct futex_q *match; -+ struct futex_q *top_waiter; - int ret; - - /* -@@ -1202,9 +1202,9 @@ static int futex_lock_pi_atomic(u32 __us - * Lookup existing state first. If it exists, try to attach to - * its pi_state. - */ -- match = futex_top_waiter(hb, key); -- if (match) -- return attach_to_pi_state(uval, match->pi_state, ps); -+ top_waiter = futex_top_waiter(hb, key); -+ if (top_waiter) -+ return attach_to_pi_state(uval, top_waiter->pi_state, ps); - - /* - * No waiter and user TID is 0. We are here because the -@@ -1294,11 +1294,11 @@ static void mark_wake_futex(struct wake_ - q->lock_ptr = NULL; - } - --static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this, -+static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *top_waiter, - struct futex_hash_bucket *hb) - { - struct task_struct *new_owner; -- struct futex_pi_state *pi_state = this->pi_state; -+ struct futex_pi_state *pi_state = top_waiter->pi_state; - u32 uninitialized_var(curval), newval; - DEFINE_WAKE_Q(wake_q); - bool deboost; -@@ -1319,11 +1319,11 @@ static int wake_futex_pi(u32 __user *uad - - /* - * It is possible that the next waiter (the one that brought -- * this owner to the kernel) timed out and is no longer -+ * top_waiter owner to the kernel) timed out and is no longer - * waiting on the lock. - */ - if (!new_owner) -- new_owner = this->task; -+ new_owner = top_waiter->task; - - /* - * We pass it to the next owner. The WAITERS bit is always -@@ -2633,7 +2633,7 @@ static int futex_unlock_pi(u32 __user *u - u32 uninitialized_var(curval), uval, vpid = task_pid_vnr(current); - union futex_key key = FUTEX_KEY_INIT; - struct futex_hash_bucket *hb; -- struct futex_q *match; -+ struct futex_q *top_waiter; - int ret; - - retry: -@@ -2657,9 +2657,9 @@ static int futex_unlock_pi(u32 __user *u - * all and we at least want to know if user space fiddled - * with the futex value instead of blindly unlocking. - */ -- match = futex_top_waiter(hb, &key); -- if (match) { -- ret = wake_futex_pi(uaddr, uval, match, hb); -+ top_waiter = futex_top_waiter(hb, &key); -+ if (top_waiter) { -+ ret = wake_futex_pi(uaddr, uval, top_waiter, hb); - /* - * In case of success wake_futex_pi dropped the hash - * bucket lock. diff --git a/patches/0001-hrtimer-Use-predefined-function-for-updating-next_ti.patch b/patches/0001-hrtimer-Use-predefined-function-for-updating-next_ti.patch index d47749b61d98..01318ec4a771 100644 --- a/patches/0001-hrtimer-Use-predefined-function-for-updating-next_ti.patch +++ b/patches/0001-hrtimer-Use-predefined-function-for-updating-next_ti.patch @@ -14,7 +14,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -629,7 +629,7 @@ static void hrtimer_reprogram(struct hrt +@@ -630,7 +630,7 @@ static void hrtimer_reprogram(struct hrt return; /* Update the pointer to the next expiring timer */ diff --git a/patches/0001-ia64-topology-Remove-cpus_allowed-manipulation.patch b/patches/0001-ia64-topology-Remove-cpus_allowed-manipulation.patch deleted file mode 100644 index d04096847c3c..000000000000 --- a/patches/0001-ia64-topology-Remove-cpus_allowed-manipulation.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 12 Apr 2017 22:07:27 +0200 -Subject: [PATCH 01/13] ia64/topology: Remove cpus_allowed manipulation - -The CPU hotplug callback fiddles with the cpus_allowed pointer to pin the -calling thread on the plugged CPU. That's already guaranteed by the hotplug -core code. - -Remove it. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Cc: Fenghua Yu <fenghua.yu@intel.com> -Cc: Tony Luck <tony.luck@intel.com> -Cc: linux-ia64@vger.kernel.org -Cc: Herbert Xu <herbert@gondor.apana.org.au> -Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Lai Jiangshan <jiangshanlai@gmail.com> -Cc: Viresh Kumar <viresh.kumar@linaro.org> -Cc: Michael Ellerman <mpe@ellerman.id.au> -Cc: Tejun Heo <tj@kernel.org> -Cc: "David S. Miller" <davem@davemloft.net> -Cc: Len Brown <lenb@kernel.org> -Link: http://lkml.kernel.org/r/20170412201042.174518069@linutronix.de -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - arch/ia64/kernel/topology.c | 6 ------ - 1 file changed, 6 deletions(-) - ---- a/arch/ia64/kernel/topology.c -+++ b/arch/ia64/kernel/topology.c -@@ -355,18 +355,12 @@ static int cache_add_dev(unsigned int cp - unsigned long i, j; - struct cache_info *this_object; - int retval = 0; -- cpumask_t oldmask; - - if (all_cpu_cache_info[cpu].kobj.parent) - return 0; - -- oldmask = current->cpus_allowed; -- retval = set_cpus_allowed_ptr(current, cpumask_of(cpu)); -- if (unlikely(retval)) -- return retval; - - retval = cpu_cache_sysfs_init(cpu); -- set_cpus_allowed_ptr(current, &oldmask); - if (unlikely(retval < 0)) - return retval; - diff --git a/patches/0001-init-Pin-init-task-to-the-boot-CPU-initially.patch b/patches/0001-init-Pin-init-task-to-the-boot-CPU-initially.patch deleted file mode 100644 index 7a806149e3a1..000000000000 --- a/patches/0001-init-Pin-init-task-to-the-boot-CPU-initially.patch +++ /dev/null @@ -1,73 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Tue, 16 May 2017 20:42:32 +0200 -Subject: [PATCH 01/17] init: Pin init task to the boot CPU, initially - -Some of the boot code in init_kernel_freeable() which runs before SMP -bringup assumes (rightfully) that it runs on the boot CPU and therefore can -use smp_processor_id() in preemptible context. - -That works so far because the smp_processor_id() check starts to be -effective after smp bringup. That's just wrong. Starting with SMP bringup -and the ability to move threads around, smp_processor_id() in preemptible -context is broken. - -Aside of that it does not make sense to allow init to run on all CPUs -before sched_smp_init() has been run. - -Pin the init to the boot CPU so the existing code can continue to use -smp_processor_id() without triggering the checks when the enabling of those -checks starts earlier. - -Tested-by: Mark Rutland <mark.rutland@arm.com> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Cc: Linus Torvalds <torvalds@linux-foundation.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Link: http://lkml.kernel.org/r/20170516184734.943149935@linutronix.de -Signed-off-by: Ingo Molnar <mingo@kernel.org> ---- - init/main.c | 17 ++++++++++++----- - 1 file changed, 12 insertions(+), 5 deletions(-) - ---- a/init/main.c -+++ b/init/main.c -@@ -389,6 +389,7 @@ static __initdata DECLARE_COMPLETION(kth - - static noinline void __ref rest_init(void) - { -+ struct task_struct *tsk; - int pid; - - rcu_scheduler_starting(); -@@ -397,7 +398,17 @@ static noinline void __ref rest_init(voi - * the init task will end up wanting to create kthreads, which, if - * we schedule it before we create kthreadd, will OOPS. - */ -- kernel_thread(kernel_init, NULL, CLONE_FS); -+ pid = kernel_thread(kernel_init, NULL, CLONE_FS); -+ /* -+ * Pin init on the boot CPU. Task migration is not properly working -+ * until sched_init_smp() has been run. It will set the allowed -+ * CPUs for init to the non isolated CPUs. -+ */ -+ rcu_read_lock(); -+ tsk = find_task_by_pid_ns(pid, &init_pid_ns); -+ set_cpus_allowed_ptr(tsk, cpumask_of(smp_processor_id())); -+ rcu_read_unlock(); -+ - numa_default_policy(); - pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); - rcu_read_lock(); -@@ -1011,10 +1022,6 @@ static noinline void __init kernel_init_ - * init can allocate pages on any node - */ - set_mems_allowed(node_states[N_MEMORY]); -- /* -- * init can run on any cpu. -- */ -- set_cpus_allowed_ptr(current, cpu_all_mask); - - cad_pid = task_pid(current); - diff --git a/patches/0001-rtmutex-Deboost-before-waking-up-the-top-waiter.patch b/patches/0001-rtmutex-Deboost-before-waking-up-the-top-waiter.patch deleted file mode 100644 index b3202e76bd89..000000000000 --- a/patches/0001-rtmutex-Deboost-before-waking-up-the-top-waiter.patch +++ /dev/null @@ -1,177 +0,0 @@ -From: Xunlei Pang <xlpang@redhat.com> -Date: Thu, 23 Mar 2017 15:56:07 +0100 -Subject: [PATCH 1/9] rtmutex: Deboost before waking up the top waiter - -We should deboost before waking the high-priority task, such that we -don't run two tasks with the same "state" (priority, deadline, -sched_class, etc). - -In order to make sure the boosting task doesn't start running between -unlock and deboost (due to 'spurious' wakeup), we move the deboost -under the wait_lock, that way its serialized against the wait loop in -__rt_mutex_slowlock(). - -Doing the deboost early can however lead to priority-inversion if -current would get preempted after the deboost but before waking our -high-prio task, hence we disable preemption before doing deboost, and -enabling it after the wake up is over. - -This gets us the right semantic order, but most importantly however; -this change ensures pointer stability for the next patch, where we -have rt_mutex_setprio() cache a pointer to the top-most waiter task. -If we, as before this change, do the wakeup first and then deboost, -this pointer might point into thin air. - -[peterz: Changelog + patch munging] -Suggested-by: Peter Zijlstra <peterz@infradead.org> -Signed-off-by: Xunlei Pang <xlpang@redhat.com> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Acked-by: Steven Rostedt <rostedt@goodmis.org> -Cc: juri.lelli@arm.com -Cc: bigeasy@linutronix.de -Cc: mathieu.desnoyers@efficios.com -Cc: jdesfossez@efficios.com -Cc: bristot@redhat.com -Link: http://lkml.kernel.org/r/20170323150216.110065320@infradead.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - kernel/futex.c | 5 --- - kernel/locking/rtmutex.c | 59 +++++++++++++++++++++------------------- - kernel/locking/rtmutex_common.h | 2 - - 3 files changed, 34 insertions(+), 32 deletions(-) - ---- a/kernel/futex.c -+++ b/kernel/futex.c -@@ -1460,10 +1460,7 @@ static int wake_futex_pi(u32 __user *uad - out_unlock: - raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); - -- if (deboost) { -- wake_up_q(&wake_q); -- rt_mutex_adjust_prio(current); -- } -+ rt_mutex_postunlock(&wake_q, deboost); - - return ret; - } ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -373,24 +373,6 @@ static void __rt_mutex_adjust_prio(struc - } - - /* -- * Adjust task priority (undo boosting). Called from the exit path of -- * rt_mutex_slowunlock() and rt_mutex_slowlock(). -- * -- * (Note: We do this outside of the protection of lock->wait_lock to -- * allow the lock to be taken while or before we readjust the priority -- * of task. We do not use the spin_xx_mutex() variants here as we are -- * outside of the debug path.) -- */ --void rt_mutex_adjust_prio(struct task_struct *task) --{ -- unsigned long flags; -- -- raw_spin_lock_irqsave(&task->pi_lock, flags); -- __rt_mutex_adjust_prio(task); -- raw_spin_unlock_irqrestore(&task->pi_lock, flags); --} -- --/* - * Deadlock detection is conditional: - * - * If CONFIG_DEBUG_RT_MUTEXES=n, deadlock detection is only conducted -@@ -1051,6 +1033,7 @@ static void mark_wakeup_next_waiter(stru - * lock->wait_lock. - */ - rt_mutex_dequeue_pi(current, waiter); -+ __rt_mutex_adjust_prio(current); - - /* - * As we are waking up the top waiter, and the waiter stays -@@ -1393,6 +1376,16 @@ static bool __sched rt_mutex_slowunlock( - */ - mark_wakeup_next_waiter(wake_q, lock); - -+ /* -+ * We should deboost before waking the top waiter task such that -+ * we don't run two tasks with the 'same' priority. This however -+ * can lead to prio-inversion if we would get preempted after -+ * the deboost but before waking our high-prio task, hence the -+ * preempt_disable before unlock. Pairs with preempt_enable() in -+ * rt_mutex_postunlock(); -+ */ -+ preempt_disable(); -+ - raw_spin_unlock_irqrestore(&lock->wait_lock, flags); - - /* check PI boosting */ -@@ -1442,6 +1435,18 @@ rt_mutex_fasttrylock(struct rt_mutex *lo - return slowfn(lock); - } - -+/* -+ * Undo pi boosting (if necessary) and wake top waiter. -+ */ -+void rt_mutex_postunlock(struct wake_q_head *wake_q, bool deboost) -+{ -+ wake_up_q(wake_q); -+ -+ /* Pairs with preempt_disable() in rt_mutex_slowunlock() */ -+ if (deboost) -+ preempt_enable(); -+} -+ - static inline void - rt_mutex_fastunlock(struct rt_mutex *lock, - bool (*slowfn)(struct rt_mutex *lock, -@@ -1455,11 +1460,7 @@ rt_mutex_fastunlock(struct rt_mutex *loc - - deboost = slowfn(lock, &wake_q); - -- wake_up_q(&wake_q); -- -- /* Undo pi boosting if necessary: */ -- if (deboost) -- rt_mutex_adjust_prio(current); -+ rt_mutex_postunlock(&wake_q, deboost); - } - - /** -@@ -1572,6 +1573,13 @@ bool __sched __rt_mutex_futex_unlock(str - } - - mark_wakeup_next_waiter(wake_q, lock); -+ /* -+ * We've already deboosted, retain preempt_disabled when dropping -+ * the wait_lock to avoid inversion until the wakeup. Matched -+ * by rt_mutex_postunlock(); -+ */ -+ preempt_disable(); -+ - return true; /* deboost and wakeups */ - } - -@@ -1584,10 +1592,7 @@ void __sched rt_mutex_futex_unlock(struc - deboost = __rt_mutex_futex_unlock(lock, &wake_q); - raw_spin_unlock_irq(&lock->wait_lock); - -- if (deboost) { -- wake_up_q(&wake_q); -- rt_mutex_adjust_prio(current); -- } -+ rt_mutex_postunlock(&wake_q, deboost); - } - - /** ---- a/kernel/locking/rtmutex_common.h -+++ b/kernel/locking/rtmutex_common.h -@@ -122,7 +122,7 @@ extern void rt_mutex_futex_unlock(struct - extern bool __rt_mutex_futex_unlock(struct rt_mutex *lock, - struct wake_q_head *wqh); - --extern void rt_mutex_adjust_prio(struct task_struct *task); -+extern void rt_mutex_postunlock(struct wake_q_head *wake_q, bool deboost); - - #ifdef CONFIG_DEBUG_RT_MUTEXES - # include "rtmutex-debug.h" diff --git a/patches/0001-sched-clock-Fix-early-boot-preempt-assumption-in-__s.patch b/patches/0001-sched-clock-Fix-early-boot-preempt-assumption-in-__s.patch deleted file mode 100644 index e9ba34641b35..000000000000 --- a/patches/0001-sched-clock-Fix-early-boot-preempt-assumption-in-__s.patch +++ /dev/null @@ -1,61 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Wed, 24 May 2017 08:52:02 +0200 -Subject: [PATCH] sched/clock: Fix early boot preempt assumption in - __set_sched_clock_stable() - -The more strict early boot preemption warnings found that -__set_sched_clock_stable() was incorrectly assuming we'd still be -running on a single CPU: - - BUG: using smp_processor_id() in preemptible [00000000] code: swapper/0/1 - caller is debug_smp_processor_id+0x1c/0x1e - CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.12.0-rc2-00108-g1c3c5ea #1 - Call Trace: - dump_stack+0x110/0x192 - check_preemption_disabled+0x10c/0x128 - ? set_debug_rodata+0x25/0x25 - debug_smp_processor_id+0x1c/0x1e - sched_clock_init_late+0x27/0x87 - [...] - -Fix it by disabling IRQs. - -Reported-by: kernel test robot <xiaolong.ye@intel.com> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Acked-by: Thomas Gleixner <tglx@linutronix.de> -Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Cc: Linus Torvalds <torvalds@linux-foundation.org> -Cc: Mark Rutland <mark.rutland@arm.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: lkp@01.org -Cc: tipbuild@zytor.com -Link: http://lkml.kernel.org/r/20170524065202.v25vyu7pvba5mhpd@hirez.programming.kicks-ass.net -Signed-off-by: Ingo Molnar <mingo@kernel.org> ---- - kernel/sched/clock.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - ---- a/kernel/sched/clock.c -+++ b/kernel/sched/clock.c -@@ -132,12 +132,19 @@ static void __scd_stamp(struct sched_clo - - static void __set_sched_clock_stable(void) - { -- struct sched_clock_data *scd = this_scd(); -+ struct sched_clock_data *scd; - - /* -+ * Since we're still unstable and the tick is already running, we have -+ * to disable IRQs in order to get a consistent scd->tick* reading. -+ */ -+ local_irq_disable(); -+ scd = this_scd(); -+ /* - * Attempt to make the (initial) unstable->stable transition continuous. - */ - __sched_clock_offset = (scd->tick_gtod + __gtod_offset) - (scd->tick_raw); -+ local_irq_enable(); - - printk(KERN_INFO "sched_clock: Marking stable (%lld, %lld)->(%lld, %lld)\n", - scd->tick_gtod, __gtod_offset, diff --git a/patches/0002-arm-Adjust-system_state-check.patch b/patches/0002-arm-Adjust-system_state-check.patch deleted file mode 100644 index 78888688cee1..000000000000 --- a/patches/0002-arm-Adjust-system_state-check.patch +++ /dev/null @@ -1,36 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Tue, 16 May 2017 20:42:33 +0200 -Subject: [PATCH 02/17] arm: Adjust system_state check - -To enable smp_processor_id() and might_sleep() debug checks earlier, it's -required to add system states between SYSTEM_BOOTING and SYSTEM_RUNNING. - -Adjust the system_state check in ipi_cpu_stop() to handle the extra states. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Cc: Linus Torvalds <torvalds@linux-foundation.org> -Cc: Mark Rutland <mark.rutland@arm.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Russell King <linux@armlinux.org.uk> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: linux-arm-kernel@lists.infradead.org -Link: http://lkml.kernel.org/r/20170516184735.020718977@linutronix.de -Signed-off-by: Ingo Molnar <mingo@kernel.org> ---- - arch/arm/kernel/smp.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/arch/arm/kernel/smp.c -+++ b/arch/arm/kernel/smp.c -@@ -555,8 +555,7 @@ static DEFINE_RAW_SPINLOCK(stop_lock); - */ - static void ipi_cpu_stop(unsigned int cpu) - { -- if (system_state == SYSTEM_BOOTING || -- system_state == SYSTEM_RUNNING) { -+ if (system_state <= SYSTEM_RUNNING) { - raw_spin_lock(&stop_lock); - pr_crit("CPU%u: stopping\n", cpu); - dump_stack(); diff --git a/patches/0002-cpu-hotplug-Provide-lockdep_assert_cpus_held.patch b/patches/0002-cpu-hotplug-Provide-lockdep_assert_cpus_held.patch deleted file mode 100644 index d3ddb7be1ab5..000000000000 --- a/patches/0002-cpu-hotplug-Provide-lockdep_assert_cpus_held.patch +++ /dev/null @@ -1,40 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 24 May 2017 10:15:13 +0200 -Subject: [PATCH 02/32] cpu/hotplug: Provide lockdep_assert_cpus_held() - -Provide a stub function which can be used in places where existing -get_online_cpus() calls are moved to call sites. - -This stub is going to be filled by the final conversion of the hotplug -locking mechanism to a percpu rwsem. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Tested-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Acked-by: Ingo Molnar <mingo@kernel.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Steven Rostedt <rostedt@goodmis.org> -Link: http://lkml.kernel.org/r/20170524081547.161282442@linutronix.de ---- - include/linux/cpu.h | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/include/linux/cpu.h -+++ b/include/linux/cpu.h -@@ -103,6 +103,7 @@ extern void cpus_write_lock(void); - extern void cpus_write_unlock(void); - extern void cpus_read_lock(void); - extern void cpus_read_unlock(void); -+static inline void lockdep_assert_cpus_held(void) { } - extern void cpu_hotplug_disable(void); - extern void cpu_hotplug_enable(void); - void clear_tasks_mm_cpumask(int cpu); -@@ -114,6 +115,7 @@ static inline void cpus_write_lock(void) - static inline void cpus_write_unlock(void) { } - static inline void cpus_read_lock(void) { } - static inline void cpus_read_unlock(void) { } -+static inline void lockdep_assert_cpus_held(void) { } - static inline void cpu_hotplug_disable(void) { } - static inline void cpu_hotplug_enable(void) { } - #endif /* !CONFIG_HOTPLUG_CPU */ diff --git a/patches/0002-futex-Fix-small-and-harmless-looking-inconsistencies.patch b/patches/0002-futex-Fix-small-and-harmless-looking-inconsistencies.patch deleted file mode 100644 index cdd80c952bd0..000000000000 --- a/patches/0002-futex-Fix-small-and-harmless-looking-inconsistencies.patch +++ /dev/null @@ -1,54 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Fri, 7 Apr 2017 09:04:07 +0200 -Subject: [PATCH 2/4] futex: Fix small (and harmless looking) inconsistencies - -During (post-commit) review Darren spotted a few minor things. One -(harmless AFAICT) type inconsistency and a comment that wasn't as -clear as hoped. - -Reported-by: Darren Hart (VMWare) <dvhart@infradead.org> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Reviewed-by: Darren Hart (VMware) <dvhart@infradead.org> -Cc: Linus Torvalds <torvalds@linux-foundation.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Thomas Gleixner <tglx@linutronix.de> -Cc: linux-kernel@vger.kernel.org -Signed-off-by: Ingo Molnar <mingo@kernel.org> ---- - kernel/futex.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - ---- a/kernel/futex.c -+++ b/kernel/futex.c -@@ -1025,7 +1025,8 @@ static int attach_to_pi_state(u32 __user - struct futex_pi_state **ps) - { - pid_t pid = uval & FUTEX_TID_MASK; -- int ret, uval2; -+ u32 uval2; -+ int ret; - - /* - * Userspace might have messed up non-PI and PI futexes [3] -@@ -1441,6 +1442,11 @@ static int wake_futex_pi(u32 __user *uad - if (ret) - goto out_unlock; - -+ /* -+ * This is a point of no return; once we modify the uval there is no -+ * going back and subsequent operations must not fail. -+ */ -+ - raw_spin_lock(&pi_state->owner->pi_lock); - WARN_ON(list_empty(&pi_state->list)); - list_del_init(&pi_state->list); -@@ -1452,9 +1458,6 @@ static int wake_futex_pi(u32 __user *uad - pi_state->owner = new_owner; - raw_spin_unlock(&new_owner->pi_lock); - -- /* -- * We've updated the uservalue, this unlock cannot fail. -- */ - postunlock = __rt_mutex_futex_unlock(&pi_state->pi_mutex, &wake_q); - - out_unlock: diff --git a/patches/0002-futex-Use-smp_store_release-in-mark_wake_futex.patch b/patches/0002-futex-Use-smp_store_release-in-mark_wake_futex.patch deleted file mode 100644 index 8f8f323fb6ab..000000000000 --- a/patches/0002-futex-Use-smp_store_release-in-mark_wake_futex.patch +++ /dev/null @@ -1,38 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Wed, 22 Mar 2017 11:35:49 +0100 -Subject: [PATCH] futex: Use smp_store_release() in mark_wake_futex() - -Upstream commit 1b367ece0d7e696cab1c8501bab282cc6a538b3f - -Since the futex_q can dissapear the instruction after assigning NULL, -this really should be a RELEASE barrier. That stops loads from hitting -dead memory too. - -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: juri.lelli@arm.com -Cc: bigeasy@linutronix.de -Cc: xlpang@redhat.com -Cc: rostedt@goodmis.org -Cc: mathieu.desnoyers@efficios.com -Cc: jdesfossez@efficios.com -Cc: dvhart@infradead.org -Cc: bristot@redhat.com -Link: http://lkml.kernel.org/r/20170322104151.604296452@infradead.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/futex.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/kernel/futex.c -+++ b/kernel/futex.c -@@ -1290,8 +1290,7 @@ static void mark_wake_futex(struct wake_ - * memory barrier is required here to prevent the following - * store to lock_ptr from getting ahead of the plist_del. - */ -- smp_wmb(); -- q->lock_ptr = NULL; -+ smp_store_release(&q->lock_ptr, NULL); - } - - static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *top_waiter, diff --git a/patches/0002-hrtimer-Correct-blantanly-wrong-comment.patch b/patches/0002-hrtimer-Correct-blantanly-wrong-comment.patch index 6f81c31bc121..7362d5417520 100644 --- a/patches/0002-hrtimer-Correct-blantanly-wrong-comment.patch +++ b/patches/0002-hrtimer-Correct-blantanly-wrong-comment.patch @@ -21,7 +21,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -1203,9 +1203,9 @@ static void __run_hrtimer(struct hrtimer +@@ -1204,9 +1204,9 @@ static void __run_hrtimer(struct hrtimer timer->is_rel = false; /* diff --git a/patches/0002-sched-rtmutex-deadline-Fix-a-PI-crash-for-deadline-t.patch b/patches/0002-sched-rtmutex-deadline-Fix-a-PI-crash-for-deadline-t.patch deleted file mode 100644 index be4a67d76730..000000000000 --- a/patches/0002-sched-rtmutex-deadline-Fix-a-PI-crash-for-deadline-t.patch +++ /dev/null @@ -1,166 +0,0 @@ -From: Xunlei Pang <xlpang@redhat.com> -Date: Thu, 23 Mar 2017 15:56:08 +0100 -Subject: [PATCH 2/9] sched/rtmutex/deadline: Fix a PI crash for deadline tasks - -A crash happened while I was playing with deadline PI rtmutex. - - BUG: unable to handle kernel NULL pointer dereference at 0000000000000018 - IP: [<ffffffff810eeb8f>] rt_mutex_get_top_task+0x1f/0x30 - PGD 232a75067 PUD 230947067 PMD 0 - Oops: 0000 [#1] SMP - CPU: 1 PID: 10994 Comm: a.out Not tainted - - Call Trace: - [<ffffffff810b658c>] enqueue_task+0x2c/0x80 - [<ffffffff810ba763>] activate_task+0x23/0x30 - [<ffffffff810d0ab5>] pull_dl_task+0x1d5/0x260 - [<ffffffff810d0be6>] pre_schedule_dl+0x16/0x20 - [<ffffffff8164e783>] __schedule+0xd3/0x900 - [<ffffffff8164efd9>] schedule+0x29/0x70 - [<ffffffff8165035b>] __rt_mutex_slowlock+0x4b/0xc0 - [<ffffffff81650501>] rt_mutex_slowlock+0xd1/0x190 - [<ffffffff810eeb33>] rt_mutex_timed_lock+0x53/0x60 - [<ffffffff810ecbfc>] futex_lock_pi.isra.18+0x28c/0x390 - [<ffffffff810ed8b0>] do_futex+0x190/0x5b0 - [<ffffffff810edd50>] SyS_futex+0x80/0x180 - -This is because rt_mutex_enqueue_pi() and rt_mutex_dequeue_pi() -are only protected by pi_lock when operating pi waiters, while -rt_mutex_get_top_task(), will access them with rq lock held but -not holding pi_lock. - -In order to tackle it, we introduce new "pi_top_task" pointer -cached in task_struct, and add new rt_mutex_update_top_task() -to update its value, it can be called by rt_mutex_setprio() -which held both owner's pi_lock and rq lock. Thus "pi_top_task" -can be safely accessed by enqueue_task_dl() under rq lock. - -Originally-From: Peter Zijlstra <peterz@infradead.org> -Signed-off-by: Xunlei Pang <xlpang@redhat.com> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Acked-by: Steven Rostedt <rostedt@goodmis.org> -Reviewed-by: Thomas Gleixner <tglx@linutronix.de> -Cc: juri.lelli@arm.com -Cc: bigeasy@linutronix.de -Cc: mathieu.desnoyers@efficios.com -Cc: jdesfossez@efficios.com -Cc: bristot@redhat.com -Link: http://lkml.kernel.org/r/20170323150216.157682758@infradead.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - include/linux/init_task.h | 1 + - include/linux/sched.h | 2 ++ - include/linux/sched/rt.h | 1 + - kernel/fork.c | 1 + - kernel/locking/rtmutex.c | 29 +++++++++++++++++++++-------- - kernel/sched/core.c | 2 ++ - 6 files changed, 28 insertions(+), 8 deletions(-) - ---- a/include/linux/init_task.h -+++ b/include/linux/init_task.h -@@ -181,6 +181,7 @@ extern struct cred init_cred; - #ifdef CONFIG_RT_MUTEXES - # define INIT_RT_MUTEXES(tsk) \ - .pi_waiters = RB_ROOT, \ -+ .pi_top_task = NULL, \ - .pi_waiters_leftmost = NULL, - #else - # define INIT_RT_MUTEXES(tsk) ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -779,6 +779,8 @@ struct task_struct { - /* PI waiters blocked on a rt_mutex held by this task: */ - struct rb_root pi_waiters; - struct rb_node *pi_waiters_leftmost; -+ /* Updated under owner's pi_lock and rq lock */ -+ struct task_struct *pi_top_task; - /* Deadlock detection and priority inheritance handling: */ - struct rt_mutex_waiter *pi_blocked_on; - #endif ---- a/include/linux/sched/rt.h -+++ b/include/linux/sched/rt.h -@@ -21,6 +21,7 @@ static inline int rt_task(struct task_st - extern int rt_mutex_getprio(struct task_struct *p); - extern void rt_mutex_setprio(struct task_struct *p, int prio); - extern int rt_mutex_get_effective_prio(struct task_struct *task, int newprio); -+extern void rt_mutex_update_top_task(struct task_struct *p); - extern struct task_struct *rt_mutex_get_top_task(struct task_struct *task); - extern void rt_mutex_adjust_pi(struct task_struct *p); - static inline bool tsk_is_pi_blocked(struct task_struct *tsk) ---- a/kernel/fork.c -+++ b/kernel/fork.c -@@ -1438,6 +1438,7 @@ static void rt_mutex_init_task(struct ta - #ifdef CONFIG_RT_MUTEXES - p->pi_waiters = RB_ROOT; - p->pi_waiters_leftmost = NULL; -+ p->pi_top_task = NULL; - p->pi_blocked_on = NULL; - #endif - } ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -323,6 +323,19 @@ rt_mutex_dequeue_pi(struct task_struct * - } - - /* -+ * Must hold both p->pi_lock and task_rq(p)->lock. -+ */ -+void rt_mutex_update_top_task(struct task_struct *p) -+{ -+ if (!task_has_pi_waiters(p)) { -+ p->pi_top_task = NULL; -+ return; -+ } -+ -+ p->pi_top_task = task_top_pi_waiter(p)->task; -+} -+ -+/* - * Calculate task priority from the waiter tree priority - * - * Return task->normal_prio when the waiter tree is empty or when -@@ -337,12 +350,12 @@ int rt_mutex_getprio(struct task_struct - task->normal_prio); - } - -+/* -+ * Must hold either p->pi_lock or task_rq(p)->lock. -+ */ - struct task_struct *rt_mutex_get_top_task(struct task_struct *task) - { -- if (likely(!task_has_pi_waiters(task))) -- return NULL; -- -- return task_top_pi_waiter(task)->task; -+ return task->pi_top_task; - } - - /* -@@ -351,12 +364,12 @@ struct task_struct *rt_mutex_get_top_tas - */ - int rt_mutex_get_effective_prio(struct task_struct *task, int newprio) - { -- if (!task_has_pi_waiters(task)) -+ struct task_struct *top_task = rt_mutex_get_top_task(task); -+ -+ if (!top_task) - return newprio; - -- if (task_top_pi_waiter(task)->task->prio <= newprio) -- return task_top_pi_waiter(task)->task->prio; -- return newprio; -+ return min(top_task->prio, newprio); - } - - /* ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -3712,6 +3712,8 @@ void rt_mutex_setprio(struct task_struct - goto out_unlock; - } - -+ rt_mutex_update_top_task(p); -+ - trace_sched_pi_setprio(p, prio); - oldprio = p->prio; - diff --git a/patches/0002-tracing-Add-support-to-detect-and-avoid-duplicates.patch b/patches/0002-tracing-Add-support-to-detect-and-avoid-duplicates.patch index 17e926674fef..78c4112ee8d6 100644 --- a/patches/0002-tracing-Add-support-to-detect-and-avoid-duplicates.patch +++ b/patches/0002-tracing-Add-support-to-detect-and-avoid-duplicates.patch @@ -48,7 +48,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/trace/tracing_map.c +++ b/kernel/trace/tracing_map.c -@@ -411,6 +411,7 @@ static inline struct tracing_map_elt * +@@ -414,6 +414,7 @@ static inline struct tracing_map_elt * __tracing_map_insert(struct tracing_map *map, void *key, bool lookup_only) { u32 idx, key_hash, test_key; @@ -56,7 +56,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> struct tracing_map_entry *entry; key_hash = jhash(key, map->key_size, 0); -@@ -423,10 +424,31 @@ static inline struct tracing_map_elt * +@@ -426,10 +427,31 @@ static inline struct tracing_map_elt * entry = TRACING_MAP_ENTRY(map->map, idx); test_key = entry->key; @@ -92,7 +92,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } if (!test_key) { -@@ -448,6 +470,13 @@ static inline struct tracing_map_elt * +@@ -451,6 +473,13 @@ static inline struct tracing_map_elt * atomic64_inc(&map->hits); return entry->val; diff --git a/patches/0002-workqueue-Provide-work_on_cpu_safe.patch b/patches/0002-workqueue-Provide-work_on_cpu_safe.patch deleted file mode 100644 index 80a6bef1dfea..000000000000 --- a/patches/0002-workqueue-Provide-work_on_cpu_safe.patch +++ /dev/null @@ -1,83 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 12 Apr 2017 22:07:28 +0200 -Subject: [PATCH 02/13] workqueue: Provide work_on_cpu_safe() - -work_on_cpu() is not protected against CPU hotplug. For code which requires -to be either executed on an online CPU or to fail if the CPU is not -available the callsite would have to protect against CPU hotplug. - -Provide a function which does get/put_online_cpus() around the call to -work_on_cpu() and fails the call with -ENODEV if the target CPU is not -online. - -Preparatory patch to convert several racy task affinity manipulations. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Tejun Heo <tj@kernel.org> -Cc: Fenghua Yu <fenghua.yu@intel.com> -Cc: Tony Luck <tony.luck@intel.com> -Cc: Herbert Xu <herbert@gondor.apana.org.au> -Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Lai Jiangshan <jiangshanlai@gmail.com> -Cc: Viresh Kumar <viresh.kumar@linaro.org> -Cc: Michael Ellerman <mpe@ellerman.id.au> -Cc: "David S. Miller" <davem@davemloft.net> -Cc: Len Brown <lenb@kernel.org> -Link: http://lkml.kernel.org/r/20170412201042.262610721@linutronix.de -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - include/linux/workqueue.h | 5 +++++ - kernel/workqueue.c | 23 +++++++++++++++++++++++ - 2 files changed, 28 insertions(+) - ---- a/include/linux/workqueue.h -+++ b/include/linux/workqueue.h -@@ -608,8 +608,13 @@ static inline long work_on_cpu(int cpu, - { - return fn(arg); - } -+static inline long work_on_cpu_safe(int cpu, long (*fn)(void *), void *arg) -+{ -+ return fn(arg); -+} - #else - long work_on_cpu(int cpu, long (*fn)(void *), void *arg); -+long work_on_cpu_safe(int cpu, long (*fn)(void *), void *arg); - #endif /* CONFIG_SMP */ - - #ifdef CONFIG_FREEZER ---- a/kernel/workqueue.c -+++ b/kernel/workqueue.c -@@ -4735,6 +4735,29 @@ long work_on_cpu(int cpu, long (*fn)(voi - return wfc.ret; - } - EXPORT_SYMBOL_GPL(work_on_cpu); -+ -+/** -+ * work_on_cpu_safe - run a function in thread context on a particular cpu -+ * @cpu: the cpu to run on -+ * @fn: the function to run -+ * @arg: the function argument -+ * -+ * Disables CPU hotplug and calls work_on_cpu(). The caller must not hold -+ * any locks which would prevent @fn from completing. -+ * -+ * Return: The value @fn returns. -+ */ -+long work_on_cpu_safe(int cpu, long (*fn)(void *), void *arg) -+{ -+ long ret = -ENODEV; -+ -+ get_online_cpus(); -+ if (cpu_online(cpu)) -+ ret = work_on_cpu(cpu, fn, arg); -+ put_online_cpus(); -+ return ret; -+} -+EXPORT_SYMBOL_GPL(work_on_cpu_safe); - #endif /* CONFIG_SMP */ - - #ifdef CONFIG_FREEZER diff --git a/patches/0003-arm64-Adjust-system_state-check.patch b/patches/0003-arm64-Adjust-system_state-check.patch deleted file mode 100644 index 3382d580c7ca..000000000000 --- a/patches/0003-arm64-Adjust-system_state-check.patch +++ /dev/null @@ -1,37 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Tue, 16 May 2017 20:42:34 +0200 -Subject: [PATCH 03/17] arm64: Adjust system_state check - -To enable smp_processor_id() and might_sleep() debug checks earlier, it's -required to add system states between SYSTEM_BOOTING and SYSTEM_RUNNING. - -Adjust the system_state check in smp_send_stop() to handle the extra states. - -Tested-by: Mark Rutland <mark.rutland@arm.com> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Acked-by: Mark Rutland <mark.rutland@arm.com> -Acked-by: Catalin Marinas <catalin.marinas@arm.com> -Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Cc: Linus Torvalds <torvalds@linux-foundation.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: Will Deacon <will.deacon@arm.com> -Link: http://lkml.kernel.org/r/20170516184735.112589728@linutronix.de -Signed-off-by: Ingo Molnar <mingo@kernel.org> ---- - arch/arm64/kernel/smp.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/arch/arm64/kernel/smp.c -+++ b/arch/arm64/kernel/smp.c -@@ -915,8 +915,7 @@ void smp_send_stop(void) - cpumask_copy(&mask, cpu_online_mask); - cpumask_clear_cpu(smp_processor_id(), &mask); - -- if (system_state == SYSTEM_BOOTING || -- system_state == SYSTEM_RUNNING) -+ if (system_state <= SYSTEM_RUNNING) - pr_crit("SMP: stopping secondary CPUs\n"); - smp_cross_call(&mask, IPI_CPU_STOP); - } diff --git a/patches/0003-cpu-hotplug-Provide-cpuhp_setup-remove_state-_nocall.patch b/patches/0003-cpu-hotplug-Provide-cpuhp_setup-remove_state-_nocall.patch deleted file mode 100644 index a62c414e2f13..000000000000 --- a/patches/0003-cpu-hotplug-Provide-cpuhp_setup-remove_state-_nocall.patch +++ /dev/null @@ -1,210 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Wed, 24 May 2017 10:15:14 +0200 -Subject: [PATCH 03/32] cpu/hotplug: Provide - cpuhp_setup/remove_state[_nocalls]_cpuslocked() - -Some call sites of cpuhp_setup/remove_state[_nocalls]() are within a -cpus_read locked region. - -cpuhp_setup/remove_state[_nocalls]() call cpus_read_lock() as well, which -is possible in the current implementation but prevents converting the -hotplug locking to a percpu rwsem. - -Provide locked versions of the interfaces to avoid nested calls to -cpus_read_lock(). - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Tested-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Acked-by: Ingo Molnar <mingo@kernel.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Link: http://lkml.kernel.org/r/20170524081547.239600868@linutronix.de ---- - include/linux/cpuhotplug.h | 29 +++++++++++++++++++++++++++ - kernel/cpu.c | 47 ++++++++++++++++++++++++++++++++++----------- - 2 files changed, 65 insertions(+), 11 deletions(-) - ---- a/include/linux/cpuhotplug.h -+++ b/include/linux/cpuhotplug.h -@@ -151,6 +151,11 @@ int __cpuhp_setup_state(enum cpuhp_state - int (*startup)(unsigned int cpu), - int (*teardown)(unsigned int cpu), bool multi_instance); - -+int __cpuhp_setup_state_cpuslocked(enum cpuhp_state state, const char *name, -+ bool invoke, -+ int (*startup)(unsigned int cpu), -+ int (*teardown)(unsigned int cpu), -+ bool multi_instance); - /** - * cpuhp_setup_state - Setup hotplug state callbacks with calling the callbacks - * @state: The state for which the calls are installed -@@ -169,6 +174,15 @@ static inline int cpuhp_setup_state(enum - return __cpuhp_setup_state(state, name, true, startup, teardown, false); - } - -+static inline int cpuhp_setup_state_cpuslocked(enum cpuhp_state state, -+ const char *name, -+ int (*startup)(unsigned int cpu), -+ int (*teardown)(unsigned int cpu)) -+{ -+ return __cpuhp_setup_state_cpuslocked(state, name, true, startup, -+ teardown, false); -+} -+ - /** - * cpuhp_setup_state_nocalls - Setup hotplug state callbacks without calling the - * callbacks -@@ -189,6 +203,15 @@ static inline int cpuhp_setup_state_noca - false); - } - -+static inline int cpuhp_setup_state_nocalls_cpuslocked(enum cpuhp_state state, -+ const char *name, -+ int (*startup)(unsigned int cpu), -+ int (*teardown)(unsigned int cpu)) -+{ -+ return __cpuhp_setup_state_cpuslocked(state, name, false, startup, -+ teardown, false); -+} -+ - /** - * cpuhp_setup_state_multi - Add callbacks for multi state - * @state: The state for which the calls are installed -@@ -248,6 +271,7 @@ static inline int cpuhp_state_add_instan - } - - void __cpuhp_remove_state(enum cpuhp_state state, bool invoke); -+void __cpuhp_remove_state_cpuslocked(enum cpuhp_state state, bool invoke); - - /** - * cpuhp_remove_state - Remove hotplug state callbacks and invoke the teardown -@@ -271,6 +295,11 @@ static inline void cpuhp_remove_state_no - __cpuhp_remove_state(state, false); - } - -+static inline void cpuhp_remove_state_nocalls_cpuslocked(enum cpuhp_state state) -+{ -+ __cpuhp_remove_state_cpuslocked(state, false); -+} -+ - /** - * cpuhp_remove_multi_state - Remove hotplug multi state callback - * @state: The state for which the calls are removed ---- a/kernel/cpu.c -+++ b/kernel/cpu.c -@@ -1458,7 +1458,7 @@ int __cpuhp_state_add_instance(enum cpuh - EXPORT_SYMBOL_GPL(__cpuhp_state_add_instance); - - /** -- * __cpuhp_setup_state - Setup the callbacks for an hotplug machine state -+ * __cpuhp_setup_state_cpuslocked - Setup the callbacks for an hotplug machine state - * @state: The state to setup - * @invoke: If true, the startup function is invoked for cpus where - * cpu state >= @state -@@ -1467,25 +1467,27 @@ EXPORT_SYMBOL_GPL(__cpuhp_state_add_inst - * @multi_instance: State is set up for multiple instances which get - * added afterwards. - * -+ * The caller needs to hold cpus read locked while calling this function. - * Returns: - * On success: - * Positive state number if @state is CPUHP_AP_ONLINE_DYN - * 0 for all other states - * On failure: proper (negative) error code - */ --int __cpuhp_setup_state(enum cpuhp_state state, -- const char *name, bool invoke, -- int (*startup)(unsigned int cpu), -- int (*teardown)(unsigned int cpu), -- bool multi_instance) -+int __cpuhp_setup_state_cpuslocked(enum cpuhp_state state, -+ const char *name, bool invoke, -+ int (*startup)(unsigned int cpu), -+ int (*teardown)(unsigned int cpu), -+ bool multi_instance) - { - int cpu, ret = 0; - bool dynstate; - -+ lockdep_assert_cpus_held(); -+ - if (cpuhp_cb_check(state) || !name) - return -EINVAL; - -- cpus_read_lock(); - mutex_lock(&cpuhp_state_mutex); - - ret = cpuhp_store_callbacks(state, name, startup, teardown, -@@ -1521,7 +1523,6 @@ int __cpuhp_setup_state(enum cpuhp_state - } - out: - mutex_unlock(&cpuhp_state_mutex); -- cpus_read_unlock(); - /* - * If the requested state is CPUHP_AP_ONLINE_DYN, return the - * dynamically allocated state in case of success. -@@ -1530,6 +1531,22 @@ int __cpuhp_setup_state(enum cpuhp_state - return state; - return ret; - } -+EXPORT_SYMBOL(__cpuhp_setup_state_cpuslocked); -+ -+int __cpuhp_setup_state(enum cpuhp_state state, -+ const char *name, bool invoke, -+ int (*startup)(unsigned int cpu), -+ int (*teardown)(unsigned int cpu), -+ bool multi_instance) -+{ -+ int ret; -+ -+ cpus_read_lock(); -+ ret = __cpuhp_setup_state_cpuslocked(state, name, invoke, startup, -+ teardown, multi_instance); -+ cpus_read_unlock(); -+ return ret; -+} - EXPORT_SYMBOL(__cpuhp_setup_state); - - int __cpuhp_state_remove_instance(enum cpuhp_state state, -@@ -1571,22 +1588,23 @@ int __cpuhp_state_remove_instance(enum c - EXPORT_SYMBOL_GPL(__cpuhp_state_remove_instance); - - /** -- * __cpuhp_remove_state - Remove the callbacks for an hotplug machine state -+ * __cpuhp_remove_state_cpuslocked - Remove the callbacks for an hotplug machine state - * @state: The state to remove - * @invoke: If true, the teardown function is invoked for cpus where - * cpu state >= @state - * -+ * The caller needs to hold cpus read locked while calling this function. - * The teardown callback is currently not allowed to fail. Think - * about module removal! - */ --void __cpuhp_remove_state(enum cpuhp_state state, bool invoke) -+void __cpuhp_remove_state_cpuslocked(enum cpuhp_state state, bool invoke) - { - struct cpuhp_step *sp = cpuhp_get_step(state); - int cpu; - - BUG_ON(cpuhp_cb_check(state)); - -- cpus_read_lock(); -+ lockdep_assert_cpus_held(); - - mutex_lock(&cpuhp_state_mutex); - if (sp->multi_instance) { -@@ -1614,6 +1632,13 @@ void __cpuhp_remove_state(enum cpuhp_sta - remove: - cpuhp_store_callbacks(state, NULL, NULL, NULL, false); - mutex_unlock(&cpuhp_state_mutex); -+} -+EXPORT_SYMBOL(__cpuhp_remove_state_cpuslocked); -+ -+void __cpuhp_remove_state(enum cpuhp_state state, bool invoke) -+{ -+ cpus_read_lock(); -+ __cpuhp_remove_state_cpuslocked(state, invoke); - cpus_read_unlock(); - } - EXPORT_SYMBOL(__cpuhp_remove_state); diff --git a/patches/0003-futex-Clarify-mark_wake_futex-memory-barrier-usage.patch b/patches/0003-futex-Clarify-mark_wake_futex-memory-barrier-usage.patch deleted file mode 100644 index 397a43b09a53..000000000000 --- a/patches/0003-futex-Clarify-mark_wake_futex-memory-barrier-usage.patch +++ /dev/null @@ -1,35 +0,0 @@ -From: "Darren Hart (VMware)" <dvhart@infradead.org> -Date: Fri, 14 Apr 2017 15:31:38 -0700 -Subject: [PATCH 3/4] futex: Clarify mark_wake_futex memory barrier usage - -Clarify the scenario described in mark_wake_futex requiring the -smp_store_release(). Update the comment to explicitly refer to the -plist_del now under __unqueue_futex() (previously plist_del was in the -same function as the comment). - -Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Link: http://lkml.kernel.org/r/20170414223138.GA4222@fury -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - kernel/futex.c | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - ---- a/kernel/futex.c -+++ b/kernel/futex.c -@@ -1380,10 +1380,11 @@ static void mark_wake_futex(struct wake_ - wake_q_add(wake_q, p); - __unqueue_futex(q); - /* -- * The waiting task can free the futex_q as soon as -- * q->lock_ptr = NULL is written, without taking any locks. A -- * memory barrier is required here to prevent the following -- * store to lock_ptr from getting ahead of the plist_del. -+ * The waiting task can free the futex_q as soon as q->lock_ptr = NULL -+ * is written, without taking any locks. This is possible in the event -+ * of a spurious wakeup, for example. A memory barrier is required here -+ * to prevent the following store to lock_ptr from getting ahead of the -+ * plist_del in __unqueue_futex(). - */ - smp_store_release(&q->lock_ptr, NULL); - } diff --git a/patches/0003-futex-Remove-rt_mutex_deadlock_account_.patch b/patches/0003-futex-Remove-rt_mutex_deadlock_account_.patch deleted file mode 100644 index 41e427d6ac53..000000000000 --- a/patches/0003-futex-Remove-rt_mutex_deadlock_account_.patch +++ /dev/null @@ -1,184 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Wed, 22 Mar 2017 11:35:50 +0100 -Subject: [PATCH] futex: Remove rt_mutex_deadlock_account_*() - -Upstream commit fffa954fb528963c2fb7b0c0084eb77e2be7ab52 - -These are unused and clutter up the code. - -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: juri.lelli@arm.com -Cc: bigeasy@linutronix.de -Cc: xlpang@redhat.com -Cc: rostedt@goodmis.org -Cc: mathieu.desnoyers@efficios.com -Cc: jdesfossez@efficios.com -Cc: dvhart@infradead.org -Cc: bristot@redhat.com -Link: http://lkml.kernel.org/r/20170322104151.652692478@infradead.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/locking/rtmutex-debug.c | 9 ------- - kernel/locking/rtmutex-debug.h | 3 -- - kernel/locking/rtmutex.c | 47 +++++++++++++++-------------------------- - kernel/locking/rtmutex.h | 2 - - 4 files changed, 18 insertions(+), 43 deletions(-) - ---- a/kernel/locking/rtmutex-debug.c -+++ b/kernel/locking/rtmutex-debug.c -@@ -174,12 +174,3 @@ void debug_rt_mutex_init(struct rt_mutex - lock->name = name; - } - --void --rt_mutex_deadlock_account_lock(struct rt_mutex *lock, struct task_struct *task) --{ --} -- --void rt_mutex_deadlock_account_unlock(struct task_struct *task) --{ --} -- ---- a/kernel/locking/rtmutex-debug.h -+++ b/kernel/locking/rtmutex-debug.h -@@ -9,9 +9,6 @@ - * This file contains macros used solely by rtmutex.c. Debug version. - */ - --extern void --rt_mutex_deadlock_account_lock(struct rt_mutex *lock, struct task_struct *task); --extern void rt_mutex_deadlock_account_unlock(struct task_struct *task); - extern void debug_rt_mutex_init_waiter(struct rt_mutex_waiter *waiter); - extern void debug_rt_mutex_free_waiter(struct rt_mutex_waiter *waiter); - extern void debug_rt_mutex_init(struct rt_mutex *lock, const char *name); ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -938,8 +938,6 @@ static int try_to_take_rt_mutex(struct r - */ - rt_mutex_set_owner(lock, task); - -- rt_mutex_deadlock_account_lock(lock, task); -- - return 1; - } - -@@ -1342,8 +1340,6 @@ static bool __sched rt_mutex_slowunlock( - - debug_rt_mutex_unlock(lock); - -- rt_mutex_deadlock_account_unlock(current); -- - /* - * We must be careful here if the fast path is enabled. If we - * have no waiters queued we cannot set owner to NULL here -@@ -1409,11 +1405,10 @@ rt_mutex_fastlock(struct rt_mutex *lock, - struct hrtimer_sleeper *timeout, - enum rtmutex_chainwalk chwalk)) - { -- if (likely(rt_mutex_cmpxchg_acquire(lock, NULL, current))) { -- rt_mutex_deadlock_account_lock(lock, current); -+ if (likely(rt_mutex_cmpxchg_acquire(lock, NULL, current))) - return 0; -- } else -- return slowfn(lock, state, NULL, RT_MUTEX_MIN_CHAINWALK); -+ -+ return slowfn(lock, state, NULL, RT_MUTEX_MIN_CHAINWALK); - } - - static inline int -@@ -1425,21 +1420,19 @@ rt_mutex_timed_fastlock(struct rt_mutex - enum rtmutex_chainwalk chwalk)) - { - if (chwalk == RT_MUTEX_MIN_CHAINWALK && -- likely(rt_mutex_cmpxchg_acquire(lock, NULL, current))) { -- rt_mutex_deadlock_account_lock(lock, current); -+ likely(rt_mutex_cmpxchg_acquire(lock, NULL, current))) - return 0; -- } else -- return slowfn(lock, state, timeout, chwalk); -+ -+ return slowfn(lock, state, timeout, chwalk); - } - - static inline int - rt_mutex_fasttrylock(struct rt_mutex *lock, - int (*slowfn)(struct rt_mutex *lock)) - { -- if (likely(rt_mutex_cmpxchg_acquire(lock, NULL, current))) { -- rt_mutex_deadlock_account_lock(lock, current); -+ if (likely(rt_mutex_cmpxchg_acquire(lock, NULL, current))) - return 1; -- } -+ - return slowfn(lock); - } - -@@ -1449,19 +1442,18 @@ rt_mutex_fastunlock(struct rt_mutex *loc - struct wake_q_head *wqh)) - { - DEFINE_WAKE_Q(wake_q); -+ bool deboost; - -- if (likely(rt_mutex_cmpxchg_release(lock, current, NULL))) { -- rt_mutex_deadlock_account_unlock(current); -+ if (likely(rt_mutex_cmpxchg_release(lock, current, NULL))) -+ return; - -- } else { -- bool deboost = slowfn(lock, &wake_q); -+ deboost = slowfn(lock, &wake_q); - -- wake_up_q(&wake_q); -+ wake_up_q(&wake_q); - -- /* Undo pi boosting if necessary: */ -- if (deboost) -- rt_mutex_adjust_prio(current); -- } -+ /* Undo pi boosting if necessary: */ -+ if (deboost) -+ rt_mutex_adjust_prio(current); - } - - /** -@@ -1572,10 +1564,9 @@ EXPORT_SYMBOL_GPL(rt_mutex_unlock); - bool __sched rt_mutex_futex_unlock(struct rt_mutex *lock, - struct wake_q_head *wqh) - { -- if (likely(rt_mutex_cmpxchg_release(lock, current, NULL))) { -- rt_mutex_deadlock_account_unlock(current); -+ if (likely(rt_mutex_cmpxchg_release(lock, current, NULL))) - return false; -- } -+ - return rt_mutex_slowunlock(lock, wqh); - } - -@@ -1637,7 +1628,6 @@ void rt_mutex_init_proxy_locked(struct r - __rt_mutex_init(lock, NULL); - debug_rt_mutex_proxy_lock(lock, proxy_owner); - rt_mutex_set_owner(lock, proxy_owner); -- rt_mutex_deadlock_account_lock(lock, proxy_owner); - } - - /** -@@ -1657,7 +1647,6 @@ void rt_mutex_proxy_unlock(struct rt_mut - { - debug_rt_mutex_proxy_unlock(lock); - rt_mutex_set_owner(lock, NULL); -- rt_mutex_deadlock_account_unlock(proxy_owner); - } - - /** ---- a/kernel/locking/rtmutex.h -+++ b/kernel/locking/rtmutex.h -@@ -11,8 +11,6 @@ - */ - - #define rt_mutex_deadlock_check(l) (0) --#define rt_mutex_deadlock_account_lock(m, t) do { } while (0) --#define rt_mutex_deadlock_account_unlock(l) do { } while (0) - #define debug_rt_mutex_init_waiter(w) do { } while (0) - #define debug_rt_mutex_free_waiter(w) do { } while (0) - #define debug_rt_mutex_lock(l) do { } while (0) diff --git a/patches/0003-ia64-salinfo-Replace-racy-task-affinity-logic.patch b/patches/0003-ia64-salinfo-Replace-racy-task-affinity-logic.patch deleted file mode 100644 index 0af2d70b7fd6..000000000000 --- a/patches/0003-ia64-salinfo-Replace-racy-task-affinity-logic.patch +++ /dev/null @@ -1,128 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 12 Apr 2017 22:07:29 +0200 -Subject: [PATCH 03/13] ia64/salinfo: Replace racy task affinity logic - -Some of the file operations in /proc/sal require to run code on the -requested cpu. This is achieved by temporarily setting the affinity of the -calling user space thread to the requested CPU and reset it to the original -affinity afterwards. - -That's racy vs. CPU hotplug and concurrent affinity settings for that -thread resulting in code executing on the wrong CPU and overwriting the -new affinity setting. - -Replace it by using work_on_cpu_safe() which guarantees to run the code on -the requested CPU or to fail in case the CPU is offline. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Cc: Fenghua Yu <fenghua.yu@intel.com> -Cc: Tony Luck <tony.luck@intel.com> -Cc: linux-ia64@vger.kernel.org -Cc: Herbert Xu <herbert@gondor.apana.org.au> -Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Lai Jiangshan <jiangshanlai@gmail.com> -Cc: Viresh Kumar <viresh.kumar@linaro.org> -Cc: Michael Ellerman <mpe@ellerman.id.au> -Cc: Tejun Heo <tj@kernel.org> -Cc: "David S. Miller" <davem@davemloft.net> -Cc: Len Brown <lenb@kernel.org> -Link: http://lkml.kernel.org/r/20170412201042.341863457@linutronix.de -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - arch/ia64/kernel/salinfo.c | 31 ++++++++++++------------------- - 1 file changed, 12 insertions(+), 19 deletions(-) - ---- a/arch/ia64/kernel/salinfo.c -+++ b/arch/ia64/kernel/salinfo.c -@@ -179,14 +179,14 @@ struct salinfo_platform_oemdata_parms { - const u8 *efi_guid; - u8 **oemdata; - u64 *oemdata_size; -- int ret; - }; - --static void -+static long - salinfo_platform_oemdata_cpu(void *context) - { - struct salinfo_platform_oemdata_parms *parms = context; -- parms->ret = salinfo_platform_oemdata(parms->efi_guid, parms->oemdata, parms->oemdata_size); -+ -+ return salinfo_platform_oemdata(parms->efi_guid, parms->oemdata, parms->oemdata_size); - } - - static void -@@ -380,16 +380,7 @@ salinfo_log_release(struct inode *inode, - return 0; - } - --static void --call_on_cpu(int cpu, void (*fn)(void *), void *arg) --{ -- cpumask_t save_cpus_allowed = current->cpus_allowed; -- set_cpus_allowed_ptr(current, cpumask_of(cpu)); -- (*fn)(arg); -- set_cpus_allowed_ptr(current, &save_cpus_allowed); --} -- --static void -+static long - salinfo_log_read_cpu(void *context) - { - struct salinfo_data *data = context; -@@ -399,6 +390,7 @@ salinfo_log_read_cpu(void *context) - /* Clear corrected errors as they are read from SAL */ - if (rh->severity == sal_log_severity_corrected) - ia64_sal_clear_state_info(data->type); -+ return 0; - } - - static void -@@ -430,7 +422,7 @@ salinfo_log_new_read(int cpu, struct sal - spin_unlock_irqrestore(&data_saved_lock, flags); - - if (!data->saved_num) -- call_on_cpu(cpu, salinfo_log_read_cpu, data); -+ work_on_cpu_safe(cpu, salinfo_log_read_cpu, data); - if (!data->log_size) { - data->state = STATE_NO_DATA; - cpumask_clear_cpu(cpu, &data->cpu_event); -@@ -459,11 +451,13 @@ salinfo_log_read(struct file *file, char - return simple_read_from_buffer(buffer, count, ppos, buf, bufsize); - } - --static void -+static long - salinfo_log_clear_cpu(void *context) - { - struct salinfo_data *data = context; -+ - ia64_sal_clear_state_info(data->type); -+ return 0; - } - - static int -@@ -486,7 +480,7 @@ salinfo_log_clear(struct salinfo_data *d - rh = (sal_log_record_header_t *)(data->log_buffer); - /* Corrected errors have already been cleared from SAL */ - if (rh->severity != sal_log_severity_corrected) -- call_on_cpu(cpu, salinfo_log_clear_cpu, data); -+ work_on_cpu_safe(cpu, salinfo_log_clear_cpu, data); - /* clearing a record may make a new record visible */ - salinfo_log_new_read(cpu, data); - if (data->state == STATE_LOG_RECORD) { -@@ -531,9 +525,8 @@ salinfo_log_write(struct file *file, con - .oemdata = &data->oemdata, - .oemdata_size = &data->oemdata_size - }; -- call_on_cpu(cpu, salinfo_platform_oemdata_cpu, &parms); -- if (parms.ret) -- count = parms.ret; -+ count = work_on_cpu_safe(cpu, salinfo_platform_oemdata_cpu, -+ &parms); - } else - data->oemdata_size = 0; - } else diff --git a/patches/0003-sched-deadline-rtmutex-Dont-miss-the-dl_runtime-dl_p.patch b/patches/0003-sched-deadline-rtmutex-Dont-miss-the-dl_runtime-dl_p.patch deleted file mode 100644 index 2e395cdb66f0..000000000000 --- a/patches/0003-sched-deadline-rtmutex-Dont-miss-the-dl_runtime-dl_p.patch +++ /dev/null @@ -1,51 +0,0 @@ -From: Xunlei Pang <xlpang@redhat.com> -Date: Thu, 23 Mar 2017 15:56:09 +0100 -Subject: [PATCH 3/9] sched/deadline/rtmutex: Dont miss the - dl_runtime/dl_period update - -Currently dl tasks will actually return at the very beginning -of rt_mutex_adjust_prio_chain() in !detect_deadlock cases: - - if (waiter->prio == task->prio) { - if (!detect_deadlock) - goto out_unlock_pi; // out here - else - requeue = false; - } - -As the deadline value of blocked deadline tasks(waiters) without -changing their sched_class(thus prio doesn't change) never changes, -this seems reasonable, but it actually misses the chance of updating -rt_mutex_waiter's "dl_runtime(period)_copy" if a waiter updates its -deadline parameters(dl_runtime, dl_period) or boosted waiter changes -to !deadline class. - -Thus, force deadline task not out by adding the !dl_prio() condition. - -Signed-off-by: Xunlei Pang <xlpang@redhat.com> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Acked-by: Steven Rostedt <rostedt@goodmis.org> -Reviewed-by: Thomas Gleixner <tglx@linutronix.de> -Cc: juri.lelli@arm.com -Cc: bigeasy@linutronix.de -Cc: mathieu.desnoyers@efficios.com -Cc: jdesfossez@efficios.com -Cc: bristot@redhat.com -Link: http://lkml.kernel.org/r/1460633827-345-7-git-send-email-xlpang@redhat.com -Link: http://lkml.kernel.org/r/20170323150216.206577901@infradead.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - kernel/locking/rtmutex.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -605,7 +605,7 @@ static int rt_mutex_adjust_prio_chain(st - * enabled we continue, but stop the requeueing in the chain - * walk. - */ -- if (waiter->prio == task->prio) { -+ if (waiter->prio == task->prio && !dl_task(task)) { - if (!detect_deadlock) - goto out_unlock_pi; - else diff --git a/patches/0003-tracing-Remove-code-which-merges-duplicates.patch b/patches/0003-tracing-Remove-code-which-merges-duplicates.patch index 9c0b254ac837..89a3a78188e9 100644 --- a/patches/0003-tracing-Remove-code-which-merges-duplicates.patch +++ b/patches/0003-tracing-Remove-code-which-merges-duplicates.patch @@ -46,7 +46,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> }; --- a/kernel/trace/tracing_map.c +++ b/kernel/trace/tracing_map.c -@@ -841,67 +841,15 @@ create_sort_entry(void *key, struct trac +@@ -844,67 +844,15 @@ create_sort_entry(void *key, struct trac return sort_entry; } @@ -117,7 +117,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> sort(sort_entries, n_entries, sizeof(struct tracing_map_sort_entry *), (int (*)(const void *, const void *))cmp_entries_dup, NULL); -@@ -910,30 +858,14 @@ static int merge_dups(struct tracing_map +@@ -913,30 +861,14 @@ static int merge_dups(struct tracing_map for (i = 1; i < n_entries; i++) { if (!memcmp(sort_entries[i]->key, key, key_size)) { dups++; total_dups++; @@ -150,7 +150,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } static bool is_key(struct tracing_map *map, unsigned int field_idx) -@@ -1059,10 +991,7 @@ int tracing_map_sort_entries(struct trac +@@ -1062,10 +994,7 @@ int tracing_map_sort_entries(struct trac return 1; } diff --git a/patches/0004-MAINTAINERS-Add-FUTEX-SUBSYSTEM.patch b/patches/0004-MAINTAINERS-Add-FUTEX-SUBSYSTEM.patch deleted file mode 100644 index 2606f7f54f30..000000000000 --- a/patches/0004-MAINTAINERS-Add-FUTEX-SUBSYSTEM.patch +++ /dev/null @@ -1,47 +0,0 @@ -From: "Darren Hart (VMware)" <dvhart@infradead.org> -Date: Fri, 14 Apr 2017 15:46:08 -0700 -Subject: [PATCH 4/4] MAINTAINERS: Add FUTEX SUBSYSTEM - -Add a MAINTAINERS block for the FUTEX SUBSYSTEM which includes the core -kernel code, include headers, testing code, and Documentation. Excludes -arch files, and higher level test code. - -I added tglx and mingo as M as they have made the tip commits and peterz -and myself as R. - -Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Shuah Khan <shuah@kernel.org> -Cc: Arnaldo Carvalho de Melo <acme@kernel.org> -Link: http://lkml.kernel.org/r/20170414224608.GA5180@fury -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - MAINTAINERS | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -5420,6 +5420,23 @@ F: fs/fuse/ - F: include/uapi/linux/fuse.h - F: Documentation/filesystems/fuse.txt - -+FUTEX SUBSYSTEM -+M: Thomas Gleixner <tglx@linutronix.de> -+M: Ingo Molnar <mingo@redhat.com> -+R: Peter Zijlstra <peterz@infradead.org> -+R: Darren Hart <dvhart@infradead.org> -+L: linux-kernel@vger.kernel.org -+T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git locking/core -+S: Maintained -+F: kernel/futex.c -+F: kernel/futex_compat.c -+F: include/asm-generic/futex.h -+F: include/linux/futex.h -+F: include/uapi/linux/futex.h -+F: tools/testing/selftests/futex/ -+F: tools/perf/bench/futex* -+F: Documentation/*futex* -+ - FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit) - M: Rik Faith <faith@cs.unc.edu> - L: linux-scsi@vger.kernel.org diff --git a/patches/0004-cpu-hotplug-Add-__cpuhp_state_add_instance_cpuslocke.patch b/patches/0004-cpu-hotplug-Add-__cpuhp_state_add_instance_cpuslocke.patch deleted file mode 100644 index a18f9a9ece4b..000000000000 --- a/patches/0004-cpu-hotplug-Add-__cpuhp_state_add_instance_cpuslocke.patch +++ /dev/null @@ -1,88 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 24 May 2017 10:15:15 +0200 -Subject: [PATCH 04/32] cpu/hotplug: Add - __cpuhp_state_add_instance_cpuslocked() - -Add cpuslocked() variants for the multi instance registration so this can -be called from a cpus_read_lock() protected region. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Tested-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Acked-by: Ingo Molnar <mingo@kernel.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Steven Rostedt <rostedt@goodmis.org> -Link: http://lkml.kernel.org/r/20170524081547.321782217@linutronix.de ---- - include/linux/cpuhotplug.h | 9 +++++++++ - kernel/cpu.c | 18 +++++++++++++++--- - 2 files changed, 24 insertions(+), 3 deletions(-) - ---- a/include/linux/cpuhotplug.h -+++ b/include/linux/cpuhotplug.h -@@ -238,6 +238,8 @@ static inline int cpuhp_setup_state_mult - - int __cpuhp_state_add_instance(enum cpuhp_state state, struct hlist_node *node, - bool invoke); -+int __cpuhp_state_add_instance_cpuslocked(enum cpuhp_state state, -+ struct hlist_node *node, bool invoke); - - /** - * cpuhp_state_add_instance - Add an instance for a state and invoke startup -@@ -270,6 +272,13 @@ static inline int cpuhp_state_add_instan - return __cpuhp_state_add_instance(state, node, false); - } - -+static inline int -+cpuhp_state_add_instance_nocalls_cpuslocked(enum cpuhp_state state, -+ struct hlist_node *node) -+{ -+ return __cpuhp_state_add_instance_cpuslocked(state, node, false); -+} -+ - void __cpuhp_remove_state(enum cpuhp_state state, bool invoke); - void __cpuhp_remove_state_cpuslocked(enum cpuhp_state state, bool invoke); - ---- a/kernel/cpu.c -+++ b/kernel/cpu.c -@@ -1412,18 +1412,20 @@ static void cpuhp_rollback_install(int f - } - } - --int __cpuhp_state_add_instance(enum cpuhp_state state, struct hlist_node *node, -- bool invoke) -+int __cpuhp_state_add_instance_cpuslocked(enum cpuhp_state state, -+ struct hlist_node *node, -+ bool invoke) - { - struct cpuhp_step *sp; - int cpu; - int ret; - -+ lockdep_assert_cpus_held(); -+ - sp = cpuhp_get_step(state); - if (sp->multi_instance == false) - return -EINVAL; - -- cpus_read_lock(); - mutex_lock(&cpuhp_state_mutex); - - if (!invoke || !sp->startup.multi) -@@ -1452,6 +1454,16 @@ int __cpuhp_state_add_instance(enum cpuh - hlist_add_head(node, &sp->list); - unlock: - mutex_unlock(&cpuhp_state_mutex); -+ return ret; -+} -+ -+int __cpuhp_state_add_instance(enum cpuhp_state state, struct hlist_node *node, -+ bool invoke) -+{ -+ int ret; -+ -+ cpus_read_lock(); -+ ret = __cpuhp_state_add_instance_cpuslocked(state, node, invoke); - cpus_read_unlock(); - return ret; - } diff --git a/patches/0004-futex-rt_mutex-Provide-futex-specific-rt_mutex-API.patch b/patches/0004-futex-rt_mutex-Provide-futex-specific-rt_mutex-API.patch deleted file mode 100644 index 66306249c23b..000000000000 --- a/patches/0004-futex-rt_mutex-Provide-futex-specific-rt_mutex-API.patch +++ /dev/null @@ -1,220 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Wed, 22 Mar 2017 11:35:51 +0100 -Subject: [PATCH] futex,rt_mutex: Provide futex specific rt_mutex API - -Upstream commit 5293c2efda37775346885c7e924d4ef7018ea60b - -Part of what makes futex_unlock_pi() intricate is that -rt_mutex_futex_unlock() -> rt_mutex_slowunlock() can drop -rt_mutex::wait_lock. - -This means it cannot rely on the atomicy of wait_lock, which would be -preferred in order to not rely on hb->lock so much. - -The reason rt_mutex_slowunlock() needs to drop wait_lock is because it can -race with the rt_mutex fastpath, however futexes have their own fast path. - -Since futexes already have a bunch of separate rt_mutex accessors, complete -that set and implement a rt_mutex variant without fastpath for them. - -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: juri.lelli@arm.com -Cc: bigeasy@linutronix.de -Cc: xlpang@redhat.com -Cc: rostedt@goodmis.org -Cc: mathieu.desnoyers@efficios.com -Cc: jdesfossez@efficios.com -Cc: dvhart@infradead.org -Cc: bristot@redhat.com -Link: http://lkml.kernel.org/r/20170322104151.702962446@infradead.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/futex.c | 30 ++++++++++----------- - kernel/locking/rtmutex.c | 55 +++++++++++++++++++++++++++++----------- - kernel/locking/rtmutex_common.h | 9 +++++- - 3 files changed, 62 insertions(+), 32 deletions(-) - ---- a/kernel/futex.c -+++ b/kernel/futex.c -@@ -916,7 +916,7 @@ void exit_pi_state_list(struct task_stru - pi_state->owner = NULL; - raw_spin_unlock_irq(&curr->pi_lock); - -- rt_mutex_unlock(&pi_state->pi_mutex); -+ rt_mutex_futex_unlock(&pi_state->pi_mutex); - - spin_unlock(&hb->lock); - -@@ -1364,20 +1364,18 @@ static int wake_futex_pi(u32 __user *uad - pi_state->owner = new_owner; - raw_spin_unlock(&new_owner->pi_lock); - -- raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); -- -- deboost = rt_mutex_futex_unlock(&pi_state->pi_mutex, &wake_q); -- - /* -- * First unlock HB so the waiter does not spin on it once he got woken -- * up. Second wake up the waiter before the priority is adjusted. If we -- * deboost first (and lose our higher priority), then the task might get -- * scheduled away before the wake up can take place. -+ * We've updated the uservalue, this unlock cannot fail. - */ -+ deboost = __rt_mutex_futex_unlock(&pi_state->pi_mutex, &wake_q); -+ -+ raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); - spin_unlock(&hb->lock); -- wake_up_q(&wake_q); -- if (deboost) -+ -+ if (deboost) { -+ wake_up_q(&wake_q); - rt_mutex_adjust_prio(current); -+ } - - return 0; - } -@@ -2253,7 +2251,7 @@ static int fixup_owner(u32 __user *uaddr - * task acquired the rt_mutex after we removed ourself from the - * rt_mutex waiters list. - */ -- if (rt_mutex_trylock(&q->pi_state->pi_mutex)) { -+ if (rt_mutex_futex_trylock(&q->pi_state->pi_mutex)) { - locked = 1; - goto out; - } -@@ -2568,7 +2566,7 @@ static int futex_lock_pi(u32 __user *uad - if (!trylock) { - ret = rt_mutex_timed_futex_lock(&q.pi_state->pi_mutex, to); - } else { -- ret = rt_mutex_trylock(&q.pi_state->pi_mutex); -+ ret = rt_mutex_futex_trylock(&q.pi_state->pi_mutex); - /* Fixup the trylock return value: */ - ret = ret ? 0 : -EWOULDBLOCK; - } -@@ -2591,7 +2589,7 @@ static int futex_lock_pi(u32 __user *uad - * it and return the fault to userspace. - */ - if (ret && (rt_mutex_owner(&q.pi_state->pi_mutex) == current)) -- rt_mutex_unlock(&q.pi_state->pi_mutex); -+ rt_mutex_futex_unlock(&q.pi_state->pi_mutex); - - /* Unqueue and drop the lock */ - unqueue_me_pi(&q); -@@ -2898,7 +2896,7 @@ static int futex_wait_requeue_pi(u32 __u - spin_lock(q.lock_ptr); - ret = fixup_pi_state_owner(uaddr2, &q, current); - if (ret && rt_mutex_owner(&q.pi_state->pi_mutex) == current) -- rt_mutex_unlock(&q.pi_state->pi_mutex); -+ rt_mutex_futex_unlock(&q.pi_state->pi_mutex); - /* - * Drop the reference to the pi state which - * the requeue_pi() code acquired for us. -@@ -2938,7 +2936,7 @@ static int futex_wait_requeue_pi(u32 __u - * userspace. - */ - if (ret && rt_mutex_owner(pi_mutex) == current) -- rt_mutex_unlock(pi_mutex); -+ rt_mutex_futex_unlock(pi_mutex); - - /* Unqueue and drop the lock. */ - unqueue_me_pi(&q); ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -1488,15 +1488,23 @@ EXPORT_SYMBOL_GPL(rt_mutex_lock_interrup - - /* - * Futex variant with full deadlock detection. -+ * Futex variants must not use the fast-path, see __rt_mutex_futex_unlock(). - */ --int rt_mutex_timed_futex_lock(struct rt_mutex *lock, -+int __sched rt_mutex_timed_futex_lock(struct rt_mutex *lock, - struct hrtimer_sleeper *timeout) - { - might_sleep(); - -- return rt_mutex_timed_fastlock(lock, TASK_INTERRUPTIBLE, timeout, -- RT_MUTEX_FULL_CHAINWALK, -- rt_mutex_slowlock); -+ return rt_mutex_slowlock(lock, TASK_INTERRUPTIBLE, -+ timeout, RT_MUTEX_FULL_CHAINWALK); -+} -+ -+/* -+ * Futex variant, must not use fastpath. -+ */ -+int __sched rt_mutex_futex_trylock(struct rt_mutex *lock) -+{ -+ return rt_mutex_slowtrylock(lock); - } - - /** -@@ -1555,19 +1563,38 @@ void __sched rt_mutex_unlock(struct rt_m - EXPORT_SYMBOL_GPL(rt_mutex_unlock); - - /** -- * rt_mutex_futex_unlock - Futex variant of rt_mutex_unlock -- * @lock: the rt_mutex to be unlocked -- * -- * Returns: true/false indicating whether priority adjustment is -- * required or not. -+ * Futex variant, that since futex variants do not use the fast-path, can be -+ * simple and will not need to retry. - */ --bool __sched rt_mutex_futex_unlock(struct rt_mutex *lock, -- struct wake_q_head *wqh) -+bool __sched __rt_mutex_futex_unlock(struct rt_mutex *lock, -+ struct wake_q_head *wake_q) -+{ -+ lockdep_assert_held(&lock->wait_lock); -+ -+ debug_rt_mutex_unlock(lock); -+ -+ if (!rt_mutex_has_waiters(lock)) { -+ lock->owner = NULL; -+ return false; /* done */ -+ } -+ -+ mark_wakeup_next_waiter(wake_q, lock); -+ return true; /* deboost and wakeups */ -+} -+ -+void __sched rt_mutex_futex_unlock(struct rt_mutex *lock) - { -- if (likely(rt_mutex_cmpxchg_release(lock, current, NULL))) -- return false; -+ DEFINE_WAKE_Q(wake_q); -+ bool deboost; - -- return rt_mutex_slowunlock(lock, wqh); -+ raw_spin_lock_irq(&lock->wait_lock); -+ deboost = __rt_mutex_futex_unlock(lock, &wake_q); -+ raw_spin_unlock_irq(&lock->wait_lock); -+ -+ if (deboost) { -+ wake_up_q(&wake_q); -+ rt_mutex_adjust_prio(current); -+ } - } - - /** ---- a/kernel/locking/rtmutex_common.h -+++ b/kernel/locking/rtmutex_common.h -@@ -109,9 +109,14 @@ extern int rt_mutex_start_proxy_lock(str - extern int rt_mutex_finish_proxy_lock(struct rt_mutex *lock, - struct hrtimer_sleeper *to, - struct rt_mutex_waiter *waiter); -+ - extern int rt_mutex_timed_futex_lock(struct rt_mutex *l, struct hrtimer_sleeper *to); --extern bool rt_mutex_futex_unlock(struct rt_mutex *lock, -- struct wake_q_head *wqh); -+extern int rt_mutex_futex_trylock(struct rt_mutex *l); -+ -+extern void rt_mutex_futex_unlock(struct rt_mutex *lock); -+extern bool __rt_mutex_futex_unlock(struct rt_mutex *lock, -+ struct wake_q_head *wqh); -+ - extern void rt_mutex_adjust_prio(struct task_struct *task); - - #ifdef CONFIG_DEBUG_RT_MUTEXES diff --git a/patches/0004-hrtimer-Cleanup-clock-argument-in-schedule_hrtimeout.patch b/patches/0004-hrtimer-Cleanup-clock-argument-in-schedule_hrtimeout.patch index 4fa116ab52f4..8cdaaaa06064 100644 --- a/patches/0004-hrtimer-Cleanup-clock-argument-in-schedule_hrtimeout.patch +++ b/patches/0004-hrtimer-Cleanup-clock-argument-in-schedule_hrtimeout.patch @@ -23,7 +23,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h -@@ -470,7 +470,7 @@ extern int schedule_hrtimeout_range(ktim +@@ -466,7 +466,7 @@ extern int schedule_hrtimeout_range(ktim extern int schedule_hrtimeout_range_clock(ktime_t *expires, u64 delta, const enum hrtimer_mode mode, @@ -34,7 +34,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* Soft interrupt function to run the hrtimer queues: */ --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -1654,12 +1654,12 @@ void __init hrtimers_init(void) +@@ -1671,12 +1671,12 @@ void __init hrtimers_init(void) * schedule_hrtimeout_range_clock - sleep until timeout * @expires: timeout value (ktime_t) * @delta: slack in expires timeout (ktime_t) @@ -50,7 +50,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> { struct hrtimer_sleeper t; -@@ -1680,7 +1680,7 @@ schedule_hrtimeout_range_clock(ktime_t * +@@ -1697,7 +1697,7 @@ schedule_hrtimeout_range_clock(ktime_t * return -EINTR; } diff --git a/patches/0004-ia64-sn-hwperf-Replace-racy-task-affinity-logic.patch b/patches/0004-ia64-sn-hwperf-Replace-racy-task-affinity-logic.patch deleted file mode 100644 index 040d433e5b10..000000000000 --- a/patches/0004-ia64-sn-hwperf-Replace-racy-task-affinity-logic.patch +++ /dev/null @@ -1,75 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Thu, 6 Apr 2017 14:56:18 +0200 -Subject: [PATCH 04/13] ia64/sn/hwperf: Replace racy task affinity logic - -sn_hwperf_op_cpu() which is invoked from an ioctl requires to run code on -the requested cpu. This is achieved by temporarily setting the affinity of -the calling user space thread to the requested CPU and reset it to the -original affinity afterwards. - -That's racy vs. CPU hotplug and concurrent affinity settings for that -thread resulting in code executing on the wrong CPU and overwriting the -new affinity setting. - -Replace it by using work_on_cpu_safe() which guarantees to run the code on -the requested CPU or to fail in case the CPU is offline. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Cc: Fenghua Yu <fenghua.yu@intel.com> -Cc: Tony Luck <tony.luck@intel.com> -Cc: linux-ia64@vger.kernel.org -Cc: Herbert Xu <herbert@gondor.apana.org.au> -Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Lai Jiangshan <jiangshanlai@gmail.com> -Cc: Viresh Kumar <viresh.kumar@linaro.org> -Cc: Michael Ellerman <mpe@ellerman.id.au> -Cc: Tejun Heo <tj@kernel.org> -Cc: "David S. Miller" <davem@davemloft.net> -Cc: Len Brown <lenb@kernel.org> -Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1704122251450.2548@nanos -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - arch/ia64/sn/kernel/sn2/sn_hwperf.c | 17 +++++++++-------- - 1 file changed, 9 insertions(+), 8 deletions(-) - ---- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c -+++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c -@@ -598,12 +598,17 @@ static void sn_hwperf_call_sal(void *inf - op_info->ret = r; - } - -+static long sn_hwperf_call_sal_work(void *info) -+{ -+ sn_hwperf_call_sal(info); -+ return 0; -+} -+ - static int sn_hwperf_op_cpu(struct sn_hwperf_op_info *op_info) - { - u32 cpu; - u32 use_ipi; - int r = 0; -- cpumask_t save_allowed; - - cpu = (op_info->a->arg & SN_HWPERF_ARG_CPU_MASK) >> 32; - use_ipi = op_info->a->arg & SN_HWPERF_ARG_USE_IPI_MASK; -@@ -629,13 +634,9 @@ static int sn_hwperf_op_cpu(struct sn_hw - /* use an interprocessor interrupt to call SAL */ - smp_call_function_single(cpu, sn_hwperf_call_sal, - op_info, 1); -- } -- else { -- /* migrate the task before calling SAL */ -- save_allowed = current->cpus_allowed; -- set_cpus_allowed_ptr(current, cpumask_of(cpu)); -- sn_hwperf_call_sal(op_info); -- set_cpus_allowed_ptr(current, &save_allowed); -+ } else { -+ /* Call on the target CPU */ -+ work_on_cpu_safe(cpu, sn_hwperf_call_sal_work, op_info); - } - } - r = op_info->ret; diff --git a/patches/0004-rtmutex-Clean-up.patch b/patches/0004-rtmutex-Clean-up.patch deleted file mode 100644 index 7140b519190e..000000000000 --- a/patches/0004-rtmutex-Clean-up.patch +++ /dev/null @@ -1,144 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Thu, 23 Mar 2017 15:56:10 +0100 -Subject: [PATCH 4/9] rtmutex: Clean up - -Previous patches changed the meaning of the return value of -rt_mutex_slowunlock(); update comments and code to reflect this. - -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: juri.lelli@arm.com -Cc: bigeasy@linutronix.de -Cc: xlpang@redhat.com -Cc: rostedt@goodmis.org -Cc: mathieu.desnoyers@efficios.com -Cc: jdesfossez@efficios.com -Cc: bristot@redhat.com -Link: http://lkml.kernel.org/r/20170323150216.255058238@infradead.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - kernel/futex.c | 7 ++++--- - kernel/locking/rtmutex.c | 28 +++++++++++++--------------- - kernel/locking/rtmutex_common.h | 2 +- - 3 files changed, 18 insertions(+), 19 deletions(-) - ---- a/kernel/futex.c -+++ b/kernel/futex.c -@@ -1394,7 +1394,7 @@ static int wake_futex_pi(u32 __user *uad - { - u32 uninitialized_var(curval), newval; - struct task_struct *new_owner; -- bool deboost = false; -+ bool postunlock = false; - DEFINE_WAKE_Q(wake_q); - int ret = 0; - -@@ -1455,12 +1455,13 @@ static int wake_futex_pi(u32 __user *uad - /* - * We've updated the uservalue, this unlock cannot fail. - */ -- deboost = __rt_mutex_futex_unlock(&pi_state->pi_mutex, &wake_q); -+ postunlock = __rt_mutex_futex_unlock(&pi_state->pi_mutex, &wake_q); - - out_unlock: - raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); - -- rt_mutex_postunlock(&wake_q, deboost); -+ if (postunlock) -+ rt_mutex_postunlock(&wake_q); - - return ret; - } ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -1330,7 +1330,8 @@ static inline int rt_mutex_slowtrylock(s - - /* - * Slow path to release a rt-mutex. -- * Return whether the current task needs to undo a potential priority boosting. -+ * -+ * Return whether the current task needs to call rt_mutex_postunlock(). - */ - static bool __sched rt_mutex_slowunlock(struct rt_mutex *lock, - struct wake_q_head *wake_q) -@@ -1401,8 +1402,7 @@ static bool __sched rt_mutex_slowunlock( - - raw_spin_unlock_irqrestore(&lock->wait_lock, flags); - -- /* check PI boosting */ -- return true; -+ return true; /* call rt_mutex_postunlock() */ - } - - /* -@@ -1449,15 +1449,14 @@ rt_mutex_fasttrylock(struct rt_mutex *lo - } - - /* -- * Undo pi boosting (if necessary) and wake top waiter. -+ * Performs the wakeup of the the top-waiter and re-enables preemption. - */ --void rt_mutex_postunlock(struct wake_q_head *wake_q, bool deboost) -+void rt_mutex_postunlock(struct wake_q_head *wake_q) - { - wake_up_q(wake_q); - - /* Pairs with preempt_disable() in rt_mutex_slowunlock() */ -- if (deboost) -- preempt_enable(); -+ preempt_enable(); - } - - static inline void -@@ -1466,14 +1465,12 @@ rt_mutex_fastunlock(struct rt_mutex *loc - struct wake_q_head *wqh)) - { - DEFINE_WAKE_Q(wake_q); -- bool deboost; - - if (likely(rt_mutex_cmpxchg_release(lock, current, NULL))) - return; - -- deboost = slowfn(lock, &wake_q); -- -- rt_mutex_postunlock(&wake_q, deboost); -+ if (slowfn(lock, &wake_q)) -+ rt_mutex_postunlock(&wake_q); - } - - /** -@@ -1593,19 +1590,20 @@ bool __sched __rt_mutex_futex_unlock(str - */ - preempt_disable(); - -- return true; /* deboost and wakeups */ -+ return true; /* call postunlock() */ - } - - void __sched rt_mutex_futex_unlock(struct rt_mutex *lock) - { - DEFINE_WAKE_Q(wake_q); -- bool deboost; -+ bool postunlock; - - raw_spin_lock_irq(&lock->wait_lock); -- deboost = __rt_mutex_futex_unlock(lock, &wake_q); -+ postunlock = __rt_mutex_futex_unlock(lock, &wake_q); - raw_spin_unlock_irq(&lock->wait_lock); - -- rt_mutex_postunlock(&wake_q, deboost); -+ if (postunlock) -+ rt_mutex_postunlock(&wake_q); - } - - /** ---- a/kernel/locking/rtmutex_common.h -+++ b/kernel/locking/rtmutex_common.h -@@ -122,7 +122,7 @@ extern void rt_mutex_futex_unlock(struct - extern bool __rt_mutex_futex_unlock(struct rt_mutex *lock, - struct wake_q_head *wqh); - --extern void rt_mutex_postunlock(struct wake_q_head *wake_q, bool deboost); -+extern void rt_mutex_postunlock(struct wake_q_head *wake_q); - - #ifdef CONFIG_DEBUG_RT_MUTEXES - # include "rtmutex-debug.h" diff --git a/patches/0004-x86-smp-Adjust-system_state-check.patch b/patches/0004-x86-smp-Adjust-system_state-check.patch deleted file mode 100644 index 98ac774fa5b5..000000000000 --- a/patches/0004-x86-smp-Adjust-system_state-check.patch +++ /dev/null @@ -1,33 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Tue, 16 May 2017 20:42:35 +0200 -Subject: [PATCH 04/17] x86/smp: Adjust system_state check - -To enable smp_processor_id() and might_sleep() debug checks earlier, it's -required to add system states between SYSTEM_BOOTING and SYSTEM_RUNNING. - -Adjust the system_state check in announce_cpu() to handle the extra states. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Reviewed-by: Steven Rostedt (VMware) <rostedt@goodmis.org> -Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Cc: Linus Torvalds <torvalds@linux-foundation.org> -Cc: Mark Rutland <mark.rutland@arm.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Link: http://lkml.kernel.org/r/20170516184735.191715856@linutronix.de -Signed-off-by: Ingo Molnar <mingo@kernel.org> ---- - arch/x86/kernel/smpboot.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/x86/kernel/smpboot.c -+++ b/arch/x86/kernel/smpboot.c -@@ -863,7 +863,7 @@ static void announce_cpu(int cpu, int ap - if (cpu == 1) - printk(KERN_INFO "x86: Booting SMP configuration:\n"); - -- if (system_state == SYSTEM_BOOTING) { -+ if (system_state < SYSTEM_RUNNING) { - if (node != current_node) { - if (current_node > (-1)) - pr_cont("\n"); diff --git a/patches/0005-futex-Change-locking-rules.patch b/patches/0005-futex-Change-locking-rules.patch deleted file mode 100644 index 2c9de0cb97da..000000000000 --- a/patches/0005-futex-Change-locking-rules.patch +++ /dev/null @@ -1,370 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Wed, 22 Mar 2017 11:35:52 +0100 -Subject: [PATCH] futex: Change locking rules - -Upstream commit 734009e96d1983ad739e5b656e03430b3660c913 - -Currently futex-pi relies on hb->lock to serialize everything. But hb->lock -creates another set of problems, especially priority inversions on RT where -hb->lock becomes a rt_mutex itself. - -The rt_mutex::wait_lock is the most obvious protection for keeping the -futex user space value and the kernel internal pi_state in sync. - -Rework and document the locking so rt_mutex::wait_lock is held accross all -operations which modify the user space value and the pi state. - -This allows to invoke rt_mutex_unlock() (including deboost) without holding -hb->lock as a next step. - -Nothing yet relies on the new locking rules. - -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: juri.lelli@arm.com -Cc: bigeasy@linutronix.de -Cc: xlpang@redhat.com -Cc: rostedt@goodmis.org -Cc: mathieu.desnoyers@efficios.com -Cc: jdesfossez@efficios.com -Cc: dvhart@infradead.org -Cc: bristot@redhat.com -Link: http://lkml.kernel.org/r/20170322104151.751993333@infradead.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/futex.c | 165 +++++++++++++++++++++++++++++++++++++++++++++------------ - 1 file changed, 132 insertions(+), 33 deletions(-) - ---- a/kernel/futex.c -+++ b/kernel/futex.c -@@ -973,6 +973,39 @@ void exit_pi_state_list(struct task_stru - * - * [10] There is no transient state which leaves owner and user space - * TID out of sync. -+ * -+ * -+ * Serialization and lifetime rules: -+ * -+ * hb->lock: -+ * -+ * hb -> futex_q, relation -+ * futex_q -> pi_state, relation -+ * -+ * (cannot be raw because hb can contain arbitrary amount -+ * of futex_q's) -+ * -+ * pi_mutex->wait_lock: -+ * -+ * {uval, pi_state} -+ * -+ * (and pi_mutex 'obviously') -+ * -+ * p->pi_lock: -+ * -+ * p->pi_state_list -> pi_state->list, relation -+ * -+ * pi_state->refcount: -+ * -+ * pi_state lifetime -+ * -+ * -+ * Lock order: -+ * -+ * hb->lock -+ * pi_mutex->wait_lock -+ * p->pi_lock -+ * - */ - - /* -@@ -980,10 +1013,12 @@ void exit_pi_state_list(struct task_stru - * the pi_state against the user space value. If correct, attach to - * it. - */ --static int attach_to_pi_state(u32 uval, struct futex_pi_state *pi_state, -+static int attach_to_pi_state(u32 __user *uaddr, u32 uval, -+ struct futex_pi_state *pi_state, - struct futex_pi_state **ps) - { - pid_t pid = uval & FUTEX_TID_MASK; -+ int ret, uval2; - - /* - * Userspace might have messed up non-PI and PI futexes [3] -@@ -991,9 +1026,34 @@ static int attach_to_pi_state(u32 uval, - if (unlikely(!pi_state)) - return -EINVAL; - -+ /* -+ * We get here with hb->lock held, and having found a -+ * futex_top_waiter(). This means that futex_lock_pi() of said futex_q -+ * has dropped the hb->lock in between queue_me() and unqueue_me_pi(), -+ * which in turn means that futex_lock_pi() still has a reference on -+ * our pi_state. -+ */ - WARN_ON(!atomic_read(&pi_state->refcount)); - - /* -+ * Now that we have a pi_state, we can acquire wait_lock -+ * and do the state validation. -+ */ -+ raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock); -+ -+ /* -+ * Since {uval, pi_state} is serialized by wait_lock, and our current -+ * uval was read without holding it, it can have changed. Verify it -+ * still is what we expect it to be, otherwise retry the entire -+ * operation. -+ */ -+ if (get_futex_value_locked(&uval2, uaddr)) -+ goto out_efault; -+ -+ if (uval != uval2) -+ goto out_eagain; -+ -+ /* - * Handle the owner died case: - */ - if (uval & FUTEX_OWNER_DIED) { -@@ -1008,11 +1068,11 @@ static int attach_to_pi_state(u32 uval, - * is not 0. Inconsistent state. [5] - */ - if (pid) -- return -EINVAL; -+ goto out_einval; - /* - * Take a ref on the state and return success. [4] - */ -- goto out_state; -+ goto out_attach; - } - - /* -@@ -1024,14 +1084,14 @@ static int attach_to_pi_state(u32 uval, - * Take a ref on the state and return success. [6] - */ - if (!pid) -- goto out_state; -+ goto out_attach; - } else { - /* - * If the owner died bit is not set, then the pi_state - * must have an owner. [7] - */ - if (!pi_state->owner) -- return -EINVAL; -+ goto out_einval; - } - - /* -@@ -1040,11 +1100,29 @@ static int attach_to_pi_state(u32 uval, - * user space TID. [9/10] - */ - if (pid != task_pid_vnr(pi_state->owner)) -- return -EINVAL; --out_state: -+ goto out_einval; -+ -+out_attach: - atomic_inc(&pi_state->refcount); -+ raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); - *ps = pi_state; - return 0; -+ -+out_einval: -+ ret = -EINVAL; -+ goto out_error; -+ -+out_eagain: -+ ret = -EAGAIN; -+ goto out_error; -+ -+out_efault: -+ ret = -EFAULT; -+ goto out_error; -+ -+out_error: -+ raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); -+ return ret; - } - - /* -@@ -1095,6 +1173,9 @@ static int attach_to_pi_owner(u32 uval, - - /* - * No existing pi state. First waiter. [2] -+ * -+ * This creates pi_state, we have hb->lock held, this means nothing can -+ * observe this state, wait_lock is irrelevant. - */ - pi_state = alloc_pi_state(); - -@@ -1119,7 +1200,8 @@ static int attach_to_pi_owner(u32 uval, - return 0; - } - --static int lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, -+static int lookup_pi_state(u32 __user *uaddr, u32 uval, -+ struct futex_hash_bucket *hb, - union futex_key *key, struct futex_pi_state **ps) - { - struct futex_q *top_waiter = futex_top_waiter(hb, key); -@@ -1129,7 +1211,7 @@ static int lookup_pi_state(u32 uval, str - * attach to the pi_state when the validation succeeds. - */ - if (top_waiter) -- return attach_to_pi_state(uval, top_waiter->pi_state, ps); -+ return attach_to_pi_state(uaddr, uval, top_waiter->pi_state, ps); - - /* - * We are the first waiter - try to look up the owner based on -@@ -1148,7 +1230,7 @@ static int lock_pi_update_atomic(u32 __u - if (unlikely(cmpxchg_futex_value_locked(&curval, uaddr, uval, newval))) - return -EFAULT; - -- /*If user space value changed, let the caller retry */ -+ /* If user space value changed, let the caller retry */ - return curval != uval ? -EAGAIN : 0; - } - -@@ -1204,7 +1286,7 @@ static int futex_lock_pi_atomic(u32 __us - */ - top_waiter = futex_top_waiter(hb, key); - if (top_waiter) -- return attach_to_pi_state(uval, top_waiter->pi_state, ps); -+ return attach_to_pi_state(uaddr, uval, top_waiter->pi_state, ps); - - /* - * No waiter and user TID is 0. We are here because the -@@ -1336,6 +1418,7 @@ static int wake_futex_pi(u32 __user *uad - - if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval)) { - ret = -EFAULT; -+ - } else if (curval != uval) { - /* - * If a unconditional UNLOCK_PI operation (user space did not -@@ -1348,6 +1431,7 @@ static int wake_futex_pi(u32 __user *uad - else - ret = -EINVAL; - } -+ - if (ret) { - raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); - return ret; -@@ -1823,7 +1907,7 @@ static int futex_requeue(u32 __user *uad - * If that call succeeds then we have pi_state and an - * initial refcount on it. - */ -- ret = lookup_pi_state(ret, hb2, &key2, &pi_state); -+ ret = lookup_pi_state(uaddr2, ret, hb2, &key2, &pi_state); - } - - switch (ret) { -@@ -2122,10 +2206,13 @@ static int fixup_pi_state_owner(u32 __us - { - u32 newtid = task_pid_vnr(newowner) | FUTEX_WAITERS; - struct futex_pi_state *pi_state = q->pi_state; -- struct task_struct *oldowner = pi_state->owner; - u32 uval, uninitialized_var(curval), newval; -+ struct task_struct *oldowner; - int ret; - -+ raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock); -+ -+ oldowner = pi_state->owner; - /* Owner died? */ - if (!pi_state->owner) - newtid |= FUTEX_OWNER_DIED; -@@ -2141,11 +2228,10 @@ static int fixup_pi_state_owner(u32 __us - * because we can fault here. Imagine swapped out pages or a fork - * that marked all the anonymous memory readonly for cow. - * -- * Modifying pi_state _before_ the user space value would -- * leave the pi_state in an inconsistent state when we fault -- * here, because we need to drop the hash bucket lock to -- * handle the fault. This might be observed in the PID check -- * in lookup_pi_state. -+ * Modifying pi_state _before_ the user space value would leave the -+ * pi_state in an inconsistent state when we fault here, because we -+ * need to drop the locks to handle the fault. This might be observed -+ * in the PID check in lookup_pi_state. - */ - retry: - if (get_futex_value_locked(&uval, uaddr)) -@@ -2166,47 +2252,60 @@ static int fixup_pi_state_owner(u32 __us - * itself. - */ - if (pi_state->owner != NULL) { -- raw_spin_lock_irq(&pi_state->owner->pi_lock); -+ raw_spin_lock(&pi_state->owner->pi_lock); - WARN_ON(list_empty(&pi_state->list)); - list_del_init(&pi_state->list); -- raw_spin_unlock_irq(&pi_state->owner->pi_lock); -+ raw_spin_unlock(&pi_state->owner->pi_lock); - } - - pi_state->owner = newowner; - -- raw_spin_lock_irq(&newowner->pi_lock); -+ raw_spin_lock(&newowner->pi_lock); - WARN_ON(!list_empty(&pi_state->list)); - list_add(&pi_state->list, &newowner->pi_state_list); -- raw_spin_unlock_irq(&newowner->pi_lock); -+ raw_spin_unlock(&newowner->pi_lock); -+ raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); -+ - return 0; - - /* -- * To handle the page fault we need to drop the hash bucket -- * lock here. That gives the other task (either the highest priority -- * waiter itself or the task which stole the rtmutex) the -- * chance to try the fixup of the pi_state. So once we are -- * back from handling the fault we need to check the pi_state -- * after reacquiring the hash bucket lock and before trying to -- * do another fixup. When the fixup has been done already we -- * simply return. -+ * To handle the page fault we need to drop the locks here. That gives -+ * the other task (either the highest priority waiter itself or the -+ * task which stole the rtmutex) the chance to try the fixup of the -+ * pi_state. So once we are back from handling the fault we need to -+ * check the pi_state after reacquiring the locks and before trying to -+ * do another fixup. When the fixup has been done already we simply -+ * return. -+ * -+ * Note: we hold both hb->lock and pi_mutex->wait_lock. We can safely -+ * drop hb->lock since the caller owns the hb -> futex_q relation. -+ * Dropping the pi_mutex->wait_lock requires the state revalidate. - */ - handle_fault: -+ raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); - spin_unlock(q->lock_ptr); - - ret = fault_in_user_writeable(uaddr); - - spin_lock(q->lock_ptr); -+ raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock); - - /* - * Check if someone else fixed it for us: - */ -- if (pi_state->owner != oldowner) -- return 0; -+ if (pi_state->owner != oldowner) { -+ ret = 0; -+ goto out_unlock; -+ } - - if (ret) -- return ret; -+ goto out_unlock; - - goto retry; -+ -+out_unlock: -+ raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); -+ return ret; - } - - static long futex_wait_restart(struct restart_block *restart); diff --git a/patches/0005-hrtimer-Switch-for-loop-to-_ffs-evaluation.patch b/patches/0005-hrtimer-Switch-for-loop-to-_ffs-evaluation.patch index ebabb389b324..57f987cfa13b 100644 --- a/patches/0005-hrtimer-Switch-for-loop-to-_ffs-evaluation.patch +++ b/patches/0005-hrtimer-Switch-for-loop-to-_ffs-evaluation.patch @@ -15,7 +15,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -464,17 +464,18 @@ static inline void hrtimer_update_next_t +@@ -465,17 +465,18 @@ static inline void hrtimer_update_next_t static ktime_t __hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base) { @@ -38,7 +38,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> next = timerqueue_getnext(&base->active); timer = container_of(next, struct hrtimer, node); -@@ -1241,15 +1242,16 @@ static void __run_hrtimer(struct hrtimer +@@ -1242,15 +1243,16 @@ static void __run_hrtimer(struct hrtimer static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now) { diff --git a/patches/0005-metag-Adjust-system_state-check.patch b/patches/0005-metag-Adjust-system_state-check.patch deleted file mode 100644 index 3a2cc0d8897b..000000000000 --- a/patches/0005-metag-Adjust-system_state-check.patch +++ /dev/null @@ -1,35 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Tue, 16 May 2017 20:42:36 +0200 -Subject: [PATCH 05/17] metag: Adjust system_state check - -To enable smp_processor_id() and might_sleep() debug checks earlier, it's -required to add system states between SYSTEM_BOOTING and SYSTEM_RUNNING. - -Adjust the system_state check in stop_this_cpu() to handle the extra states. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Cc: James Hogan <james.hogan@imgtec.com> -Cc: Linus Torvalds <torvalds@linux-foundation.org> -Cc: Mark Rutland <mark.rutland@arm.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Link: http://lkml.kernel.org/r/20170516184735.283420315@linutronix.de -Signed-off-by: Ingo Molnar <mingo@kernel.org> ---- - arch/metag/kernel/smp.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/arch/metag/kernel/smp.c -+++ b/arch/metag/kernel/smp.c -@@ -567,8 +567,7 @@ static void stop_this_cpu(void *data) - { - unsigned int cpu = smp_processor_id(); - -- if (system_state == SYSTEM_BOOTING || -- system_state == SYSTEM_RUNNING) { -+ if (system_state <= SYSTEM_RUNNING) { - spin_lock(&stop_lock); - pr_crit("CPU%u: stopping\n", cpu); - dump_stack(); diff --git a/patches/0005-powerpc-smp-Replace-open-coded-task-affinity-logic.patch b/patches/0005-powerpc-smp-Replace-open-coded-task-affinity-logic.patch deleted file mode 100644 index 3fa118c44246..000000000000 --- a/patches/0005-powerpc-smp-Replace-open-coded-task-affinity-logic.patch +++ /dev/null @@ -1,88 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 12 Apr 2017 22:07:31 +0200 -Subject: [PATCH 05/13] powerpc/smp: Replace open coded task affinity logic - -Init task invokes smp_ops->setup_cpu() from smp_cpus_done(). Init task can -run on any online CPU at this point, but the setup_cpu() callback requires -to be invoked on the boot CPU. This is achieved by temporarily setting the -affinity of the calling user space thread to the requested CPU and reset it -to the original affinity afterwards. - -That's racy vs. CPU hotplug and concurrent affinity settings for that -thread resulting in code executing on the wrong CPU and overwriting the -new affinity setting. - -That's actually not a problem in this context as neither CPU hotplug nor -affinity settings can happen, but the access to task_struct::cpus_allowed -is about to restricted. - -Replace it with a call to work_on_cpu_safe() which achieves the same result. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Michael Ellerman <mpe@ellerman.id.au> -Cc: Fenghua Yu <fenghua.yu@intel.com> -Cc: Tony Luck <tony.luck@intel.com> -Cc: Herbert Xu <herbert@gondor.apana.org.au> -Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Lai Jiangshan <jiangshanlai@gmail.com> -Cc: Viresh Kumar <viresh.kumar@linaro.org> -Cc: Tejun Heo <tj@kernel.org> -Cc: Paul Mackerras <paulus@samba.org> -Cc: linuxppc-dev@lists.ozlabs.org -Cc: "David S. Miller" <davem@davemloft.net> -Cc: Len Brown <lenb@kernel.org> -Link: http://lkml.kernel.org/r/20170412201042.518053336@linutronix.de -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - arch/powerpc/kernel/smp.c | 26 +++++++++++--------------- - 1 file changed, 11 insertions(+), 15 deletions(-) - ---- a/arch/powerpc/kernel/smp.c -+++ b/arch/powerpc/kernel/smp.c -@@ -787,24 +787,21 @@ static struct sched_domain_topology_leve - { NULL, }, - }; - --void __init smp_cpus_done(unsigned int max_cpus) -+static __init long smp_setup_cpu_workfn(void *data __always_unused) - { -- cpumask_var_t old_mask; -+ smp_ops->setup_cpu(boot_cpuid); -+ return 0; -+} - -- /* We want the setup_cpu() here to be called from CPU 0, but our -- * init thread may have been "borrowed" by another CPU in the meantime -- * se we pin us down to CPU 0 for a short while -+void __init smp_cpus_done(unsigned int max_cpus) -+{ -+ /* -+ * We want the setup_cpu() here to be called on the boot CPU, but -+ * init might run on any CPU, so make sure it's invoked on the boot -+ * CPU. - */ -- alloc_cpumask_var(&old_mask, GFP_NOWAIT); -- cpumask_copy(old_mask, ¤t->cpus_allowed); -- set_cpus_allowed_ptr(current, cpumask_of(boot_cpuid)); -- - if (smp_ops && smp_ops->setup_cpu) -- smp_ops->setup_cpu(boot_cpuid); -- -- set_cpus_allowed_ptr(current, old_mask); -- -- free_cpumask_var(old_mask); -+ work_on_cpu_safe(boot_cpuid, smp_setup_cpu_workfn, NULL); - - if (smp_ops && smp_ops->bringup_done) - smp_ops->bringup_done(); -@@ -812,7 +809,6 @@ void __init smp_cpus_done(unsigned int m - dump_numa_cpu_topology(); - - set_sched_topology(powerpc_topology); -- - } - - #ifdef CONFIG_HOTPLUG_CPU diff --git a/patches/0005-sched-rtmutex-Refactor-rt_mutex_setprio.patch b/patches/0005-sched-rtmutex-Refactor-rt_mutex_setprio.patch deleted file mode 100644 index 54ccf522b2ac..000000000000 --- a/patches/0005-sched-rtmutex-Refactor-rt_mutex_setprio.patch +++ /dev/null @@ -1,391 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Thu, 23 Mar 2017 15:56:11 +0100 -Subject: [PATCH 5/9] sched/rtmutex: Refactor rt_mutex_setprio() - -With the introduction of SCHED_DEADLINE the whole notion that priority -is a single number is gone, therefore the @prio argument to -rt_mutex_setprio() doesn't make sense anymore. - -So rework the code to pass a pi_task instead. - -Note this also fixes a problem with pi_top_task caching; previously we -would not set the pointer (call rt_mutex_update_top_task) if the -priority didn't change, this could lead to a stale pointer. - -As for the XXX, I think its fine to use pi_task->prio, because if it -differs from waiter->prio, a PI chain update is immenent. - -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: juri.lelli@arm.com -Cc: bigeasy@linutronix.de -Cc: xlpang@redhat.com -Cc: rostedt@goodmis.org -Cc: mathieu.desnoyers@efficios.com -Cc: jdesfossez@efficios.com -Cc: bristot@redhat.com -Link: http://lkml.kernel.org/r/20170323150216.303827095@infradead.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - include/linux/sched/rt.h | 24 +++------- - kernel/locking/rtmutex.c | 112 ++++++++++++----------------------------------- - kernel/sched/core.c | 66 ++++++++++++++++++++++----- - 3 files changed, 91 insertions(+), 111 deletions(-) - ---- a/include/linux/sched/rt.h -+++ b/include/linux/sched/rt.h -@@ -18,28 +18,20 @@ static inline int rt_task(struct task_st - } - - #ifdef CONFIG_RT_MUTEXES --extern int rt_mutex_getprio(struct task_struct *p); --extern void rt_mutex_setprio(struct task_struct *p, int prio); --extern int rt_mutex_get_effective_prio(struct task_struct *task, int newprio); --extern void rt_mutex_update_top_task(struct task_struct *p); --extern struct task_struct *rt_mutex_get_top_task(struct task_struct *task); -+/* -+ * Must hold either p->pi_lock or task_rq(p)->lock. -+ */ -+static inline struct task_struct *rt_mutex_get_top_task(struct task_struct *p) -+{ -+ return p->pi_top_task; -+} -+extern void rt_mutex_setprio(struct task_struct *p, struct task_struct *pi_task); - extern void rt_mutex_adjust_pi(struct task_struct *p); - static inline bool tsk_is_pi_blocked(struct task_struct *tsk) - { - return tsk->pi_blocked_on != NULL; - } - #else --static inline int rt_mutex_getprio(struct task_struct *p) --{ -- return p->normal_prio; --} -- --static inline int rt_mutex_get_effective_prio(struct task_struct *task, -- int newprio) --{ -- return newprio; --} -- - static inline struct task_struct *rt_mutex_get_top_task(struct task_struct *task) - { - return NULL; ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -322,67 +322,16 @@ rt_mutex_dequeue_pi(struct task_struct * - RB_CLEAR_NODE(&waiter->pi_tree_entry); - } - --/* -- * Must hold both p->pi_lock and task_rq(p)->lock. -- */ --void rt_mutex_update_top_task(struct task_struct *p) --{ -- if (!task_has_pi_waiters(p)) { -- p->pi_top_task = NULL; -- return; -- } -- -- p->pi_top_task = task_top_pi_waiter(p)->task; --} -- --/* -- * Calculate task priority from the waiter tree priority -- * -- * Return task->normal_prio when the waiter tree is empty or when -- * the waiter is not allowed to do priority boosting -- */ --int rt_mutex_getprio(struct task_struct *task) --{ -- if (likely(!task_has_pi_waiters(task))) -- return task->normal_prio; -- -- return min(task_top_pi_waiter(task)->prio, -- task->normal_prio); --} -- --/* -- * Must hold either p->pi_lock or task_rq(p)->lock. -- */ --struct task_struct *rt_mutex_get_top_task(struct task_struct *task) --{ -- return task->pi_top_task; --} -- --/* -- * Called by sched_setscheduler() to get the priority which will be -- * effective after the change. -- */ --int rt_mutex_get_effective_prio(struct task_struct *task, int newprio) -+static void rt_mutex_adjust_prio(struct task_struct *p) - { -- struct task_struct *top_task = rt_mutex_get_top_task(task); -+ struct task_struct *pi_task = NULL; - -- if (!top_task) -- return newprio; -+ lockdep_assert_held(&p->pi_lock); - -- return min(top_task->prio, newprio); --} -+ if (task_has_pi_waiters(p)) -+ pi_task = task_top_pi_waiter(p)->task; - --/* -- * Adjust the priority of a task, after its pi_waiters got modified. -- * -- * This can be both boosting and unboosting. task->pi_lock must be held. -- */ --static void __rt_mutex_adjust_prio(struct task_struct *task) --{ -- int prio = rt_mutex_getprio(task); -- -- if (task->prio != prio || dl_prio(prio)) -- rt_mutex_setprio(task, prio); -+ rt_mutex_setprio(p, pi_task); - } - - /* -@@ -742,7 +691,7 @@ static int rt_mutex_adjust_prio_chain(st - */ - rt_mutex_dequeue_pi(task, prerequeue_top_waiter); - rt_mutex_enqueue_pi(task, waiter); -- __rt_mutex_adjust_prio(task); -+ rt_mutex_adjust_prio(task); - - } else if (prerequeue_top_waiter == waiter) { - /* -@@ -758,7 +707,7 @@ static int rt_mutex_adjust_prio_chain(st - rt_mutex_dequeue_pi(task, waiter); - waiter = rt_mutex_top_waiter(lock); - rt_mutex_enqueue_pi(task, waiter); -- __rt_mutex_adjust_prio(task); -+ rt_mutex_adjust_prio(task); - } else { - /* - * Nothing changed. No need to do any priority -@@ -966,7 +915,7 @@ static int task_blocks_on_rt_mutex(struc - return -EDEADLK; - - raw_spin_lock(&task->pi_lock); -- __rt_mutex_adjust_prio(task); -+ rt_mutex_adjust_prio(task); - waiter->task = task; - waiter->lock = lock; - waiter->prio = task->prio; -@@ -988,7 +937,7 @@ static int task_blocks_on_rt_mutex(struc - rt_mutex_dequeue_pi(owner, top_waiter); - rt_mutex_enqueue_pi(owner, waiter); - -- __rt_mutex_adjust_prio(owner); -+ rt_mutex_adjust_prio(owner); - if (owner->pi_blocked_on) - chain_walk = 1; - } else if (rt_mutex_cond_detect_deadlock(waiter, chwalk)) { -@@ -1040,13 +989,14 @@ static void mark_wakeup_next_waiter(stru - waiter = rt_mutex_top_waiter(lock); - - /* -- * Remove it from current->pi_waiters. We do not adjust a -- * possible priority boost right now. We execute wakeup in the -- * boosted mode and go back to normal after releasing -- * lock->wait_lock. -+ * Remove it from current->pi_waiters and deboost. -+ * -+ * We must in fact deboost here in order to ensure we call -+ * rt_mutex_setprio() to update p->pi_top_task before the -+ * task unblocks. - */ - rt_mutex_dequeue_pi(current, waiter); -- __rt_mutex_adjust_prio(current); -+ rt_mutex_adjust_prio(current); - - /* - * As we are waking up the top waiter, and the waiter stays -@@ -1058,9 +1008,19 @@ static void mark_wakeup_next_waiter(stru - */ - lock->owner = (void *) RT_MUTEX_HAS_WAITERS; - -- raw_spin_unlock(¤t->pi_lock); -- -+ /* -+ * We deboosted before waking the top waiter task such that we don't -+ * run two tasks with the 'same' priority (and ensure the -+ * p->pi_top_task pointer points to a blocked task). This however can -+ * lead to priority inversion if we would get preempted after the -+ * deboost but before waking our donor task, hence the preempt_disable() -+ * before unlock. -+ * -+ * Pairs with preempt_enable() in rt_mutex_postunlock(); -+ */ -+ preempt_disable(); - wake_q_add(wake_q, waiter->task); -+ raw_spin_unlock(¤t->pi_lock); - } - - /* -@@ -1095,7 +1055,7 @@ static void remove_waiter(struct rt_mute - if (rt_mutex_has_waiters(lock)) - rt_mutex_enqueue_pi(owner, rt_mutex_top_waiter(lock)); - -- __rt_mutex_adjust_prio(owner); -+ rt_mutex_adjust_prio(owner); - - /* Store the lock on which owner is blocked or NULL */ - next_lock = task_blocked_on_lock(owner); -@@ -1134,8 +1094,7 @@ void rt_mutex_adjust_pi(struct task_stru - raw_spin_lock_irqsave(&task->pi_lock, flags); - - waiter = task->pi_blocked_on; -- if (!waiter || (waiter->prio == task->prio && -- !dl_prio(task->prio))) { -+ if (!waiter || (waiter->prio == task->prio && !dl_prio(task->prio))) { - raw_spin_unlock_irqrestore(&task->pi_lock, flags); - return; - } -@@ -1389,17 +1348,6 @@ static bool __sched rt_mutex_slowunlock( - * Queue the next waiter for wakeup once we release the wait_lock. - */ - mark_wakeup_next_waiter(wake_q, lock); -- -- /* -- * We should deboost before waking the top waiter task such that -- * we don't run two tasks with the 'same' priority. This however -- * can lead to prio-inversion if we would get preempted after -- * the deboost but before waking our high-prio task, hence the -- * preempt_disable before unlock. Pairs with preempt_enable() in -- * rt_mutex_postunlock(); -- */ -- preempt_disable(); -- - raw_spin_unlock_irqrestore(&lock->wait_lock, flags); - - return true; /* call rt_mutex_postunlock() */ ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -3671,10 +3671,25 @@ EXPORT_SYMBOL(default_wake_function); - - #ifdef CONFIG_RT_MUTEXES - -+static inline int __rt_effective_prio(struct task_struct *pi_task, int prio) -+{ -+ if (pi_task) -+ prio = min(prio, pi_task->prio); -+ -+ return prio; -+} -+ -+static inline int rt_effective_prio(struct task_struct *p, int prio) -+{ -+ struct task_struct *pi_task = rt_mutex_get_top_task(p); -+ -+ return __rt_effective_prio(pi_task, prio); -+} -+ - /* - * rt_mutex_setprio - set the current priority of a task -- * @p: task -- * @prio: prio value (kernel-internal form) -+ * @p: task to boost -+ * @pi_task: donor task - * - * This function changes the 'effective' priority of a task. It does - * not touch ->normal_prio like __setscheduler(). -@@ -3682,17 +3697,41 @@ EXPORT_SYMBOL(default_wake_function); - * Used by the rt_mutex code to implement priority inheritance - * logic. Call site only calls if the priority of the task changed. - */ --void rt_mutex_setprio(struct task_struct *p, int prio) -+void rt_mutex_setprio(struct task_struct *p, struct task_struct *pi_task) - { -- int oldprio, queued, running, queue_flag = DEQUEUE_SAVE | DEQUEUE_MOVE; -+ int prio, oldprio, queued, running, queue_flag = DEQUEUE_SAVE | DEQUEUE_MOVE; - const struct sched_class *prev_class; - struct rq_flags rf; - struct rq *rq; - -- BUG_ON(prio > MAX_PRIO); -+ /* XXX used to be waiter->prio, not waiter->task->prio */ -+ prio = __rt_effective_prio(pi_task, p->normal_prio); -+ -+ /* -+ * If nothing changed; bail early. -+ */ -+ if (p->pi_top_task == pi_task && prio == p->prio && !dl_prio(prio)) -+ return; - - rq = __task_rq_lock(p, &rf); - update_rq_clock(rq); -+ /* -+ * Set under pi_lock && rq->lock, such that the value can be used under -+ * either lock. -+ * -+ * Note that there is loads of tricky to make this pointer cache work -+ * right. rt_mutex_slowunlock()+rt_mutex_postunlock() work together to -+ * ensure a task is de-boosted (pi_task is set to NULL) before the -+ * task is allowed to run again (and can exit). This ensures the pointer -+ * points to a blocked task -- which guaratees the task is present. -+ */ -+ p->pi_top_task = pi_task; -+ -+ /* -+ * For FIFO/RR we only need to set prio, if that matches we're done. -+ */ -+ if (prio == p->prio && !dl_prio(prio)) -+ goto out_unlock; - - /* - * Idle task boosting is a nono in general. There is one -@@ -3712,9 +3751,7 @@ void rt_mutex_setprio(struct task_struct - goto out_unlock; - } - -- rt_mutex_update_top_task(p); -- -- trace_sched_pi_setprio(p, prio); -+ trace_sched_pi_setprio(p, prio); /* broken */ - oldprio = p->prio; - - if (oldprio == prio) -@@ -3738,7 +3775,6 @@ void rt_mutex_setprio(struct task_struct - * running task - */ - if (dl_prio(prio)) { -- struct task_struct *pi_task = rt_mutex_get_top_task(p); - if (!dl_prio(p->normal_prio) || - (pi_task && dl_entity_preempt(&pi_task->dl, &p->dl))) { - p->dl.dl_boosted = 1; -@@ -3776,6 +3812,11 @@ void rt_mutex_setprio(struct task_struct - balance_callback(rq); - preempt_enable(); - } -+#else -+static inline int rt_effective_prio(struct task_struct *p, int prio) -+{ -+ return prio; -+} - #endif - - void set_user_nice(struct task_struct *p, long nice) -@@ -4022,10 +4063,9 @@ static void __setscheduler(struct rq *rq - * Keep a potential priority boosting if called from - * sched_setscheduler(). - */ -+ p->prio = normal_prio(p); - if (keep_boost) -- p->prio = rt_mutex_get_effective_prio(p, normal_prio(p)); -- else -- p->prio = normal_prio(p); -+ p->prio = rt_effective_prio(p, p->prio); - - if (dl_prio(p->prio)) - p->sched_class = &dl_sched_class; -@@ -4312,7 +4352,7 @@ static int __sched_setscheduler(struct t - * the runqueue. This will be done when the task deboost - * itself. - */ -- new_effective_prio = rt_mutex_get_effective_prio(p, newprio); -+ new_effective_prio = rt_effective_prio(p, newprio); - if (new_effective_prio == oldprio) - queue_flags &= ~DEQUEUE_MOVE; - } diff --git a/patches/0005-stop_machine-Provide-stop_machine_cpuslocked.patch b/patches/0005-stop_machine-Provide-stop_machine_cpuslocked.patch deleted file mode 100644 index dd0fa6f147bb..000000000000 --- a/patches/0005-stop_machine-Provide-stop_machine_cpuslocked.patch +++ /dev/null @@ -1,108 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Wed, 24 May 2017 10:15:16 +0200 -Subject: [PATCH 05/32] stop_machine: Provide stop_machine_cpuslocked() - -Some call sites of stop_machine() are within a get_online_cpus() protected -region. - -stop_machine() calls get_online_cpus() as well, which is possible in the -current implementation but prevents converting the hotplug locking to a -percpu rwsem. - -Provide stop_machine_cpuslocked() to avoid nested calls to get_online_cpus(). - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Tested-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Acked-by: Ingo Molnar <mingo@kernel.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Link: http://lkml.kernel.org/r/20170524081547.400700852@linutronix.de ---- - include/linux/stop_machine.h | 26 +++++++++++++++++++++++--- - kernel/stop_machine.c | 11 +++++++---- - 2 files changed, 30 insertions(+), 7 deletions(-) - ---- a/include/linux/stop_machine.h -+++ b/include/linux/stop_machine.h -@@ -116,15 +116,29 @@ static inline int try_stop_cpus(const st - * @fn() runs. - * - * This can be thought of as a very heavy write lock, equivalent to -- * grabbing every spinlock in the kernel. */ -+ * grabbing every spinlock in the kernel. -+ * -+ * Protects against CPU hotplug. -+ */ - int stop_machine(cpu_stop_fn_t fn, void *data, const struct cpumask *cpus); - -+/** -+ * stop_machine_cpuslocked: freeze the machine on all CPUs and run this function -+ * @fn: the function to run -+ * @data: the data ptr for the @fn() -+ * @cpus: the cpus to run the @fn() on (NULL = any online cpu) -+ * -+ * Same as above. Must be called from with in a cpus_read_lock() protected -+ * region. Avoids nested calls to cpus_read_lock(). -+ */ -+int stop_machine_cpuslocked(cpu_stop_fn_t fn, void *data, const struct cpumask *cpus); -+ - int stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data, - const struct cpumask *cpus); - #else /* CONFIG_SMP || CONFIG_HOTPLUG_CPU */ - --static inline int stop_machine(cpu_stop_fn_t fn, void *data, -- const struct cpumask *cpus) -+static inline int stop_machine_cpuslocked(cpu_stop_fn_t fn, void *data, -+ const struct cpumask *cpus) - { - unsigned long flags; - int ret; -@@ -134,6 +148,12 @@ static inline int stop_machine(cpu_stop_ - return ret; - } - -+static inline int stop_machine(cpu_stop_fn_t fn, void *data, -+ const struct cpumask *cpus) -+{ -+ return stop_machine_cpuslocked(fn, data, cpus); -+} -+ - static inline int stop_machine_from_inactive_cpu(cpu_stop_fn_t fn, void *data, - const struct cpumask *cpus) - { ---- a/kernel/stop_machine.c -+++ b/kernel/stop_machine.c -@@ -552,7 +552,8 @@ static int __init cpu_stop_init(void) - } - early_initcall(cpu_stop_init); - --static int __stop_machine(cpu_stop_fn_t fn, void *data, const struct cpumask *cpus) -+int stop_machine_cpuslocked(cpu_stop_fn_t fn, void *data, -+ const struct cpumask *cpus) - { - struct multi_stop_data msdata = { - .fn = fn, -@@ -561,6 +562,8 @@ static int __stop_machine(cpu_stop_fn_t - .active_cpus = cpus, - }; - -+ lockdep_assert_cpus_held(); -+ - if (!stop_machine_initialized) { - /* - * Handle the case where stop_machine() is called -@@ -590,9 +593,9 @@ int stop_machine(cpu_stop_fn_t fn, void - int ret; - - /* No CPUs can come up or down during this. */ -- get_online_cpus(); -- ret = __stop_machine(fn, data, cpus); -- put_online_cpus(); -+ cpus_read_lock(); -+ ret = stop_machine_cpuslocked(fn, data, cpus); -+ cpus_read_unlock(); - return ret; - } - EXPORT_SYMBOL_GPL(stop_machine); diff --git a/patches/0006-futex-Cleanup-refcounting.patch b/patches/0006-futex-Cleanup-refcounting.patch deleted file mode 100644 index 566a1356f606..000000000000 --- a/patches/0006-futex-Cleanup-refcounting.patch +++ /dev/null @@ -1,75 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Wed, 22 Mar 2017 11:35:53 +0100 -Subject: [PATCH] futex: Cleanup refcounting - -Upstream commit bf92cf3a5100f5a0d5f9834787b130159397cb22 - -Add a put_pit_state() as counterpart for get_pi_state() so the refcounting -becomes consistent. - -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: juri.lelli@arm.com -Cc: bigeasy@linutronix.de -Cc: xlpang@redhat.com -Cc: rostedt@goodmis.org -Cc: mathieu.desnoyers@efficios.com -Cc: jdesfossez@efficios.com -Cc: dvhart@infradead.org -Cc: bristot@redhat.com -Link: http://lkml.kernel.org/r/20170322104151.801778516@infradead.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/futex.c | 13 +++++++++---- - 1 file changed, 9 insertions(+), 4 deletions(-) - ---- a/kernel/futex.c -+++ b/kernel/futex.c -@@ -802,7 +802,7 @@ static int refill_pi_state_cache(void) - return 0; - } - --static struct futex_pi_state * alloc_pi_state(void) -+static struct futex_pi_state *alloc_pi_state(void) - { - struct futex_pi_state *pi_state = current->pi_state_cache; - -@@ -812,6 +812,11 @@ static struct futex_pi_state * alloc_pi_ - return pi_state; - } - -+static void get_pi_state(struct futex_pi_state *pi_state) -+{ -+ WARN_ON_ONCE(!atomic_inc_not_zero(&pi_state->refcount)); -+} -+ - /* - * Drops a reference to the pi_state object and frees or caches it - * when the last reference is gone. -@@ -856,7 +861,7 @@ static void put_pi_state(struct futex_pi - * Look up the task based on what TID userspace gave us. - * We dont trust it. - */ --static struct task_struct * futex_find_get_task(pid_t pid) -+static struct task_struct *futex_find_get_task(pid_t pid) - { - struct task_struct *p; - -@@ -1103,7 +1108,7 @@ static int attach_to_pi_state(u32 __user - goto out_einval; - - out_attach: -- atomic_inc(&pi_state->refcount); -+ get_pi_state(pi_state); - raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); - *ps = pi_state; - return 0; -@@ -1990,7 +1995,7 @@ static int futex_requeue(u32 __user *uad - * refcount on the pi_state and store the pointer in - * the futex_q object of the waiter. - */ -- atomic_inc(&pi_state->refcount); -+ get_pi_state(pi_state); - this->pi_state = pi_state; - ret = rt_mutex_start_proxy_lock(&pi_state->pi_mutex, - this->rt_waiter, diff --git a/patches/0006-hrtimer-Store-running-timer-in-hrtimer_clock_base.patch b/patches/0006-hrtimer-Store-running-timer-in-hrtimer_clock_base.patch index dc484681ed6c..df4d12e75c08 100644 --- a/patches/0006-hrtimer-Store-running-timer-in-hrtimer_clock_base.patch +++ b/patches/0006-hrtimer-Store-running-timer-in-hrtimer_clock_base.patch @@ -96,7 +96,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> timer->node.expires = time; timer->_softexpires = time; } -@@ -426,7 +424,7 @@ static inline int hrtimer_is_queued(stru +@@ -422,7 +420,7 @@ static inline int hrtimer_is_queued(stru */ static inline int hrtimer_callback_running(struct hrtimer *timer) { @@ -107,7 +107,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* Forward a hrtimer so it expires after now: */ --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -69,7 +69,6 @@ +@@ -70,7 +70,6 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) = { .lock = __RAW_SPIN_LOCK_UNLOCKED(hrtimer_bases.lock), @@ -115,7 +115,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> .clock_base = { { -@@ -117,7 +116,6 @@ static const int hrtimer_clock_to_base_t +@@ -118,7 +117,6 @@ static const int hrtimer_clock_to_base_t * timer->base->cpu_base */ static struct hrtimer_cpu_base migration_cpu_base = { @@ -123,7 +123,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> .clock_base = { { .cpu_base = &migration_cpu_base, }, }, }; -@@ -1135,19 +1133,19 @@ EXPORT_SYMBOL_GPL(hrtimer_init); +@@ -1136,19 +1134,19 @@ EXPORT_SYMBOL_GPL(hrtimer_init); */ bool hrtimer_active(const struct hrtimer *timer) { @@ -149,7 +149,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return false; } -@@ -1181,16 +1179,16 @@ static void __run_hrtimer(struct hrtimer +@@ -1182,16 +1180,16 @@ static void __run_hrtimer(struct hrtimer lockdep_assert_held(&cpu_base->lock); debug_deactivate(timer); @@ -169,7 +169,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> __remove_hrtimer(timer, base, HRTIMER_STATE_INACTIVE, 0); fn = timer->function; -@@ -1231,13 +1229,13 @@ static void __run_hrtimer(struct hrtimer +@@ -1232,13 +1230,13 @@ static void __run_hrtimer(struct hrtimer * Separate the ->running assignment from the ->state assignment. * * As with a regular write barrier, this ensures the read side in diff --git a/patches/0006-padata-Make-padata_alloc-static.patch b/patches/0006-padata-Make-padata_alloc-static.patch deleted file mode 100644 index e7605db4db76..000000000000 --- a/patches/0006-padata-Make-padata_alloc-static.patch +++ /dev/null @@ -1,87 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 24 May 2017 10:15:17 +0200 -Subject: [PATCH 06/32] padata: Make padata_alloc() static - -No users outside of padata.c - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Tested-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Acked-by: Ingo Molnar <mingo@kernel.org> -Cc: Steffen Klassert <steffen.klassert@secunet.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: linux-crypto@vger.kernel.org -Link: http://lkml.kernel.org/r/20170524081547.491457256@linutronix.de ---- - include/linux/padata.h | 3 --- - kernel/padata.c | 32 ++++++++++++++++---------------- - 2 files changed, 16 insertions(+), 19 deletions(-) - ---- a/include/linux/padata.h -+++ b/include/linux/padata.h -@@ -166,9 +166,6 @@ struct padata_instance { - - extern struct padata_instance *padata_alloc_possible( - struct workqueue_struct *wq); --extern struct padata_instance *padata_alloc(struct workqueue_struct *wq, -- const struct cpumask *pcpumask, -- const struct cpumask *cbcpumask); - extern void padata_free(struct padata_instance *pinst); - extern int padata_do_parallel(struct padata_instance *pinst, - struct padata_priv *padata, int cb_cpu); ---- a/kernel/padata.c -+++ b/kernel/padata.c -@@ -939,19 +939,6 @@ static struct kobj_type padata_attr_type - }; - - /** -- * padata_alloc_possible - Allocate and initialize padata instance. -- * Use the cpu_possible_mask for serial and -- * parallel workers. -- * -- * @wq: workqueue to use for the allocated padata instance -- */ --struct padata_instance *padata_alloc_possible(struct workqueue_struct *wq) --{ -- return padata_alloc(wq, cpu_possible_mask, cpu_possible_mask); --} --EXPORT_SYMBOL(padata_alloc_possible); -- --/** - * padata_alloc - allocate and initialize a padata instance and specify - * cpumasks for serial and parallel workers. - * -@@ -959,9 +946,9 @@ EXPORT_SYMBOL(padata_alloc_possible); - * @pcpumask: cpumask that will be used for padata parallelization - * @cbcpumask: cpumask that will be used for padata serialization - */ --struct padata_instance *padata_alloc(struct workqueue_struct *wq, -- const struct cpumask *pcpumask, -- const struct cpumask *cbcpumask) -+static struct padata_instance *padata_alloc(struct workqueue_struct *wq, -+ const struct cpumask *pcpumask, -+ const struct cpumask *cbcpumask) - { - struct padata_instance *pinst; - struct parallel_data *pd = NULL; -@@ -1016,6 +1003,19 @@ struct padata_instance *padata_alloc(str - } - - /** -+ * padata_alloc_possible - Allocate and initialize padata instance. -+ * Use the cpu_possible_mask for serial and -+ * parallel workers. -+ * -+ * @wq: workqueue to use for the allocated padata instance -+ */ -+struct padata_instance *padata_alloc_possible(struct workqueue_struct *wq) -+{ -+ return padata_alloc(wq, cpu_possible_mask, cpu_possible_mask); -+} -+EXPORT_SYMBOL(padata_alloc_possible); -+ -+/** - * padata_free - free a padata instance - * - * @padata_inst: padata instance to free diff --git a/patches/0006-powerpc-Adjust-system_state-check.patch b/patches/0006-powerpc-Adjust-system_state-check.patch deleted file mode 100644 index 5250cfaadcb9..000000000000 --- a/patches/0006-powerpc-Adjust-system_state-check.patch +++ /dev/null @@ -1,38 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Tue, 16 May 2017 20:42:37 +0200 -Subject: [PATCH 06/17] powerpc: Adjust system_state check - -To enable smp_processor_id() and might_sleep() debug checks earlier, it's -required to add system states between SYSTEM_BOOTING and SYSTEM_RUNNING. - -Adjust the system_state check in smp_generic_cpu_bootable() to handle the -extra states. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Acked-by: Michael Ellerman <mpe@ellerman.id.au> -Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> -Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Cc: Linus Torvalds <torvalds@linux-foundation.org> -Cc: Mark Rutland <mark.rutland@arm.com> -Cc: Paul Mackerras <paulus@samba.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: linuxppc-dev@lists.ozlabs.org -Link: http://lkml.kernel.org/r/20170516184735.359536998@linutronix.de -Signed-off-by: Ingo Molnar <mingo@kernel.org> ---- - arch/powerpc/kernel/smp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/powerpc/kernel/smp.c -+++ b/arch/powerpc/kernel/smp.c -@@ -98,7 +98,7 @@ int smp_generic_cpu_bootable(unsigned in - /* Special case - we inhibit secondary thread startup - * during boot if the user requests it. - */ -- if (system_state == SYSTEM_BOOTING && cpu_has_feature(CPU_FTR_SMT)) { -+ if (system_state < SYSTEM_RUNNING && cpu_has_feature(CPU_FTR_SMT)) { - if (!smt_enabled_at_boot && cpu_thread_in_core(nr) != 0) - return 0; - if (smt_enabled_at_boot diff --git a/patches/0006-ring-buffer-Add-interface-for-setting-absolute-time-.patch b/patches/0006-ring-buffer-Add-interface-for-setting-absolute-time-.patch index 263313eb3e83..69b007605471 100644 --- a/patches/0006-ring-buffer-Add-interface-for-setting-absolute-time-.patch +++ b/patches/0006-ring-buffer-Add-interface-for-setting-absolute-time-.patch @@ -35,7 +35,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c -@@ -484,6 +484,7 @@ struct ring_buffer { +@@ -485,6 +485,7 @@ struct ring_buffer { u64 (*clock)(void); struct rb_irq_work irq_work; @@ -43,7 +43,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> }; struct ring_buffer_iter { -@@ -1378,6 +1379,16 @@ void ring_buffer_set_clock(struct ring_b +@@ -1379,6 +1380,16 @@ void ring_buffer_set_clock(struct ring_b buffer->clock = clock; } @@ -62,7 +62,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static inline unsigned long rb_page_entries(struct buffer_page *bpage) --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c -@@ -2082,7 +2082,7 @@ trace_event_buffer_lock_reserve(struct r +@@ -2266,7 +2266,7 @@ trace_event_buffer_lock_reserve(struct r *current_rb = trace_file->tr->trace_buffer.buffer; @@ -71,7 +71,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> (EVENT_FILE_FL_SOFT_DISABLED | EVENT_FILE_FL_FILTERED)) && (entry = this_cpu_read(trace_buffered_event))) { /* Try to use the per cpu buffer first */ -@@ -5958,6 +5958,44 @@ static int tracing_clock_open(struct ino +@@ -6287,6 +6287,44 @@ static int tracing_clock_open(struct ino return ret; } @@ -118,7 +118,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> struct trace_iterator iter; --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h -@@ -265,6 +265,7 @@ struct trace_array { +@@ -271,6 +271,7 @@ struct trace_array { /* function tracing enabled */ int function_enabled; #endif @@ -126,7 +126,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> }; enum { -@@ -278,6 +279,8 @@ extern struct mutex trace_types_lock; +@@ -284,6 +285,8 @@ extern struct mutex trace_types_lock; extern int trace_array_get(struct trace_array *tr); extern void trace_array_put(struct trace_array *tr); diff --git a/patches/0006-sched-tracing-Update-trace_sched_pi_setprio.patch b/patches/0006-sched-tracing-Update-trace_sched_pi_setprio.patch deleted file mode 100644 index e1918397abb4..000000000000 --- a/patches/0006-sched-tracing-Update-trace_sched_pi_setprio.patch +++ /dev/null @@ -1,106 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Thu, 23 Mar 2017 15:56:12 +0100 -Subject: [PATCH 6/9] sched,tracing: Update trace_sched_pi_setprio() - -Pass the PI donor task, instead of a numerical priority. - -Numerical priorities are not sufficient to describe state ever since -SCHED_DEADLINE. - -Annotate all sched tracepoints that are currently broken; fixing them -will bork userspace. *hate*. - -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Reviewed-by: Steven Rostedt <rostedt@goodmis.org> -Cc: juri.lelli@arm.com -Cc: bigeasy@linutronix.de -Cc: xlpang@redhat.com -Cc: mathieu.desnoyers@efficios.com -Cc: jdesfossez@efficios.com -Cc: bristot@redhat.com -Link: http://lkml.kernel.org/r/20170323150216.353599881@infradead.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - include/trace/events/sched.h | 16 +++++++++------- - kernel/sched/core.c | 2 +- - 2 files changed, 10 insertions(+), 8 deletions(-) - ---- a/include/trace/events/sched.h -+++ b/include/trace/events/sched.h -@@ -70,7 +70,7 @@ DECLARE_EVENT_CLASS(sched_wakeup_templat - TP_fast_assign( - memcpy(__entry->comm, p->comm, TASK_COMM_LEN); - __entry->pid = p->pid; -- __entry->prio = p->prio; -+ __entry->prio = p->prio; /* XXX SCHED_DEADLINE */ - __entry->success = 1; /* rudiment, kill when possible */ - __entry->target_cpu = task_cpu(p); - ), -@@ -147,6 +147,7 @@ TRACE_EVENT(sched_switch, - memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN); - __entry->next_pid = next->pid; - __entry->next_prio = next->prio; -+ /* XXX SCHED_DEADLINE */ - ), - - TP_printk("prev_comm=%s prev_pid=%d prev_prio=%d prev_state=%s%s ==> next_comm=%s next_pid=%d next_prio=%d", -@@ -181,7 +182,7 @@ TRACE_EVENT(sched_migrate_task, - TP_fast_assign( - memcpy(__entry->comm, p->comm, TASK_COMM_LEN); - __entry->pid = p->pid; -- __entry->prio = p->prio; -+ __entry->prio = p->prio; /* XXX SCHED_DEADLINE */ - __entry->orig_cpu = task_cpu(p); - __entry->dest_cpu = dest_cpu; - ), -@@ -206,7 +207,7 @@ DECLARE_EVENT_CLASS(sched_process_templa - TP_fast_assign( - memcpy(__entry->comm, p->comm, TASK_COMM_LEN); - __entry->pid = p->pid; -- __entry->prio = p->prio; -+ __entry->prio = p->prio; /* XXX SCHED_DEADLINE */ - ), - - TP_printk("comm=%s pid=%d prio=%d", -@@ -253,7 +254,7 @@ TRACE_EVENT(sched_process_wait, - TP_fast_assign( - memcpy(__entry->comm, current->comm, TASK_COMM_LEN); - __entry->pid = pid_nr(pid); -- __entry->prio = current->prio; -+ __entry->prio = current->prio; /* XXX SCHED_DEADLINE */ - ), - - TP_printk("comm=%s pid=%d prio=%d", -@@ -413,9 +414,9 @@ DEFINE_EVENT(sched_stat_runtime, sched_s - */ - TRACE_EVENT(sched_pi_setprio, - -- TP_PROTO(struct task_struct *tsk, int newprio), -+ TP_PROTO(struct task_struct *tsk, struct task_struct *pi_task), - -- TP_ARGS(tsk, newprio), -+ TP_ARGS(tsk, pi_task), - - TP_STRUCT__entry( - __array( char, comm, TASK_COMM_LEN ) -@@ -428,7 +429,8 @@ TRACE_EVENT(sched_pi_setprio, - memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN); - __entry->pid = tsk->pid; - __entry->oldprio = tsk->prio; -- __entry->newprio = newprio; -+ __entry->newprio = pi_task ? pi_task->prio : tsk->prio; -+ /* XXX SCHED_DEADLINE bits missing */ - ), - - TP_printk("comm=%s pid=%d oldprio=%d newprio=%d", ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -3751,7 +3751,7 @@ void rt_mutex_setprio(struct task_struct - goto out_unlock; - } - -- trace_sched_pi_setprio(p, prio); /* broken */ -+ trace_sched_pi_setprio(p, pi_task); - oldprio = p->prio; - - if (oldprio == prio) diff --git a/patches/0006-sparc-sysfs-Replace-racy-task-affinity-logic.patch b/patches/0006-sparc-sysfs-Replace-racy-task-affinity-logic.patch deleted file mode 100644 index af399790e7cc..000000000000 --- a/patches/0006-sparc-sysfs-Replace-racy-task-affinity-logic.patch +++ /dev/null @@ -1,117 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Thu, 13 Apr 2017 10:17:07 +0200 -Subject: [PATCH 06/13] sparc/sysfs: Replace racy task affinity logic - -The mmustat_enable sysfs file accessor functions must run code on the -target CPU. This is achieved by temporarily setting the affinity of the -calling user space thread to the requested CPU and reset it to the original -affinity afterwards. - -That's racy vs. concurrent affinity settings for that thread resulting in -code executing on the wrong CPU and overwriting the new affinity setting. - -Replace it by using work_on_cpu() which guarantees to run the code on the -requested CPU. - -Protection against CPU hotplug is not required as the open sysfs file -already prevents the removal from the CPU offline callback. Using the -hotplug protected version would actually be wrong because it would deadlock -against a CPU hotplug operation of the CPU associated to the sysfs file in -progress. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: David S. Miller <davem@davemloft.net> -Cc: fenghua.yu@intel.com -Cc: tony.luck@intel.com -Cc: herbert@gondor.apana.org.au -Cc: rjw@rjwysocki.net -Cc: peterz@infradead.org -Cc: benh@kernel.crashing.org -Cc: bigeasy@linutronix.de -Cc: jiangshanlai@gmail.com -Cc: sparclinux@vger.kernel.org -Cc: viresh.kumar@linaro.org -Cc: mpe@ellerman.id.au -Cc: tj@kernel.org -Cc: lenb@kernel.org -Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1704131001270.2408@nanos -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - arch/sparc/kernel/sysfs.c | 39 +++++++++++---------------------------- - 1 file changed, 11 insertions(+), 28 deletions(-) - ---- a/arch/sparc/kernel/sysfs.c -+++ b/arch/sparc/kernel/sysfs.c -@@ -98,27 +98,7 @@ static struct attribute_group mmu_stat_g - .name = "mmu_stats", - }; - --/* XXX convert to rusty's on_one_cpu */ --static unsigned long run_on_cpu(unsigned long cpu, -- unsigned long (*func)(unsigned long), -- unsigned long arg) --{ -- cpumask_t old_affinity; -- unsigned long ret; -- -- cpumask_copy(&old_affinity, ¤t->cpus_allowed); -- /* should return -EINVAL to userspace */ -- if (set_cpus_allowed_ptr(current, cpumask_of(cpu))) -- return 0; -- -- ret = func(arg); -- -- set_cpus_allowed_ptr(current, &old_affinity); -- -- return ret; --} -- --static unsigned long read_mmustat_enable(unsigned long junk) -+static long read_mmustat_enable(void *data __maybe_unused) - { - unsigned long ra = 0; - -@@ -127,11 +107,11 @@ static unsigned long read_mmustat_enable - return ra != 0; - } - --static unsigned long write_mmustat_enable(unsigned long val) -+static long write_mmustat_enable(void *data) - { -- unsigned long ra, orig_ra; -+ unsigned long ra, orig_ra, *val = data; - -- if (val) -+ if (*val) - ra = __pa(&per_cpu(mmu_stats, smp_processor_id())); - else - ra = 0UL; -@@ -142,7 +122,8 @@ static unsigned long write_mmustat_enabl - static ssize_t show_mmustat_enable(struct device *s, - struct device_attribute *attr, char *buf) - { -- unsigned long val = run_on_cpu(s->id, read_mmustat_enable, 0); -+ long val = work_on_cpu(s->id, read_mmustat_enable, NULL); -+ - return sprintf(buf, "%lx\n", val); - } - -@@ -150,13 +131,15 @@ static ssize_t store_mmustat_enable(stru - struct device_attribute *attr, const char *buf, - size_t count) - { -- unsigned long val, err; -- int ret = sscanf(buf, "%lu", &val); -+ unsigned long val; -+ long err; -+ int ret; - -+ ret = sscanf(buf, "%lu", &val); - if (ret != 1) - return -EINVAL; - -- err = run_on_cpu(s->id, write_mmustat_enable, val); -+ err = work_on_cpu(s->id, write_mmustat_enable, &val); - if (err) - return -EIO; - diff --git a/patches/0007-ACPI-Adjust-system_state-check.patch b/patches/0007-ACPI-Adjust-system_state-check.patch deleted file mode 100644 index d9445d1e8199..000000000000 --- a/patches/0007-ACPI-Adjust-system_state-check.patch +++ /dev/null @@ -1,37 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Tue, 16 May 2017 20:42:38 +0200 -Subject: [PATCH 07/17] ACPI: Adjust system_state check - -To enable smp_processor_id() and might_sleep() debug checks earlier, it's -required to add system states between SYSTEM_BOOTING and SYSTEM_RUNNING. - -Make the decision whether a pci root is hotplugged depend on SYSTEM_RUNNING -instead of !SYSTEM_BOOTING. It makes no sense to cover states greater than -SYSTEM_RUNNING as there are not hotplug events on reboot and poweroff. - -Tested-by: Mark Rutland <mark.rutland@arm.com> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Reviewed-by: Steven Rostedt (VMware) <rostedt@goodmis.org> -Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Cc: Len Brown <lenb@kernel.org> -Cc: Linus Torvalds <torvalds@linux-foundation.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Rafael J. Wysocki <rjw@rjwysocki.net> -Link: http://lkml.kernel.org/r/20170516184735.446455652@linutronix.de -Signed-off-by: Ingo Molnar <mingo@kernel.org> ---- - drivers/acpi/pci_root.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/acpi/pci_root.c -+++ b/drivers/acpi/pci_root.c -@@ -523,7 +523,7 @@ static int acpi_pci_root_add(struct acpi - struct acpi_pci_root *root; - acpi_handle handle = device->handle; - int no_aspm = 0; -- bool hotadd = system_state != SYSTEM_BOOTING; -+ bool hotadd = system_state == SYSTEM_RUNNING; - - root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); - if (!root) diff --git a/patches/0007-ACPI-processor-Fix-error-handling-in-__acpi_processo.patch b/patches/0007-ACPI-processor-Fix-error-handling-in-__acpi_processo.patch deleted file mode 100644 index 01de1e487cfa..000000000000 --- a/patches/0007-ACPI-processor-Fix-error-handling-in-__acpi_processo.patch +++ /dev/null @@ -1,44 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 12 Apr 2017 22:07:33 +0200 -Subject: [PATCH 07/13] ACPI/processor: Fix error handling in - __acpi_processor_start() - -When acpi_install_notify_handler() fails the cooling device stays -registered and the sysfs files created via acpi_pss_perf_init() are -leaked and the function returns success. - -Undo acpi_pss_perf_init() and return a proper error code. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Cc: Fenghua Yu <fenghua.yu@intel.com> -Cc: Tony Luck <tony.luck@intel.com> -Cc: Herbert Xu <herbert@gondor.apana.org.au> -Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Lai Jiangshan <jiangshanlai@gmail.com> -Cc: linux-acpi@vger.kernel.org -Cc: Viresh Kumar <viresh.kumar@linaro.org> -Cc: Michael Ellerman <mpe@ellerman.id.au> -Cc: Tejun Heo <tj@kernel.org> -Cc: "David S. Miller" <davem@davemloft.net> -Cc: Len Brown <lenb@kernel.org> -Link: http://lkml.kernel.org/r/20170412201042.695499645@linutronix.de -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - drivers/acpi/processor_driver.c | 3 +++ - 1 file changed, 3 insertions(+) - ---- a/drivers/acpi/processor_driver.c -+++ b/drivers/acpi/processor_driver.c -@@ -251,6 +251,9 @@ static int __acpi_processor_start(struct - if (ACPI_SUCCESS(status)) - return 0; - -+ result = -ENODEV; -+ acpi_pss_perf_exit(pr, device); -+ - err_power_exit: - acpi_processor_power_exit(pr); - return result; diff --git a/patches/0007-futex-Rework-inconsistent-rt_mutex-futex_q-state.patch b/patches/0007-futex-Rework-inconsistent-rt_mutex-futex_q-state.patch deleted file mode 100644 index 9d764e763197..000000000000 --- a/patches/0007-futex-Rework-inconsistent-rt_mutex-futex_q-state.patch +++ /dev/null @@ -1,139 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Wed, 22 Mar 2017 11:35:54 +0100 -Subject: [PATCH] futex: Rework inconsistent rt_mutex/futex_q state - -Upstream commit 73d786bd043ebc855f349c81ea805f6b11cbf2aa - -There is a weird state in the futex_unlock_pi() path when it interleaves -with a concurrent futex_lock_pi() at the point where it drops hb->lock. - -In this case, it can happen that the rt_mutex wait_list and the futex_q -disagree on pending waiters, in particular rt_mutex will find no pending -waiters where futex_q thinks there are. In this case the rt_mutex unlock -code cannot assign an owner. - -The futex side fixup code has to cleanup the inconsistencies with quite a -bunch of interesting corner cases. - -Simplify all this by changing wake_futex_pi() to return -EAGAIN when this -situation occurs. This then gives the futex_lock_pi() code the opportunity -to continue and the retried futex_unlock_pi() will now observe a coherent -state. - -The only problem is that this breaks RT timeliness guarantees. That -is, consider the following scenario: - - T1 and T2 are both pinned to CPU0. prio(T2) > prio(T1) - - CPU0 - - T1 - lock_pi() - queue_me() <- Waiter is visible - - preemption - - T2 - unlock_pi() - loops with -EAGAIN forever - -Which is undesirable for PI primitives. Future patches will rectify -this. - -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: juri.lelli@arm.com -Cc: bigeasy@linutronix.de -Cc: xlpang@redhat.com -Cc: rostedt@goodmis.org -Cc: mathieu.desnoyers@efficios.com -Cc: jdesfossez@efficios.com -Cc: dvhart@infradead.org -Cc: bristot@redhat.com -Link: http://lkml.kernel.org/r/20170322104151.850383690@infradead.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/futex.c | 50 ++++++++++++++------------------------------------ - 1 file changed, 14 insertions(+), 36 deletions(-) - ---- a/kernel/futex.c -+++ b/kernel/futex.c -@@ -1404,12 +1404,19 @@ static int wake_futex_pi(u32 __user *uad - new_owner = rt_mutex_next_owner(&pi_state->pi_mutex); - - /* -- * It is possible that the next waiter (the one that brought -- * top_waiter owner to the kernel) timed out and is no longer -- * waiting on the lock. -+ * When we interleave with futex_lock_pi() where it does -+ * rt_mutex_timed_futex_lock(), we might observe @this futex_q waiter, -+ * but the rt_mutex's wait_list can be empty (either still, or again, -+ * depending on which side we land). -+ * -+ * When this happens, give up our locks and try again, giving the -+ * futex_lock_pi() instance time to complete, either by waiting on the -+ * rtmutex or removing itself from the futex queue. - */ -- if (!new_owner) -- new_owner = top_waiter->task; -+ if (!new_owner) { -+ raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); -+ return -EAGAIN; -+ } - - /* - * We pass it to the next owner. The WAITERS bit is always -@@ -2332,7 +2339,6 @@ static long futex_wait_restart(struct re - */ - static int fixup_owner(u32 __user *uaddr, struct futex_q *q, int locked) - { -- struct task_struct *owner; - int ret = 0; - - if (locked) { -@@ -2346,43 +2352,15 @@ static int fixup_owner(u32 __user *uaddr - } - - /* -- * Catch the rare case, where the lock was released when we were on the -- * way back before we locked the hash bucket. -- */ -- if (q->pi_state->owner == current) { -- /* -- * Try to get the rt_mutex now. This might fail as some other -- * task acquired the rt_mutex after we removed ourself from the -- * rt_mutex waiters list. -- */ -- if (rt_mutex_futex_trylock(&q->pi_state->pi_mutex)) { -- locked = 1; -- goto out; -- } -- -- /* -- * pi_state is incorrect, some other task did a lock steal and -- * we returned due to timeout or signal without taking the -- * rt_mutex. Too late. -- */ -- raw_spin_lock_irq(&q->pi_state->pi_mutex.wait_lock); -- owner = rt_mutex_owner(&q->pi_state->pi_mutex); -- if (!owner) -- owner = rt_mutex_next_owner(&q->pi_state->pi_mutex); -- raw_spin_unlock_irq(&q->pi_state->pi_mutex.wait_lock); -- ret = fixup_pi_state_owner(uaddr, q, owner); -- goto out; -- } -- -- /* - * Paranoia check. If we did not take the lock, then we should not be - * the owner of the rt_mutex. - */ -- if (rt_mutex_owner(&q->pi_state->pi_mutex) == current) -+ if (rt_mutex_owner(&q->pi_state->pi_mutex) == current) { - printk(KERN_ERR "fixup_owner: ret = %d pi-mutex: %p " - "pi-state %p\n", ret, - q->pi_state->pi_mutex.owner, - q->pi_state->owner); -+ } - - out: - return ret ? ret : locked; diff --git a/patches/0007-hrtimer-Reduce-conditional-code-hres_active.patch b/patches/0007-hrtimer-Reduce-conditional-code-hres_active.patch index ca9ba2ce52c9..4eb2fb772577 100644 --- a/patches/0007-hrtimer-Reduce-conditional-code-hres_active.patch +++ b/patches/0007-hrtimer-Reduce-conditional-code-hres_active.patch @@ -66,7 +66,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #endif --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -504,6 +504,19 @@ static inline ktime_t hrtimer_update_bas +@@ -505,6 +505,19 @@ static inline ktime_t hrtimer_update_bas offs_real, offs_boot, offs_tai); } @@ -86,7 +86,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* High resolution timer related functions */ #ifdef CONFIG_HIGH_RES_TIMERS -@@ -533,19 +546,6 @@ static inline int hrtimer_is_hres_enable +@@ -534,19 +547,6 @@ static inline int hrtimer_is_hres_enable } /* @@ -106,7 +106,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * Reprogram the event source with checking both queues for the * next event * Called with interrupts disabled and base->lock held -@@ -653,7 +653,6 @@ static void hrtimer_reprogram(struct hrt +@@ -654,7 +654,6 @@ static void hrtimer_reprogram(struct hrt static inline void hrtimer_init_hres(struct hrtimer_cpu_base *base) { base->expires_next = KTIME_MAX; @@ -114,7 +114,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } /* -@@ -712,8 +711,6 @@ void clock_was_set_delayed(void) +@@ -713,8 +712,6 @@ void clock_was_set_delayed(void) #else @@ -123,7 +123,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static inline int hrtimer_is_hres_enabled(void) { return 0; } static inline void hrtimer_switch_to_hres(void) { } static inline void -@@ -1572,6 +1569,7 @@ int hrtimers_prepare_cpu(unsigned int cp +@@ -1592,6 +1589,7 @@ int hrtimers_prepare_cpu(unsigned int cp } cpu_base->cpu = cpu; diff --git a/patches/0007-padata-Avoid-nested-calls-to-cpus_read_lock-in-pcryp.patch b/patches/0007-padata-Avoid-nested-calls-to-cpus_read_lock-in-pcryp.patch deleted file mode 100644 index 71e99d636fc5..000000000000 --- a/patches/0007-padata-Avoid-nested-calls-to-cpus_read_lock-in-pcryp.patch +++ /dev/null @@ -1,89 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Wed, 24 May 2017 10:15:18 +0200 -Subject: [PATCH 07/32] padata: Avoid nested calls to cpus_read_lock() in - pcrypt_init_padata() - -pcrypt_init_padata() - cpus_read_lock() - padata_alloc_possible() - padata_alloc() - cpus_read_lock() - -The nested call to cpus_read_lock() works with the current implementation, -but prevents the conversion to a percpu rwsem. - -The other caller of padata_alloc_possible() is pcrypt_init_padata() which -calls from a cpus_read_lock() protected region as well. - -Remove the cpus_read_lock() call in padata_alloc() and document the -calling convention. - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Tested-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Acked-by: Ingo Molnar <mingo@kernel.org> -Cc: Steffen Klassert <steffen.klassert@secunet.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: linux-crypto@vger.kernel.org -Link: http://lkml.kernel.org/r/20170524081547.571278910@linutronix.de ---- - kernel/padata.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - ---- a/kernel/padata.c -+++ b/kernel/padata.c -@@ -945,6 +945,8 @@ static struct kobj_type padata_attr_type - * @wq: workqueue to use for the allocated padata instance - * @pcpumask: cpumask that will be used for padata parallelization - * @cbcpumask: cpumask that will be used for padata serialization -+ * -+ * Must be called from a cpus_read_lock() protected region - */ - static struct padata_instance *padata_alloc(struct workqueue_struct *wq, - const struct cpumask *pcpumask, -@@ -957,7 +959,6 @@ static struct padata_instance *padata_al - if (!pinst) - goto err; - -- get_online_cpus(); - if (!alloc_cpumask_var(&pinst->cpumask.pcpu, GFP_KERNEL)) - goto err_free_inst; - if (!alloc_cpumask_var(&pinst->cpumask.cbcpu, GFP_KERNEL)) { -@@ -981,14 +982,12 @@ static struct padata_instance *padata_al - - pinst->flags = 0; - -- put_online_cpus(); -- - BLOCKING_INIT_NOTIFIER_HEAD(&pinst->cpumask_change_notifier); - kobject_init(&pinst->kobj, &padata_attr_type); - mutex_init(&pinst->lock); - - #ifdef CONFIG_HOTPLUG_CPU -- cpuhp_state_add_instance_nocalls(hp_online, &pinst->node); -+ cpuhp_state_add_instance_nocalls_cpuslocked(hp_online, &pinst->node); - #endif - return pinst; - -@@ -997,7 +996,6 @@ static struct padata_instance *padata_al - free_cpumask_var(pinst->cpumask.cbcpu); - err_free_inst: - kfree(pinst); -- put_online_cpus(); - err: - return NULL; - } -@@ -1008,9 +1006,12 @@ static struct padata_instance *padata_al - * parallel workers. - * - * @wq: workqueue to use for the allocated padata instance -+ * -+ * Must be called from a cpus_read_lock() protected region - */ - struct padata_instance *padata_alloc_possible(struct workqueue_struct *wq) - { -+ lockdep_assert_cpus_held(); - return padata_alloc(wq, cpu_possible_mask, cpu_possible_mask); - } - EXPORT_SYMBOL(padata_alloc_possible); diff --git a/patches/0007-rtmutex-Fix-PI-chain-order-integrity.patch b/patches/0007-rtmutex-Fix-PI-chain-order-integrity.patch deleted file mode 100644 index 62ae9e900947..000000000000 --- a/patches/0007-rtmutex-Fix-PI-chain-order-integrity.patch +++ /dev/null @@ -1,119 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Thu, 23 Mar 2017 15:56:13 +0100 -Subject: [PATCH 7/9] rtmutex: Fix PI chain order integrity - -rt_mutex_waiter::prio is a copy of task_struct::prio which is updated -during the PI chain walk, such that the PI chain order isn't messed up -by (asynchronous) task state updates. - -Currently rt_mutex_waiter_less() uses task state for deadline tasks; -this is broken, since the task state can, as said above, change -asynchronously, causing the RB tree order to change without actual -tree update -> FAIL. - -Fix this by also copying the deadline into the rt_mutex_waiter state -and updating it along with its prio field. - -Ideally we would also force PI chain updates whenever DL tasks update -their deadline parameter, but for first approximation this is less -broken than it was. - -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: juri.lelli@arm.com -Cc: bigeasy@linutronix.de -Cc: xlpang@redhat.com -Cc: rostedt@goodmis.org -Cc: mathieu.desnoyers@efficios.com -Cc: jdesfossez@efficios.com -Cc: bristot@redhat.com -Link: http://lkml.kernel.org/r/20170323150216.403992539@infradead.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - kernel/locking/rtmutex.c | 29 +++++++++++++++++++++++++++-- - kernel/locking/rtmutex_common.h | 1 + - 2 files changed, 28 insertions(+), 2 deletions(-) - ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -238,8 +238,7 @@ rt_mutex_waiter_less(struct rt_mutex_wai - * then right waiter has a dl_prio() too. - */ - if (dl_prio(left->prio)) -- return dl_time_before(left->task->dl.deadline, -- right->task->dl.deadline); -+ return dl_time_before(left->deadline, right->deadline); - - return 0; - } -@@ -650,7 +649,26 @@ static int rt_mutex_adjust_prio_chain(st - - /* [7] Requeue the waiter in the lock waiter tree. */ - rt_mutex_dequeue(lock, waiter); -+ -+ /* -+ * Update the waiter prio fields now that we're dequeued. -+ * -+ * These values can have changed through either: -+ * -+ * sys_sched_set_scheduler() / sys_sched_setattr() -+ * -+ * or -+ * -+ * DL CBS enforcement advancing the effective deadline. -+ * -+ * Even though pi_waiters also uses these fields, and that tree is only -+ * updated in [11], we can do this here, since we hold [L], which -+ * serializes all pi_waiters access and rb_erase() does not care about -+ * the values of the node being removed. -+ */ - waiter->prio = task->prio; -+ waiter->deadline = task->dl.deadline; -+ - rt_mutex_enqueue(lock, waiter); - - /* [8] Release the task */ -@@ -777,6 +795,8 @@ static int rt_mutex_adjust_prio_chain(st - static int try_to_take_rt_mutex(struct rt_mutex *lock, struct task_struct *task, - struct rt_mutex_waiter *waiter) - { -+ lockdep_assert_held(&lock->wait_lock); -+ - /* - * Before testing whether we can acquire @lock, we set the - * RT_MUTEX_HAS_WAITERS bit in @lock->owner. This forces all -@@ -902,6 +922,8 @@ static int task_blocks_on_rt_mutex(struc - struct rt_mutex *next_lock; - int chain_walk = 0, res; - -+ lockdep_assert_held(&lock->wait_lock); -+ - /* - * Early deadlock detection. We really don't want the task to - * enqueue on itself just to untangle the mess later. It's not -@@ -919,6 +941,7 @@ static int task_blocks_on_rt_mutex(struc - waiter->task = task; - waiter->lock = lock; - waiter->prio = task->prio; -+ waiter->deadline = task->dl.deadline; - - /* Get the top priority waiter on the lock */ - if (rt_mutex_has_waiters(lock)) -@@ -1036,6 +1059,8 @@ static void remove_waiter(struct rt_mute - struct task_struct *owner = rt_mutex_owner(lock); - struct rt_mutex *next_lock; - -+ lockdep_assert_held(&lock->wait_lock); -+ - raw_spin_lock(¤t->pi_lock); - rt_mutex_dequeue(lock, waiter); - current->pi_blocked_on = NULL; ---- a/kernel/locking/rtmutex_common.h -+++ b/kernel/locking/rtmutex_common.h -@@ -34,6 +34,7 @@ struct rt_mutex_waiter { - struct rt_mutex *deadlock_lock; - #endif - int prio; -+ u64 deadline; - }; - - /* diff --git a/patches/0007-tracing-Apply-absolute-timestamps-to-instance-max-bu.patch b/patches/0007-tracing-Apply-absolute-timestamps-to-instance-max-bu.patch deleted file mode 100644 index cca73e93a23d..000000000000 --- a/patches/0007-tracing-Apply-absolute-timestamps-to-instance-max-bu.patch +++ /dev/null @@ -1,41 +0,0 @@ -From: Baohong Liu <baohong.liu@intel.com> -Date: Tue, 5 Sep 2017 16:57:19 -0500 -Subject: [PATCH 07/40] tracing: Apply absolute timestamps to instance max - buffer - -Currently absolute timestamps are applied to both regular and max -buffers only for global trace. For instance trace, absolute -timestamps are applied only to regular buffer. But, regular and max -buffers can be swapped, for example, following a snapshot. So, for -instance trace, bad timestamps can be seen following a snapshot. -Let's apply absolute timestamps to instance max buffer as well. - -Similarly, buffer clock change is applied to instance max buffer -as well. - -Signed-off-by: Baohong Liu <baohong.liu@intel.com> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/trace/trace.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/kernel/trace/trace.c -+++ b/kernel/trace/trace.c -@@ -5903,7 +5903,7 @@ static int tracing_set_clock(struct trac - tracing_reset_online_cpus(&tr->trace_buffer); - - #ifdef CONFIG_TRACER_MAX_TRACE -- if (tr->flags & TRACE_ARRAY_FL_GLOBAL && tr->max_buffer.buffer) -+ if (tr->max_buffer.buffer) - ring_buffer_set_clock(tr->max_buffer.buffer, trace_clocks[i].func); - tracing_reset_online_cpus(&tr->max_buffer); - #endif -@@ -5987,7 +5987,7 @@ int tracing_set_time_stamp_abs(struct tr - tracing_reset_online_cpus(&tr->trace_buffer); - - #ifdef CONFIG_TRACER_MAX_TRACE -- if (tr->flags & TRACE_ARRAY_FL_GLOBAL && tr->max_buffer.buffer) -+ if (tr->max_buffer.buffer) - ring_buffer_set_time_stamp_abs(tr->max_buffer.buffer, abs); - tracing_reset_online_cpus(&tr->max_buffer); - #endif diff --git a/patches/0008-ACPI-processor-Replace-racy-task-affinity-logic.patch b/patches/0008-ACPI-processor-Replace-racy-task-affinity-logic.patch deleted file mode 100644 index 485477ee3f7d..000000000000 --- a/patches/0008-ACPI-processor-Replace-racy-task-affinity-logic.patch +++ /dev/null @@ -1,192 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 12 Apr 2017 22:07:34 +0200 -Subject: [PATCH 08/13] ACPI/processor: Replace racy task affinity logic - -acpi_processor_get_throttling() requires to invoke the getter function on -the target CPU. This is achieved by temporarily setting the affinity of the -calling user space thread to the requested CPU and reset it to the original -affinity afterwards. - -That's racy vs. CPU hotplug and concurrent affinity settings for that -thread resulting in code executing on the wrong CPU and overwriting the -new affinity setting. - -acpi_processor_get_throttling() is invoked in two ways: - -1) The CPU online callback, which is already running on the target CPU and - obviously protected against hotplug and not affected by affinity - settings. - -2) The ACPI driver probe function, which is not protected against hotplug - during modprobe. - -Switch it over to work_on_cpu() and protect the probe function against CPU -hotplug. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Cc: Fenghua Yu <fenghua.yu@intel.com> -Cc: Tony Luck <tony.luck@intel.com> -Cc: Herbert Xu <herbert@gondor.apana.org.au> -Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Lai Jiangshan <jiangshanlai@gmail.com> -Cc: linux-acpi@vger.kernel.org -Cc: Viresh Kumar <viresh.kumar@linaro.org> -Cc: Michael Ellerman <mpe@ellerman.id.au> -Cc: Tejun Heo <tj@kernel.org> -Cc: "David S. Miller" <davem@davemloft.net> -Cc: Len Brown <lenb@kernel.org> -Link: http://lkml.kernel.org/r/20170412201042.785920903@linutronix.de -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - drivers/acpi/processor_driver.c | 7 +++- - drivers/acpi/processor_throttling.c | 62 ++++++++++++++++++++---------------- - 2 files changed, 42 insertions(+), 27 deletions(-) - ---- a/drivers/acpi/processor_driver.c -+++ b/drivers/acpi/processor_driver.c -@@ -262,11 +262,16 @@ static int __acpi_processor_start(struct - static int acpi_processor_start(struct device *dev) - { - struct acpi_device *device = ACPI_COMPANION(dev); -+ int ret; - - if (!device) - return -ENODEV; - -- return __acpi_processor_start(device); -+ /* Protect against concurrent CPU hotplug operations */ -+ get_online_cpus(); -+ ret = __acpi_processor_start(device); -+ put_online_cpus(); -+ return ret; - } - - static int acpi_processor_stop(struct device *dev) ---- a/drivers/acpi/processor_throttling.c -+++ b/drivers/acpi/processor_throttling.c -@@ -62,8 +62,8 @@ struct acpi_processor_throttling_arg { - #define THROTTLING_POSTCHANGE (2) - - static int acpi_processor_get_throttling(struct acpi_processor *pr); --int acpi_processor_set_throttling(struct acpi_processor *pr, -- int state, bool force); -+static int __acpi_processor_set_throttling(struct acpi_processor *pr, -+ int state, bool force, bool direct); - - static int acpi_processor_update_tsd_coord(void) - { -@@ -891,7 +891,8 @@ static int acpi_processor_get_throttling - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Invalid throttling state, reset\n")); - state = 0; -- ret = acpi_processor_set_throttling(pr, state, true); -+ ret = __acpi_processor_set_throttling(pr, state, true, -+ true); - if (ret) - return ret; - } -@@ -901,36 +902,31 @@ static int acpi_processor_get_throttling - return 0; - } - --static int acpi_processor_get_throttling(struct acpi_processor *pr) -+static long __acpi_processor_get_throttling(void *data) - { -- cpumask_var_t saved_mask; -- int ret; -+ struct acpi_processor *pr = data; -+ -+ return pr->throttling.acpi_processor_get_throttling(pr); -+} - -+static int acpi_processor_get_throttling(struct acpi_processor *pr) -+{ - if (!pr) - return -EINVAL; - - if (!pr->flags.throttling) - return -ENODEV; - -- if (!alloc_cpumask_var(&saved_mask, GFP_KERNEL)) -- return -ENOMEM; -- - /* -- * Migrate task to the cpu pointed by pr. -+ * This is either called from the CPU hotplug callback of -+ * processor_driver or via the ACPI probe function. In the latter -+ * case the CPU is not guaranteed to be online. Both call sites are -+ * protected against CPU hotplug. - */ -- cpumask_copy(saved_mask, ¤t->cpus_allowed); -- /* FIXME: use work_on_cpu() */ -- if (set_cpus_allowed_ptr(current, cpumask_of(pr->id))) { -- /* Can't migrate to the target pr->id CPU. Exit */ -- free_cpumask_var(saved_mask); -+ if (!cpu_online(pr->id)) - return -ENODEV; -- } -- ret = pr->throttling.acpi_processor_get_throttling(pr); -- /* restore the previous state */ -- set_cpus_allowed_ptr(current, saved_mask); -- free_cpumask_var(saved_mask); - -- return ret; -+ return work_on_cpu(pr->id, __acpi_processor_get_throttling, pr); - } - - static int acpi_processor_get_fadt_info(struct acpi_processor *pr) -@@ -1080,8 +1076,15 @@ static long acpi_processor_throttling_fn - arg->target_state, arg->force); - } - --int acpi_processor_set_throttling(struct acpi_processor *pr, -- int state, bool force) -+static int call_on_cpu(int cpu, long (*fn)(void *), void *arg, bool direct) -+{ -+ if (direct) -+ return fn(arg); -+ return work_on_cpu(cpu, fn, arg); -+} -+ -+static int __acpi_processor_set_throttling(struct acpi_processor *pr, -+ int state, bool force, bool direct) - { - int ret = 0; - unsigned int i; -@@ -1130,7 +1133,8 @@ int acpi_processor_set_throttling(struct - arg.pr = pr; - arg.target_state = state; - arg.force = force; -- ret = work_on_cpu(pr->id, acpi_processor_throttling_fn, &arg); -+ ret = call_on_cpu(pr->id, acpi_processor_throttling_fn, &arg, -+ direct); - } else { - /* - * When the T-state coordination is SW_ALL or HW_ALL, -@@ -1163,8 +1167,8 @@ int acpi_processor_set_throttling(struct - arg.pr = match_pr; - arg.target_state = state; - arg.force = force; -- ret = work_on_cpu(pr->id, acpi_processor_throttling_fn, -- &arg); -+ ret = call_on_cpu(pr->id, acpi_processor_throttling_fn, -+ &arg, direct); - } - } - /* -@@ -1182,6 +1186,12 @@ int acpi_processor_set_throttling(struct - return ret; - } - -+int acpi_processor_set_throttling(struct acpi_processor *pr, int state, -+ bool force) -+{ -+ return __acpi_processor_set_throttling(pr, state, force, false); -+} -+ - int acpi_processor_get_throttling_info(struct acpi_processor *pr) - { - int result = 0; diff --git a/patches/0008-futex-Pull-rt_mutex_futex_unlock-out-from-under-hb-l.patch b/patches/0008-futex-Pull-rt_mutex_futex_unlock-out-from-under-hb-l.patch deleted file mode 100644 index aba723367584..000000000000 --- a/patches/0008-futex-Pull-rt_mutex_futex_unlock-out-from-under-hb-l.patch +++ /dev/null @@ -1,357 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Wed, 22 Mar 2017 11:35:55 +0100 -Subject: [PATCH] futex: Pull rt_mutex_futex_unlock() out from under hb->lock - -Upstream commit 16ffa12d742534d4ff73e8b3a4e81c1de39196f0 - -There's a number of 'interesting' problems, all caused by holding -hb->lock while doing the rt_mutex_unlock() equivalient. - -Notably: - - - a PI inversion on hb->lock; and, - - - a SCHED_DEADLINE crash because of pointer instability. - -The previous changes: - - - changed the locking rules to cover {uval,pi_state} with wait_lock. - - - allow to do rt_mutex_futex_unlock() without dropping wait_lock; which in - turn allows to rely on wait_lock atomicity completely. - - - simplified the waiter conundrum. - -It's now sufficient to hold rtmutex::wait_lock and a reference on the -pi_state to protect the state consistency, so hb->lock can be dropped -before calling rt_mutex_futex_unlock(). - -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: juri.lelli@arm.com -Cc: bigeasy@linutronix.de -Cc: xlpang@redhat.com -Cc: rostedt@goodmis.org -Cc: mathieu.desnoyers@efficios.com -Cc: jdesfossez@efficios.com -Cc: dvhart@infradead.org -Cc: bristot@redhat.com -Link: http://lkml.kernel.org/r/20170322104151.900002056@infradead.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/futex.c | 154 +++++++++++++++++++++++++++++++++++++-------------------- - 1 file changed, 100 insertions(+), 54 deletions(-) - ---- a/kernel/futex.c -+++ b/kernel/futex.c -@@ -921,10 +921,12 @@ void exit_pi_state_list(struct task_stru - pi_state->owner = NULL; - raw_spin_unlock_irq(&curr->pi_lock); - -- rt_mutex_futex_unlock(&pi_state->pi_mutex); -- -+ get_pi_state(pi_state); - spin_unlock(&hb->lock); - -+ rt_mutex_futex_unlock(&pi_state->pi_mutex); -+ put_pi_state(pi_state); -+ - raw_spin_lock_irq(&curr->pi_lock); - } - raw_spin_unlock_irq(&curr->pi_lock); -@@ -1037,6 +1039,11 @@ static int attach_to_pi_state(u32 __user - * has dropped the hb->lock in between queue_me() and unqueue_me_pi(), - * which in turn means that futex_lock_pi() still has a reference on - * our pi_state. -+ * -+ * The waiter holding a reference on @pi_state also protects against -+ * the unlocked put_pi_state() in futex_unlock_pi(), futex_lock_pi() -+ * and futex_wait_requeue_pi() as it cannot go to 0 and consequently -+ * free pi_state before we can take a reference ourselves. - */ - WARN_ON(!atomic_read(&pi_state->refcount)); - -@@ -1380,48 +1387,40 @@ static void mark_wake_futex(struct wake_ - smp_store_release(&q->lock_ptr, NULL); - } - --static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *top_waiter, -- struct futex_hash_bucket *hb) -+/* -+ * Caller must hold a reference on @pi_state. -+ */ -+static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_pi_state *pi_state) - { -- struct task_struct *new_owner; -- struct futex_pi_state *pi_state = top_waiter->pi_state; - u32 uninitialized_var(curval), newval; -+ struct task_struct *new_owner; -+ bool deboost = false; - DEFINE_WAKE_Q(wake_q); -- bool deboost; - int ret = 0; - -- if (!pi_state) -- return -EINVAL; -- -- /* -- * If current does not own the pi_state then the futex is -- * inconsistent and user space fiddled with the futex value. -- */ -- if (pi_state->owner != current) -- return -EINVAL; -- - raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock); - new_owner = rt_mutex_next_owner(&pi_state->pi_mutex); -- -- /* -- * When we interleave with futex_lock_pi() where it does -- * rt_mutex_timed_futex_lock(), we might observe @this futex_q waiter, -- * but the rt_mutex's wait_list can be empty (either still, or again, -- * depending on which side we land). -- * -- * When this happens, give up our locks and try again, giving the -- * futex_lock_pi() instance time to complete, either by waiting on the -- * rtmutex or removing itself from the futex queue. -- */ - if (!new_owner) { -- raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); -- return -EAGAIN; -+ /* -+ * Since we held neither hb->lock nor wait_lock when coming -+ * into this function, we could have raced with futex_lock_pi() -+ * such that we might observe @this futex_q waiter, but the -+ * rt_mutex's wait_list can be empty (either still, or again, -+ * depending on which side we land). -+ * -+ * When this happens, give up our locks and try again, giving -+ * the futex_lock_pi() instance time to complete, either by -+ * waiting on the rtmutex or removing itself from the futex -+ * queue. -+ */ -+ ret = -EAGAIN; -+ goto out_unlock; - } - - /* -- * We pass it to the next owner. The WAITERS bit is always -- * kept enabled while there is PI state around. We cleanup the -- * owner died bit, because we are the owner. -+ * We pass it to the next owner. The WAITERS bit is always kept -+ * enabled while there is PI state around. We cleanup the owner -+ * died bit, because we are the owner. - */ - newval = FUTEX_WAITERS | task_pid_vnr(new_owner); - -@@ -1444,10 +1443,8 @@ static int wake_futex_pi(u32 __user *uad - ret = -EINVAL; - } - -- if (ret) { -- raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); -- return ret; -- } -+ if (ret) -+ goto out_unlock; - - raw_spin_lock(&pi_state->owner->pi_lock); - WARN_ON(list_empty(&pi_state->list)); -@@ -1465,15 +1462,15 @@ static int wake_futex_pi(u32 __user *uad - */ - deboost = __rt_mutex_futex_unlock(&pi_state->pi_mutex, &wake_q); - -+out_unlock: - raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); -- spin_unlock(&hb->lock); - - if (deboost) { - wake_up_q(&wake_q); - rt_mutex_adjust_prio(current); - } - -- return 0; -+ return ret; - } - - /* -@@ -2232,7 +2229,8 @@ static int fixup_pi_state_owner(u32 __us - /* - * We are here either because we stole the rtmutex from the - * previous highest priority waiter or we are the highest priority -- * waiter but failed to get the rtmutex the first time. -+ * waiter but have failed to get the rtmutex the first time. -+ * - * We have to replace the newowner TID in the user space variable. - * This must be atomic as we have to preserve the owner died bit here. - * -@@ -2249,7 +2247,7 @@ static int fixup_pi_state_owner(u32 __us - if (get_futex_value_locked(&uval, uaddr)) - goto handle_fault; - -- while (1) { -+ for (;;) { - newval = (uval & FUTEX_OWNER_DIED) | newtid; - - if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval)) -@@ -2345,6 +2343,10 @@ static int fixup_owner(u32 __user *uaddr - /* - * Got the lock. We might not be the anticipated owner if we - * did a lock-steal - fix up the PI-state in that case: -+ * -+ * We can safely read pi_state->owner without holding wait_lock -+ * because we now own the rt_mutex, only the owner will attempt -+ * to change it. - */ - if (q->pi_state->owner != current) - ret = fixup_pi_state_owner(uaddr, q, current); -@@ -2584,6 +2586,7 @@ static int futex_lock_pi(u32 __user *uad - ktime_t *time, int trylock) - { - struct hrtimer_sleeper timeout, *to = NULL; -+ struct futex_pi_state *pi_state = NULL; - struct futex_hash_bucket *hb; - struct futex_q q = futex_q_init; - int res, ret; -@@ -2670,12 +2673,19 @@ static int futex_lock_pi(u32 __user *uad - * If fixup_owner() faulted and was unable to handle the fault, unlock - * it and return the fault to userspace. - */ -- if (ret && (rt_mutex_owner(&q.pi_state->pi_mutex) == current)) -- rt_mutex_futex_unlock(&q.pi_state->pi_mutex); -+ if (ret && (rt_mutex_owner(&q.pi_state->pi_mutex) == current)) { -+ pi_state = q.pi_state; -+ get_pi_state(pi_state); -+ } - - /* Unqueue and drop the lock */ - unqueue_me_pi(&q); - -+ if (pi_state) { -+ rt_mutex_futex_unlock(&pi_state->pi_mutex); -+ put_pi_state(pi_state); -+ } -+ - goto out_put_key; - - out_unlock_put_key: -@@ -2738,10 +2748,36 @@ static int futex_unlock_pi(u32 __user *u - */ - top_waiter = futex_top_waiter(hb, &key); - if (top_waiter) { -- ret = wake_futex_pi(uaddr, uval, top_waiter, hb); -+ struct futex_pi_state *pi_state = top_waiter->pi_state; -+ -+ ret = -EINVAL; -+ if (!pi_state) -+ goto out_unlock; -+ -+ /* -+ * If current does not own the pi_state then the futex is -+ * inconsistent and user space fiddled with the futex value. -+ */ -+ if (pi_state->owner != current) -+ goto out_unlock; -+ -+ /* -+ * Grab a reference on the pi_state and drop hb->lock. -+ * -+ * The reference ensures pi_state lives, dropping the hb->lock -+ * is tricky.. wake_futex_pi() will take rt_mutex::wait_lock to -+ * close the races against futex_lock_pi(), but in case of -+ * _any_ fail we'll abort and retry the whole deal. -+ */ -+ get_pi_state(pi_state); -+ spin_unlock(&hb->lock); -+ -+ ret = wake_futex_pi(uaddr, uval, pi_state); -+ -+ put_pi_state(pi_state); -+ - /* -- * In case of success wake_futex_pi dropped the hash -- * bucket lock. -+ * Success, we're done! No tricky corner cases. - */ - if (!ret) - goto out_putkey; -@@ -2756,7 +2792,6 @@ static int futex_unlock_pi(u32 __user *u - * setting the FUTEX_WAITERS bit. Try again. - */ - if (ret == -EAGAIN) { -- spin_unlock(&hb->lock); - put_futex_key(&key); - goto retry; - } -@@ -2764,7 +2799,7 @@ static int futex_unlock_pi(u32 __user *u - * wake_futex_pi has detected invalid state. Tell user - * space. - */ -- goto out_unlock; -+ goto out_putkey; - } - - /* -@@ -2774,8 +2809,10 @@ static int futex_unlock_pi(u32 __user *u - * preserve the WAITERS bit not the OWNER_DIED one. We are the - * owner. - */ -- if (cmpxchg_futex_value_locked(&curval, uaddr, uval, 0)) -+ if (cmpxchg_futex_value_locked(&curval, uaddr, uval, 0)) { -+ spin_unlock(&hb->lock); - goto pi_faulted; -+ } - - /* - * If uval has changed, let user space handle it. -@@ -2789,7 +2826,6 @@ static int futex_unlock_pi(u32 __user *u - return ret; - - pi_faulted: -- spin_unlock(&hb->lock); - put_futex_key(&key); - - ret = fault_in_user_writeable(uaddr); -@@ -2893,6 +2929,7 @@ static int futex_wait_requeue_pi(u32 __u - u32 __user *uaddr2) - { - struct hrtimer_sleeper timeout, *to = NULL; -+ struct futex_pi_state *pi_state = NULL; - struct rt_mutex_waiter rt_waiter; - struct futex_hash_bucket *hb; - union futex_key key2 = FUTEX_KEY_INIT; -@@ -2977,8 +3014,10 @@ static int futex_wait_requeue_pi(u32 __u - if (q.pi_state && (q.pi_state->owner != current)) { - spin_lock(q.lock_ptr); - ret = fixup_pi_state_owner(uaddr2, &q, current); -- if (ret && rt_mutex_owner(&q.pi_state->pi_mutex) == current) -- rt_mutex_futex_unlock(&q.pi_state->pi_mutex); -+ if (ret && rt_mutex_owner(&q.pi_state->pi_mutex) == current) { -+ pi_state = q.pi_state; -+ get_pi_state(pi_state); -+ } - /* - * Drop the reference to the pi state which - * the requeue_pi() code acquired for us. -@@ -3017,13 +3056,20 @@ static int futex_wait_requeue_pi(u32 __u - * the fault, unlock the rt_mutex and return the fault to - * userspace. - */ -- if (ret && rt_mutex_owner(pi_mutex) == current) -- rt_mutex_futex_unlock(pi_mutex); -+ if (ret && rt_mutex_owner(&q.pi_state->pi_mutex) == current) { -+ pi_state = q.pi_state; -+ get_pi_state(pi_state); -+ } - - /* Unqueue and drop the lock. */ - unqueue_me_pi(&q); - } - -+ if (pi_state) { -+ rt_mutex_futex_unlock(&pi_state->pi_mutex); -+ put_pi_state(pi_state); -+ } -+ - if (ret == -EINTR) { - /* - * We've already been requeued, but cannot restart by calling diff --git a/patches/0008-hrtimer-Reduce-conditional-code-expires_next-next_ti.patch b/patches/0008-hrtimer-Reduce-conditional-code-expires_next-next_ti.patch index ed2a839925cb..07a336bf833a 100644 --- a/patches/0008-hrtimer-Reduce-conditional-code-expires_next-next_ti.patch +++ b/patches/0008-hrtimer-Reduce-conditional-code-expires_next-next_ti.patch @@ -53,7 +53,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -153,16 +153,16 @@ struct hrtimer_clock_base *lock_hrtimer_ +@@ -154,16 +154,16 @@ struct hrtimer_clock_base *lock_hrtimer_ } /* @@ -74,7 +74,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ktime_t expires; if (!new_base->cpu_base->hres_active) -@@ -170,9 +170,6 @@ hrtimer_check_target(struct hrtimer *tim +@@ -171,9 +171,6 @@ hrtimer_check_target(struct hrtimer *tim expires = ktime_sub(hrtimer_get_expires(timer), new_base->offset); return expires <= new_base->cpu_base->expires_next; @@ -84,7 +84,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } #ifdef CONFIG_NO_HZ_COMMON -@@ -455,9 +452,7 @@ static inline void debug_deactivate(stru +@@ -456,9 +453,7 @@ static inline void debug_deactivate(stru static inline void hrtimer_update_next_timer(struct hrtimer_cpu_base *cpu_base, struct hrtimer *timer) { @@ -94,7 +94,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } static ktime_t __hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base) -@@ -648,14 +643,6 @@ static void hrtimer_reprogram(struct hrt +@@ -649,14 +644,6 @@ static void hrtimer_reprogram(struct hrt } /* @@ -109,7 +109,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * Retrigger next event is called after clock was set * * Called with interrupts disabled via on_each_cpu() -@@ -720,7 +707,6 @@ static inline int hrtimer_reprogram(stru +@@ -721,7 +708,6 @@ static inline int hrtimer_reprogram(stru { return 0; } @@ -117,7 +117,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static inline void retrigger_next_event(void *arg) { } #endif /* CONFIG_HIGH_RES_TIMERS */ -@@ -1570,7 +1556,7 @@ int hrtimers_prepare_cpu(unsigned int cp +@@ -1590,7 +1576,7 @@ int hrtimers_prepare_cpu(unsigned int cp cpu_base->cpu = cpu; cpu_base->hres_active = 0; diff --git a/patches/0008-mm-Adjust-system_state-check.patch b/patches/0008-mm-Adjust-system_state-check.patch deleted file mode 100644 index 978c025e00a6..000000000000 --- a/patches/0008-mm-Adjust-system_state-check.patch +++ /dev/null @@ -1,41 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Tue, 16 May 2017 20:42:39 +0200 -Subject: [PATCH 08/17] mm: Adjust system_state check - -To enable smp_processor_id() and might_sleep() debug checks earlier, it's -required to add system states between SYSTEM_BOOTING and SYSTEM_RUNNING. - -get_nid_for_pfn() checks for system_state == BOOTING to decide whether to -use early_pfn_to_nid() when CONFIG_DEFERRED_STRUCT_PAGE_INIT=y. - -That check is dubious, because the switch to state RUNNING happes way after -page_alloc_init_late() has been invoked. - -Change the check to less than RUNNING state so it covers the new -intermediate states as well. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Cc: Linus Torvalds <torvalds@linux-foundation.org> -Cc: Mark Rutland <mark.rutland@arm.com> -Cc: Mel Gorman <mgorman@techsingularity.net> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Link: http://lkml.kernel.org/r/20170516184735.528279534@linutronix.de -Signed-off-by: Ingo Molnar <mingo@kernel.org> ---- - drivers/base/node.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/base/node.c -+++ b/drivers/base/node.c -@@ -377,7 +377,7 @@ static int __ref get_nid_for_pfn(unsigne - if (!pfn_valid_within(pfn)) - return -1; - #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT -- if (system_state == SYSTEM_BOOTING) -+ if (system_state < SYSTEM_RUNNING) - return early_pfn_to_nid(pfn); - #endif - page = pfn_to_page(pfn); diff --git a/patches/0008-ring-buffer-Redefine-the-unimplemented-RINGBUF_TIME_.patch b/patches/0008-ring-buffer-Redefine-the-unimplemented-RINGBUF_TIME_.patch index be733e52ae2c..7d334b4f3726 100644 --- a/patches/0008-ring-buffer-Redefine-the-unimplemented-RINGBUF_TIME_.patch +++ b/patches/0008-ring-buffer-Redefine-the-unimplemented-RINGBUF_TIME_.patch @@ -143,7 +143,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* Flag when events were overwritten */ #define RB_MISSED_EVENTS (1 << 31) /* Missed count stored at end */ -@@ -2219,13 +2245,16 @@ rb_move_tail(struct ring_buffer_per_cpu +@@ -2220,13 +2246,16 @@ rb_move_tail(struct ring_buffer_per_cpu } /* Slow path, do not inline */ @@ -165,7 +165,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> event->time_delta = delta & TS_MASK; event->array[0] = delta >> TS_SHIFT; } else { -@@ -2268,7 +2297,9 @@ rb_update_event(struct ring_buffer_per_c +@@ -2269,7 +2298,9 @@ rb_update_event(struct ring_buffer_per_c * add it to the start of the resevered space. */ if (unlikely(info->add_timestamp)) { @@ -176,7 +176,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> length -= RB_LEN_TIME_EXTEND; delta = 0; } -@@ -2456,7 +2487,7 @@ static __always_inline void rb_end_commi +@@ -2457,7 +2488,7 @@ static __always_inline void rb_end_commi static inline void rb_event_discard(struct ring_buffer_event *event) { @@ -185,7 +185,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> event = skip_time_extend(event); /* array[0] holds the actual length for the discarded event */ -@@ -2487,6 +2518,10 @@ rb_update_write_stamp(struct ring_buffer +@@ -2488,6 +2519,10 @@ rb_update_write_stamp(struct ring_buffer { u64 delta; @@ -196,7 +196,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * The event first in the commit queue updates the * time stamp. -@@ -2500,9 +2535,7 @@ rb_update_write_stamp(struct ring_buffer +@@ -2501,9 +2536,7 @@ rb_update_write_stamp(struct ring_buffer cpu_buffer->write_stamp = cpu_buffer->commit_page->page->time_stamp; else if (event->type_len == RINGBUF_TYPE_TIME_EXTEND) { @@ -207,7 +207,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> cpu_buffer->write_stamp += delta; } else cpu_buffer->write_stamp += event->time_delta; -@@ -2686,7 +2719,7 @@ static struct ring_buffer_event * +@@ -2687,7 +2720,7 @@ static struct ring_buffer_event * * If this is the first commit on the page, then it has the same * timestamp as the page itself. */ @@ -216,7 +216,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> info->delta = 0; /* See if we shot pass the end of this buffer page */ -@@ -2764,8 +2797,11 @@ rb_reserve_next_event(struct ring_buffer +@@ -2765,8 +2798,11 @@ rb_reserve_next_event(struct ring_buffer /* make sure this diff is calculated here */ barrier(); @@ -230,7 +230,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> info.delta = diff; if (unlikely(test_time_stamp(info.delta))) rb_handle_timestamp(cpu_buffer, &info); -@@ -3447,14 +3483,12 @@ rb_update_read_stamp(struct ring_buffer_ +@@ -3448,14 +3484,12 @@ rb_update_read_stamp(struct ring_buffer_ return; case RINGBUF_TYPE_TIME_EXTEND: @@ -247,7 +247,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return; case RINGBUF_TYPE_DATA: -@@ -3478,14 +3512,12 @@ rb_update_iter_read_stamp(struct ring_bu +@@ -3479,14 +3513,12 @@ rb_update_iter_read_stamp(struct ring_bu return; case RINGBUF_TYPE_TIME_EXTEND: @@ -264,7 +264,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return; case RINGBUF_TYPE_DATA: -@@ -3709,6 +3741,8 @@ rb_buffer_peek(struct ring_buffer_per_cp +@@ -3710,6 +3742,8 @@ rb_buffer_peek(struct ring_buffer_per_cp struct buffer_page *reader; int nr_loops = 0; @@ -273,7 +273,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> again: /* * We repeat when a time extend is encountered. -@@ -3745,12 +3779,17 @@ rb_buffer_peek(struct ring_buffer_per_cp +@@ -3746,12 +3780,17 @@ rb_buffer_peek(struct ring_buffer_per_cp goto again; case RINGBUF_TYPE_TIME_STAMP: @@ -293,7 +293,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> *ts = cpu_buffer->read_stamp + event->time_delta; ring_buffer_normalize_time_stamp(cpu_buffer->buffer, cpu_buffer->cpu, ts); -@@ -3775,6 +3814,9 @@ rb_iter_peek(struct ring_buffer_iter *it +@@ -3776,6 +3815,9 @@ rb_iter_peek(struct ring_buffer_iter *it struct ring_buffer_event *event; int nr_loops = 0; @@ -303,7 +303,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> cpu_buffer = iter->cpu_buffer; buffer = cpu_buffer->buffer; -@@ -3827,12 +3869,17 @@ rb_iter_peek(struct ring_buffer_iter *it +@@ -3828,12 +3870,17 @@ rb_iter_peek(struct ring_buffer_iter *it goto again; case RINGBUF_TYPE_TIME_STAMP: diff --git a/patches/0008-rtmutex-Fix-more-prio-comparisons.patch b/patches/0008-rtmutex-Fix-more-prio-comparisons.patch deleted file mode 100644 index e2ea32a6ce21..000000000000 --- a/patches/0008-rtmutex-Fix-more-prio-comparisons.patch +++ /dev/null @@ -1,99 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Thu, 23 Mar 2017 15:56:14 +0100 -Subject: [PATCH 8/9] rtmutex: Fix more prio comparisons - -There was a pure ->prio comparison left in try_to_wake_rt_mutex(), -convert it to use rt_mutex_waiter_less(), noting that greater-or-equal -is not-less (both in kernel priority view). - -This necessitated the introduction of cmp_task() which creates a -pointer to an unnamed stack variable of struct rt_mutex_waiter type to -compare against tasks. - -With this, we can now also create and employ rt_mutex_waiter_equal(). - -Reviewed-and-tested-by: Juri Lelli <juri.lelli@arm.com> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Reviewed-by: Thomas Gleixner <tglx@linutronix.de> -Cc: juri.lelli@arm.com -Cc: bigeasy@linutronix.de -Cc: xlpang@redhat.com -Cc: rostedt@goodmis.org -Cc: mathieu.desnoyers@efficios.com -Cc: jdesfossez@efficios.com -Cc: bristot@redhat.com -Link: http://lkml.kernel.org/r/20170323150216.455584638@infradead.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - kernel/locking/rtmutex.c | 32 +++++++++++++++++++++++++++++--- - 1 file changed, 29 insertions(+), 3 deletions(-) - ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -224,6 +224,12 @@ static inline bool unlock_rt_mutex_safe( - } - #endif - -+/* -+ * Only use with rt_mutex_waiter_{less,equal}() -+ */ -+#define task_to_waiter(p) \ -+ &(struct rt_mutex_waiter){ .prio = (p)->prio, .deadline = (p)->dl.deadline } -+ - static inline int - rt_mutex_waiter_less(struct rt_mutex_waiter *left, - struct rt_mutex_waiter *right) -@@ -243,6 +249,25 @@ rt_mutex_waiter_less(struct rt_mutex_wai - return 0; - } - -+static inline int -+rt_mutex_waiter_equal(struct rt_mutex_waiter *left, -+ struct rt_mutex_waiter *right) -+{ -+ if (left->prio != right->prio) -+ return 0; -+ -+ /* -+ * If both waiters have dl_prio(), we check the deadlines of the -+ * associated tasks. -+ * If left waiter has a dl_prio(), and we didn't return 0 above, -+ * then right waiter has a dl_prio() too. -+ */ -+ if (dl_prio(left->prio)) -+ return left->deadline == right->deadline; -+ -+ return 1; -+} -+ - static void - rt_mutex_enqueue(struct rt_mutex *lock, struct rt_mutex_waiter *waiter) - { -@@ -553,7 +578,7 @@ static int rt_mutex_adjust_prio_chain(st - * enabled we continue, but stop the requeueing in the chain - * walk. - */ -- if (waiter->prio == task->prio && !dl_task(task)) { -+ if (rt_mutex_waiter_equal(waiter, task_to_waiter(task))) { - if (!detect_deadlock) - goto out_unlock_pi; - else -@@ -856,7 +881,8 @@ static int try_to_take_rt_mutex(struct r - * the top waiter priority (kernel view), - * @task lost. - */ -- if (task->prio >= rt_mutex_top_waiter(lock)->prio) -+ if (!rt_mutex_waiter_less(task_to_waiter(task), -+ rt_mutex_top_waiter(lock))) - return 0; - - /* -@@ -1119,7 +1145,7 @@ void rt_mutex_adjust_pi(struct task_stru - raw_spin_lock_irqsave(&task->pi_lock, flags); - - waiter = task->pi_blocked_on; -- if (!waiter || (waiter->prio == task->prio && !dl_prio(task->prio))) { -+ if (!waiter || rt_mutex_waiter_equal(waiter, task_to_waiter(task))) { - raw_spin_unlock_irqrestore(&task->pi_lock, flags); - return; - } diff --git a/patches/0008-x86-mtrr-Remove-get_online_cpus-from-mtrr_save_state.patch b/patches/0008-x86-mtrr-Remove-get_online_cpus-from-mtrr_save_state.patch deleted file mode 100644 index a650f376b1af..000000000000 --- a/patches/0008-x86-mtrr-Remove-get_online_cpus-from-mtrr_save_state.patch +++ /dev/null @@ -1,38 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Wed, 24 May 2017 10:15:19 +0200 -Subject: [PATCH 08/32] x86/mtrr: Remove get_online_cpus() from - mtrr_save_state() - -mtrr_save_state() is invoked from native_cpu_up() which is in the context -of a CPU hotplug operation and therefor calling get_online_cpus() is -pointless. - -While this works in the current get_online_cpus() implementation it -prevents from converting the hotplug locking to percpu rwsems. - -Remove it. - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Tested-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Acked-by: Ingo Molnar <mingo@kernel.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Link: http://lkml.kernel.org/r/20170524081547.651378834@linutronix.de ---- - arch/x86/kernel/cpu/mtrr/main.c | 2 -- - 1 file changed, 2 deletions(-) - ---- a/arch/x86/kernel/cpu/mtrr/main.c -+++ b/arch/x86/kernel/cpu/mtrr/main.c -@@ -807,10 +807,8 @@ void mtrr_save_state(void) - if (!mtrr_enabled()) - return; - -- get_online_cpus(); - first_cpu = cpumask_first(cpu_online_mask); - smp_call_function_single(first_cpu, mtrr_save_fixed_ranges, NULL, 1); -- put_online_cpus(); - } - - void set_mtrr_aps_delayed_init(void) diff --git a/patches/0009-cpufreq-Use-cpuhp_setup_state_nocalls_cpuslocked.patch b/patches/0009-cpufreq-Use-cpuhp_setup_state_nocalls_cpuslocked.patch deleted file mode 100644 index 3cdf80c77398..000000000000 --- a/patches/0009-cpufreq-Use-cpuhp_setup_state_nocalls_cpuslocked.patch +++ /dev/null @@ -1,102 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Wed, 24 May 2017 10:15:20 +0200 -Subject: [PATCH 09/32] cpufreq: Use cpuhp_setup_state_nocalls_cpuslocked() - -cpufreq holds get_online_cpus() while invoking cpuhp_setup_state_nocalls() -to make subsys_interface_register() and the registration of hotplug calls -atomic versus cpu hotplug. - -cpuhp_setup_state_nocalls() invokes get_online_cpus() as well. This is -correct, but prevents the conversion of the hotplug locking to a percpu -rwsem. - -Use cpuhp_setup/remove_state_nocalls_cpuslocked() to avoid the nested -call. Convert *_online_cpus() to the new interfaces while at it. - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Tested-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Acked-by: Ingo Molnar <mingo@kernel.org> -Acked-by: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> -Acked-by: Viresh Kumar <viresh.kumar@linaro.org> -Cc: linux-pm@vger.kernel.org -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Link: http://lkml.kernel.org/r/20170524081547.731628408@linutronix.de ---- - drivers/cpufreq/cpufreq.c | 21 +++++++++++---------- - 1 file changed, 11 insertions(+), 10 deletions(-) - ---- a/drivers/cpufreq/cpufreq.c -+++ b/drivers/cpufreq/cpufreq.c -@@ -887,7 +887,7 @@ static ssize_t store(struct kobject *kob - struct freq_attr *fattr = to_attr(attr); - ssize_t ret = -EINVAL; - -- get_online_cpus(); -+ cpus_read_lock(); - - if (cpu_online(policy->cpu)) { - down_write(&policy->rwsem); -@@ -895,7 +895,7 @@ static ssize_t store(struct kobject *kob - up_write(&policy->rwsem); - } - -- put_online_cpus(); -+ cpus_read_unlock(); - - return ret; - } -@@ -2441,7 +2441,7 @@ int cpufreq_register_driver(struct cpufr - pr_debug("trying to register driver %s\n", driver_data->name); - - /* Protect against concurrent CPU online/offline. */ -- get_online_cpus(); -+ cpus_read_lock(); - - write_lock_irqsave(&cpufreq_driver_lock, flags); - if (cpufreq_driver) { -@@ -2474,9 +2474,10 @@ int cpufreq_register_driver(struct cpufr - goto err_if_unreg; - } - -- ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "cpufreq:online", -- cpuhp_cpufreq_online, -- cpuhp_cpufreq_offline); -+ ret = cpuhp_setup_state_nocalls_cpuslocked(CPUHP_AP_ONLINE_DYN, -+ "cpufreq:online", -+ cpuhp_cpufreq_online, -+ cpuhp_cpufreq_offline); - if (ret < 0) - goto err_if_unreg; - hp_online = ret; -@@ -2494,7 +2495,7 @@ int cpufreq_register_driver(struct cpufr - cpufreq_driver = NULL; - write_unlock_irqrestore(&cpufreq_driver_lock, flags); - out: -- put_online_cpus(); -+ cpus_read_unlock(); - return ret; - } - EXPORT_SYMBOL_GPL(cpufreq_register_driver); -@@ -2517,17 +2518,17 @@ int cpufreq_unregister_driver(struct cpu - pr_debug("unregistering driver %s\n", driver->name); - - /* Protect against concurrent cpu hotplug */ -- get_online_cpus(); -+ cpus_read_lock(); - subsys_interface_unregister(&cpufreq_interface); - remove_boost_sysfs_file(); -- cpuhp_remove_state_nocalls(hp_online); -+ cpuhp_remove_state_nocalls_cpuslocked(hp_online); - - write_lock_irqsave(&cpufreq_driver_lock, flags); - - cpufreq_driver = NULL; - - write_unlock_irqrestore(&cpufreq_driver_lock, flags); -- put_online_cpus(); -+ cpus_read_unlock(); - - return 0; - } diff --git a/patches/0009-cpufreq-ia64-Replace-racy-task-affinity-logic.patch b/patches/0009-cpufreq-ia64-Replace-racy-task-affinity-logic.patch deleted file mode 100644 index 5cdf89a318f3..000000000000 --- a/patches/0009-cpufreq-ia64-Replace-racy-task-affinity-logic.patch +++ /dev/null @@ -1,208 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 12 Apr 2017 22:55:03 +0200 -Subject: [PATCH 09/13] cpufreq/ia64: Replace racy task affinity logic - -The get() and target() callbacks must run on the affected cpu. This is -achieved by temporarily setting the affinity of the calling thread to the -requested CPU and reset it to the original affinity afterwards. - -That's racy vs. concurrent affinity settings for that thread resulting in -code executing on the wrong CPU and overwriting the new affinity setting. - -Replace it by work_on_cpu(). All call pathes which invoke the callbacks are -already protected against CPU hotplug. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Viresh Kumar <viresh.kumar@linaro.org> -Cc: Fenghua Yu <fenghua.yu@intel.com> -Cc: Tony Luck <tony.luck@intel.com> -Cc: Herbert Xu <herbert@gondor.apana.org.au> -Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: linux-pm@vger.kernel.org -Cc: Lai Jiangshan <jiangshanlai@gmail.com> -Cc: Michael Ellerman <mpe@ellerman.id.au> -Cc: Tejun Heo <tj@kernel.org> -Cc: "David S. Miller" <davem@davemloft.net> -Cc: Len Brown <lenb@kernel.org> -Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1704122231100.2548@nanos -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - drivers/cpufreq/ia64-acpi-cpufreq.c | 92 +++++++++++++++--------------------- - 1 file changed, 39 insertions(+), 53 deletions(-) - ---- a/drivers/cpufreq/ia64-acpi-cpufreq.c -+++ b/drivers/cpufreq/ia64-acpi-cpufreq.c -@@ -34,6 +34,11 @@ struct cpufreq_acpi_io { - unsigned int resume; - }; - -+struct cpufreq_acpi_req { -+ unsigned int cpu; -+ unsigned int state; -+}; -+ - static struct cpufreq_acpi_io *acpi_io_data[NR_CPUS]; - - static struct cpufreq_driver acpi_cpufreq_driver; -@@ -83,8 +88,7 @@ processor_get_pstate ( - static unsigned - extract_clock ( - struct cpufreq_acpi_io *data, -- unsigned value, -- unsigned int cpu) -+ unsigned value) - { - unsigned long i; - -@@ -98,60 +102,43 @@ extract_clock ( - } - - --static unsigned int -+static long - processor_get_freq ( -- struct cpufreq_acpi_io *data, -- unsigned int cpu) -+ void *arg) - { -- int ret = 0; -- u32 value = 0; -- cpumask_t saved_mask; -- unsigned long clock_freq; -+ struct cpufreq_acpi_req *req = arg; -+ unsigned int cpu = req->cpu; -+ struct cpufreq_acpi_io *data = acpi_io_data[cpu]; -+ u32 value; -+ int ret; - - pr_debug("processor_get_freq\n"); -- -- saved_mask = current->cpus_allowed; -- set_cpus_allowed_ptr(current, cpumask_of(cpu)); - if (smp_processor_id() != cpu) -- goto migrate_end; -+ return -EAGAIN; - - /* processor_get_pstate gets the instantaneous frequency */ - ret = processor_get_pstate(&value); -- - if (ret) { -- set_cpus_allowed_ptr(current, &saved_mask); - pr_warn("get performance failed with error %d\n", ret); -- ret = 0; -- goto migrate_end; -+ return ret; - } -- clock_freq = extract_clock(data, value, cpu); -- ret = (clock_freq*1000); -- --migrate_end: -- set_cpus_allowed_ptr(current, &saved_mask); -- return ret; -+ return 1000 * extract_clock(data, value); - } - - --static int -+static long - processor_set_freq ( -- struct cpufreq_acpi_io *data, -- struct cpufreq_policy *policy, -- int state) -+ void *arg) - { -- int ret = 0; -- u32 value = 0; -- cpumask_t saved_mask; -- int retval; -+ struct cpufreq_acpi_req *req = arg; -+ unsigned int cpu = req->cpu; -+ struct cpufreq_acpi_io *data = acpi_io_data[cpu]; -+ int ret, state = req->state; -+ u32 value; - - pr_debug("processor_set_freq\n"); -- -- saved_mask = current->cpus_allowed; -- set_cpus_allowed_ptr(current, cpumask_of(policy->cpu)); -- if (smp_processor_id() != policy->cpu) { -- retval = -EAGAIN; -- goto migrate_end; -- } -+ if (smp_processor_id() != cpu) -+ return -EAGAIN; - - if (state == data->acpi_data.state) { - if (unlikely(data->resume)) { -@@ -159,8 +146,7 @@ processor_set_freq ( - data->resume = 0; - } else { - pr_debug("Already at target state (P%d)\n", state); -- retval = 0; -- goto migrate_end; -+ return 0; - } - } - -@@ -171,7 +157,6 @@ processor_set_freq ( - * First we write the target state's 'control' value to the - * control_register. - */ -- - value = (u32) data->acpi_data.states[state].control; - - pr_debug("Transitioning to state: 0x%08x\n", value); -@@ -179,17 +164,11 @@ processor_set_freq ( - ret = processor_set_pstate(value); - if (ret) { - pr_warn("Transition failed with error %d\n", ret); -- retval = -ENODEV; -- goto migrate_end; -+ return -ENODEV; - } - - data->acpi_data.state = state; -- -- retval = 0; -- --migrate_end: -- set_cpus_allowed_ptr(current, &saved_mask); -- return (retval); -+ return 0; - } - - -@@ -197,11 +176,13 @@ static unsigned int - acpi_cpufreq_get ( - unsigned int cpu) - { -- struct cpufreq_acpi_io *data = acpi_io_data[cpu]; -+ struct cpufreq_acpi_req req; -+ long ret; - -- pr_debug("acpi_cpufreq_get\n"); -+ req.cpu = cpu; -+ ret = work_on_cpu(cpu, processor_get_freq, &req); - -- return processor_get_freq(data, cpu); -+ return ret > 0 ? (unsigned int) ret : 0; - } - - -@@ -210,7 +191,12 @@ acpi_cpufreq_target ( - struct cpufreq_policy *policy, - unsigned int index) - { -- return processor_set_freq(acpi_io_data[policy->cpu], policy, index); -+ struct cpufreq_acpi_req req; -+ -+ req.cpu = policy->cpu; -+ req.state = index; -+ -+ return work_on_cpu(req.cpu, processor_set_freq, &req); - } - - static int diff --git a/patches/0009-cpufreq-pasemi-Adjust-system_state-check.patch b/patches/0009-cpufreq-pasemi-Adjust-system_state-check.patch deleted file mode 100644 index bdcab4ad03e1..000000000000 --- a/patches/0009-cpufreq-pasemi-Adjust-system_state-check.patch +++ /dev/null @@ -1,37 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Tue, 16 May 2017 20:42:40 +0200 -Subject: [PATCH 09/17] cpufreq/pasemi: Adjust system_state check - -To enable smp_processor_id() and might_sleep() debug checks earlier, it's -required to add system states between SYSTEM_BOOTING and SYSTEM_RUNNING. - -Adjust the system_state check in pas_cpufreq_cpu_exit() to handle the extra -states. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Acked-by: Viresh Kumar <viresh.kumar@linaro.org> -Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Cc: Linus Torvalds <torvalds@linux-foundation.org> -Cc: Mark Rutland <mark.rutland@arm.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Rafael J. Wysocki <rjw@rjwysocki.net> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: linuxppc-dev@lists.ozlabs.org -Link: http://lkml.kernel.org/r/20170516184735.620023128@linutronix.de -Signed-off-by: Ingo Molnar <mingo@kernel.org> ---- - drivers/cpufreq/pasemi-cpufreq.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/cpufreq/pasemi-cpufreq.c -+++ b/drivers/cpufreq/pasemi-cpufreq.c -@@ -226,7 +226,7 @@ static int pas_cpufreq_cpu_exit(struct c - * We don't support CPU hotplug. Don't unmap after the system - * has already made it to a running state. - */ -- if (system_state != SYSTEM_BOOTING) -+ if (system_state >= SYSTEM_RUNNING) - return 0; - - if (sdcasr_mapbase) diff --git a/patches/0009-futex-rt_mutex-Introduce-rt_mutex_init_waiter.patch b/patches/0009-futex-rt_mutex-Introduce-rt_mutex_init_waiter.patch deleted file mode 100644 index 052a7c41ac43..000000000000 --- a/patches/0009-futex-rt_mutex-Introduce-rt_mutex_init_waiter.patch +++ /dev/null @@ -1,79 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Wed, 22 Mar 2017 11:35:56 +0100 -Subject: [PATCH] futex,rt_mutex: Introduce rt_mutex_init_waiter() - -Upstream commit 50809358dd7199aa7ce232f6877dd09ec30ef374 - -Since there's already two copies of this code, introduce a helper now -before adding a third one. - -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: juri.lelli@arm.com -Cc: bigeasy@linutronix.de -Cc: xlpang@redhat.com -Cc: rostedt@goodmis.org -Cc: mathieu.desnoyers@efficios.com -Cc: jdesfossez@efficios.com -Cc: dvhart@infradead.org -Cc: bristot@redhat.com -Link: http://lkml.kernel.org/r/20170322104151.950039479@infradead.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/futex.c | 5 +---- - kernel/locking/rtmutex.c | 12 +++++++++--- - kernel/locking/rtmutex_common.h | 1 + - 3 files changed, 11 insertions(+), 7 deletions(-) - ---- a/kernel/futex.c -+++ b/kernel/futex.c -@@ -2956,10 +2956,7 @@ static int futex_wait_requeue_pi(u32 __u - * The waiter is allocated on our stack, manipulated by the requeue - * code while we sleep on uaddr. - */ -- debug_rt_mutex_init_waiter(&rt_waiter); -- RB_CLEAR_NODE(&rt_waiter.pi_tree_entry); -- RB_CLEAR_NODE(&rt_waiter.tree_entry); -- rt_waiter.task = NULL; -+ rt_mutex_init_waiter(&rt_waiter); - - ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, VERIFY_WRITE); - if (unlikely(ret != 0)) ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -1153,6 +1153,14 @@ void rt_mutex_adjust_pi(struct task_stru - next_lock, NULL, task); - } - -+void rt_mutex_init_waiter(struct rt_mutex_waiter *waiter) -+{ -+ debug_rt_mutex_init_waiter(waiter); -+ RB_CLEAR_NODE(&waiter->pi_tree_entry); -+ RB_CLEAR_NODE(&waiter->tree_entry); -+ waiter->task = NULL; -+} -+ - /** - * __rt_mutex_slowlock() - Perform the wait-wake-try-to-take loop - * @lock: the rt_mutex to take -@@ -1235,9 +1243,7 @@ rt_mutex_slowlock(struct rt_mutex *lock, - unsigned long flags; - int ret = 0; - -- debug_rt_mutex_init_waiter(&waiter); -- RB_CLEAR_NODE(&waiter.pi_tree_entry); -- RB_CLEAR_NODE(&waiter.tree_entry); -+ rt_mutex_init_waiter(&waiter); - - /* - * Technically we could use raw_spin_[un]lock_irq() here, but this can ---- a/kernel/locking/rtmutex_common.h -+++ b/kernel/locking/rtmutex_common.h -@@ -103,6 +103,7 @@ extern void rt_mutex_init_proxy_locked(s - struct task_struct *proxy_owner); - extern void rt_mutex_proxy_unlock(struct rt_mutex *lock, - struct task_struct *proxy_owner); -+extern void rt_mutex_init_waiter(struct rt_mutex_waiter *waiter); - extern int rt_mutex_start_proxy_lock(struct rt_mutex *lock, - struct rt_mutex_waiter *waiter, - struct task_struct *task); diff --git a/patches/0009-hrtimer-Reduce-conditional-code-hrtimer_reprogram.patch b/patches/0009-hrtimer-Reduce-conditional-code-hrtimer_reprogram.patch index 384ac35b4c2c..e5d6ac5f2f9f 100644 --- a/patches/0009-hrtimer-Reduce-conditional-code-hrtimer_reprogram.patch +++ b/patches/0009-hrtimer-Reduce-conditional-code-hrtimer_reprogram.patch @@ -36,7 +36,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> unsigned int nr_hangs; --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -448,13 +448,13 @@ static inline void debug_deactivate(stru +@@ -449,13 +449,13 @@ static inline void debug_deactivate(stru trace_hrtimer_cancel(timer); } @@ -51,7 +51,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static ktime_t __hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base) { unsigned int active = cpu_base->active_bases; -@@ -581,68 +581,6 @@ hrtimer_force_reprogram(struct hrtimer_c +@@ -582,68 +582,6 @@ hrtimer_force_reprogram(struct hrtimer_c } /* @@ -120,7 +120,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * Retrigger next event is called after clock was set * * Called with interrupts disabled via on_each_cpu() -@@ -702,16 +640,73 @@ static inline int hrtimer_is_hres_enable +@@ -703,16 +641,73 @@ static inline int hrtimer_is_hres_enable static inline void hrtimer_switch_to_hres(void) { } static inline void hrtimer_force_reprogram(struct hrtimer_cpu_base *base, int skip_equal) { } diff --git a/patches/0009-rtmutex-Plug-preempt-count-leak-in-rt_mutex_futex_un.patch b/patches/0009-rtmutex-Plug-preempt-count-leak-in-rt_mutex_futex_un.patch deleted file mode 100644 index a9dd7e64add5..000000000000 --- a/patches/0009-rtmutex-Plug-preempt-count-leak-in-rt_mutex_futex_un.patch +++ /dev/null @@ -1,40 +0,0 @@ -From: Mike Galbraith <efault@gmx.de> -Date: Wed, 5 Apr 2017 10:08:27 +0200 -Subject: [PATCH 9/9] rtmutex: Plug preempt count leak in - rt_mutex_futex_unlock() - -mark_wakeup_next_waiter() already disables preemption, doing so again -leaves us with an unpaired preempt_disable(). - -Fixes: 2a1c60299406 ("rtmutex: Deboost before waking up the top waiter") -Signed-off-by: Mike Galbraith <efault@gmx.de> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: xlpang@redhat.com -Cc: rostedt@goodmis.org -Link: http://lkml.kernel.org/r/1491379707.6538.2.camel@gmx.de -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - kernel/locking/rtmutex.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -1581,13 +1581,13 @@ bool __sched __rt_mutex_futex_unlock(str - return false; /* done */ - } - -- mark_wakeup_next_waiter(wake_q, lock); - /* -- * We've already deboosted, retain preempt_disabled when dropping -- * the wait_lock to avoid inversion until the wakeup. Matched -- * by rt_mutex_postunlock(); -+ * We've already deboosted, mark_wakeup_next_waiter() will -+ * retain preempt_disabled when we drop the wait_lock, to -+ * avoid inversion prior to the wakeup. preempt_disable() -+ * therein pairs with rt_mutex_postunlock(). - */ -- preempt_disable(); -+ mark_wakeup_next_waiter(wake_q, lock); - - return true; /* call postunlock() */ - } diff --git a/patches/0009-tracing-Give-event-triggers-access-to-ring_buffer_ev.patch b/patches/0009-tracing-Give-event-triggers-access-to-ring_buffer_ev.patch index 840e4441dd87..d384e8e31ece 100644 --- a/patches/0009-tracing-Give-event-triggers-access-to-ring_buffer_ev.patch +++ b/patches/0009-tracing-Give-event-triggers-access-to-ring_buffer_ev.patch @@ -17,7 +17,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/include/linux/trace_events.h +++ b/include/linux/trace_events.h -@@ -400,11 +400,13 @@ enum event_trigger_type { +@@ -403,11 +403,13 @@ enum event_trigger_type { extern int filter_match_preds(struct event_filter *filter, void *rec); @@ -36,7 +36,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> bool trace_event_ignore_this_pid(struct trace_event_file *trace_file); -@@ -424,7 +426,7 @@ trace_trigger_soft_disabled(struct trace +@@ -427,7 +429,7 @@ trace_trigger_soft_disabled(struct trace if (!(eflags & EVENT_FILE_FL_TRIGGER_COND)) { if (eflags & EVENT_FILE_FL_TRIGGER_MODE) @@ -47,7 +47,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (eflags & EVENT_FILE_FL_PID_FILTER) --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h -@@ -1190,7 +1190,7 @@ static inline bool +@@ -1292,7 +1292,7 @@ static inline bool unsigned long eflags = file->flags; if (eflags & EVENT_FILE_FL_TRIGGER_COND) @@ -56,7 +56,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (test_bit(EVENT_FILE_FL_SOFT_DISABLED_BIT, &file->flags) || (unlikely(file->flags & EVENT_FILE_FL_FILTERED) && -@@ -1227,7 +1227,7 @@ event_trigger_unlock_commit(struct trace +@@ -1329,7 +1329,7 @@ event_trigger_unlock_commit(struct trace trace_buffer_unlock_commit(file->tr, buffer, event, irq_flags, pc); if (tt) @@ -65,7 +65,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } /** -@@ -1260,7 +1260,7 @@ event_trigger_unlock_commit_regs(struct +@@ -1362,7 +1362,7 @@ event_trigger_unlock_commit_regs(struct irq_flags, pc, regs); if (tt) @@ -74,7 +74,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } #define FILTER_PRED_INVALID ((unsigned short)-1) -@@ -1483,7 +1483,8 @@ extern int register_trigger_hist_enable_ +@@ -1587,7 +1587,8 @@ extern int register_trigger_hist_enable_ */ struct event_trigger_ops { void (*func)(struct event_trigger_data *data, diff --git a/patches/0010-KVM-PPC-Book3S-HV-Use-cpuhp_setup_state_nocalls_cpus.patch b/patches/0010-KVM-PPC-Book3S-HV-Use-cpuhp_setup_state_nocalls_cpus.patch deleted file mode 100644 index 64db0e55a0f1..000000000000 --- a/patches/0010-KVM-PPC-Book3S-HV-Use-cpuhp_setup_state_nocalls_cpus.patch +++ /dev/null @@ -1,67 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Wed, 24 May 2017 10:15:21 +0200 -Subject: [PATCH 10/32] KVM/PPC/Book3S HV: Use - cpuhp_setup_state_nocalls_cpuslocked() - -kvmppc_alloc_host_rm_ops() holds get_online_cpus() while invoking -cpuhp_setup_state_nocalls(). - -cpuhp_setup_state_nocalls() invokes get_online_cpus() as well. This is -correct, but prevents the conversion of the hotplug locking to a percpu -rwsem. - -Use cpuhp_setup_state_nocalls_cpuslocked() to avoid the nested -call. Convert *_online_cpus() to the new interfaces while at it. - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Ingo Molnar <mingo@kernel.org> -Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Cc: kvm@vger.kernel.org -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: kvm-ppc@vger.kernel.org -Cc: Michael Ellerman <mpe@ellerman.id.au> -Cc: linuxppc-dev@lists.ozlabs.org -Cc: Alexander Graf <agraf@suse.com> -Link: http://lkml.kernel.org/r/20170524081547.809616236@linutronix.de ---- - arch/powerpc/kvm/book3s_hv.c | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - ---- a/arch/powerpc/kvm/book3s_hv.c -+++ b/arch/powerpc/kvm/book3s_hv.c -@@ -3359,7 +3359,7 @@ void kvmppc_alloc_host_rm_ops(void) - return; - } - -- get_online_cpus(); -+ cpus_read_lock(); - - for (cpu = 0; cpu < nr_cpu_ids; cpu += threads_per_core) { - if (!cpu_online(cpu)) -@@ -3381,17 +3381,17 @@ void kvmppc_alloc_host_rm_ops(void) - l_ops = (unsigned long) ops; - - if (cmpxchg64((unsigned long *)&kvmppc_host_rm_ops_hv, 0, l_ops)) { -- put_online_cpus(); -+ cpus_read_unlock(); - kfree(ops->rm_core); - kfree(ops); - return; - } - -- cpuhp_setup_state_nocalls(CPUHP_KVM_PPC_BOOK3S_PREPARE, -- "ppc/kvm_book3s:prepare", -- kvmppc_set_host_core, -- kvmppc_clear_host_core); -- put_online_cpus(); -+ cpuhp_setup_state_nocalls_cpuslocked(CPUHP_KVM_PPC_BOOK3S_PREPARE, -+ "ppc/kvm_book3s:prepare", -+ kvmppc_set_host_core, -+ kvmppc_clear_host_core); -+ cpus_read_unlock(); - } - - void kvmppc_free_host_rm_ops(void) diff --git a/patches/0010-cpufreq-sh-Replace-racy-task-affinity-logic.patch b/patches/0010-cpufreq-sh-Replace-racy-task-affinity-logic.patch deleted file mode 100644 index 2d78323acf17..000000000000 --- a/patches/0010-cpufreq-sh-Replace-racy-task-affinity-logic.patch +++ /dev/null @@ -1,119 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 12 Apr 2017 22:07:36 +0200 -Subject: [PATCH 10/13] cpufreq/sh: Replace racy task affinity logic - -The target() callback must run on the affected cpu. This is achieved by -temporarily setting the affinity of the calling thread to the requested CPU -and reset it to the original affinity afterwards. - -That's racy vs. concurrent affinity settings for that thread resulting in -code executing on the wrong CPU. - -Replace it by work_on_cpu(). All call pathes which invoke the callbacks are -already protected against CPU hotplug. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Viresh Kumar <viresh.kumar@linaro.org> -Cc: Fenghua Yu <fenghua.yu@intel.com> -Cc: Tony Luck <tony.luck@intel.com> -Cc: Herbert Xu <herbert@gondor.apana.org.au> -Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: linux-pm@vger.kernel.org -Cc: Lai Jiangshan <jiangshanlai@gmail.com> -Cc: Michael Ellerman <mpe@ellerman.id.au> -Cc: Tejun Heo <tj@kernel.org> -Cc: "David S. Miller" <davem@davemloft.net> -Cc: Len Brown <lenb@kernel.org> -Link: http://lkml.kernel.org/r/20170412201042.958216363@linutronix.de -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - drivers/cpufreq/sh-cpufreq.c | 45 +++++++++++++++++++++++++------------------ - 1 file changed, 27 insertions(+), 18 deletions(-) - ---- a/drivers/cpufreq/sh-cpufreq.c -+++ b/drivers/cpufreq/sh-cpufreq.c -@@ -30,54 +30,63 @@ - - static DEFINE_PER_CPU(struct clk, sh_cpuclk); - -+struct cpufreq_target { -+ struct cpufreq_policy *policy; -+ unsigned int freq; -+}; -+ - static unsigned int sh_cpufreq_get(unsigned int cpu) - { - return (clk_get_rate(&per_cpu(sh_cpuclk, cpu)) + 500) / 1000; - } - --/* -- * Here we notify other drivers of the proposed change and the final change. -- */ --static int sh_cpufreq_target(struct cpufreq_policy *policy, -- unsigned int target_freq, -- unsigned int relation) -+static long __sh_cpufreq_target(void *arg) - { -- unsigned int cpu = policy->cpu; -+ struct cpufreq_target *target = arg; -+ struct cpufreq_policy *policy = target->policy; -+ int cpu = policy->cpu; - struct clk *cpuclk = &per_cpu(sh_cpuclk, cpu); -- cpumask_t cpus_allowed; - struct cpufreq_freqs freqs; - struct device *dev; - long freq; - -- cpus_allowed = current->cpus_allowed; -- set_cpus_allowed_ptr(current, cpumask_of(cpu)); -- -- BUG_ON(smp_processor_id() != cpu); -+ if (smp_processor_id() != cpu) -+ return -ENODEV; - - dev = get_cpu_device(cpu); - - /* Convert target_freq from kHz to Hz */ -- freq = clk_round_rate(cpuclk, target_freq * 1000); -+ freq = clk_round_rate(cpuclk, target->freq * 1000); - - if (freq < (policy->min * 1000) || freq > (policy->max * 1000)) - return -EINVAL; - -- dev_dbg(dev, "requested frequency %u Hz\n", target_freq * 1000); -+ dev_dbg(dev, "requested frequency %u Hz\n", target->freq * 1000); - - freqs.old = sh_cpufreq_get(cpu); - freqs.new = (freq + 500) / 1000; - freqs.flags = 0; - -- cpufreq_freq_transition_begin(policy, &freqs); -- set_cpus_allowed_ptr(current, &cpus_allowed); -+ cpufreq_freq_transition_begin(target->policy, &freqs); - clk_set_rate(cpuclk, freq); -- cpufreq_freq_transition_end(policy, &freqs, 0); -+ cpufreq_freq_transition_end(target->policy, &freqs, 0); - - dev_dbg(dev, "set frequency %lu Hz\n", freq); -- - return 0; - } - -+/* -+ * Here we notify other drivers of the proposed change and the final change. -+ */ -+static int sh_cpufreq_target(struct cpufreq_policy *policy, -+ unsigned int target_freq, -+ unsigned int relation) -+{ -+ struct cpufreq_target data = { .policy = policy, .freq = target_freq }; -+ -+ return work_on_cpu(policy->cpu, __sh_cpufreq_target, &data); -+} -+ - static int sh_cpufreq_verify(struct cpufreq_policy *policy) - { - struct clk *cpuclk = &per_cpu(sh_cpuclk, policy->cpu); diff --git a/patches/0010-futex-rt_mutex-Restructure-rt_mutex_finish_proxy_loc.patch b/patches/0010-futex-rt_mutex-Restructure-rt_mutex_finish_proxy_loc.patch deleted file mode 100644 index 4b00ec745cd1..000000000000 --- a/patches/0010-futex-rt_mutex-Restructure-rt_mutex_finish_proxy_loc.patch +++ /dev/null @@ -1,158 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Wed, 22 Mar 2017 11:35:57 +0100 -Subject: [PATCH] futex,rt_mutex: Restructure rt_mutex_finish_proxy_lock() - -Upstream commit 38d589f2fd08f1296aea3ce62bebd185125c6d81 - -With the ultimate goal of keeping rt_mutex wait_list and futex_q waiters -consistent it's necessary to split 'rt_mutex_futex_lock()' into finer -parts, such that only the actual blocking can be done without hb->lock -held. - -Split split_mutex_finish_proxy_lock() into two parts, one that does the -blocking and one that does remove_waiter() when the lock acquire failed. - -When the rtmutex was acquired successfully the waiter can be removed in the -acquisiton path safely, since there is no concurrency on the lock owner. - -This means that, except for futex_lock_pi(), all wait_list modifications -are done with both hb->lock and wait_lock held. - -[bigeasy@linutronix.de: fix for futex_requeue_pi_signal_restart] - -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: juri.lelli@arm.com -Cc: bigeasy@linutronix.de -Cc: xlpang@redhat.com -Cc: rostedt@goodmis.org -Cc: mathieu.desnoyers@efficios.com -Cc: jdesfossez@efficios.com -Cc: dvhart@infradead.org -Cc: bristot@redhat.com -Link: http://lkml.kernel.org/r/20170322104152.001659630@infradead.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/futex.c | 7 +++-- - kernel/locking/rtmutex.c | 52 ++++++++++++++++++++++++++++++++++------ - kernel/locking/rtmutex_common.h | 8 +++--- - 3 files changed, 55 insertions(+), 12 deletions(-) - ---- a/kernel/futex.c -+++ b/kernel/futex.c -@@ -3032,10 +3032,13 @@ static int futex_wait_requeue_pi(u32 __u - */ - WARN_ON(!q.pi_state); - pi_mutex = &q.pi_state->pi_mutex; -- ret = rt_mutex_finish_proxy_lock(pi_mutex, to, &rt_waiter); -- debug_rt_mutex_free_waiter(&rt_waiter); -+ ret = rt_mutex_wait_proxy_lock(pi_mutex, to, &rt_waiter); - - spin_lock(q.lock_ptr); -+ if (ret && !rt_mutex_cleanup_proxy_lock(pi_mutex, &rt_waiter)) -+ ret = 0; -+ -+ debug_rt_mutex_free_waiter(&rt_waiter); - /* - * Fixup the pi_state owner and possibly acquire the lock if we - * haven't already. ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -1753,21 +1753,23 @@ struct task_struct *rt_mutex_next_owner( - } - - /** -- * rt_mutex_finish_proxy_lock() - Complete lock acquisition -+ * rt_mutex_wait_proxy_lock() - Wait for lock acquisition - * @lock: the rt_mutex we were woken on - * @to: the timeout, null if none. hrtimer should already have - * been started. - * @waiter: the pre-initialized rt_mutex_waiter - * -- * Complete the lock acquisition started our behalf by another thread. -+ * Wait for the the lock acquisition started on our behalf by -+ * rt_mutex_start_proxy_lock(). Upon failure, the caller must call -+ * rt_mutex_cleanup_proxy_lock(). - * - * Returns: - * 0 - success - * <0 - error, one of -EINTR, -ETIMEDOUT - * -- * Special API call for PI-futex requeue support -+ * Special API call for PI-futex support - */ --int rt_mutex_finish_proxy_lock(struct rt_mutex *lock, -+int rt_mutex_wait_proxy_lock(struct rt_mutex *lock, - struct hrtimer_sleeper *to, - struct rt_mutex_waiter *waiter) - { -@@ -1780,9 +1782,6 @@ int rt_mutex_finish_proxy_lock(struct rt - /* sleep on the mutex */ - ret = __rt_mutex_slowlock(lock, TASK_INTERRUPTIBLE, to, waiter); - -- if (unlikely(ret)) -- remove_waiter(lock, waiter); -- - /* - * try_to_take_rt_mutex() sets the waiter bit unconditionally. We might - * have to fix that up. -@@ -1793,3 +1792,42 @@ int rt_mutex_finish_proxy_lock(struct rt - - return ret; - } -+ -+/** -+ * rt_mutex_cleanup_proxy_lock() - Cleanup failed lock acquisition -+ * @lock: the rt_mutex we were woken on -+ * @waiter: the pre-initialized rt_mutex_waiter -+ * -+ * Attempt to clean up after a failed rt_mutex_wait_proxy_lock(). -+ * -+ * Unless we acquired the lock; we're still enqueued on the wait-list and can -+ * in fact still be granted ownership until we're removed. Therefore we can -+ * find we are in fact the owner and must disregard the -+ * rt_mutex_wait_proxy_lock() failure. -+ * -+ * Returns: -+ * true - did the cleanup, we done. -+ * false - we acquired the lock after rt_mutex_wait_proxy_lock() returned, -+ * caller should disregards its return value. -+ * -+ * Special API call for PI-futex support -+ */ -+bool rt_mutex_cleanup_proxy_lock(struct rt_mutex *lock, -+ struct rt_mutex_waiter *waiter) -+{ -+ bool cleanup = false; -+ -+ raw_spin_lock_irq(&lock->wait_lock); -+ /* -+ * Unless we're the owner; we're still enqueued on the wait_list. -+ * So check if we became owner, if not, take us off the wait_list. -+ */ -+ if (rt_mutex_owner(lock) != current) { -+ remove_waiter(lock, waiter); -+ fixup_rt_mutex_waiters(lock); -+ cleanup = true; -+ } -+ raw_spin_unlock_irq(&lock->wait_lock); -+ -+ return cleanup; -+} ---- a/kernel/locking/rtmutex_common.h -+++ b/kernel/locking/rtmutex_common.h -@@ -107,9 +107,11 @@ extern void rt_mutex_init_waiter(struct - extern int rt_mutex_start_proxy_lock(struct rt_mutex *lock, - struct rt_mutex_waiter *waiter, - struct task_struct *task); --extern int rt_mutex_finish_proxy_lock(struct rt_mutex *lock, -- struct hrtimer_sleeper *to, -- struct rt_mutex_waiter *waiter); -+extern int rt_mutex_wait_proxy_lock(struct rt_mutex *lock, -+ struct hrtimer_sleeper *to, -+ struct rt_mutex_waiter *waiter); -+extern bool rt_mutex_cleanup_proxy_lock(struct rt_mutex *lock, -+ struct rt_mutex_waiter *waiter); - - extern int rt_mutex_timed_futex_lock(struct rt_mutex *l, struct hrtimer_sleeper *to); - extern int rt_mutex_futex_trylock(struct rt_mutex *l); diff --git a/patches/0010-hrtimer-Make-handling-of-hrtimer-reprogramming-and-e.patch b/patches/0010-hrtimer-Make-handling-of-hrtimer-reprogramming-and-e.patch index aafd35824187..610f2a028705 100644 --- a/patches/0010-hrtimer-Make-handling-of-hrtimer-reprogramming-and-e.patch +++ b/patches/0010-hrtimer-Make-handling-of-hrtimer-reprogramming-and-e.patch @@ -22,7 +22,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -153,10 +153,11 @@ struct hrtimer_clock_base *lock_hrtimer_ +@@ -154,10 +154,11 @@ struct hrtimer_clock_base *lock_hrtimer_ } /* @@ -38,7 +38,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * * Called with cpu_base->lock of target cpu held. */ -@@ -165,9 +166,6 @@ hrtimer_check_target(struct hrtimer *tim +@@ -166,9 +167,6 @@ hrtimer_check_target(struct hrtimer *tim { ktime_t expires; @@ -48,7 +48,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> expires = ktime_sub(hrtimer_get_expires(timer), new_base->offset); return expires <= new_base->cpu_base->expires_next; } -@@ -688,21 +686,24 @@ static void hrtimer_reprogram(struct hrt +@@ -689,21 +687,24 @@ static void hrtimer_reprogram(struct hrt /* Update the pointer to the next expiring timer */ hrtimer_update_next_timer(cpu_base, timer); @@ -75,7 +75,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> tick_program_event(expires, 1); } -@@ -942,16 +943,8 @@ void hrtimer_start_range_ns(struct hrtim +@@ -943,16 +944,8 @@ void hrtimer_start_range_ns(struct hrtim if (!leftmost) goto unlock; diff --git a/patches/0010-iommu-vt-d-Adjust-system_state-checks.patch b/patches/0010-iommu-vt-d-Adjust-system_state-checks.patch deleted file mode 100644 index fb61919578d3..000000000000 --- a/patches/0010-iommu-vt-d-Adjust-system_state-checks.patch +++ /dev/null @@ -1,46 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Tue, 16 May 2017 20:42:41 +0200 -Subject: [PATCH 10/17] iommu/vt-d: Adjust system_state checks - -To enable smp_processor_id() and might_sleep() debug checks earlier, it's -required to add system states between SYSTEM_BOOTING and SYSTEM_RUNNING. - -Adjust the system_state checks in dmar_parse_one_atsr() and -dmar_iommu_notify_scope_dev() to handle the extra states. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Acked-by: Joerg Roedel <joro@8bytes.org> -Cc: David Woodhouse <dwmw2@infradead.org> -Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Cc: Linus Torvalds <torvalds@linux-foundation.org> -Cc: Mark Rutland <mark.rutland@arm.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: iommu@lists.linux-foundation.org -Link: http://lkml.kernel.org/r/20170516184735.712365947@linutronix.de -Signed-off-by: Ingo Molnar <mingo@kernel.org> ---- - drivers/iommu/intel-iommu.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/iommu/intel-iommu.c -+++ b/drivers/iommu/intel-iommu.c -@@ -4310,7 +4310,7 @@ int dmar_parse_one_atsr(struct acpi_dmar - struct acpi_dmar_atsr *atsr; - struct dmar_atsr_unit *atsru; - -- if (system_state != SYSTEM_BOOTING && !intel_iommu_enabled) -+ if (system_state >= SYSTEM_RUNNING && !intel_iommu_enabled) - return 0; - - atsr = container_of(hdr, struct acpi_dmar_atsr, header); -@@ -4560,7 +4560,7 @@ int dmar_iommu_notify_scope_dev(struct d - struct acpi_dmar_atsr *atsr; - struct acpi_dmar_reserved_memory *rmrr; - -- if (!intel_iommu_enabled && system_state != SYSTEM_BOOTING) -+ if (!intel_iommu_enabled && system_state >= SYSTEM_RUNNING) - return 0; - - list_for_each_entry(rmrru, &dmar_rmrr_units, list) { diff --git a/patches/0011-cpufreq-sparc-us3-Replace-racy-task-affinity-logic.patch b/patches/0011-cpufreq-sparc-us3-Replace-racy-task-affinity-logic.patch deleted file mode 100644 index 5a64452a7dbe..000000000000 --- a/patches/0011-cpufreq-sparc-us3-Replace-racy-task-affinity-logic.patch +++ /dev/null @@ -1,123 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 12 Apr 2017 22:07:37 +0200 -Subject: [PATCH 11/13] cpufreq/sparc-us3: Replace racy task affinity logic - -The access to the safari config register in the CPU frequency functions -must be executed on the target CPU. This is achieved by temporarily setting -the affinity of the calling user space thread to the requested CPU and -reset it to the original affinity afterwards. - -That's racy vs. CPU hotplug and concurrent affinity settings for that -thread resulting in code executing on the wrong CPU and overwriting the -new affinity setting. - -Replace it by a straight forward smp function call. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Viresh Kumar <viresh.kumar@linaro.org> -Cc: Fenghua Yu <fenghua.yu@intel.com> -Cc: Tony Luck <tony.luck@intel.com> -Cc: Herbert Xu <herbert@gondor.apana.org.au> -Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: linux-pm@vger.kernel.org -Cc: Lai Jiangshan <jiangshanlai@gmail.com> -Cc: Michael Ellerman <mpe@ellerman.id.au> -Cc: Tejun Heo <tj@kernel.org> -Cc: "David S. Miller" <davem@davemloft.net> -Cc: Len Brown <lenb@kernel.org> -Link: http://lkml.kernel.org/r/20170412201043.047558840@linutronix.de -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - drivers/cpufreq/sparc-us3-cpufreq.c | 46 ++++++++++++------------------------ - 1 file changed, 16 insertions(+), 30 deletions(-) - ---- a/drivers/cpufreq/sparc-us3-cpufreq.c -+++ b/drivers/cpufreq/sparc-us3-cpufreq.c -@@ -35,22 +35,28 @@ static struct us3_freq_percpu_info *us3_ - #define SAFARI_CFG_DIV_32 0x0000000080000000UL - #define SAFARI_CFG_DIV_MASK 0x00000000C0000000UL - --static unsigned long read_safari_cfg(void) -+static void read_safari_cfg(void *arg) - { -- unsigned long ret; -+ unsigned long ret, *val = arg; - - __asm__ __volatile__("ldxa [%%g0] %1, %0" - : "=&r" (ret) - : "i" (ASI_SAFARI_CONFIG)); -- return ret; -+ *val = ret; - } - --static void write_safari_cfg(unsigned long val) -+static void update_safari_cfg(void *arg) - { -+ unsigned long reg, *new_bits = arg; -+ -+ read_safari_cfg(®); -+ reg &= ~SAFARI_CFG_DIV_MASK; -+ reg |= *new_bits; -+ - __asm__ __volatile__("stxa %0, [%%g0] %1\n\t" - "membar #Sync" - : /* no outputs */ -- : "r" (val), "i" (ASI_SAFARI_CONFIG) -+ : "r" (reg), "i" (ASI_SAFARI_CONFIG) - : "memory"); - } - -@@ -78,29 +84,17 @@ static unsigned long get_current_freq(un - - static unsigned int us3_freq_get(unsigned int cpu) - { -- cpumask_t cpus_allowed; - unsigned long reg; -- unsigned int ret; -- -- cpumask_copy(&cpus_allowed, ¤t->cpus_allowed); -- set_cpus_allowed_ptr(current, cpumask_of(cpu)); -- -- reg = read_safari_cfg(); -- ret = get_current_freq(cpu, reg); - -- set_cpus_allowed_ptr(current, &cpus_allowed); -- -- return ret; -+ if (smp_call_function_single(cpu, read_safari_cfg, ®, 1)) -+ return 0; -+ return get_current_freq(cpu, reg); - } - - static int us3_freq_target(struct cpufreq_policy *policy, unsigned int index) - { - unsigned int cpu = policy->cpu; -- unsigned long new_bits, new_freq, reg; -- cpumask_t cpus_allowed; -- -- cpumask_copy(&cpus_allowed, ¤t->cpus_allowed); -- set_cpus_allowed_ptr(current, cpumask_of(cpu)); -+ unsigned long new_bits, new_freq; - - new_freq = sparc64_get_clock_tick(cpu) / 1000; - switch (index) { -@@ -121,15 +115,7 @@ static int us3_freq_target(struct cpufre - BUG(); - } - -- reg = read_safari_cfg(); -- -- reg &= ~SAFARI_CFG_DIV_MASK; -- reg |= new_bits; -- write_safari_cfg(reg); -- -- set_cpus_allowed_ptr(current, &cpus_allowed); -- -- return 0; -+ return smp_call_function_single(cpu, update_safari_cfg, &new_bits, 1); - } - - static int __init us3_freq_cpu_init(struct cpufreq_policy *policy) diff --git a/patches/0011-futex-Rework-futex_lock_pi-to-use-rt_mutex_-_proxy_l.patch b/patches/0011-futex-Rework-futex_lock_pi-to-use-rt_mutex_-_proxy_l.patch deleted file mode 100644 index 42c581b2187d..000000000000 --- a/patches/0011-futex-Rework-futex_lock_pi-to-use-rt_mutex_-_proxy_l.patch +++ /dev/null @@ -1,266 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Wed, 22 Mar 2017 11:35:58 +0100 -Subject: [PATCH] futex: Rework futex_lock_pi() to use rt_mutex_*_proxy_lock() - -Upstream commit cfafcd117da0216520568c195cb2f6cd1980c4bb - -By changing futex_lock_pi() to use rt_mutex_*_proxy_lock() all wait_list -modifications are done under both hb->lock and wait_lock. - -This closes the obvious interleave pattern between futex_lock_pi() and -futex_unlock_pi(), but not entirely so. See below: - -Before: - -futex_lock_pi() futex_unlock_pi() - unlock hb->lock - - lock hb->lock - unlock hb->lock - - lock rt_mutex->wait_lock - unlock rt_mutex_wait_lock - -EAGAIN - - lock rt_mutex->wait_lock - list_add - unlock rt_mutex->wait_lock - - schedule() - - lock rt_mutex->wait_lock - list_del - unlock rt_mutex->wait_lock - - <idem> - -EAGAIN - - lock hb->lock - - -After: - -futex_lock_pi() futex_unlock_pi() - - lock hb->lock - lock rt_mutex->wait_lock - list_add - unlock rt_mutex->wait_lock - unlock hb->lock - - schedule() - lock hb->lock - unlock hb->lock - lock hb->lock - lock rt_mutex->wait_lock - list_del - unlock rt_mutex->wait_lock - - lock rt_mutex->wait_lock - unlock rt_mutex_wait_lock - -EAGAIN - - unlock hb->lock - - -It does however solve the earlier starvation/live-lock scenario which got -introduced with the -EAGAIN since unlike the before scenario; where the --EAGAIN happens while futex_unlock_pi() doesn't hold any locks; in the -after scenario it happens while futex_unlock_pi() actually holds a lock, -and then it is serialized on that lock. - -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: juri.lelli@arm.com -Cc: bigeasy@linutronix.de -Cc: xlpang@redhat.com -Cc: rostedt@goodmis.org -Cc: mathieu.desnoyers@efficios.com -Cc: jdesfossez@efficios.com -Cc: dvhart@infradead.org -Cc: bristot@redhat.com -Link: http://lkml.kernel.org/r/20170322104152.062785528@infradead.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/futex.c | 77 ++++++++++++++++++++++++++++------------ - kernel/locking/rtmutex.c | 26 +++---------- - kernel/locking/rtmutex_common.h | 1 - 3 files changed, 62 insertions(+), 42 deletions(-) - ---- a/kernel/futex.c -+++ b/kernel/futex.c -@@ -2099,20 +2099,7 @@ queue_unlock(struct futex_hash_bucket *h - hb_waiters_dec(hb); - } - --/** -- * queue_me() - Enqueue the futex_q on the futex_hash_bucket -- * @q: The futex_q to enqueue -- * @hb: The destination hash bucket -- * -- * The hb->lock must be held by the caller, and is released here. A call to -- * queue_me() is typically paired with exactly one call to unqueue_me(). The -- * exceptions involve the PI related operations, which may use unqueue_me_pi() -- * or nothing if the unqueue is done as part of the wake process and the unqueue -- * state is implicit in the state of woken task (see futex_wait_requeue_pi() for -- * an example). -- */ --static inline void queue_me(struct futex_q *q, struct futex_hash_bucket *hb) -- __releases(&hb->lock) -+static inline void __queue_me(struct futex_q *q, struct futex_hash_bucket *hb) - { - int prio; - -@@ -2129,6 +2116,24 @@ static inline void queue_me(struct futex - plist_node_init(&q->list, prio); - plist_add(&q->list, &hb->chain); - q->task = current; -+} -+ -+/** -+ * queue_me() - Enqueue the futex_q on the futex_hash_bucket -+ * @q: The futex_q to enqueue -+ * @hb: The destination hash bucket -+ * -+ * The hb->lock must be held by the caller, and is released here. A call to -+ * queue_me() is typically paired with exactly one call to unqueue_me(). The -+ * exceptions involve the PI related operations, which may use unqueue_me_pi() -+ * or nothing if the unqueue is done as part of the wake process and the unqueue -+ * state is implicit in the state of woken task (see futex_wait_requeue_pi() for -+ * an example). -+ */ -+static inline void queue_me(struct futex_q *q, struct futex_hash_bucket *hb) -+ __releases(&hb->lock) -+{ -+ __queue_me(q, hb); - spin_unlock(&hb->lock); - } - -@@ -2587,6 +2592,7 @@ static int futex_lock_pi(u32 __user *uad - { - struct hrtimer_sleeper timeout, *to = NULL; - struct futex_pi_state *pi_state = NULL; -+ struct rt_mutex_waiter rt_waiter; - struct futex_hash_bucket *hb; - struct futex_q q = futex_q_init; - int res, ret; -@@ -2639,25 +2645,52 @@ static int futex_lock_pi(u32 __user *uad - } - } - -+ WARN_ON(!q.pi_state); -+ - /* - * Only actually queue now that the atomic ops are done: - */ -- queue_me(&q, hb); -+ __queue_me(&q, hb); - -- WARN_ON(!q.pi_state); -- /* -- * Block on the PI mutex: -- */ -- if (!trylock) { -- ret = rt_mutex_timed_futex_lock(&q.pi_state->pi_mutex, to); -- } else { -+ if (trylock) { - ret = rt_mutex_futex_trylock(&q.pi_state->pi_mutex); - /* Fixup the trylock return value: */ - ret = ret ? 0 : -EWOULDBLOCK; -+ goto no_block; - } - -+ /* -+ * We must add ourselves to the rt_mutex waitlist while holding hb->lock -+ * such that the hb and rt_mutex wait lists match. -+ */ -+ rt_mutex_init_waiter(&rt_waiter); -+ ret = rt_mutex_start_proxy_lock(&q.pi_state->pi_mutex, &rt_waiter, current); -+ if (ret) { -+ if (ret == 1) -+ ret = 0; -+ -+ goto no_block; -+ } -+ -+ spin_unlock(q.lock_ptr); -+ -+ if (unlikely(to)) -+ hrtimer_start_expires(&to->timer, HRTIMER_MODE_ABS); -+ -+ ret = rt_mutex_wait_proxy_lock(&q.pi_state->pi_mutex, to, &rt_waiter); -+ - spin_lock(q.lock_ptr); - /* -+ * If we failed to acquire the lock (signal/timeout), we must -+ * first acquire the hb->lock before removing the lock from the -+ * rt_mutex waitqueue, such that we can keep the hb and rt_mutex -+ * wait lists consistent. -+ */ -+ if (ret && !rt_mutex_cleanup_proxy_lock(&q.pi_state->pi_mutex, &rt_waiter)) -+ ret = 0; -+ -+no_block: -+ /* - * Fixup the pi_state owner and possibly acquire the lock if we - * haven't already. - */ ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -1493,19 +1493,6 @@ int __sched rt_mutex_lock_interruptible( - EXPORT_SYMBOL_GPL(rt_mutex_lock_interruptible); - - /* -- * Futex variant with full deadlock detection. -- * Futex variants must not use the fast-path, see __rt_mutex_futex_unlock(). -- */ --int __sched rt_mutex_timed_futex_lock(struct rt_mutex *lock, -- struct hrtimer_sleeper *timeout) --{ -- might_sleep(); -- -- return rt_mutex_slowlock(lock, TASK_INTERRUPTIBLE, -- timeout, RT_MUTEX_FULL_CHAINWALK); --} -- --/* - * Futex variant, must not use fastpath. - */ - int __sched rt_mutex_futex_trylock(struct rt_mutex *lock) -@@ -1782,12 +1769,6 @@ int rt_mutex_wait_proxy_lock(struct rt_m - /* sleep on the mutex */ - ret = __rt_mutex_slowlock(lock, TASK_INTERRUPTIBLE, to, waiter); - -- /* -- * try_to_take_rt_mutex() sets the waiter bit unconditionally. We might -- * have to fix that up. -- */ -- fixup_rt_mutex_waiters(lock); -- - raw_spin_unlock_irq(&lock->wait_lock); - - return ret; -@@ -1827,6 +1808,13 @@ bool rt_mutex_cleanup_proxy_lock(struct - fixup_rt_mutex_waiters(lock); - cleanup = true; - } -+ -+ /* -+ * try_to_take_rt_mutex() sets the waiter bit unconditionally. We might -+ * have to fix that up. -+ */ -+ fixup_rt_mutex_waiters(lock); -+ - raw_spin_unlock_irq(&lock->wait_lock); - - return cleanup; ---- a/kernel/locking/rtmutex_common.h -+++ b/kernel/locking/rtmutex_common.h -@@ -113,7 +113,6 @@ extern int rt_mutex_wait_proxy_lock(stru - extern bool rt_mutex_cleanup_proxy_lock(struct rt_mutex *lock, - struct rt_mutex_waiter *waiter); - --extern int rt_mutex_timed_futex_lock(struct rt_mutex *l, struct hrtimer_sleeper *to); - extern int rt_mutex_futex_trylock(struct rt_mutex *l); - - extern void rt_mutex_futex_unlock(struct rt_mutex *lock); diff --git a/patches/0011-hrtimer-Allow-remote-hrtimer-enqueue-with-expires_ne.patch b/patches/0011-hrtimer-Allow-remote-hrtimer-enqueue-with-expires_ne.patch index bb487542bcfe..85c85c5f9bba 100644 --- a/patches/0011-hrtimer-Allow-remote-hrtimer-enqueue-with-expires_ne.patch +++ b/patches/0011-hrtimer-Allow-remote-hrtimer-enqueue-with-expires_ne.patch @@ -20,7 +20,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -167,7 +167,7 @@ hrtimer_check_target(struct hrtimer *tim +@@ -168,7 +168,7 @@ hrtimer_check_target(struct hrtimer *tim ktime_t expires; expires = ktime_sub(hrtimer_get_expires(timer), new_base->offset); diff --git a/patches/0011-hwtracing-coresight-etm3x-Use-cpuhp_setup_state_noca.patch b/patches/0011-hwtracing-coresight-etm3x-Use-cpuhp_setup_state_noca.patch deleted file mode 100644 index 97f56da14b53..000000000000 --- a/patches/0011-hwtracing-coresight-etm3x-Use-cpuhp_setup_state_noca.patch +++ /dev/null @@ -1,82 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Wed, 24 May 2017 10:15:22 +0200 -Subject: [PATCH 11/32] hwtracing/coresight-etm3x: Use - cpuhp_setup_state_nocalls_cpuslocked() - -etm_probe() holds get_online_cpus() while invoking -cpuhp_setup_state_nocalls(). - -cpuhp_setup_state_nocalls() invokes get_online_cpus() as well. This is -correct, but prevents the conversion of the hotplug locking to a percpu -rwsem. - -Use cpuhp_setup_state_nocalls_cpuslocked() to avoid the nested -call. Convert *_online_cpus() to the new interfaces while at it. - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Ingo Molnar <mingo@kernel.org> -Acked-by: Mathieu Poirier <mathieu.poirier@linaro.org> -Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: linux-arm-kernel@lists.infradead.org -Link: http://lkml.kernel.org/r/20170524081547.889092478@linutronix.de ---- - drivers/hwtracing/coresight/coresight-etm3x.c | 20 ++++++++++---------- - 1 file changed, 10 insertions(+), 10 deletions(-) - ---- a/drivers/hwtracing/coresight/coresight-etm3x.c -+++ b/drivers/hwtracing/coresight/coresight-etm3x.c -@@ -587,7 +587,7 @@ static void etm_disable_sysfs(struct cor - * after cpu online mask indicates the cpu is offline but before the - * DYING hotplug callback is serviced by the ETM driver. - */ -- get_online_cpus(); -+ cpus_read_lock(); - spin_lock(&drvdata->spinlock); - - /* -@@ -597,7 +597,7 @@ static void etm_disable_sysfs(struct cor - smp_call_function_single(drvdata->cpu, etm_disable_hw, drvdata, 1); - - spin_unlock(&drvdata->spinlock); -- put_online_cpus(); -+ cpus_read_unlock(); - - dev_info(drvdata->dev, "ETM tracing disabled\n"); - } -@@ -795,7 +795,7 @@ static int etm_probe(struct amba_device - - drvdata->cpu = pdata ? pdata->cpu : 0; - -- get_online_cpus(); -+ cpus_read_lock(); - etmdrvdata[drvdata->cpu] = drvdata; - - if (smp_call_function_single(drvdata->cpu, -@@ -803,17 +803,17 @@ static int etm_probe(struct amba_device - dev_err(dev, "ETM arch init failed\n"); - - if (!etm_count++) { -- cpuhp_setup_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING, -- "arm/coresight:starting", -- etm_starting_cpu, etm_dying_cpu); -- ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, -- "arm/coresight:online", -- etm_online_cpu, NULL); -+ cpuhp_setup_state_nocalls_cpuslocked(CPUHP_AP_ARM_CORESIGHT_STARTING, -+ "arm/coresight:starting", -+ etm_starting_cpu, etm_dying_cpu); -+ ret = cpuhp_setup_state_nocalls_cpuslocked(CPUHP_AP_ONLINE_DYN, -+ "arm/coresight:online", -+ etm_online_cpu, NULL); - if (ret < 0) - goto err_arch_supported; - hp_online = ret; - } -- put_online_cpus(); -+ cpus_read_unlock(); - - if (etm_arch_supported(drvdata->arch) == false) { - ret = -EINVAL; diff --git a/patches/0012-async-Adjust-system_state-checks.patch b/patches/0012-async-Adjust-system_state-checks.patch deleted file mode 100644 index 1df1d996665c..000000000000 --- a/patches/0012-async-Adjust-system_state-checks.patch +++ /dev/null @@ -1,60 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Tue, 16 May 2017 20:42:43 +0200 -Subject: [PATCH 12/17] async: Adjust system_state checks - -To enable smp_processor_id() and might_sleep() debug checks earlier, it's -required to add system states between SYSTEM_BOOTING and SYSTEM_RUNNING. - -Adjust the system_state check in async_run_entry_fn() and -async_synchronize_cookie_domain() to handle the extra states. - -Tested-by: Mark Rutland <mark.rutland@arm.com> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Acked-by: Arjan van de Ven <arjan@linux.intel.com> -Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Cc: Linus Torvalds <torvalds@linux-foundation.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Link: http://lkml.kernel.org/r/20170516184735.865155020@linutronix.de -Signed-off-by: Ingo Molnar <mingo@kernel.org> ---- - kernel/async.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/kernel/async.c -+++ b/kernel/async.c -@@ -114,14 +114,14 @@ static void async_run_entry_fn(struct wo - ktime_t uninitialized_var(calltime), delta, rettime; - - /* 1) run (and print duration) */ -- if (initcall_debug && system_state == SYSTEM_BOOTING) { -+ if (initcall_debug && system_state < SYSTEM_RUNNING) { - pr_debug("calling %lli_%pF @ %i\n", - (long long)entry->cookie, - entry->func, task_pid_nr(current)); - calltime = ktime_get(); - } - entry->func(entry->data, entry->cookie); -- if (initcall_debug && system_state == SYSTEM_BOOTING) { -+ if (initcall_debug && system_state < SYSTEM_RUNNING) { - rettime = ktime_get(); - delta = ktime_sub(rettime, calltime); - pr_debug("initcall %lli_%pF returned 0 after %lld usecs\n", -@@ -284,14 +284,14 @@ void async_synchronize_cookie_domain(asy - { - ktime_t uninitialized_var(starttime), delta, endtime; - -- if (initcall_debug && system_state == SYSTEM_BOOTING) { -+ if (initcall_debug && system_state < SYSTEM_RUNNING) { - pr_debug("async_waiting @ %i\n", task_pid_nr(current)); - starttime = ktime_get(); - } - - wait_event(async_done, lowest_in_progress(domain) >= cookie); - -- if (initcall_debug && system_state == SYSTEM_BOOTING) { -+ if (initcall_debug && system_state < SYSTEM_RUNNING) { - endtime = ktime_get(); - delta = ktime_sub(endtime, starttime); - diff --git a/patches/0012-cpufreq-sparc-us2e-Replace-racy-task-affinity-logic.patch b/patches/0012-cpufreq-sparc-us2e-Replace-racy-task-affinity-logic.patch deleted file mode 100644 index abf8a75f5838..000000000000 --- a/patches/0012-cpufreq-sparc-us2e-Replace-racy-task-affinity-logic.patch +++ /dev/null @@ -1,128 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Thu, 13 Apr 2017 10:22:43 +0200 -Subject: [PATCH 12/13] cpufreq/sparc-us2e: Replace racy task affinity logic - -The access to the HBIRD_ESTAR_MODE register in the cpu frequency control -functions must happen on the target CPU. This is achieved by temporarily -setting the affinity of the calling user space thread to the requested CPU -and reset it to the original affinity afterwards. - -That's racy vs. CPU hotplug and concurrent affinity settings for that -thread resulting in code executing on the wrong CPU and overwriting the -new affinity setting. - -Replace it by a straight forward smp function call. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Viresh Kumar <viresh.kumar@linaro.org> -Cc: Fenghua Yu <fenghua.yu@intel.com> -Cc: Tony Luck <tony.luck@intel.com> -Cc: Herbert Xu <herbert@gondor.apana.org.au> -Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: linux-pm@vger.kernel.org -Cc: Lai Jiangshan <jiangshanlai@gmail.com> -Cc: Michael Ellerman <mpe@ellerman.id.au> -Cc: Tejun Heo <tj@kernel.org> -Cc: "David S. Miller" <davem@davemloft.net> -Cc: Len Brown <lenb@kernel.org> -Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1704131020280.2408@nanos -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - drivers/cpufreq/sparc-us2e-cpufreq.c | 45 ++++++++++++++++------------------- - 1 file changed, 21 insertions(+), 24 deletions(-) - ---- a/drivers/cpufreq/sparc-us2e-cpufreq.c -+++ b/drivers/cpufreq/sparc-us2e-cpufreq.c -@@ -118,10 +118,6 @@ static void us2e_transition(unsigned lon - unsigned long clock_tick, - unsigned long old_divisor, unsigned long divisor) - { -- unsigned long flags; -- -- local_irq_save(flags); -- - estar &= ~ESTAR_MODE_DIV_MASK; - - /* This is based upon the state transition diagram in the IIe manual. */ -@@ -152,8 +148,6 @@ static void us2e_transition(unsigned lon - } else { - BUG(); - } -- -- local_irq_restore(flags); - } - - static unsigned long index_to_estar_mode(unsigned int index) -@@ -229,48 +223,51 @@ static unsigned long estar_to_divisor(un - return ret; - } - -+static void __us2e_freq_get(void *arg) -+{ -+ unsigned long *estar = arg; -+ -+ *estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR); -+} -+ - static unsigned int us2e_freq_get(unsigned int cpu) - { -- cpumask_t cpus_allowed; - unsigned long clock_tick, estar; - -- cpumask_copy(&cpus_allowed, ¤t->cpus_allowed); -- set_cpus_allowed_ptr(current, cpumask_of(cpu)); -- - clock_tick = sparc64_get_clock_tick(cpu) / 1000; -- estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR); -- -- set_cpus_allowed_ptr(current, &cpus_allowed); -+ if (smp_call_function_single(cpu, __us2e_freq_get, &estar, 1)) -+ return 0; - - return clock_tick / estar_to_divisor(estar); - } - --static int us2e_freq_target(struct cpufreq_policy *policy, unsigned int index) -+static void __us2e_freq_target(void *arg) - { -- unsigned int cpu = policy->cpu; -+ unsigned int cpu = smp_processor_id(); -+ unsigned int *index = arg; - unsigned long new_bits, new_freq; - unsigned long clock_tick, divisor, old_divisor, estar; -- cpumask_t cpus_allowed; -- -- cpumask_copy(&cpus_allowed, ¤t->cpus_allowed); -- set_cpus_allowed_ptr(current, cpumask_of(cpu)); - - new_freq = clock_tick = sparc64_get_clock_tick(cpu) / 1000; -- new_bits = index_to_estar_mode(index); -- divisor = index_to_divisor(index); -+ new_bits = index_to_estar_mode(*index); -+ divisor = index_to_divisor(*index); - new_freq /= divisor; - - estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR); - - old_divisor = estar_to_divisor(estar); - -- if (old_divisor != divisor) -+ if (old_divisor != divisor) { - us2e_transition(estar, new_bits, clock_tick * 1000, - old_divisor, divisor); -+ } -+} - -- set_cpus_allowed_ptr(current, &cpus_allowed); -+static int us2e_freq_target(struct cpufreq_policy *policy, unsigned int index) -+{ -+ unsigned int cpu = policy->cpu; - -- return 0; -+ return smp_call_function_single(cpu, __us2e_freq_target, &index, 1); - } - - static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy) diff --git a/patches/0012-futex-Futex_unlock_pi-determinism.patch b/patches/0012-futex-Futex_unlock_pi-determinism.patch deleted file mode 100644 index 1715c5c79704..000000000000 --- a/patches/0012-futex-Futex_unlock_pi-determinism.patch +++ /dev/null @@ -1,80 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Wed, 22 Mar 2017 11:35:59 +0100 -Subject: [PATCH] futex: Futex_unlock_pi() determinism - -Upstream commit bebe5b514345f09be2c15e414d076b02ecb9cce8 - -The problem with returning -EAGAIN when the waiter state mismatches is that -it becomes very hard to proof a bounded execution time on the -operation. And seeing that this is a RT operation, this is somewhat -important. - -While in practise; given the previous patch; it will be very unlikely to -ever really take more than one or two rounds, proving so becomes rather -hard. - -However, now that modifying wait_list is done while holding both hb->lock -and wait_lock, the scenario can be avoided entirely by acquiring wait_lock -while still holding hb-lock. Doing a hand-over, without leaving a hole. - -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: juri.lelli@arm.com -Cc: bigeasy@linutronix.de -Cc: xlpang@redhat.com -Cc: rostedt@goodmis.org -Cc: mathieu.desnoyers@efficios.com -Cc: jdesfossez@efficios.com -Cc: dvhart@infradead.org -Cc: bristot@redhat.com -Link: http://lkml.kernel.org/r/20170322104152.112378812@infradead.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/futex.c | 24 +++++++++++------------- - 1 file changed, 11 insertions(+), 13 deletions(-) - ---- a/kernel/futex.c -+++ b/kernel/futex.c -@@ -1398,15 +1398,10 @@ static int wake_futex_pi(u32 __user *uad - DEFINE_WAKE_Q(wake_q); - int ret = 0; - -- raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock); - new_owner = rt_mutex_next_owner(&pi_state->pi_mutex); -- if (!new_owner) { -+ if (WARN_ON_ONCE(!new_owner)) { - /* -- * Since we held neither hb->lock nor wait_lock when coming -- * into this function, we could have raced with futex_lock_pi() -- * such that we might observe @this futex_q waiter, but the -- * rt_mutex's wait_list can be empty (either still, or again, -- * depending on which side we land). -+ * As per the comment in futex_unlock_pi() this should not happen. - * - * When this happens, give up our locks and try again, giving - * the futex_lock_pi() instance time to complete, either by -@@ -2794,15 +2789,18 @@ static int futex_unlock_pi(u32 __user *u - if (pi_state->owner != current) - goto out_unlock; - -+ get_pi_state(pi_state); - /* -- * Grab a reference on the pi_state and drop hb->lock. -+ * Since modifying the wait_list is done while holding both -+ * hb->lock and wait_lock, holding either is sufficient to -+ * observe it. - * -- * The reference ensures pi_state lives, dropping the hb->lock -- * is tricky.. wake_futex_pi() will take rt_mutex::wait_lock to -- * close the races against futex_lock_pi(), but in case of -- * _any_ fail we'll abort and retry the whole deal. -+ * By taking wait_lock while still holding hb->lock, we ensure -+ * there is no point where we hold neither; and therefore -+ * wake_futex_pi() must observe a state consistent with what we -+ * observed. - */ -- get_pi_state(pi_state); -+ raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock); - spin_unlock(&hb->lock); - - ret = wake_futex_pi(uaddr, uval, pi_state); diff --git a/patches/0012-hrtimer-Simplify-hrtimer_reprogram-call.patch b/patches/0012-hrtimer-Simplify-hrtimer_reprogram-call.patch index 5a9e6afcef4c..1735b2b9e521 100644 --- a/patches/0012-hrtimer-Simplify-hrtimer_reprogram-call.patch +++ b/patches/0012-hrtimer-Simplify-hrtimer_reprogram-call.patch @@ -14,7 +14,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -649,10 +649,10 @@ static inline void retrigger_next_event( +@@ -650,10 +650,10 @@ static inline void retrigger_next_event( * * Called with interrupts disabled and base->cpu_base.lock held */ @@ -27,7 +27,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ktime_t expires = ktime_sub(hrtimer_get_expires(timer), base->offset); WARN_ON_ONCE(hrtimer_get_expires_tv64(timer) < 0); -@@ -943,7 +943,7 @@ void hrtimer_start_range_ns(struct hrtim +@@ -944,7 +944,7 @@ void hrtimer_start_range_ns(struct hrtim if (!leftmost) goto unlock; diff --git a/patches/0012-hwtracing-coresight-etm4x-Use-cpuhp_setup_state_noca.patch b/patches/0012-hwtracing-coresight-etm4x-Use-cpuhp_setup_state_noca.patch deleted file mode 100644 index 8006cbac7daa..000000000000 --- a/patches/0012-hwtracing-coresight-etm4x-Use-cpuhp_setup_state_noca.patch +++ /dev/null @@ -1,83 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Wed, 24 May 2017 10:15:23 +0200 -Subject: [PATCH 12/32] hwtracing/coresight-etm4x: Use - cpuhp_setup_state_nocalls_cpuslocked() - -etm_probe4() holds get_online_cpus() while invoking -cpuhp_setup_state_nocalls(). - -cpuhp_setup_state_nocalls() invokes get_online_cpus() as well. This is -correct, but prevents the conversion of the hotplug locking to a percpu -rwsem. - -Use cpuhp_setup_state_nocalls_cpuslocked() to avoid the nested -call. Convert *_online_cpus() to the new interfaces while at it. - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Ingo Molnar <mingo@kernel.org> -Acked-by: Mathieu Poirier <mathieu.poirier@linaro.org> -Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: linux-arm-kernel@lists.infradead.org -Link: http://lkml.kernel.org/r/20170524081547.983493849@linutronix.de ---- - drivers/hwtracing/coresight/coresight-etm4x.c | 20 ++++++++++---------- - 1 file changed, 10 insertions(+), 10 deletions(-) - ---- a/drivers/hwtracing/coresight/coresight-etm4x.c -+++ b/drivers/hwtracing/coresight/coresight-etm4x.c -@@ -371,7 +371,7 @@ static void etm4_disable_sysfs(struct co - * after cpu online mask indicates the cpu is offline but before the - * DYING hotplug callback is serviced by the ETM driver. - */ -- get_online_cpus(); -+ cpus_read_lock(); - spin_lock(&drvdata->spinlock); - - /* -@@ -381,7 +381,7 @@ static void etm4_disable_sysfs(struct co - smp_call_function_single(drvdata->cpu, etm4_disable_hw, drvdata, 1); - - spin_unlock(&drvdata->spinlock); -- put_online_cpus(); -+ cpus_read_unlock(); - - dev_info(drvdata->dev, "ETM tracing disabled\n"); - } -@@ -982,7 +982,7 @@ static int etm4_probe(struct amba_device - - drvdata->cpu = pdata ? pdata->cpu : 0; - -- get_online_cpus(); -+ cpus_read_lock(); - etmdrvdata[drvdata->cpu] = drvdata; - - if (smp_call_function_single(drvdata->cpu, -@@ -990,18 +990,18 @@ static int etm4_probe(struct amba_device - dev_err(dev, "ETM arch init failed\n"); - - if (!etm4_count++) { -- cpuhp_setup_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING, -- "arm/coresight4:starting", -- etm4_starting_cpu, etm4_dying_cpu); -- ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, -- "arm/coresight4:online", -- etm4_online_cpu, NULL); -+ cpuhp_setup_state_nocalls_cpuslocked(CPUHP_AP_ARM_CORESIGHT_STARTING, -+ "arm/coresight4:starting", -+ etm4_starting_cpu, etm4_dying_cpu); -+ ret = cpuhp_setup_state_nocalls_cpuslocked(CPUHP_AP_ONLINE_DYN, -+ "arm/coresight4:online", -+ etm4_online_cpu, NULL); - if (ret < 0) - goto err_arch_supported; - hp_online = ret; - } - -- put_online_cpus(); -+ cpus_read_unlock(); - - if (etm4_arch_supported(drvdata->arch) == false) { - ret = -EINVAL; diff --git a/patches/0013-crypto-N2-Replace-racy-task-affinity-logic.patch b/patches/0013-crypto-N2-Replace-racy-task-affinity-logic.patch deleted file mode 100644 index d76c717cf650..000000000000 --- a/patches/0013-crypto-N2-Replace-racy-task-affinity-logic.patch +++ /dev/null @@ -1,94 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Thu, 13 Apr 2017 10:20:23 +0200 -Subject: [PATCH 13/13] crypto: N2 - Replace racy task affinity logic - -spu_queue_register() needs to invoke setup functions on a particular -CPU. This is achieved by temporarily setting the affinity of the -calling user space thread to the requested CPU and reset it to the original -affinity afterwards. - -That's racy vs. CPU hotplug and concurrent affinity settings for that -thread resulting in code executing on the wrong CPU and overwriting the -new affinity setting. - -Replace it by using work_on_cpu_safe() which guarantees to run the code on -the requested CPU or to fail in case the CPU is offline. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Herbert Xu <herbert@gondor.apana.org.au> -Acked-by: "David S. Miller" <davem@davemloft.net> -Cc: Fenghua Yu <fenghua.yu@intel.com> -Cc: Tony Luck <tony.luck@intel.com> -Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Lai Jiangshan <jiangshanlai@gmail.com> -Cc: Viresh Kumar <viresh.kumar@linaro.org> -Cc: linux-crypto@vger.kernel.org -Cc: Michael Ellerman <mpe@ellerman.id.au> -Cc: Tejun Heo <tj@kernel.org> -Cc: Len Brown <lenb@kernel.org> -Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1704131019420.2408@nanos -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - drivers/crypto/n2_core.c | 31 ++++++++++++++++--------------- - 1 file changed, 16 insertions(+), 15 deletions(-) - ---- a/drivers/crypto/n2_core.c -+++ b/drivers/crypto/n2_core.c -@@ -65,6 +65,11 @@ struct spu_queue { - struct list_head list; - }; - -+struct spu_qreg { -+ struct spu_queue *queue; -+ unsigned long type; -+}; -+ - static struct spu_queue **cpu_to_cwq; - static struct spu_queue **cpu_to_mau; - -@@ -1631,31 +1636,27 @@ static void queue_cache_destroy(void) - kmem_cache_destroy(queue_cache[HV_NCS_QTYPE_CWQ - 1]); - } - --static int spu_queue_register(struct spu_queue *p, unsigned long q_type) -+static long spu_queue_register_workfn(void *arg) - { -- cpumask_var_t old_allowed; -+ struct spu_qreg *qr = arg; -+ struct spu_queue *p = qr->queue; -+ unsigned long q_type = qr->type; - unsigned long hv_ret; - -- if (cpumask_empty(&p->sharing)) -- return -EINVAL; -- -- if (!alloc_cpumask_var(&old_allowed, GFP_KERNEL)) -- return -ENOMEM; -- -- cpumask_copy(old_allowed, ¤t->cpus_allowed); -- -- set_cpus_allowed_ptr(current, &p->sharing); -- - hv_ret = sun4v_ncs_qconf(q_type, __pa(p->q), - CWQ_NUM_ENTRIES, &p->qhandle); - if (!hv_ret) - sun4v_ncs_sethead_marker(p->qhandle, 0); - -- set_cpus_allowed_ptr(current, old_allowed); -+ return hv_ret ? -EINVAL : 0; -+} - -- free_cpumask_var(old_allowed); -+static int spu_queue_register(struct spu_queue *p, unsigned long q_type) -+{ -+ int cpu = cpumask_any_and(&p->sharing, cpu_online_mask); -+ struct spu_qreg qr = { .queue = p, .type = q_type }; - -- return (hv_ret ? -EINVAL : 0); -+ return work_on_cpu_safe(cpu, spu_queue_register_workfn, &qr); - } - - static int spu_queue_setup(struct spu_queue *p) diff --git a/patches/0013-extable-Adjust-system_state-checks.patch b/patches/0013-extable-Adjust-system_state-checks.patch deleted file mode 100644 index 27d43e42325b..000000000000 --- a/patches/0013-extable-Adjust-system_state-checks.patch +++ /dev/null @@ -1,35 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Tue, 16 May 2017 20:42:44 +0200 -Subject: [PATCH 13/17] extable: Adjust system_state checks - -To enable smp_processor_id() and might_sleep() debug checks earlier, it's -required to add system states between SYSTEM_BOOTING and SYSTEM_RUNNING. - -Adjust the system_state check in core_kernel_text() to handle the extra -states, i.e. to cover init text up to the point where the system switches -to state RUNNING. - -Tested-by: Mark Rutland <mark.rutland@arm.com> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Reviewed-by: Steven Rostedt (VMware) <rostedt@goodmis.org> -Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Cc: Linus Torvalds <torvalds@linux-foundation.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Link: http://lkml.kernel.org/r/20170516184735.949992741@linutronix.de -Signed-off-by: Ingo Molnar <mingo@kernel.org> ---- - kernel/extable.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/kernel/extable.c -+++ b/kernel/extable.c -@@ -75,7 +75,7 @@ int notrace core_kernel_text(unsigned lo - addr < (unsigned long)_etext) - return 1; - -- if (system_state == SYSTEM_BOOTING && -+ if (system_state < SYSTEM_RUNNING && - init_kernel_text(addr)) - return 1; - return 0; diff --git a/patches/0013-futex-Drop-hb-lock-before-enqueueing-on-the-rtmutex.patch b/patches/0013-futex-Drop-hb-lock-before-enqueueing-on-the-rtmutex.patch deleted file mode 100644 index f6e22ae19ffd..000000000000 --- a/patches/0013-futex-Drop-hb-lock-before-enqueueing-on-the-rtmutex.patch +++ /dev/null @@ -1,203 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Wed, 22 Mar 2017 11:36:00 +0100 -Subject: [PATCH] futex: Drop hb->lock before enqueueing on the rtmutex - -Upstream commit 56222b212e8edb1cf51f5dd73ff645809b082b40 - -When PREEMPT_RT_FULL does the spinlock -> rt_mutex substitution the PI -chain code will (falsely) report a deadlock and BUG. - -The problem is that it hold hb->lock (now an rt_mutex) while doing -task_blocks_on_rt_mutex on the futex's pi_state::rtmutex. This, when -interleaved just right with futex_unlock_pi() leads it to believe to see an -AB-BA deadlock. - - Task1 (holds rt_mutex, Task2 (does FUTEX_LOCK_PI) - does FUTEX_UNLOCK_PI) - - lock hb->lock - lock rt_mutex (as per start_proxy) - lock hb->lock - -Which is a trivial AB-BA. - -It is not an actual deadlock, because it won't be holding hb->lock by the -time it actually blocks on the rt_mutex, but the chainwalk code doesn't -know that and it would be a nightmare to handle this gracefully. - -To avoid this problem, do the same as in futex_unlock_pi() and drop -hb->lock after acquiring wait_lock. This still fully serializes against -futex_unlock_pi(), since adding to the wait_list does the very same lock -dance, and removing it holds both locks. - -Aside of solving the RT problem this makes the lock and unlock mechanism -symetric and reduces the hb->lock held time. - -Reported-and-tested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Suggested-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: juri.lelli@arm.com -Cc: xlpang@redhat.com -Cc: rostedt@goodmis.org -Cc: mathieu.desnoyers@efficios.com -Cc: jdesfossez@efficios.com -Cc: dvhart@infradead.org -Cc: bristot@redhat.com -Link: http://lkml.kernel.org/r/20170322104152.161341537@infradead.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/futex.c | 30 +++++++++++++++++------- - kernel/locking/rtmutex.c | 49 ++++++++++++++++++++++------------------ - kernel/locking/rtmutex_common.h | 3 ++ - 3 files changed, 52 insertions(+), 30 deletions(-) - ---- a/kernel/futex.c -+++ b/kernel/futex.c -@@ -2654,20 +2654,33 @@ static int futex_lock_pi(u32 __user *uad - goto no_block; - } - -+ rt_mutex_init_waiter(&rt_waiter); -+ - /* -- * We must add ourselves to the rt_mutex waitlist while holding hb->lock -- * such that the hb and rt_mutex wait lists match. -+ * On PREEMPT_RT_FULL, when hb->lock becomes an rt_mutex, we must not -+ * hold it while doing rt_mutex_start_proxy(), because then it will -+ * include hb->lock in the blocking chain, even through we'll not in -+ * fact hold it while blocking. This will lead it to report -EDEADLK -+ * and BUG when futex_unlock_pi() interleaves with this. -+ * -+ * Therefore acquire wait_lock while holding hb->lock, but drop the -+ * latter before calling rt_mutex_start_proxy_lock(). This still fully -+ * serializes against futex_unlock_pi() as that does the exact same -+ * lock handoff sequence. - */ -- rt_mutex_init_waiter(&rt_waiter); -- ret = rt_mutex_start_proxy_lock(&q.pi_state->pi_mutex, &rt_waiter, current); -+ raw_spin_lock_irq(&q.pi_state->pi_mutex.wait_lock); -+ spin_unlock(q.lock_ptr); -+ ret = __rt_mutex_start_proxy_lock(&q.pi_state->pi_mutex, &rt_waiter, current); -+ raw_spin_unlock_irq(&q.pi_state->pi_mutex.wait_lock); -+ - if (ret) { - if (ret == 1) - ret = 0; - -+ spin_lock(q.lock_ptr); - goto no_block; - } - -- spin_unlock(q.lock_ptr); - - if (unlikely(to)) - hrtimer_start_expires(&to->timer, HRTIMER_MODE_ABS); -@@ -2680,6 +2693,9 @@ static int futex_lock_pi(u32 __user *uad - * first acquire the hb->lock before removing the lock from the - * rt_mutex waitqueue, such that we can keep the hb and rt_mutex - * wait lists consistent. -+ * -+ * In particular; it is important that futex_unlock_pi() can not -+ * observe this inconsistency. - */ - if (ret && !rt_mutex_cleanup_proxy_lock(&q.pi_state->pi_mutex, &rt_waiter)) - ret = 0; -@@ -2791,10 +2807,6 @@ static int futex_unlock_pi(u32 __user *u - - get_pi_state(pi_state); - /* -- * Since modifying the wait_list is done while holding both -- * hb->lock and wait_lock, holding either is sufficient to -- * observe it. -- * - * By taking wait_lock while still holding hb->lock, we ensure - * there is no point where we hold neither; and therefore - * wake_futex_pi() must observe a state consistent with what we ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -1669,31 +1669,14 @@ void rt_mutex_proxy_unlock(struct rt_mut - rt_mutex_set_owner(lock, NULL); - } - --/** -- * rt_mutex_start_proxy_lock() - Start lock acquisition for another task -- * @lock: the rt_mutex to take -- * @waiter: the pre-initialized rt_mutex_waiter -- * @task: the task to prepare -- * -- * Returns: -- * 0 - task blocked on lock -- * 1 - acquired the lock for task, caller should wake it up -- * <0 - error -- * -- * Special API call for FUTEX_REQUEUE_PI support. -- */ --int rt_mutex_start_proxy_lock(struct rt_mutex *lock, -+int __rt_mutex_start_proxy_lock(struct rt_mutex *lock, - struct rt_mutex_waiter *waiter, - struct task_struct *task) - { - int ret; - -- raw_spin_lock_irq(&lock->wait_lock); -- -- if (try_to_take_rt_mutex(lock, task, NULL)) { -- raw_spin_unlock_irq(&lock->wait_lock); -+ if (try_to_take_rt_mutex(lock, task, NULL)) - return 1; -- } - - /* We enforce deadlock detection for futexes */ - ret = task_blocks_on_rt_mutex(lock, waiter, task, -@@ -1712,12 +1695,36 @@ int rt_mutex_start_proxy_lock(struct rt_ - if (unlikely(ret)) - remove_waiter(lock, waiter); - -- raw_spin_unlock_irq(&lock->wait_lock); -- - debug_rt_mutex_print_deadlock(waiter); - - return ret; - } -+ -+/** -+ * rt_mutex_start_proxy_lock() - Start lock acquisition for another task -+ * @lock: the rt_mutex to take -+ * @waiter: the pre-initialized rt_mutex_waiter -+ * @task: the task to prepare -+ * -+ * Returns: -+ * 0 - task blocked on lock -+ * 1 - acquired the lock for task, caller should wake it up -+ * <0 - error -+ * -+ * Special API call for FUTEX_REQUEUE_PI support. -+ */ -+int rt_mutex_start_proxy_lock(struct rt_mutex *lock, -+ struct rt_mutex_waiter *waiter, -+ struct task_struct *task) -+{ -+ int ret; -+ -+ raw_spin_lock_irq(&lock->wait_lock); -+ ret = __rt_mutex_start_proxy_lock(lock, waiter, task); -+ raw_spin_unlock_irq(&lock->wait_lock); -+ -+ return ret; -+} - - /** - * rt_mutex_next_owner - return the next owner of the lock ---- a/kernel/locking/rtmutex_common.h -+++ b/kernel/locking/rtmutex_common.h -@@ -104,6 +104,9 @@ extern void rt_mutex_init_proxy_locked(s - extern void rt_mutex_proxy_unlock(struct rt_mutex *lock, - struct task_struct *proxy_owner); - extern void rt_mutex_init_waiter(struct rt_mutex_waiter *waiter); -+extern int __rt_mutex_start_proxy_lock(struct rt_mutex *lock, -+ struct rt_mutex_waiter *waiter, -+ struct task_struct *task); - extern int rt_mutex_start_proxy_lock(struct rt_mutex *lock, - struct rt_mutex_waiter *waiter, - struct task_struct *task); diff --git a/patches/0013-hrtimer-Split-out-code-from-hrtimer_start_range_ns-f.patch b/patches/0013-hrtimer-Split-out-code-from-hrtimer_start_range_ns-f.patch index bf58aaf3b34b..6ae61f41b2fa 100644 --- a/patches/0013-hrtimer-Split-out-code-from-hrtimer_start_range_ns-f.patch +++ b/patches/0013-hrtimer-Split-out-code-from-hrtimer_start_range_ns-f.patch @@ -13,7 +13,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -909,22 +909,11 @@ static inline ktime_t hrtimer_update_low +@@ -910,22 +910,11 @@ static inline ktime_t hrtimer_update_low return tim; } @@ -40,7 +40,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* Remove an active timer from the queue: */ remove_hrtimer(timer, base, true); -@@ -939,13 +928,28 @@ void hrtimer_start_range_ns(struct hrtim +@@ -940,13 +929,28 @@ void hrtimer_start_range_ns(struct hrtim /* Switch the timer base, if necessary: */ new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED); diff --git a/patches/0013-perf-x86-intel-cqm-Use-cpuhp_setup_state_cpuslocked.patch b/patches/0013-perf-x86-intel-cqm-Use-cpuhp_setup_state_cpuslocked.patch deleted file mode 100644 index edb975571664..000000000000 --- a/patches/0013-perf-x86-intel-cqm-Use-cpuhp_setup_state_cpuslocked.patch +++ /dev/null @@ -1,58 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Wed, 24 May 2017 10:15:24 +0200 -Subject: [PATCH 13/32] perf/x86/intel/cqm: Use cpuhp_setup_state_cpuslocked() - -intel_cqm_init() holds get_online_cpus() while registerring the hotplug -callbacks. - -cpuhp_setup_state() invokes get_online_cpus() as well. This is correct, but -prevents the conversion of the hotplug locking to a percpu rwsem. - -Use cpuhp_setup_state_cpuslocked() to avoid the nested call. Convert -*_online_cpus() to the new interfaces while at it. - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Ingo Molnar <mingo@kernel.org> -Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Cc: Fenghua Yu <fenghua.yu@intel.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Link: http://lkml.kernel.org/r/20170524081548.075604046@linutronix.de ---- - arch/x86/events/intel/cqm.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - ---- a/arch/x86/events/intel/cqm.c -+++ b/arch/x86/events/intel/cqm.c -@@ -1682,7 +1682,7 @@ static int __init intel_cqm_init(void) - * - * Also, check that the scales match on all cpus. - */ -- get_online_cpus(); -+ cpus_read_lock(); - for_each_online_cpu(cpu) { - struct cpuinfo_x86 *c = &cpu_data(cpu); - -@@ -1746,14 +1746,14 @@ static int __init intel_cqm_init(void) - * Setup the hot cpu notifier once we are sure cqm - * is enabled to avoid notifier leak. - */ -- cpuhp_setup_state(CPUHP_AP_PERF_X86_CQM_STARTING, -- "perf/x86/cqm:starting", -- intel_cqm_cpu_starting, NULL); -- cpuhp_setup_state(CPUHP_AP_PERF_X86_CQM_ONLINE, "perf/x86/cqm:online", -- NULL, intel_cqm_cpu_exit); -- -+ cpuhp_setup_state_cpuslocked(CPUHP_AP_PERF_X86_CQM_STARTING, -+ "perf/x86/cqm:starting", -+ intel_cqm_cpu_starting, NULL); -+ cpuhp_setup_state_cpuslocked(CPUHP_AP_PERF_X86_CQM_ONLINE, -+ "perf/x86/cqm:online", -+ NULL, intel_cqm_cpu_exit); - out: -- put_online_cpus(); -+ cpus_read_unlock(); - - if (ret) { - kfree(str); diff --git a/patches/0013-tracing-Make-traceprobe-parsing-code-reusable.patch b/patches/0013-tracing-Make-traceprobe-parsing-code-reusable.patch index 05a7bbd6da53..4c1702e3367d 100644 --- a/patches/0013-tracing-Make-traceprobe-parsing-code-reusable.patch +++ b/patches/0013-tracing-Make-traceprobe-parsing-code-reusable.patch @@ -24,7 +24,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c -@@ -7922,6 +7922,92 @@ void ftrace_dump(enum ftrace_dump_mode o +@@ -8304,6 +8304,92 @@ void ftrace_dump(enum ftrace_dump_mode o } EXPORT_SYMBOL_GPL(ftrace_dump); @@ -119,7 +119,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> int ring_buf_size; --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h -@@ -1651,6 +1651,13 @@ void trace_printk_start_comm(void); +@@ -1755,6 +1755,13 @@ void trace_printk_start_comm(void); int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set); int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled); @@ -135,7 +135,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * to do the manipulation, as well as saves the print formats --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c -@@ -873,8 +873,8 @@ static int probes_open(struct inode *ino +@@ -907,8 +907,8 @@ static int probes_open(struct inode *ino static ssize_t probes_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { @@ -146,7 +146,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } static const struct file_operations kprobe_events_ops = { -@@ -1399,9 +1399,9 @@ static __init int kprobe_trace_self_test +@@ -1433,9 +1433,9 @@ static __init int kprobe_trace_self_test pr_info("Testing kprobe tracing: "); @@ -159,7 +159,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (WARN_ON_ONCE(ret)) { pr_warn("error on probing function entry.\n"); warn++; -@@ -1421,8 +1421,8 @@ static __init int kprobe_trace_self_test +@@ -1455,8 +1455,8 @@ static __init int kprobe_trace_self_test } } @@ -170,7 +170,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (WARN_ON_ONCE(ret)) { pr_warn("error on probing function return.\n"); warn++; -@@ -1492,13 +1492,13 @@ static __init int kprobe_trace_self_test +@@ -1526,13 +1526,13 @@ static __init int kprobe_trace_self_test disable_trace_kprobe(tk, file); } diff --git a/patches/0014-ARM-hw_breakpoint-Use-cpuhp_setup_state_cpuslocked.patch b/patches/0014-ARM-hw_breakpoint-Use-cpuhp_setup_state_cpuslocked.patch deleted file mode 100644 index fa6bcdef18e3..000000000000 --- a/patches/0014-ARM-hw_breakpoint-Use-cpuhp_setup_state_cpuslocked.patch +++ /dev/null @@ -1,68 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Wed, 24 May 2017 10:15:25 +0200 -Subject: [PATCH 14/32] ARM/hw_breakpoint: Use cpuhp_setup_state_cpuslocked() - -arch_hw_breakpoint_init() holds get_online_cpus() while registerring the -hotplug callbacks. - -cpuhp_setup_state() invokes get_online_cpus() as well. This is correct, but -prevents the conversion of the hotplug locking to a percpu rwsem. - -Use cpuhp_setup_state_cpuslocked() to avoid the nested call. Convert -*_online_cpus() to the new interfaces while at it. - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Ingo Molnar <mingo@kernel.org> -Acked-by: Mark Rutland <mark.rutland@arm.com> -Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Will Deacon <will.deacon@arm.com> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: Russell King <linux@armlinux.org.uk> -Cc: linux-arm-kernel@lists.infradead.org -Link: http://lkml.kernel.org/r/20170524081548.170940729@linutronix.de ---- - arch/arm/kernel/hw_breakpoint.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - ---- a/arch/arm/kernel/hw_breakpoint.c -+++ b/arch/arm/kernel/hw_breakpoint.c -@@ -1090,7 +1090,7 @@ static int __init arch_hw_breakpoint_ini - * driven low on this core and there isn't an architected way to - * determine that. - */ -- get_online_cpus(); -+ cpus_read_lock(); - register_undef_hook(&debug_reg_hook); - - /* -@@ -1098,15 +1098,16 @@ static int __init arch_hw_breakpoint_ini - * assume that a halting debugger will leave the world in a nice state - * for us. - */ -- ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "arm/hw_breakpoint:online", -- dbg_reset_online, NULL); -+ ret = cpuhp_setup_state_cpuslocked(CPUHP_AP_ONLINE_DYN, -+ "arm/hw_breakpoint:online", -+ dbg_reset_online, NULL); - unregister_undef_hook(&debug_reg_hook); - if (WARN_ON(ret < 0) || !cpumask_empty(&debug_err_mask)) { - core_num_brps = 0; - core_num_wrps = 0; - if (ret > 0) - cpuhp_remove_state_nocalls(ret); -- put_online_cpus(); -+ cpus_read_unlock(); - return 0; - } - -@@ -1124,7 +1125,7 @@ static int __init arch_hw_breakpoint_ini - TRAP_HWBKPT, "watchpoint debug exception"); - hook_ifault_code(FAULT_CODE_DEBUG, hw_breakpoint_pending, SIGTRAP, - TRAP_HWBKPT, "breakpoint debug exception"); -- put_online_cpus(); -+ cpus_read_unlock(); - - /* Register PM notifiers. */ - pm_init(); diff --git a/patches/0014-hrtimer-Split-out-code-from-__hrtimer_get_next_event.patch b/patches/0014-hrtimer-Split-out-code-from-__hrtimer_get_next_event.patch index 60d8443773a8..1590a8ddb010 100644 --- a/patches/0014-hrtimer-Split-out-code-from-__hrtimer_get_next_event.patch +++ b/patches/0014-hrtimer-Split-out-code-from-__hrtimer_get_next_event.patch @@ -13,7 +13,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -453,12 +453,12 @@ static inline void hrtimer_update_next_t +@@ -454,12 +454,12 @@ static inline void hrtimer_update_next_t } #if defined(CONFIG_NO_HZ_COMMON) || defined(CONFIG_HIGH_RES_TIMERS) @@ -30,7 +30,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> while (active) { unsigned int id = __ffs(active); struct hrtimer_clock_base *base; -@@ -485,6 +485,18 @@ static ktime_t __hrtimer_get_next_event( +@@ -486,6 +486,18 @@ static ktime_t __hrtimer_get_next_event( expires_next = 0; return expires_next; } diff --git a/patches/0014-printk-Adjust-system_state-checks.patch b/patches/0014-printk-Adjust-system_state-checks.patch deleted file mode 100644 index c729a84a04cc..000000000000 --- a/patches/0014-printk-Adjust-system_state-checks.patch +++ /dev/null @@ -1,34 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Tue, 16 May 2017 20:42:45 +0200 -Subject: [PATCH 14/17] printk: Adjust system_state checks - -To enable smp_processor_id() and might_sleep() debug checks earlier, it's -required to add system states between SYSTEM_BOOTING and SYSTEM_RUNNING. - -Adjust the system_state check in boot_delay_msec() to handle the extra -states. - -Tested-by: Mark Rutland <mark.rutland@arm.com> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Reviewed-by: Steven Rostedt (VMware) <rostedt@goodmis.org> -Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Cc: Linus Torvalds <torvalds@linux-foundation.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Link: http://lkml.kernel.org/r/20170516184736.027534895@linutronix.de -Signed-off-by: Ingo Molnar <mingo@kernel.org> ---- - kernel/printk/printk.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/kernel/printk/printk.c -+++ b/kernel/printk/printk.c -@@ -1176,7 +1176,7 @@ static void boot_delay_msec(int level) - unsigned long long k; - unsigned long timeout; - -- if ((boot_delay == 0 || system_state != SYSTEM_BOOTING) -+ if ((boot_delay == 0 || system_state >= SYSTEM_RUNNING) - || suppress_message_printing(level)) { - return; - } diff --git a/patches/0015-hrtimer-Add-clock-bases-for-soft-irq-context.patch b/patches/0015-hrtimer-Add-clock-bases-for-soft-irq-context.patch index d41f8866cb79..688dabb3543d 100644 --- a/patches/0015-hrtimer-Add-clock-bases-for-soft-irq-context.patch +++ b/patches/0015-hrtimer-Add-clock-bases-for-soft-irq-context.patch @@ -35,7 +35,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -59,6 +59,18 @@ +@@ -60,6 +60,18 @@ #include "tick-internal.h" /* @@ -54,7 +54,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * The timer bases: * * There are more clockids than hrtimer bases. Thus, we index -@@ -91,17 +103,43 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, +@@ -92,17 +104,43 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, .clockid = CLOCK_TAI, .get_time = &ktime_get_clocktai, }, @@ -104,7 +104,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> }; /* -@@ -1632,6 +1670,12 @@ int hrtimers_dead_cpu(unsigned int scpu) +@@ -1652,6 +1690,12 @@ int hrtimers_dead_cpu(unsigned int scpu) void __init hrtimers_init(void) { diff --git a/patches/0015-mm-vmscan-Adjust-system_state-checks.patch b/patches/0015-mm-vmscan-Adjust-system_state-checks.patch deleted file mode 100644 index 8c06086f2d2d..000000000000 --- a/patches/0015-mm-vmscan-Adjust-system_state-checks.patch +++ /dev/null @@ -1,38 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Tue, 16 May 2017 20:42:46 +0200 -Subject: [PATCH 15/17] mm/vmscan: Adjust system_state checks - -To enable smp_processor_id() and might_sleep() debug checks earlier, it's -required to add system states between SYSTEM_BOOTING and SYSTEM_RUNNING. - -Adjust the system_state check in kswapd_run() to handle the extra states. - -Tested-by: Mark Rutland <mark.rutland@arm.com> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Reviewed-by: Steven Rostedt (VMware) <rostedt@goodmis.org> -Acked-by: Vlastimil Babka <vbabka@suse.cz> -Cc: Andrew Morton <akpm@linux-foundation.org> -Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Cc: Johannes Weiner <hannes@cmpxchg.org> -Cc: Linus Torvalds <torvalds@linux-foundation.org> -Cc: Mel Gorman <mgorman@techsingularity.net> -Cc: Michal Hocko <mhocko@suse.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Link: http://lkml.kernel.org/r/20170516184736.119158930@linutronix.de -Signed-off-by: Ingo Molnar <mingo@kernel.org> ---- - mm/vmscan.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/mm/vmscan.c -+++ b/mm/vmscan.c -@@ -3654,7 +3654,7 @@ int kswapd_run(int nid) - pgdat->kswapd = kthread_run(kswapd, pgdat, "kswapd%d", nid); - if (IS_ERR(pgdat->kswapd)) { - /* failure at boot is fatal */ -- BUG_ON(system_state == SYSTEM_BOOTING); -+ BUG_ON(system_state < SYSTEM_RUNNING); - pr_err("Failed to start kswapd on node %d\n", nid); - ret = PTR_ERR(pgdat->kswapd); - pgdat->kswapd = NULL; diff --git a/patches/0015-s390-kernel-Use-stop_machine_cpuslocked.patch b/patches/0015-s390-kernel-Use-stop_machine_cpuslocked.patch deleted file mode 100644 index 961d6ed653c7..000000000000 --- a/patches/0015-s390-kernel-Use-stop_machine_cpuslocked.patch +++ /dev/null @@ -1,43 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Wed, 24 May 2017 10:15:26 +0200 -Subject: [PATCH 15/32] s390/kernel: Use stop_machine_cpuslocked() - -stp_work_fn() holds get_online_cpus() while invoking stop_machine(). - -stop_machine() invokes get_online_cpus() as well. This is correct, but -prevents the conversion of the hotplug locking to a percpu rwsem. - -Use stop_machine_cpuslocked() to avoid the nested call. Convert -*_online_cpus() to the new interfaces while at it. - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Ingo Molnar <mingo@kernel.org> -Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com> -Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Cc: linux-s390@vger.kernel.org -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: David Hildenbrand <dahi@linux.vnet.ibm.com> -Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> -Link: http://lkml.kernel.org/r/20170524081548.250203087@linutronix.de ---- - arch/s390/kernel/time.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - ---- a/arch/s390/kernel/time.c -+++ b/arch/s390/kernel/time.c -@@ -634,10 +634,10 @@ static void stp_work_fn(struct work_stru - goto out_unlock; - - memset(&stp_sync, 0, sizeof(stp_sync)); -- get_online_cpus(); -+ cpus_read_lock(); - atomic_set(&stp_sync.cpus, num_online_cpus() - 1); -- stop_machine(stp_sync_clock, &stp_sync, cpu_online_mask); -- put_online_cpus(); -+ stop_machine_cpuslocked(stp_sync_clock, &stp_sync, cpu_online_mask); -+ cpus_read_unlock(); - - if (!check_sync_clock()) - /* diff --git a/patches/0015-tracing-Add-per-element-variable-support-to-tracing_.patch b/patches/0015-tracing-Add-per-element-variable-support-to-tracing_.patch index 6ecb342492fe..c06a44682c81 100644 --- a/patches/0015-tracing-Add-per-element-variable-support-to-tracing_.patch +++ b/patches/0015-tracing-Add-per-element-variable-support-to-tracing_.patch @@ -129,7 +129,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * tracing_map_add_key_field - Add a field describing a tracing_map key * @map: The tracing_map * @offset: The offset within the key -@@ -277,6 +366,11 @@ static void tracing_map_elt_clear(struct +@@ -280,6 +369,11 @@ static void tracing_map_elt_clear(struct if (elt->fields[i].cmp_fn == tracing_map_cmp_atomic64) atomic64_set(&elt->fields[i].sum, 0); @@ -141,7 +141,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (elt->map->ops && elt->map->ops->elt_clear) elt->map->ops->elt_clear(elt); } -@@ -303,6 +397,8 @@ static void tracing_map_elt_free(struct +@@ -306,6 +400,8 @@ static void tracing_map_elt_free(struct if (elt->map->ops && elt->map->ops->elt_free) elt->map->ops->elt_free(elt); kfree(elt->fields); @@ -150,7 +150,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> kfree(elt->key); kfree(elt); } -@@ -329,6 +425,18 @@ static struct tracing_map_elt *tracing_m +@@ -332,6 +428,18 @@ static struct tracing_map_elt *tracing_m err = -ENOMEM; goto free; } diff --git a/patches/0016-hrtimer-Allow-function-reuse-for-softirq-based-hrtim.patch b/patches/0016-hrtimer-Allow-function-reuse-for-softirq-based-hrtim.patch index cc38556ae8f4..e2da5a4b28cc 100644 --- a/patches/0016-hrtimer-Allow-function-reuse-for-softirq-based-hrtim.patch +++ b/patches/0016-hrtimer-Allow-function-reuse-for-softirq-based-hrtim.patch @@ -15,7 +15,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -71,6 +71,14 @@ +@@ -72,6 +72,14 @@ #define CLOCK_TAI_SOFT (CLOCK_TAI | HRTIMER_BASE_SOFT_MASK) /* @@ -30,7 +30,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * The timer bases: * * There are more clockids than hrtimer bases. Thus, we index -@@ -526,11 +534,12 @@ static ktime_t __hrtimer_next_event_base +@@ -527,11 +535,12 @@ static ktime_t __hrtimer_next_event_base static ktime_t __hrtimer_get_next_event(struct hrtimer_cpu_base *cpu_base) { @@ -44,7 +44,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> expires_next = __hrtimer_next_event_base(cpu_base, active, expires_next); return expires_next; -@@ -1263,9 +1272,10 @@ static void __run_hrtimer(struct hrtimer +@@ -1264,9 +1273,10 @@ static void __run_hrtimer(struct hrtimer base->running = NULL; } @@ -57,7 +57,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> while (active) { unsigned int id = __ffs(active); -@@ -1332,7 +1342,7 @@ void hrtimer_interrupt(struct clock_even +@@ -1333,7 +1343,7 @@ void hrtimer_interrupt(struct clock_even */ cpu_base->expires_next = KTIME_MAX; @@ -66,7 +66,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* Reevaluate the clock bases for the next expiry */ expires_next = __hrtimer_get_next_event(cpu_base); -@@ -1437,7 +1447,7 @@ void hrtimer_run_queues(void) +@@ -1438,7 +1448,7 @@ void hrtimer_run_queues(void) raw_spin_lock(&cpu_base->lock); now = hrtimer_update_base(cpu_base); diff --git a/patches/0016-init-Introduce-SYSTEM_SCHEDULING-state.patch b/patches/0016-init-Introduce-SYSTEM_SCHEDULING-state.patch deleted file mode 100644 index bbf5c6fc82b7..000000000000 --- a/patches/0016-init-Introduce-SYSTEM_SCHEDULING-state.patch +++ /dev/null @@ -1,59 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Tue, 16 May 2017 20:42:47 +0200 -Subject: [PATCH 16/17] init: Introduce SYSTEM_SCHEDULING state - -might_sleep() debugging and smp_processor_id() debugging should be active -right after the scheduler starts working. The init task can invoke -smp_processor_id() from preemptible context as it is pinned on the boot cpu -until sched_smp_init() removes the pinning and lets it schedule on all non -isolated cpus. - -Add a new state which allows to enable those checks earlier and add it to -the xen do_poweroff() function. - -No functional change. - -Tested-by: Mark Rutland <mark.rutland@arm.com> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> -Acked-by: Mark Rutland <mark.rutland@arm.com> -Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Cc: Juergen Gross <jgross@suse.com> -Cc: Linus Torvalds <torvalds@linux-foundation.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Link: http://lkml.kernel.org/r/20170516184736.196214622@linutronix.de -Signed-off-by: Ingo Molnar <mingo@kernel.org> ---- - drivers/xen/manage.c | 1 + - include/linux/kernel.h | 6 +++++- - 2 files changed, 6 insertions(+), 1 deletion(-) - ---- a/drivers/xen/manage.c -+++ b/drivers/xen/manage.c -@@ -190,6 +190,7 @@ static void do_poweroff(void) - { - switch (system_state) { - case SYSTEM_BOOTING: -+ case SYSTEM_SCHEDULING: - orderly_poweroff(true); - break; - case SYSTEM_RUNNING: ---- a/include/linux/kernel.h -+++ b/include/linux/kernel.h -@@ -488,9 +488,13 @@ extern int root_mountflags; - - extern bool early_boot_irqs_disabled; - --/* Values used for system_state */ -+/* -+ * Values used for system_state. Ordering of the states must not be changed -+ * as code checks for <, <=, >, >= STATE. -+ */ - extern enum system_states { - SYSTEM_BOOTING, -+ SYSTEM_SCHEDULING, - SYSTEM_RUNNING, - SYSTEM_HALT, - SYSTEM_POWER_OFF, diff --git a/patches/0016-powerpc-powernv-Use-stop_machine_cpuslocked.patch b/patches/0016-powerpc-powernv-Use-stop_machine_cpuslocked.patch deleted file mode 100644 index ad8bd5831243..000000000000 --- a/patches/0016-powerpc-powernv-Use-stop_machine_cpuslocked.patch +++ /dev/null @@ -1,50 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Wed, 24 May 2017 10:15:27 +0200 -Subject: [PATCH 16/32] powerpc/powernv: Use stop_machine_cpuslocked() - -set_subcores_per_core() holds get_online_cpus() while invoking stop_machine(). - -stop_machine() invokes get_online_cpus() as well. This is correct, but -prevents the conversion of the hotplug locking to a percpu rwsem. - -Use stop_machine_cpuslocked() to avoid the nested call. Convert -*_online_cpus() to the new interfaces while at it. - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Ingo Molnar <mingo@kernel.org> -Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: Michael Ellerman <mpe@ellerman.id.au> -Cc: linuxppc-dev@lists.ozlabs.org -Link: http://lkml.kernel.org/r/20170524081548.331016542@linutronix.de ---- - arch/powerpc/platforms/powernv/subcore.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - ---- a/arch/powerpc/platforms/powernv/subcore.c -+++ b/arch/powerpc/platforms/powernv/subcore.c -@@ -348,7 +348,7 @@ static int set_subcores_per_core(int new - state->master = 0; - } - -- get_online_cpus(); -+ cpus_read_lock(); - - /* This cpu will update the globals before exiting stop machine */ - this_cpu_ptr(&split_state)->master = 1; -@@ -356,9 +356,10 @@ static int set_subcores_per_core(int new - /* Ensure state is consistent before we call the other cpus */ - mb(); - -- stop_machine(cpu_update_split_mode, &new_mode, cpu_online_mask); -+ stop_machine_cpuslocked(cpu_update_split_mode, &new_mode, -+ cpu_online_mask); - -- put_online_cpus(); -+ cpus_read_unlock(); - - return 0; - } diff --git a/patches/0017-cpu-hotplug-Use-stop_machine_cpuslocked-in-takedown_.patch b/patches/0017-cpu-hotplug-Use-stop_machine_cpuslocked-in-takedown_.patch deleted file mode 100644 index b3914d943d42..000000000000 --- a/patches/0017-cpu-hotplug-Use-stop_machine_cpuslocked-in-takedown_.patch +++ /dev/null @@ -1,35 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Wed, 24 May 2017 10:15:28 +0200 -Subject: [PATCH 17/32] cpu/hotplug: Use stop_machine_cpuslocked() in - takedown_cpu() - -takedown_cpu() is a cpu hotplug function invoking stop_machine(). The cpu -hotplug machinery holds the hotplug lock for write. - -stop_machine() invokes get_online_cpus() as well. This is correct, but -prevents the conversion of the hotplug locking to a percpu rwsem. - -Use stop_machine_cpuslocked() to avoid the nested call. - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Tested-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Acked-by: Ingo Molnar <mingo@kernel.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Link: http://lkml.kernel.org/r/20170524081548.423292433@linutronix.de ---- - kernel/cpu.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/kernel/cpu.c -+++ b/kernel/cpu.c -@@ -711,7 +711,7 @@ static int takedown_cpu(unsigned int cpu - /* - * So now all preempt/rcu users must observe !cpu_active(). - */ -- err = stop_machine(take_cpu_down, NULL, cpumask_of(cpu)); -+ err = stop_machine_cpuslocked(take_cpu_down, NULL, cpumask_of(cpu)); - if (err) { - /* CPU refused to die */ - irq_unlock_sparse(); diff --git a/patches/0017-hrtimer-Implementation-of-softirq-hrtimer-handling.patch b/patches/0017-hrtimer-Implementation-of-softirq-hrtimer-handling.patch index e9e131657936..219d41b13810 100644 --- a/patches/0017-hrtimer-Implementation-of-softirq-hrtimer-handling.patch +++ b/patches/0017-hrtimer-Implementation-of-softirq-hrtimer-handling.patch @@ -65,7 +65,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -498,7 +498,6 @@ static inline void hrtimer_update_next_t +@@ -499,7 +499,6 @@ static inline void hrtimer_update_next_t cpu_base->next_timer = timer; } @@ -73,7 +73,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static ktime_t __hrtimer_next_event_base(struct hrtimer_cpu_base *cpu_base, unsigned int active, ktime_t expires_next) -@@ -539,12 +538,23 @@ static ktime_t __hrtimer_get_next_event( +@@ -540,12 +539,23 @@ static ktime_t __hrtimer_get_next_event( hrtimer_update_next_timer(cpu_base, NULL); @@ -98,7 +98,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static inline ktime_t hrtimer_update_base(struct hrtimer_cpu_base *base) { -@@ -968,6 +978,49 @@ static inline ktime_t hrtimer_update_low +@@ -969,6 +979,49 @@ static inline ktime_t hrtimer_update_low return tim; } @@ -148,7 +148,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, u64 delta_ns, const enum hrtimer_mode mode, struct hrtimer_clock_base *base) -@@ -1006,9 +1059,12 @@ void hrtimer_start_range_ns(struct hrtim +@@ -1007,9 +1060,12 @@ void hrtimer_start_range_ns(struct hrtim base = lock_hrtimer_base(timer, &flags); @@ -164,7 +164,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> unlock_hrtimer_base(timer, &flags); } EXPORT_SYMBOL_GPL(hrtimer_start_range_ns); -@@ -1205,7 +1261,8 @@ EXPORT_SYMBOL_GPL(hrtimer_active); +@@ -1206,7 +1262,8 @@ EXPORT_SYMBOL_GPL(hrtimer_active); static void __run_hrtimer(struct hrtimer_cpu_base *cpu_base, struct hrtimer_clock_base *base, @@ -174,7 +174,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> { enum hrtimer_restart (*fn)(struct hrtimer *); int restart; -@@ -1240,11 +1297,19 @@ static void __run_hrtimer(struct hrtimer +@@ -1241,11 +1298,19 @@ static void __run_hrtimer(struct hrtimer * protected against migration to a different CPU even if the lock * is dropped. */ @@ -196,7 +196,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * Note: We clear the running state after enqueue_hrtimer and -@@ -1308,11 +1373,28 @@ static void __hrtimer_run_queues(struct +@@ -1309,11 +1374,28 @@ static void __hrtimer_run_queues(struct if (basenow < hrtimer_get_softexpires_tv64(timer)) break; @@ -226,7 +226,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #ifdef CONFIG_HIGH_RES_TIMERS /* -@@ -1342,9 +1424,15 @@ void hrtimer_interrupt(struct clock_even +@@ -1343,9 +1425,15 @@ void hrtimer_interrupt(struct clock_even */ cpu_base->expires_next = KTIME_MAX; @@ -243,7 +243,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> expires_next = __hrtimer_get_next_event(cpu_base); /* * Store the new expiry value so the migration code can verify -@@ -1447,6 +1535,13 @@ void hrtimer_run_queues(void) +@@ -1448,6 +1536,13 @@ void hrtimer_run_queues(void) raw_spin_lock(&cpu_base->lock); now = hrtimer_update_base(cpu_base); @@ -257,7 +257,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> __hrtimer_run_queues(cpu_base, now, HRTIMER_ACTIVE_HARD); raw_spin_unlock(&cpu_base->lock); } -@@ -1609,6 +1704,7 @@ int hrtimers_prepare_cpu(unsigned int cp +@@ -1629,6 +1724,7 @@ int hrtimers_prepare_cpu(unsigned int cp cpu_base->cpu = cpu; cpu_base->hres_active = 0; cpu_base->expires_next = KTIME_MAX; @@ -265,7 +265,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return 0; } -@@ -1652,6 +1748,7 @@ int hrtimers_dead_cpu(unsigned int scpu) +@@ -1672,6 +1768,7 @@ int hrtimers_dead_cpu(unsigned int scpu) BUG_ON(cpu_online(scpu)); tick_cancel_sched_timer(scpu); @@ -273,7 +273,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> local_irq_disable(); old_base = &per_cpu(hrtimer_bases, scpu); new_base = this_cpu_ptr(&hrtimer_bases); -@@ -1667,12 +1764,19 @@ int hrtimers_dead_cpu(unsigned int scpu) +@@ -1687,12 +1784,19 @@ int hrtimers_dead_cpu(unsigned int scpu) &new_base->clock_base[i]); } @@ -293,7 +293,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return 0; } -@@ -1687,6 +1791,7 @@ void __init hrtimers_init(void) +@@ -1707,6 +1811,7 @@ void __init hrtimers_init(void) BUILD_BUG_ON_NOT_POWER_OF_2(HRTIMER_BASE_SOFT_MASK); hrtimers_prepare_cpu(smp_processor_id()); diff --git a/patches/0017-sched-core-Enable-might_sleep-and-smp_processor_id-c.patch b/patches/0017-sched-core-Enable-might_sleep-and-smp_processor_id-c.patch deleted file mode 100644 index beda0b821376..000000000000 --- a/patches/0017-sched-core-Enable-might_sleep-and-smp_processor_id-c.patch +++ /dev/null @@ -1,73 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Tue, 16 May 2017 20:42:48 +0200 -Subject: [PATCH 17/17] sched/core: Enable might_sleep() and smp_processor_id() - checks early - -might_sleep() and smp_processor_id() checks are enabled after the boot -process is done. That hides bugs in the SMP bringup and driver -initialization code. - -Enable it right when the scheduler starts working, i.e. when init task and -kthreadd have been created and right before the idle task enables -preemption. - -Tested-by: Mark Rutland <mark.rutland@arm.com> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Acked-by: Mark Rutland <mark.rutland@arm.com> -Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -Cc: Linus Torvalds <torvalds@linux-foundation.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Link: http://lkml.kernel.org/r/20170516184736.272225698@linutronix.de -Signed-off-by: Ingo Molnar <mingo@kernel.org> ---- - init/main.c | 10 ++++++++++ - kernel/sched/core.c | 4 +++- - lib/smp_processor_id.c | 2 +- - 3 files changed, 14 insertions(+), 2 deletions(-) - ---- a/init/main.c -+++ b/init/main.c -@@ -414,6 +414,16 @@ static noinline void __ref rest_init(voi - rcu_read_lock(); - kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns); - rcu_read_unlock(); -+ -+ /* -+ * Enable might_sleep() and smp_processor_id() checks. -+ * They cannot be enabled earlier because with CONFIG_PRREMPT=y -+ * kernel_thread() would trigger might_sleep() splats. With -+ * CONFIG_PREEMPT_VOLUNTARY=y the init task might have scheduled -+ * already, but it's stuck on the kthreadd_done completion. -+ */ -+ system_state = SYSTEM_SCHEDULING; -+ - complete(&kthreadd_done); - - /* ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -6223,8 +6223,10 @@ void ___might_sleep(const char *file, in - - if ((preempt_count_equals(preempt_offset) && !irqs_disabled() && - !is_idle_task(current)) || -- system_state != SYSTEM_RUNNING || oops_in_progress) -+ system_state == SYSTEM_BOOTING || system_state > SYSTEM_RUNNING || -+ oops_in_progress) - return; -+ - if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy) - return; - prev_jiffy = jiffies; ---- a/lib/smp_processor_id.c -+++ b/lib/smp_processor_id.c -@@ -28,7 +28,7 @@ notrace static unsigned int check_preemp - /* - * It is valid to assume CPU-locality during early bootup: - */ -- if (system_state != SYSTEM_RUNNING) -+ if (system_state < SYSTEM_SCHEDULING) - goto out; - - /* diff --git a/patches/0017-tracing-Add-usecs-modifier-for-hist-trigger-timestam.patch b/patches/0017-tracing-Add-usecs-modifier-for-hist-trigger-timestam.patch index e5232007c2ca..948c91bd8ded 100644 --- a/patches/0017-tracing-Add-usecs-modifier-for-hist-trigger-timestam.patch +++ b/patches/0017-tracing-Add-usecs-modifier-for-hist-trigger-timestam.patch @@ -23,7 +23,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c -@@ -1164,6 +1164,14 @@ static struct { +@@ -1170,6 +1170,14 @@ static struct { ARCH_TRACE_CLOCKS }; @@ -40,7 +40,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> */ --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h -@@ -281,6 +281,8 @@ extern void trace_array_put(struct trace +@@ -287,6 +287,8 @@ extern void trace_array_put(struct trace extern int tracing_set_time_stamp_abs(struct trace_array *tr, bool abs); diff --git a/patches/0018-hrtimer-Enable-soft-and-hard-hrtimer.patch b/patches/0018-hrtimer-Enable-soft-and-hard-hrtimer.patch index dcdf0dbaec8d..5b0372fd610f 100644 --- a/patches/0018-hrtimer-Enable-soft-and-hard-hrtimer.patch +++ b/patches/0018-hrtimer-Enable-soft-and-hard-hrtimer.patch @@ -37,7 +37,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -59,18 +59,6 @@ +@@ -60,18 +60,6 @@ #include "tick-internal.h" /* @@ -56,7 +56,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * Masks for selecting the soft and hard context timers from * cpu_base->active */ -@@ -1172,7 +1160,7 @@ u64 hrtimer_get_next_event(void) +@@ -1173,7 +1161,7 @@ u64 hrtimer_get_next_event(void) static inline int hrtimer_clockid_to_base(clockid_t clock_id) { @@ -65,7 +65,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> int base = hrtimer_clock_to_base_table[clock_id]; if (likely(base != HRTIMER_MAX_CLOCK_BASES)) -@@ -1192,8 +1180,12 @@ static void __hrtimer_init(struct hrtime +@@ -1193,8 +1181,12 @@ static void __hrtimer_init(struct hrtime cpu_base = raw_cpu_ptr(&hrtimer_bases); diff --git a/patches/0018-x86-perf-Drop-EXPORT-of-perf_check_microcode.patch b/patches/0018-x86-perf-Drop-EXPORT-of-perf_check_microcode.patch deleted file mode 100644 index 47273e01bad7..000000000000 --- a/patches/0018-x86-perf-Drop-EXPORT-of-perf_check_microcode.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 24 May 2017 10:15:29 +0200 -Subject: [PATCH 18/32] x86/perf: Drop EXPORT of perf_check_microcode - -The only caller is the microcode update, which cannot be modular. - -Drop the export. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Ingo Molnar <mingo@kernel.org> -Acked-by: Borislav Petkov <bp@suse.de> -Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: Borislav Petkov <bp@alien8.de> -Link: http://lkml.kernel.org/r/20170524081548.515204988@linutronix.de ---- - arch/x86/events/core.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/arch/x86/events/core.c -+++ b/arch/x86/events/core.c -@@ -2224,7 +2224,6 @@ void perf_check_microcode(void) - if (x86_pmu.check_microcode) - x86_pmu.check_microcode(); - } --EXPORT_SYMBOL_GPL(perf_check_microcode); - - static struct pmu pmu = { - .pmu_enable = x86_pmu_enable, diff --git a/patches/0019-can-bcm-Replace-hrtimer_tasklet-with-softirq-based-h.patch b/patches/0019-can-bcm-Replace-hrtimer_tasklet-with-softirq-based-h.patch index 6ca9ba3a6e5b..9f2dcbc000bd 100644 --- a/patches/0019-can-bcm-Replace-hrtimer_tasklet-with-softirq-based-h.patch +++ b/patches/0019-can-bcm-Replace-hrtimer_tasklet-with-softirq-based-h.patch @@ -26,7 +26,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ktime_t rx_stamp, kt_ival1, kt_ival2, kt_lastmsg; int rx_ifindex; int cfsiz; -@@ -363,25 +362,34 @@ static void bcm_send_to_user(struct bcm_ +@@ -364,25 +363,34 @@ static void bcm_send_to_user(struct bcm_ } } @@ -71,7 +71,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> op->count--; if (!op->count && (op->flags & TX_COUNTEVT)) { -@@ -398,22 +406,12 @@ static void bcm_tx_timeout_tsklet(unsign +@@ -399,22 +407,12 @@ static void bcm_tx_timeout_tsklet(unsign } bcm_can_tx(op); @@ -98,7 +98,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } /* -@@ -541,11 +539,18 @@ static void bcm_rx_starttimer(struct bcm +@@ -542,11 +540,18 @@ static void bcm_rx_starttimer(struct bcm hrtimer_start(&op->timer, op->kt_ival1, HRTIMER_MODE_REL); } @@ -119,7 +119,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* create notification to user */ msg_head.opcode = RX_TIMEOUT; msg_head.flags = op->flags; -@@ -556,25 +561,6 @@ static void bcm_rx_timeout_tsklet(unsign +@@ -557,25 +562,6 @@ static void bcm_rx_timeout_tsklet(unsign msg_head.nframes = 0; bcm_send_to_user(op, &msg_head, NULL, 0); @@ -145,7 +145,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return HRTIMER_NORESTART; } -@@ -582,14 +568,12 @@ static enum hrtimer_restart bcm_rx_timeo +@@ -583,14 +569,12 @@ static enum hrtimer_restart bcm_rx_timeo /* * bcm_rx_do_flush - helper for bcm_rx_thr_flush */ @@ -162,7 +162,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return 1; } return 0; -@@ -597,11 +581,8 @@ static inline int bcm_rx_do_flush(struct +@@ -598,11 +582,8 @@ static inline int bcm_rx_do_flush(struct /* * bcm_rx_thr_flush - Check for throttled data and send it to the userspace @@ -175,7 +175,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> { int updated = 0; -@@ -610,24 +591,16 @@ static int bcm_rx_thr_flush(struct bcm_o +@@ -611,24 +592,16 @@ static int bcm_rx_thr_flush(struct bcm_o /* for MUX filter we start at index 1 */ for (i = 1; i < op->nframes; i++) @@ -202,7 +202,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * bcm_rx_thr_handler - the time for blocked content updates is over now: * Check for throttled data and send it to the userspace -@@ -636,9 +609,7 @@ static enum hrtimer_restart bcm_rx_thr_h +@@ -637,9 +610,7 @@ static enum hrtimer_restart bcm_rx_thr_h { struct bcm_op *op = container_of(hrtimer, struct bcm_op, thrtimer); @@ -213,7 +213,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> hrtimer_forward(hrtimer, ktime_get(), op->kt_ival2); return HRTIMER_RESTART; } else { -@@ -734,23 +705,8 @@ static struct bcm_op *bcm_find_op(struct +@@ -735,23 +706,8 @@ static struct bcm_op *bcm_find_op(struct static void bcm_remove_op(struct bcm_op *op) { @@ -239,7 +239,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if ((op->frames) && (op->frames != &op->sframe)) kfree(op->frames); -@@ -977,15 +933,13 @@ static int bcm_tx_setup(struct bcm_msg_h +@@ -979,15 +935,13 @@ static int bcm_tx_setup(struct bcm_msg_h op->ifindex = ifindex; /* initialize uninitialized (kzalloc) structure */ @@ -259,7 +259,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* add this bcm_op to the list of the tx_ops */ list_add(&op->list, &bo->tx_ops); -@@ -1148,20 +1102,14 @@ static int bcm_rx_setup(struct bcm_msg_h +@@ -1150,20 +1104,14 @@ static int bcm_rx_setup(struct bcm_msg_h op->rx_ifindex = ifindex; /* initialize uninitialized (kzalloc) structure */ @@ -284,7 +284,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* add this bcm_op to the list of the rx_ops */ list_add(&op->list, &bo->rx_ops); -@@ -1207,7 +1155,7 @@ static int bcm_rx_setup(struct bcm_msg_h +@@ -1209,7 +1157,7 @@ static int bcm_rx_setup(struct bcm_msg_h */ op->kt_lastmsg = 0; hrtimer_cancel(&op->thrtimer); diff --git a/patches/0019-perf-x86-intel-Drop-get_online_cpus-in-intel_snb_che.patch b/patches/0019-perf-x86-intel-Drop-get_online_cpus-in-intel_snb_che.patch deleted file mode 100644 index 1a42e07cd6ab..000000000000 --- a/patches/0019-perf-x86-intel-Drop-get_online_cpus-in-intel_snb_che.patch +++ /dev/null @@ -1,75 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Wed, 24 May 2017 10:15:30 +0200 -Subject: [PATCH 19/32] perf/x86/intel: Drop get_online_cpus() in - intel_snb_check_microcode() - -If intel_snb_check_microcode() is invoked via - microcode_init -> perf_check_microcode -> intel_snb_check_microcode - -then get_online_cpus() is invoked nested. This works with the current -implementation of get_online_cpus() but prevents converting it to a percpu -rwsem. - -intel_snb_check_microcode() is also invoked from intel_sandybridge_quirk() -unprotected. - -Drop get_online_cpus() from intel_snb_check_microcode() and add it to -intel_sandybridge_quirk() so both call sites are protected. - -Convert *_online_cpus() to the new interfaces while at it. - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Ingo Molnar <mingo@kernel.org> -Acked-by: Borislav Petkov <bp@suse.de> -Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: Borislav Petkov <bp@alien8.de> -Link: http://lkml.kernel.org/r/20170524081548.594862191@linutronix.de ---- - arch/x86/events/intel/core.c | 11 +++++------ - 1 file changed, 5 insertions(+), 6 deletions(-) - ---- a/arch/x86/events/intel/core.c -+++ b/arch/x86/events/intel/core.c -@@ -3389,12 +3389,10 @@ static void intel_snb_check_microcode(vo - int pebs_broken = 0; - int cpu; - -- get_online_cpus(); - for_each_online_cpu(cpu) { - if ((pebs_broken = intel_snb_pebs_broken(cpu))) - break; - } -- put_online_cpus(); - - if (pebs_broken == x86_pmu.pebs_broken) - return; -@@ -3467,7 +3465,9 @@ static bool check_msr(unsigned long msr, - static __init void intel_sandybridge_quirk(void) - { - x86_pmu.check_microcode = intel_snb_check_microcode; -+ cpus_read_lock(); - intel_snb_check_microcode(); -+ cpus_read_unlock(); - } - - static const struct { int id; char *name; } intel_arch_events_map[] __initconst = { -@@ -4090,13 +4090,12 @@ static __init int fixup_ht_bug(void) - - lockup_detector_resume(); - -- get_online_cpus(); -+ cpus_read_lock(); - -- for_each_online_cpu(c) { -+ for_each_online_cpu(c) - free_excl_cntrs(c); -- } - -- put_online_cpus(); -+ cpus_read_unlock(); - pr_info("PMU erratum BJ122, BV98, HSD29 workaround disabled, HT off\n"); - return 0; - } diff --git a/patches/0020-PCI-Use-cpu_hotplug_disable-instead-of-get_online_cp.patch b/patches/0020-PCI-Use-cpu_hotplug_disable-instead-of-get_online_cp.patch deleted file mode 100644 index 5ebfb25b6324..000000000000 --- a/patches/0020-PCI-Use-cpu_hotplug_disable-instead-of-get_online_cp.patch +++ /dev/null @@ -1,86 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 24 May 2017 10:15:31 +0200 -Subject: [PATCH 20/32] PCI: Use cpu_hotplug_disable() instead of - get_online_cpus() - -Converting the hotplug locking, i.e. get_online_cpus(), to a percpu rwsem -unearthed a circular lock dependency which was hidden from lockdep due to -the lockdep annotation of get_online_cpus() which prevents lockdep from -creating full dependency chains. There are several variants of this. And -example is: - -Chain exists of: - -cpu_hotplug_lock.rw_sem --> drm_global_mutex --> &item->mutex - -CPU0 CPU1 ----- ---- -lock(&item->mutex); - lock(drm_global_mutex); - lock(&item->mutex); -lock(cpu_hotplug_lock.rw_sem); - -because there are dependencies through workqueues. The call chain is: - - get_online_cpus - apply_workqueue_attrs - __alloc_workqueue_key - ttm_mem_global_init - ast_ttm_mem_global_init - drm_global_item_ref - ast_mm_init - ast_driver_load - drm_dev_register - drm_get_pci_dev - ast_pci_probe - local_pci_probe - work_for_cpu_fn - process_one_work - worker_thread - -This is not a problem of get_online_cpus() recursion, it's a possible -deadlock undetected by lockdep so far. - -The cure is to use cpu_hotplug_disable() instead of get_online_cpus() to -protect the PCI probing. - -There is a side effect to this: cpu_hotplug_disable() makes a concurrent -cpu hotplug attempt via the sysfs interfaces fail with -EBUSY, but PCI -probing usually happens during the boot process where no interaction is -possible. Any later invocations are infrequent enough and concurrent -hotplug attempts are so unlikely that the danger of user space visible -regressions is very close to zero. Anyway, thats preferrable over a real -deadlock. - - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Ingo Molnar <mingo@kernel.org> -Acked-by: Bjorn Helgaas <bhelgaas@google.com> -Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: linux-pci@vger.kernel.org -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Steven Rostedt <rostedt@goodmis.org> -Link: http://lkml.kernel.org/r/20170524081548.691198590@linutronix.de ---- - drivers/pci/pci-driver.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/pci/pci-driver.c -+++ b/drivers/pci/pci-driver.c -@@ -349,13 +349,13 @@ static int pci_call_probe(struct pci_dri - if (node >= 0 && node != numa_node_id()) { - int cpu; - -- get_online_cpus(); -+ cpu_hotplug_disable(); - cpu = cpumask_any_and(cpumask_of_node(node), cpu_online_mask); - if (cpu < nr_cpu_ids) - error = work_on_cpu(cpu, local_pci_probe, &ddi); - else - error = local_pci_probe(&ddi); -- put_online_cpus(); -+ cpu_hotplug_enable(); - } else - error = local_pci_probe(&ddi); - diff --git a/patches/0020-mac80211_hwsim-Replace-hrtimer-tasklet-with-softirq-.patch b/patches/0020-mac80211_hwsim-Replace-hrtimer-tasklet-with-softirq-.patch index f5fa41b66684..f7a1f680d75d 100644 --- a/patches/0020-mac80211_hwsim-Replace-hrtimer-tasklet-with-softirq-.patch +++ b/patches/0020-mac80211_hwsim-Replace-hrtimer-tasklet-with-softirq-.patch @@ -18,7 +18,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c -@@ -531,7 +531,7 @@ struct mac80211_hwsim_data { +@@ -537,7 +537,7 @@ struct mac80211_hwsim_data { unsigned int rx_filter; bool started, idle, scanning; struct mutex mutex; @@ -27,7 +27,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> enum ps_mode { PS_DISABLED, PS_ENABLED, PS_AUTO_POLL, PS_MANUAL_POLL } ps; -@@ -1408,7 +1408,7 @@ static void mac80211_hwsim_stop(struct i +@@ -1418,7 +1418,7 @@ static void mac80211_hwsim_stop(struct i { struct mac80211_hwsim_data *data = hw->priv; data->started = false; @@ -36,7 +36,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> wiphy_debug(hw->wiphy, "%s\n", __func__); } -@@ -1531,14 +1531,12 @@ static enum hrtimer_restart +@@ -1541,14 +1541,12 @@ static enum hrtimer_restart mac80211_hwsim_beacon(struct hrtimer *timer) { struct mac80211_hwsim_data *data = @@ -53,7 +53,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ieee80211_iterate_active_interfaces_atomic( hw, IEEE80211_IFACE_ITER_NORMAL, -@@ -1550,11 +1548,9 @@ mac80211_hwsim_beacon(struct hrtimer *ti +@@ -1560,11 +1558,9 @@ mac80211_hwsim_beacon(struct hrtimer *ti data->bcn_delta = 0; } @@ -68,9 +68,9 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } static const char * const hwsim_chanwidths[] = { -@@ -1604,15 +1600,15 @@ static int mac80211_hwsim_config(struct +@@ -1638,15 +1634,15 @@ static int mac80211_hwsim_config(struct + mutex_unlock(&data->mutex); - data->power_level = conf->power_level; if (!data->started || !data->beacon_int) - tasklet_hrtimer_cancel(&data->beacon_timer); - else if (!hrtimer_is_queued(&data->beacon_timer.timer)) { @@ -89,7 +89,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } return 0; -@@ -1675,7 +1671,7 @@ static void mac80211_hwsim_bss_info_chan +@@ -1709,7 +1705,7 @@ static void mac80211_hwsim_bss_info_chan info->enable_beacon, info->beacon_int); vp->bcn_en = info->enable_beacon; if (data->started && @@ -98,7 +98,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> info->enable_beacon) { u64 tsf, until_tbtt; u32 bcn_int; -@@ -1683,9 +1679,9 @@ static void mac80211_hwsim_bss_info_chan +@@ -1717,9 +1713,9 @@ static void mac80211_hwsim_bss_info_chan tsf = mac80211_hwsim_get_tsf(hw, vif); bcn_int = data->beacon_int; until_tbtt = bcn_int - do_div(tsf, bcn_int); @@ -111,7 +111,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } else if (!info->enable_beacon) { unsigned int count = 0; ieee80211_iterate_active_interfaces_atomic( -@@ -1694,7 +1690,7 @@ static void mac80211_hwsim_bss_info_chan +@@ -1728,7 +1724,7 @@ static void mac80211_hwsim_bss_info_chan wiphy_debug(hw->wiphy, " beaconing vifs remaining: %u", count); if (count == 0) { @@ -120,7 +120,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> data->beacon_int = 0; } } -@@ -2669,9 +2665,9 @@ static int mac80211_hwsim_new_radio(stru +@@ -2720,9 +2716,9 @@ static int mac80211_hwsim_new_radio(stru data->debugfs, data, &hwsim_simulate_radar); diff --git a/patches/0021-PCI-Replace-the-racy-recursion-prevention.patch b/patches/0021-PCI-Replace-the-racy-recursion-prevention.patch deleted file mode 100644 index 8261c9deedbd..000000000000 --- a/patches/0021-PCI-Replace-the-racy-recursion-prevention.patch +++ /dev/null @@ -1,127 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 24 May 2017 10:15:32 +0200 -Subject: [PATCH 21/32] PCI: Replace the racy recursion prevention - -pci_call_probe() can called recursively when a physcial function is probed -and the probing creates virtual functions, which are populated via -pci_bus_add_device() which in turn can end up calling pci_call_probe() -again. - -The code has an interesting way to prevent recursing into the workqueue -code. That's accomplished by a check whether the current task runs already -on the numa node which is associated with the device. - -While that works to prevent the recursion into the workqueue code, it's -racy versus normal execution as there is no guarantee that the node does -not vanish after the check. - -There is another issue with this code. It dereferences cpumask_of_node() -unconditionally without checking whether the node is available. - -Make the detection reliable by: - - - Mark a probed device as 'is_probed' in pci_call_probe() - - - Check in pci_call_probe for a virtual function. If it's a virtual - function and the associated physical function device is marked - 'is_probed' then this is a recursive call, so the call can be invoked in - the calling context. - - - Add a check whether the node is online before dereferencing it. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Ingo Molnar <mingo@kernel.org> -Acked-by: Bjorn Helgaas <bhelgaas@google.com> -Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: linux-pci@vger.kernel.org -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Steven Rostedt <rostedt@goodmis.org> -Link: http://lkml.kernel.org/r/20170524081548.771457199@linutronix.de ---- - drivers/pci/pci-driver.c | 47 +++++++++++++++++++++++++---------------------- - include/linux/pci.h | 1 + - 2 files changed, 26 insertions(+), 22 deletions(-) - ---- a/drivers/pci/pci-driver.c -+++ b/drivers/pci/pci-driver.c -@@ -320,10 +320,19 @@ static long local_pci_probe(void *_ddi) - return 0; - } - -+static bool pci_physfn_is_probed(struct pci_dev *dev) -+{ -+#ifdef CONFIG_PCI_IOV -+ return dev->is_virtfn && dev->physfn->is_probed; -+#else -+ return false; -+#endif -+} -+ - static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, - const struct pci_device_id *id) - { -- int error, node; -+ int error, node, cpu; - struct drv_dev_and_id ddi = { drv, dev, id }; - - /* -@@ -332,33 +341,27 @@ static int pci_call_probe(struct pci_dri - * on the right node. - */ - node = dev_to_node(&dev->dev); -+ dev->is_probed = 1; -+ -+ cpu_hotplug_disable(); - - /* -- * On NUMA systems, we are likely to call a PF probe function using -- * work_on_cpu(). If that probe calls pci_enable_sriov() (which -- * adds the VF devices via pci_bus_add_device()), we may re-enter -- * this function to call the VF probe function. Calling -- * work_on_cpu() again will cause a lockdep warning. Since VFs are -- * always on the same node as the PF, we can work around this by -- * avoiding work_on_cpu() when we're already on the correct node. -- * -- * Preemption is enabled, so it's theoretically unsafe to use -- * numa_node_id(), but even if we run the probe function on the -- * wrong node, it should be functionally correct. -+ * Prevent nesting work_on_cpu() for the case where a Virtual Function -+ * device is probed from work_on_cpu() of the Physical device. - */ -- if (node >= 0 && node != numa_node_id()) { -- int cpu; -- -- cpu_hotplug_disable(); -+ if (node < 0 || node >= MAX_NUMNODES || !node_online(node) || -+ pci_physfn_is_probed(dev)) -+ cpu = nr_cpu_ids; -+ else - cpu = cpumask_any_and(cpumask_of_node(node), cpu_online_mask); -- if (cpu < nr_cpu_ids) -- error = work_on_cpu(cpu, local_pci_probe, &ddi); -- else -- error = local_pci_probe(&ddi); -- cpu_hotplug_enable(); -- } else -+ -+ if (cpu < nr_cpu_ids) -+ error = work_on_cpu(cpu, local_pci_probe, &ddi); -+ else - error = local_pci_probe(&ddi); - -+ dev->is_probed = 0; -+ cpu_hotplug_enable(); - return error; - } - ---- a/include/linux/pci.h -+++ b/include/linux/pci.h -@@ -370,6 +370,7 @@ struct pci_dev { - unsigned int irq_managed:1; - unsigned int has_secondary_link:1; - unsigned int non_compliant_bars:1; /* broken BARs; ignore them */ -+ unsigned int is_probed:1; /* device probing in progress */ - pci_dev_flags_t dev_flags; - atomic_t enable_cnt; /* pci_enable_device has been called */ - diff --git a/patches/0021-xfrm-Replace-hrtimer-tasklet-with-softirq-hrtimer.patch b/patches/0021-xfrm-Replace-hrtimer-tasklet-with-softirq-hrtimer.patch index 6a8ee1b97aa2..edc93abcd6ca 100644 --- a/patches/0021-xfrm-Replace-hrtimer-tasklet-with-softirq-hrtimer.patch +++ b/patches/0021-xfrm-Replace-hrtimer-tasklet-with-softirq-hrtimer.patch @@ -19,18 +19,18 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/include/net/xfrm.h +++ b/include/net/xfrm.h -@@ -205,7 +205,7 @@ struct xfrm_state { +@@ -213,7 +213,7 @@ struct xfrm_state { struct xfrm_stats stats; struct xfrm_lifetime_cur curlft; - struct tasklet_hrtimer mtimer; + struct hrtimer mtimer; - /* used to fix curlft->add_time when changing date */ - long saved_tmo; + struct xfrm_state_offload xso; + --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c -@@ -349,7 +349,7 @@ static void xfrm_put_mode(struct xfrm_mo +@@ -418,7 +418,7 @@ static void xfrm_put_mode(struct xfrm_mo static void xfrm_state_gc_destroy(struct xfrm_state *x) { @@ -39,7 +39,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> del_timer_sync(&x->rtimer); kfree(x->aead); kfree(x->aalg); -@@ -391,8 +391,8 @@ static void xfrm_state_gc_task(struct wo +@@ -463,8 +463,8 @@ static void xfrm_state_gc_task(struct wo static enum hrtimer_restart xfrm_timer_handler(struct hrtimer *me) { @@ -50,7 +50,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> unsigned long now = get_seconds(); long next = LONG_MAX; int warn = 0; -@@ -456,7 +456,8 @@ static enum hrtimer_restart xfrm_timer_h +@@ -528,7 +528,8 @@ static enum hrtimer_restart xfrm_timer_h km_state_expired(x, 0, 0); resched: if (next != LONG_MAX) { @@ -60,7 +60,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } goto out; -@@ -473,7 +474,7 @@ static enum hrtimer_restart xfrm_timer_h +@@ -545,7 +546,7 @@ static enum hrtimer_restart xfrm_timer_h out: spin_unlock(&x->lock); @@ -69,7 +69,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } static void xfrm_replay_timer_handler(unsigned long data); -@@ -492,8 +493,8 @@ struct xfrm_state *xfrm_state_alloc(stru +@@ -564,8 +565,8 @@ struct xfrm_state *xfrm_state_alloc(stru INIT_HLIST_NODE(&x->bydst); INIT_HLIST_NODE(&x->bysrc); INIT_HLIST_NODE(&x->byspi); @@ -80,7 +80,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> setup_timer(&x->rtimer, xfrm_replay_timer_handler, (unsigned long)x); x->curlft.add_time = get_seconds(); -@@ -876,7 +877,9 @@ xfrm_state_find(const xfrm_address_t *da +@@ -1021,7 +1022,9 @@ xfrm_state_find(const xfrm_address_t *da hlist_add_head_rcu(&x->byspi, net->xfrm.state_byspi + h); } x->lft.hard_add_expires_seconds = net->xfrm.sysctl_acq_expires; @@ -91,7 +91,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> net->xfrm.state_num++; xfrm_hash_grow_check(net, x->bydst.next != NULL); spin_unlock_bh(&net->xfrm.xfrm_state_lock); -@@ -987,7 +990,7 @@ static void __xfrm_state_insert(struct x +@@ -1132,7 +1135,7 @@ static void __xfrm_state_insert(struct x hlist_add_head_rcu(&x->byspi, net->xfrm.state_byspi + h); } @@ -100,7 +100,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (x->replay_maxage) mod_timer(&x->rtimer, jiffies + x->replay_maxage); -@@ -1091,7 +1094,9 @@ static struct xfrm_state *__find_acq_cor +@@ -1236,7 +1239,9 @@ static struct xfrm_state *__find_acq_cor x->mark.m = m->m; x->lft.hard_add_expires_seconds = net->xfrm.sysctl_acq_expires; xfrm_state_hold(x); @@ -111,7 +111,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> list_add(&x->km.all, &net->xfrm.state_all); hlist_add_head_rcu(&x->bydst, net->xfrm.state_bydst + h); h = xfrm_src_hash(net, daddr, saddr, family); -@@ -1380,7 +1385,7 @@ int xfrm_state_update(struct xfrm_state +@@ -1535,7 +1540,7 @@ int xfrm_state_update(struct xfrm_state memcpy(&x1->lft, &x->lft, sizeof(x1->lft)); x1->km.dying = 0; @@ -120,7 +120,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (x1->curlft.use_time) xfrm_state_check_expire(x1); -@@ -1404,7 +1409,7 @@ int xfrm_state_check_expire(struct xfrm_ +@@ -1559,7 +1564,7 @@ int xfrm_state_check_expire(struct xfrm_ if (x->curlft.bytes >= x->lft.hard_byte_limit || x->curlft.packets >= x->lft.hard_packet_limit) { x->km.state = XFRM_STATE_EXPIRED; diff --git a/patches/0022-ACPI-processor-Use-cpu_hotplug_disable-instead-of-ge.patch b/patches/0022-ACPI-processor-Use-cpu_hotplug_disable-instead-of-ge.patch deleted file mode 100644 index 56c12505a7e5..000000000000 --- a/patches/0022-ACPI-processor-Use-cpu_hotplug_disable-instead-of-ge.patch +++ /dev/null @@ -1,63 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 24 May 2017 10:15:33 +0200 -Subject: [PATCH 22/32] ACPI/processor: Use cpu_hotplug_disable() instead of - get_online_cpus() - -Converting the hotplug locking, i.e. get_online_cpus(), to a percpu rwsem -unearthed a circular lock dependency which was hidden from lockdep due to -the lockdep annotation of get_online_cpus() which prevents lockdep from -creating full dependency chains. - -CPU0 CPU1 ----- ---- -lock((&wfc.work)); - lock(cpu_hotplug_lock.rw_sem); - lock((&wfc.work)); -lock(cpu_hotplug_lock.rw_sem); - -This dependency is established via acpi_processor_start() which calls into -the work queue code. And the work queue code establishes the reverse -dependency. - -This is not a problem of get_online_cpus() recursion, it's a possible -deadlock undetected by lockdep so far. - -The cure is to use cpu_hotplug_disable() instead of get_online_cpus() to -protect the probing from acpi_processor_start(). - -There is a side effect to this: cpu_hotplug_disable() makes a concurrent -cpu hotplug attempt via the sysfs interfaces fail with -EBUSY, but that -probing usually happens during the boot process where no interaction is -possible. Any later invocations are infrequent enough and concurrent -hotplug attempts are so unlikely that the danger of user space visible -regressions is very close to zero. Anyway, thats preferrable over a real -deadlock. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Ingo Molnar <mingo@kernel.org> -Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> -Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: linux-acpi@vger.kernel.org -Cc: Len Brown <lenb@kernel.org> -Link: http://lkml.kernel.org/r/20170524081548.851588594@linutronix.de ---- - drivers/acpi/processor_driver.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/acpi/processor_driver.c -+++ b/drivers/acpi/processor_driver.c -@@ -268,9 +268,9 @@ static int acpi_processor_start(struct d - return -ENODEV; - - /* Protect against concurrent CPU hotplug operations */ -- get_online_cpus(); -+ cpu_hotplug_disable(); - ret = __acpi_processor_start(device); -- put_online_cpus(); -+ cpu_hotplug_enable(); - return ret; - } - diff --git a/patches/0022-softirq-Remove-tasklet_hrtimer.patch b/patches/0022-softirq-Remove-tasklet_hrtimer.patch index e3196f16257e..317c650b8a49 100644 --- a/patches/0022-softirq-Remove-tasklet_hrtimer.patch +++ b/patches/0022-softirq-Remove-tasklet_hrtimer.patch @@ -15,7 +15,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h -@@ -622,31 +622,6 @@ extern void tasklet_kill_immediate(struc +@@ -631,31 +631,6 @@ extern void tasklet_kill_immediate(struc extern void tasklet_init(struct tasklet_struct *t, void (*func)(unsigned long), unsigned long data); diff --git a/patches/0023-perf-tracing-cpuhotplug-Fix-locking-order.patch b/patches/0023-perf-tracing-cpuhotplug-Fix-locking-order.patch deleted file mode 100644 index 7d7b681d169f..000000000000 --- a/patches/0023-perf-tracing-cpuhotplug-Fix-locking-order.patch +++ /dev/null @@ -1,301 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 24 May 2017 10:15:34 +0200 -Subject: [PATCH 23/32] perf/tracing/cpuhotplug: Fix locking order - -perf, tracing, kprobes and jump_labels have a gazillion of ways to create -dependency lock chains. Some of those involve nested invocations of -get_online_cpus(). - -The conversion of the hotplug locking to a percpu rwsem requires to avoid -such nested calls. sys_perf_event_open() protects most of the syscall logic -against cpu hotplug. This causes nested calls and lock inversions versus -ftrace and kprobes in various interesting ways. - -It's impossible to move the hotplug locking to the outer end of all call -chains in the involved facilities, so the hotplug protection in -sys_perf_event_open() needs to be solved differently. - -Introduce 'pmus_mutex' which protects a perf private online cpumask. This -mutex is taken when the mask is updated in the cpu hotplug callbacks and -can be taken in sys_perf_event_open() to protect the swhash setup/teardown -code and when the final judgement about a valid event has to be made. - -[ tglx: Produced changelog and fixed the swhash interaction ] - -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Ingo Molnar <mingo@kernel.org> -Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> -Cc: Masami Hiramatsu <mhiramat@kernel.org> -Link: http://lkml.kernel.org/r/20170524081548.930941109@linutronix.de ---- - include/linux/perf_event.h | 2 - kernel/events/core.c | 106 ++++++++++++++++++++++++++++++++------------- - 2 files changed, 78 insertions(+), 30 deletions(-) - ---- a/include/linux/perf_event.h -+++ b/include/linux/perf_event.h -@@ -794,6 +794,8 @@ struct perf_cpu_context { - - struct list_head sched_cb_entry; - int sched_cb_usage; -+ -+ int online; - }; - - struct perf_output_handle { ---- a/kernel/events/core.c -+++ b/kernel/events/core.c -@@ -386,6 +386,7 @@ static atomic_t nr_switch_events __read_ - static LIST_HEAD(pmus); - static DEFINE_MUTEX(pmus_lock); - static struct srcu_struct pmus_srcu; -+static cpumask_var_t perf_online_mask; - - /* - * perf event paranoia level: -@@ -3809,14 +3810,6 @@ find_get_context(struct pmu *pmu, struct - if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN)) - return ERR_PTR(-EACCES); - -- /* -- * We could be clever and allow to attach a event to an -- * offline CPU and activate it when the CPU comes up, but -- * that's for later. -- */ -- if (!cpu_online(cpu)) -- return ERR_PTR(-ENODEV); -- - cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu); - ctx = &cpuctx->ctx; - get_ctx(ctx); -@@ -7592,7 +7585,8 @@ static int swevent_hlist_get_cpu(int cpu - int err = 0; - - mutex_lock(&swhash->hlist_mutex); -- if (!swevent_hlist_deref(swhash) && cpu_online(cpu)) { -+ if (!swevent_hlist_deref(swhash) && -+ cpumask_test_cpu(cpu, perf_online_mask)) { - struct swevent_hlist *hlist; - - hlist = kzalloc(sizeof(*hlist), GFP_KERNEL); -@@ -7613,7 +7607,7 @@ static int swevent_hlist_get(void) - { - int err, cpu, failed_cpu; - -- get_online_cpus(); -+ mutex_lock(&pmus_lock); - for_each_possible_cpu(cpu) { - err = swevent_hlist_get_cpu(cpu); - if (err) { -@@ -7621,8 +7615,7 @@ static int swevent_hlist_get(void) - goto fail; - } - } -- put_online_cpus(); -- -+ mutex_unlock(&pmus_lock); - return 0; - fail: - for_each_possible_cpu(cpu) { -@@ -7630,8 +7623,7 @@ static int swevent_hlist_get(void) - break; - swevent_hlist_put_cpu(cpu); - } -- -- put_online_cpus(); -+ mutex_unlock(&pmus_lock); - return err; - } - -@@ -8809,7 +8801,7 @@ perf_event_mux_interval_ms_store(struct - pmu->hrtimer_interval_ms = timer; - - /* update all cpuctx for this PMU */ -- get_online_cpus(); -+ cpus_read_lock(); - for_each_online_cpu(cpu) { - struct perf_cpu_context *cpuctx; - cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu); -@@ -8818,7 +8810,7 @@ perf_event_mux_interval_ms_store(struct - cpu_function_call(cpu, - (remote_function_f)perf_mux_hrtimer_restart, cpuctx); - } -- put_online_cpus(); -+ cpus_read_unlock(); - mutex_unlock(&mux_interval_mutex); - - return count; -@@ -8948,6 +8940,7 @@ int perf_pmu_register(struct pmu *pmu, c - lockdep_set_class(&cpuctx->ctx.mutex, &cpuctx_mutex); - lockdep_set_class(&cpuctx->ctx.lock, &cpuctx_lock); - cpuctx->ctx.pmu = pmu; -+ cpuctx->online = cpumask_test_cpu(cpu, perf_online_mask); - - __perf_mux_hrtimer_init(cpuctx, cpu); - } -@@ -9764,12 +9757,10 @@ SYSCALL_DEFINE5(perf_event_open, - goto err_task; - } - -- get_online_cpus(); -- - if (task) { - err = mutex_lock_interruptible(&task->signal->cred_guard_mutex); - if (err) -- goto err_cpus; -+ goto err_cred; - - /* - * Reuse ptrace permission checks for now. -@@ -9955,6 +9946,23 @@ SYSCALL_DEFINE5(perf_event_open, - goto err_locked; - } - -+ if (!task) { -+ /* -+ * Check if the @cpu we're creating an event for is online. -+ * -+ * We use the perf_cpu_context::ctx::mutex to serialize against -+ * the hotplug notifiers. See perf_event_{init,exit}_cpu(). -+ */ -+ struct perf_cpu_context *cpuctx = -+ container_of(ctx, struct perf_cpu_context, ctx); -+ -+ if (!cpuctx->online) { -+ err = -ENODEV; -+ goto err_locked; -+ } -+ } -+ -+ - /* - * Must be under the same ctx::mutex as perf_install_in_context(), - * because we need to serialize with concurrent event creation. -@@ -10044,8 +10052,6 @@ SYSCALL_DEFINE5(perf_event_open, - put_task_struct(task); - } - -- put_online_cpus(); -- - mutex_lock(¤t->perf_event_mutex); - list_add_tail(&event->owner_entry, ¤t->perf_event_list); - mutex_unlock(¤t->perf_event_mutex); -@@ -10079,8 +10085,6 @@ SYSCALL_DEFINE5(perf_event_open, - err_cred: - if (task) - mutex_unlock(&task->signal->cred_guard_mutex); --err_cpus: -- put_online_cpus(); - err_task: - if (task) - put_task_struct(task); -@@ -10135,6 +10139,21 @@ perf_event_create_kernel_counter(struct - goto err_unlock; - } - -+ if (!task) { -+ /* -+ * Check if the @cpu we're creating an event for is online. -+ * -+ * We use the perf_cpu_context::ctx::mutex to serialize against -+ * the hotplug notifiers. See perf_event_{init,exit}_cpu(). -+ */ -+ struct perf_cpu_context *cpuctx = -+ container_of(ctx, struct perf_cpu_context, ctx); -+ if (!cpuctx->online) { -+ err = -ENODEV; -+ goto err_unlock; -+ } -+ } -+ - if (!exclusive_event_installable(event, ctx)) { - err = -EBUSY; - goto err_unlock; -@@ -10802,6 +10821,8 @@ static void __init perf_event_init_all_c - struct swevent_htable *swhash; - int cpu; - -+ zalloc_cpumask_var(&perf_online_mask, GFP_KERNEL); -+ - for_each_possible_cpu(cpu) { - swhash = &per_cpu(swevent_htable, cpu); - mutex_init(&swhash->hlist_mutex); -@@ -10817,7 +10838,7 @@ static void __init perf_event_init_all_c - } - } - --int perf_event_init_cpu(unsigned int cpu) -+void perf_swevent_init_cpu(unsigned int cpu) - { - struct swevent_htable *swhash = &per_cpu(swevent_htable, cpu); - -@@ -10830,7 +10851,6 @@ int perf_event_init_cpu(unsigned int cpu - rcu_assign_pointer(swhash->swevent_hlist, hlist); - } - mutex_unlock(&swhash->hlist_mutex); -- return 0; - } - - #if defined CONFIG_HOTPLUG_CPU || defined CONFIG_KEXEC_CORE -@@ -10848,19 +10868,22 @@ static void __perf_event_exit_context(vo - - static void perf_event_exit_cpu_context(int cpu) - { -+ struct perf_cpu_context *cpuctx; - struct perf_event_context *ctx; - struct pmu *pmu; -- int idx; - -- idx = srcu_read_lock(&pmus_srcu); -- list_for_each_entry_rcu(pmu, &pmus, entry) { -- ctx = &per_cpu_ptr(pmu->pmu_cpu_context, cpu)->ctx; -+ mutex_lock(&pmus_lock); -+ list_for_each_entry(pmu, &pmus, entry) { -+ cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu); -+ ctx = &cpuctx->ctx; - - mutex_lock(&ctx->mutex); - smp_call_function_single(cpu, __perf_event_exit_context, ctx, 1); -+ cpuctx->online = 0; - mutex_unlock(&ctx->mutex); - } -- srcu_read_unlock(&pmus_srcu, idx); -+ cpumask_clear_cpu(cpu, perf_online_mask); -+ mutex_unlock(&pmus_lock); - } - #else - -@@ -10868,6 +10891,29 @@ static void perf_event_exit_cpu_context( - - #endif - -+int perf_event_init_cpu(unsigned int cpu) -+{ -+ struct perf_cpu_context *cpuctx; -+ struct perf_event_context *ctx; -+ struct pmu *pmu; -+ -+ perf_swevent_init_cpu(cpu); -+ -+ mutex_lock(&pmus_lock); -+ cpumask_set_cpu(cpu, perf_online_mask); -+ list_for_each_entry(pmu, &pmus, entry) { -+ cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu); -+ ctx = &cpuctx->ctx; -+ -+ mutex_lock(&ctx->mutex); -+ cpuctx->online = 1; -+ mutex_unlock(&ctx->mutex); -+ } -+ mutex_unlock(&pmus_lock); -+ -+ return 0; -+} -+ - int perf_event_exit_cpu(unsigned int cpu) - { - perf_event_exit_cpu_context(cpu); diff --git a/patches/0024-jump_label-Reorder-hotplug-lock-and-jump_label_lock.patch b/patches/0024-jump_label-Reorder-hotplug-lock-and-jump_label_lock.patch deleted file mode 100644 index 9182f6d78695..000000000000 --- a/patches/0024-jump_label-Reorder-hotplug-lock-and-jump_label_lock.patch +++ /dev/null @@ -1,207 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 24 May 2017 10:15:35 +0200 -Subject: [PATCH 24/32] jump_label: Reorder hotplug lock and jump_label_lock - -The conversion of the hotplug locking to a percpu rwsem unearthed lock -ordering issues all over the place. - -The jump_label code has two issues: - - 1) Nested get_online_cpus() invocations - - 2) Ordering problems vs. the cpus rwsem and the jump_label_mutex - -To cure these, the following lock order has been established; - - cpus_rwsem -> jump_label_lock -> text_mutex - -Even if not all architectures need protection against CPU hotplug, taking -cpus_rwsem before jump_label_lock is now mandatory in code pathes which -actually modify code and therefor need text_mutex protection. - -Move the get_online_cpus() invocations into the core jump label code and -establish the proper lock order where required. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Ingo Molnar <mingo@kernel.org> -Acked-by: "David S. Miller" <davem@davemloft.net> -Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Cc: Chris Metcalf <cmetcalf@mellanox.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: Jason Baron <jbaron@akamai.com> -Cc: Ralf Baechle <ralf@linux-mips.org> -Link: http://lkml.kernel.org/r/20170524081549.025830817@linutronix.de ---- - arch/mips/kernel/jump_label.c | 2 -- - arch/sparc/kernel/jump_label.c | 2 -- - arch/tile/kernel/jump_label.c | 2 -- - arch/x86/kernel/jump_label.c | 2 -- - kernel/jump_label.c | 20 ++++++++++++++------ - 5 files changed, 14 insertions(+), 14 deletions(-) - ---- a/arch/mips/kernel/jump_label.c -+++ b/arch/mips/kernel/jump_label.c -@@ -58,7 +58,6 @@ void arch_jump_label_transform(struct ju - insn.word = 0; /* nop */ - } - -- get_online_cpus(); - mutex_lock(&text_mutex); - if (IS_ENABLED(CONFIG_CPU_MICROMIPS)) { - insn_p->halfword[0] = insn.word >> 16; -@@ -70,7 +69,6 @@ void arch_jump_label_transform(struct ju - (unsigned long)insn_p + sizeof(*insn_p)); - - mutex_unlock(&text_mutex); -- put_online_cpus(); - } - - #endif /* HAVE_JUMP_LABEL */ ---- a/arch/sparc/kernel/jump_label.c -+++ b/arch/sparc/kernel/jump_label.c -@@ -41,12 +41,10 @@ void arch_jump_label_transform(struct ju - val = 0x01000000; - } - -- get_online_cpus(); - mutex_lock(&text_mutex); - *insn = val; - flushi(insn); - mutex_unlock(&text_mutex); -- put_online_cpus(); - } - - #endif ---- a/arch/tile/kernel/jump_label.c -+++ b/arch/tile/kernel/jump_label.c -@@ -45,14 +45,12 @@ static void __jump_label_transform(struc - void arch_jump_label_transform(struct jump_entry *e, - enum jump_label_type type) - { -- get_online_cpus(); - mutex_lock(&text_mutex); - - __jump_label_transform(e, type); - flush_icache_range(e->code, e->code + sizeof(tilegx_bundle_bits)); - - mutex_unlock(&text_mutex); -- put_online_cpus(); - } - - __init_or_module void arch_jump_label_transform_static(struct jump_entry *e, ---- a/arch/x86/kernel/jump_label.c -+++ b/arch/x86/kernel/jump_label.c -@@ -105,11 +105,9 @@ static void __jump_label_transform(struc - void arch_jump_label_transform(struct jump_entry *entry, - enum jump_label_type type) - { -- get_online_cpus(); - mutex_lock(&text_mutex); - __jump_label_transform(entry, type, NULL, 0); - mutex_unlock(&text_mutex); -- put_online_cpus(); - } - - static enum { ---- a/kernel/jump_label.c -+++ b/kernel/jump_label.c -@@ -15,6 +15,7 @@ - #include <linux/static_key.h> - #include <linux/jump_label_ratelimit.h> - #include <linux/bug.h> -+#include <linux/cpu.h> - - #ifdef HAVE_JUMP_LABEL - -@@ -124,6 +125,7 @@ void static_key_slow_inc(struct static_k - return; - } - -+ cpus_read_lock(); - jump_label_lock(); - if (atomic_read(&key->enabled) == 0) { - atomic_set(&key->enabled, -1); -@@ -133,12 +135,14 @@ void static_key_slow_inc(struct static_k - atomic_inc(&key->enabled); - } - jump_label_unlock(); -+ cpus_read_unlock(); - } - EXPORT_SYMBOL_GPL(static_key_slow_inc); - - static void __static_key_slow_dec(struct static_key *key, - unsigned long rate_limit, struct delayed_work *work) - { -+ cpus_read_lock(); - /* - * The negative count check is valid even when a negative - * key->enabled is in use by static_key_slow_inc(); a -@@ -149,6 +153,7 @@ static void __static_key_slow_dec(struct - if (!atomic_dec_and_mutex_lock(&key->enabled, &jump_label_mutex)) { - WARN(atomic_read(&key->enabled) < 0, - "jump label: negative count!\n"); -+ cpus_read_unlock(); - return; - } - -@@ -159,6 +164,7 @@ static void __static_key_slow_dec(struct - jump_label_update(key); - } - jump_label_unlock(); -+ cpus_read_unlock(); - } - - static void jump_label_update_timeout(struct work_struct *work) -@@ -334,6 +340,7 @@ void __init jump_label_init(void) - if (static_key_initialized) - return; - -+ cpus_read_lock(); - jump_label_lock(); - jump_label_sort_entries(iter_start, iter_stop); - -@@ -353,6 +360,7 @@ void __init jump_label_init(void) - } - static_key_initialized = true; - jump_label_unlock(); -+ cpus_read_unlock(); - } - - #ifdef CONFIG_MODULES -@@ -590,28 +598,28 @@ jump_label_module_notify(struct notifier - struct module *mod = data; - int ret = 0; - -+ cpus_read_lock(); -+ jump_label_lock(); -+ - switch (val) { - case MODULE_STATE_COMING: -- jump_label_lock(); - ret = jump_label_add_module(mod); - if (ret) { - WARN(1, "Failed to allocatote memory: jump_label may not work properly.\n"); - jump_label_del_module(mod); - } -- jump_label_unlock(); - break; - case MODULE_STATE_GOING: -- jump_label_lock(); - jump_label_del_module(mod); -- jump_label_unlock(); - break; - case MODULE_STATE_LIVE: -- jump_label_lock(); - jump_label_invalidate_module_init(mod); -- jump_label_unlock(); - break; - } - -+ jump_label_unlock(); -+ cpus_read_unlock(); -+ - return notifier_from_errno(ret); - } - diff --git a/patches/0024-tracing-Add-variable-reference-handling-to-hist-trig.patch b/patches/0024-tracing-Add-variable-reference-handling-to-hist-trig.patch index 6576aeb1de12..ac5c8d2a971b 100644 --- a/patches/0024-tracing-Add-variable-reference-handling-to-hist-trig.patch +++ b/patches/0024-tracing-Add-variable-reference-handling-to-hist-trig.patch @@ -32,7 +32,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c -@@ -7380,6 +7380,7 @@ static int instance_mkdir(const char *na +@@ -7755,6 +7755,7 @@ static int instance_mkdir(const char *na INIT_LIST_HEAD(&tr->systems); INIT_LIST_HEAD(&tr->events); @@ -40,7 +40,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (allocate_trace_buffers(tr, trace_buf_size) < 0) goto out_free_tr; -@@ -8112,6 +8113,7 @@ ssize_t trace_parse_run_command(struct f +@@ -8498,6 +8499,7 @@ ssize_t trace_parse_run_command(struct f INIT_LIST_HEAD(&global_trace.systems); INIT_LIST_HEAD(&global_trace.events); @@ -50,7 +50,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> apply_trace_boot_options(); --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h -@@ -266,6 +266,7 @@ struct trace_array { +@@ -272,6 +272,7 @@ struct trace_array { int function_enabled; #endif int time_stamp_abs_ref; @@ -58,7 +58,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> }; enum { -@@ -1442,6 +1443,8 @@ extern void pause_named_trigger(struct e +@@ -1546,6 +1547,8 @@ extern void pause_named_trigger(struct e extern void unpause_named_trigger(struct event_trigger_data *data); extern void set_named_trigger_data(struct event_trigger_data *data, struct event_trigger_data *named_data); diff --git a/patches/0025-kprobes-Cure-hotplug-lock-ordering-issues.patch b/patches/0025-kprobes-Cure-hotplug-lock-ordering-issues.patch deleted file mode 100644 index 4b76428dbaba..000000000000 --- a/patches/0025-kprobes-Cure-hotplug-lock-ordering-issues.patch +++ /dev/null @@ -1,258 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 24 May 2017 10:15:36 +0200 -Subject: [PATCH 25/32] kprobes: Cure hotplug lock ordering issues - -Converting the cpu hotplug locking to a percpu rwsem unearthed hidden lock -ordering problems. - -There is a wide range of locks involved in this: kprobe_mutex, -jump_label_mutex, ftrace_lock, text_mutex, event_mutex, module_mutex, -func_hash->regex_lock and a gazillion of lock order permutations with -nested get_online_cpus() calls. - -Some of those permutations are potential deadlocks even with the current -nesting hotplug locking scheme, but they can't be discovered by lockdep. - -The conversion of the hotplug locking to a percpu rwsem requires to prevent -nested locking, so it's required to take the hotplug rwsem early in the -call chain and establish a proper lock order. - -After quite some analysis and going down the wrong road severa times the -following lock order has been chosen: - -kprobe_mutex -> cpus_rwsem -> jump_label_mutex -> text_mutex - -For kprobes which hook on an ftrace function trace point, it's required to -drop cpus_rwsem before calling into the ftrace code to avoid a deadlock on -the func_hash->regex_lock. - -[ Steven: Ftrace interaction fixes ] - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Steven Rostedt <rostedt@goodmis.org> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Ingo Molnar <mingo@kernel.org> -Acked-by: Masami Hiramatsu <mhiramat@kernel.org> -Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Link: http://lkml.kernel.org/r/20170524081549.104864779@linutronix.de ---- - kernel/kprobes.c | 59 +++++++++++++++++++++++++++++-------------------------- - 1 file changed, 32 insertions(+), 27 deletions(-) - ---- a/kernel/kprobes.c -+++ b/kernel/kprobes.c -@@ -486,11 +486,6 @@ static DECLARE_DELAYED_WORK(optimizing_w - */ - static void do_optimize_kprobes(void) - { -- /* Optimization never be done when disarmed */ -- if (kprobes_all_disarmed || !kprobes_allow_optimization || -- list_empty(&optimizing_list)) -- return; -- - /* - * The optimization/unoptimization refers online_cpus via - * stop_machine() and cpu-hotplug modifies online_cpus. -@@ -498,14 +493,19 @@ static void do_optimize_kprobes(void) - * This combination can cause a deadlock (cpu-hotplug try to lock - * text_mutex but stop_machine can not be done because online_cpus - * has been changed) -- * To avoid this deadlock, we need to call get_online_cpus() -+ * To avoid this deadlock, caller must have locked cpu hotplug - * for preventing cpu-hotplug outside of text_mutex locking. - */ -- get_online_cpus(); -+ lockdep_assert_cpus_held(); -+ -+ /* Optimization never be done when disarmed */ -+ if (kprobes_all_disarmed || !kprobes_allow_optimization || -+ list_empty(&optimizing_list)) -+ return; -+ - mutex_lock(&text_mutex); - arch_optimize_kprobes(&optimizing_list); - mutex_unlock(&text_mutex); -- put_online_cpus(); - } - - /* -@@ -516,12 +516,13 @@ static void do_unoptimize_kprobes(void) - { - struct optimized_kprobe *op, *tmp; - -+ /* See comment in do_optimize_kprobes() */ -+ lockdep_assert_cpus_held(); -+ - /* Unoptimization must be done anytime */ - if (list_empty(&unoptimizing_list)) - return; - -- /* Ditto to do_optimize_kprobes */ -- get_online_cpus(); - mutex_lock(&text_mutex); - arch_unoptimize_kprobes(&unoptimizing_list, &freeing_list); - /* Loop free_list for disarming */ -@@ -540,7 +541,6 @@ static void do_unoptimize_kprobes(void) - list_del_init(&op->list); - } - mutex_unlock(&text_mutex); -- put_online_cpus(); - } - - /* Reclaim all kprobes on the free_list */ -@@ -565,6 +565,7 @@ static void kick_kprobe_optimizer(void) - static void kprobe_optimizer(struct work_struct *work) - { - mutex_lock(&kprobe_mutex); -+ cpus_read_lock(); - /* Lock modules while optimizing kprobes */ - mutex_lock(&module_mutex); - -@@ -590,6 +591,7 @@ static void kprobe_optimizer(struct work - do_free_cleaned_kprobes(); - - mutex_unlock(&module_mutex); -+ cpus_read_unlock(); - mutex_unlock(&kprobe_mutex); - - /* Step 5: Kick optimizer again if needed */ -@@ -653,9 +655,8 @@ static void optimize_kprobe(struct kprob - /* Short cut to direct unoptimizing */ - static void force_unoptimize_kprobe(struct optimized_kprobe *op) - { -- get_online_cpus(); -+ lockdep_assert_cpus_held(); - arch_unoptimize_kprobe(op); -- put_online_cpus(); - if (kprobe_disabled(&op->kp)) - arch_disarm_kprobe(&op->kp); - } -@@ -787,6 +788,7 @@ static void try_to_optimize_kprobe(struc - return; - - /* For preparing optimization, jump_label_text_reserved() is called */ -+ cpus_read_lock(); - jump_label_lock(); - mutex_lock(&text_mutex); - -@@ -808,6 +810,7 @@ static void try_to_optimize_kprobe(struc - out: - mutex_unlock(&text_mutex); - jump_label_unlock(); -+ cpus_read_unlock(); - } - - #ifdef CONFIG_SYSCTL -@@ -822,6 +825,7 @@ static void optimize_all_kprobes(void) - if (kprobes_allow_optimization) - goto out; - -+ cpus_read_lock(); - kprobes_allow_optimization = true; - for (i = 0; i < KPROBE_TABLE_SIZE; i++) { - head = &kprobe_table[i]; -@@ -829,6 +833,7 @@ static void optimize_all_kprobes(void) - if (!kprobe_disabled(p)) - optimize_kprobe(p); - } -+ cpus_read_unlock(); - printk(KERN_INFO "Kprobes globally optimized\n"); - out: - mutex_unlock(&kprobe_mutex); -@@ -847,6 +852,7 @@ static void unoptimize_all_kprobes(void) - return; - } - -+ cpus_read_lock(); - kprobes_allow_optimization = false; - for (i = 0; i < KPROBE_TABLE_SIZE; i++) { - head = &kprobe_table[i]; -@@ -855,6 +861,7 @@ static void unoptimize_all_kprobes(void) - unoptimize_kprobe(p, false); - } - } -+ cpus_read_unlock(); - mutex_unlock(&kprobe_mutex); - - /* Wait for unoptimizing completion */ -@@ -1006,14 +1013,11 @@ static void arm_kprobe(struct kprobe *kp - arm_kprobe_ftrace(kp); - return; - } -- /* -- * Here, since __arm_kprobe() doesn't use stop_machine(), -- * this doesn't cause deadlock on text_mutex. So, we don't -- * need get_online_cpus(). -- */ -+ cpus_read_lock(); - mutex_lock(&text_mutex); - __arm_kprobe(kp); - mutex_unlock(&text_mutex); -+ cpus_read_unlock(); - } - - /* Disarm a kprobe with text_mutex */ -@@ -1023,10 +1027,12 @@ static void disarm_kprobe(struct kprobe - disarm_kprobe_ftrace(kp); - return; - } -- /* Ditto */ -+ -+ cpus_read_lock(); - mutex_lock(&text_mutex); - __disarm_kprobe(kp, reopt); - mutex_unlock(&text_mutex); -+ cpus_read_unlock(); - } - - /* -@@ -1294,13 +1300,10 @@ static int register_aggr_kprobe(struct k - int ret = 0; - struct kprobe *ap = orig_p; - -+ cpus_read_lock(); -+ - /* For preparing optimization, jump_label_text_reserved() is called */ - jump_label_lock(); -- /* -- * Get online CPUs to avoid text_mutex deadlock.with stop machine, -- * which is invoked by unoptimize_kprobe() in add_new_kprobe() -- */ -- get_online_cpus(); - mutex_lock(&text_mutex); - - if (!kprobe_aggrprobe(orig_p)) { -@@ -1348,8 +1351,8 @@ static int register_aggr_kprobe(struct k - - out: - mutex_unlock(&text_mutex); -- put_online_cpus(); - jump_label_unlock(); -+ cpus_read_unlock(); - - if (ret == 0 && kprobe_disabled(ap) && !kprobe_disabled(p)) { - ap->flags &= ~KPROBE_FLAG_DISABLED; -@@ -1548,9 +1551,12 @@ int register_kprobe(struct kprobe *p) - goto out; - } - -- mutex_lock(&text_mutex); /* Avoiding text modification */ -+ cpus_read_lock(); -+ /* Prevent text modification */ -+ mutex_lock(&text_mutex); - ret = prepare_kprobe(p); - mutex_unlock(&text_mutex); -+ cpus_read_unlock(); - if (ret) - goto out; - -@@ -1563,7 +1569,6 @@ int register_kprobe(struct kprobe *p) - - /* Try to optimize kprobe */ - try_to_optimize_kprobe(p); -- - out: - mutex_unlock(&kprobe_mutex); - diff --git a/patches/0026-arm64-Prevent-cpu-hotplug-rwsem-recursion.patch b/patches/0026-arm64-Prevent-cpu-hotplug-rwsem-recursion.patch deleted file mode 100644 index 8ef952ef3a2a..000000000000 --- a/patches/0026-arm64-Prevent-cpu-hotplug-rwsem-recursion.patch +++ /dev/null @@ -1,58 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 24 May 2017 10:15:37 +0200 -Subject: [PATCH 26/32] arm64: Prevent cpu hotplug rwsem recursion - -The text patching functions which are invoked from jump_label and kprobes -code are protected against cpu hotplug at the call sites. - -Use stop_machine_cpuslocked() to avoid recursion on the cpu hotplug -rwsem. stop_machine_cpuslocked() contains a lockdep assertion to catch any -unprotected callers. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Ingo Molnar <mingo@kernel.org> -Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Cc: Mark Rutland <mark.rutland@arm.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Catalin Marinas <catalin.marinas@arm.com> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Will Deacon <will.deacon@arm.com> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: linux-arm-kernel@lists.infradead.org -Link: http://lkml.kernel.org/r/20170524081549.197070135@linutronix.de ---- - arch/arm64/include/asm/insn.h | 1 - - arch/arm64/kernel/insn.c | 5 +++-- - 2 files changed, 3 insertions(+), 3 deletions(-) - ---- a/arch/arm64/include/asm/insn.h -+++ b/arch/arm64/include/asm/insn.h -@@ -403,7 +403,6 @@ u32 aarch64_set_branch_offset(u32 insn, - bool aarch64_insn_hotpatch_safe(u32 old_insn, u32 new_insn); - - int aarch64_insn_patch_text_nosync(void *addr, u32 insn); --int aarch64_insn_patch_text_sync(void *addrs[], u32 insns[], int cnt); - int aarch64_insn_patch_text(void *addrs[], u32 insns[], int cnt); - - s32 aarch64_insn_adrp_get_offset(u32 insn); ---- a/arch/arm64/kernel/insn.c -+++ b/arch/arm64/kernel/insn.c -@@ -255,6 +255,7 @@ static int __kprobes aarch64_insn_patch_ - return ret; - } - -+static - int __kprobes aarch64_insn_patch_text_sync(void *addrs[], u32 insns[], int cnt) - { - struct aarch64_insn_patch patch = { -@@ -267,8 +268,8 @@ int __kprobes aarch64_insn_patch_text_sy - if (cnt <= 0) - return -EINVAL; - -- return stop_machine(aarch64_insn_patch_text_cb, &patch, -- cpu_online_mask); -+ return stop_machine_cpuslocked(aarch64_insn_patch_text_cb, &patch, -+ cpu_online_mask); - } - - int __kprobes aarch64_insn_patch_text(void *addrs[], u32 insns[], int cnt) diff --git a/patches/0027-arm-Prevent-hotplug-rwsem-recursion.patch b/patches/0027-arm-Prevent-hotplug-rwsem-recursion.patch deleted file mode 100644 index 924d8f7d5662..000000000000 --- a/patches/0027-arm-Prevent-hotplug-rwsem-recursion.patch +++ /dev/null @@ -1,46 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 24 May 2017 10:15:38 +0200 -Subject: [PATCH 27/32] arm: Prevent hotplug rwsem recursion - -The text patching functions which are invoked from jump_label and kprobes -code are protected against cpu hotplug at the call sites. - -Use stop_machine_cpuslocked() to avoid recursion on the cpu hotplug -rwsem. stop_machine_cpuslocked() contains a lockdep assertion to catch any -unprotected callers. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Ingo Molnar <mingo@kernel.org> -Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: Russell King <linux@armlinux.org.uk> -Cc: linux-arm-kernel@lists.infradead.org -Link: http://lkml.kernel.org/r/20170524081549.275871311@linutronix.de ---- - arch/arm/kernel/patch.c | 2 +- - arch/arm/probes/kprobes/core.c | 3 ++- - 2 files changed, 3 insertions(+), 2 deletions(-) - ---- a/arch/arm/kernel/patch.c -+++ b/arch/arm/kernel/patch.c -@@ -124,5 +124,5 @@ void __kprobes patch_text(void *addr, un - .insn = insn, - }; - -- stop_machine(patch_text_stop_machine, &patch, NULL); -+ stop_machine_cpuslocked(patch_text_stop_machine, &patch, NULL); - } ---- a/arch/arm/probes/kprobes/core.c -+++ b/arch/arm/probes/kprobes/core.c -@@ -182,7 +182,8 @@ void __kprobes kprobes_remove_breakpoint - .addr = addr, - .insn = insn, - }; -- stop_machine(__kprobes_remove_breakpoint, &p, cpu_online_mask); -+ stop_machine_cpuslocked(__kprobes_remove_breakpoint, &p, -+ cpu_online_mask); - } - - void __kprobes arch_disarm_kprobe(struct kprobe *p) diff --git a/patches/0028-s390-Prevent-hotplug-rwsem-recursion.patch b/patches/0028-s390-Prevent-hotplug-rwsem-recursion.patch deleted file mode 100644 index acac05937b05..000000000000 --- a/patches/0028-s390-Prevent-hotplug-rwsem-recursion.patch +++ /dev/null @@ -1,57 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 24 May 2017 10:15:39 +0200 -Subject: [PATCH 28/32] s390: Prevent hotplug rwsem recursion - -The text patching functions which are invoked from jump_label and kprobes -code are protected against cpu hotplug at the call sites. - -Use stop_machine_cpuslocked() to avoid recursion on the cpu hotplug -rwsem. stop_machine_cpuslocked() contains a lockdep assertion to catch any -unprotected callers. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Ingo Molnar <mingo@kernel.org> -Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com> -Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Cc: linux-s390@vger.kernel.org -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> -Link: http://lkml.kernel.org/r/20170524081549.354513406@linutronix.de ---- - arch/s390/kernel/jump_label.c | 2 +- - arch/s390/kernel/kprobes.c | 4 ++-- - 2 files changed, 3 insertions(+), 3 deletions(-) - ---- a/arch/s390/kernel/jump_label.c -+++ b/arch/s390/kernel/jump_label.c -@@ -93,7 +93,7 @@ void arch_jump_label_transform(struct ju - args.entry = entry; - args.type = type; - -- stop_machine(__sm_arch_jump_label_transform, &args, NULL); -+ stop_machine_cpuslocked(__sm_arch_jump_label_transform, &args, NULL); - } - - void arch_jump_label_transform_static(struct jump_entry *entry, ---- a/arch/s390/kernel/kprobes.c -+++ b/arch/s390/kernel/kprobes.c -@@ -196,7 +196,7 @@ void arch_arm_kprobe(struct kprobe *p) - { - struct swap_insn_args args = {.p = p, .arm_kprobe = 1}; - -- stop_machine(swap_instruction, &args, NULL); -+ stop_machine_cpuslocked(swap_instruction, &args, NULL); - } - NOKPROBE_SYMBOL(arch_arm_kprobe); - -@@ -204,7 +204,7 @@ void arch_disarm_kprobe(struct kprobe *p - { - struct swap_insn_args args = {.p = p, .arm_kprobe = 0}; - -- stop_machine(swap_instruction, &args, NULL); -+ stop_machine_cpuslocked(swap_instruction, &args, NULL); - } - NOKPROBE_SYMBOL(arch_disarm_kprobe); - diff --git a/patches/0029-cpu-hotplug-Convert-hotplug-locking-to-percpu-rwsem.patch b/patches/0029-cpu-hotplug-Convert-hotplug-locking-to-percpu-rwsem.patch deleted file mode 100644 index 496f4d1d7f97..000000000000 --- a/patches/0029-cpu-hotplug-Convert-hotplug-locking-to-percpu-rwsem.patch +++ /dev/null @@ -1,176 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 24 May 2017 10:15:40 +0200 -Subject: [PATCH 29/32] cpu/hotplug: Convert hotplug locking to percpu rwsem - -There are no more (known) nested calls to get_online_cpus() and all -observed lock ordering problems have been addressed. - -Replace the magic nested 'rwsem' hackery with a percpu-rwsem. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Tested-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Acked-by: Ingo Molnar <mingo@kernel.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Steven Rostedt <rostedt@goodmis.org> -Link: http://lkml.kernel.org/r/20170524081549.447014063@linutronix.de ---- - include/linux/cpu.h | 2 - kernel/cpu.c | 105 ++++++---------------------------------------------- - 2 files changed, 14 insertions(+), 93 deletions(-) - ---- a/include/linux/cpu.h -+++ b/include/linux/cpu.h -@@ -103,7 +103,7 @@ extern void cpus_write_lock(void); - extern void cpus_write_unlock(void); - extern void cpus_read_lock(void); - extern void cpus_read_unlock(void); --static inline void lockdep_assert_cpus_held(void) { } -+extern void lockdep_assert_cpus_held(void); - extern void cpu_hotplug_disable(void); - extern void cpu_hotplug_enable(void); - void clear_tasks_mm_cpumask(int cpu); ---- a/kernel/cpu.c -+++ b/kernel/cpu.c -@@ -27,6 +27,7 @@ - #include <linux/smpboot.h> - #include <linux/relay.h> - #include <linux/slab.h> -+#include <linux/percpu-rwsem.h> - - #include <trace/events/power.h> - #define CREATE_TRACE_POINTS -@@ -196,121 +197,41 @@ void cpu_maps_update_done(void) - mutex_unlock(&cpu_add_remove_lock); - } - --/* If set, cpu_up and cpu_down will return -EBUSY and do nothing. -+/* -+ * If set, cpu_up and cpu_down will return -EBUSY and do nothing. - * Should always be manipulated under cpu_add_remove_lock - */ - static int cpu_hotplug_disabled; - - #ifdef CONFIG_HOTPLUG_CPU - --static struct { -- struct task_struct *active_writer; -- /* wait queue to wake up the active_writer */ -- wait_queue_head_t wq; -- /* verifies that no writer will get active while readers are active */ -- struct mutex lock; -- /* -- * Also blocks the new readers during -- * an ongoing cpu hotplug operation. -- */ -- atomic_t refcount; -- --#ifdef CONFIG_DEBUG_LOCK_ALLOC -- struct lockdep_map dep_map; --#endif --} cpu_hotplug = { -- .active_writer = NULL, -- .wq = __WAIT_QUEUE_HEAD_INITIALIZER(cpu_hotplug.wq), -- .lock = __MUTEX_INITIALIZER(cpu_hotplug.lock), --#ifdef CONFIG_DEBUG_LOCK_ALLOC -- .dep_map = STATIC_LOCKDEP_MAP_INIT("cpu_hotplug.dep_map", &cpu_hotplug.dep_map), --#endif --}; -- --/* Lockdep annotations for get/put_online_cpus() and cpu_hotplug_begin/end() */ --#define cpuhp_lock_acquire_read() lock_map_acquire_read(&cpu_hotplug.dep_map) --#define cpuhp_lock_acquire_tryread() \ -- lock_map_acquire_tryread(&cpu_hotplug.dep_map) --#define cpuhp_lock_acquire() lock_map_acquire(&cpu_hotplug.dep_map) --#define cpuhp_lock_release() lock_map_release(&cpu_hotplug.dep_map) -- -+DEFINE_STATIC_PERCPU_RWSEM(cpu_hotplug_lock); - - void cpus_read_lock(void) - { -- might_sleep(); -- if (cpu_hotplug.active_writer == current) -- return; -- cpuhp_lock_acquire_read(); -- mutex_lock(&cpu_hotplug.lock); -- atomic_inc(&cpu_hotplug.refcount); -- mutex_unlock(&cpu_hotplug.lock); -+ percpu_down_read(&cpu_hotplug_lock); - } - EXPORT_SYMBOL_GPL(cpus_read_lock); - - void cpus_read_unlock(void) - { -- int refcount; -- -- if (cpu_hotplug.active_writer == current) -- return; -- -- refcount = atomic_dec_return(&cpu_hotplug.refcount); -- if (WARN_ON(refcount < 0)) /* try to fix things up */ -- atomic_inc(&cpu_hotplug.refcount); -- -- if (refcount <= 0 && waitqueue_active(&cpu_hotplug.wq)) -- wake_up(&cpu_hotplug.wq); -- -- cpuhp_lock_release(); -- -+ percpu_up_read(&cpu_hotplug_lock); - } - EXPORT_SYMBOL_GPL(cpus_read_unlock); - --/* -- * This ensures that the hotplug operation can begin only when the -- * refcount goes to zero. -- * -- * Note that during a cpu-hotplug operation, the new readers, if any, -- * will be blocked by the cpu_hotplug.lock -- * -- * Since cpu_hotplug_begin() is always called after invoking -- * cpu_maps_update_begin(), we can be sure that only one writer is active. -- * -- * Note that theoretically, there is a possibility of a livelock: -- * - Refcount goes to zero, last reader wakes up the sleeping -- * writer. -- * - Last reader unlocks the cpu_hotplug.lock. -- * - A new reader arrives at this moment, bumps up the refcount. -- * - The writer acquires the cpu_hotplug.lock finds the refcount -- * non zero and goes to sleep again. -- * -- * However, this is very difficult to achieve in practice since -- * get_online_cpus() not an api which is called all that often. -- * -- */ - void cpus_write_lock(void) - { -- DEFINE_WAIT(wait); -- -- cpu_hotplug.active_writer = current; -- cpuhp_lock_acquire(); -- -- for (;;) { -- mutex_lock(&cpu_hotplug.lock); -- prepare_to_wait(&cpu_hotplug.wq, &wait, TASK_UNINTERRUPTIBLE); -- if (likely(!atomic_read(&cpu_hotplug.refcount))) -- break; -- mutex_unlock(&cpu_hotplug.lock); -- schedule(); -- } -- finish_wait(&cpu_hotplug.wq, &wait); -+ percpu_down_write(&cpu_hotplug_lock); - } - - void cpus_write_unlock(void) - { -- cpu_hotplug.active_writer = NULL; -- mutex_unlock(&cpu_hotplug.lock); -- cpuhp_lock_release(); -+ percpu_up_write(&cpu_hotplug_lock); -+} -+ -+void lockdep_assert_cpus_held(void) -+{ -+ percpu_rwsem_assert_held(&cpu_hotplug_lock); - } - - /* diff --git a/patches/0030-sched-Provide-is_percpu_thread-helper.patch b/patches/0030-sched-Provide-is_percpu_thread-helper.patch deleted file mode 100644 index 7883629a3a9e..000000000000 --- a/patches/0030-sched-Provide-is_percpu_thread-helper.patch +++ /dev/null @@ -1,37 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 24 May 2017 10:15:41 +0200 -Subject: [PATCH 30/32] sched: Provide is_percpu_thread() helper - -Provide a helper function for checking whether current task is a per cpu -thread. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Tested-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Acked-by: Ingo Molnar <mingo@kernel.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Steven Rostedt <rostedt@goodmis.org> -Link: http://lkml.kernel.org/r/20170524081549.541649540@linutronix.de ---- - include/linux/sched.h | 10 ++++++++++ - 1 file changed, 10 insertions(+) - ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -1258,6 +1258,16 @@ extern struct pid *cad_pid; - #define tsk_used_math(p) ((p)->flags & PF_USED_MATH) - #define used_math() tsk_used_math(current) - -+static inline bool is_percpu_thread(void) -+{ -+#ifdef CONFIG_SMP -+ return (current->flags & PF_NO_SETAFFINITY) && -+ (current->nr_cpus_allowed == 1); -+#else -+ return true; -+#endif -+} -+ - /* Per-process atomic flags. */ - #define PFA_NO_NEW_PRIVS 0 /* May not gain new privileges. */ - #define PFA_SPREAD_PAGE 1 /* Spread page cache over cpuset */ diff --git a/patches/0031-acpi-processor-Prevent-cpu-hotplug-deadlock.patch b/patches/0031-acpi-processor-Prevent-cpu-hotplug-deadlock.patch deleted file mode 100644 index 833746254b3c..000000000000 --- a/patches/0031-acpi-processor-Prevent-cpu-hotplug-deadlock.patch +++ /dev/null @@ -1,188 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 24 May 2017 10:15:42 +0200 -Subject: [PATCH 31/32] acpi/processor: Prevent cpu hotplug deadlock - -With the enhanced CPU hotplug lockdep coverage the following lockdep splat -happens: - -====================================================== -WARNING: possible circular locking dependency detected -4.12.0-rc2+ #84 Tainted: G W ------------------------------------------------------- -cpuhp/1/15 is trying to acquire lock: -flush_work+0x39/0x2f0 - -but task is already holding lock: -cpuhp_thread_fun+0x30/0x160 - -which lock already depends on the new lock. - -the existing dependency chain (in reverse order) is: - --> #2 (cpuhp_state){+.+.+.}: - lock_acquire+0xb4/0x200 - cpuhp_kick_ap_work+0x72/0x330 - _cpu_down+0x8b/0x100 - do_cpu_down+0x3e/0x60 - cpu_down+0x10/0x20 - cpu_subsys_offline+0x14/0x20 - device_offline+0x88/0xb0 - online_store+0x4c/0xa0 - dev_attr_store+0x18/0x30 - sysfs_kf_write+0x45/0x60 - kernfs_fop_write+0x156/0x1e0 - __vfs_write+0x37/0x160 - vfs_write+0xca/0x1c0 - SyS_write+0x58/0xc0 - entry_SYSCALL_64_fastpath+0x23/0xc2 - --> #1 (cpu_hotplug_lock.rw_sem){++++++}: - lock_acquire+0xb4/0x200 - cpus_read_lock+0x3d/0xb0 - apply_workqueue_attrs+0x17/0x50 - __alloc_workqueue_key+0x1e1/0x530 - scsi_host_alloc+0x373/0x480 [scsi_mod] - ata_scsi_add_hosts+0xcb/0x130 [libata] - ata_host_register+0x11a/0x2c0 [libata] - ata_host_activate+0xf0/0x150 [libata] - ahci_host_activate+0x13e/0x170 [libahci] - ahci_init_one+0xa3a/0xd3f [ahci] - local_pci_probe+0x45/0xa0 - work_for_cpu_fn+0x14/0x20 - process_one_work+0x1f9/0x690 - worker_thread+0x200/0x3d0 - kthread+0x138/0x170 - ret_from_fork+0x31/0x40 - --> #0 ((&wfc.work)){+.+.+.}: - __lock_acquire+0x11e1/0x13e0 - lock_acquire+0xb4/0x200 - flush_work+0x5c/0x2f0 - work_on_cpu+0xa1/0xd0 - acpi_processor_get_throttling+0x3d/0x50 - acpi_processor_reevaluate_tstate+0x2c/0x50 - acpi_soft_cpu_online+0x69/0xd0 - cpuhp_invoke_callback+0xb4/0x8b0 - cpuhp_up_callbacks+0x36/0xc0 - cpuhp_thread_fun+0x14e/0x160 - smpboot_thread_fn+0x1e8/0x300 - kthread+0x138/0x170 - ret_from_fork+0x31/0x40 - -other info that might help us debug this: - -Chain exists of: - (&wfc.work) --> cpu_hotplug_lock.rw_sem --> cpuhp_state - - Possible unsafe locking scenario: - - CPU0 CPU1 - ---- ---- - lock(cpuhp_state); - lock(cpu_hotplug_lock.rw_sem); - lock(cpuhp_state); - lock((&wfc.work)); - - *** DEADLOCK *** - -1 lock held by cpuhp/1/15: -cpuhp_thread_fun+0x30/0x160 - -stack backtrace: -CPU: 1 PID: 15 Comm: cpuhp/1 Tainted: G W 4.12.0-rc2+ #84 -Hardware name: Supermicro SYS-4048B-TR4FT/X10QBi, BIOS 1.1a 07/29/2015 -Call Trace: - dump_stack+0x85/0xc4 - print_circular_bug+0x209/0x217 - __lock_acquire+0x11e1/0x13e0 - lock_acquire+0xb4/0x200 - ? lock_acquire+0xb4/0x200 - ? flush_work+0x39/0x2f0 - ? acpi_processor_start+0x50/0x50 - flush_work+0x5c/0x2f0 - ? flush_work+0x39/0x2f0 - ? acpi_processor_start+0x50/0x50 - ? mark_held_locks+0x6d/0x90 - ? queue_work_on+0x56/0x90 - ? trace_hardirqs_on_caller+0x154/0x1c0 - ? trace_hardirqs_on+0xd/0x10 - ? acpi_processor_start+0x50/0x50 - work_on_cpu+0xa1/0xd0 - ? find_worker_executing_work+0x50/0x50 - ? acpi_processor_power_exit+0x70/0x70 - acpi_processor_get_throttling+0x3d/0x50 - acpi_processor_reevaluate_tstate+0x2c/0x50 - acpi_soft_cpu_online+0x69/0xd0 - cpuhp_invoke_callback+0xb4/0x8b0 - ? lock_acquire+0xb4/0x200 - ? padata_replace+0x120/0x120 - cpuhp_up_callbacks+0x36/0xc0 - cpuhp_thread_fun+0x14e/0x160 - smpboot_thread_fn+0x1e8/0x300 - kthread+0x138/0x170 - ? sort_range+0x30/0x30 - ? kthread_create_on_node+0x70/0x70 - ret_from_fork+0x31/0x40 - -The problem is that the work is scheduled on the current CPU from the -hotplug thread associated with that CPU. - -It's not required to invoke these functions via the workqueue because the -hotplug thread runs on the target CPU already. - -Check whether current is a per cpu thread pinned on the target CPU and -invoke the function directly to avoid the workqueue. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Ingo Molnar <mingo@kernel.org> -Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: linux-acpi@vger.kernel.org -Cc: Len Brown <lenb@kernel.org> -Link: http://lkml.kernel.org/r/20170524081549.620489733@linutronix.de ---- - drivers/acpi/processor_throttling.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - ---- a/drivers/acpi/processor_throttling.c -+++ b/drivers/acpi/processor_throttling.c -@@ -909,6 +909,13 @@ static long __acpi_processor_get_throttl - return pr->throttling.acpi_processor_get_throttling(pr); - } - -+static int call_on_cpu(int cpu, long (*fn)(void *), void *arg, bool direct) -+{ -+ if (direct || (is_percpu_thread() && cpu == smp_processor_id())) -+ return fn(arg); -+ return work_on_cpu(cpu, fn, arg); -+} -+ - static int acpi_processor_get_throttling(struct acpi_processor *pr) - { - if (!pr) -@@ -926,7 +933,7 @@ static int acpi_processor_get_throttling - if (!cpu_online(pr->id)) - return -ENODEV; - -- return work_on_cpu(pr->id, __acpi_processor_get_throttling, pr); -+ return call_on_cpu(pr->id, __acpi_processor_get_throttling, pr, false); - } - - static int acpi_processor_get_fadt_info(struct acpi_processor *pr) -@@ -1076,13 +1083,6 @@ static long acpi_processor_throttling_fn - arg->target_state, arg->force); - } - --static int call_on_cpu(int cpu, long (*fn)(void *), void *arg, bool direct) --{ -- if (direct) -- return fn(arg); -- return work_on_cpu(cpu, fn, arg); --} -- - static int __acpi_processor_set_throttling(struct acpi_processor *pr, - int state, bool force, bool direct) - { diff --git a/patches/0032-cpuhotplug-Link-lock-stacks-for-hotplug-callbacks.patch b/patches/0032-cpuhotplug-Link-lock-stacks-for-hotplug-callbacks.patch deleted file mode 100644 index 027e687498cd..000000000000 --- a/patches/0032-cpuhotplug-Link-lock-stacks-for-hotplug-callbacks.patch +++ /dev/null @@ -1,87 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 24 May 2017 10:15:43 +0200 -Subject: [PATCH 32/32] cpuhotplug: Link lock stacks for hotplug callbacks - -The CPU hotplug callbacks are not covered by lockdep versus the cpu hotplug -rwsem. - -CPU0 CPU1 -cpuhp_setup_state(STATE, startup, teardown); - cpus_read_lock(); - invoke_callback_on_ap(); - kick_hotplug_thread(ap); - wait_for_completion(); hotplug_thread_fn() - lock(m); - do_stuff(); - unlock(m); - -Lockdep does not know about this dependency and will not trigger on the -following code sequence: - - lock(m); - cpus_read_lock(); - -Add a lockdep map and connect the initiators lock chain with the hotplug -thread lock chain, so potential deadlocks can be detected. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Tested-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> -Acked-by: Ingo Molnar <mingo@kernel.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Sebastian Siewior <bigeasy@linutronix.de> -Cc: Steven Rostedt <rostedt@goodmis.org> -Link: http://lkml.kernel.org/r/20170524081549.709375845@linutronix.de ---- - kernel/cpu.c | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - ---- a/kernel/cpu.c -+++ b/kernel/cpu.c -@@ -66,6 +66,12 @@ struct cpuhp_cpu_state { - - static DEFINE_PER_CPU(struct cpuhp_cpu_state, cpuhp_state); - -+#if defined(CONFIG_LOCKDEP) && defined(CONFIG_SMP) -+static struct lock_class_key cpuhp_state_key; -+static struct lockdep_map cpuhp_state_lock_map = -+ STATIC_LOCKDEP_MAP_INIT("cpuhp_state", &cpuhp_state_key); -+#endif -+ - /** - * cpuhp_step - Hotplug state machine step - * @name: Name of the step -@@ -415,6 +421,7 @@ static void cpuhp_thread_fun(unsigned in - - st->should_run = false; - -+ lock_map_acquire(&cpuhp_state_lock_map); - /* Single callback invocation for [un]install ? */ - if (st->single) { - if (st->cb_state < CPUHP_AP_ONLINE) { -@@ -441,6 +448,7 @@ static void cpuhp_thread_fun(unsigned in - else if (st->state > st->target) - ret = cpuhp_ap_offline(cpu, st); - } -+ lock_map_release(&cpuhp_state_lock_map); - st->result = ret; - complete(&st->done); - } -@@ -455,6 +463,9 @@ cpuhp_invoke_ap_callback(int cpu, enum c - if (!cpu_online(cpu)) - return 0; - -+ lock_map_acquire(&cpuhp_state_lock_map); -+ lock_map_release(&cpuhp_state_lock_map); -+ - /* - * If we are up and running, use the hotplug thread. For early calls - * we invoke the thread function directly. -@@ -498,6 +509,8 @@ static int cpuhp_kick_ap_work(unsigned i - enum cpuhp_state state = st->state; - - trace_cpuhp_enter(cpu, st->target, state, cpuhp_kick_ap_work); -+ lock_map_acquire(&cpuhp_state_lock_map); -+ lock_map_release(&cpuhp_state_lock_map); - __cpuhp_kick_ap_work(st); - wait_for_completion(&st->done); - trace_cpuhp_exit(cpu, st->state, state, st->result); diff --git a/patches/0035-tracing-Reverse-the-order-event_mutex-trace_types_lo.patch b/patches/0035-tracing-Reverse-the-order-event_mutex-trace_types_lo.patch index 400cac857dc7..a90762ed786c 100644 --- a/patches/0035-tracing-Reverse-the-order-event_mutex-trace_types_lo.patch +++ b/patches/0035-tracing-Reverse-the-order-event_mutex-trace_types_lo.patch @@ -19,7 +19,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c -@@ -1366,8 +1366,8 @@ static int subsystem_open(struct inode * +@@ -1406,8 +1406,8 @@ static int subsystem_open(struct inode * return -ENODEV; /* Make sure the system still exists */ @@ -29,7 +29,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> list_for_each_entry(tr, &ftrace_trace_arrays, list) { list_for_each_entry(dir, &tr->systems, list) { if (dir == inode->i_private) { -@@ -1381,8 +1381,8 @@ static int subsystem_open(struct inode * +@@ -1421,8 +1421,8 @@ static int subsystem_open(struct inode * } } exit_loop: @@ -39,7 +39,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (!system) return -ENODEV; -@@ -2250,15 +2250,15 @@ static void __add_event_to_tracers(struc +@@ -2290,15 +2290,15 @@ static void __add_event_to_tracers(struc int trace_add_event_call(struct trace_event_call *call) { int ret; @@ -57,7 +57,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return ret; } -@@ -2312,13 +2312,13 @@ int trace_remove_event_call(struct trace +@@ -2352,13 +2352,13 @@ int trace_remove_event_call(struct trace { int ret; @@ -73,7 +73,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return ret; } -@@ -2385,8 +2385,8 @@ static int trace_module_notify(struct no +@@ -2425,8 +2425,8 @@ static int trace_module_notify(struct no { struct module *mod = data; @@ -83,7 +83,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> switch (val) { case MODULE_STATE_COMING: trace_module_add_events(mod); -@@ -2395,8 +2395,8 @@ static int trace_module_notify(struct no +@@ -2435,8 +2435,8 @@ static int trace_module_notify(struct no trace_module_remove_events(mod); break; } diff --git a/patches/0036-tracing-Remove-lookups-from-tracing_map-hitcount.patch b/patches/0036-tracing-Remove-lookups-from-tracing_map-hitcount.patch index 39722e6579c3..24e4c9eb2a1c 100644 --- a/patches/0036-tracing-Remove-lookups-from-tracing_map-hitcount.patch +++ b/patches/0036-tracing-Remove-lookups-from-tracing_map-hitcount.patch @@ -14,7 +14,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/trace/tracing_map.c +++ b/kernel/trace/tracing_map.c -@@ -535,7 +535,8 @@ static inline struct tracing_map_elt * +@@ -538,7 +538,8 @@ static inline struct tracing_map_elt * if (test_key && test_key == key_hash) { if (entry->val && keys_match(key, entry->val->key, map->key_size)) { diff --git a/patches/0038-tracing-Make-tracing_set_clock-non-static.patch b/patches/0038-tracing-Make-tracing_set_clock-non-static.patch index a72269254654..0dfea2d8b100 100644 --- a/patches/0038-tracing-Make-tracing_set_clock-non-static.patch +++ b/patches/0038-tracing-Make-tracing_set_clock-non-static.patch @@ -18,7 +18,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c -@@ -5887,7 +5887,7 @@ static int tracing_clock_show(struct seq +@@ -6216,7 +6216,7 @@ static int tracing_clock_show(struct seq return 0; } @@ -29,7 +29,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h -@@ -281,6 +281,7 @@ extern int trace_array_get(struct trace_ +@@ -287,6 +287,7 @@ extern int trace_array_get(struct trace_ extern void trace_array_put(struct trace_array *tr); extern int tracing_set_time_stamp_abs(struct trace_array *tr, bool abs); diff --git a/patches/0040-tracing-Add-trace_event_buffer_reserve-variant-that-.patch b/patches/0040-tracing-Add-trace_event_buffer_reserve-variant-that-.patch index a7f603a6b87e..653a9a63ae59 100644 --- a/patches/0040-tracing-Add-trace_event_buffer_reserve-variant-that-.patch +++ b/patches/0040-tracing-Add-trace_event_buffer_reserve-variant-that-.patch @@ -38,7 +38,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c -@@ -2581,61 +2581,29 @@ rb_wakeups(struct ring_buffer *buffer, s +@@ -2582,61 +2582,29 @@ rb_wakeups(struct ring_buffer *buffer, s * The lock and unlock are done within a preempt disable section. * The current_context per_cpu variable can only be modified * by the current task between lock and unlock. But it can @@ -115,7 +115,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return 0; } -@@ -2643,7 +2611,9 @@ trace_recursive_lock(struct ring_buffer_ +@@ -2644,7 +2612,9 @@ trace_recursive_lock(struct ring_buffer_ static __always_inline void trace_recursive_unlock(struct ring_buffer_per_cpu *cpu_buffer) { diff --git a/patches/ARM-enable-irq-in-translation-section-permission-fau.patch b/patches/ARM-enable-irq-in-translation-section-permission-fau.patch index 70eaa5a13a9f..d90d23403814 100644 --- a/patches/ARM-enable-irq-in-translation-section-permission-fau.patch +++ b/patches/ARM-enable-irq-in-translation-section-permission-fau.patch @@ -63,7 +63,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c -@@ -431,6 +431,9 @@ do_translation_fault(unsigned long addr, +@@ -434,6 +434,9 @@ do_translation_fault(unsigned long addr, if (addr < TASK_SIZE) return do_page_fault(addr, fsr, regs); @@ -73,7 +73,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (user_mode(regs)) goto bad_area; -@@ -498,6 +501,9 @@ do_translation_fault(unsigned long addr, +@@ -501,6 +504,9 @@ do_translation_fault(unsigned long addr, static int do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { diff --git a/patches/CPUFREQ-Loongson2-drop-set_cpus_allowed_ptr.patch b/patches/CPUFREQ-Loongson2-drop-set_cpus_allowed_ptr.patch deleted file mode 100644 index 06ba3563b23f..000000000000 --- a/patches/CPUFREQ-Loongson2-drop-set_cpus_allowed_ptr.patch +++ /dev/null @@ -1,42 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Tue, 4 Apr 2017 17:43:55 +0200 -Subject: [PATCH] CPUFREQ: Loongson2: drop set_cpus_allowed_ptr() - -It is pure mystery to me why we need to be on a specific CPU while -looking up a value in an array. -My best shot at this is that before commit d4019f0a92ab ("cpufreq: move -freq change notifications to cpufreq core") it was required to invoke -cpufreq_notify_transition() on a special CPU. - -Since it looks like a waste, remove it. - -Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net> -Cc: Viresh Kumar <viresh.kumar@linaro.org> -Cc: linux-pm@vger.kernel.org -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - drivers/cpufreq/loongson2_cpufreq.c | 7 ------- - 1 file changed, 7 deletions(-) - ---- a/drivers/cpufreq/loongson2_cpufreq.c -+++ b/drivers/cpufreq/loongson2_cpufreq.c -@@ -51,19 +51,12 @@ static int loongson2_cpu_freq_notifier(s - static int loongson2_cpufreq_target(struct cpufreq_policy *policy, - unsigned int index) - { -- unsigned int cpu = policy->cpu; -- cpumask_t cpus_allowed; - unsigned int freq; - -- cpus_allowed = current->cpus_allowed; -- set_cpus_allowed_ptr(current, cpumask_of(cpu)); -- - freq = - ((cpu_clock_freq / 1000) * - loongson2_clockmod_table[index].driver_data) / 8; - -- set_cpus_allowed_ptr(current, &cpus_allowed); -- - /* setting the cpu frequency */ - clk_set_rate(policy->clk, freq * 1000); - diff --git a/patches/HACK-printk-drop-the-logbuf_lock-more-often.patch b/patches/HACK-printk-drop-the-logbuf_lock-more-often.patch index 67fa30de8beb..0282b1dde960 100644 --- a/patches/HACK-printk-drop-the-logbuf_lock-more-often.patch +++ b/patches/HACK-printk-drop-the-logbuf_lock-more-often.patch @@ -12,7 +12,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c -@@ -1409,6 +1409,8 @@ static int syslog_print_all(char __user +@@ -1408,6 +1408,8 @@ static int syslog_print_all(char __user { char *text; int len = 0; @@ -21,7 +21,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL); if (!text) -@@ -1420,6 +1422,14 @@ static int syslog_print_all(char __user +@@ -1419,6 +1421,14 @@ static int syslog_print_all(char __user u64 seq; u32 idx; @@ -36,7 +36,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * Find first record that fits, including all following records, * into the user-provided buffer for this dump. -@@ -1432,6 +1442,14 @@ static int syslog_print_all(char __user +@@ -1431,6 +1441,14 @@ static int syslog_print_all(char __user len += msg_print_text(msg, true, NULL, 0); idx = log_next(idx); seq++; @@ -51,7 +51,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } /* move first record forward until length fits into the buffer */ -@@ -1443,6 +1461,14 @@ static int syslog_print_all(char __user +@@ -1442,6 +1460,14 @@ static int syslog_print_all(char __user len -= msg_print_text(msg, true, NULL, 0); idx = log_next(idx); seq++; @@ -66,7 +66,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } /* last message fitting into this dump */ -@@ -1481,6 +1507,7 @@ static int syslog_print_all(char __user +@@ -1480,6 +1506,7 @@ static int syslog_print_all(char __user clear_seq = log_next_seq; clear_idx = log_next_idx; } diff --git a/patches/KVM-arm-arm64-downgrade-preempt_disable-d-region-to-.patch b/patches/KVM-arm-arm64-downgrade-preempt_disable-d-region-to-.patch index 192e4c6b3f35..af8cce4068c0 100644 --- a/patches/KVM-arm-arm64-downgrade-preempt_disable-d-region-to-.patch +++ b/patches/KVM-arm-arm64-downgrade-preempt_disable-d-region-to-.patch @@ -17,21 +17,21 @@ Reported-by: Manish Jaggi <Manish.Jaggi@caviumnetworks.com> Signed-off-by: Josh Cartwright <joshc@ni.com> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - arch/arm/kvm/arm.c | 6 +++--- + virt/kvm/arm/arm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) ---- a/arch/arm/kvm/arm.c -+++ b/arch/arm/kvm/arm.c -@@ -632,7 +632,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v +--- a/virt/kvm/arm/arm.c ++++ b/virt/kvm/arm/arm.c +@@ -645,7 +645,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v * involves poking the GIC, which must be done in a * non-preemptible context. */ - preempt_disable(); + migrate_disable(); + kvm_pmu_flush_hwstate(vcpu); - kvm_timer_flush_hwstate(vcpu); - kvm_vgic_flush_hwstate(vcpu); -@@ -653,7 +653,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v + +@@ -682,7 +682,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v kvm_pmu_sync_hwstate(vcpu); kvm_timer_sync_hwstate(vcpu); kvm_vgic_sync_hwstate(vcpu); @@ -40,7 +40,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> continue; } -@@ -709,7 +709,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v +@@ -737,7 +737,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v kvm_vgic_sync_hwstate(vcpu); diff --git a/patches/NFSv4-replace-seqcount_t-with-a-seqlock_t.patch b/patches/NFSv4-replace-seqcount_t-with-a-seqlock_t.patch index afa9e17fc14b..1ba7e78d6df5 100644 --- a/patches/NFSv4-replace-seqcount_t-with-a-seqlock_t.patch +++ b/patches/NFSv4-replace-seqcount_t-with-a-seqlock_t.patch @@ -57,7 +57,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c -@@ -2608,7 +2608,7 @@ static int _nfs4_open_and_get_state(stru +@@ -2615,7 +2615,7 @@ static int _nfs4_open_and_get_state(stru unsigned int seq; int ret; @@ -66,7 +66,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ret = _nfs4_proc_open(opendata); if (ret != 0) -@@ -2646,7 +2646,7 @@ static int _nfs4_open_and_get_state(stru +@@ -2653,7 +2653,7 @@ static int _nfs4_open_and_get_state(stru if (d_inode(dentry) == state->inode) { nfs_inode_attach_open_context(ctx); @@ -77,7 +77,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> out: --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c -@@ -488,7 +488,7 @@ nfs4_alloc_state_owner(struct nfs_server +@@ -494,7 +494,7 @@ nfs4_alloc_state_owner(struct nfs_server nfs4_init_seqid_counter(&sp->so_seqid); atomic_set(&sp->so_count, 1); INIT_LIST_HEAD(&sp->so_lru); @@ -86,7 +86,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> mutex_init(&sp->so_delegreturn_mutex); return sp; } -@@ -1510,8 +1510,12 @@ static int nfs4_reclaim_open_state(struc +@@ -1516,8 +1516,12 @@ static int nfs4_reclaim_open_state(struc * recovering after a network partition or a reboot from a * server that doesn't support a grace period. */ @@ -100,7 +100,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> restart: list_for_each_entry(state, &sp->so_states, open_states) { if (!test_and_clear_bit(ops->state_flag_bit, &state->flags)) -@@ -1580,14 +1584,20 @@ static int nfs4_reclaim_open_state(struc +@@ -1586,14 +1590,20 @@ static int nfs4_reclaim_open_state(struc spin_lock(&sp->so_lock); goto restart; } diff --git a/patches/RCU-we-need-to-skip-that-warning-but-only-on-sleepin.patch b/patches/RCU-we-need-to-skip-that-warning-but-only-on-sleepin.patch new file mode 100644 index 000000000000..29c575ef833b --- /dev/null +++ b/patches/RCU-we-need-to-skip-that-warning-but-only-on-sleepin.patch @@ -0,0 +1,35 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Thu, 21 Sep 2017 14:25:13 +0200 +Subject: [PATCH] RCU: we need to skip that warning but only on sleeping + locks + +This check is okay for upstream. On RT we trigger this while blocking on +sleeping lock. In this case, it is okay to schedule() within a RCU +section. +Since spin_lock() and read_lock() disables migration it should be okay +to test for this as an indication whether or not a sleeping lock is +held. The ->pi_blocked_on member won't work becasuse it might also be +set on regular mutexes. + +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + kernel/rcu/tree_plugin.h | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/kernel/rcu/tree_plugin.h ++++ b/kernel/rcu/tree_plugin.h +@@ -317,9 +317,13 @@ static void rcu_preempt_note_context_swi + struct task_struct *t = current; + struct rcu_data *rdp; + struct rcu_node *rnp; ++ int mg_counter = 0; + + RCU_LOCKDEP_WARN(!irqs_disabled(), "rcu_preempt_note_context_switch() invoked with interrupts enabled!!!\n"); +- WARN_ON_ONCE(!preempt && t->rcu_read_lock_nesting > 0); ++#if defined(CONFIG_PREEMPT_COUNT) && defined(CONFIG_SMP) ++ mg_counter = t->migrate_disable; ++#endif ++ WARN_ON_ONCE(!preempt && t->rcu_read_lock_nesting > 0 && !mg_counter); + if (t->rcu_read_lock_nesting > 0 && + !t->rcu_read_unlock_special.b.blocked) { + diff --git a/patches/add_migrate_disable.patch b/patches/add_migrate_disable.patch index 2dd2fd565fe7..bb1cdba90f35 100644 --- a/patches/add_migrate_disable.patch +++ b/patches/add_migrate_disable.patch @@ -51,7 +51,7 @@ Subject: kernel/sched/core: add migrate_disable() #ifdef MODULE --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -537,6 +537,13 @@ struct task_struct { +@@ -580,6 +580,13 @@ struct task_struct { int nr_cpus_allowed; const cpumask_t *cpus_ptr; cpumask_t cpus_mask; @@ -79,7 +79,7 @@ Subject: kernel/sched/core: add migrate_disable() * boot command line: --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -1047,7 +1047,15 @@ void set_cpus_allowed_common(struct task +@@ -1018,7 +1018,15 @@ void set_cpus_allowed_common(struct task p->nr_cpus_allowed = cpumask_weight(new_mask); } @@ -96,7 +96,7 @@ Subject: kernel/sched/core: add migrate_disable() { struct rq *rq = task_rq(p); bool queued, running; -@@ -1076,6 +1084,20 @@ void do_set_cpus_allowed(struct task_str +@@ -1047,6 +1055,20 @@ void do_set_cpus_allowed(struct task_str set_curr_task(rq, p); } @@ -117,7 +117,7 @@ Subject: kernel/sched/core: add migrate_disable() /* * Change a given task's CPU affinity. Migrate the thread to a * proper CPU and schedule it away if the CPU it's executing on -@@ -1134,9 +1156,16 @@ static int __set_cpus_allowed_ptr(struct +@@ -1105,9 +1127,16 @@ static int __set_cpus_allowed_ptr(struct } /* Can the task run on the task's current CPU? If so, we're done */ @@ -135,7 +135,7 @@ Subject: kernel/sched/core: add migrate_disable() dest_cpu = cpumask_any_and(cpu_valid_mask, new_mask); if (task_running(rq, p) || p->state == TASK_WAKING) { struct migration_arg arg = { p, dest_cpu }; -@@ -7357,3 +7386,100 @@ const u32 sched_prio_to_wmult[40] = { +@@ -6716,3 +6745,100 @@ const u32 sched_prio_to_wmult[40] = { /* 10 */ 39045157, 49367440, 61356676, 76695844, 95443717, /* 15 */ 119304647, 148102320, 186737708, 238609294, 286331153, }; @@ -238,7 +238,7 @@ Subject: kernel/sched/core: add migrate_disable() +#endif --- a/kernel/sched/debug.c +++ b/kernel/sched/debug.c -@@ -958,6 +958,10 @@ void proc_sched_show_task(struct task_st +@@ -971,6 +971,10 @@ void proc_sched_show_task(struct task_st P(dl.runtime); P(dl.deadline); } diff --git a/patches/apparmor-use-a-locallock-instead-preempt_disable.patch b/patches/apparmor-use-a-locallock-instead-preempt_disable.patch index 57a4cd2cc609..6bd8c73ac89e 100644 --- a/patches/apparmor-use-a-locallock-instead-preempt_disable.patch +++ b/patches/apparmor-use-a-locallock-instead-preempt_disable.patch @@ -4,8 +4,8 @@ Subject: apparmor: use a locallock instead preempt_disable() get_buffers() disables preemption which acts as a lock for the per-CPU variable. Since we can't disable preemption here on RT, a local_lock is -used in order to remain on the same CPU and not to have more than one user -within the critical section. +lock is used in order to remain on the same CPU and not to have more +than one user within the critical section. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- @@ -15,7 +15,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/security/apparmor/include/path.h +++ b/security/apparmor/include/path.h -@@ -38,9 +38,10 @@ struct aa_buffers { +@@ -39,9 +39,10 @@ struct aa_buffers { }; #include <linux/percpu.h> @@ -27,7 +27,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #define COUNT_ARGS(X...) COUNT_ARGS_HELPER(, ##X, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) #define COUNT_ARGS_HELPER(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, n, X...) n -@@ -54,12 +55,24 @@ DECLARE_PER_CPU(struct aa_buffers, aa_bu +@@ -55,12 +56,24 @@ DECLARE_PER_CPU(struct aa_buffers, aa_bu #define for_each_cpu_buffer(I) for ((I) = 0; (I) < MAX_PATH_BUFFERS; (I)++) @@ -53,7 +53,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #define __get_buffer(N) ({ \ struct aa_buffers *__cpu_var; \ AA_BUG_PREEMPT_ENABLED("__get_buffer without preempt disabled"); \ -@@ -72,14 +85,14 @@ DECLARE_PER_CPU(struct aa_buffers, aa_bu +@@ -73,14 +86,14 @@ DECLARE_PER_CPU(struct aa_buffers, aa_bu #define get_buffers(X...) \ do { \ @@ -72,8 +72,8 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #endif /* __AA_PATH_H */ --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c -@@ -42,7 +42,7 @@ - int apparmor_initialized __initdata; +@@ -43,7 +43,7 @@ + int apparmor_initialized; DEFINE_PER_CPU(struct aa_buffers, aa_buffers); - diff --git a/patches/arch-arm64-Add-lazy-preempt-support.patch b/patches/arch-arm64-Add-lazy-preempt-support.patch index 4cb41aefeeb7..859d2087a81f 100644 --- a/patches/arch-arm64-Add-lazy-preempt-support.patch +++ b/patches/arch-arm64-Add-lazy-preempt-support.patch @@ -20,7 +20,7 @@ Signed-off-by: Anders Roxell <anders.roxell@linaro.org> --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig -@@ -96,6 +96,7 @@ config ARM64 +@@ -102,6 +102,7 @@ config ARM64 select HAVE_PERF_EVENTS select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP @@ -107,7 +107,7 @@ Signed-off-by: Anders Roxell <anders.roxell@linaro.org> --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c -@@ -409,7 +409,7 @@ asmlinkage void do_notify_resume(struct +@@ -750,7 +750,7 @@ asmlinkage void do_notify_resume(struct */ trace_hardirqs_off(); do { diff --git a/patches/arm-preempt-lazy-support.patch b/patches/arm-preempt-lazy-support.patch index a300d3be5222..b15cdbfc2a2a 100644 --- a/patches/arm-preempt-lazy-support.patch +++ b/patches/arm-preempt-lazy-support.patch @@ -16,7 +16,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig -@@ -81,6 +81,7 @@ config ARM +@@ -84,6 +84,7 @@ config ARM select HAVE_PERF_EVENTS select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP @@ -139,7 +139,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c -@@ -572,7 +572,8 @@ do_work_pending(struct pt_regs *regs, un +@@ -614,7 +614,8 @@ do_work_pending(struct pt_regs *regs, un */ trace_hardirqs_off(); do { diff --git a/patches/arm-xen-don-t-inclide-rwlock.h-directly.patch b/patches/arm-xen-don-t-inclide-rwlock.h-directly.patch new file mode 100644 index 000000000000..36a500ec7815 --- /dev/null +++ b/patches/arm-xen-don-t-inclide-rwlock.h-directly.patch @@ -0,0 +1,26 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Thu, 5 Oct 2017 14:38:52 +0200 +Subject: [PATCH] arm/xen: don't inclide rwlock.h directly. + +rwlock.h should not be included directly. Instead linux/splinlock.h +should be included. One thing it does is to break the RT build. + +Cc: Stefano Stabellini <sstabellini@kernel.org> +Cc: xen-devel@lists.xenproject.org +Cc: linux-arm-kernel@lists.infradead.org +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + arch/arm/xen/p2m.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/xen/p2m.c ++++ b/arch/arm/xen/p2m.c +@@ -1,7 +1,7 @@ + #include <linux/bootmem.h> + #include <linux/gfp.h> + #include <linux/export.h> +-#include <linux/rwlock.h> ++#include <linux/spinlock.h> + #include <linux/slab.h> + #include <linux/types.h> + #include <linux/dma-mapping.h> diff --git a/patches/arm64-cpufeature-don-t-use-mutex-in-bringup-path.patch b/patches/arm64-cpufeature-don-t-use-mutex-in-bringup-path.patch deleted file mode 100644 index ce4f85545922..000000000000 --- a/patches/arm64-cpufeature-don-t-use-mutex-in-bringup-path.patch +++ /dev/null @@ -1,169 +0,0 @@ -From: Mark Rutland <mark.rutland@arm.com> -Date: Tue, 16 May 2017 15:18:05 +0100 -Subject: [PATCH] arm64/cpufeature: don't use mutex in bringup path - -Commit b2bb439ad99a1497daa392a527c0e52c69915ce9 upstream - -Currently, cpus_set_cap() calls static_branch_enable_cpuslocked(), which -must take the jump_label mutex. - -We call cpus_set_cap() in the secondary bringup path, from the idle -thread where interrupts are disabled. Taking a mutex in this path "is a -NONO" regardless of whether it's contended, and something we must avoid. -We didn't spot this until recently, as ___might_sleep() won't warn for -this case until all CPUs have been brought up. - -This patch avoids taking the mutex in the secondary bringup path. The -poking of static keys is deferred until enable_cpu_capabilities(), which -runs in a suitable context on the boot CPU. To account for the static -keys being set later, cpus_have_const_cap() is updated to use another -static key to check whether the const cap keys have been initialised, -falling back to the caps bitmap until this is the case. - -This means that users of cpus_have_const_cap() gain should only gain a -single additional NOP in the fast path once the const caps are -initialised, but should always see the current cap value. - -The hyp code should never dereference the caps array, since the caps are -initialized before we run the module initcall to initialise hyp. A check -is added to the hyp init code to document this requirement. - -This change will sidestep a number of issues when the upcoming hotplug -locking rework is merged. - -Signed-off-by: Mark Rutland <mark.rutland@arm.com> -Reviewed-by: Marc Zyniger <marc.zyngier@arm.com> -Reviewed-by: Suzuki Poulose <suzuki.poulose@arm.com> -Acked-by: Will Deacon <will.deacon@arm.com> -Cc: Christoffer Dall <christoffer.dall@linaro.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Sebastian Sewior <bigeasy@linutronix.de> -Cc: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - arch/arm64/include/asm/cpufeature.h | 12 ++++++++++-- - arch/arm64/include/asm/kvm_host.h | 8 ++++++-- - arch/arm64/kernel/cpufeature.c | 23 +++++++++++++++++++++-- - 3 files changed, 37 insertions(+), 6 deletions(-) - ---- a/arch/arm64/include/asm/cpufeature.h -+++ b/arch/arm64/include/asm/cpufeature.h -@@ -115,6 +115,7 @@ struct arm64_cpu_capabilities { - - extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS); - extern struct static_key_false cpu_hwcap_keys[ARM64_NCAPS]; -+extern struct static_key_false arm64_const_caps_ready; - - bool this_cpu_has_cap(unsigned int cap); - -@@ -124,7 +125,7 @@ static inline bool cpu_have_feature(unsi - } - - /* System capability check for constant caps */ --static inline bool cpus_have_const_cap(int num) -+static inline bool __cpus_have_const_cap(int num) - { - if (num >= ARM64_NCAPS) - return false; -@@ -138,6 +139,14 @@ static inline bool cpus_have_cap(unsigne - return test_bit(num, cpu_hwcaps); - } - -+static inline bool cpus_have_const_cap(int num) -+{ -+ if (static_branch_likely(&arm64_const_caps_ready)) -+ return __cpus_have_const_cap(num); -+ else -+ return cpus_have_cap(num); -+} -+ - static inline void cpus_set_cap(unsigned int num) - { - if (num >= ARM64_NCAPS) { -@@ -145,7 +154,6 @@ static inline void cpus_set_cap(unsigned - num, ARM64_NCAPS); - } else { - __set_bit(num, cpu_hwcaps); -- static_branch_enable(&cpu_hwcap_keys[num]); - } - } - ---- a/arch/arm64/include/asm/kvm_host.h -+++ b/arch/arm64/include/asm/kvm_host.h -@@ -24,6 +24,7 @@ - - #include <linux/types.h> - #include <linux/kvm_types.h> -+#include <asm/cpufeature.h> - #include <asm/kvm.h> - #include <asm/kvm_asm.h> - #include <asm/kvm_mmio.h> -@@ -356,9 +357,12 @@ static inline void __cpu_init_hyp_mode(p - unsigned long vector_ptr) - { - /* -- * Call initialization code, and switch to the full blown -- * HYP code. -+ * Call initialization code, and switch to the full blown HYP code. -+ * If the cpucaps haven't been finalized yet, something has gone very -+ * wrong, and hyp will crash and burn when it uses any -+ * cpus_have_const_cap() wrapper. - */ -+ BUG_ON(!static_branch_likely(&arm64_const_caps_ready)); - __kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr); - } - ---- a/arch/arm64/kernel/cpufeature.c -+++ b/arch/arm64/kernel/cpufeature.c -@@ -975,8 +975,16 @@ void update_cpu_capabilities(const struc - */ - void __init enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps) - { -- for (; caps->matches; caps++) -- if (caps->enable && cpus_have_cap(caps->capability)) -+ for (; caps->matches; caps++) { -+ unsigned int num = caps->capability; -+ -+ if (!cpus_have_cap(num)) -+ continue; -+ -+ /* Ensure cpus_have_const_cap(num) works */ -+ static_branch_enable(&cpu_hwcap_keys[num]); -+ -+ if (caps->enable) { - /* - * Use stop_machine() as it schedules the work allowing - * us to modify PSTATE, instead of on_each_cpu() which -@@ -984,6 +992,8 @@ void __init enable_cpu_capabilities(cons - * we return. - */ - stop_machine(caps->enable, NULL, cpu_online_mask); -+ } -+ } - } - - /* -@@ -1086,6 +1096,14 @@ static void __init setup_feature_capabil - enable_cpu_capabilities(arm64_features); - } - -+DEFINE_STATIC_KEY_FALSE(arm64_const_caps_ready); -+EXPORT_SYMBOL(arm64_const_caps_ready); -+ -+static void __init mark_const_caps_ready(void) -+{ -+ static_branch_enable(&arm64_const_caps_ready); -+} -+ - /* - * Check if the current CPU has a given feature capability. - * Should be called from non-preemptible context. -@@ -1112,6 +1130,7 @@ void __init setup_cpu_features(void) - /* Set the CPU feature capabilies */ - setup_feature_capabilities(); - enable_errata_workarounds(); -+ mark_const_caps_ready(); - setup_elf_hwcaps(arm64_elf_hwcaps); - - if (system_supports_32bit_el0()) diff --git a/patches/arm64-xen--Make-XEN-depend-on-non-rt.patch b/patches/arm64-xen--Make-XEN-depend-on-non-rt.patch index 15d7ad9087a8..fffd54beb518 100644 --- a/patches/arm64-xen--Make-XEN-depend-on-non-rt.patch +++ b/patches/arm64-xen--Make-XEN-depend-on-non-rt.patch @@ -12,7 +12,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig -@@ -742,7 +742,7 @@ config XEN_DOM0 +@@ -773,7 +773,7 @@ config XEN_DOM0 config XEN bool "Xen guest support on ARM64" diff --git a/patches/at91_dont_enable_disable_clock.patch b/patches/at91_dont_enable_disable_clock.patch index c098bbdd7822..1d4b4f9a6ece 100644 --- a/patches/at91_dont_enable_disable_clock.patch +++ b/patches/at91_dont_enable_disable_clock.patch @@ -13,7 +13,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/drivers/clocksource/tcb_clksrc.c +++ b/drivers/clocksource/tcb_clksrc.c -@@ -74,6 +74,7 @@ static struct clocksource clksrc = { +@@ -125,6 +125,7 @@ static struct clocksource clksrc = { struct tc_clkevt_device { struct clock_event_device clkevt; struct clk *clk; @@ -21,7 +21,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> void __iomem *regs; }; -@@ -91,6 +92,24 @@ static struct tc_clkevt_device *to_tc_cl +@@ -142,6 +143,24 @@ static struct tc_clkevt_device *to_tc_cl */ static u32 timer_clock; @@ -46,10 +46,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static int tc_shutdown(struct clock_event_device *d) { struct tc_clkevt_device *tcd = to_tc_clkevt(d); -@@ -98,8 +117,14 @@ static int tc_shutdown(struct clock_even +@@ -149,8 +168,14 @@ static int tc_shutdown(struct clock_even - __raw_writel(0xff, regs + ATMEL_TC_REG(2, IDR)); - __raw_writel(ATMEL_TC_CLKDIS, regs + ATMEL_TC_REG(2, CCR)); + writel(0xff, regs + ATMEL_TC_REG(2, IDR)); + writel(ATMEL_TC_CLKDIS, regs + ATMEL_TC_REG(2, CCR)); + return 0; +} + @@ -62,7 +62,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return 0; } -@@ -112,7 +137,7 @@ static int tc_set_oneshot(struct clock_e +@@ -163,7 +188,7 @@ static int tc_set_oneshot(struct clock_e if (clockevent_state_oneshot(d) || clockevent_state_periodic(d)) tc_shutdown(d); @@ -70,8 +70,8 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + tc_clk_enable(d); /* slow clock, count up to RC, then irq and stop */ - __raw_writel(timer_clock | ATMEL_TC_CPCSTOP | ATMEL_TC_WAVE | -@@ -134,7 +159,7 @@ static int tc_set_periodic(struct clock_ + writel(timer_clock | ATMEL_TC_CPCSTOP | ATMEL_TC_WAVE | +@@ -185,7 +210,7 @@ static int tc_set_periodic(struct clock_ /* By not making the gentime core emulate periodic mode on top * of oneshot, we get lower overhead and improved accuracy. */ @@ -79,8 +79,8 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + tc_clk_enable(d); /* slow clock, count up to RC, then irq and restart */ - __raw_writel(timer_clock | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO, -@@ -168,7 +193,7 @@ static struct tc_clkevt_device clkevt = + writel(timer_clock | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO, +@@ -219,7 +244,7 @@ static struct tc_clkevt_device clkevt = /* Should be lower than at91rm9200's system timer */ .rating = 125, .set_next_event = tc_next_event, diff --git a/patches/ata-disable-interrupts-if-non-rt.patch b/patches/ata-disable-interrupts-if-non-rt.patch index 32bb01a80bbf..6de60f7f80ef 100644 --- a/patches/ata-disable-interrupts-if-non-rt.patch +++ b/patches/ata-disable-interrupts-if-non-rt.patch @@ -9,8 +9,8 @@ Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- - drivers/ata/libata-sff.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) + drivers/ata/libata-sff.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -26,39 +26,3 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return consumed; } -@@ -720,7 +720,7 @@ static void ata_pio_sector(struct ata_qu - unsigned long flags; - - /* FIXME: use a bounce buffer */ -- local_irq_save(flags); -+ local_irq_save_nort(flags); - buf = kmap_atomic(page); - - /* do the actual data transfer */ -@@ -728,7 +728,7 @@ static void ata_pio_sector(struct ata_qu - do_write); - - kunmap_atomic(buf); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - } else { - buf = page_address(page); - ap->ops->sff_data_xfer(qc, buf + offset, qc->sect_size, -@@ -865,7 +865,7 @@ static int __atapi_pio_bytes(struct ata_ - unsigned long flags; - - /* FIXME: use bounce buffer */ -- local_irq_save(flags); -+ local_irq_save_nort(flags); - buf = kmap_atomic(page); - - /* do the actual data transfer */ -@@ -873,7 +873,7 @@ static int __atapi_pio_bytes(struct ata_ - count, rw); - - kunmap_atomic(buf); -- local_irq_restore(flags); -+ local_irq_restore_nort(flags); - } else { - buf = page_address(page); - consumed = ap->ops->sff_data_xfer(qc, buf + offset, diff --git a/patches/block-blk-mq-use-swait.patch b/patches/block-blk-mq-use-swait.patch index 6c36fa46406f..4f5321d5c662 100644 --- a/patches/block-blk-mq-use-swait.patch +++ b/patches/block-blk-mq-use-swait.patch @@ -45,16 +45,16 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/block/blk-core.c +++ b/block/blk-core.c -@@ -678,7 +678,7 @@ int blk_queue_enter(struct request_queue - if (nowait) - return -EBUSY; +@@ -783,7 +783,7 @@ int blk_queue_enter(struct request_queue + */ + smp_rmb(); - ret = wait_event_interruptible(q->mq_freeze_wq, + ret = swait_event_interruptible(q->mq_freeze_wq, !atomic_read(&q->mq_freeze_depth) || blk_queue_dying(q)); if (blk_queue_dying(q)) -@@ -698,7 +698,7 @@ static void blk_queue_usage_counter_rele +@@ -803,7 +803,7 @@ static void blk_queue_usage_counter_rele struct request_queue *q = container_of(ref, struct request_queue, q_usage_counter); @@ -63,7 +63,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } static void blk_rq_timed_out_timer(unsigned long data) -@@ -766,7 +766,7 @@ struct request_queue *blk_alloc_queue_no +@@ -875,7 +875,7 @@ struct request_queue *blk_alloc_queue_no q->bypass_depth = 1; __set_bit(QUEUE_FLAG_BYPASS, &q->queue_flags); @@ -74,7 +74,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * Init percpu_ref in atomic mode so that it's faster to shutdown. --- a/block/blk-mq.c +++ b/block/blk-mq.c -@@ -79,14 +79,14 @@ EXPORT_SYMBOL_GPL(blk_mq_freeze_queue_st +@@ -97,14 +97,14 @@ EXPORT_SYMBOL_GPL(blk_freeze_queue_start void blk_mq_freeze_queue_wait(struct request_queue *q) { @@ -91,7 +91,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> percpu_ref_is_zero(&q->q_usage_counter), timeout); } -@@ -127,7 +127,7 @@ void blk_mq_unfreeze_queue(struct reques +@@ -145,7 +145,7 @@ void blk_mq_unfreeze_queue(struct reques WARN_ON_ONCE(freeze_depth < 0); if (!freeze_depth) { percpu_ref_reinit(&q->q_usage_counter); @@ -100,7 +100,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } } EXPORT_SYMBOL_GPL(blk_mq_unfreeze_queue); -@@ -173,7 +173,7 @@ void blk_mq_wake_waiters(struct request_ +@@ -226,7 +226,7 @@ void blk_mq_wake_waiters(struct request_ * dying, we need to ensure that processes currently waiting on * the queue are notified as well. */ @@ -111,7 +111,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> bool blk_mq_can_queue(struct blk_mq_hw_ctx *hctx) --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h -@@ -566,7 +566,7 @@ struct request_queue { +@@ -579,7 +579,7 @@ struct request_queue { struct throtl_data *td; #endif struct rcu_head rcu_head; diff --git a/patches/block-mq-don-t-complete-requests-via-IPI.patch b/patches/block-mq-don-t-complete-requests-via-IPI.patch index bb62787879f2..84c461da0c20 100644 --- a/patches/block-mq-don-t-complete-requests-via-IPI.patch +++ b/patches/block-mq-don-t-complete-requests-via-IPI.patch @@ -8,10 +8,10 @@ moves the completion into a workqueue. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- block/blk-core.c | 3 +++ - block/blk-mq.c | 24 ++++++++++++++++++++++++ + block/blk-mq.c | 23 +++++++++++++++++++++++ include/linux/blk-mq.h | 2 +- include/linux/blkdev.h | 3 +++ - 4 files changed, 31 insertions(+), 1 deletion(-) + 4 files changed, 30 insertions(+), 1 deletion(-) --- a/block/blk-core.c +++ b/block/blk-core.c @@ -27,8 +27,8 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> rq->__sector = (sector_t) -1; --- a/block/blk-mq.c +++ b/block/blk-mq.c -@@ -213,6 +213,9 @@ void blk_mq_rq_ctx_init(struct request_q - rq->errors = 0; +@@ -283,6 +283,9 @@ static struct request *blk_mq_rq_ctx_ini + /* tag was already set */ rq->extra_len = 0; +#ifdef CONFIG_PREEMPT_RT_FULL @@ -37,7 +37,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> INIT_LIST_HEAD(&rq->timeout_list); rq->timeout = 0; -@@ -395,6 +398,17 @@ void blk_mq_end_request(struct request * +@@ -477,12 +480,24 @@ void blk_mq_end_request(struct request * } EXPORT_SYMBOL(blk_mq_end_request); @@ -55,16 +55,14 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static void __blk_mq_complete_request_remote(void *data) { struct request *rq = data; -@@ -402,6 +416,8 @@ static void __blk_mq_complete_request_re + rq->q->softirq_done_fn(rq); } - +#endif -+ - static void blk_mq_ipi_complete_request(struct request *rq) + + static void __blk_mq_complete_request(struct request *rq) { - struct blk_mq_ctx *ctx = rq->mq_ctx; -@@ -418,10 +434,18 @@ static void blk_mq_ipi_complete_request( +@@ -507,10 +522,18 @@ static void __blk_mq_complete_request(st shared = cpus_share_cache(cpu, ctx->cpu); if (cpu != ctx->cpu && !shared && cpu_online(ctx->cpu)) { @@ -85,7 +83,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h -@@ -218,7 +218,7 @@ static inline u16 blk_mq_unique_tag_to_t +@@ -227,7 +227,7 @@ static inline u16 blk_mq_unique_tag_to_t return unique_tag & BLK_MQ_UNIQUE_TAG_MASK; } @@ -93,10 +91,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +void __blk_mq_complete_request_remote_work(struct work_struct *work); int blk_mq_request_started(struct request *rq); void blk_mq_start_request(struct request *rq); - void blk_mq_end_request(struct request *rq, int error); + void blk_mq_end_request(struct request *rq, blk_status_t error); --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h -@@ -128,6 +128,9 @@ typedef __u32 __bitwise req_flags_t; +@@ -133,6 +133,9 @@ typedef __u32 __bitwise req_flags_t; */ struct request { struct list_head queuelist; diff --git a/patches/block-mq-drop-preempt-disable.patch b/patches/block-mq-drop-preempt-disable.patch index 2cb8d57c4dfc..ff9ccee07aed 100644 --- a/patches/block-mq-drop-preempt-disable.patch +++ b/patches/block-mq-drop-preempt-disable.patch @@ -13,7 +13,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/block/blk-mq.c +++ b/block/blk-mq.c -@@ -413,7 +413,7 @@ static void blk_mq_ipi_complete_request( +@@ -502,7 +502,7 @@ static void __blk_mq_complete_request(st return; } @@ -22,7 +22,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (!test_bit(QUEUE_FLAG_SAME_FORCE, &rq->q->queue_flags)) shared = cpus_share_cache(cpu, ctx->cpu); -@@ -425,7 +425,7 @@ static void blk_mq_ipi_complete_request( +@@ -514,7 +514,7 @@ static void __blk_mq_complete_request(st } else { rq->q->softirq_done_fn(rq); } @@ -30,8 +30,8 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + put_cpu_light(); } - static void blk_mq_stat_add(struct request *rq) -@@ -1143,14 +1143,14 @@ static void __blk_mq_delay_run_hw_queue( + /** +@@ -1153,14 +1153,14 @@ static void __blk_mq_delay_run_hw_queue( return; if (!async && !(hctx->flags & BLK_MQ_F_BLOCKING)) { @@ -48,4 +48,4 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + put_cpu_light(); } - if (msecs == 0) + kblockd_schedule_delayed_work_on(blk_mq_hctx_next_cpu(hctx), diff --git a/patches/block-mq-use-cpu_light.patch b/patches/block-mq-use-cpu_light.patch index ba9ecb0c5fff..49394064d38c 100644 --- a/patches/block-mq-use-cpu_light.patch +++ b/patches/block-mq-use-cpu_light.patch @@ -12,7 +12,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/block/blk-mq.h +++ b/block/blk-mq.h -@@ -130,12 +130,12 @@ static inline struct blk_mq_ctx *__blk_m +@@ -97,12 +97,12 @@ static inline struct blk_mq_ctx *__blk_m */ static inline struct blk_mq_ctx *blk_mq_get_ctx(struct request_queue *q) { diff --git a/patches/block-shorten-interrupt-disabled-regions.patch b/patches/block-shorten-interrupt-disabled-regions.patch index 190b4be0019d..bbab37e5ed33 100644 --- a/patches/block-shorten-interrupt-disabled-regions.patch +++ b/patches/block-shorten-interrupt-disabled-regions.patch @@ -47,7 +47,7 @@ Link: http://lkml.kernel.org/r/20110622174919.025446432@linutronix.de --- a/block/blk-core.c +++ b/block/blk-core.c -@@ -3186,7 +3186,7 @@ static void queue_unplugged(struct reque +@@ -3276,7 +3276,7 @@ static void queue_unplugged(struct reque blk_run_queue_async(q); else __blk_run_queue(q); @@ -56,7 +56,7 @@ Link: http://lkml.kernel.org/r/20110622174919.025446432@linutronix.de } static void flush_plug_callbacks(struct blk_plug *plug, bool from_schedule) -@@ -3234,7 +3234,6 @@ EXPORT_SYMBOL(blk_check_plugged); +@@ -3324,7 +3324,6 @@ EXPORT_SYMBOL(blk_check_plugged); void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule) { struct request_queue *q; @@ -64,7 +64,7 @@ Link: http://lkml.kernel.org/r/20110622174919.025446432@linutronix.de struct request *rq; LIST_HEAD(list); unsigned int depth; -@@ -3254,11 +3253,6 @@ void blk_flush_plug_list(struct blk_plug +@@ -3344,11 +3343,6 @@ void blk_flush_plug_list(struct blk_plug q = NULL; depth = 0; @@ -76,7 +76,7 @@ Link: http://lkml.kernel.org/r/20110622174919.025446432@linutronix.de while (!list_empty(&list)) { rq = list_entry_rq(list.next); list_del_init(&rq->queuelist); -@@ -3271,7 +3265,7 @@ void blk_flush_plug_list(struct blk_plug +@@ -3361,7 +3355,7 @@ void blk_flush_plug_list(struct blk_plug queue_unplugged(q, depth, from_schedule); q = rq->q; depth = 0; @@ -85,7 +85,7 @@ Link: http://lkml.kernel.org/r/20110622174919.025446432@linutronix.de } /* -@@ -3298,8 +3292,6 @@ void blk_flush_plug_list(struct blk_plug +@@ -3388,8 +3382,6 @@ void blk_flush_plug_list(struct blk_plug */ if (q) queue_unplugged(q, depth, from_schedule); diff --git a/patches/bug-rt-dependend-variants.patch b/patches/bug-rt-dependend-variants.patch index e9be71768437..a15ab6c1a81a 100644 --- a/patches/bug-rt-dependend-variants.patch +++ b/patches/bug-rt-dependend-variants.patch @@ -13,7 +13,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h -@@ -215,6 +215,20 @@ void __warn(const char *file, int line, +@@ -232,6 +232,20 @@ void __warn(const char *file, int line, # define WARN_ON_SMP(x) ({0;}) #endif diff --git a/patches/cgroups-scheduling-while-atomic-in-cgroup-code.patch b/patches/cgroups-scheduling-while-atomic-in-cgroup-code.patch index 145335072e3f..fdb796a12355 100644 --- a/patches/cgroups-scheduling-while-atomic-in-cgroup-code.patch +++ b/patches/cgroups-scheduling-while-atomic-in-cgroup-code.patch @@ -42,7 +42,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/mm/memcontrol.c +++ b/mm/memcontrol.c -@@ -1685,6 +1685,7 @@ struct memcg_stock_pcp { +@@ -1709,6 +1709,7 @@ struct memcg_stock_pcp { #define FLUSHING_CACHED_CHARGE 0 }; static DEFINE_PER_CPU(struct memcg_stock_pcp, memcg_stock); @@ -50,7 +50,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static DEFINE_MUTEX(percpu_charge_mutex); /** -@@ -1707,7 +1708,7 @@ static bool consume_stock(struct mem_cgr +@@ -1731,7 +1732,7 @@ static bool consume_stock(struct mem_cgr if (nr_pages > CHARGE_BATCH) return ret; @@ -59,7 +59,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> stock = this_cpu_ptr(&memcg_stock); if (memcg == stock->cached && stock->nr_pages >= nr_pages) { -@@ -1715,7 +1716,7 @@ static bool consume_stock(struct mem_cgr +@@ -1739,7 +1740,7 @@ static bool consume_stock(struct mem_cgr ret = true; } @@ -68,7 +68,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return ret; } -@@ -1742,13 +1743,13 @@ static void drain_local_stock(struct wor +@@ -1766,13 +1767,13 @@ static void drain_local_stock(struct wor struct memcg_stock_pcp *stock; unsigned long flags; @@ -84,7 +84,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } /* -@@ -1760,7 +1761,7 @@ static void refill_stock(struct mem_cgro +@@ -1784,7 +1785,7 @@ static void refill_stock(struct mem_cgro struct memcg_stock_pcp *stock; unsigned long flags; @@ -93,7 +93,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> stock = this_cpu_ptr(&memcg_stock); if (stock->cached != memcg) { /* reset if necessary */ -@@ -1769,7 +1770,7 @@ static void refill_stock(struct mem_cgro +@@ -1793,7 +1794,7 @@ static void refill_stock(struct mem_cgro } stock->nr_pages += nr_pages; diff --git a/patches/cgroups-use-simple-wait-in-css_release.patch b/patches/cgroups-use-simple-wait-in-css_release.patch index 88ba2b39b1eb..3f26e8f40031 100644 --- a/patches/cgroups-use-simple-wait-in-css_release.patch +++ b/patches/cgroups-use-simple-wait-in-css_release.patch @@ -34,7 +34,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/include/linux/cgroup-defs.h +++ b/include/linux/cgroup-defs.h -@@ -17,6 +17,7 @@ +@@ -18,6 +18,7 @@ #include <linux/percpu-rwsem.h> #include <linux/workqueue.h> #include <linux/bpf-cgroup.h> @@ -42,17 +42,17 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #ifdef CONFIG_CGROUPS -@@ -139,6 +140,7 @@ struct cgroup_subsys_state { +@@ -146,6 +147,7 @@ struct cgroup_subsys_state { /* percpu_ref killing and RCU release */ struct rcu_head rcu_head; struct work_struct destroy_work; + struct swork_event destroy_swork; - }; - /* + /* + * PI: the parent css. Placed here for cache proximity to following --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c -@@ -3895,10 +3895,10 @@ static void css_free_rcu_fn(struct rcu_h +@@ -4001,10 +4001,10 @@ static void css_free_rcu_fn(struct rcu_h queue_work(cgroup_destroy_wq, &css->destroy_work); } @@ -65,7 +65,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> struct cgroup_subsys *ss = css->ss; struct cgroup *cgrp = css->cgroup; -@@ -3943,8 +3943,8 @@ static void css_release(struct percpu_re +@@ -4049,8 +4049,8 @@ static void css_release(struct percpu_re struct cgroup_subsys_state *css = container_of(ref, struct cgroup_subsys_state, refcnt); @@ -76,7 +76,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } static void init_and_link_css(struct cgroup_subsys_state *css, -@@ -4601,6 +4601,7 @@ static int __init cgroup_wq_init(void) +@@ -4712,6 +4712,7 @@ static int __init cgroup_wq_init(void) */ cgroup_destroy_wq = alloc_workqueue("cgroup_destroy", 0, 1); BUG_ON(!cgroup_destroy_wq); diff --git a/patches/clocksource-tclib-allow-higher-clockrates.patch b/patches/clocksource-tclib-allow-higher-clockrates.patch index ca4647a942e1..4a1f9831c834 100644 --- a/patches/clocksource-tclib-allow-higher-clockrates.patch +++ b/patches/clocksource-tclib-allow-higher-clockrates.patch @@ -16,7 +16,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/drivers/clocksource/tcb_clksrc.c +++ b/drivers/clocksource/tcb_clksrc.c -@@ -23,8 +23,7 @@ +@@ -24,8 +24,7 @@ * this 32 bit free-running counter. the second channel is not used. * * - The third channel may be used to provide a 16-bit clockevent @@ -26,7 +26,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> * * A boot clocksource and clockevent source are also currently needed, * unless the relevant platforms (ARM/AT91, AVR32/AT32) are changed so -@@ -75,6 +74,7 @@ struct tc_clkevt_device { +@@ -126,6 +125,7 @@ struct tc_clkevt_device { struct clock_event_device clkevt; struct clk *clk; bool clk_enabled; @@ -34,7 +34,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> void __iomem *regs; }; -@@ -83,13 +83,6 @@ static struct tc_clkevt_device *to_tc_cl +@@ -134,13 +134,6 @@ static struct tc_clkevt_device *to_tc_cl return container_of(clkevt, struct tc_clkevt_device, clkevt); } @@ -48,29 +48,29 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> static u32 timer_clock; static void tc_clk_disable(struct clock_event_device *d) -@@ -139,7 +132,7 @@ static int tc_set_oneshot(struct clock_e +@@ -190,7 +183,7 @@ static int tc_set_oneshot(struct clock_e tc_clk_enable(d); - /* slow clock, count up to RC, then irq and stop */ + /* count up to RC, then irq and stop */ - __raw_writel(timer_clock | ATMEL_TC_CPCSTOP | ATMEL_TC_WAVE | + writel(timer_clock | ATMEL_TC_CPCSTOP | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO, regs + ATMEL_TC_REG(2, CMR)); - __raw_writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER)); -@@ -161,10 +154,10 @@ static int tc_set_periodic(struct clock_ + writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER)); +@@ -212,10 +205,10 @@ static int tc_set_periodic(struct clock_ */ tc_clk_enable(d); - /* slow clock, count up to RC, then irq and restart */ + /* count up to RC, then irq and restart */ - __raw_writel(timer_clock | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO, + writel(timer_clock | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO, regs + ATMEL_TC_REG(2, CMR)); -- __raw_writel((32768 + HZ / 2) / HZ, tcaddr + ATMEL_TC_REG(2, RC)); -+ __raw_writel((tcd->freq + HZ / 2) / HZ, tcaddr + ATMEL_TC_REG(2, RC)); +- writel((32768 + HZ / 2) / HZ, tcaddr + ATMEL_TC_REG(2, RC)); ++ writel((tcd->freq + HZ / 2) / HZ, tcaddr + ATMEL_TC_REG(2, RC)); /* Enable clock and interrupts on RC compare */ - __raw_writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER)); -@@ -191,7 +184,11 @@ static struct tc_clkevt_device clkevt = + writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER)); +@@ -242,7 +235,11 @@ static struct tc_clkevt_device clkevt = .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, /* Should be lower than at91rm9200's system timer */ @@ -82,7 +82,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> .set_next_event = tc_next_event, .set_state_shutdown = tc_shutdown_clk_off, .set_state_periodic = tc_set_periodic, -@@ -213,8 +210,9 @@ static irqreturn_t ch2_irq(int irq, void +@@ -264,8 +261,9 @@ static irqreturn_t ch2_irq(int irq, void return IRQ_NONE; } @@ -93,7 +93,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> int ret; struct clk *t2_clk = tc->clk[2]; int irq = tc->irq[2]; -@@ -235,7 +233,11 @@ static int __init setup_clkevents(struct +@@ -286,7 +284,11 @@ static int __init setup_clkevents(struct clkevt.regs = tc->regs; clkevt.clk = t2_clk; @@ -106,7 +106,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> clkevt.clkevt.cpumask = cpumask_of(0); -@@ -246,7 +248,7 @@ static int __init setup_clkevents(struct +@@ -297,7 +299,7 @@ static int __init setup_clkevents(struct return ret; } @@ -115,7 +115,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return ret; } -@@ -383,7 +385,11 @@ static int __init tcb_clksrc_init(void) +@@ -434,7 +436,11 @@ static int __init tcb_clksrc_init(void) goto err_disable_t1; /* channel 2: periodic and oneshot timer support */ diff --git a/patches/completion-use-simple-wait-queues.patch b/patches/completion-use-simple-wait-queues.patch index 0b08be768f44..c43447449315 100644 --- a/patches/completion-use-simple-wait-queues.patch +++ b/patches/completion-use-simple-wait-queues.patch @@ -23,7 +23,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/drivers/net/wireless/intersil/orinoco/orinoco_usb.c +++ b/drivers/net/wireless/intersil/orinoco/orinoco_usb.c -@@ -696,7 +696,7 @@ static void ezusb_req_ctx_wait(struct ez +@@ -697,7 +697,7 @@ static void ezusb_req_ctx_wait(struct ez while (!ctx->done.done && msecs--) udelay(1000); } else { @@ -34,18 +34,18 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> break; --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c -@@ -1594,7 +1594,7 @@ static void ffs_data_put(struct ffs_data +@@ -1609,7 +1609,7 @@ static void ffs_data_put(struct ffs_data pr_info("%s(): freeing\n", __func__); ffs_data_clear(ffs); BUG_ON(waitqueue_active(&ffs->ev.waitq) || -- waitqueue_active(&ffs->ep0req_completion.wait)); -+ swait_active(&ffs->ep0req_completion.wait)); +- waitqueue_active(&ffs->ep0req_completion.wait) || ++ swait_active(&ffs->ep0req_completion.wait) || + waitqueue_active(&ffs->wait)); kfree(ffs->dev_name); kfree(ffs); - } --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c -@@ -345,7 +345,7 @@ ep_io (struct ep_data *epdata, void *buf +@@ -347,7 +347,7 @@ ep_io (struct ep_data *epdata, void *buf spin_unlock_irq (&epdata->dev->lock); if (likely (value == 0)) { @@ -54,7 +54,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> if (value != 0) { spin_lock_irq (&epdata->dev->lock); if (likely (epdata->ep != NULL)) { -@@ -354,7 +354,7 @@ ep_io (struct ep_data *epdata, void *buf +@@ -356,7 +356,7 @@ ep_io (struct ep_data *epdata, void *buf usb_ep_dequeue (epdata->ep, epdata->req); spin_unlock_irq (&epdata->dev->lock); @@ -100,7 +100,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /** --- a/include/linux/suspend.h +++ b/include/linux/suspend.h -@@ -193,6 +193,12 @@ struct platform_freeze_ops { +@@ -195,6 +195,12 @@ struct platform_freeze_ops { void (*end)(void); }; @@ -155,7 +155,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c -@@ -546,6 +546,8 @@ static int enter_state(suspend_state_t s +@@ -569,6 +569,8 @@ static int enter_state(suspend_state_t s return error; } @@ -164,7 +164,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /** * pm_suspend - Externally visible function for suspending the system. * @state: System sleep state to enter. -@@ -560,6 +562,8 @@ int pm_suspend(suspend_state_t state) +@@ -583,6 +585,8 @@ int pm_suspend(suspend_state_t state) if (state <= PM_SUSPEND_ON || state >= PM_SUSPEND_MAX) return -EINVAL; @@ -173,7 +173,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> error = enter_state(state); if (error) { suspend_stats.fail++; -@@ -567,6 +571,7 @@ int pm_suspend(suspend_state_t state) +@@ -590,6 +594,7 @@ int pm_suspend(suspend_state_t state) } else { suspend_stats.success++; } @@ -219,7 +219,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> - DECLARE_WAITQUEUE(wait, current); + DECLARE_SWAITQUEUE(wait); -- __add_wait_queue_tail_exclusive(&x->wait, &wait); +- __add_wait_queue_entry_tail_exclusive(&x->wait, &wait); + __prepare_to_swait(&x->wait, &wait); do { if (signal_pending_state(state, current)) { @@ -276,7 +276,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> EXPORT_SYMBOL(completion_done); --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -7527,7 +7527,10 @@ void migrate_disable(void) +@@ -6886,7 +6886,10 @@ void migrate_disable(void) return; } #ifdef CONFIG_SCHED_DEBUG @@ -288,7 +288,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #endif if (p->migrate_disable) { -@@ -7557,7 +7560,10 @@ void migrate_enable(void) +@@ -6916,7 +6919,10 @@ void migrate_enable(void) } #ifdef CONFIG_SCHED_DEBUG diff --git a/patches/cond-resched-softirq-rt.patch b/patches/cond-resched-softirq-rt.patch index 032da7826e9e..7fb731f5cd00 100644 --- a/patches/cond-resched-softirq-rt.patch +++ b/patches/cond-resched-softirq-rt.patch @@ -15,7 +15,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -1519,12 +1519,16 @@ extern int __cond_resched_lock(spinlock_ +@@ -1565,12 +1565,16 @@ extern int __cond_resched_lock(spinlock_ __cond_resched_lock(lock); \ }) @@ -34,7 +34,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> { --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -5095,6 +5095,7 @@ int __cond_resched_lock(spinlock_t *lock +@@ -4912,6 +4912,7 @@ int __cond_resched_lock(spinlock_t *lock } EXPORT_SYMBOL(__cond_resched_lock); @@ -42,7 +42,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> int __sched __cond_resched_softirq(void) { BUG_ON(!in_softirq()); -@@ -5108,6 +5109,7 @@ int __sched __cond_resched_softirq(void) +@@ -4925,6 +4926,7 @@ int __sched __cond_resched_softirq(void) return 0; } EXPORT_SYMBOL(__cond_resched_softirq); diff --git a/patches/cpu-hotplug--Implement-CPU-pinning.patch b/patches/cpu-hotplug--Implement-CPU-pinning.patch index 3c4a005a1d18..69e01f8334c1 100644 --- a/patches/cpu-hotplug--Implement-CPU-pinning.patch +++ b/patches/cpu-hotplug--Implement-CPU-pinning.patch @@ -10,7 +10,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -546,6 +546,7 @@ struct task_struct { +@@ -589,6 +589,7 @@ struct task_struct { #if defined(CONFIG_PREEMPT_COUNT) && defined(CONFIG_SMP) int migrate_disable; int migrate_disable_update; @@ -77,7 +77,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } DEFINE_STATIC_PERCPU_RWSEM(cpu_hotplug_lock); -@@ -644,6 +679,7 @@ static int take_cpu_down(void *_param) +@@ -621,6 +656,7 @@ static int take_cpu_down(void *_param) static int takedown_cpu(unsigned int cpu) { @@ -85,7 +85,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); int err; -@@ -657,11 +693,14 @@ static int takedown_cpu(unsigned int cpu +@@ -634,11 +670,14 @@ static int takedown_cpu(unsigned int cpu */ irq_lock_sparse(); @@ -100,7 +100,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* CPU refused to die */ irq_unlock_sparse(); /* Unpark the hotplug thread so we can rollback there */ -@@ -680,6 +719,7 @@ static int takedown_cpu(unsigned int cpu +@@ -657,6 +696,7 @@ static int takedown_cpu(unsigned int cpu wait_for_completion(&st->done); BUG_ON(st->state != CPUHP_AP_IDLE_DEAD); diff --git a/patches/cpu_chill-Add-a-UNINTERRUPTIBLE-hrtimer_nanosleep.patch b/patches/cpu_chill-Add-a-UNINTERRUPTIBLE-hrtimer_nanosleep.patch index fa483e301775..3c85f50f0de8 100644 --- a/patches/cpu_chill-Add-a-UNINTERRUPTIBLE-hrtimer_nanosleep.patch +++ b/patches/cpu_chill-Add-a-UNINTERRUPTIBLE-hrtimer_nanosleep.patch @@ -28,76 +28,74 @@ Reported-by: Ulrich Obergfell <uobergfe@redhat.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - kernel/time/hrtimer.c | 25 ++++++++++++++++++------- - 1 file changed, 18 insertions(+), 7 deletions(-) + kernel/time/hrtimer.c | 24 +++++++++++++++++------- + 1 file changed, 17 insertions(+), 7 deletions(-) --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -1689,10 +1689,11 @@ EXPORT_SYMBOL_GPL(hrtimer_init_sleeper_o - #endif - +@@ -1709,12 +1709,13 @@ int nanosleep_copyout(struct restart_blo + return -ERESTART_RESTARTBLOCK; + } -static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode) +static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode, + unsigned long state) { + struct restart_block *restart; + do { - set_current_state(TASK_INTERRUPTIBLE); + set_current_state(state); hrtimer_start_expires(&t->timer, mode); if (likely(t->task)) -@@ -1734,7 +1735,8 @@ long __sched hrtimer_nanosleep_restart(s +@@ -1752,13 +1753,15 @@ static long __sched hrtimer_nanosleep_re + hrtimer_init_sleeper_on_stack(&t, restart->nanosleep.clockid, HRTIMER_MODE_ABS, current); hrtimer_set_expires_tv64(&t.timer, restart->nanosleep.expires); - -- if (do_nanosleep(&t, HRTIMER_MODE_ABS)) +- ret = do_nanosleep(&t, HRTIMER_MODE_ABS); + /* cpu_chill() does not care about restart state. */ -+ if (do_nanosleep(&t, HRTIMER_MODE_ABS, TASK_INTERRUPTIBLE)) - goto out; - - rmtp = restart->nanosleep.rmtp; -@@ -1751,8 +1753,10 @@ long __sched hrtimer_nanosleep_restart(s ++ ret = do_nanosleep(&t, HRTIMER_MODE_ABS, TASK_INTERRUPTIBLE); + destroy_hrtimer_on_stack(&t.timer); return ret; } --long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, +-long hrtimer_nanosleep(const struct timespec64 *rqtp, - const enum hrtimer_mode mode, const clockid_t clockid) -+static long -+__hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, -+ const enum hrtimer_mode mode, const clockid_t clockid, -+ unsigned long state) ++static long __hrtimer_nanosleep(const struct timespec64 *rqtp, ++ const enum hrtimer_mode mode, const clockid_t clockid, ++ unsigned long state) { struct restart_block *restart; struct hrtimer_sleeper t; -@@ -1766,7 +1770,7 @@ long hrtimer_nanosleep(struct timespec * - hrtimer_init_sleeper_on_stack(&t, clockid, mode, current); - hrtimer_set_expires_range_ns(&t.timer, timespec_to_ktime(*rqtp), slack); +@@ -1771,7 +1774,7 @@ long hrtimer_nanosleep(const struct time -- if (do_nanosleep(&t, mode)) -+ if (do_nanosleep(&t, mode, state)) + hrtimer_init_sleeper_on_stack(&t, clockid, mode, current); + hrtimer_set_expires_range_ns(&t.timer, timespec64_to_ktime(*rqtp), slack); +- ret = do_nanosleep(&t, mode); ++ ret = do_nanosleep(&t, mode, state); + if (ret != -ERESTART_RESTARTBLOCK) goto out; - /* Absolute timers do not update the rmtp value and restart: */ -@@ -1793,6 +1797,12 @@ long hrtimer_nanosleep(struct timespec * +@@ -1790,6 +1793,12 @@ long hrtimer_nanosleep(const struct time return ret; } -+long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, ++long hrtimer_nanosleep(const struct timespec64 *rqtp, + const enum hrtimer_mode mode, const clockid_t clockid) +{ -+ return __hrtimer_nanosleep(rqtp, rmtp, mode, clockid, TASK_INTERRUPTIBLE); ++ return __hrtimer_nanosleep(rqtp, mode, clockid, TASK_INTERRUPTIBLE); +} + SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp, struct timespec __user *, rmtp) { -@@ -1819,7 +1829,8 @@ void cpu_chill(void) +@@ -1837,7 +1846,8 @@ void cpu_chill(void) unsigned int freeze_flag = current->flags & PF_NOFREEZE; current->flags |= PF_NOFREEZE; -- hrtimer_nanosleep(&tu, NULL, HRTIMER_MODE_REL, CLOCK_MONOTONIC_HARD); -+ __hrtimer_nanosleep(&tu, NULL, HRTIMER_MODE_REL, CLOCK_MONOTONIC_HARD, +- hrtimer_nanosleep(&tu, HRTIMER_MODE_REL, CLOCK_MONOTONIC_HARD); ++ __hrtimer_nanosleep(&tu, HRTIMER_MODE_REL, CLOCK_MONOTONIC_HARD, + TASK_UNINTERRUPTIBLE); if (!freeze_flag) current->flags &= ~PF_NOFREEZE; diff --git a/patches/cpumask-disable-offstack-on-rt.patch b/patches/cpumask-disable-offstack-on-rt.patch index bdf44b5c8213..220a71e134f0 100644 --- a/patches/cpumask-disable-offstack-on-rt.patch +++ b/patches/cpumask-disable-offstack-on-rt.patch @@ -46,7 +46,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig -@@ -908,7 +908,7 @@ config IOMMU_HELPER +@@ -919,7 +919,7 @@ config IOMMU_HELPER config MAXSMP bool "Enable Maximum number of SMP Processors and NUMA Nodes" depends on X86_64 && SMP && DEBUG_KERNEL @@ -57,7 +57,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> If unsure, say N. --- a/lib/Kconfig +++ b/lib/Kconfig -@@ -409,6 +409,7 @@ config CHECK_SIGNATURE +@@ -417,6 +417,7 @@ config CHECK_SIGNATURE config CPUMASK_OFFSTACK bool "Force CPU masks off stack" if DEBUG_PER_CPU_MAPS diff --git a/patches/cpuset-Convert-callback_lock-to-raw_spinlock_t.patch b/patches/cpuset-Convert-callback_lock-to-raw_spinlock_t.patch index ee674f25a519..97c607f2fdc9 100644 --- a/patches/cpuset-Convert-callback_lock-to-raw_spinlock_t.patch +++ b/patches/cpuset-Convert-callback_lock-to-raw_spinlock_t.patch @@ -50,7 +50,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c -@@ -286,7 +286,7 @@ static struct cpuset top_cpuset = { +@@ -287,7 +287,7 @@ static struct cpuset top_cpuset = { */ static DEFINE_MUTEX(cpuset_mutex); @@ -59,7 +59,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static struct workqueue_struct *cpuset_migrate_mm_wq; -@@ -909,9 +909,9 @@ static void update_cpumasks_hier(struct +@@ -910,9 +910,9 @@ static void update_cpumasks_hier(struct continue; rcu_read_unlock(); @@ -71,7 +71,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> WARN_ON(!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) && !cpumask_equal(cp->cpus_allowed, cp->effective_cpus)); -@@ -976,9 +976,9 @@ static int update_cpumask(struct cpuset +@@ -977,9 +977,9 @@ static int update_cpumask(struct cpuset if (retval < 0) return retval; @@ -83,7 +83,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* use trialcs->cpus_allowed as a temp variable */ update_cpumasks_hier(cs, trialcs->cpus_allowed); -@@ -1178,9 +1178,9 @@ static void update_nodemasks_hier(struct +@@ -1164,9 +1164,9 @@ static void update_nodemasks_hier(struct continue; rcu_read_unlock(); @@ -95,7 +95,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> WARN_ON(!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) && !nodes_equal(cp->mems_allowed, cp->effective_mems)); -@@ -1248,9 +1248,9 @@ static int update_nodemask(struct cpuset +@@ -1234,9 +1234,9 @@ static int update_nodemask(struct cpuset if (retval < 0) goto done; @@ -107,7 +107,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* use trialcs->mems_allowed as a temp variable */ update_nodemasks_hier(cs, &trialcs->mems_allowed); -@@ -1341,9 +1341,9 @@ static int update_flag(cpuset_flagbits_t +@@ -1327,9 +1327,9 @@ static int update_flag(cpuset_flagbits_t spread_flag_changed = ((is_spread_slab(cs) != is_spread_slab(trialcs)) || (is_spread_page(cs) != is_spread_page(trialcs))); @@ -119,7 +119,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (!cpumask_empty(trialcs->cpus_allowed) && balance_flag_changed) rebuild_sched_domains_locked(); -@@ -1758,7 +1758,7 @@ static int cpuset_common_seq_show(struct +@@ -1744,7 +1744,7 @@ static int cpuset_common_seq_show(struct cpuset_filetype_t type = seq_cft(sf)->private; int ret = 0; @@ -128,7 +128,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> switch (type) { case FILE_CPULIST: -@@ -1777,7 +1777,7 @@ static int cpuset_common_seq_show(struct +@@ -1763,7 +1763,7 @@ static int cpuset_common_seq_show(struct ret = -EINVAL; } @@ -137,7 +137,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return ret; } -@@ -1991,12 +1991,12 @@ static int cpuset_css_online(struct cgro +@@ -1978,12 +1978,12 @@ static int cpuset_css_online(struct cgro cpuset_inc(); @@ -152,7 +152,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (!test_bit(CGRP_CPUSET_CLONE_CHILDREN, &css->cgroup->flags)) goto out_unlock; -@@ -2023,12 +2023,12 @@ static int cpuset_css_online(struct cgro +@@ -2010,12 +2010,12 @@ static int cpuset_css_online(struct cgro } rcu_read_unlock(); @@ -167,7 +167,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> out_unlock: mutex_unlock(&cpuset_mutex); return 0; -@@ -2067,7 +2067,7 @@ static void cpuset_css_free(struct cgrou +@@ -2054,7 +2054,7 @@ static void cpuset_css_free(struct cgrou static void cpuset_bind(struct cgroup_subsys_state *root_css) { mutex_lock(&cpuset_mutex); @@ -176,7 +176,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys)) { cpumask_copy(top_cpuset.cpus_allowed, cpu_possible_mask); -@@ -2078,7 +2078,7 @@ static void cpuset_bind(struct cgroup_su +@@ -2065,7 +2065,7 @@ static void cpuset_bind(struct cgroup_su top_cpuset.mems_allowed = top_cpuset.effective_mems; } @@ -185,7 +185,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> mutex_unlock(&cpuset_mutex); } -@@ -2179,12 +2179,12 @@ hotplug_update_tasks_legacy(struct cpuse +@@ -2163,12 +2163,12 @@ hotplug_update_tasks_legacy(struct cpuse { bool is_empty; @@ -200,7 +200,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * Don't call update_tasks_cpumask() if the cpuset becomes empty, -@@ -2221,10 +2221,10 @@ hotplug_update_tasks(struct cpuset *cs, +@@ -2205,10 +2205,10 @@ hotplug_update_tasks(struct cpuset *cs, if (nodes_empty(*new_mems)) *new_mems = parent_cs(cs)->effective_mems; @@ -213,7 +213,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (cpus_updated) update_tasks_cpumask(cs); -@@ -2310,21 +2310,21 @@ static void cpuset_hotplug_workfn(struct +@@ -2301,21 +2301,21 @@ static void cpuset_hotplug_workfn(struct /* synchronize cpus_allowed to cpu_active_mask */ if (cpus_updated) { @@ -239,7 +239,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> update_tasks_nodemask(&top_cpuset); } -@@ -2422,11 +2422,11 @@ void cpuset_cpus_allowed(struct task_str +@@ -2420,11 +2420,11 @@ void cpuset_cpus_allowed(struct task_str { unsigned long flags; @@ -253,7 +253,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } void cpuset_cpus_allowed_fallback(struct task_struct *tsk) -@@ -2474,11 +2474,11 @@ nodemask_t cpuset_mems_allowed(struct ta +@@ -2472,11 +2472,11 @@ nodemask_t cpuset_mems_allowed(struct ta nodemask_t mask; unsigned long flags; @@ -267,7 +267,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return mask; } -@@ -2570,14 +2570,14 @@ bool __cpuset_node_allowed(int node, gfp +@@ -2568,14 +2568,14 @@ bool __cpuset_node_allowed(int node, gfp return true; /* Not hardwall and node outside mems_allowed: scan up cpusets */ diff --git a/patches/crypto-Reduce-preempt-disabled-regions-more-algos.patch b/patches/crypto-Reduce-preempt-disabled-regions-more-algos.patch index 2dd404c05764..e36b96ec1640 100644 --- a/patches/crypto-Reduce-preempt-disabled-regions-more-algos.patch +++ b/patches/crypto-Reduce-preempt-disabled-regions-more-algos.patch @@ -124,7 +124,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> err = blkcipher_walk_done(desc, &walk, 0); --- a/arch/x86/crypto/glue_helper.c +++ b/arch/x86/crypto/glue_helper.c -@@ -39,7 +39,7 @@ static int __glue_ecb_crypt_128bit(const +@@ -40,7 +40,7 @@ static int __glue_ecb_crypt_128bit(const void *ctx = crypto_blkcipher_ctx(desc->tfm); const unsigned int bsize = 128 / 8; unsigned int nbytes, i, func_bytes; @@ -133,7 +133,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> int err; err = blkcipher_walk_virt(desc, walk); -@@ -49,7 +49,7 @@ static int __glue_ecb_crypt_128bit(const +@@ -50,7 +50,7 @@ static int __glue_ecb_crypt_128bit(const u8 *wdst = walk->dst.virt.addr; fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, @@ -142,7 +142,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> for (i = 0; i < gctx->num_funcs; i++) { func_bytes = bsize * gctx->funcs[i].num_blocks; -@@ -71,10 +71,10 @@ static int __glue_ecb_crypt_128bit(const +@@ -72,10 +72,10 @@ static int __glue_ecb_crypt_128bit(const } done: @@ -154,7 +154,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return err; } -@@ -194,7 +194,7 @@ int glue_cbc_decrypt_128bit(const struct +@@ -192,7 +192,7 @@ int glue_cbc_decrypt_128bit(const struct struct scatterlist *src, unsigned int nbytes) { const unsigned int bsize = 128 / 8; @@ -163,7 +163,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> struct blkcipher_walk walk; int err; -@@ -203,12 +203,12 @@ int glue_cbc_decrypt_128bit(const struct +@@ -201,12 +201,12 @@ int glue_cbc_decrypt_128bit(const struct while ((nbytes = walk.nbytes)) { fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, @@ -178,7 +178,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return err; } EXPORT_SYMBOL_GPL(glue_cbc_decrypt_128bit); -@@ -277,7 +277,7 @@ int glue_ctr_crypt_128bit(const struct c +@@ -275,7 +275,7 @@ int glue_ctr_crypt_128bit(const struct c struct scatterlist *src, unsigned int nbytes) { const unsigned int bsize = 128 / 8; @@ -187,7 +187,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> struct blkcipher_walk walk; int err; -@@ -286,13 +286,12 @@ int glue_ctr_crypt_128bit(const struct c +@@ -284,13 +284,12 @@ int glue_ctr_crypt_128bit(const struct c while ((nbytes = walk.nbytes) >= bsize) { fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, @@ -203,7 +203,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (walk.nbytes) { glue_ctr_crypt_final_128bit( gctx->funcs[gctx->num_funcs - 1].fn_u.ctr, desc, &walk); -@@ -382,7 +381,7 @@ int glue_xts_crypt_128bit(const struct c +@@ -380,7 +379,7 @@ int glue_xts_crypt_128bit(const struct c void *tweak_ctx, void *crypt_ctx) { const unsigned int bsize = 128 / 8; @@ -212,7 +212,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> struct blkcipher_walk walk; int err; -@@ -395,21 +394,21 @@ int glue_xts_crypt_128bit(const struct c +@@ -393,21 +392,21 @@ int glue_xts_crypt_128bit(const struct c /* set minimum length to bsize, for tweak_fn */ fpu_enabled = glue_fpu_begin(bsize, gctx->fpu_blocks_limit, diff --git a/patches/dm-make-rt-aware.patch b/patches/dm-make-rt-aware.patch index 0ec19f8c25a2..268b1d0a3f34 100644 --- a/patches/dm-make-rt-aware.patch +++ b/patches/dm-make-rt-aware.patch @@ -15,7 +15,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/drivers/md/dm-rq.c +++ b/drivers/md/dm-rq.c -@@ -667,7 +667,7 @@ static void dm_old_request_fn(struct req +@@ -674,7 +674,7 @@ static void dm_old_request_fn(struct req /* Establish tio->ti before queuing work (map_tio_request) */ tio->ti = ti; kthread_queue_work(&md->kworker, &tio->work); diff --git a/patches/drivers-block-zram-Replace-bit-spinlocks-with-rtmute.patch b/patches/drivers-block-zram-Replace-bit-spinlocks-with-rtmute.patch index 6b2930760412..de4b4bca6253 100644 --- a/patches/drivers-block-zram-Replace-bit-spinlocks-with-rtmute.patch +++ b/patches/drivers-block-zram-Replace-bit-spinlocks-with-rtmute.patch @@ -9,114 +9,57 @@ OTOH, they're a lot less wasteful than an rtmutex per page. Signed-off-by: Mike Galbraith <umgwanakikbuti@gmail.com> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - drivers/block/zram/zram_drv.c | 30 ++++++++++++++++-------------- - drivers/block/zram/zram_drv.h | 41 +++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 57 insertions(+), 14 deletions(-) + drivers/block/zram/zram_drv.c | 26 ++++++++++++++++++++++++++ + drivers/block/zram/zram_drv.h | 4 ++++ + 2 files changed, 30 insertions(+) --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c -@@ -461,6 +461,8 @@ static struct zram_meta *zram_meta_alloc - goto out_error; - } +@@ -422,6 +422,30 @@ static DEVICE_ATTR_RO(io_stat); + static DEVICE_ATTR_RO(mm_stat); + static DEVICE_ATTR_RO(debug_stat); -+ zram_meta_init_table_locks(meta, disksize); ++#ifdef CONFIG_PREEMPT_RT_BASE ++static void zram_meta_init_table_locks(struct zram *zram, size_t num_pages) ++{ ++ size_t index; + - return meta; - - out_error: -@@ -511,12 +513,12 @@ static int zram_decompress_page(struct z - unsigned long handle; - unsigned int size; - -- bit_spin_lock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_lock_table(&meta->table[index]); - handle = meta->table[index].handle; - size = zram_get_obj_size(meta, index); - - if (!handle || zram_test_flag(meta, index, ZRAM_SAME)) { -- bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_unlock_table(&meta->table[index]); - zram_fill_page(mem, PAGE_SIZE, meta->table[index].element); - return 0; - } -@@ -531,7 +533,7 @@ static int zram_decompress_page(struct z - zcomp_stream_put(zram->comp); - } - zs_unmap_object(meta->mem_pool, handle); -- bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_unlock_table(&meta->table[index]); - - /* Should NEVER happen. Return bio error if it does. */ - if (unlikely(ret)) { -@@ -551,14 +553,14 @@ static int zram_bvec_read(struct zram *z - struct zram_meta *meta = zram->meta; - page = bvec->bv_page; - -- bit_spin_lock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_lock_table(&meta->table[index]); - if (unlikely(!meta->table[index].handle) || - zram_test_flag(meta, index, ZRAM_SAME)) { -- bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_unlock_table(&meta->table[index]); - handle_same_page(bvec, meta->table[index].element); - return 0; - } -- bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_unlock_table(&meta->table[index]); - - if (is_partial_io(bvec)) - /* Use a temporary buffer to decompress the page */ -@@ -636,11 +638,11 @@ static int zram_bvec_write(struct zram * - if (user_mem) - kunmap_atomic(user_mem); - /* Free memory associated with this sector now. */ -- bit_spin_lock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_lock_table(&meta->table[index]); - zram_free_page(zram, index); - zram_set_flag(meta, index, ZRAM_SAME); - zram_set_element(meta, index, element); -- bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_unlock_table(&meta->table[index]); - - atomic64_inc(&zram->stats.same_pages); - ret = 0; -@@ -731,12 +733,12 @@ static int zram_bvec_write(struct zram * - * Free memory associated with this sector - * before overwriting unused sectors. - */ -- bit_spin_lock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_lock_table(&meta->table[index]); - zram_free_page(zram, index); - - meta->table[index].handle = handle; - zram_set_obj_size(meta, index, clen); -- bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_unlock_table(&meta->table[index]); ++ for (index = 0; index < num_pages; index++) ++ spin_lock_init(&zram->table[index].lock); ++} ++ ++static void zram_slot_lock(struct zram *zram, u32 index) ++{ ++ spin_lock(&zram->table[index].lock); ++ __set_bit(ZRAM_ACCESS, &zram->table[index].value); ++} ++ ++static void zram_slot_unlock(struct zram *zram, u32 index) ++{ ++ __clear_bit(ZRAM_ACCESS, &zram->table[index].value); ++ spin_unlock(&zram->table[index].lock); ++} ++ ++#else ++static void zram_meta_init_table_locks(struct zram *zram, size_t num_pages) { } ++ + static void zram_slot_lock(struct zram *zram, u32 index) + { + bit_spin_lock(ZRAM_ACCESS, &zram->table[index].value); +@@ -431,6 +455,7 @@ static void zram_slot_unlock(struct zram + { + bit_spin_unlock(ZRAM_ACCESS, &zram->table[index].value); + } ++#endif - /* Update stats */ - atomic64_add(clen, &zram->stats.compr_data_size); -@@ -779,9 +781,9 @@ static void zram_bio_discard(struct zram + static bool zram_same_page_read(struct zram *zram, u32 index, + struct page *page, +@@ -505,6 +530,7 @@ static bool zram_meta_alloc(struct zram + return false; } - while (n >= PAGE_SIZE) { -- bit_spin_lock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_lock_table(&meta->table[index]); - zram_free_page(zram, index); -- bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_unlock_table(&meta->table[index]); - atomic64_inc(&zram->stats.notify_free); - index++; - n -= PAGE_SIZE; -@@ -905,9 +907,9 @@ static void zram_slot_free_notify(struct - zram = bdev->bd_disk->private_data; - meta = zram->meta; - -- bit_spin_lock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_lock_table(&meta->table[index]); - zram_free_page(zram, index); -- bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value); -+ zram_unlock_table(&meta->table[index]); - atomic64_inc(&zram->stats.notify_free); ++ zram_meta_init_table_locks(zram, disksize); + return true; } --- a/drivers/block/zram/zram_drv.h @@ -131,46 +74,9 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> }; struct zram_stats { -@@ -120,4 +123,42 @@ struct zram { +@@ -116,4 +119,5 @@ struct zram { */ bool claim; /* Protected by bdev->bd_mutex */ }; + -+#ifndef CONFIG_PREEMPT_RT_BASE -+static inline void zram_lock_table(struct zram_table_entry *table) -+{ -+ bit_spin_lock(ZRAM_ACCESS, &table->value); -+} -+ -+static inline void zram_unlock_table(struct zram_table_entry *table) -+{ -+ bit_spin_unlock(ZRAM_ACCESS, &table->value); -+} -+ -+static inline void zram_meta_init_table_locks(struct zram_meta *meta, u64 disksize) { } -+#else /* CONFIG_PREEMPT_RT_BASE */ -+static inline void zram_lock_table(struct zram_table_entry *table) -+{ -+ spin_lock(&table->lock); -+ __set_bit(ZRAM_ACCESS, &table->value); -+} -+ -+static inline void zram_unlock_table(struct zram_table_entry *table) -+{ -+ __clear_bit(ZRAM_ACCESS, &table->value); -+ spin_unlock(&table->lock); -+} -+ -+static inline void zram_meta_init_table_locks(struct zram_meta *meta, u64 disksize) -+{ -+ size_t num_pages = disksize >> PAGE_SHIFT; -+ size_t index; -+ -+ for (index = 0; index < num_pages; index++) { -+ spinlock_t *lock = &meta->table[index].lock; -+ spin_lock_init(lock); -+ } -+} -+#endif /* CONFIG_PREEMPT_RT_BASE */ -+ #endif diff --git a/patches/drivers-net-8139-disable-irq-nosync.patch b/patches/drivers-net-8139-disable-irq-nosync.patch index 82cd2f3a0f0b..3c01971e035a 100644 --- a/patches/drivers-net-8139-disable-irq-nosync.patch +++ b/patches/drivers-net-8139-disable-irq-nosync.patch @@ -14,7 +14,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/drivers/net/ethernet/realtek/8139too.c +++ b/drivers/net/ethernet/realtek/8139too.c -@@ -2223,7 +2223,7 @@ static void rtl8139_poll_controller(stru +@@ -2224,7 +2224,7 @@ static void rtl8139_poll_controller(stru struct rtl8139_private *tp = netdev_priv(dev); const int irq = tp->pci_dev->irq; diff --git a/patches/drivers-tty-pl011-irq-disable-madness.patch b/patches/drivers-tty-pl011-irq-disable-madness.patch index 76d6db60c33f..7ee9fe7045f0 100644 --- a/patches/drivers-tty-pl011-irq-disable-madness.patch +++ b/patches/drivers-tty-pl011-irq-disable-madness.patch @@ -12,7 +12,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c -@@ -2222,13 +2222,19 @@ pl011_console_write(struct console *co, +@@ -2220,13 +2220,19 @@ pl011_console_write(struct console *co, clk_enable(uap->clk); @@ -35,7 +35,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * First save the CR then disable the interrupts -@@ -2254,8 +2260,7 @@ pl011_console_write(struct console *co, +@@ -2252,8 +2258,7 @@ pl011_console_write(struct console *co, pl011_write(old_cr, uap, REG_CR); if (locked) diff --git a/patches/drivers-zram-Don-t-disable-preemption-in-zcomp_strea.patch b/patches/drivers-zram-Don-t-disable-preemption-in-zcomp_strea.patch index 92d15f6af596..ceec63cd1644 100644 --- a/patches/drivers-zram-Don-t-disable-preemption-in-zcomp_strea.patch +++ b/patches/drivers-zram-Don-t-disable-preemption-in-zcomp_strea.patch @@ -15,12 +15,12 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- drivers/block/zram/zcomp.c | 12 ++++++++++-- drivers/block/zram/zcomp.h | 1 + - drivers/block/zram/zram_drv.c | 6 +++--- - 3 files changed, 14 insertions(+), 5 deletions(-) + drivers/block/zram/zram_drv.c | 5 +++-- + 3 files changed, 14 insertions(+), 4 deletions(-) --- a/drivers/block/zram/zcomp.c +++ b/drivers/block/zram/zcomp.c -@@ -118,12 +118,19 @@ ssize_t zcomp_available_show(const char +@@ -116,12 +116,19 @@ ssize_t zcomp_available_show(const char struct zcomp_strm *zcomp_stream_get(struct zcomp *comp) { @@ -42,7 +42,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } int zcomp_compress(struct zcomp_strm *zstrm, -@@ -173,6 +180,7 @@ int zcomp_cpu_up_prepare(unsigned int cp +@@ -171,6 +178,7 @@ int zcomp_cpu_up_prepare(unsigned int cp pr_err("Can't allocate a compression stream\n"); return -ENOMEM; } @@ -62,30 +62,35 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* dynamic per-device compression frontend */ --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c -@@ -512,6 +512,7 @@ static int zram_decompress_page(struct z - struct zram_meta *meta = zram->meta; +@@ -574,6 +574,7 @@ static int zram_decompress_page(struct z unsigned long handle; unsigned int size; + void *src, *dst; + struct zcomp_strm *zstrm; - zram_lock_table(&meta->table[index]); - handle = meta->table[index].handle; -@@ -523,16 +524,15 @@ static int zram_decompress_page(struct z + if (zram_same_page_read(zram, index, page, 0, PAGE_SIZE)) return 0; - } +@@ -582,6 +583,7 @@ static int zram_decompress_page(struct z + handle = zram_get_handle(zram, index); + size = zram_get_obj_size(zram, index); + zstrm = zcomp_stream_get(zram->comp); - cmem = zs_map_object(meta->mem_pool, handle, ZS_MM_RO); + src = zs_map_object(zram->mem_pool, handle, ZS_MM_RO); if (size == PAGE_SIZE) { - memcpy(mem, cmem, PAGE_SIZE); + dst = kmap_atomic(page); +@@ -589,14 +591,13 @@ static int zram_decompress_page(struct z + kunmap_atomic(dst); + ret = 0; } else { - struct zcomp_strm *zstrm = zcomp_stream_get(zram->comp); -- - ret = zcomp_decompress(zstrm, cmem, size, mem); + + dst = kmap_atomic(page); + ret = zcomp_decompress(zstrm, src, size, dst); + kunmap_atomic(dst); - zcomp_stream_put(zram->comp); } - zs_unmap_object(meta->mem_pool, handle); + zs_unmap_object(zram->mem_pool, handle); + zcomp_stream_put(zram->comp); - zram_unlock_table(&meta->table[index]); + zram_slot_unlock(zram, index); /* Should NEVER happen. Return bio error if it does. */ diff --git a/patches/drivers-zram-fix-zcomp_stream_get-smp_processor_id-u.patch b/patches/drivers-zram-fix-zcomp_stream_get-smp_processor_id-u.patch index 8eabb445eaef..fde000b05a19 100644 --- a/patches/drivers-zram-fix-zcomp_stream_get-smp_processor_id-u.patch +++ b/patches/drivers-zram-fix-zcomp_stream_get-smp_processor_id-u.patch @@ -18,7 +18,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/drivers/block/zram/zcomp.c +++ b/drivers/block/zram/zcomp.c -@@ -120,7 +120,7 @@ struct zcomp_strm *zcomp_stream_get(stru +@@ -118,7 +118,7 @@ struct zcomp_strm *zcomp_stream_get(stru { struct zcomp_strm *zstrm; @@ -27,7 +27,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> spin_lock(&zstrm->zcomp_lock); return zstrm; } -@@ -131,6 +131,7 @@ void zcomp_stream_put(struct zcomp *comp +@@ -129,6 +129,7 @@ void zcomp_stream_put(struct zcomp *comp zstrm = *this_cpu_ptr(comp->stream); spin_unlock(&zstrm->zcomp_lock); diff --git a/patches/drm-i915-drop-trace_i915_gem_ring_dispatch-onrt.patch b/patches/drm-i915-drop-trace_i915_gem_ring_dispatch-onrt.patch deleted file mode 100644 index 91240516fae1..000000000000 --- a/patches/drm-i915-drop-trace_i915_gem_ring_dispatch-onrt.patch +++ /dev/null @@ -1,58 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Thu, 25 Apr 2013 18:12:52 +0200 -Subject: drm/i915: drop trace_i915_gem_ring_dispatch on rt - -This tracepoint is responsible for: - -|[<814cc358>] __schedule_bug+0x4d/0x59 -|[<814d24cc>] __schedule+0x88c/0x930 -|[<814d3b90>] ? _raw_spin_unlock_irqrestore+0x40/0x50 -|[<814d3b95>] ? _raw_spin_unlock_irqrestore+0x45/0x50 -|[<810b57b5>] ? task_blocks_on_rt_mutex+0x1f5/0x250 -|[<814d27d9>] schedule+0x29/0x70 -|[<814d3423>] rt_spin_lock_slowlock+0x15b/0x278 -|[<814d3786>] rt_spin_lock+0x26/0x30 -|[<a00dced9>] gen6_gt_force_wake_get+0x29/0x60 [i915] -|[<a00e183f>] gen6_ring_get_irq+0x5f/0x100 [i915] -|[<a00b2a33>] ftrace_raw_event_i915_gem_ring_dispatch+0xe3/0x100 [i915] -|[<a00ac1b3>] i915_gem_do_execbuffer.isra.13+0xbd3/0x1430 [i915] -|[<810f8943>] ? trace_buffer_unlock_commit+0x43/0x60 -|[<8113e8d2>] ? ftrace_raw_event_kmem_alloc+0xd2/0x180 -|[<8101d063>] ? native_sched_clock+0x13/0x80 -|[<a00acf29>] i915_gem_execbuffer2+0x99/0x280 [i915] -|[<a00114a3>] drm_ioctl+0x4c3/0x570 [drm] -|[<8101d0d9>] ? sched_clock+0x9/0x10 -|[<a00ace90>] ? i915_gem_execbuffer+0x480/0x480 [i915] -|[<810f1c18>] ? rb_commit+0x68/0xa0 -|[<810f1c6c>] ? ring_buffer_unlock_commit+0x1c/0xa0 -|[<81197467>] do_vfs_ioctl+0x97/0x540 -|[<81021318>] ? ftrace_raw_event_sys_enter+0xd8/0x130 -|[<811979a1>] sys_ioctl+0x91/0xb0 -|[<814db931>] tracesys+0xe1/0xe6 - -Chris Wilson does not like to move i915_trace_irq_get() out of the macro - -|No. This enables the IRQ, as well as making a number of -|very expensively serialised read, unconditionally. - -so it is gone now on RT. - - -Reported-by: Joakim Hernberg <jbh@alchemy.lu> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c -+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c -@@ -1445,7 +1445,9 @@ execbuf_submit(struct i915_execbuffer_pa - if (ret) - return ret; - -+#ifndef CONFIG_PREEMPT_RT_BASE - trace_i915_gem_ring_dispatch(params->request, params->dispatch_flags); -+#endif - - i915_gem_execbuffer_move_to_active(vmas, params->request); - diff --git a/patches/drm-i915-init-spinlock-properly-on-RT.patch b/patches/drm-i915-init-spinlock-properly-on-RT.patch index a0fbb615dd78..11cda8f82c9c 100644 --- a/patches/drm-i915-init-spinlock-properly-on-RT.patch +++ b/patches/drm-i915-init-spinlock-properly-on-RT.patch @@ -11,16 +11,16 @@ Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> --- a/drivers/gpu/drm/i915/i915_gem_timeline.c +++ b/drivers/gpu/drm/i915/i915_gem_timeline.c -@@ -50,7 +50,12 @@ static int __i915_gem_timeline_init(stru - tl->fence_context = fences++; - tl->common = timeline; +@@ -34,7 +34,12 @@ static void __intel_timeline_init(struct + tl->fence_context = context; + tl->common = parent; #ifdef CONFIG_DEBUG_SPINLOCK +# ifdef CONFIG_PREEMPT_RT_FULL -+ rt_mutex_init(&tl->lock.lock); -+ __rt_spin_lock_init(&tl->lock, lockname, lockclass); ++ rt_mutex_init(&tl->lock.lock); ++ __rt_spin_lock_init(&tl->lock, lockname, lockclass); +# else - __raw_spin_lock_init(&tl->lock.rlock, lockname, lockclass); + __raw_spin_lock_init(&tl->lock.rlock, lockname, lockclass); +# endif #else - spin_lock_init(&tl->lock); + spin_lock_init(&tl->lock); #endif diff --git a/patches/drmi915_Use_local_lockunlock_irq()_in_intel_pipe_update_startend().patch b/patches/drmi915_Use_local_lockunlock_irq()_in_intel_pipe_update_startend().patch index 38a0ece74ccb..c12fc3be285e 100644 --- a/patches/drmi915_Use_local_lockunlock_irq()_in_intel_pipe_update_startend().patch +++ b/patches/drmi915_Use_local_lockunlock_irq()_in_intel_pipe_update_startend().patch @@ -56,8 +56,8 @@ Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Cc: linux-rt-users <linux-rt-users@vger.kernel.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- - drivers/gpu/drm/i915/intel_sprite.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) + drivers/gpu/drm/i915/intel_sprite.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -69,17 +69,17 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #include "intel_drv.h" #include "intel_frontbuffer.h" #include <drm/i915_drm.h> -@@ -65,6 +66,8 @@ int intel_usecs_to_scanlines(const struc - 1000 * adjusted_mode->crtc_htotal); +@@ -66,7 +67,7 @@ int intel_usecs_to_scanlines(const struc } + #define VBLANK_EVASION_TIME_US 100 +- +static DEFINE_LOCAL_IRQ_LOCK(pipe_update_lock); -+ /** * intel_pipe_update_start() - start update of a set of display registers * @crtc: the crtc of which the registers are going to be updated -@@ -98,7 +101,7 @@ void intel_pipe_update_start(struct inte - min = vblank_start - intel_usecs_to_scanlines(adjusted_mode, 100); +@@ -101,7 +102,7 @@ void intel_pipe_update_start(struct inte + VBLANK_EVASION_TIME_US); max = vblank_start - 1; - local_irq_disable(); @@ -87,7 +87,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> if (min <= 0 || max <= 0) return; -@@ -128,11 +131,11 @@ void intel_pipe_update_start(struct inte +@@ -131,11 +132,11 @@ void intel_pipe_update_start(struct inte break; } @@ -101,12 +101,12 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } finish_wait(wq, &wait); -@@ -202,7 +205,7 @@ void intel_pipe_update_end(struct intel_ +@@ -206,7 +207,7 @@ void intel_pipe_update_end(struct intel_ crtc->base.state->event = NULL; } - local_irq_enable(); + local_unlock_irq(pipe_update_lock); - if (crtc->debug.start_vbl_count && - crtc->debug.start_vbl_count != end_vbl_count) { + if (intel_vgpu_active(dev_priv)) + return; diff --git a/patches/drmradeoni915_Use_preempt_disableenable_rt()_where_recommended.patch b/patches/drmradeoni915_Use_preempt_disableenable_rt()_where_recommended.patch index 2f8e9da43b15..8aa5a875b887 100644 --- a/patches/drmradeoni915_Use_preempt_disableenable_rt()_where_recommended.patch +++ b/patches/drmradeoni915_Use_preempt_disableenable_rt()_where_recommended.patch @@ -15,7 +15,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c -@@ -867,6 +867,7 @@ static int i915_get_crtc_scanoutpos(stru +@@ -868,6 +868,7 @@ static bool i915_get_crtc_scanoutpos(str spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ @@ -23,7 +23,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* Get optional system timestamp before query. */ if (stime) -@@ -918,6 +919,7 @@ static int i915_get_crtc_scanoutpos(stru +@@ -919,6 +920,7 @@ static bool i915_get_crtc_scanoutpos(str *etime = ktime_get(); /* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */ @@ -33,7 +33,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c -@@ -1845,6 +1845,7 @@ int radeon_get_crtc_scanoutpos(struct dr +@@ -1854,6 +1854,7 @@ int radeon_get_crtc_scanoutpos(struct dr struct radeon_device *rdev = dev->dev_private; /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ @@ -41,7 +41,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* Get optional system timestamp before query. */ if (stime) -@@ -1937,6 +1938,7 @@ int radeon_get_crtc_scanoutpos(struct dr +@@ -1946,6 +1947,7 @@ int radeon_get_crtc_scanoutpos(struct dr *etime = ktime_get(); /* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */ diff --git a/patches/epoll-use-get-cpu-light.patch b/patches/epoll-use-get-cpu-light.patch index 2824ec2c2a63..7dfa6c5b3fb5 100644 --- a/patches/epoll-use-get-cpu-light.patch +++ b/patches/epoll-use-get-cpu-light.patch @@ -13,7 +13,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/fs/eventpoll.c +++ b/fs/eventpoll.c -@@ -510,12 +510,12 @@ static int ep_poll_wakeup_proc(void *pri +@@ -587,12 +587,12 @@ static int ep_poll_wakeup_proc(void *pri */ static void ep_poll_safewake(wait_queue_head_t *wq) { diff --git a/patches/fs-block-rt-support.patch b/patches/fs-block-rt-support.patch index d52294701d18..78f9980d47c1 100644 --- a/patches/fs-block-rt-support.patch +++ b/patches/fs-block-rt-support.patch @@ -11,12 +11,12 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/block/blk-core.c +++ b/block/blk-core.c -@@ -214,7 +214,7 @@ EXPORT_SYMBOL(blk_start_queue_async); - **/ +@@ -280,7 +280,7 @@ EXPORT_SYMBOL(blk_start_queue_async); void blk_start_queue(struct request_queue *q) { -- WARN_ON(!irqs_disabled()); -+ WARN_ON_NONRT(!irqs_disabled()); + lockdep_assert_held(q->queue_lock); +- WARN_ON(!in_interrupt() && !irqs_disabled()); ++ WARN_ON_NONRT(!in_interrupt() && !irqs_disabled()); + WARN_ON_ONCE(q->mq_ops); queue_flag_clear(QUEUE_FLAG_STOPPED, q); - __blk_run_queue(q); diff --git a/patches/fs-dcache-bringt-back-explicit-INIT_HLIST_BL_HEAD-in.patch b/patches/fs-dcache-bringt-back-explicit-INIT_HLIST_BL_HEAD-in.patch new file mode 100644 index 000000000000..423ab2412b84 --- /dev/null +++ b/patches/fs-dcache-bringt-back-explicit-INIT_HLIST_BL_HEAD-in.patch @@ -0,0 +1,51 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Wed, 13 Sep 2017 12:32:34 +0200 +Subject: [PATCH] fs/dcache: bringt back explicit INIT_HLIST_BL_HEAD init + +Commit 3d375d78593c ("mm: update callers to use HASH_ZERO flag") removed +INIT_HLIST_BL_HEAD and uses the ZERO flag instead for the init. However +on RT we have also a spinlock which needs an init call so we can't use +that. + +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + fs/dcache.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -3578,6 +3578,8 @@ static int __init set_dhash_entries(char + + static void __init dcache_init_early(void) + { ++ unsigned int loop; ++ + /* If hashes are distributed across NUMA nodes, defer + * hash allocation until vmalloc space is available. + */ +@@ -3594,10 +3596,14 @@ static void __init dcache_init_early(voi + &d_hash_mask, + 0, + 0); ++ ++ for (loop = 0; loop < (1U << d_hash_shift); loop++) ++ INIT_HLIST_BL_HEAD(dentry_hashtable + loop); + } + + static void __init dcache_init(void) + { ++ unsigned int loop; + /* + * A constructor could be added for stable state like the lists, + * but it is probably not worth it because of the cache nature +@@ -3620,6 +3626,10 @@ static void __init dcache_init(void) + &d_hash_mask, + 0, + 0); ++ ++ for (loop = 0; loop < (1U << d_hash_shift); loop++) ++ INIT_HLIST_BL_HEAD(dentry_hashtable + loop); ++ + } + + /* SLAB cache for __getname() consumers */ diff --git a/patches/fs-dcache-init-in_lookup_hashtable.patch b/patches/fs-dcache-init-in_lookup_hashtable.patch deleted file mode 100644 index 0d3d30c91b67..000000000000 --- a/patches/fs-dcache-init-in_lookup_hashtable.patch +++ /dev/null @@ -1,27 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Wed, 14 Sep 2016 17:57:03 +0200 -Subject: [PATCH] fs/dcache: init in_lookup_hashtable - -in_lookup_hashtable was introduced in commit 94bdd655caba ("parallel -lookups machinery, part 3") and never initialized but since it is in -the data it is all zeros. But we need this for -RT. - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - fs/dcache.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/fs/dcache.c -+++ b/fs/dcache.c -@@ -3611,6 +3611,11 @@ EXPORT_SYMBOL(d_genocide); - - void __init vfs_caches_init_early(void) - { -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(in_lookup_hashtable); i++) -+ INIT_HLIST_BL_HEAD(&in_lookup_hashtable[i]); -+ - dcache_init_early(); - inode_init_early(); - } diff --git a/patches/fs-dcache-use-cpu-chill-in-trylock-loops.patch b/patches/fs-dcache-use-cpu-chill-in-trylock-loops.patch index caacbbf4059d..64fb26097e2d 100644 --- a/patches/fs-dcache-use-cpu-chill-in-trylock-loops.patch +++ b/patches/fs-dcache-use-cpu-chill-in-trylock-loops.patch @@ -46,7 +46,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #include <linux/slab.h> #include <linux/init.h> #include <linux/hash.h> -@@ -750,6 +751,8 @@ static inline bool fast_dput(struct dent +@@ -784,6 +785,8 @@ static inline bool fast_dput(struct dent */ void dput(struct dentry *dentry) { @@ -55,7 +55,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> if (unlikely(!dentry)) return; -@@ -788,9 +791,18 @@ void dput(struct dentry *dentry) +@@ -820,9 +823,18 @@ void dput(struct dentry *dentry) return; kill_it: @@ -77,7 +77,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> goto repeat; } } -@@ -2331,7 +2343,7 @@ void d_delete(struct dentry * dentry) +@@ -2360,7 +2372,7 @@ void d_delete(struct dentry * dentry) if (dentry->d_lockref.count == 1) { if (!spin_trylock(&inode->i_lock)) { spin_unlock(&dentry->d_lock); @@ -96,7 +96,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #include <linux/security.h> #include <linux/cred.h> #include <linux/idr.h> -@@ -358,7 +359,7 @@ int __mnt_want_write(struct vfsmount *m) +@@ -355,7 +356,7 @@ int __mnt_want_write(struct vfsmount *m) smp_mb(); while (ACCESS_ONCE(mnt->mnt.mnt_flags) & MNT_WRITE_HOLD) { preempt_enable(); diff --git a/patches/fs-dcache-use-swait_queue-instead-of-waitqueue.patch b/patches/fs-dcache-use-swait_queue-instead-of-waitqueue.patch index 32a09b14f9f7..9ca117f2bb6c 100644 --- a/patches/fs-dcache-use-swait_queue-instead-of-waitqueue.patch +++ b/patches/fs-dcache-use-swait_queue-instead-of-waitqueue.patch @@ -33,7 +33,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/fs/dcache.c +++ b/fs/dcache.c -@@ -2403,21 +2403,24 @@ static inline void end_dir_add(struct in +@@ -2432,21 +2432,24 @@ static inline void end_dir_add(struct in static void d_wait_lookup(struct dentry *dentry) { @@ -69,7 +69,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> { unsigned int hash = name->hash; struct hlist_bl_head *b = in_lookup_hash(parent, hash); -@@ -2526,7 +2529,7 @@ void __d_lookup_done(struct dentry *dent +@@ -2555,7 +2558,7 @@ void __d_lookup_done(struct dentry *dent hlist_bl_lock(b); dentry->d_flags &= ~DCACHE_PAR_LOOKUP; __hlist_bl_del(&dentry->d_u.d_in_lookup_hash); @@ -100,7 +100,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> inode_lock_shared(inode); /* Don't go there if it's already dead */ -@@ -3069,7 +3069,7 @@ static int lookup_open(struct nameidata +@@ -3101,7 +3101,7 @@ static int lookup_open(struct nameidata struct dentry *dentry; int error, create_error = 0; umode_t mode = op->mode; @@ -111,7 +111,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return -ENOENT; --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c -@@ -491,7 +491,7 @@ static +@@ -452,7 +452,7 @@ static void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) { struct qstr filename = QSTR_INIT(entry->name, entry->len); @@ -120,7 +120,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> struct dentry *dentry; struct dentry *alias; struct inode *dir = d_inode(parent); -@@ -1493,7 +1493,7 @@ int nfs_atomic_open(struct inode *dir, s +@@ -1443,7 +1443,7 @@ int nfs_atomic_open(struct inode *dir, s struct file *file, unsigned open_flags, umode_t mode, int *opened) { @@ -151,7 +151,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> spin_lock(&dentry->d_lock); --- a/fs/proc/base.c +++ b/fs/proc/base.c -@@ -1836,7 +1836,7 @@ bool proc_fill_cache(struct file *file, +@@ -1876,7 +1876,7 @@ bool proc_fill_cache(struct file *file, child = d_hash_and_lookup(dir, &qname); if (!child) { @@ -162,7 +162,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> goto end_instantiate; --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c -@@ -682,7 +682,7 @@ static bool proc_sys_fill_cache(struct f +@@ -678,7 +678,7 @@ static bool proc_sys_fill_cache(struct f child = d_lookup(dir, &qname); if (!child) { @@ -173,7 +173,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return false; --- a/include/linux/dcache.h +++ b/include/linux/dcache.h -@@ -101,7 +101,7 @@ struct dentry { +@@ -106,7 +106,7 @@ struct dentry { union { struct list_head d_lru; /* LRU list */ @@ -182,7 +182,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> }; struct list_head d_child; /* child of parent list */ struct list_head d_subdirs; /* our children */ -@@ -231,7 +231,7 @@ extern void d_set_d_op(struct dentry *de +@@ -236,7 +236,7 @@ extern void d_set_d_op(struct dentry *de extern struct dentry * d_alloc(struct dentry *, const struct qstr *); extern struct dentry * d_alloc_pseudo(struct super_block *, const struct qstr *); extern struct dentry * d_alloc_parallel(struct dentry *, const struct qstr *, @@ -193,7 +193,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> extern struct dentry * d_exact_alias(struct dentry *, struct inode *); --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h -@@ -1513,7 +1513,7 @@ struct nfs_unlinkdata { +@@ -1529,7 +1529,7 @@ struct nfs_unlinkdata { struct nfs_removeargs args; struct nfs_removeres res; struct dentry *dentry; diff --git a/patches/fs-namespace-preemption-fix.patch b/patches/fs-namespace-preemption-fix.patch index b9434a1f0fd0..405111933672 100644 --- a/patches/fs-namespace-preemption-fix.patch +++ b/patches/fs-namespace-preemption-fix.patch @@ -15,7 +15,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/fs/namespace.c +++ b/fs/namespace.c -@@ -356,8 +356,11 @@ int __mnt_want_write(struct vfsmount *m) +@@ -353,8 +353,11 @@ int __mnt_want_write(struct vfsmount *m) * incremented count after it has set MNT_WRITE_HOLD. */ smp_mb(); diff --git a/patches/fs-nfs-turn-rmdir_sem-into-a-semaphore.patch b/patches/fs-nfs-turn-rmdir_sem-into-a-semaphore.patch index 2bd5cff05e62..b7acd7238af8 100644 --- a/patches/fs-nfs-turn-rmdir_sem-into-a-semaphore.patch +++ b/patches/fs-nfs-turn-rmdir_sem-into-a-semaphore.patch @@ -21,7 +21,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c -@@ -1813,7 +1813,11 @@ int nfs_rmdir(struct inode *dir, struct +@@ -1763,7 +1763,11 @@ int nfs_rmdir(struct inode *dir, struct trace_nfs_rmdir_enter(dir, dentry); if (d_really_is_positive(dentry)) { @@ -33,7 +33,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> error = NFS_PROTO(dir)->rmdir(dir, &dentry->d_name); /* Ensure the VFS deletes this inode */ switch (error) { -@@ -1823,7 +1827,11 @@ int nfs_rmdir(struct inode *dir, struct +@@ -1773,7 +1777,11 @@ int nfs_rmdir(struct inode *dir, struct case -ENOENT: nfs_dentry_handle_enoent(dentry); } @@ -47,7 +47,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> trace_nfs_rmdir_exit(dir, dentry, error); --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c -@@ -1984,7 +1984,11 @@ static void init_once(void *foo) +@@ -2015,7 +2015,11 @@ static void init_once(void *foo) nfsi->nrequests = 0; nfsi->commit_info.ncommit = 0; atomic_set(&nfsi->commit_info.rpcs_out, 0); @@ -124,7 +124,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * point dentry is definitely not a root, so we won't need --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h -@@ -161,7 +161,11 @@ struct nfs_inode { +@@ -162,7 +162,11 @@ struct nfs_inode { /* Readers: in-flight sillydelete RPC calls */ /* Writers: rmdir */ diff --git a/patches/fs-replace-bh_uptodate_lock-for-rt.patch b/patches/fs-replace-bh_uptodate_lock-for-rt.patch index f3e951daf43a..0b65a1fbbd8e 100644 --- a/patches/fs-replace-bh_uptodate_lock-for-rt.patch +++ b/patches/fs-replace-bh_uptodate_lock-for-rt.patch @@ -14,7 +14,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/fs/buffer.c +++ b/fs/buffer.c -@@ -303,8 +303,7 @@ static void end_buffer_async_read(struct +@@ -302,8 +302,7 @@ static void end_buffer_async_read(struct * decide that the page is now completely done. */ first = page_buffers(page); @@ -24,7 +24,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> clear_buffer_async_read(bh); unlock_buffer(bh); tmp = bh; -@@ -317,8 +316,7 @@ static void end_buffer_async_read(struct +@@ -316,8 +315,7 @@ static void end_buffer_async_read(struct } tmp = tmp->b_this_page; } while (tmp != bh); @@ -34,7 +34,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * If none of the buffers had errors and they are all -@@ -330,9 +328,7 @@ static void end_buffer_async_read(struct +@@ -329,9 +327,7 @@ static void end_buffer_async_read(struct return; still_busy: @@ -45,7 +45,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } /* -@@ -360,8 +356,7 @@ void end_buffer_async_write(struct buffe +@@ -358,8 +354,7 @@ void end_buffer_async_write(struct buffe } first = page_buffers(page); @@ -55,7 +55,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> clear_buffer_async_write(bh); unlock_buffer(bh); -@@ -373,15 +368,12 @@ void end_buffer_async_write(struct buffe +@@ -371,15 +366,12 @@ void end_buffer_async_write(struct buffe } tmp = tmp->b_this_page; } @@ -73,7 +73,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } EXPORT_SYMBOL(end_buffer_async_write); -@@ -3426,6 +3418,7 @@ struct buffer_head *alloc_buffer_head(gf +@@ -3410,6 +3402,7 @@ struct buffer_head *alloc_buffer_head(gf struct buffer_head *ret = kmem_cache_zalloc(bh_cachep, gfp_flags); if (ret) { INIT_LIST_HEAD(&ret->b_assoc_buffers); diff --git a/patches/ftrace-Fix-trace-header-alignment.patch b/patches/ftrace-Fix-trace-header-alignment.patch index ba263bd43182..0b4219fd36f5 100644 --- a/patches/ftrace-Fix-trace-header-alignment.patch +++ b/patches/ftrace-Fix-trace-header-alignment.patch @@ -9,12 +9,12 @@ Signed-off-by: Mike Galbraith <umgwanakikbuti@gmail.com> [bigeasy: fixup function tracer header] Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - kernel/trace/trace.c | 32 ++++++++++++++++---------------- - 1 file changed, 16 insertions(+), 16 deletions(-) + kernel/trace/trace.c | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c -@@ -3121,17 +3121,17 @@ get_total_entries(struct trace_buffer *b +@@ -3340,17 +3340,17 @@ get_total_entries(struct trace_buffer *b static void print_lat_help_header(struct seq_file *m) { @@ -43,20 +43,3 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } static void print_event_info(struct trace_buffer *buf, struct seq_file *m) -@@ -3160,11 +3160,11 @@ static void print_func_help_header_irq(s - "# |/ _-----=> need-resched_lazy\n" - "# || / _---=> hardirq/softirq\n" - "# ||| / _--=> preempt-depth\n" -- "# |||| /_--=> preempt-lazy-depth\n" -- "# ||||| _-=> migrate-disable \n" -- "# ||||| / delay\n" -- "# TASK-PID CPU# |||||| TIMESTAMP FUNCTION\n" -- "# | | | |||||| | |\n"); -+ "# |||| / _-=> preempt-lazy-depth\n" -+ "# ||||| / _-=> migrate-disable \n" -+ "# |||||| / delay\n" -+ "# TASK-PID CPU# ||||||| TIMESTAMP FUNCTION\n" -+ "# | | | ||||||| | |\n"); - } - - void diff --git a/patches/ftrace-migrate-disable-tracing.patch b/patches/ftrace-migrate-disable-tracing.patch index dd2ebfb8e4bc..440b4d1186d7 100644 --- a/patches/ftrace-migrate-disable-tracing.patch +++ b/patches/ftrace-migrate-disable-tracing.patch @@ -23,7 +23,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #define TRACE_EVENT_TYPE_MAX \ --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c -@@ -1954,6 +1954,8 @@ tracing_generic_entry_update(struct trac +@@ -2138,6 +2138,8 @@ tracing_generic_entry_update(struct trac ((pc & SOFTIRQ_OFFSET) ? TRACE_FLAG_SOFTIRQ : 0) | (tif_need_resched() ? TRACE_FLAG_NEED_RESCHED : 0) | (test_preempt_need_resched() ? TRACE_FLAG_PREEMPT_RESCHED : 0); @@ -32,7 +32,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } EXPORT_SYMBOL_GPL(tracing_generic_entry_update); -@@ -3122,9 +3124,10 @@ static void print_lat_help_header(struct +@@ -3341,9 +3343,10 @@ static void print_lat_help_header(struct "# | / _----=> need-resched \n" "# || / _---=> hardirq/softirq \n" "# ||| / _--=> preempt-depth \n" @@ -59,7 +59,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c -@@ -484,6 +484,11 @@ int trace_print_lat_fmt(struct trace_seq +@@ -493,6 +493,11 @@ int trace_print_lat_fmt(struct trace_seq else trace_seq_putc(s, '.'); diff --git a/patches/futex-Ensure-lock-unlock-symetry-versus-pi_lock-and-.patch b/patches/futex-Ensure-lock-unlock-symetry-versus-pi_lock-and-.patch index 70e3601e1aa8..fc8ebb987515 100644 --- a/patches/futex-Ensure-lock-unlock-symetry-versus-pi_lock-and-.patch +++ b/patches/futex-Ensure-lock-unlock-symetry-versus-pi_lock-and-.patch @@ -30,10 +30,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/futex.c +++ b/kernel/futex.c -@@ -911,7 +911,9 @@ void exit_pi_state_list(struct task_stru - * task still owns the PI-state: +@@ -917,7 +917,9 @@ void exit_pi_state_list(struct task_stru */ if (head->next != next) { + raw_spin_unlock(&pi_state->pi_mutex.wait_lock); + raw_spin_unlock_irq(&curr->pi_lock); spin_unlock(&hb->lock); + raw_spin_lock_irq(&curr->pi_lock); diff --git a/patches/futex-requeue-pi-fix.patch b/patches/futex-requeue-pi-fix.patch index a6f5311b201b..b1a5cb410d76 100644 --- a/patches/futex-requeue-pi-fix.patch +++ b/patches/futex-requeue-pi-fix.patch @@ -65,7 +65,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } /* -@@ -1722,6 +1723,35 @@ int __rt_mutex_start_proxy_lock(struct r +@@ -1743,6 +1744,35 @@ int __rt_mutex_start_proxy_lock(struct r if (try_to_take_rt_mutex(lock, task, NULL)) return 1; diff --git a/patches/futex-rt_mutex-Fix-rt_mutex_cleanup_proxy_lock.patch b/patches/futex-rt_mutex-Fix-rt_mutex_cleanup_proxy_lock.patch deleted file mode 100644 index 476d45149fb2..000000000000 --- a/patches/futex-rt_mutex-Fix-rt_mutex_cleanup_proxy_lock.patch +++ /dev/null @@ -1,125 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Mon, 22 May 2017 13:04:50 -0700 -Subject: [PATCH] futex,rt_mutex: Fix rt_mutex_cleanup_proxy_lock() - -Markus reported that the glibc/nptl/tst-robustpi8 test was failing after -commit: - - cfafcd117da0 ("futex: Rework futex_lock_pi() to use rt_mutex_*_proxy_lock()") - -The following trace shows the problem: - - ld-linux-x86-64-2161 [019] .... 410.760971: SyS_futex: 00007ffbeb76b028: 80000875 op=FUTEX_LOCK_PI - ld-linux-x86-64-2161 [019] ...1 410.760972: lock_pi_update_atomic: 00007ffbeb76b028: curval=80000875 uval=80000875 newval=80000875 ret=0 - ld-linux-x86-64-2165 [011] .... 410.760978: SyS_futex: 00007ffbeb76b028: 80000875 op=FUTEX_UNLOCK_PI - ld-linux-x86-64-2165 [011] d..1 410.760979: do_futex: 00007ffbeb76b028: curval=80000875 uval=80000875 newval=80000871 ret=0 - ld-linux-x86-64-2165 [011] .... 410.760980: SyS_futex: 00007ffbeb76b028: 80000871 ret=0000 - ld-linux-x86-64-2161 [019] .... 410.760980: SyS_futex: 00007ffbeb76b028: 80000871 ret=ETIMEDOUT - -Task 2165 does an UNLOCK_PI, assigning the lock to the waiter task 2161 -which then returns with -ETIMEDOUT. That wrecks the lock state, because now -the owner isn't aware it acquired the lock and removes the pending robust -list entry. - -If 2161 is killed, the robust list will not clear out this futex and the -subsequent acquire on this futex will then (correctly) result in -ESRCH -which is unexpected by glibc, triggers an internal assertion and dies. - -Task 2161 Task 2165 - -rt_mutex_wait_proxy_lock() - timeout(); - /* T2161 is still queued in the waiter list */ - return -ETIMEDOUT; - - futex_unlock_pi() - spin_lock(hb->lock); - rtmutex_unlock() - remove_rtmutex_waiter(T2161); - mark_lock_available(); - /* Make the next waiter owner of the user space side */ - futex_uval = 2161; - spin_unlock(hb->lock); -spin_lock(hb->lock); -rt_mutex_cleanup_proxy_lock() - if (rtmutex_owner() !== current) - ... - return FAIL; -.... -return -ETIMEOUT; - -This means that rt_mutex_cleanup_proxy_lock() needs to call -try_to_take_rt_mutex() so it can take over the rtmutex correctly which was -assigned by the waker. If the rtmutex is owned by some other task then this -call is harmless and just confirmes that the waiter is not able to acquire -it. - -While there, fix what looks like a merge error which resulted in -rt_mutex_cleanup_proxy_lock() having two calls to -fixup_rt_mutex_waiters() and rt_mutex_wait_proxy_lock() not having any. -Both should have one, since both potentially touch the waiter list. - -Fixes: 38d589f2fd08 ("futex,rt_mutex: Restructure rt_mutex_finish_proxy_lock()") -Reported-by: Markus Trippelsdorf <markus@trippelsdorf.de> -Bug-Spotted-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: Florian Weimer <fweimer@redhat.com> -Cc: Darren Hart <dvhart@infradead.org> -Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Cc: Markus Trippelsdorf <markus@trippelsdorf.de> -Link: http://lkml.kernel.org/r/20170519154850.mlomgdsd26drq5j6@hirez.programming.kicks-ass.net -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/locking/rtmutex.c | 24 ++++++++++++++++++------ - 1 file changed, 18 insertions(+), 6 deletions(-) - ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -1785,12 +1785,14 @@ int rt_mutex_wait_proxy_lock(struct rt_m - int ret; - - raw_spin_lock_irq(&lock->wait_lock); -- -- set_current_state(TASK_INTERRUPTIBLE); -- - /* sleep on the mutex */ -+ set_current_state(TASK_INTERRUPTIBLE); - ret = __rt_mutex_slowlock(lock, TASK_INTERRUPTIBLE, to, waiter); -- -+ /* -+ * try_to_take_rt_mutex() sets the waiter bit unconditionally. We might -+ * have to fix that up. -+ */ -+ fixup_rt_mutex_waiters(lock); - raw_spin_unlock_irq(&lock->wait_lock); - - return ret; -@@ -1822,15 +1824,25 @@ bool rt_mutex_cleanup_proxy_lock(struct - - raw_spin_lock_irq(&lock->wait_lock); - /* -+ * Do an unconditional try-lock, this deals with the lock stealing -+ * state where __rt_mutex_futex_unlock() -> mark_wakeup_next_waiter() -+ * sets a NULL owner. -+ * -+ * We're not interested in the return value, because the subsequent -+ * test on rt_mutex_owner() will infer that. If the trylock succeeded, -+ * we will own the lock and it will have removed the waiter. If we -+ * failed the trylock, we're still not owner and we need to remove -+ * ourselves. -+ */ -+ try_to_take_rt_mutex(lock, current, waiter); -+ /* - * Unless we're the owner; we're still enqueued on the wait_list. - * So check if we became owner, if not, take us off the wait_list. - */ - if (rt_mutex_owner(lock) != current) { - remove_waiter(lock, waiter); -- fixup_rt_mutex_waiters(lock); - cleanup = true; - } -- - /* - * try_to_take_rt_mutex() sets the waiter bit unconditionally. We might - * have to fix that up. diff --git a/patches/futex-rtmutex-Cure-RT-double-blocking-issue.patch b/patches/futex-rtmutex-Cure-RT-double-blocking-issue.patch deleted file mode 100644 index 831ec3d398f5..000000000000 --- a/patches/futex-rtmutex-Cure-RT-double-blocking-issue.patch +++ /dev/null @@ -1,60 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Tue, 9 May 2017 17:11:10 +0200 -Subject: [PATCH] futex/rtmutex: Cure RT double blocking issue - -RT has a problem when the wait on a futex/rtmutex got interrupted by a -timeout or a signal. task->pi_blocked_on is still set when returning from -rt_mutex_wait_proxy_lock(). The task must acquire the hash bucket lock -after this. - -If the hash bucket lock is contended then the -BUG_ON(rt_mutex_real_waiter(task->pi_blocked_on)) in -task_blocks_on_rt_mutex() will trigger. - -This can be avoided by clearing task->pi_blocked_on in the return path of -rt_mutex_wait_proxy_lock() which removes the task from the boosting chain -of the rtmutex. That's correct because the task is not longer blocked on -it. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Reported-by: Engleder Gerhard <eg@keba.com> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/locking/rtmutex.c | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) - ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -2406,6 +2406,7 @@ int rt_mutex_wait_proxy_lock(struct rt_m - struct hrtimer_sleeper *to, - struct rt_mutex_waiter *waiter) - { -+ struct task_struct *tsk = current; - int ret; - - raw_spin_lock_irq(&lock->wait_lock); -@@ -2417,6 +2418,24 @@ int rt_mutex_wait_proxy_lock(struct rt_m - * have to fix that up. - */ - fixup_rt_mutex_waiters(lock); -+ /* -+ * RT has a problem here when the wait got interrupted by a timeout -+ * or a signal. task->pi_blocked_on is still set. The task must -+ * acquire the hash bucket lock when returning from this function. -+ * -+ * If the hash bucket lock is contended then the -+ * BUG_ON(rt_mutex_real_waiter(task->pi_blocked_on)) in -+ * task_blocks_on_rt_mutex() will trigger. This can be avoided by -+ * clearing task->pi_blocked_on which removes the task from the -+ * boosting chain of the rtmutex. That's correct because the task -+ * is not longer blocked on it. -+ */ -+ if (ret) { -+ raw_spin_lock(&tsk->pi_lock); -+ tsk->pi_blocked_on = NULL; -+ raw_spin_unlock(&tsk->pi_lock); -+ } -+ - raw_spin_unlock_irq(&lock->wait_lock); - - return ret; diff --git a/patches/futex-workaround-migrate_disable-enable-in-different.patch b/patches/futex-workaround-migrate_disable-enable-in-different.patch index ea63415d1897..91e40a4f0a70 100644 --- a/patches/futex-workaround-migrate_disable-enable-in-different.patch +++ b/patches/futex-workaround-migrate_disable-enable-in-different.patch @@ -10,12 +10,12 @@ enabled and unlock it with interrupts disabled. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - kernel/futex.c | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) + kernel/futex.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) --- a/kernel/futex.c +++ b/kernel/futex.c -@@ -2671,9 +2671,18 @@ static int futex_lock_pi(u32 __user *uad +@@ -2682,9 +2682,18 @@ static int futex_lock_pi(u32 __user *uad * lock handoff sequence. */ raw_spin_lock_irq(&q.pi_state->pi_mutex.wait_lock); @@ -34,7 +34,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (ret) { if (ret == 1) -@@ -2817,10 +2826,21 @@ static int futex_unlock_pi(u32 __user *u +@@ -2828,11 +2837,21 @@ static int futex_unlock_pi(u32 __user *u * observed. */ raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock); @@ -48,7 +48,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + migrate_disable(); spin_unlock(&hb->lock); -+ /* Drops pi_state->pi_mutex.wait_lock */ + /* drops pi_state->pi_mutex.wait_lock */ ret = wake_futex_pi(uaddr, uval, pi_state); + migrate_enable(); diff --git a/patches/genirq-do-not-invoke-the-affinity-callback-via-a-wor.patch b/patches/genirq-do-not-invoke-the-affinity-callback-via-a-wor.patch index 320dd408f8f5..b8071b716e18 100644 --- a/patches/genirq-do-not-invoke-the-affinity-callback-via-a-wor.patch +++ b/patches/genirq-do-not-invoke-the-affinity-callback-via-a-wor.patch @@ -23,7 +23,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #include <linux/atomic.h> #include <asm/ptrace.h> -@@ -218,6 +219,7 @@ extern void resume_device_irqs(void); +@@ -227,6 +228,7 @@ extern void resume_device_irqs(void); * struct irq_affinity_notify - context for notification of IRQ affinity changes * @irq: Interrupt to which notification applies * @kref: Reference count, for internal use @@ -31,7 +31,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * @work: Work item, for internal use * @notify: Function to be called on change. This will be * called in process context. -@@ -229,7 +231,11 @@ extern void resume_device_irqs(void); +@@ -238,7 +240,11 @@ extern void resume_device_irqs(void); struct irq_affinity_notify { unsigned int irq; struct kref kref; @@ -45,7 +45,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> }; --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c -@@ -237,7 +237,12 @@ int irq_set_affinity_locked(struct irq_d +@@ -209,7 +209,12 @@ int irq_set_affinity_locked(struct irq_d if (desc->affinity_notify) { kref_get(&desc->affinity_notify->kref); @@ -58,7 +58,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } irqd_set(data, IRQD_AFFINITY_SET); -@@ -275,10 +280,8 @@ int irq_set_affinity_hint(unsigned int i +@@ -247,10 +252,8 @@ int irq_set_affinity_hint(unsigned int i } EXPORT_SYMBOL_GPL(irq_set_affinity_hint); @@ -70,7 +70,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> struct irq_desc *desc = irq_to_desc(notify->irq); cpumask_var_t cpumask; unsigned long flags; -@@ -300,6 +303,35 @@ static void irq_affinity_notify(struct w +@@ -272,6 +275,35 @@ static void irq_affinity_notify(struct w kref_put(¬ify->kref, notify->release); } @@ -106,7 +106,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /** * irq_set_affinity_notifier - control notification of IRQ affinity changes * @irq: Interrupt for which to enable/disable notification -@@ -328,7 +360,12 @@ irq_set_affinity_notifier(unsigned int i +@@ -300,7 +332,12 @@ irq_set_affinity_notifier(unsigned int i if (notify) { notify->irq = irq; kref_init(¬ify->kref); diff --git a/patches/genirq-force-threading.patch b/patches/genirq-force-threading.patch index 0ee64c401f32..3c2f363dbab8 100644 --- a/patches/genirq-force-threading.patch +++ b/patches/genirq-force-threading.patch @@ -13,7 +13,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h -@@ -418,9 +418,13 @@ extern int irq_set_irqchip_state(unsigne +@@ -427,9 +427,13 @@ extern int irq_set_irqchip_state(unsigne bool state); #ifdef CONFIG_IRQ_FORCED_THREADING diff --git a/patches/genirq-update-irq_set_irqchip_state-documentation.patch b/patches/genirq-update-irq_set_irqchip_state-documentation.patch index 75131c2118bb..1b5688b8d6d6 100644 --- a/patches/genirq-update-irq_set_irqchip_state-documentation.patch +++ b/patches/genirq-update-irq_set_irqchip_state-documentation.patch @@ -14,7 +14,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c -@@ -2115,7 +2115,7 @@ EXPORT_SYMBOL_GPL(irq_get_irqchip_state) +@@ -2160,7 +2160,7 @@ EXPORT_SYMBOL_GPL(irq_get_irqchip_state) * This call sets the internal irqchip state of an interrupt, * depending on the value of @which. * diff --git a/patches/greybus-audio-don-t-inclide-rwlock.h-directly.patch b/patches/greybus-audio-don-t-inclide-rwlock.h-directly.patch new file mode 100644 index 000000000000..2973b4080811 --- /dev/null +++ b/patches/greybus-audio-don-t-inclide-rwlock.h-directly.patch @@ -0,0 +1,30 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Thu, 5 Oct 2017 14:38:52 +0200 +Subject: [PATCH] greybus: audio: don't inclide rwlock.h directly. + +rwlock.h should not be included directly. Instead linux/splinlock.h +should be included. One thing it does is to break the RT build. + +Cc: Vaibhav Agarwal <vaibhav.sr@gmail.com> +Cc: Mark Greer <mgreer@animalcreek.com> +Cc: Johan Hovold <johan@kernel.org> +Cc: Alex Elder <elder@kernel.org> +Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Cc: greybus-dev@lists.linaro.org +Cc: devel@driverdev.osuosl.org +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/staging/greybus/audio_manager.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/staging/greybus/audio_manager.c ++++ b/drivers/staging/greybus/audio_manager.c +@@ -10,7 +10,7 @@ + #include <linux/sysfs.h> + #include <linux/module.h> + #include <linux/init.h> +-#include <linux/rwlock.h> ++#include <linux/spinlock.h> + #include <linux/idr.h> + + #include "audio_manager.h" diff --git a/patches/hotplug-duct-tape-RT-rwlock-usage-for-non-RT.patch b/patches/hotplug-duct-tape-RT-rwlock-usage-for-non-RT.patch index eb02caf01c57..6a251600ddf0 100644 --- a/patches/hotplug-duct-tape-RT-rwlock-usage-for-non-RT.patch +++ b/patches/hotplug-duct-tape-RT-rwlock-usage-for-non-RT.patch @@ -54,7 +54,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } DEFINE_STATIC_PERCPU_RWSEM(cpu_hotplug_lock); -@@ -679,7 +683,9 @@ static int take_cpu_down(void *_param) +@@ -656,7 +660,9 @@ static int take_cpu_down(void *_param) static int takedown_cpu(unsigned int cpu) { @@ -64,7 +64,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); int err; -@@ -693,14 +699,18 @@ static int takedown_cpu(unsigned int cpu +@@ -670,14 +676,18 @@ static int takedown_cpu(unsigned int cpu */ irq_lock_sparse(); @@ -83,7 +83,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* CPU refused to die */ irq_unlock_sparse(); /* Unpark the hotplug thread so we can rollback there */ -@@ -719,7 +729,9 @@ static int takedown_cpu(unsigned int cpu +@@ -696,7 +706,9 @@ static int takedown_cpu(unsigned int cpu wait_for_completion(&st->done); BUG_ON(st->state != CPUHP_AP_IDLE_DEAD); diff --git a/patches/hotplug-light-get-online-cpus.patch b/patches/hotplug-light-get-online-cpus.patch index 20c4c5b3c638..4bea0e315b14 100644 --- a/patches/hotplug-light-get-online-cpus.patch +++ b/patches/hotplug-light-get-online-cpus.patch @@ -64,7 +64,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> void cpus_read_lock(void) --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -7509,6 +7509,7 @@ void migrate_disable(void) +@@ -6868,6 +6868,7 @@ void migrate_disable(void) } preempt_disable(); @@ -72,7 +72,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> migrate_disable_update_cpus_allowed(p); p->migrate_disable = 1; -@@ -7571,12 +7572,15 @@ void migrate_enable(void) +@@ -6930,12 +6931,15 @@ void migrate_enable(void) arg.task = p; arg.dest_cpu = dest_cpu; diff --git a/patches/hrtimer-Move-schedule_work-call-to-helper-thread.patch b/patches/hrtimer-Move-schedule_work-call-to-helper-thread.patch index bff567d7dbf8..b174e8f5e74a 100644 --- a/patches/hrtimer-Move-schedule_work-call-to-helper-thread.patch +++ b/patches/hrtimer-Move-schedule_work-call-to-helper-thread.patch @@ -51,7 +51,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -691,6 +691,29 @@ static void hrtimer_switch_to_hres(void) +@@ -692,6 +692,29 @@ static void hrtimer_switch_to_hres(void) retrigger_next_event(NULL); } @@ -81,7 +81,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static void clock_was_set_work(struct work_struct *work) { clock_was_set(); -@@ -706,6 +729,7 @@ void clock_was_set_delayed(void) +@@ -707,6 +730,7 @@ void clock_was_set_delayed(void) { schedule_work(&hrtimer_work); } diff --git a/patches/hrtimer-Remove-hrtimer_peek_ahead_timers-leftovers.patch b/patches/hrtimer-Remove-hrtimer_peek_ahead_timers-leftovers.patch deleted file mode 100644 index 453563cdcb3f..000000000000 --- a/patches/hrtimer-Remove-hrtimer_peek_ahead_timers-leftovers.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Stephen Boyd <sboyd@codeaurora.org> -Date: Thu, 16 Mar 2017 18:08:13 -0700 -Subject: [PATCH] hrtimer: Remove hrtimer_peek_ahead_timers() leftovers - -This function was removed in commit c6eb3f70d448 (hrtimer: Get rid of -hrtimer softirq, 2015-04-14) but the prototype wasn't ever deleted. - -Delete it now. - -Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> -Link: http://lkml.kernel.org/r/20170317010814.2591-1-sboyd@codeaurora.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - include/linux/hrtimer.h | 4 ---- - kernel/time/hrtimer.c | 5 +---- - 2 files changed, 1 insertion(+), 8 deletions(-) - ---- a/include/linux/hrtimer.h -+++ b/include/linux/hrtimer.h -@@ -274,8 +274,6 @@ static inline int hrtimer_is_hres_active - return timer->base->cpu_base->hres_active; - } - --extern void hrtimer_peek_ahead_timers(void); -- - /* - * The resolution of the clocks. The resolution value is returned in - * the clock_getres() system call to give application programmers an -@@ -298,8 +296,6 @@ extern unsigned int hrtimer_resolution; - - #define hrtimer_resolution (unsigned int)LOW_RES_NSEC - --static inline void hrtimer_peek_ahead_timers(void) { } -- - static inline int hrtimer_is_hres_active(struct hrtimer *timer) - { - return 0; ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -1368,10 +1368,7 @@ void hrtimer_interrupt(struct clock_even - ktime_to_ns(delta)); - } - --/* -- * local version of hrtimer_peek_ahead_timers() called with interrupts -- * disabled. -- */ -+/* called with interrupts disabled */ - static inline void __hrtimer_peek_ahead_timers(void) - { - struct tick_device *td; diff --git a/patches/hrtimer-by-timers-by-default-into-the-softirq-context.patch b/patches/hrtimer-by-timers-by-default-into-the-softirq-context.patch index 7891c2323360..9675e77b314b 100644 --- a/patches/hrtimer-by-timers-by-default-into-the-softirq-context.patch +++ b/patches/hrtimer-by-timers-by-default-into-the-softirq-context.patch @@ -13,21 +13,21 @@ Those are: Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - arch/x86/kvm/lapic.c | 2 +- - include/linux/hrtimer.h | 6 ++++++ - kernel/events/core.c | 4 ++-- - kernel/sched/core.c | 2 +- - kernel/sched/deadline.c | 2 +- - kernel/sched/rt.c | 4 ++-- - kernel/time/hrtimer.c | 22 +++++++++++++++++++++- - kernel/time/tick-broadcast-hrtimer.c | 2 +- - kernel/time/tick-sched.c | 2 +- - kernel/watchdog.c | 2 +- - 10 files changed, 37 insertions(+), 11 deletions(-) + arch/x86/kvm/lapic.c | 2 - + include/linux/hrtimer.h | 6 +++++ + kernel/events/core.c | 4 +-- + kernel/sched/core.c | 2 - + kernel/sched/deadline.c | 2 - + kernel/sched/rt.c | 4 +-- + kernel/time/hrtimer.c | 41 ++++++++++++++++++++++++++++++++++- + kernel/time/tick-broadcast-hrtimer.c | 2 - + kernel/time/tick-sched.c | 2 - + kernel/watchdog.c | 2 - + 10 files changed, 56 insertions(+), 11 deletions(-) --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c -@@ -2059,7 +2059,7 @@ int kvm_create_lapic(struct kvm_vcpu *vc +@@ -2085,7 +2085,7 @@ int kvm_create_lapic(struct kvm_vcpu *vc } apic->vcpu = vcpu; @@ -59,7 +59,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/events/core.c +++ b/kernel/events/core.c -@@ -1042,7 +1042,7 @@ static void __perf_mux_hrtimer_init(stru +@@ -1040,7 +1040,7 @@ static void __perf_mux_hrtimer_init(stru cpuctx->hrtimer_interval = ns_to_ktime(NSEC_PER_MSEC * interval); raw_spin_lock_init(&cpuctx->hrtimer_lock); @@ -68,7 +68,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> timer->function = perf_mux_hrtimer_handler; } -@@ -8485,7 +8485,7 @@ static void perf_swevent_init_hrtimer(st +@@ -8653,7 +8653,7 @@ static void perf_swevent_init_hrtimer(st if (!is_sampling_event(event)) return; @@ -79,7 +79,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -350,7 +350,7 @@ static void init_rq_hrtick(struct rq *rq +@@ -341,7 +341,7 @@ static void init_rq_hrtick(struct rq *rq rq->hrtick_csd.info = rq; #endif @@ -90,7 +90,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #else /* CONFIG_SCHED_HRTICK */ --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c -@@ -691,7 +691,7 @@ void init_dl_task_timer(struct sched_dl_ +@@ -1021,7 +1021,7 @@ void init_dl_task_timer(struct sched_dl_ { struct hrtimer *timer = &dl_se->dl_timer; @@ -114,7 +114,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -122,20 +122,32 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, +@@ -123,20 +123,32 @@ DEFINE_PER_CPU(struct hrtimer_cpu_base, } }; @@ -148,7 +148,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> }; /* -@@ -1200,7 +1212,11 @@ static inline int hrtimer_clockid_to_bas +@@ -1201,7 +1213,11 @@ static inline int hrtimer_clockid_to_bas return base; } WARN(1, "Invalid clockid %d. Using MONOTONIC\n", clock_id); @@ -160,13 +160,44 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id, -@@ -1593,6 +1609,10 @@ static void __hrtimer_init_sleeper(struc +@@ -1219,6 +1235,8 @@ static void __hrtimer_init(struct hrtime + clock_id = CLOCK_MONOTONIC; + else if (clock_id == CLOCK_REALTIME_SOFT) + clock_id = CLOCK_MONOTONIC_SOFT; ++ else if (clock_id == CLOCK_REALTIME_HARD) ++ clock_id = CLOCK_MONOTONIC_HARD; + } + + base = hrtimer_clockid_to_base(clock_id); +@@ -1589,11 +1607,32 @@ static enum hrtimer_restart hrtimer_wake + return HRTIMER_NORESTART; + } + ++#ifdef CONFIG_PREEMPT_RT_FULL ++static bool task_is_realtime(struct task_struct *tsk) ++{ ++ int policy = tsk->policy; ++ ++ if (policy == SCHED_FIFO || policy == SCHED_RR) ++ return true; ++ if (policy == SCHED_DEADLINE) ++ return true; ++ return false; ++} ++#endif ++ + static void __hrtimer_init_sleeper(struct hrtimer_sleeper *sl, + clockid_t clock_id, enum hrtimer_mode mode, struct task_struct *task) { +#ifdef CONFIG_PREEMPT_RT_FULL -+ if (!(clock_id & HRTIMER_BASE_SOFT_MASK)) -+ clock_id |= HRTIMER_BASE_HARD_MASK; ++ if (!(clock_id & (HRTIMER_BASE_HARD_MASK | HRTIMER_BASE_SOFT_MASK))) { ++ if (task_is_realtime(current) || system_state != SYSTEM_RUNNING) ++ clock_id |= HRTIMER_BASE_HARD_MASK; ++ else ++ clock_id |= HRTIMER_BASE_SOFT_MASK; ++ } +#endif __hrtimer_init(&sl->timer, clock_id, mode); sl->timer.function = hrtimer_wakeup; @@ -184,7 +215,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c -@@ -1196,7 +1196,7 @@ void tick_setup_sched_timer(void) +@@ -1226,7 +1226,7 @@ void tick_setup_sched_timer(void) /* * Emulate tick processing via per-CPU hrtimers: */ @@ -195,7 +226,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* Get the next period (per-CPU) */ --- a/kernel/watchdog.c +++ b/kernel/watchdog.c -@@ -382,7 +382,7 @@ static void watchdog_enable(unsigned int +@@ -450,7 +450,7 @@ static void watchdog_enable(unsigned int struct hrtimer *hrtimer = raw_cpu_ptr(&watchdog_hrtimer); /* kick off the timer for the hardlockup detector */ diff --git a/patches/hrtimer-consolidate-hrtimer_init-hrtimer_init_sleepe.patch b/patches/hrtimer-consolidate-hrtimer_init-hrtimer_init_sleepe.patch index 6d5fd53f1b32..b7d8a519040b 100644 --- a/patches/hrtimer-consolidate-hrtimer_init-hrtimer_init_sleepe.patch +++ b/patches/hrtimer-consolidate-hrtimer_init-hrtimer_init_sleepe.patch @@ -11,15 +11,15 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- block/blk-mq.c | 3 +-- include/linux/hrtimer.h | 19 ++++++++++++++++--- - include/linux/wait.h | 5 ++--- + include/linux/wait.h | 4 ++-- kernel/futex.c | 19 ++++++++----------- - kernel/time/hrtimer.c | 47 ++++++++++++++++++++++++++++++++++++++--------- + kernel/time/hrtimer.c | 46 ++++++++++++++++++++++++++++++++++++---------- net/core/pktgen.c | 4 ++-- - 6 files changed, 67 insertions(+), 30 deletions(-) + 6 files changed, 65 insertions(+), 30 deletions(-) --- a/block/blk-mq.c +++ b/block/blk-mq.c -@@ -2848,10 +2848,9 @@ static bool blk_mq_poll_hybrid_sleep(str +@@ -2756,10 +2756,9 @@ static bool blk_mq_poll_hybrid_sleep(str kt = nsecs; mode = HRTIMER_MODE_REL; @@ -67,9 +67,9 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static inline void destroy_hrtimer_on_stack(struct hrtimer *timer) { } #endif -@@ -472,9 +488,6 @@ extern long hrtimer_nanosleep(struct tim +@@ -472,9 +488,6 @@ extern long hrtimer_nanosleep(const stru + const enum hrtimer_mode mode, const clockid_t clockid); - extern long hrtimer_nanosleep_restart(struct restart_block *restart_block); -extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, - struct task_struct *tsk); @@ -79,21 +79,20 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> extern int schedule_hrtimeout_range_clock(ktime_t *expires, --- a/include/linux/wait.h +++ b/include/linux/wait.h -@@ -508,9 +508,8 @@ do { \ - int __ret = 0; \ - struct hrtimer_sleeper __t; \ - \ -- hrtimer_init_on_stack(&__t.timer, CLOCK_MONOTONIC, \ -- HRTIMER_MODE_REL); \ -- hrtimer_init_sleeper(&__t, current); \ -+ hrtimer_init_sleeper_on_stack(&__t, CLOCK_MONOTONIC, \ -+ HRTIMER_MODE_REL, current); \ - if ((timeout) != KTIME_MAX) \ - hrtimer_start_range_ns(&__t.timer, timeout, \ - current->timer_slack_ns, \ +@@ -482,8 +482,8 @@ do { \ + int __ret = 0; \ + struct hrtimer_sleeper __t; \ + \ +- hrtimer_init_on_stack(&__t.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); \ +- hrtimer_init_sleeper(&__t, current); \ ++ hrtimer_init_sleeper_on_stack(&__t, CLOCK_MONOTONIC, HRTIMER_MODE_REL, \ ++ current); \ + if ((timeout) != KTIME_MAX) \ + hrtimer_start_range_ns(&__t.timer, timeout, \ + current->timer_slack_ns, \ --- a/kernel/futex.c +++ b/kernel/futex.c -@@ -2500,10 +2500,9 @@ static int futex_wait(u32 __user *uaddr, +@@ -2511,10 +2511,9 @@ static int futex_wait(u32 __user *uaddr, if (abs_time) { to = &timeout; @@ -107,7 +106,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> hrtimer_set_expires_range_ns(&to->timer, *abs_time, current->timer_slack_ns); } -@@ -2599,9 +2598,8 @@ static int futex_lock_pi(u32 __user *uad +@@ -2610,9 +2609,8 @@ static int futex_lock_pi(u32 __user *uad if (time) { to = &timeout; @@ -119,7 +118,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> hrtimer_set_expires(&to->timer, *time); } -@@ -3011,10 +3009,9 @@ static int futex_wait_requeue_pi(u32 __u +@@ -3022,10 +3020,9 @@ static int futex_wait_requeue_pi(u32 __u if (abs_time) { to = &timeout; @@ -135,7 +134,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -1560,17 +1560,46 @@ static enum hrtimer_restart hrtimer_wake +@@ -1561,13 +1561,44 @@ static enum hrtimer_restart hrtimer_wake return HRTIMER_NORESTART; } @@ -151,10 +150,11 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } + +/** -+ * hrtimer_init - initialize a timer to the given clock -+ * @timer: the timer to be initialized ++ * hrtimer_init_sleeper - initialize sleeper to the given clock ++ * @sl: sleeper to be initialized + * @clock_id: the clock to be used + * @mode: timer mode abs/rel ++ * @task: the task to wake up + */ +void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, clockid_t clock_id, + enum hrtimer_mode mode, struct task_struct *task) @@ -165,61 +165,65 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +} EXPORT_SYMBOL_GPL(hrtimer_init_sleeper); --static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode) +#ifdef CONFIG_DEBUG_OBJECTS_TIMERS +void hrtimer_init_sleeper_on_stack(struct hrtimer_sleeper *sl, + clockid_t clock_id, + enum hrtimer_mode mode, + struct task_struct *task) - { -- hrtimer_init_sleeper(t, current); ++{ + debug_object_init_on_stack(&sl->timer, &hrtimer_debug_descr); + __hrtimer_init_sleeper(sl, clock_id, mode, task); +} +EXPORT_SYMBOL_GPL(hrtimer_init_sleeper_on_stack); +#endif + + int nanosleep_copyout(struct restart_block *restart, struct timespec64 *ts) + { + switch(restart->nanosleep.type) { +@@ -1591,8 +1622,6 @@ static int __sched do_nanosleep(struct h + { + struct restart_block *restart; -+static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode) -+{ +- hrtimer_init_sleeper(t, current); +- do { set_current_state(TASK_INTERRUPTIBLE); hrtimer_start_expires(&t->timer, mode); -@@ -1610,8 +1639,8 @@ long __sched hrtimer_nanosleep_restart(s - struct timespec __user *rmtp; - int ret = 0; +@@ -1629,10 +1658,9 @@ static long __sched hrtimer_nanosleep_re + struct hrtimer_sleeper t; + int ret; - hrtimer_init_on_stack(&t.timer, restart->nanosleep.clockid, - HRTIMER_MODE_ABS); + hrtimer_init_sleeper_on_stack(&t, restart->nanosleep.clockid, + HRTIMER_MODE_ABS, current); hrtimer_set_expires_tv64(&t.timer, restart->nanosleep.expires); - - if (do_nanosleep(&t, HRTIMER_MODE_ABS)) -@@ -1643,8 +1672,9 @@ long hrtimer_nanosleep(struct timespec * +- + ret = do_nanosleep(&t, HRTIMER_MODE_ABS); + destroy_hrtimer_on_stack(&t.timer); + return ret; +@@ -1650,7 +1678,7 @@ long hrtimer_nanosleep(const struct time if (dl_task(current) || rt_task(current)) slack = 0; - hrtimer_init_on_stack(&t.timer, clockid, mode); + hrtimer_init_sleeper_on_stack(&t, clockid, mode, current); - hrtimer_set_expires_range_ns(&t.timer, timespec_to_ktime(*rqtp), slack); -+ - if (do_nanosleep(&t, mode)) - goto out; - -@@ -1822,10 +1852,9 @@ schedule_hrtimeout_range_clock(ktime_t * + hrtimer_set_expires_range_ns(&t.timer, timespec64_to_ktime(*rqtp), slack); + ret = do_nanosleep(&t, mode); + if (ret != -ERESTART_RESTARTBLOCK) +@@ -1842,11 +1870,9 @@ schedule_hrtimeout_range_clock(ktime_t * return -EINTR; } - hrtimer_init_on_stack(&t.timer, clock_id, mode); -- hrtimer_set_expires_range_ns(&t.timer, *expires, delta); + hrtimer_init_sleeper_on_stack(&t, clock_id, mode, current); + hrtimer_set_expires_range_ns(&t.timer, *expires, delta); - hrtimer_init_sleeper(&t, current); -+ hrtimer_set_expires_range_ns(&t.timer, *expires, delta); - +- hrtimer_start_expires(&t.timer, mode); + if (likely(t.task)) --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -2252,7 +2252,8 @@ static void spin(struct pktgen_dev *pkt_ diff --git a/patches/hrtimer-soft-bases-timekeeping.patch b/patches/hrtimer-soft-bases-timekeeping.patch index 1280fe4977a4..57efe6f96c2c 100644 --- a/patches/hrtimer-soft-bases-timekeeping.patch +++ b/patches/hrtimer-soft-bases-timekeeping.patch @@ -13,7 +13,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -550,8 +550,14 @@ static inline ktime_t hrtimer_update_bas +@@ -551,8 +551,14 @@ static inline ktime_t hrtimer_update_bas ktime_t *offs_boot = &base->clock_base[HRTIMER_BASE_BOOTTIME].offset; ktime_t *offs_tai = &base->clock_base[HRTIMER_BASE_TAI].offset; diff --git a/patches/hrtimers-prepare-full-preemption.patch b/patches/hrtimers-prepare-full-preemption.patch index f4716c78e81c..42712528a35c 100644 --- a/patches/hrtimers-prepare-full-preemption.patch +++ b/patches/hrtimers-prepare-full-preemption.patch @@ -60,7 +60,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -868,6 +868,33 @@ u64 hrtimer_forward(struct hrtimer *time +@@ -869,6 +869,33 @@ u64 hrtimer_forward(struct hrtimer *time } EXPORT_SYMBOL_GPL(hrtimer_forward); @@ -94,7 +94,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * enqueue_hrtimer - internal function to (re)start a timer * -@@ -1115,7 +1142,7 @@ int hrtimer_cancel(struct hrtimer *timer +@@ -1116,7 +1143,7 @@ int hrtimer_cancel(struct hrtimer *timer if (ret >= 0) return ret; @@ -103,7 +103,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } } EXPORT_SYMBOL_GPL(hrtimer_cancel); -@@ -1391,6 +1418,7 @@ static __latent_entropy void hrtimer_run +@@ -1392,6 +1419,7 @@ static __latent_entropy void hrtimer_run hrtimer_update_softirq_timer(cpu_base, true); raw_spin_unlock_irq(&cpu_base->lock); @@ -111,7 +111,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } #ifdef CONFIG_HIGH_RES_TIMERS -@@ -1733,6 +1761,9 @@ int hrtimers_prepare_cpu(unsigned int cp +@@ -1751,6 +1779,9 @@ int hrtimers_prepare_cpu(unsigned int cp cpu_base->hres_active = 0; cpu_base->expires_next = KTIME_MAX; cpu_base->softirq_expires_next = KTIME_MAX; @@ -123,7 +123,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/kernel/time/itimer.c +++ b/kernel/time/itimer.c -@@ -195,6 +195,7 @@ int do_setitimer(int which, struct itime +@@ -213,6 +213,7 @@ int do_setitimer(int which, struct itime /* We are sharing ->siglock with it_real_fn() */ if (hrtimer_try_to_cancel(timer) < 0) { spin_unlock_irq(&tsk->sighand->siglock); @@ -133,14 +133,14 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> expires = timeval_to_ktime(value->it_value); --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c -@@ -829,6 +829,20 @@ SYSCALL_DEFINE1(timer_getoverrun, timer_ +@@ -791,6 +791,20 @@ SYSCALL_DEFINE1(timer_getoverrun, timer_ return overrun; } +/* + * Protected by RCU! + */ -+static void timer_wait_for_callback(struct k_clock *kc, struct k_itimer *timr) ++static void timer_wait_for_callback(const struct k_clock *kc, struct k_itimer *timr) +{ +#ifdef CONFIG_PREEMPT_RT_FULL + if (kc->timer_set == common_timer_set) @@ -151,31 +151,31 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +#endif +} + - /* Set a POSIX.1b interval timer. */ - /* timr->it_lock is taken. */ - static int -@@ -906,6 +920,7 @@ SYSCALL_DEFINE4(timer_settime, timer_t, + static void common_hrtimer_arm(struct k_itimer *timr, ktime_t expires, + bool absolute, bool sigev_none) + { +@@ -885,6 +899,7 @@ static int do_timer_settime(timer_t time if (!timr) return -EINVAL; + rcu_read_lock(); - kc = clockid_to_kclock(timr->it_clock); + kc = timr->kclock; if (WARN_ON_ONCE(!kc || !kc->timer_set)) error = -EINVAL; -@@ -914,9 +929,12 @@ SYSCALL_DEFINE4(timer_settime, timer_t, +@@ -893,9 +908,12 @@ static int do_timer_settime(timer_t time unlock_timer(timr, flag); if (error == TIMER_RETRY) { + timer_wait_for_callback(kc, timr); - rtn = NULL; // We already got the old time... + old_spec64 = NULL; // We already got the old time... + rcu_read_unlock(); goto retry; } + rcu_read_unlock(); - if (old_setting && !error && - copy_to_user(old_setting, &old_spec, sizeof (old_spec))) -@@ -954,10 +972,15 @@ SYSCALL_DEFINE1(timer_delete, timer_t, t + return error; + } +@@ -977,10 +995,15 @@ SYSCALL_DEFINE1(timer_delete, timer_t, t if (!timer) return -EINVAL; @@ -191,7 +191,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> spin_lock(¤t->sighand->siglock); list_del(&timer->list); -@@ -983,8 +1006,18 @@ static void itimer_delete(struct k_itime +@@ -1006,8 +1029,18 @@ static void itimer_delete(struct k_itime retry_delete: spin_lock_irqsave(&timer->it_lock, flags); diff --git a/patches/i915-bogus-warning-from-i915-when-running-on-PREEMPT.patch b/patches/i915-bogus-warning-from-i915-when-running-on-PREEMPT.patch index 18e5ffba5980..e8442d060666 100644 --- a/patches/i915-bogus-warning-from-i915-when-running-on-PREEMPT.patch +++ b/patches/i915-bogus-warning-from-i915-when-running-on-PREEMPT.patch @@ -18,7 +18,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c -@@ -12115,7 +12115,7 @@ void intel_check_page_flip(struct drm_i9 +@@ -10687,7 +10687,7 @@ void intel_check_page_flip(struct drm_i9 struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe); struct intel_flip_work *work; diff --git a/patches/infiniband-mellanox-ib-use-nort-irq.patch b/patches/infiniband-mellanox-ib-use-nort-irq.patch index f7456ed0b8dc..d62a01a35484 100644 --- a/patches/infiniband-mellanox-ib-use-nort-irq.patch +++ b/patches/infiniband-mellanox-ib-use-nort-irq.patch @@ -20,7 +20,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c -@@ -902,7 +902,7 @@ void ipoib_mcast_restart_task(struct wor +@@ -895,7 +895,7 @@ void ipoib_mcast_restart_task(struct wor ipoib_dbg_mcast(priv, "restarting multicast task\n"); @@ -29,12 +29,12 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> netif_addr_lock(dev); spin_lock(&priv->lock); -@@ -984,7 +984,7 @@ void ipoib_mcast_restart_task(struct wor +@@ -977,7 +977,7 @@ void ipoib_mcast_restart_task(struct wor spin_unlock(&priv->lock); netif_addr_unlock(dev); - local_irq_restore(flags); + local_irq_restore_nort(flags); - /* - * make sure the in-flight joins have finished before we attempt + ipoib_mcast_remove_list(&remove_list); + diff --git a/patches/iommu-amd--Use-WARN_ON_NORT.patch b/patches/iommu-amd--Use-WARN_ON_NORT.patch index 177838406a15..74bba3545877 100644 --- a/patches/iommu-amd--Use-WARN_ON_NORT.patch +++ b/patches/iommu-amd--Use-WARN_ON_NORT.patch @@ -16,7 +16,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c -@@ -1929,10 +1929,10 @@ static int __attach_device(struct iommu_ +@@ -2170,10 +2170,10 @@ static int __attach_device(struct iommu_ int ret; /* @@ -30,7 +30,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* lock domain */ spin_lock(&domain->lock); -@@ -2100,10 +2100,10 @@ static void __detach_device(struct iommu +@@ -2341,10 +2341,10 @@ static void __detach_device(struct iommu struct protection_domain *domain; /* diff --git a/patches/iommu-amd-Use-raw_cpu_ptr-instead-of-get_cpu_ptr-for.patch b/patches/iommu-amd-Use-raw_cpu_ptr-instead-of-get_cpu_ptr-for.patch index 228c9adf2755..cee4e44c11dd 100644 --- a/patches/iommu-amd-Use-raw_cpu_ptr-instead-of-get_cpu_ptr-for.patch +++ b/patches/iommu-amd-Use-raw_cpu_ptr-instead-of-get_cpu_ptr-for.patch @@ -23,21 +23,21 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c -@@ -2289,7 +2289,7 @@ static void queue_add(struct dma_ops_dom +@@ -1909,7 +1909,7 @@ static void queue_add(struct dma_ops_dom pages = __roundup_pow_of_two(pages); address >>= PAGE_SHIFT; -- queue = get_cpu_ptr(&flush_queue); -+ queue = raw_cpu_ptr(&flush_queue); +- queue = get_cpu_ptr(dom->flush_queue); ++ queue = raw_cpu_ptr(dom->flush_queue); spin_lock_irqsave(&queue->lock, flags); - if (queue->next == FLUSH_QUEUE_SIZE) -@@ -2306,8 +2306,6 @@ static void queue_add(struct dma_ops_dom + /* +@@ -1938,8 +1938,6 @@ static void queue_add(struct dma_ops_dom - if (atomic_cmpxchg(&queue_timer_on, 0, 1) == 0) - mod_timer(&queue_timer, jiffies + msecs_to_jiffies(10)); + if (atomic_cmpxchg(&dom->flush_timer_on, 0, 1) == 0) + mod_timer(&dom->flush_timer, jiffies + msecs_to_jiffies(10)); - -- put_cpu_ptr(&flush_queue); +- put_cpu_ptr(dom->flush_queue); } - + static void queue_flush_timeout(unsigned long data) diff --git a/patches/iommu-iova-don-t-disable-preempt-around-this_cpu_ptr.patch b/patches/iommu-iova-don-t-disable-preempt-around-this_cpu_ptr.patch deleted file mode 100644 index 47f9642a0ade..000000000000 --- a/patches/iommu-iova-don-t-disable-preempt-around-this_cpu_ptr.patch +++ /dev/null @@ -1,81 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Thu, 15 Sep 2016 16:58:19 +0200 -Subject: [PATCH] iommu/iova: don't disable preempt around this_cpu_ptr() - -Commit 583248e6620a ("iommu/iova: Disable preemption around use of -this_cpu_ptr()") disables preemption while accessing a per-CPU variable. -This does keep lockdep quiet. However I don't see the point why it is -bad if we get migrated after its access to another CPU. -__iova_rcache_insert() and __iova_rcache_get() immediately locks the -variable after obtaining it - before accessing its members. -_If_ we get migrated away after retrieving the address of cpu_rcache -before taking the lock then the *other* task on the same CPU will -retrieve the same address of cpu_rcache and will spin on the lock. - -alloc_iova_fast() disables preemption while invoking -free_cpu_cached_iovas() on each CPU. The function itself uses -per_cpu_ptr() which does not trigger a warning (like this_cpu_ptr() -does) because it assumes the caller knows what he does because he might -access the data structure from a different CPU (which means he needs -protection against concurrent access). - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - drivers/iommu/iova.c | 9 +++------ - 1 file changed, 3 insertions(+), 6 deletions(-) - ---- a/drivers/iommu/iova.c -+++ b/drivers/iommu/iova.c -@@ -22,6 +22,7 @@ - #include <linux/slab.h> - #include <linux/smp.h> - #include <linux/bitops.h> -+#include <linux/cpu.h> - - static bool iova_rcache_insert(struct iova_domain *iovad, - unsigned long pfn, -@@ -419,10 +420,8 @@ alloc_iova_fast(struct iova_domain *iova - - /* Try replenishing IOVAs by flushing rcache. */ - flushed_rcache = true; -- preempt_disable(); - for_each_online_cpu(cpu) - free_cpu_cached_iovas(cpu, iovad); -- preempt_enable(); - goto retry; - } - -@@ -750,7 +749,7 @@ static bool __iova_rcache_insert(struct - bool can_insert = false; - unsigned long flags; - -- cpu_rcache = get_cpu_ptr(rcache->cpu_rcaches); -+ cpu_rcache = raw_cpu_ptr(rcache->cpu_rcaches); - spin_lock_irqsave(&cpu_rcache->lock, flags); - - if (!iova_magazine_full(cpu_rcache->loaded)) { -@@ -780,7 +779,6 @@ static bool __iova_rcache_insert(struct - iova_magazine_push(cpu_rcache->loaded, iova_pfn); - - spin_unlock_irqrestore(&cpu_rcache->lock, flags); -- put_cpu_ptr(rcache->cpu_rcaches); - - if (mag_to_free) { - iova_magazine_free_pfns(mag_to_free, iovad); -@@ -814,7 +812,7 @@ static unsigned long __iova_rcache_get(s - bool has_pfn = false; - unsigned long flags; - -- cpu_rcache = get_cpu_ptr(rcache->cpu_rcaches); -+ cpu_rcache = raw_cpu_ptr(rcache->cpu_rcaches); - spin_lock_irqsave(&cpu_rcache->lock, flags); - - if (!iova_magazine_empty(cpu_rcache->loaded)) { -@@ -836,7 +834,6 @@ static unsigned long __iova_rcache_get(s - iova_pfn = iova_magazine_pop(cpu_rcache->loaded, limit_pfn); - - spin_unlock_irqrestore(&cpu_rcache->lock, flags); -- put_cpu_ptr(rcache->cpu_rcaches); - - return iova_pfn; - } diff --git a/patches/iommu-vt-d-don-t-disable-preemption-while-accessing-.patch b/patches/iommu-vt-d-don-t-disable-preemption-while-accessing-.patch deleted file mode 100644 index 8276ad7a54f0..000000000000 --- a/patches/iommu-vt-d-don-t-disable-preemption-while-accessing-.patch +++ /dev/null @@ -1,58 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Thu, 15 Sep 2016 17:16:44 +0200 -Subject: [PATCH] iommu/vt-d: don't disable preemption while accessing - deferred_flush() - -get_cpu() disables preemption and returns the current CPU number. The -CPU number is later only used once while retrieving the address of the -local's CPU deferred_flush pointer. -We can instead use raw_cpu_ptr() while we remain preemptible. The worst -thing that can happen is that flush_unmaps_timeout() is invoked multiple -times: once by taskA after seeing HIGH_WATER_MARK and then preempted to -another CPU and then by taskB which saw HIGH_WATER_MARK on the same CPU -as taskA. It is also likely that ->size got from HIGH_WATER_MARK to 0 -right after its read because another CPU invoked flush_unmaps_timeout() -for this CPU. -The access to flush_data is protected by a spinlock so even if we get -migrated to another CPU or preempted - the data structure is protected. - -While at it, I marked deferred_flush static since I can't find a -reference to it outside of this file. - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - drivers/iommu/intel-iommu.c | 8 ++------ - 1 file changed, 2 insertions(+), 6 deletions(-) - ---- a/drivers/iommu/intel-iommu.c -+++ b/drivers/iommu/intel-iommu.c -@@ -480,7 +480,7 @@ struct deferred_flush_data { - struct deferred_flush_table *tables; - }; - --DEFINE_PER_CPU(struct deferred_flush_data, deferred_flush); -+static DEFINE_PER_CPU(struct deferred_flush_data, deferred_flush); - - /* bitmap for indexing intel_iommus */ - static int g_num_of_iommus; -@@ -3720,10 +3720,8 @@ static void add_unmap(struct dmar_domain - struct intel_iommu *iommu; - struct deferred_flush_entry *entry; - struct deferred_flush_data *flush_data; -- unsigned int cpuid; - -- cpuid = get_cpu(); -- flush_data = per_cpu_ptr(&deferred_flush, cpuid); -+ flush_data = raw_cpu_ptr(&deferred_flush); - - /* Flush all CPUs' entries to avoid deferring too much. If - * this becomes a bottleneck, can just flush us, and rely on -@@ -3756,8 +3754,6 @@ static void add_unmap(struct dmar_domain - } - flush_data->size++; - spin_unlock_irqrestore(&flush_data->lock, flags); -- -- put_cpu(); - } - - static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size) diff --git a/patches/irq-allow-disabling-of-softirq-processing-in-irq-thread-context.patch b/patches/irq-allow-disabling-of-softirq-processing-in-irq-thread-context.patch index b56f6d991a5e..44a6c552faf2 100644 --- a/patches/irq-allow-disabling-of-softirq-processing-in-irq-thread-context.patch +++ b/patches/irq-allow-disabling-of-softirq-processing-in-irq-thread-context.patch @@ -38,7 +38,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/include/linux/irq.h +++ b/include/linux/irq.h -@@ -72,6 +72,7 @@ enum irqchip_irq_state; +@@ -73,6 +73,7 @@ enum irqchip_irq_state; * IRQ_IS_POLLED - Always polled by another interrupt. Exclude * it from the spurious interrupt detection * mechanism and from core side polling. @@ -46,7 +46,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> * IRQ_DISABLE_UNLAZY - Disable lazy irq disable */ enum { -@@ -99,13 +100,14 @@ enum { +@@ -100,13 +101,14 @@ enum { IRQ_PER_CPU_DEVID = (1 << 17), IRQ_IS_POLLED = (1 << 18), IRQ_DISABLE_UNLAZY = (1 << 19), @@ -64,7 +64,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c -@@ -883,7 +883,15 @@ irq_forced_thread_fn(struct irq_desc *de +@@ -858,7 +858,15 @@ irq_forced_thread_fn(struct irq_desc *de local_bh_disable(); ret = action->thread_fn(action->irq, action->dev_id); irq_finalize_oneshot(desc, action); @@ -81,16 +81,16 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return ret; } -@@ -1342,6 +1350,9 @@ static int +@@ -1335,6 +1343,9 @@ static int irqd_set(&desc->irq_data, IRQD_NO_BALANCING); } + if (new->flags & IRQF_NO_SOFTIRQ_CALL) + irq_settings_set_no_softirq_call(desc); + - /* Set default affinity mask once everything is setup */ - setup_affinity(desc, mask); - + if (irq_settings_can_autoenable(desc)) { + irq_startup(desc, IRQ_RESEND, IRQ_START_COND); + } else { --- a/kernel/irq/settings.h +++ b/kernel/irq/settings.h @@ -16,6 +16,7 @@ enum { diff --git a/patches/irqwork-Move-irq-safe-work-to-irq-context.patch b/patches/irqwork-Move-irq-safe-work-to-irq-context.patch index 3301b02274f1..395ca4379d3f 100644 --- a/patches/irqwork-Move-irq-safe-work-to-irq-context.patch +++ b/patches/irqwork-Move-irq-safe-work-to-irq-context.patch @@ -55,7 +55,7 @@ Cc: stable-rt@vger.kernel.org * Synchronize against the irq_work @entry, ensures the entry is not --- a/kernel/time/timer.c +++ b/kernel/time/timer.c -@@ -1604,7 +1604,7 @@ void update_process_times(int user_tick) +@@ -1623,7 +1623,7 @@ void update_process_times(int user_tick) scheduler_tick(); run_local_timers(); rcu_check_callbacks(user_tick); @@ -64,7 +64,7 @@ Cc: stable-rt@vger.kernel.org if (in_irq()) irq_work_tick(); #endif -@@ -1645,9 +1645,7 @@ static __latent_entropy void run_timer_s +@@ -1664,9 +1664,7 @@ static __latent_entropy void run_timer_s { struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]); @@ -72,6 +72,6 @@ Cc: stable-rt@vger.kernel.org - irq_work_tick(); -#endif + irq_work_tick_soft(); - - __run_timers(base); - if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && base->nohz_active) + /* + * must_forward_clk must be cleared before running timers so that any + * timer functions that call mod_timer will not try to forward the diff --git a/patches/irqwork-push_most_work_into_softirq_context.patch b/patches/irqwork-push_most_work_into_softirq_context.patch index f3f9b28e9381..d6526ec63f33 100644 --- a/patches/irqwork-push_most_work_into_softirq_context.patch +++ b/patches/irqwork-push_most_work_into_softirq_context.patch @@ -23,8 +23,8 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> kernel/irq_work.c | 47 ++++++++++++++++++++++++++++++++++------------- kernel/sched/rt.c | 1 + kernel/time/tick-sched.c | 1 + - kernel/time/timer.c | 6 +++++- - 5 files changed, 42 insertions(+), 14 deletions(-) + kernel/time/timer.c | 5 ++++- + 5 files changed, 41 insertions(+), 14 deletions(-) --- a/include/linux/irq_work.h +++ b/include/linux/irq_work.h @@ -153,7 +153,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* We start is dequeued state, because no RT tasks are queued */ --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c -@@ -224,6 +224,7 @@ static void nohz_full_kick_func(struct i +@@ -230,6 +230,7 @@ static void nohz_full_kick_func(struct i static DEFINE_PER_CPU(struct irq_work, nohz_full_kick_work) = { .func = nohz_full_kick_func, @@ -163,7 +163,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* --- a/kernel/time/timer.c +++ b/kernel/time/timer.c -@@ -1604,7 +1604,7 @@ void update_process_times(int user_tick) +@@ -1623,7 +1623,7 @@ void update_process_times(int user_tick) scheduler_tick(); run_local_timers(); rcu_check_callbacks(user_tick); @@ -172,14 +172,13 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (in_irq()) irq_work_tick(); #endif -@@ -1645,6 +1645,10 @@ static __latent_entropy void run_timer_s +@@ -1664,6 +1664,9 @@ static __latent_entropy void run_timer_s { struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]); +#if defined(CONFIG_IRQ_WORK) && defined(CONFIG_PREEMPT_RT_FULL) + irq_work_tick(); +#endif -+ - __run_timers(base); - if (IS_ENABLED(CONFIG_NO_HZ_COMMON) && base->nohz_active) - __run_timers(this_cpu_ptr(&timer_bases[BASE_DEF])); + /* + * must_forward_clk must be cleared before running timers so that any + * timer functions that call mod_timer will not try to forward the diff --git a/patches/jump-label-rt.patch b/patches/jump-label-rt.patch index 1f4ee1ad694b..9dca87b1226e 100644 --- a/patches/jump-label-rt.patch +++ b/patches/jump-label-rt.patch @@ -24,10 +24,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig -@@ -42,7 +42,7 @@ config ARM +@@ -44,7 +44,7 @@ config ARM + select HARDIRQS_SW_RESEND select HAVE_ARCH_AUDITSYSCALL if (AEABI && !OABI_COMPAT) select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6 - select HAVE_ARCH_HARDENED_USERCOPY - select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU + select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU && !PREEMPT_RT_BASE select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU diff --git a/patches/kconfig-disable-a-few-options-rt.patch b/patches/kconfig-disable-a-few-options-rt.patch index 5c9ecdc7c8ac..2e4fb718ef49 100644 --- a/patches/kconfig-disable-a-few-options-rt.patch +++ b/patches/kconfig-disable-a-few-options-rt.patch @@ -12,7 +12,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/arch/Kconfig +++ b/arch/Kconfig -@@ -12,6 +12,7 @@ config OPROFILE +@@ -16,6 +16,7 @@ config OPROFILE tristate "OProfile system profiling" depends on PROFILING depends on HAVE_OPROFILE @@ -22,7 +22,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> help --- a/mm/Kconfig +++ b/mm/Kconfig -@@ -410,7 +410,7 @@ config NOMMU_INITIAL_TRIM_EXCESS +@@ -382,7 +382,7 @@ config NOMMU_INITIAL_TRIM_EXCESS config TRANSPARENT_HUGEPAGE bool "Transparent Hugepage Support" diff --git a/patches/kernel-SRCU-provide-a-static-initializer.patch b/patches/kernel-SRCU-provide-a-static-initializer.patch index e67e5b256565..572c852cc05a 100644 --- a/patches/kernel-SRCU-provide-a-static-initializer.patch +++ b/patches/kernel-SRCU-provide-a-static-initializer.patch @@ -14,7 +14,7 @@ complete. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- include/linux/notifier.h | 34 +++++++++++++++++++++++++--------- - include/linux/srcu.h | 6 +++--- + include/linux/srcutree.h | 6 +++--- 2 files changed, 28 insertions(+), 12 deletions(-) --- a/include/linux/notifier.h @@ -68,10 +68,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> RAW_NOTIFIER_INIT(name) +#define _SRCU_NOTIFIER_HEAD(name, mod) \ -+ static DEFINE_PER_CPU(struct srcu_array, \ -+ name##_head_srcu_array); \ ++ static DEFINE_PER_CPU(struct srcu_data, \ ++ name##_head_srcu_data); \ + mod struct srcu_notifier_head name = \ -+ SRCU_NOTIFIER_INIT(name, name##_head_srcu_array) ++ SRCU_NOTIFIER_INIT(name, name##_head_srcu_data) + +#define SRCU_NOTIFIER_HEAD(name) \ + _SRCU_NOTIFIER_HEAD(name, ) @@ -98,27 +98,26 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* CPU notfiers are defined in include/linux/cpu.h. */ /* netdevice notifiers are defined in include/linux/netdevice.h */ ---- a/include/linux/srcu.h -+++ b/include/linux/srcu.h -@@ -84,10 +84,10 @@ int init_srcu_struct(struct srcu_struct +--- a/include/linux/srcutree.h ++++ b/include/linux/srcutree.h +@@ -106,9 +106,9 @@ struct srcu_struct { void process_srcu(struct work_struct *work); -#define __SRCU_STRUCT_INIT(name) \ +#define __SRCU_STRUCT_INIT(name, pcpu_name) \ { \ - .completed = -300, \ -- .per_cpu_ref = &name##_srcu_array, \ -+ .per_cpu_ref = &pcpu_name, \ - .queue_lock = __SPIN_LOCK_UNLOCKED(name.queue_lock), \ - .running = false, \ - .batch_queue = RCU_BATCH_INIT(name.batch_queue), \ -@@ -119,7 +119,7 @@ void process_srcu(struct work_struct *wo +- .sda = &name##_srcu_data, \ ++ .sda = &pcpu_name, \ + .lock = __RAW_SPIN_LOCK_UNLOCKED(name.lock), \ + .srcu_gp_seq_needed = 0 - 1, \ + __SRCU_DEP_MAP_INIT(name) \ +@@ -135,7 +135,7 @@ void process_srcu(struct work_struct *wo */ #define __DEFINE_SRCU(name, is_static) \ - static DEFINE_PER_CPU(struct srcu_array, name##_srcu_array);\ + static DEFINE_PER_CPU(struct srcu_data, name##_srcu_data);\ - is_static struct srcu_struct name = __SRCU_STRUCT_INIT(name) -+ is_static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name##_srcu_array) ++ is_static struct srcu_struct name = __SRCU_STRUCT_INIT(name, name##_srcu_data) #define DEFINE_SRCU(name) __DEFINE_SRCU(name, /* not static */) #define DEFINE_STATIC_SRCU(name) __DEFINE_SRCU(name, static) diff --git a/patches/kernel-locking-use-an-exclusive-wait_q-for-sleeper.patch b/patches/kernel-locking-use-an-exclusive-wait_q-for-sleeper.patch deleted file mode 100644 index ff3f6be32617..000000000000 --- a/patches/kernel-locking-use-an-exclusive-wait_q-for-sleeper.patch +++ /dev/null @@ -1,141 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Thu, 22 Jun 2017 17:53:34 +0200 -Subject: [PATCH] kernel/locking: use an exclusive wait_q for sleepers -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -If a task is queued as a sleeper for a wakeup and never goes to -schedule() (because it just obtained the lock) then it will receive a -spurious wake up which is not "bad", it is considered. Until that wake -up happens this task can no be enqueued for any wake ups handled by the -WAKE_Q infrastructure (because a task can only be enqueued once). This -wouldn't be bad if we would use the same wakeup mechanism for the wake -up of sleepers as we do for "normal" wake ups. But we don't… - -So. - T1 T2 T3 - spin_lock(x) spin_unlock(x); - wake_q_add_sleeper(q1, T1) - spin_unlock(x) - set_state(TASK_INTERRUPTIBLE) - if (!condition) - schedule() - condition = true - wake_q_add(q2, T1) - // T1 not added, still enqueued - wake_up_q(q2) - wake_up_q_sleeper(q1) - // T1 not woken up, wrong task state - -In order to solve this race this patch adds a wake_q_node for the -sleeper case. - -Reported-by: Mike Galbraith <efault@gmx.de> -Cc: stable-rt@vger.kernel.org -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - include/linux/sched.h | 1 + - include/linux/sched/wake_q.h | 16 ++++++++++++++-- - kernel/fork.c | 1 + - kernel/locking/rtmutex.c | 2 +- - kernel/sched/core.c | 21 ++++++++++++++++----- - 5 files changed, 33 insertions(+), 8 deletions(-) - ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -800,6 +800,7 @@ struct task_struct { - raw_spinlock_t pi_lock; - - struct wake_q_node wake_q; -+ struct wake_q_node wake_q_sleeper; - - #ifdef CONFIG_RT_MUTEXES - /* PI waiters blocked on a rt_mutex held by this task: */ ---- a/include/linux/sched/wake_q.h -+++ b/include/linux/sched/wake_q.h -@@ -46,8 +46,20 @@ static inline void wake_q_init(struct wa - head->lastp = &head->first; - } - --extern void wake_q_add(struct wake_q_head *head, -- struct task_struct *task); -+extern void __wake_q_add(struct wake_q_head *head, -+ struct task_struct *task, bool sleeper); -+static inline void wake_q_add(struct wake_q_head *head, -+ struct task_struct *task) -+{ -+ __wake_q_add(head, task, false); -+} -+ -+static inline void wake_q_add_sleeper(struct wake_q_head *head, -+ struct task_struct *task) -+{ -+ __wake_q_add(head, task, true); -+} -+ - extern void __wake_up_q(struct wake_q_head *head, bool sleeper); - static inline void wake_up_q(struct wake_q_head *head) - { ---- a/kernel/fork.c -+++ b/kernel/fork.c -@@ -575,6 +575,7 @@ static struct task_struct *dup_task_stru - tsk->splice_pipe = NULL; - tsk->task_frag.page = NULL; - tsk->wake_q.next = NULL; -+ tsk->wake_q_sleeper.next = NULL; - - account_kernel_stack(tsk, 1); - ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -1463,7 +1463,7 @@ static void mark_wakeup_next_waiter(stru - */ - preempt_disable(); - if (waiter->savestate) -- wake_q_add(wake_sleeper_q, waiter->task); -+ wake_q_add_sleeper(wake_sleeper_q, waiter->task); - else - wake_q_add(wake_q, waiter->task); - raw_spin_unlock(¤t->pi_lock); ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -436,9 +436,15 @@ static bool set_nr_if_polling(struct tas - #endif - #endif - --void wake_q_add(struct wake_q_head *head, struct task_struct *task) -+void __wake_q_add(struct wake_q_head *head, struct task_struct *task, -+ bool sleeper) - { -- struct wake_q_node *node = &task->wake_q; -+ struct wake_q_node *node; -+ -+ if (sleeper) -+ node = &task->wake_q_sleeper; -+ else -+ node = &task->wake_q; - - /* - * Atomically grab the task, if ->wake_q is !nil already it means -@@ -467,12 +473,17 @@ void __wake_up_q(struct wake_q_head *hea - while (node != WAKE_Q_TAIL) { - struct task_struct *task; - -- task = container_of(node, struct task_struct, wake_q); -+ if (sleeper) -+ task = container_of(node, struct task_struct, wake_q_sleeper); -+ else -+ task = container_of(node, struct task_struct, wake_q); - BUG_ON(!task); - /* Task can safely be re-inserted now: */ - node = node->next; -- task->wake_q.next = NULL; -- -+ if (sleeper) -+ task->wake_q_sleeper.next = NULL; -+ else -+ task->wake_q.next = NULL; - /* - * wake_up_process() implies a wmb() to pair with the queueing - * in wake_q_add() so as not to miss wakeups. diff --git a/patches/kernel-printk-Don-t-try-to-print-from-IRQ-NMI-region.patch b/patches/kernel-printk-Don-t-try-to-print-from-IRQ-NMI-region.patch index 63a372184a3e..e52743002fa9 100644 --- a/patches/kernel-printk-Don-t-try-to-print-from-IRQ-NMI-region.patch +++ b/patches/kernel-printk-Don-t-try-to-print-from-IRQ-NMI-region.patch @@ -15,7 +15,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c -@@ -1630,6 +1630,11 @@ static void call_console_drivers(const c +@@ -1629,6 +1629,11 @@ static void call_console_drivers(const c if (!console_drivers) return; @@ -27,7 +27,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> migrate_disable(); for_each_console(con) { if (exclusive_console && con != exclusive_console) -@@ -2357,6 +2362,11 @@ void console_unblank(void) +@@ -2361,6 +2366,11 @@ void console_unblank(void) { struct console *c; diff --git a/patches/kernel-sched-Provide-a-pointer-to-the-valid-CPU-mask.patch b/patches/kernel-sched-Provide-a-pointer-to-the-valid-CPU-mask.patch index c5f431799ab9..baad1c6e6095 100644 --- a/patches/kernel-sched-Provide-a-pointer-to-the-valid-CPU-mask.patch +++ b/patches/kernel-sched-Provide-a-pointer-to-the-valid-CPU-mask.patch @@ -70,7 +70,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> include/linux/init_task.h | 3 +- include/linux/sched.h | 5 ++- kernel/cgroup/cpuset.c | 2 - - kernel/fork.c | 2 + + kernel/fork.c | 3 +- kernel/sched/core.c | 42 ++++++++++++++--------------- kernel/sched/cpudeadline.c | 4 +- kernel/sched/cpupri.c | 4 +- @@ -80,7 +80,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> kernel/trace/trace_hwlat.c | 2 - lib/smp_processor_id.c | 2 - samples/trace_events/trace-events-sample.c | 2 - - 24 files changed, 78 insertions(+), 76 deletions(-) + 24 files changed, 78 insertions(+), 77 deletions(-) --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -126,7 +126,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> out_unlock: --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c -@@ -1193,12 +1193,12 @@ static void mt_ase_fp_affinity(void) +@@ -1194,12 +1194,12 @@ static void mt_ase_fp_affinity(void) * restricted the allowed set to exclude any CPUs with FPUs, * we'll skip the procedure. */ @@ -274,7 +274,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (!find_hca(cpu, &unit) && unit >= 0) --- a/fs/proc/array.c +++ b/fs/proc/array.c -@@ -364,9 +364,9 @@ static inline void task_context_switch_c +@@ -365,9 +365,9 @@ static inline void task_context_switch_c static void task_cpus_allowed(struct seq_file *m, struct task_struct *task) { seq_printf(m, "Cpus_allowed:\t%*pb\n", @@ -288,7 +288,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, --- a/include/linux/init_task.h +++ b/include/linux/init_task.h -@@ -226,7 +226,8 @@ extern struct cred init_cred; +@@ -240,7 +240,8 @@ extern struct cred init_cred; .static_prio = MAX_PRIO-20, \ .normal_prio = MAX_PRIO-20, \ .policy = SCHED_NORMAL, \ @@ -300,7 +300,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> .active_mm = &init_mm, \ --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -535,7 +535,8 @@ struct task_struct { +@@ -578,7 +578,8 @@ struct task_struct { unsigned int policy; int nr_cpus_allowed; @@ -310,7 +310,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #ifdef CONFIG_PREEMPT_RCU int rcu_read_lock_nesting; -@@ -1224,7 +1225,7 @@ extern struct pid *cad_pid; +@@ -1274,7 +1275,7 @@ extern struct pid *cad_pid; #define PF_KTHREAD 0x00200000 /* I am a kernel thread */ #define PF_RANDOMIZE 0x00400000 /* Randomize virtual address space */ #define PF_SWAPWRITE 0x00800000 /* Allowed to write to swap */ @@ -321,7 +321,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezable */ --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c -@@ -2092,7 +2092,7 @@ static void cpuset_fork(struct task_stru +@@ -2079,7 +2079,7 @@ static void cpuset_fork(struct task_stru if (task_css_is_root(task, cpuset_cgrp_id)) return; @@ -332,10 +332,11 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -539,6 +539,8 @@ static struct task_struct *dup_task_stru - tsk->stack_canary = get_random_long(); +@@ -556,7 +556,8 @@ static struct task_struct *dup_task_stru + #ifdef CONFIG_CC_STACKPROTECTOR + tsk->stack_canary = get_random_canary(); #endif - +- + if (orig->cpus_ptr == &orig->cpus_mask) + tsk->cpus_ptr = &tsk->cpus_mask; /* @@ -343,7 +344,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * parent) --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -986,7 +986,7 @@ static struct rq *__migrate_task(struct +@@ -955,7 +955,7 @@ static struct rq *__migrate_task(struct return rq; /* Affinity changed (again). */ @@ -351,8 +352,8 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + if (!cpumask_test_cpu(dest_cpu, p->cpus_ptr)) return rq; - rq = move_queued_task(rq, p, dest_cpu); -@@ -1012,7 +1012,7 @@ static int migration_cpu_stop(void *data + update_rq_clock(rq); +@@ -983,7 +983,7 @@ static int migration_cpu_stop(void *data local_irq_disable(); /* * We need to explicitly wake pending tasks before running @@ -361,7 +362,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * during wakeups, see set_cpus_allowed_ptr()'s TASK_WAKING test. */ sched_ttwu_pending(); -@@ -1043,7 +1043,7 @@ static int migration_cpu_stop(void *data +@@ -1014,7 +1014,7 @@ static int migration_cpu_stop(void *data */ void set_cpus_allowed_common(struct task_struct *p, const struct cpumask *new_mask) { @@ -370,7 +371,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> p->nr_cpus_allowed = cpumask_weight(new_mask); } -@@ -1113,7 +1113,7 @@ static int __set_cpus_allowed_ptr(struct +@@ -1084,7 +1084,7 @@ static int __set_cpus_allowed_ptr(struct goto out; } @@ -379,7 +380,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> goto out; if (!cpumask_intersects(new_mask, cpu_valid_mask)) { -@@ -1264,10 +1264,10 @@ static int migrate_swap_stop(void *data) +@@ -1241,10 +1241,10 @@ static int migrate_swap_stop(void *data) if (task_cpu(arg->src_task) != arg->src_cpu) goto unlock; @@ -392,7 +393,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> goto unlock; __migrate_swap_task(arg->src_task, arg->dst_cpu); -@@ -1308,10 +1308,10 @@ int migrate_swap(struct task_struct *cur +@@ -1285,10 +1285,10 @@ int migrate_swap(struct task_struct *cur if (!cpu_active(arg.src_cpu) || !cpu_active(arg.dst_cpu)) goto out; @@ -405,7 +406,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> goto out; trace_sched_swap_numa(cur, arg.src_cpu, p, arg.dst_cpu); -@@ -1455,7 +1455,7 @@ void kick_process(struct task_struct *p) +@@ -1432,7 +1432,7 @@ void kick_process(struct task_struct *p) EXPORT_SYMBOL_GPL(kick_process); /* @@ -414,7 +415,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * * A few notes on cpu_active vs cpu_online: * -@@ -1495,14 +1495,14 @@ static int select_fallback_rq(int cpu, s +@@ -1472,14 +1472,14 @@ static int select_fallback_rq(int cpu, s for_each_cpu(dest_cpu, nodemask) { if (!cpu_active(dest_cpu)) continue; @@ -431,7 +432,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (!(p->flags & PF_KTHREAD) && !cpu_active(dest_cpu)) continue; if (!cpu_online(dest_cpu)) -@@ -1547,7 +1547,7 @@ static int select_fallback_rq(int cpu, s +@@ -1524,7 +1524,7 @@ static int select_fallback_rq(int cpu, s } /* @@ -440,7 +441,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> */ static inline int select_task_rq(struct task_struct *p, int cpu, int sd_flags, int wake_flags) -@@ -1557,11 +1557,11 @@ int select_task_rq(struct task_struct *p +@@ -1534,11 +1534,11 @@ int select_task_rq(struct task_struct *p if (p->nr_cpus_allowed > 1) cpu = p->sched_class->select_task_rq(p, cpu, sd_flags, wake_flags); else @@ -454,7 +455,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * CPU. * * Since this is common to all placement strategies, this lives here. -@@ -1569,7 +1569,7 @@ int select_task_rq(struct task_struct *p +@@ -1546,7 +1546,7 @@ int select_task_rq(struct task_struct *p * [ this allows ->select_task() to simply return task_cpu(p) and * not worry about this generic constraint ] */ @@ -463,7 +464,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> !cpu_online(cpu))) cpu = select_fallback_rq(task_cpu(p), p); -@@ -2543,7 +2543,7 @@ void wake_up_new_task(struct task_struct +@@ -2436,7 +2436,7 @@ void wake_up_new_task(struct task_struct #ifdef CONFIG_SMP /* * Fork balancing, do it here and not earlier because: @@ -472,7 +473,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * - any previously selected CPU might disappear through hotplug * * Use __set_task_cpu() to avoid calling sched_class::migrate_task_rq, -@@ -4315,7 +4315,7 @@ static int __sched_setscheduler(struct t +@@ -4128,7 +4128,7 @@ static int __sched_setscheduler(struct t * the entire root_domain to become SCHED_DEADLINE. We * will also fail if there's no bandwidth available. */ @@ -481,7 +482,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> rq->rd->dl_bw.bw == 0) { task_rq_unlock(rq, p, &rf); return -EPERM; -@@ -4909,7 +4909,7 @@ long sched_getaffinity(pid_t pid, struct +@@ -4722,7 +4722,7 @@ long sched_getaffinity(pid_t pid, struct goto out_unlock; raw_spin_lock_irqsave(&p->pi_lock, flags); @@ -490,7 +491,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> raw_spin_unlock_irqrestore(&p->pi_lock, flags); out_unlock: -@@ -5469,7 +5469,7 @@ int task_can_attach(struct task_struct * +@@ -5277,7 +5277,7 @@ int task_can_attach(struct task_struct * * allowed nodes is unnecessary. Thus, cpusets are not * applicable for such threads. This prevents checking for * success of set_cpus_allowed_ptr() on all attached tasks @@ -499,7 +500,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> */ if (p->flags & PF_NO_SETAFFINITY) { ret = -EINVAL; -@@ -5525,7 +5525,7 @@ int migrate_task_to(struct task_struct * +@@ -5304,7 +5304,7 @@ int migrate_task_to(struct task_struct * if (curr_cpu == target_cpu) return 0; @@ -508,7 +509,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return -EINVAL; /* TODO: This is not properly updating schedstats */ -@@ -5665,7 +5665,7 @@ static void migrate_tasks(struct rq *dea +@@ -5441,7 +5441,7 @@ static void migrate_tasks(struct rq *dea next->sched_class->put_prev_task(rq, next); /* @@ -550,7 +551,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * We have to ensure that we have at least one bit --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c -@@ -252,7 +252,7 @@ static struct rq *dl_task_offline_migrat +@@ -505,7 +505,7 @@ static struct rq *dl_task_offline_migrat * If we cannot preempt any rq, fall back to pick any * online cpu. */ @@ -559,7 +560,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (cpu >= nr_cpu_ids) { /* * Fail to find any suitable cpu. -@@ -1286,7 +1286,7 @@ static void set_curr_task_dl(struct rq * +@@ -1760,7 +1760,7 @@ static void set_curr_task_dl(struct rq * static int pick_dl_task(struct rq *rq, struct task_struct *p, int cpu) { if (!task_running(rq, p) && @@ -568,7 +569,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return 1; return 0; } -@@ -1435,7 +1435,7 @@ static struct rq *find_lock_later_rq(str +@@ -1909,7 +1909,7 @@ static struct rq *find_lock_later_rq(str /* Retry if something changed. */ if (double_lock_balance(rq, later_rq)) { if (unlikely(task_rq(task) != rq || @@ -579,7 +580,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> !task_on_rq_queued(task))) { --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c -@@ -1553,7 +1553,7 @@ static void task_numa_compare(struct tas +@@ -1547,7 +1547,7 @@ static void task_numa_compare(struct tas */ if (cur) { /* Skip this swap candidate if cannot move to the source cpu */ @@ -588,7 +589,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> goto unlock; /* -@@ -1663,7 +1663,7 @@ static void task_numa_find_cpu(struct ta +@@ -1657,7 +1657,7 @@ static void task_numa_find_cpu(struct ta for_each_cpu(cpu, cpumask_of_node(env->dst_nid)) { /* Skip this CPU if the source task cannot migrate */ @@ -597,25 +598,25 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> continue; env->dst_cpu = cpu; -@@ -5460,7 +5460,7 @@ find_idlest_group(struct sched_domain *s +@@ -5406,7 +5406,7 @@ find_idlest_group(struct sched_domain *s /* Skip over this group if it has no CPUs allowed */ - if (!cpumask_intersects(sched_group_cpus(group), + if (!cpumask_intersects(sched_group_span(group), - &p->cpus_allowed)) + p->cpus_ptr)) continue; local_group = cpumask_test_cpu(this_cpu, -@@ -5580,7 +5580,7 @@ find_idlest_cpu(struct sched_group *grou - return cpumask_first(sched_group_cpus(group)); +@@ -5526,7 +5526,7 @@ find_idlest_cpu(struct sched_group *grou + return cpumask_first(sched_group_span(group)); /* Traverse only the allowed CPUs */ -- for_each_cpu_and(i, sched_group_cpus(group), &p->cpus_allowed) { -+ for_each_cpu_and(i, sched_group_cpus(group), p->cpus_ptr) { +- for_each_cpu_and(i, sched_group_span(group), &p->cpus_allowed) { ++ for_each_cpu_and(i, sched_group_span(group), p->cpus_ptr) { if (idle_cpu(i)) { struct rq *rq = cpu_rq(i); struct cpuidle_state *idle = idle_get_state(rq); -@@ -5682,7 +5682,7 @@ static int select_idle_core(struct task_ +@@ -5628,7 +5628,7 @@ static int select_idle_core(struct task_ if (!test_idle_cores(target, false)) return -1; @@ -624,7 +625,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> for_each_cpu_wrap(core, cpus, target) { bool idle = true; -@@ -5716,7 +5716,7 @@ static int select_idle_smt(struct task_s +@@ -5662,7 +5662,7 @@ static int select_idle_smt(struct task_s return -1; for_each_cpu(cpu, cpu_smt_mask(target)) { @@ -633,16 +634,16 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> continue; if (idle_cpu(cpu)) return cpu; -@@ -5768,7 +5768,7 @@ static int select_idle_cpu(struct task_s - time = local_clock(); - +@@ -5725,7 +5725,7 @@ static int select_idle_cpu(struct task_s for_each_cpu_wrap(cpu, sched_domain_span(sd), target) { + if (!--nr) + return -1; - if (!cpumask_test_cpu(cpu, &p->cpus_allowed)) + if (!cpumask_test_cpu(cpu, p->cpus_ptr)) continue; if (idle_cpu(cpu)) break; -@@ -5923,7 +5923,7 @@ select_task_rq_fair(struct task_struct * +@@ -5880,7 +5880,7 @@ select_task_rq_fair(struct task_struct * if (sd_flag & SD_BALANCE_WAKE) { record_wakee(p); want_affine = !wake_wide(p) && !wake_cap(p, cpu, prev_cpu) @@ -651,7 +652,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } rcu_read_lock(); -@@ -6656,14 +6656,14 @@ int can_migrate_task(struct task_struct +@@ -6627,14 +6627,14 @@ int can_migrate_task(struct task_struct /* * We do not migrate tasks that are: * 1) throttled_lb_pair, or @@ -668,7 +669,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> int cpu; schedstat_inc(p->se.statistics.nr_failed_migrations_affine); -@@ -6683,7 +6683,7 @@ int can_migrate_task(struct task_struct +@@ -6654,7 +6654,7 @@ int can_migrate_task(struct task_struct /* Prevent to re-select dst_cpu via env's cpus */ for_each_cpu_and(cpu, env->dst_grpmask, env->cpus) { @@ -677,7 +678,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> env->flags |= LBF_DST_PINNED; env->new_dst_cpu = cpu; break; -@@ -7217,7 +7217,7 @@ check_cpu_capacity(struct rq *rq, struct +@@ -7221,7 +7221,7 @@ check_cpu_capacity(struct rq *rq, struct /* * Group imbalance indicates (and tries to solve) the problem where balancing @@ -686,7 +687,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * * Imagine a situation of two groups of 4 cpus each and 4 tasks each with a * cpumask covering 1 cpu of the first group and 3 cpus of the second group. -@@ -7791,7 +7791,7 @@ static struct sched_group *find_busiest_ +@@ -7796,7 +7796,7 @@ static struct sched_group *find_busiest_ /* * If the busiest group is imbalanced the below checks don't * work because they assume all things are equal, which typically @@ -695,7 +696,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> */ if (busiest->group_type == group_imbalanced) goto force_balance; -@@ -8176,7 +8176,7 @@ static int load_balance(int this_cpu, st +@@ -8181,7 +8181,7 @@ static int load_balance(int this_cpu, st * if the curr task on busiest cpu can't be * moved to this_cpu */ @@ -706,7 +707,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> env.flags |= LBF_ALL_PINNED; --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c -@@ -1591,7 +1591,7 @@ static void put_prev_task_rt(struct rq * +@@ -1602,7 +1602,7 @@ static void put_prev_task_rt(struct rq * static int pick_rt_task(struct rq *rq, struct task_struct *p, int cpu) { if (!task_running(rq, p) && @@ -715,7 +716,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return 1; return 0; } -@@ -1726,7 +1726,7 @@ static struct rq *find_lock_lowest_rq(st +@@ -1737,7 +1737,7 @@ static struct rq *find_lock_lowest_rq(st * Also make sure that it wasn't scheduled on its rq. */ if (unlikely(task_rq(task) != rq || diff --git a/patches/kernel-sched-move-stack-kprobe-clean-up-to-__put_tas.patch b/patches/kernel-sched-move-stack-kprobe-clean-up-to-__put_tas.patch index 76175a23298b..06b0120ad5bd 100644 --- a/patches/kernel-sched-move-stack-kprobe-clean-up-to-__put_tas.patch +++ b/patches/kernel-sched-move-stack-kprobe-clean-up-to-__put_tas.patch @@ -16,15 +16,15 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -87,6 +87,7 @@ - #include <linux/compiler.h> - #include <linux/sysctl.h> - #include <linux/kcov.h> +@@ -39,6 +39,7 @@ + #include <linux/mmu_notifier.h> + #include <linux/fs.h> + #include <linux/mm.h> +#include <linux/kprobes.h> - - #include <asm/pgtable.h> - #include <asm/pgalloc.h> -@@ -398,6 +399,15 @@ void __put_task_struct(struct task_struc + #include <linux/vmacache.h> + #include <linux/nsproxy.h> + #include <linux/capability.h> +@@ -411,6 +412,15 @@ void __put_task_struct(struct task_struc WARN_ON(atomic_read(&tsk->usage)); WARN_ON(tsk == current); @@ -42,7 +42,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> security_task_free(tsk); --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -2794,15 +2794,6 @@ static struct rq *finish_task_switch(str +@@ -2687,15 +2687,6 @@ static struct rq *finish_task_switch(str if (prev->sched_class->task_dead) prev->sched_class->task_dead(prev); diff --git a/patches/kgb-serial-hackaround.patch b/patches/kgb-serial-hackaround.patch index 76505b19bd58..05ffbaaee595 100644 --- a/patches/kgb-serial-hackaround.patch +++ b/patches/kgb-serial-hackaround.patch @@ -33,7 +33,7 @@ Jason. #include <linux/uaccess.h> #include <linux/pm_runtime.h> #include <linux/timer.h> -@@ -3181,6 +3182,8 @@ void serial8250_console_write(struct uar +@@ -3191,6 +3192,8 @@ void serial8250_console_write(struct uar if (port->sysrq || oops_in_progress) locked = 0; diff --git a/patches/local-irq-rt-depending-variants.patch b/patches/local-irq-rt-depending-variants.patch index af811d03f390..2e0831532af2 100644 --- a/patches/local-irq-rt-depending-variants.patch +++ b/patches/local-irq-rt-depending-variants.patch @@ -15,7 +15,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h -@@ -196,7 +196,7 @@ extern void devm_free_irq(struct device +@@ -205,7 +205,7 @@ extern void devm_free_irq(struct device #ifdef CONFIG_LOCKDEP # define local_irq_enable_in_hardirq() do { } while (0) #else diff --git a/patches/locallock-add-local_lock_on.patch b/patches/locallock-add-local_lock_on.patch deleted file mode 100644 index bb3846f205d9..000000000000 --- a/patches/locallock-add-local_lock_on.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Fri, 27 May 2016 15:11:51 +0200 -Subject: [PATCH] locallock: add local_lock_on() - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - include/linux/locallock.h | 6 ++++++ - 1 file changed, 6 insertions(+) - ---- a/include/linux/locallock.h -+++ b/include/linux/locallock.h -@@ -60,6 +60,9 @@ static inline void __local_lock(struct l - #define local_lock(lvar) \ - do { __local_lock(&get_local_var(lvar)); } while (0) - -+#define local_lock_on(lvar, cpu) \ -+ do { __local_lock(&per_cpu(lvar, cpu)); } while (0) -+ - static inline int __local_trylock(struct local_irq_lock *lv) - { - if (lv->owner != current && spin_trylock_local(&lv->lock)) { -@@ -101,6 +104,9 @@ static inline void __local_unlock(struct - put_local_var(lvar); \ - } while (0) - -+#define local_unlock_on(lvar, cpu) \ -+ do { __local_unlock(&per_cpu(lvar, cpu)); } while (0) -+ - static inline void __local_lock_irq(struct local_irq_lock *lv) - { - spin_lock_irqsave(&lv->lock, lv->flags); diff --git a/patches/localversion.patch b/patches/localversion.patch index 0cccc7790a5d..a02382e6df70 100644 --- a/patches/localversion.patch +++ b/patches/localversion.patch @@ -10,4 +10,4 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- /dev/null +++ b/localversion-rt @@ -0,0 +1 @@ -+-rt16 ++-rt1 diff --git a/patches/lockdep-Fix-compilation-error-for-CONFIG_MODULES-and.patch b/patches/lockdep-Fix-compilation-error-for-CONFIG_MODULES-and.patch deleted file mode 100644 index d6385cee687e..000000000000 --- a/patches/lockdep-Fix-compilation-error-for-CONFIG_MODULES-and.patch +++ /dev/null @@ -1,55 +0,0 @@ -From: Dan Murphy <dmurphy@ti.com> -Date: Fri, 24 Feb 2017 08:41:49 -0600 -Subject: [PATCH] lockdep: Fix compilation error for !CONFIG_MODULES and - !CONFIG_SMP - -When CONFIG_MODULES is not set then it fails to compile in lockdep: - -|kernel/locking/lockdep.c: In function 'look_up_lock_class': -|kernel/locking/lockdep.c:684:12: error: implicit declaration of function -| '__is_module_percpu_address' [-Werror=implicit-function-declaration] - -If CONFIG_MODULES is set but CONFIG_SMP is not, then it compiles but -fails link at the end: - -|kernel/locking/lockdep.c:684: undefined reference to `__is_module_percpu_address' -|kernel/built-in.o:(.debug_addr+0x1e674): undefined reference to `__is_module_percpu_address' - -This patch adds the function for both cases. - -Signed-off-by: Dan Murphy <dmurphy@ti.com> -[bigeasy: merge the two patches from Dan into one, adapt changelog] -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - include/linux/module.h | 5 +++++ - kernel/module.c | 5 +++++ - 2 files changed, 10 insertions(+) - ---- a/include/linux/module.h -+++ b/include/linux/module.h -@@ -661,6 +661,11 @@ static inline bool is_module_percpu_addr - return false; - } - -+static inline bool __is_module_percpu_address(unsigned long addr, unsigned long *can_addr) -+{ -+ return false; -+} -+ - static inline bool is_module_text_address(unsigned long addr) - { - return false; ---- a/kernel/module.c -+++ b/kernel/module.c -@@ -739,6 +739,11 @@ bool is_module_percpu_address(unsigned l - return false; - } - -+bool __is_module_percpu_address(unsigned long addr, unsigned long *can_addr) -+{ -+ return false; -+} -+ - #endif /* CONFIG_SMP */ - - #define MODINFO_ATTR(field) \ diff --git a/patches/lockdep-Fix-per-cpu-static-objects.patch b/patches/lockdep-Fix-per-cpu-static-objects.patch deleted file mode 100644 index ec2cea43c710..000000000000 --- a/patches/lockdep-Fix-per-cpu-static-objects.patch +++ /dev/null @@ -1,123 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Mon, 20 Mar 2017 12:26:55 +0100 -Subject: [PATCH] lockdep: Fix per-cpu static objects - -Since commit 383776fa7527 ("locking/lockdep: Handle statically initialized -PER_CPU locks properly") we try to collapse per-cpu locks into a single -class by giving them all the same key. For this key we choose the canonical -address of the per-cpu object, which would be the offset into the per-cpu -area. - -This has two problems: - - - there is a case where we run !0 lock->key through static_obj() and - expect this to pass; it doesn't for canonical pointers. - - - 0 is a valid canonical address. - -Cure both issues by redefining the canonical address as the address of the -per-cpu variable on the boot CPU. - -Since I didn't want to rely on CPU0 being the boot-cpu, or even existing at -all, track the boot CPU in a variable. - -Fixes: 383776fa7527 ("locking/lockdep: Handle statically initialized PER_CPU locks properly") -Reported-by: kernel test robot <fengguang.wu@intel.com> -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Tested-by: Borislav Petkov <bp@suse.de> -Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Cc: linux-mm@kvack.org -Cc: wfg@linux.intel.com -Cc: kernel test robot <fengguang.wu@intel.com> -Cc: LKP <lkp@01.org> -Link: http://lkml.kernel.org/r/20170320114108.kbvcsuepem45j5cr@hirez.programming.kicks-ass.net -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - include/linux/smp.h | 12 ++++++++++++ - kernel/cpu.c | 6 ++++++ - kernel/module.c | 6 +++++- - mm/percpu.c | 5 ++++- - 4 files changed, 27 insertions(+), 2 deletions(-) - ---- a/include/linux/smp.h -+++ b/include/linux/smp.h -@@ -120,6 +120,13 @@ extern unsigned int setup_max_cpus; - extern void __init setup_nr_cpu_ids(void); - extern void __init smp_init(void); - -+extern int __boot_cpu_id; -+ -+static inline int get_boot_cpu_id(void) -+{ -+ return __boot_cpu_id; -+} -+ - #else /* !SMP */ - - static inline void smp_send_stop(void) { } -@@ -158,6 +165,11 @@ static inline void smp_init(void) { up_l - static inline void smp_init(void) { } - #endif - -+static inline int get_boot_cpu_id(void) -+{ -+ return 0; -+} -+ - #endif /* !SMP */ - - /* ---- a/kernel/cpu.c -+++ b/kernel/cpu.c -@@ -1125,6 +1125,8 @@ core_initcall(cpu_hotplug_pm_sync_init); - - #endif /* CONFIG_PM_SLEEP_SMP */ - -+int __boot_cpu_id; -+ - #endif /* CONFIG_SMP */ - - /* Boot processor state steps */ -@@ -1815,6 +1817,10 @@ void __init boot_cpu_init(void) - set_cpu_active(cpu, true); - set_cpu_present(cpu, true); - set_cpu_possible(cpu, true); -+ -+#ifdef CONFIG_SMP -+ __boot_cpu_id = cpu; -+#endif - } - - /* ---- a/kernel/module.c -+++ b/kernel/module.c -@@ -682,8 +682,12 @@ bool __is_module_percpu_address(unsigned - void *va = (void *)addr; - - if (va >= start && va < start + mod->percpu_size) { -- if (can_addr) -+ if (can_addr) { - *can_addr = (unsigned long) (va - start); -+ *can_addr += (unsigned long) -+ per_cpu_ptr(mod->percpu, -+ get_boot_cpu_id()); -+ } - preempt_enable(); - return true; - } ---- a/mm/percpu.c -+++ b/mm/percpu.c -@@ -1296,8 +1296,11 @@ bool __is_kernel_percpu_address(unsigned - void *va = (void *)addr; - - if (va >= start && va < start + static_size) { -- if (can_addr) -+ if (can_addr) { - *can_addr = (unsigned long) (va - start); -+ *can_addr += (unsigned long) -+ per_cpu_ptr(base, get_boot_cpu_id()); -+ } - return true; - } - } diff --git a/patches/lockdep-Handle-statically-initialized-PER_CPU-locks-.patch b/patches/lockdep-Handle-statically-initialized-PER_CPU-locks-.patch deleted file mode 100644 index 64a6f75e8665..000000000000 --- a/patches/lockdep-Handle-statically-initialized-PER_CPU-locks-.patch +++ /dev/null @@ -1,268 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Fri, 17 Feb 2017 19:44:39 +0100 -Subject: [PATCH] lockdep: Handle statically initialized PER_CPU locks proper - -If a PER_CPU struct which contains a spin_lock is statically initialized -via: - -DEFINE_PER_CPU(struct foo, bla) = { - .lock = __SPIN_LOCK_UNLOCKED(bla.lock) -}; - -then lockdep assigns a seperate key to each lock because the logic for -assigning a key to statically initialized locks is to use the address as -the key. With per CPU locks the address is obvioulsy different on each CPU. - -That's wrong, because all locks should have the same key. - -To solve this the following modifications are required: - - 1) Extend the is_kernel/module_percpu_addr() functions to hand back the - canonical address of the per CPU address, i.e. the per CPU address - minus the per CPU offset. - - 2) Check the lock address with these functions and if the per CPU check - matches use the returned canonical address as the lock key, so all per - CPU locks have the same key. - - 3) Move the static_obj(key) check into look_up_lock_class() so this check - can be avoided for statically initialized per CPU locks. That's - required because the canonical address fails the static_obj(key) check - for obvious reasons. - -Reported-by: Mike Galbraith <efault@gmx.de> -Cc: stable-rt@vger.kernel.org -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - include/linux/module.h | 1 + - include/linux/percpu.h | 1 + - kernel/locking/lockdep.c | 35 ++++++++++++++++++++++++----------- - kernel/module.c | 31 +++++++++++++++++++------------ - mm/percpu.c | 37 +++++++++++++++++++++++-------------- - 5 files changed, 68 insertions(+), 37 deletions(-) - ---- a/include/linux/module.h -+++ b/include/linux/module.h -@@ -493,6 +493,7 @@ static inline int module_is_live(struct - struct module *__module_text_address(unsigned long addr); - struct module *__module_address(unsigned long addr); - bool is_module_address(unsigned long addr); -+bool __is_module_percpu_address(unsigned long addr, unsigned long *can_addr); - bool is_module_percpu_address(unsigned long addr); - bool is_module_text_address(unsigned long addr); - ---- a/include/linux/percpu.h -+++ b/include/linux/percpu.h -@@ -110,6 +110,7 @@ extern int __init pcpu_page_first_chunk( - #endif - - extern void __percpu *__alloc_reserved_percpu(size_t size, size_t align); -+extern bool __is_kernel_percpu_address(unsigned long addr, unsigned long *can_addr); - extern bool is_kernel_percpu_address(unsigned long addr); - - #if !defined(CONFIG_SMP) || !defined(CONFIG_HAVE_SETUP_PER_CPU_AREA) ---- a/kernel/locking/lockdep.c -+++ b/kernel/locking/lockdep.c -@@ -660,6 +660,7 @@ look_up_lock_class(struct lockdep_map *l - struct lockdep_subclass_key *key; - struct hlist_head *hash_head; - struct lock_class *class; -+ bool is_static = false; - - if (unlikely(subclass >= MAX_LOCKDEP_SUBCLASSES)) { - debug_locks_off(); -@@ -673,10 +674,23 @@ look_up_lock_class(struct lockdep_map *l - - /* - * Static locks do not have their class-keys yet - for them the key -- * is the lock object itself: -- */ -- if (unlikely(!lock->key)) -- lock->key = (void *)lock; -+ * is the lock object itself. If the lock is in the per cpu area, -+ * the canonical address of the lock (per cpu offset removed) is -+ * used. -+ */ -+ if (unlikely(!lock->key)) { -+ unsigned long can_addr, addr = (unsigned long)lock; -+ -+ if (__is_kernel_percpu_address(addr, &can_addr)) -+ lock->key = (void *)can_addr; -+ else if (__is_module_percpu_address(addr, &can_addr)) -+ lock->key = (void *)can_addr; -+ else if (static_obj(lock)) -+ lock->key = (void *)lock; -+ else -+ return ERR_PTR(-EINVAL); -+ is_static = true; -+ } - - /* - * NOTE: the class-key must be unique. For dynamic locks, a static -@@ -708,7 +722,7 @@ look_up_lock_class(struct lockdep_map *l - } - } - -- return NULL; -+ return is_static || static_obj(lock->key) ? NULL : ERR_PTR(-EINVAL); - } - - /* -@@ -726,19 +740,18 @@ register_lock_class(struct lockdep_map * - DEBUG_LOCKS_WARN_ON(!irqs_disabled()); - - class = look_up_lock_class(lock, subclass); -- if (likely(class)) -+ if (likely(!IS_ERR_OR_NULL(class))) - goto out_set_class_cache; - - /* - * Debug-check: all keys must be persistent! -- */ -- if (!static_obj(lock->key)) { -+ */ -+ if (IS_ERR(class)) { - debug_locks_off(); - printk("INFO: trying to register non-static key.\n"); - printk("the code is fine but needs lockdep annotation.\n"); - printk("turning off the locking correctness validator.\n"); - dump_stack(); -- - return NULL; - } - -@@ -3419,7 +3432,7 @@ static int match_held_lock(struct held_l - * Clearly if the lock hasn't been acquired _ever_, we're not - * holding it either, so report failure. - */ -- if (!class) -+ if (IS_ERR_OR_NULL(class)) - return 0; - - /* -@@ -4172,7 +4185,7 @@ void lockdep_reset_lock(struct lockdep_m - * If the class exists we look it up and zap it: - */ - class = look_up_lock_class(lock, j); -- if (class) -+ if (!IS_ERR_OR_NULL(class)) - zap_class(class); - } - /* ---- a/kernel/module.c -+++ b/kernel/module.c -@@ -665,16 +665,7 @@ static void percpu_modcopy(struct module - memcpy(per_cpu_ptr(mod->percpu, cpu), from, size); - } - --/** -- * is_module_percpu_address - test whether address is from module static percpu -- * @addr: address to test -- * -- * Test whether @addr belongs to module static percpu area. -- * -- * RETURNS: -- * %true if @addr is from module static percpu area -- */ --bool is_module_percpu_address(unsigned long addr) -+bool __is_module_percpu_address(unsigned long addr, unsigned long *can_addr) - { - struct module *mod; - unsigned int cpu; -@@ -688,9 +679,11 @@ bool is_module_percpu_address(unsigned l - continue; - for_each_possible_cpu(cpu) { - void *start = per_cpu_ptr(mod->percpu, cpu); -+ void *va = (void *)addr; - -- if ((void *)addr >= start && -- (void *)addr < start + mod->percpu_size) { -+ if (va >= start && va < start + mod->percpu_size) { -+ if (can_addr) -+ *can_addr = (unsigned long) (va - start); - preempt_enable(); - return true; - } -@@ -701,6 +694,20 @@ bool is_module_percpu_address(unsigned l - return false; - } - -+/** -+ * is_module_percpu_address - test whether address is from module static percpu -+ * @addr: address to test -+ * -+ * Test whether @addr belongs to module static percpu area. -+ * -+ * RETURNS: -+ * %true if @addr is from module static percpu area -+ */ -+bool is_module_percpu_address(unsigned long addr) -+{ -+ return __is_module_percpu_address(addr, NULL); -+} -+ - #else /* ... !CONFIG_SMP */ - - static inline void __percpu *mod_percpu(struct module *mod) ---- a/mm/percpu.c -+++ b/mm/percpu.c -@@ -1284,18 +1284,7 @@ void free_percpu(void __percpu *ptr) - } - EXPORT_SYMBOL_GPL(free_percpu); - --/** -- * is_kernel_percpu_address - test whether address is from static percpu area -- * @addr: address to test -- * -- * Test whether @addr belongs to in-kernel static percpu area. Module -- * static percpu areas are not considered. For those, use -- * is_module_percpu_address(). -- * -- * RETURNS: -- * %true if @addr is from in-kernel static percpu area, %false otherwise. -- */ --bool is_kernel_percpu_address(unsigned long addr) -+bool __is_kernel_percpu_address(unsigned long addr, unsigned long *can_addr) - { - #ifdef CONFIG_SMP - const size_t static_size = __per_cpu_end - __per_cpu_start; -@@ -1304,16 +1293,36 @@ bool is_kernel_percpu_address(unsigned l - - for_each_possible_cpu(cpu) { - void *start = per_cpu_ptr(base, cpu); -+ void *va = (void *)addr; - -- if ((void *)addr >= start && (void *)addr < start + static_size) -+ if (va >= start && va < start + static_size) { -+ if (can_addr) -+ *can_addr = (unsigned long) (va - start); - return true; -- } -+ } -+ } - #endif - /* on UP, can't distinguish from other static vars, always false */ - return false; - } - - /** -+ * is_kernel_percpu_address - test whether address is from static percpu area -+ * @addr: address to test -+ * -+ * Test whether @addr belongs to in-kernel static percpu area. Module -+ * static percpu areas are not considered. For those, use -+ * is_module_percpu_address(). -+ * -+ * RETURNS: -+ * %true if @addr is from in-kernel static percpu area, %false otherwise. -+ */ -+bool is_kernel_percpu_address(unsigned long addr) -+{ -+ return __is_kernel_percpu_address(addr, NULL); -+} -+ -+/** - * per_cpu_ptr_to_phys - convert translated percpu address to physical address - * @addr: the address to be converted to physical address - * diff --git a/patches/lockdep-disable-self-test.patch b/patches/lockdep-disable-self-test.patch new file mode 100644 index 000000000000..4b751d021068 --- /dev/null +++ b/patches/lockdep-disable-self-test.patch @@ -0,0 +1,28 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Tue, 17 Oct 2017 16:36:18 +0200 +Subject: [PATCH] lockdep: disable self-test +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The self-test wasn't always 100% accurate for RT. We disabled a few +tests which failed because they had a different semantic for RT. Some +still reported false positives. Now the selftest locks up the system +during boot and it needs to be investigated… + +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + lib/Kconfig.debug | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/lib/Kconfig.debug ++++ b/lib/Kconfig.debug +@@ -1177,7 +1177,7 @@ config DEBUG_ATOMIC_SLEEP + + config DEBUG_LOCKING_API_SELFTESTS + bool "Locking API boot-time self-tests" +- depends on DEBUG_KERNEL ++ depends on DEBUG_KERNEL && !PREEMPT_RT_FULL + help + Say Y here if you want the kernel to run a short self-test during + bootup. The self-test checks whether common types of locking bugs diff --git a/patches/lockdep-no-softirq-accounting-on-rt.patch b/patches/lockdep-no-softirq-accounting-on-rt.patch index fc7e870bc411..d8e8b5b00f19 100644 --- a/patches/lockdep-no-softirq-accounting-on-rt.patch +++ b/patches/lockdep-no-softirq-accounting-on-rt.patch @@ -40,7 +40,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #if defined(CONFIG_IRQSOFF_TRACER) || \ --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c -@@ -3715,6 +3715,7 @@ static void check_flags(unsigned long fl +@@ -3778,6 +3778,7 @@ static void check_flags(unsigned long fl } } @@ -48,7 +48,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * We dont accurately track softirq state in e.g. * hardirq contexts (such as on 4KSTACKS), so only -@@ -3729,6 +3730,7 @@ static void check_flags(unsigned long fl +@@ -3792,6 +3793,7 @@ static void check_flags(unsigned long fl DEBUG_LOCKS_WARN_ON(!current->softirqs_enabled); } } diff --git a/patches/lockdep-selftest-fix-warnings-due-to-missing-PREEMPT.patch b/patches/lockdep-selftest-fix-warnings-due-to-missing-PREEMPT.patch index 3f503ad0e7a3..2ba4e59c7149 100644 --- a/patches/lockdep-selftest-fix-warnings-due-to-missing-PREEMPT.patch +++ b/patches/lockdep-selftest-fix-warnings-due-to-missing-PREEMPT.patch @@ -28,7 +28,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/lib/locking-selftest.c +++ b/lib/locking-selftest.c -@@ -590,6 +590,8 @@ GENERATE_TESTCASE(init_held_rsem) +@@ -644,6 +644,8 @@ GENERATE_TESTCASE(init_held_rtmutex); #include "locking-selftest-spin-hardirq.h" GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_spin) @@ -37,7 +37,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #include "locking-selftest-rlock-hardirq.h" GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_hard_rlock) -@@ -605,9 +607,12 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_ +@@ -659,9 +661,12 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_ #include "locking-selftest-wlock-softirq.h" GENERATE_PERMUTATIONS_2_EVENTS(irqsafe1_soft_wlock) @@ -50,7 +50,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * Enabling hardirqs with a softirq-safe lock held: */ -@@ -640,6 +645,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A +@@ -694,6 +699,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A #undef E1 #undef E2 @@ -59,7 +59,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * Enabling irqs with an irq-safe lock held: */ -@@ -663,6 +670,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A +@@ -717,6 +724,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2A #include "locking-selftest-spin-hardirq.h" GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_spin) @@ -68,7 +68,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #include "locking-selftest-rlock-hardirq.h" GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_hard_rlock) -@@ -678,6 +687,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B +@@ -732,6 +741,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B #include "locking-selftest-wlock-softirq.h" GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B_soft_wlock) @@ -77,7 +77,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #undef E1 #undef E2 -@@ -709,6 +720,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B +@@ -763,6 +774,8 @@ GENERATE_PERMUTATIONS_2_EVENTS(irqsafe2B #include "locking-selftest-spin-hardirq.h" GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_spin) @@ -86,7 +86,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #include "locking-selftest-rlock-hardirq.h" GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_hard_rlock) -@@ -724,6 +737,8 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_ +@@ -778,6 +791,8 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_ #include "locking-selftest-wlock-softirq.h" GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_soft_wlock) @@ -95,7 +95,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #undef E1 #undef E2 #undef E3 -@@ -757,6 +772,8 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_ +@@ -811,6 +826,8 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe3_ #include "locking-selftest-spin-hardirq.h" GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_spin) @@ -104,7 +104,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #include "locking-selftest-rlock-hardirq.h" GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_hard_rlock) -@@ -772,10 +789,14 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_ +@@ -826,10 +843,14 @@ GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_ #include "locking-selftest-wlock-softirq.h" GENERATE_PERMUTATIONS_3_EVENTS(irqsafe4_soft_wlock) @@ -119,7 +119,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * read-lock / write-lock irq inversion. * -@@ -838,6 +859,10 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_inver +@@ -892,6 +913,10 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_inver #undef E2 #undef E3 @@ -130,7 +130,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * read-lock / write-lock recursion that is actually safe. */ -@@ -876,6 +901,8 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_ +@@ -930,6 +955,8 @@ GENERATE_PERMUTATIONS_3_EVENTS(irq_read_ #undef E2 #undef E3 diff --git a/patches/lockdep-selftest-only-do-hardirq-context-test-for-raw-spinlock.patch b/patches/lockdep-selftest-only-do-hardirq-context-test-for-raw-spinlock.patch index 9e71bad35c2c..c39a991c2d31 100644 --- a/patches/lockdep-selftest-only-do-hardirq-context-test-for-raw-spinlock.patch +++ b/patches/lockdep-selftest-only-do-hardirq-context-test-for-raw-spinlock.patch @@ -17,7 +17,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/lib/locking-selftest.c +++ b/lib/locking-selftest.c -@@ -1858,6 +1858,7 @@ void locking_selftest(void) +@@ -1935,6 +1935,7 @@ void locking_selftest(void) printk(" --------------------------------------------------------------------------\n"); @@ -25,7 +25,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * irq-context testcases: */ -@@ -1870,6 +1871,28 @@ void locking_selftest(void) +@@ -1947,6 +1948,28 @@ void locking_selftest(void) DO_TESTCASE_6x2("irq read-recursion", irq_read_recursion); // DO_TESTCASE_6x2B("irq read-recursion #2", irq_read_recursion2); diff --git a/patches/locking-don-t-check-for-__LINUX_SPINLOCK_TYPES_H-on-.patch b/patches/locking-don-t-check-for-__LINUX_SPINLOCK_TYPES_H-on-.patch index 3c31a911a93d..1200335d1e6e 100644 --- a/patches/locking-don-t-check-for-__LINUX_SPINLOCK_TYPES_H-on-.patch +++ b/patches/locking-don-t-check-for-__LINUX_SPINLOCK_TYPES_H-on-.patch @@ -21,16 +21,14 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> arch/ia64/include/asm/spinlock_types.h | 4 ---- arch/m32r/include/asm/spinlock_types.h | 4 ---- arch/metag/include/asm/spinlock_types.h | 4 ---- - arch/mips/include/asm/spinlock_types.h | 4 ---- arch/mn10300/include/asm/spinlock_types.h | 4 ---- arch/powerpc/include/asm/spinlock_types.h | 4 ---- arch/s390/include/asm/spinlock_types.h | 4 ---- arch/sh/include/asm/spinlock_types.h | 4 ---- - arch/sparc/include/asm/spinlock_types.h | 4 ---- arch/tile/include/asm/spinlock_types.h | 4 ---- arch/xtensa/include/asm/spinlock_types.h | 4 ---- include/linux/spinlock_types_up.h | 4 ---- - 17 files changed, 68 deletions(-) + 15 files changed, 60 deletions(-) --- a/arch/alpha/include/asm/spinlock_types.h +++ b/arch/alpha/include/asm/spinlock_types.h @@ -136,19 +134,6 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> typedef struct { volatile unsigned int lock; } arch_spinlock_t; ---- a/arch/mips/include/asm/spinlock_types.h -+++ b/arch/mips/include/asm/spinlock_types.h -@@ -1,10 +1,6 @@ - #ifndef _ASM_SPINLOCK_TYPES_H - #define _ASM_SPINLOCK_TYPES_H - --#ifndef __LINUX_SPINLOCK_TYPES_H --# error "please don't include this file directly" --#endif -- - #include <linux/types.h> - - #include <asm/byteorder.h> --- a/arch/mn10300/include/asm/spinlock_types.h +++ b/arch/mn10300/include/asm/spinlock_types.h @@ -1,10 +1,6 @@ @@ -186,7 +171,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -#endif - typedef struct { - unsigned int lock; + int lock; } __attribute__ ((aligned (4))) arch_spinlock_t; --- a/arch/sh/include/asm/spinlock_types.h +++ b/arch/sh/include/asm/spinlock_types.h @@ -201,19 +186,6 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> typedef struct { volatile unsigned int lock; } arch_spinlock_t; ---- a/arch/sparc/include/asm/spinlock_types.h -+++ b/arch/sparc/include/asm/spinlock_types.h -@@ -1,10 +1,6 @@ - #ifndef __SPARC_SPINLOCK_TYPES_H - #define __SPARC_SPINLOCK_TYPES_H - --#ifndef __LINUX_SPINLOCK_TYPES_H --# error "please don't include this file directly" --#endif -- - typedef struct { - volatile unsigned char lock; - } arch_spinlock_t; --- a/arch/tile/include/asm/spinlock_types.h +++ b/arch/tile/include/asm/spinlock_types.h @@ -15,10 +15,6 @@ diff --git a/patches/locking-rt-rwlock--Make-reader-biased-rwlocks-selectable.patch b/patches/locking-rt-rwlock--Make-reader-biased-rwlocks-selectable.patch deleted file mode 100644 index da122fc7519b..000000000000 --- a/patches/locking-rt-rwlock--Make-reader-biased-rwlocks-selectable.patch +++ /dev/null @@ -1,231 +0,0 @@ -Subject: locking/rt-rwlock: Make reader biased rwlocks selectable -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 12 Jul 2017 17:04:09 +0200 - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - include/linux/rwlock_rt.h | 14 ++++---- - include/linux/rwlock_types_rt.h | 36 +++++++++++--------- - kernel/Kconfig.locks | 17 +++++++++ - kernel/locking/rt.c | 2 + - kernel/locking/rwlock-rt.c | 70 ++++++++++++++++++++++++++++++++++++++++ - 5 files changed, 116 insertions(+), 23 deletions(-) - ---- a/include/linux/rwlock_rt.h -+++ b/include/linux/rwlock_rt.h -@@ -5,13 +5,6 @@ - #error Do not include directly. Use spinlock.h - #endif - --#define rwlock_init(rwl) \ --do { \ -- static struct lock_class_key __key; \ -- \ -- __rt_rwlock_init(rwl, #rwl, &__key); \ --} while (0) -- - extern void __lockfunc rt_write_lock(rwlock_t *rwlock); - extern void __lockfunc rt_read_lock(rwlock_t *rwlock); - extern int __lockfunc rt_write_trylock(rwlock_t *rwlock); -@@ -101,6 +94,13 @@ static inline int __write_trylock_rt_irq - rt_write_unlock(lock); \ - } while (0) - -+#define rwlock_init(rwl) \ -+do { \ -+ static struct lock_class_key __key; \ -+ \ -+ __rt_rwlock_init(rwl, #rwl, &__key); \ -+} while (0) -+ - /* - * Internal functions made global for CPU pinning - */ ---- a/include/linux/rwlock_types_rt.h -+++ b/include/linux/rwlock_types_rt.h -@@ -5,6 +5,13 @@ - #error "Do not include directly. Include spinlock_types.h instead" - #endif - -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+# define RW_DEP_MAP_INIT(lockname) .dep_map = { .name = #lockname } -+#else -+# define RW_DEP_MAP_INIT(lockname) -+#endif -+ -+#ifndef CONFIG_RWLOCK_RT_READER_BIASED - /* - * rwlocks - rtmutex which allows single reader recursion - */ -@@ -16,12 +23,6 @@ typedef struct { - #endif - } rwlock_t; - --#ifdef CONFIG_DEBUG_LOCK_ALLOC --# define RW_DEP_MAP_INIT(lockname) .dep_map = { .name = #lockname } --#else --# define RW_DEP_MAP_INIT(lockname) --#endif -- - #define __RW_LOCK_UNLOCKED(name) \ - { .lock = __RT_MUTEX_INITIALIZER_SAVE_STATE(name.lock), \ - RW_DEP_MAP_INIT(name) } -@@ -29,8 +30,16 @@ typedef struct { - #define DEFINE_RWLOCK(name) \ - rwlock_t name = __RW_LOCK_UNLOCKED(name) - --#define READER_BIAS (1U << 31) --#define WRITER_BIAS (1U << 30) -+#else /* CONFIG_RWLOCK_RT_READER_BIASED */ -+ -+typedef struct rt_rw_lock rwlock_t; -+ -+#define __RW_LOCK_UNLOCKED(name) __RWLOCK_RT_INITIALIZER(name) -+ -+#define DEFINE_RWLOCK(name) \ -+ rwlock_t name = __RW_LOCK_UNLOCKED(name) -+ -+#endif /* !CONFIG_RWLOCK_RT_READER_BIASED */ - - /* - * A reader biased implementation primarily for CPU pinning. -@@ -46,6 +55,9 @@ struct rt_rw_lock { - #endif - }; - -+#define READER_BIAS (1U << 31) -+#define WRITER_BIAS (1U << 30) -+ - #define __RWLOCK_RT_INITIALIZER(name) \ - { \ - .readers = ATOMIC_INIT(READER_BIAS), \ -@@ -63,12 +75,4 @@ void __rwlock_biased_rt_init(struct rt_r - __rwlock_biased_rt_init((rwlock), #rwlock, &__key); \ - } while (0) - --int __read_rt_trylock(struct rt_rw_lock *rwlock); --void __read_rt_lock(struct rt_rw_lock *rwlock); --void __read_rt_unlock(struct rt_rw_lock *rwlock); -- --void __write_rt_lock(struct rt_rw_lock *rwlock); --int __write_rt_trylock(struct rt_rw_lock *rwlock); --void __write_rt_unlock(struct rt_rw_lock *rwlock); -- - #endif ---- a/kernel/Kconfig.locks -+++ b/kernel/Kconfig.locks -@@ -248,3 +248,20 @@ config ARCH_USE_QUEUED_RWLOCKS - config QUEUED_RWLOCKS - def_bool y if ARCH_USE_QUEUED_RWLOCKS - depends on SMP -+ -+if PREEMPT_RT_FULL -+ -+menu "RT Locking" -+ -+config RWLOCK_RT_READER_BIASED -+ bool "Reader biased RWLOCK implementation for Preempt-RT" -+ def_bool n -+ help -+ This is option provides an alternative RWLOCK implementation for -+ PREEMPT-RT. This new implementation is not writer friendly as -+ the regular RT implementation or mainline. However nothing RT -+ related should be affected. Nevertheless here is a switch in case -+ something stalls to double check. -+endmenu -+ -+endif ---- a/kernel/locking/rt.c -+++ b/kernel/locking/rt.c -@@ -198,6 +198,7 @@ void __lockfunc _mutex_unlock(struct mut - } - EXPORT_SYMBOL(_mutex_unlock); - -+#ifndef CONFIG_RWLOCK_RT_READER_BIASED - /* - * rwlock_t functions - */ -@@ -280,6 +281,7 @@ void __rt_rwlock_init(rwlock_t *rwlock, - rwlock->lock.save_state = 1; - } - EXPORT_SYMBOL(__rt_rwlock_init); -+#endif - - /** - * atomic_dec_and_mutex_lock - return holding mutex if we dec to 0 ---- a/kernel/locking/rwlock-rt.c -+++ b/kernel/locking/rwlock-rt.c -@@ -244,3 +244,73 @@ void __write_rt_unlock(struct rt_rw_lock - raw_spin_lock_irqsave(&m->wait_lock, flags); - __write_unlock_common(lock, WRITER_BIAS, flags); - } -+ -+#ifdef CONFIG_RWLOCK_RT_READER_BIASED -+ -+int __lockfunc rt_read_trylock(rwlock_t *rwlock) -+{ -+ int ret; -+ -+ migrate_disable(); -+ ret = __read_rt_trylock(rwlock); -+ if (ret) -+ rwlock_acquire_read(&rwlock->dep_map, 0, 1, _RET_IP_); -+ else -+ migrate_enable(); -+ return ret; -+} -+EXPORT_SYMBOL(rt_read_trylock); -+ -+int __lockfunc rt_write_trylock(rwlock_t *rwlock) -+{ -+ int ret; -+ -+ migrate_disable(); -+ ret = __write_rt_trylock(rwlock); -+ if (ret) -+ rwlock_acquire(&rwlock->dep_map, 0, 1, _RET_IP_); -+ else -+ migrate_enable(); -+ return ret; -+} -+EXPORT_SYMBOL(rt_write_trylock); -+ -+void __lockfunc rt_read_lock(rwlock_t *rwlock) -+{ -+ migrate_disable(); -+ rwlock_acquire_read(&rwlock->dep_map, 0, 0, _RET_IP_); -+ __read_rt_lock(rwlock); -+} -+EXPORT_SYMBOL(rt_read_lock); -+ -+void __lockfunc rt_write_lock(rwlock_t *rwlock) -+{ -+ migrate_disable(); -+ rwlock_acquire(&rwlock->dep_map, 0, 0, _RET_IP_); -+ __write_rt_lock(rwlock); -+} -+EXPORT_SYMBOL(rt_write_lock); -+ -+void __lockfunc rt_read_unlock(rwlock_t *rwlock) -+{ -+ rwlock_release(&rwlock->dep_map, 1, _RET_IP_); -+ __read_rt_unlock(rwlock); -+ migrate_enable(); -+} -+EXPORT_SYMBOL(rt_read_unlock); -+ -+void __lockfunc rt_write_unlock(rwlock_t *rwlock) -+{ -+ rwlock_release(&rwlock->dep_map, 1, _RET_IP_); -+ __write_rt_unlock(rwlock); -+ migrate_enable(); -+} -+EXPORT_SYMBOL(rt_write_unlock); -+ -+void __rt_rwlock_init(rwlock_t *rwlock, char *name, struct lock_class_key *key) -+{ -+ __rwlock_biased_rt_init(rwlock, name, key); -+} -+EXPORT_SYMBOL(__rt_rwlock_init); -+ -+#endif diff --git a/patches/locking-rtmutex--Make-inner-working-of-rt_spin_slow_lock---accessible.patch b/patches/locking-rtmutex--Make-inner-working-of-rt_spin_slow_lock---accessible.patch deleted file mode 100644 index b72578e2a8a6..000000000000 --- a/patches/locking-rtmutex--Make-inner-working-of-rt_spin_slow_lock---accessible.patch +++ /dev/null @@ -1,112 +0,0 @@ -Subject: locking/rtmutex: Make inner working of rt_spin_slow_lock() accessible -From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 12 Jul 2017 10:24:49 +0200 - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - kernel/locking/rtmutex.c | 40 ++++++++++++++++++++++------------------ - kernel/locking/rtmutex_common.h | 4 ++++ - 2 files changed, 26 insertions(+), 18 deletions(-) - ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -1045,21 +1045,16 @@ static int task_blocks_on_rt_mutex(struc - * We store the current state under p->pi_lock in p->saved_state and - * the try_to_wake_up() code handles this accordingly. - */ --static void noinline __sched rt_spin_lock_slowlock(struct rt_mutex *lock) -+void __sched rt_spin_lock_slowlock_locked(struct rt_mutex *lock, -+ struct rt_mutex_waiter *waiter, -+ unsigned long flags) - { - struct task_struct *lock_owner, *self = current; -- struct rt_mutex_waiter waiter, *top_waiter; -- unsigned long flags; -+ struct rt_mutex_waiter *top_waiter; - int ret; - -- rt_mutex_init_waiter(&waiter, true); -- -- raw_spin_lock_irqsave(&lock->wait_lock, flags); -- -- if (__try_to_take_rt_mutex(lock, self, NULL, STEAL_LATERAL)) { -- raw_spin_unlock_irqrestore(&lock->wait_lock, flags); -+ if (__try_to_take_rt_mutex(lock, self, NULL, STEAL_LATERAL)) - return; -- } - - BUG_ON(rt_mutex_owner(lock) == self); - -@@ -1074,12 +1069,12 @@ static void noinline __sched rt_spin_lo - __set_current_state_no_track(TASK_UNINTERRUPTIBLE); - raw_spin_unlock(&self->pi_lock); - -- ret = task_blocks_on_rt_mutex(lock, &waiter, self, RT_MUTEX_MIN_CHAINWALK); -+ ret = task_blocks_on_rt_mutex(lock, waiter, self, RT_MUTEX_MIN_CHAINWALK); - BUG_ON(ret); - - for (;;) { - /* Try to acquire the lock again. */ -- if (__try_to_take_rt_mutex(lock, self, &waiter, STEAL_LATERAL)) -+ if (__try_to_take_rt_mutex(lock, self, waiter, STEAL_LATERAL)) - break; - - top_waiter = rt_mutex_top_waiter(lock); -@@ -1087,9 +1082,9 @@ static void noinline __sched rt_spin_lo - - raw_spin_unlock_irqrestore(&lock->wait_lock, flags); - -- debug_rt_mutex_print_deadlock(&waiter); -+ debug_rt_mutex_print_deadlock(waiter); - -- if (top_waiter != &waiter || adaptive_wait(lock, lock_owner)) -+ if (top_waiter != waiter || adaptive_wait(lock, lock_owner)) - schedule(); - - raw_spin_lock_irqsave(&lock->wait_lock, flags); -@@ -1117,11 +1112,20 @@ static void noinline __sched rt_spin_lo - */ - fixup_rt_mutex_waiters(lock); - -- BUG_ON(rt_mutex_has_waiters(lock) && &waiter == rt_mutex_top_waiter(lock)); -- BUG_ON(!RB_EMPTY_NODE(&waiter.tree_entry)); -+ BUG_ON(rt_mutex_has_waiters(lock) && waiter == rt_mutex_top_waiter(lock)); -+ BUG_ON(!RB_EMPTY_NODE(&waiter->tree_entry)); -+} - -- raw_spin_unlock_irqrestore(&lock->wait_lock, flags); -+static void noinline __sched rt_spin_lock_slowlock(struct rt_mutex *lock) -+{ -+ struct rt_mutex_waiter waiter; -+ unsigned long flags; - -+ rt_mutex_init_waiter(&waiter, true); -+ -+ raw_spin_lock_irqsave(&lock->wait_lock, flags); -+ rt_spin_lock_slowlock_locked(lock, &waiter, flags); -+ raw_spin_unlock_irqrestore(&lock->wait_lock, flags); - debug_rt_mutex_free_waiter(&waiter); - } - -@@ -1131,7 +1135,7 @@ static bool __sched __rt_mutex_unlock_co - /* - * Slow path to release a rt_mutex spin_lock style - */ --static void noinline __sched rt_spin_lock_slowunlock(struct rt_mutex *lock) -+void __sched rt_spin_lock_slowunlock(struct rt_mutex *lock) - { - unsigned long flags; - DEFINE_WAKE_Q(wake_q); ---- a/kernel/locking/rtmutex_common.h -+++ b/kernel/locking/rtmutex_common.h -@@ -139,6 +139,10 @@ int __sched rt_mutex_slowlock_locked(str - enum rtmutex_chainwalk chwalk, - struct ww_acquire_ctx *ww_ctx, - struct rt_mutex_waiter *waiter); -+void __sched rt_spin_lock_slowlock_locked(struct rt_mutex *lock, -+ struct rt_mutex_waiter *waiter, -+ unsigned long flags); -+void __sched rt_spin_lock_slowunlock(struct rt_mutex *lock); - - #ifdef CONFIG_DEBUG_RT_MUTEXES - # include "rtmutex-debug.h" diff --git a/patches/locking-rtmutex-don-t-drop-the-wait_lock-twice.patch b/patches/locking-rtmutex-don-t-drop-the-wait_lock-twice.patch index e5a2346657e8..c4ca232027ee 100644 --- a/patches/locking-rtmutex-don-t-drop-the-wait_lock-twice.patch +++ b/patches/locking-rtmutex-don-t-drop-the-wait_lock-twice.patch @@ -19,7 +19,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c -@@ -1745,7 +1745,6 @@ int __rt_mutex_start_proxy_lock(struct r +@@ -1766,7 +1766,6 @@ int __rt_mutex_start_proxy_lock(struct r raw_spin_lock(&task->pi_lock); if (task->pi_blocked_on) { raw_spin_unlock(&task->pi_lock); diff --git a/patches/locking-rwlock-rt-do-not-save-state-multiple-times-i.patch b/patches/locking-rwlock-rt-do-not-save-state-multiple-times-i.patch deleted file mode 100644 index b5f9fc1bb79c..000000000000 --- a/patches/locking-rwlock-rt-do-not-save-state-multiple-times-i.patch +++ /dev/null @@ -1,51 +0,0 @@ -From: Mike Galbraith <efault@gmx.de> -Date: Fri, 18 Aug 2017 10:56:14 +0200 -Subject: [PATCH] locking, rwlock-rt: do not save state multiple times in - __write_rt_lock() - -Save state prior to entering the acquisition loop, otherwise we may -initially see readers, but upon releasing ->wait_lock see none, loop -back around, and having not slept, save TASK_UNINTERRUPTIBLE. - -Signed-off-by: Mike Galbraith <efault@gmx.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/locking/rwlock-rt.c | 18 ++++++++++++------ - 1 file changed, 12 insertions(+), 6 deletions(-) - ---- a/kernel/locking/rwlock-rt.c -+++ b/kernel/locking/rwlock-rt.c -@@ -190,14 +190,14 @@ void __sched __write_rt_lock(struct rt_r - /* Force readers into slow path */ - atomic_sub(READER_BIAS, &lock->readers); - -- for (;;) { -- raw_spin_lock_irqsave(&m->wait_lock, flags); -+ raw_spin_lock_irqsave(&m->wait_lock, flags); - -- raw_spin_lock(&self->pi_lock); -- self->saved_state = self->state; -- __set_current_state_no_track(TASK_UNINTERRUPTIBLE); -- raw_spin_unlock(&self->pi_lock); -+ raw_spin_lock(&self->pi_lock); -+ self->saved_state = self->state; -+ __set_current_state_no_track(TASK_UNINTERRUPTIBLE); -+ raw_spin_unlock(&self->pi_lock); - -+ for (;;) { - /* Have all readers left the critical region? */ - if (!atomic_read(&lock->readers)) { - atomic_set(&lock->readers, WRITER_BIAS); -@@ -213,6 +213,12 @@ void __sched __write_rt_lock(struct rt_r - - if (atomic_read(&lock->readers) != 0) - schedule(); -+ -+ raw_spin_lock_irqsave(&m->wait_lock, flags); -+ -+ raw_spin_lock(&self->pi_lock); -+ __set_current_state_no_track(TASK_UNINTERRUPTIBLE); -+ raw_spin_unlock(&self->pi_lock); - } - } - diff --git a/patches/md-raid5-percpu-handling-rt-aware.patch b/patches/md-raid5-percpu-handling-rt-aware.patch index 59fdfefc2ac8..9784356b6d6c 100644 --- a/patches/md-raid5-percpu-handling-rt-aware.patch +++ b/patches/md-raid5-percpu-handling-rt-aware.patch @@ -20,7 +20,7 @@ Tested-by: Udo van den Heuvel <udovdh@xs4all.nl> --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c -@@ -1986,8 +1986,9 @@ static void raid_run_ops(struct stripe_h +@@ -2065,8 +2065,9 @@ static void raid_run_ops(struct stripe_h struct raid5_percpu *percpu; unsigned long cpu; @@ -31,7 +31,7 @@ Tested-by: Udo van den Heuvel <udovdh@xs4all.nl> if (test_bit(STRIPE_OP_BIOFILL, &ops_request)) { ops_run_biofill(sh); overlap_clear++; -@@ -2043,7 +2044,8 @@ static void raid_run_ops(struct stripe_h +@@ -2125,7 +2126,8 @@ static void raid_run_ops(struct stripe_h if (test_and_clear_bit(R5_Overlap, &dev->flags)) wake_up(&sh->raid_conf->wait_for_overlap); } @@ -40,8 +40,8 @@ Tested-by: Udo van den Heuvel <udovdh@xs4all.nl> + put_cpu_light(); } - static struct stripe_head *alloc_stripe(struct kmem_cache *sc, gfp_t gfp, -@@ -6664,6 +6666,7 @@ static int raid456_cpu_up_prepare(unsign + static void free_stripe(struct kmem_cache *sc, struct stripe_head *sh) +@@ -6797,6 +6799,7 @@ static int raid456_cpu_up_prepare(unsign __func__, cpu); return -ENOMEM; } @@ -49,7 +49,7 @@ Tested-by: Udo van den Heuvel <udovdh@xs4all.nl> return 0; } -@@ -6674,7 +6677,6 @@ static int raid5_alloc_percpu(struct r5c +@@ -6807,7 +6810,6 @@ static int raid5_alloc_percpu(struct r5c conf->percpu = alloc_percpu(struct raid5_percpu); if (!conf->percpu) return -ENOMEM; @@ -59,7 +59,7 @@ Tested-by: Udo van den Heuvel <udovdh@xs4all.nl> conf->scribble_disks = max(conf->raid_disks, --- a/drivers/md/raid5.h +++ b/drivers/md/raid5.h -@@ -643,6 +643,7 @@ struct r5conf { +@@ -623,6 +623,7 @@ struct r5conf { int recovery_disabled; /* per cpu variables */ struct raid5_percpu { diff --git a/patches/mfd-syscon-atmel-smc-include-string.h.patch b/patches/mfd-syscon-atmel-smc-include-string.h.patch new file mode 100644 index 000000000000..db4e313e6feb --- /dev/null +++ b/patches/mfd-syscon-atmel-smc-include-string.h.patch @@ -0,0 +1,22 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Wed, 4 Oct 2017 09:55:58 +0200 +Subject: [PATCH] mfd: syscon: atmel-smc: include string.h + +The string.h header file is needed for the memset() definition. The RT +build fails because it is not pulled in via other header files. + +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/mfd/atmel-smc.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/mfd/atmel-smc.c ++++ b/drivers/mfd/atmel-smc.c +@@ -12,6 +12,7 @@ + */ + + #include <linux/mfd/syscon/atmel-smc.h> ++#include <linux/string.h> + + /** + * atmel_smc_cs_conf_init - initialize a SMC CS conf diff --git a/patches/mips-disable-highmem-on-rt.patch b/patches/mips-disable-highmem-on-rt.patch index 34b86bdd04e4..902e2a0ed053 100644 --- a/patches/mips-disable-highmem-on-rt.patch +++ b/patches/mips-disable-highmem-on-rt.patch @@ -11,7 +11,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig -@@ -2520,7 +2520,7 @@ config MIPS_ASID_BITS_VARIABLE +@@ -2529,7 +2529,7 @@ config MIPS_ASID_BITS_VARIABLE # config HIGHMEM bool "High Memory Support" diff --git a/patches/mm-backing-dev-don-t-disable-IRQs-in-wb_congested_pu.patch b/patches/mm-backing-dev-don-t-disable-IRQs-in-wb_congested_pu.patch index a9faebd35840..1b4eb21d14b2 100644 --- a/patches/mm-backing-dev-don-t-disable-IRQs-in-wb_congested_pu.patch +++ b/patches/mm-backing-dev-don-t-disable-IRQs-in-wb_congested_pu.patch @@ -27,7 +27,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/mm/backing-dev.c +++ b/mm/backing-dev.c -@@ -459,9 +459,9 @@ void wb_congested_put(struct bdi_writeba +@@ -482,9 +482,9 @@ void wb_congested_put(struct bdi_writeba { unsigned long flags; diff --git a/patches/mm-bounce-local-irq-save-nort.patch b/patches/mm-bounce-local-irq-save-nort.patch index de36519d141d..58d12de2f287 100644 --- a/patches/mm-bounce-local-irq-save-nort.patch +++ b/patches/mm-bounce-local-irq-save-nort.patch @@ -11,7 +11,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/block/bounce.c +++ b/block/bounce.c -@@ -55,11 +55,11 @@ static void bounce_copy_vec(struct bio_v +@@ -65,11 +65,11 @@ static void bounce_copy_vec(struct bio_v unsigned long flags; unsigned char *vto; diff --git a/patches/mm-convert-swap-to-percpu-locked.patch b/patches/mm-convert-swap-to-percpu-locked.patch index c40c2d08a062..267686e4cee0 100644 --- a/patches/mm-convert-swap-to-percpu-locked.patch +++ b/patches/mm-convert-swap-to-percpu-locked.patch @@ -27,7 +27,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> extern void lru_cache_add_file(struct page *page); --- a/mm/compaction.c +++ b/mm/compaction.c -@@ -1601,10 +1601,12 @@ static enum compact_result compact_zone( +@@ -1633,10 +1633,12 @@ static enum compact_result compact_zone( block_start_pfn(cc->migrate_pfn, cc->order); if (cc->last_migrated_pfn < current_block_start) { @@ -44,7 +44,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } --- a/mm/page_alloc.c +++ b/mm/page_alloc.c -@@ -6787,8 +6787,9 @@ void __init free_area_init(unsigned long +@@ -6918,8 +6918,9 @@ void __init free_area_init(unsigned long static int page_alloc_cpu_dead(unsigned int cpu) { @@ -74,7 +74,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * This path almost never happens for VM activity - pages are normally -@@ -242,11 +245,11 @@ void rotate_reclaimable_page(struct page +@@ -252,11 +255,11 @@ void rotate_reclaimable_page(struct page unsigned long flags; get_page(page); @@ -88,7 +88,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } } -@@ -296,12 +299,13 @@ void activate_page(struct page *page) +@@ -306,12 +309,13 @@ void activate_page(struct page *page) { page = compound_head(page); if (PageLRU(page) && !PageActive(page) && !PageUnevictable(page)) { @@ -104,7 +104,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } } -@@ -328,7 +332,7 @@ void activate_page(struct page *page) +@@ -338,7 +342,7 @@ void activate_page(struct page *page) static void __lru_cache_activate_page(struct page *page) { @@ -113,7 +113,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> int i; /* -@@ -350,7 +354,7 @@ static void __lru_cache_activate_page(st +@@ -360,7 +364,7 @@ static void __lru_cache_activate_page(st } } @@ -122,7 +122,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } /* -@@ -392,12 +396,12 @@ EXPORT_SYMBOL(mark_page_accessed); +@@ -402,12 +406,12 @@ EXPORT_SYMBOL(mark_page_accessed); static void __lru_cache_add(struct page *page) { @@ -137,7 +137,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } /** -@@ -595,9 +599,9 @@ void lru_add_drain_cpu(int cpu) +@@ -613,9 +617,9 @@ void lru_add_drain_cpu(int cpu) unsigned long flags; /* No harm done if a racing interrupt already did this */ @@ -149,7 +149,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } pvec = &per_cpu(lru_deactivate_file_pvecs, cpu); -@@ -629,11 +633,12 @@ void deactivate_file_page(struct page *p +@@ -647,11 +651,12 @@ void deactivate_file_page(struct page *p return; if (likely(get_page_unless_zero(page))) { @@ -164,19 +164,19 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } } -@@ -648,19 +653,20 @@ void deactivate_file_page(struct page *p - void deactivate_page(struct page *page) +@@ -666,19 +671,20 @@ void mark_page_lazyfree(struct page *pag { - if (PageLRU(page) && PageActive(page) && !PageUnevictable(page)) { -- struct pagevec *pvec = &get_cpu_var(lru_deactivate_pvecs); + if (PageLRU(page) && PageAnon(page) && PageSwapBacked(page) && + !PageSwapCache(page) && !PageUnevictable(page)) { +- struct pagevec *pvec = &get_cpu_var(lru_lazyfree_pvecs); + struct pagevec *pvec = &get_locked_var(swapvec_lock, -+ lru_deactivate_pvecs); ++ lru_lazyfree_pvecs); get_page(page); if (!pagevec_add(pvec, page) || PageCompound(page)) - pagevec_lru_move_fn(pvec, lru_deactivate_fn, NULL); -- put_cpu_var(lru_deactivate_pvecs); -+ put_locked_var(swapvec_lock, lru_deactivate_pvecs); + pagevec_lru_move_fn(pvec, lru_lazyfree_fn, NULL); +- put_cpu_var(lru_lazyfree_pvecs); ++ put_locked_var(swapvec_lock, lru_lazyfree_pvecs); } } diff --git a/patches/mm-disable-sloub-rt.patch b/patches/mm-disable-sloub-rt.patch index e8de9f89cbbd..523991b3e10b 100644 --- a/patches/mm-disable-sloub-rt.patch +++ b/patches/mm-disable-sloub-rt.patch @@ -13,7 +13,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/init/Kconfig +++ b/init/Kconfig -@@ -1825,6 +1825,7 @@ choice +@@ -1521,6 +1521,7 @@ choice config SLAB bool "SLAB" @@ -21,7 +21,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> select HAVE_HARDENED_USERCOPY_ALLOCATOR help The regular slab allocator that is established and known to work -@@ -1845,6 +1846,7 @@ config SLUB +@@ -1541,6 +1542,7 @@ config SLUB config SLOB depends on EXPERT bool "SLOB (Simple Allocator)" diff --git a/patches/mm-enable-slub.patch b/patches/mm-enable-slub.patch index c2962f641ae6..c5fd3dd4ef0f 100644 --- a/patches/mm-enable-slub.patch +++ b/patches/mm-enable-slub.patch @@ -8,12 +8,12 @@ move the freeing out of the lock held region. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- mm/slab.h | 4 + - mm/slub.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++-------------- - 2 files changed, 109 insertions(+), 29 deletions(-) + mm/slub.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++-------------- + 2 files changed, 110 insertions(+), 30 deletions(-) --- a/mm/slab.h +++ b/mm/slab.h -@@ -465,7 +465,11 @@ static inline void slab_post_alloc_hook( +@@ -449,7 +449,11 @@ static inline void slab_post_alloc_hook( * The slab lists for all objects. */ struct kmem_cache_node { @@ -157,7 +157,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> if (m == M_FREE) { stat(s, DEACTIVATE_EMPTY); -@@ -2157,10 +2187,10 @@ static void unfreeze_partials(struct kme +@@ -2160,10 +2190,10 @@ static void unfreeze_partials(struct kme n2 = get_node(s, page_to_nid(page)); if (n != n2) { if (n) @@ -170,7 +170,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } do { -@@ -2189,7 +2219,7 @@ static void unfreeze_partials(struct kme +@@ -2192,7 +2222,7 @@ static void unfreeze_partials(struct kme } if (n) @@ -179,7 +179,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> while (discard_page) { page = discard_page; -@@ -2228,14 +2258,21 @@ static void put_cpu_partial(struct kmem_ +@@ -2231,14 +2261,21 @@ static void put_cpu_partial(struct kmem_ pobjects = oldpage->pobjects; pages = oldpage->pages; if (drain && pobjects > s->cpu_partial) { @@ -201,7 +201,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> oldpage = NULL; pobjects = 0; pages = 0; -@@ -2307,7 +2344,22 @@ static bool has_cpu_slab(int cpu, void * +@@ -2308,7 +2345,22 @@ static bool has_cpu_slab(int cpu, void * static void flush_all(struct kmem_cache *s) { @@ -224,7 +224,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } /* -@@ -2362,10 +2414,10 @@ static unsigned long count_partial(struc +@@ -2363,10 +2415,10 @@ static unsigned long count_partial(struc unsigned long x = 0; struct page *page; @@ -237,7 +237,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return x; } #endif /* CONFIG_SLUB_DEBUG || CONFIG_SYSFS */ -@@ -2503,8 +2555,10 @@ static inline void *get_freelist(struct +@@ -2504,8 +2556,10 @@ static inline void *get_freelist(struct * already disabled (which is the case for bulk allocation). */ static void *___slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node, @@ -249,7 +249,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> void *freelist; struct page *page; -@@ -2564,6 +2618,13 @@ static void *___slab_alloc(struct kmem_c +@@ -2561,6 +2615,13 @@ static void *___slab_alloc(struct kmem_c VM_BUG_ON(!c->page->frozen); c->freelist = get_freepointer(s, freelist); c->tid = next_tid(c->tid); @@ -263,16 +263,25 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return freelist; new_slab: -@@ -2595,7 +2656,7 @@ static void *___slab_alloc(struct kmem_c - deactivate_slab(s, page, get_freepointer(s, freelist)); - c->page = NULL; - c->freelist = NULL; +@@ -2576,7 +2637,7 @@ static void *___slab_alloc(struct kmem_c + + if (unlikely(!freelist)) { + slab_out_of_memory(s, gfpflags, node); +- return NULL; ++ goto out; + } + + page = c->page; +@@ -2589,7 +2650,7 @@ static void *___slab_alloc(struct kmem_c + goto new_slab; /* Slab failed checks. Next slab needed */ + + deactivate_slab(s, page, get_freepointer(s, freelist), c); - return freelist; + goto out; } /* -@@ -2607,6 +2668,7 @@ static void *__slab_alloc(struct kmem_ca +@@ -2601,6 +2662,7 @@ static void *__slab_alloc(struct kmem_ca { void *p; unsigned long flags; @@ -280,7 +289,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> local_irq_save(flags); #ifdef CONFIG_PREEMPT -@@ -2618,8 +2680,9 @@ static void *__slab_alloc(struct kmem_ca +@@ -2612,8 +2674,9 @@ static void *__slab_alloc(struct kmem_ca c = this_cpu_ptr(s->cpu_slab); #endif @@ -291,7 +300,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return p; } -@@ -2805,7 +2868,7 @@ static void __slab_free(struct kmem_cach +@@ -2799,7 +2862,7 @@ static void __slab_free(struct kmem_cach do { if (unlikely(n)) { @@ -300,7 +309,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> n = NULL; } prior = page->freelist; -@@ -2837,7 +2900,7 @@ static void __slab_free(struct kmem_cach +@@ -2831,7 +2894,7 @@ static void __slab_free(struct kmem_cach * Otherwise the list_lock will synchronize with * other processors updating the list of slabs. */ @@ -309,7 +318,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } } -@@ -2879,7 +2942,7 @@ static void __slab_free(struct kmem_cach +@@ -2873,7 +2936,7 @@ static void __slab_free(struct kmem_cach add_partial(n, page, DEACTIVATE_TO_TAIL); stat(s, FREE_ADD_PARTIAL); } @@ -318,7 +327,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return; slab_empty: -@@ -2894,7 +2957,7 @@ static void __slab_free(struct kmem_cach +@@ -2888,7 +2951,7 @@ static void __slab_free(struct kmem_cach remove_full(s, n, page); } @@ -327,7 +336,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> stat(s, FREE_SLAB); discard_slab(s, page); } -@@ -3099,6 +3162,7 @@ int kmem_cache_alloc_bulk(struct kmem_ca +@@ -3093,6 +3156,7 @@ int kmem_cache_alloc_bulk(struct kmem_ca void **p) { struct kmem_cache_cpu *c; @@ -335,7 +344,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> int i; /* memcg and kmem_cache debug support */ -@@ -3122,7 +3186,7 @@ int kmem_cache_alloc_bulk(struct kmem_ca +@@ -3116,7 +3180,7 @@ int kmem_cache_alloc_bulk(struct kmem_ca * of re-populating per CPU c->freelist */ p[i] = ___slab_alloc(s, flags, NUMA_NO_NODE, @@ -344,7 +353,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> if (unlikely(!p[i])) goto error; -@@ -3134,6 +3198,7 @@ int kmem_cache_alloc_bulk(struct kmem_ca +@@ -3128,6 +3192,7 @@ int kmem_cache_alloc_bulk(struct kmem_ca } c->tid = next_tid(c->tid); local_irq_enable(); @@ -352,7 +361,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* Clear memory outside IRQ disabled fastpath loop */ if (unlikely(flags & __GFP_ZERO)) { -@@ -3281,7 +3346,7 @@ static void +@@ -3275,7 +3340,7 @@ static void init_kmem_cache_node(struct kmem_cache_node *n) { n->nr_partial = 0; @@ -361,7 +370,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> INIT_LIST_HEAD(&n->partial); #ifdef CONFIG_SLUB_DEBUG atomic_long_set(&n->nr_slabs, 0); -@@ -3625,6 +3690,10 @@ static void list_slab_objects(struct kme +@@ -3626,6 +3691,10 @@ static void list_slab_objects(struct kme const char *text) { #ifdef CONFIG_SLUB_DEBUG @@ -372,7 +381,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> void *addr = page_address(page); void *p; unsigned long *map = kzalloc(BITS_TO_LONGS(page->objects) * -@@ -3645,6 +3714,7 @@ static void list_slab_objects(struct kme +@@ -3646,6 +3715,7 @@ static void list_slab_objects(struct kme slab_unlock(page); kfree(map); #endif @@ -380,7 +389,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } /* -@@ -3658,7 +3728,7 @@ static void free_partial(struct kmem_cac +@@ -3659,7 +3729,7 @@ static void free_partial(struct kmem_cac struct page *page, *h; BUG_ON(irqs_disabled()); @@ -389,7 +398,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> list_for_each_entry_safe(page, h, &n->partial, lru) { if (!page->inuse) { remove_partial(n, page); -@@ -3668,7 +3738,7 @@ static void free_partial(struct kmem_cac +@@ -3669,7 +3739,7 @@ static void free_partial(struct kmem_cac "Objects remaining in %s on __kmem_cache_shutdown()"); } } @@ -398,7 +407,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> list_for_each_entry_safe(page, h, &discard, lru) discard_slab(s, page); -@@ -3912,7 +3982,7 @@ int __kmem_cache_shrink(struct kmem_cach +@@ -3913,7 +3983,7 @@ int __kmem_cache_shrink(struct kmem_cach for (i = 0; i < SHRINK_PROMOTE_MAX; i++) INIT_LIST_HEAD(promote + i); @@ -407,7 +416,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * Build lists of slabs to discard or promote. -@@ -3943,7 +4013,7 @@ int __kmem_cache_shrink(struct kmem_cach +@@ -3944,7 +4014,7 @@ int __kmem_cache_shrink(struct kmem_cach for (i = SHRINK_PROMOTE_MAX - 1; i >= 0; i--) list_splice(promote + i, &n->partial); @@ -416,7 +425,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* Release empty slabs */ list_for_each_entry_safe(page, t, &discard, lru) -@@ -4156,6 +4226,12 @@ void __init kmem_cache_init(void) +@@ -4157,6 +4227,12 @@ void __init kmem_cache_init(void) { static __initdata struct kmem_cache boot_kmem_cache, boot_kmem_cache_node; @@ -429,7 +438,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> if (debug_guardpage_minorder()) slub_max_order = 0; -@@ -4364,7 +4440,7 @@ static int validate_slab_node(struct kme +@@ -4365,7 +4441,7 @@ static int validate_slab_node(struct kme struct page *page; unsigned long flags; @@ -438,7 +447,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> list_for_each_entry(page, &n->partial, lru) { validate_slab_slab(s, page, map); -@@ -4386,7 +4462,7 @@ static int validate_slab_node(struct kme +@@ -4387,7 +4463,7 @@ static int validate_slab_node(struct kme s->name, count, atomic_long_read(&n->nr_slabs)); out: @@ -447,7 +456,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return count; } -@@ -4574,12 +4650,12 @@ static int list_locations(struct kmem_ca +@@ -4575,12 +4651,12 @@ static int list_locations(struct kmem_ca if (!atomic_long_read(&n->nr_slabs)) continue; diff --git a/patches/mm-make-vmstat-rt-aware.patch b/patches/mm-make-vmstat-rt-aware.patch index a87d95ca0cd9..042330ae6131 100644 --- a/patches/mm-make-vmstat-rt-aware.patch +++ b/patches/mm-make-vmstat-rt-aware.patch @@ -16,7 +16,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h -@@ -33,7 +33,9 @@ DECLARE_PER_CPU(struct vm_event_state, v +@@ -32,7 +32,9 @@ DECLARE_PER_CPU(struct vm_event_state, v */ static inline void __count_vm_event(enum vm_event_item item) { @@ -26,7 +26,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } static inline void count_vm_event(enum vm_event_item item) -@@ -43,7 +45,9 @@ static inline void count_vm_event(enum v +@@ -42,7 +44,9 @@ static inline void count_vm_event(enum v static inline void __count_vm_events(enum vm_event_item item, long delta) { diff --git a/patches/mm-memcontrol-Don-t-call-schedule_work_on-in-preempt.patch b/patches/mm-memcontrol-Don-t-call-schedule_work_on-in-preempt.patch index 59c4c0f0412a..684069dc27df 100644 --- a/patches/mm-memcontrol-Don-t-call-schedule_work_on-in-preempt.patch +++ b/patches/mm-memcontrol-Don-t-call-schedule_work_on-in-preempt.patch @@ -48,7 +48,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/mm/memcontrol.c +++ b/mm/memcontrol.c -@@ -1782,7 +1782,7 @@ static void drain_all_stock(struct mem_c +@@ -1806,7 +1806,7 @@ static void drain_all_stock(struct mem_c return; /* Notify other cpus that system-wide "drain" is running */ get_online_cpus(); @@ -57,7 +57,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> for_each_online_cpu(cpu) { struct memcg_stock_pcp *stock = &per_cpu(memcg_stock, cpu); struct mem_cgroup *memcg; -@@ -1799,7 +1799,7 @@ static void drain_all_stock(struct mem_c +@@ -1823,7 +1823,7 @@ static void drain_all_stock(struct mem_c schedule_work_on(cpu, &stock->work); } } diff --git a/patches/mm-memcontrol-do_not_disable_irq.patch b/patches/mm-memcontrol-do_not_disable_irq.patch index cddbaeaf4ff6..da5c359b52c7 100644 --- a/patches/mm-memcontrol-do_not_disable_irq.patch +++ b/patches/mm-memcontrol-do_not_disable_irq.patch @@ -7,8 +7,8 @@ patch converts them local locks. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - mm/memcontrol.c | 20 ++++++++++++++------ - 1 file changed, 14 insertions(+), 6 deletions(-) + mm/memcontrol.c | 24 ++++++++++++++++-------- + 1 file changed, 16 insertions(+), 8 deletions(-) --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -29,7 +29,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* Whether legacy memory+swap accounting is active */ static bool do_memsw_account(void) { -@@ -4535,12 +4538,12 @@ static int mem_cgroup_move_account(struc +@@ -4574,12 +4577,12 @@ static int mem_cgroup_move_account(struc ret = 0; @@ -44,7 +44,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> out_unlock: unlock_page(page); out: -@@ -5422,10 +5425,10 @@ void mem_cgroup_commit_charge(struct pag +@@ -5486,10 +5489,10 @@ void mem_cgroup_commit_charge(struct pag commit_charge(page, memcg, lrucare); @@ -57,16 +57,17 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (do_memsw_account() && PageSwapCache(page)) { swp_entry_t entry = { .val = page_private(page) }; -@@ -5481,14 +5484,14 @@ static void uncharge_batch(struct mem_cg +@@ -5545,7 +5548,7 @@ static void uncharge_batch(struct mem_cg memcg_oom_recover(memcg); } - local_irq_save(flags); + local_lock_irqsave(event_lock, flags); - __this_cpu_sub(memcg->stat->count[MEM_CGROUP_STAT_RSS], nr_anon); - __this_cpu_sub(memcg->stat->count[MEM_CGROUP_STAT_CACHE], nr_file); - __this_cpu_sub(memcg->stat->count[MEM_CGROUP_STAT_RSS_HUGE], nr_huge); - __this_cpu_add(memcg->stat->events[MEM_CGROUP_EVENTS_PGPGOUT], pgpgout); + __this_cpu_sub(memcg->stat->count[MEMCG_RSS], nr_anon); + __this_cpu_sub(memcg->stat->count[MEMCG_CACHE], nr_file); + __this_cpu_sub(memcg->stat->count[MEMCG_RSS_HUGE], nr_huge); +@@ -5553,7 +5556,7 @@ static void uncharge_batch(struct mem_cg + __this_cpu_add(memcg->stat->events[PGPGOUT], pgpgout); __this_cpu_add(memcg->stat->nr_page_events, nr_pages); memcg_check_events(memcg, dummy_page); - local_irq_restore(flags); @@ -74,7 +75,20 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (!mem_cgroup_is_root(memcg)) css_put_many(&memcg->css, nr_pages); -@@ -5838,6 +5841,7 @@ void mem_cgroup_swapout(struct page *pag +@@ -5712,10 +5715,10 @@ void mem_cgroup_migrate(struct page *old + + commit_charge(newpage, memcg, false); + +- local_irq_save(flags); ++ local_lock_irqsave(event_lock, flags); + mem_cgroup_charge_statistics(memcg, newpage, compound, nr_pages); + memcg_check_events(memcg, newpage); +- local_irq_restore(flags); ++ local_unlock_irqrestore(event_lock, flags); + } + + DEFINE_STATIC_KEY_FALSE(memcg_sockets_enabled_key); +@@ -5907,6 +5910,7 @@ void mem_cgroup_swapout(struct page *pag { struct mem_cgroup *memcg, *swap_memcg; unsigned short oldid; @@ -82,7 +96,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> VM_BUG_ON_PAGE(PageLRU(page), page); VM_BUG_ON_PAGE(page_count(page), page); -@@ -5878,12 +5882,16 @@ void mem_cgroup_swapout(struct page *pag +@@ -5947,12 +5951,16 @@ void mem_cgroup_swapout(struct page *pag * important here to have the interrupts disabled because it is the * only synchronisation we have for udpating the per-CPU variables. */ @@ -98,4 +112,4 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + local_unlock_irqrestore(event_lock, flags); } - /* + /** diff --git a/patches/mm-memcontrol-mem_cgroup_migrate-replace-another-loc.patch b/patches/mm-memcontrol-mem_cgroup_migrate-replace-another-loc.patch deleted file mode 100644 index 4c40b9559bb5..000000000000 --- a/patches/mm-memcontrol-mem_cgroup_migrate-replace-another-loc.patch +++ /dev/null @@ -1,29 +0,0 @@ -From: Mike Galbraith <umgwanakikbuti@gmail.com> -Date: Sun, 5 Jun 2016 08:11:13 +0200 -Subject: [PATCH] mm/memcontrol: mem_cgroup_migrate() - replace another - local_irq_disable() w. local_lock_irq() - -v4.6 grew a local_irq_disable() in mm/memcontrol.c::mem_cgroup_migrate(). -Convert it to use the existing local lock (event_lock) like the others. - -Signed-off-by: Mike Galbraith <umgwanakikbuti@gmail.com> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - mm/memcontrol.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/mm/memcontrol.c -+++ b/mm/memcontrol.c -@@ -5646,10 +5646,10 @@ void mem_cgroup_migrate(struct page *old - - commit_charge(newpage, memcg, false); - -- local_irq_save(flags); -+ local_lock_irqsave(event_lock, flags); - mem_cgroup_charge_statistics(memcg, newpage, compound, nr_pages); - memcg_check_events(memcg, newpage); -- local_irq_restore(flags); -+ local_unlock_irqrestore(event_lock, flags); - } - - DEFINE_STATIC_KEY_FALSE(memcg_sockets_enabled_key); diff --git a/patches/mm-page_alloc-reduce-lock-sections-further.patch b/patches/mm-page_alloc-reduce-lock-sections-further.patch index f6adc0f79567..a60330013037 100644 --- a/patches/mm-page_alloc-reduce-lock-sections-further.patch +++ b/patches/mm-page_alloc-reduce-lock-sections-further.patch @@ -8,8 +8,8 @@ call free_pages_bulk() outside of the percpu page allocator locks. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- - mm/page_alloc.c | 94 +++++++++++++++++++++++++++++++++++++++----------------- - 1 file changed, 66 insertions(+), 28 deletions(-) + mm/page_alloc.c | 93 +++++++++++++++++++++++++++++++++++++++----------------- + 1 file changed, 65 insertions(+), 28 deletions(-) --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -22,7 +22,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> * Assumes all pages on list are in same zone, and of same order. * count is the number of pages to free. * -@@ -1110,19 +1110,58 @@ static bool bulkfree_pcp_prepare(struct +@@ -1110,15 +1110,53 @@ static bool bulkfree_pcp_prepare(struct * pinned" detection logic. */ static void free_pcppages_bulk(struct zone *zone, int count, @@ -31,21 +31,16 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> { - int migratetype = 0; - int batch_free = 0; - unsigned long nr_scanned; bool isolated_pageblocks; + unsigned long flags; -+ -+ spin_lock_irqsave(&zone->lock, flags); - spin_lock(&zone->lock); ++ spin_lock_irqsave(&zone->lock, flags); isolated_pageblocks = has_isolate_pageblock(zone); - nr_scanned = node_page_state(zone->zone_pgdat, NR_PAGES_SCANNED); - if (nr_scanned) - __mod_node_page_state(zone->zone_pgdat, NR_PAGES_SCANNED, -nr_scanned); + while (!list_empty(list)) { + struct page *page; -+ int mt; /* migratetype of the to-be-freed page */ ++ int mt; /* migratetype of the to-be-freed page */ + + page = list_first_entry(list, struct page, lru); + /* must delete as __free_one_page list manipulates */ @@ -85,7 +80,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> while (count) { struct page *page; struct list_head *list; -@@ -1138,7 +1177,7 @@ static void free_pcppages_bulk(struct zo +@@ -1134,7 +1172,7 @@ static void free_pcppages_bulk(struct zo batch_free++; if (++migratetype == MIGRATE_PCPTYPES) migratetype = 0; @@ -94,7 +89,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } while (list_empty(list)); /* This is the only non-empty list. Free them all. */ -@@ -1146,27 +1185,12 @@ static void free_pcppages_bulk(struct zo +@@ -1142,27 +1180,12 @@ static void free_pcppages_bulk(struct zo batch_free = count; do { @@ -123,18 +118,16 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } static void free_one_page(struct zone *zone, -@@ -1175,7 +1199,9 @@ static void free_one_page(struct zone *z +@@ -1170,13 +1193,15 @@ static void free_one_page(struct zone *z + unsigned int order, int migratetype) { - unsigned long nr_scanned; - spin_lock(&zone->lock); + unsigned long flags; + + spin_lock_irqsave(&zone->lock, flags); - nr_scanned = node_page_state(zone->zone_pgdat, NR_PAGES_SCANNED); - if (nr_scanned) - __mod_node_page_state(zone->zone_pgdat, NR_PAGES_SCANNED, -nr_scanned); -@@ -1185,7 +1211,7 @@ static void free_one_page(struct zone *z + if (unlikely(has_isolate_pageblock(zone) || + is_migrate_isolate(migratetype))) { migratetype = get_pfnblock_migratetype(page, pfn); } __free_one_page(page, pfn, zone, order, migratetype); @@ -143,7 +136,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } static void __meminit __init_single_page(struct page *page, unsigned long pfn, -@@ -2299,16 +2325,18 @@ static int rmqueue_bulk(struct zone *zon +@@ -2383,16 +2408,18 @@ static int rmqueue_bulk(struct zone *zon void drain_zone_pages(struct zone *zone, struct per_cpu_pages *pcp) { unsigned long flags; @@ -163,7 +156,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } #endif -@@ -2324,16 +2352,21 @@ static void drain_pages_zone(unsigned in +@@ -2408,16 +2435,21 @@ static void drain_pages_zone(unsigned in unsigned long flags; struct per_cpu_pageset *pset; struct per_cpu_pages *pcp; @@ -187,7 +180,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } /* -@@ -2556,8 +2589,13 @@ void free_hot_cold_page(struct page *pag +@@ -2655,8 +2687,13 @@ void free_hot_cold_page(struct page *pag pcp->count++; if (pcp->count >= pcp->high) { unsigned long batch = READ_ONCE(pcp->batch); diff --git a/patches/mm-page_alloc-rt-friendly-per-cpu-pages.patch b/patches/mm-page_alloc-rt-friendly-per-cpu-pages.patch index 2e38cdb16267..db4654d4e0a7 100644 --- a/patches/mm-page_alloc-rt-friendly-per-cpu-pages.patch +++ b/patches/mm-page_alloc-rt-friendly-per-cpu-pages.patch @@ -44,7 +44,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> int page_group_by_mobility_disabled __read_mostly; #ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT -@@ -1258,10 +1271,10 @@ static void __free_pages_ok(struct page +@@ -1249,10 +1262,10 @@ static void __free_pages_ok(struct page return; migratetype = get_pfnblock_migratetype(page, pfn); @@ -57,7 +57,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } static void __init __free_pages_boot_core(struct page *page, unsigned int order) -@@ -2288,14 +2301,14 @@ void drain_zone_pages(struct zone *zone, +@@ -2372,14 +2385,14 @@ void drain_zone_pages(struct zone *zone, unsigned long flags; int to_drain, batch; @@ -74,7 +74,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } #endif -@@ -2312,7 +2325,7 @@ static void drain_pages_zone(unsigned in +@@ -2396,7 +2409,7 @@ static void drain_pages_zone(unsigned in struct per_cpu_pageset *pset; struct per_cpu_pages *pcp; @@ -83,7 +83,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> pset = per_cpu_ptr(zone->pageset, cpu); pcp = &pset->pcp; -@@ -2320,7 +2333,7 @@ static void drain_pages_zone(unsigned in +@@ -2404,7 +2417,7 @@ static void drain_pages_zone(unsigned in free_pcppages_bulk(zone, pcp->count, pcp); pcp->count = 0; } @@ -92,7 +92,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } /* -@@ -2355,6 +2368,7 @@ void drain_local_pages(struct zone *zone +@@ -2439,6 +2452,7 @@ void drain_local_pages(struct zone *zone drain_pages(cpu); } @@ -100,7 +100,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> static void drain_local_pages_wq(struct work_struct *work) { /* -@@ -2368,6 +2382,7 @@ static void drain_local_pages_wq(struct +@@ -2452,6 +2466,7 @@ static void drain_local_pages_wq(struct drain_local_pages(NULL); preempt_enable(); } @@ -108,7 +108,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * Spill all the per-cpu pages from all CPUs back into the buddy allocator. -@@ -2438,7 +2453,14 @@ void drain_all_pages(struct zone *zone) +@@ -2522,7 +2537,14 @@ void drain_all_pages(struct zone *zone) else cpumask_clear_cpu(cpu, &cpus_with_pcps); } @@ -124,7 +124,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> for_each_cpu(cpu, &cpus_with_pcps) { struct work_struct *work = per_cpu_ptr(&pcpu_drain, cpu); INIT_WORK(work, drain_local_pages_wq); -@@ -2446,6 +2468,7 @@ void drain_all_pages(struct zone *zone) +@@ -2530,6 +2552,7 @@ void drain_all_pages(struct zone *zone) } for_each_cpu(cpu, &cpus_with_pcps) flush_work(per_cpu_ptr(&pcpu_drain, cpu)); @@ -132,7 +132,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> mutex_unlock(&pcpu_drain_mutex); } -@@ -2507,7 +2530,7 @@ void free_hot_cold_page(struct page *pag +@@ -2606,7 +2629,7 @@ void free_hot_cold_page(struct page *pag migratetype = get_pfnblock_migratetype(page, pfn); set_pcppage_migratetype(page, migratetype); @@ -141,7 +141,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> __count_vm_event(PGFREE); /* -@@ -2538,7 +2561,7 @@ void free_hot_cold_page(struct page *pag +@@ -2637,7 +2660,7 @@ void free_hot_cold_page(struct page *pag } out: @@ -150,7 +150,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } /* -@@ -2695,7 +2718,7 @@ static struct page *rmqueue_pcplist(stru +@@ -2794,7 +2817,7 @@ static struct page *rmqueue_pcplist(stru struct page *page; unsigned long flags; @@ -159,7 +159,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> pcp = &this_cpu_ptr(zone->pageset)->pcp; list = &pcp->lists[migratetype]; page = __rmqueue_pcplist(zone, migratetype, cold, pcp, list); -@@ -2703,7 +2726,7 @@ static struct page *rmqueue_pcplist(stru +@@ -2802,7 +2825,7 @@ static struct page *rmqueue_pcplist(stru __count_zid_vm_events(PGALLOC, page_zonenum(page), 1 << order); zone_statistics(preferred_zone, zone); } @@ -168,7 +168,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return page; } -@@ -2730,7 +2753,7 @@ struct page *rmqueue(struct zone *prefer +@@ -2829,7 +2852,7 @@ struct page *rmqueue(struct zone *prefer * allocate greater than order-1 page units with __GFP_NOFAIL. */ WARN_ON_ONCE((gfp_flags & __GFP_NOFAIL) && (order > 1)); @@ -177,7 +177,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> do { page = NULL; -@@ -2750,14 +2773,14 @@ struct page *rmqueue(struct zone *prefer +@@ -2849,14 +2872,14 @@ struct page *rmqueue(struct zone *prefer __count_zid_vm_events(PGALLOC, page_zonenum(page), 1 << order); zone_statistics(preferred_zone, zone); @@ -194,7 +194,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return NULL; } -@@ -7591,7 +7614,7 @@ void zone_pcp_reset(struct zone *zone) +@@ -7754,7 +7777,7 @@ void zone_pcp_reset(struct zone *zone) struct per_cpu_pageset *pset; /* avoid races with drain_pages() */ @@ -203,7 +203,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> if (zone->pageset != &boot_pageset) { for_each_online_cpu(cpu) { pset = per_cpu_ptr(zone->pageset, cpu); -@@ -7600,7 +7623,7 @@ void zone_pcp_reset(struct zone *zone) +@@ -7763,7 +7786,7 @@ void zone_pcp_reset(struct zone *zone) free_percpu(zone->pageset); zone->pageset = &boot_pageset; } diff --git a/patches/mm-perform-lru_add_drain_all-remotely.patch b/patches/mm-perform-lru_add_drain_all-remotely.patch index 10f37c213381..a223409ebd17 100644 --- a/patches/mm-perform-lru_add_drain_all-remotely.patch +++ b/patches/mm-perform-lru_add_drain_all-remotely.patch @@ -19,12 +19,12 @@ Signed-off-by: Rik van Riel <riel@redhat.com> Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - mm/swap.c | 37 ++++++++++++++++++++++++++++++------- - 1 file changed, 30 insertions(+), 7 deletions(-) + mm/swap.c | 36 ++++++++++++++++++++++++++++++------ + 1 file changed, 30 insertions(+), 6 deletions(-) --- a/mm/swap.c +++ b/mm/swap.c -@@ -599,9 +599,15 @@ void lru_add_drain_cpu(int cpu) +@@ -617,9 +617,15 @@ void lru_add_drain_cpu(int cpu) unsigned long flags; /* No harm done if a racing interrupt already did this */ @@ -40,7 +40,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } pvec = &per_cpu(lru_deactivate_file_pvecs, cpu); -@@ -669,6 +675,16 @@ void lru_add_drain(void) +@@ -687,6 +693,16 @@ void lru_add_drain(void) local_unlock_cpu(swapvec_lock); } @@ -57,7 +57,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static void lru_add_drain_per_cpu(struct work_struct *dummy) { lru_add_drain(); -@@ -676,6 +692,16 @@ static void lru_add_drain_per_cpu(struct +@@ -694,6 +710,16 @@ static void lru_add_drain_per_cpu(struct static DEFINE_PER_CPU(struct work_struct, lru_add_drain_work); @@ -71,19 +71,19 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +} +#endif + - void lru_add_drain_all(void) + void lru_add_drain_all_cpuslocked(void) { static DEFINE_MUTEX(lock); -@@ -694,21 +720,18 @@ void lru_add_drain_all(void) +@@ -711,21 +737,19 @@ void lru_add_drain_all_cpuslocked(void) cpumask_clear(&has_work); for_each_online_cpu(cpu) { - struct work_struct *work = &per_cpu(lru_add_drain_work, cpu); -- + if (pagevec_count(&per_cpu(lru_add_pvec, cpu)) || pagevec_count(&per_cpu(lru_rotate_pvecs, cpu)) || pagevec_count(&per_cpu(lru_deactivate_file_pvecs, cpu)) || - pagevec_count(&per_cpu(lru_deactivate_pvecs, cpu)) || + pagevec_count(&per_cpu(lru_lazyfree_pvecs, cpu)) || - need_activate_page_drain(cpu)) { - INIT_WORK(work, lru_add_drain_per_cpu); - queue_work_on(cpu, mm_percpu_wq, work); @@ -98,5 +98,5 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> flush_work(&per_cpu(lru_add_drain_work, cpu)); +#endif - put_online_cpus(); mutex_unlock(&lock); + } diff --git a/patches/mm-rt-kmap-atomic-scheduling.patch b/patches/mm-rt-kmap-atomic-scheduling.patch index 9ef4f9e4aae9..6af4e0d8f8fa 100644 --- a/patches/mm-rt-kmap-atomic-scheduling.patch +++ b/patches/mm-rt-kmap-atomic-scheduling.patch @@ -30,15 +30,15 @@ Link: http://lkml.kernel.org/r/1311842631.5890.208.camel@twins --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c -@@ -37,6 +37,7 @@ - #include <linux/uaccess.h> +@@ -38,6 +38,7 @@ #include <linux/io.h> #include <linux/kdebug.h> + #include <linux/syscalls.h> +#include <linux/highmem.h> #include <asm/pgtable.h> #include <asm/ldt.h> -@@ -196,6 +197,35 @@ start_thread(struct pt_regs *regs, unsig +@@ -198,6 +199,35 @@ start_thread(struct pt_regs *regs, unsig } EXPORT_SYMBOL_GPL(start_thread); @@ -74,7 +74,7 @@ Link: http://lkml.kernel.org/r/1311842631.5890.208.camel@twins /* * switch_to(x,y) should switch tasks from x to y. -@@ -271,6 +301,8 @@ EXPORT_SYMBOL_GPL(start_thread); +@@ -273,6 +303,8 @@ EXPORT_SYMBOL_GPL(start_thread); task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT)) __switch_to_xtra(prev_p, next_p, tss); @@ -229,7 +229,7 @@ Link: http://lkml.kernel.org/r/1311842631.5890.208.camel@twins /* task_struct member predeclarations (sorted alphabetically): */ struct audit_context; -@@ -1058,6 +1059,12 @@ struct task_struct { +@@ -1093,6 +1094,12 @@ struct task_struct { int softirq_nestcnt; unsigned int softirqs_raised; #endif @@ -244,7 +244,7 @@ Link: http://lkml.kernel.org/r/1311842631.5890.208.camel@twins #endif --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h -@@ -24,6 +24,7 @@ static __always_inline void pagefault_di +@@ -184,6 +184,7 @@ static __always_inline void pagefault_di */ static inline void pagefault_disable(void) { @@ -252,7 +252,7 @@ Link: http://lkml.kernel.org/r/1311842631.5890.208.camel@twins pagefault_disabled_inc(); /* * make sure to have issued the store before a pagefault -@@ -40,6 +41,7 @@ static inline void pagefault_enable(void +@@ -200,6 +201,7 @@ static inline void pagefault_enable(void */ barrier(); pagefault_disabled_dec(); diff --git a/patches/mm-swap-don-t-disable-preemption-while-taking-the-pe.patch b/patches/mm-swap-don-t-disable-preemption-while-taking-the-pe.patch deleted file mode 100644 index e61ed54e3cf6..000000000000 --- a/patches/mm-swap-don-t-disable-preemption-while-taking-the-pe.patch +++ /dev/null @@ -1,45 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Fri, 23 Jun 2017 11:43:30 +0200 -Subject: [PATCH] mm, swap: don't disable preemption while taking the per-CPU - cache - -get_cpu_var() disables preemption and returns the per-CPU version of the -variable. Disabling preemption is useful to ensure atomic access to the -variable within the critical section. -In this case however, after the per-CPU version of the variable is -obtained the ->free_lock is acquired. For that reason it seems the raw -accessor could be used. It only seems that ->slots_ret should be -retested (because with disabled preemption this variable can not be set -to NULL otherwise). -This popped up during PREEMPT-RT testing because it tries to take -spinlocks in a preempt disabled section. - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - mm/swap_slots.c | 5 ++--- - 1 file changed, 2 insertions(+), 3 deletions(-) - ---- a/mm/swap_slots.c -+++ b/mm/swap_slots.c -@@ -267,11 +267,11 @@ int free_swap_slot(swp_entry_t entry) - { - struct swap_slots_cache *cache; - -- cache = &get_cpu_var(swp_slots); -+ cache = raw_cpu_ptr(&swp_slots); - if (use_swap_slot_cache && cache->slots_ret) { - spin_lock_irq(&cache->free_lock); - /* Swap slots cache may be deactivated before acquiring lock */ -- if (!use_swap_slot_cache) { -+ if (!use_swap_slot_cache || !cache->slots_ret) { - spin_unlock_irq(&cache->free_lock); - goto direct_free; - } -@@ -291,7 +291,6 @@ int free_swap_slot(swp_entry_t entry) - direct_free: - swapcache_free_entries(&entry, 1); - } -- put_cpu_var(swp_slots); - - return 0; - } diff --git a/patches/mm-vmalloc-use-get-cpu-light.patch b/patches/mm-vmalloc-use-get-cpu-light.patch index 38f2ce4b8a3b..1280a8f8b851 100644 --- a/patches/mm-vmalloc-use-get-cpu-light.patch +++ b/patches/mm-vmalloc-use-get-cpu-light.patch @@ -12,7 +12,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/mm/vmalloc.c +++ b/mm/vmalloc.c -@@ -866,7 +866,7 @@ static void *new_vmap_block(unsigned int +@@ -867,7 +867,7 @@ static void *new_vmap_block(unsigned int struct vmap_block *vb; struct vmap_area *va; unsigned long vb_idx; @@ -21,7 +21,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> void *vaddr; node = numa_node_id(); -@@ -909,11 +909,12 @@ static void *new_vmap_block(unsigned int +@@ -910,11 +910,12 @@ static void *new_vmap_block(unsigned int BUG_ON(err); radix_tree_preload_end(); @@ -36,7 +36,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return vaddr; } -@@ -982,6 +983,7 @@ static void *vb_alloc(unsigned long size +@@ -983,6 +984,7 @@ static void *vb_alloc(unsigned long size struct vmap_block *vb; void *vaddr = NULL; unsigned int order; @@ -44,7 +44,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> BUG_ON(offset_in_page(size)); BUG_ON(size > PAGE_SIZE*VMAP_MAX_ALLOC); -@@ -996,7 +998,8 @@ static void *vb_alloc(unsigned long size +@@ -997,7 +999,8 @@ static void *vb_alloc(unsigned long size order = get_order(size); rcu_read_lock(); @@ -54,7 +54,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> list_for_each_entry_rcu(vb, &vbq->free, free_list) { unsigned long pages_off; -@@ -1019,7 +1022,7 @@ static void *vb_alloc(unsigned long size +@@ -1020,7 +1023,7 @@ static void *vb_alloc(unsigned long size break; } diff --git a/patches/mm-workingset-do-not-protect-workingset_shadow_nodes.patch b/patches/mm-workingset-do-not-protect-workingset_shadow_nodes.patch index 8d6ea6c2e3b0..237af2b875c1 100644 --- a/patches/mm-workingset-do-not-protect-workingset_shadow_nodes.patch +++ b/patches/mm-workingset-do-not-protect-workingset_shadow_nodes.patch @@ -92,7 +92,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> spin_unlock_irq(&mapping->tree_lock); --- a/mm/workingset.c +++ b/mm/workingset.c -@@ -339,9 +339,10 @@ void workingset_activation(struct page * +@@ -337,9 +337,10 @@ void workingset_activation(struct page * * point where they would still be useful. */ @@ -105,7 +105,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> { struct address_space *mapping = private; -@@ -359,10 +360,10 @@ void workingset_update_node(struct radix +@@ -357,10 +358,10 @@ void workingset_update_node(struct radix */ if (node->count && node->count == node->exceptional) { if (list_empty(&node->private_list)) @@ -118,7 +118,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } } -@@ -374,9 +375,9 @@ static unsigned long count_shadow_nodes( +@@ -372,9 +373,9 @@ static unsigned long count_shadow_nodes( unsigned long cache; /* list_lru lock nests inside IRQ-safe mapping->tree_lock */ @@ -131,9 +131,9 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * Approximate a reasonable limit for the radix tree nodes -@@ -478,15 +479,15 @@ static enum lru_status shadow_lru_isolat - mem_cgroup_inc_page_stat(virt_to_page(node), - MEMCG_WORKINGSET_NODERECLAIM); +@@ -474,15 +475,15 @@ static enum lru_status shadow_lru_isolat + goto out_invalid; + inc_lruvec_page_state(virt_to_page(node), WORKINGSET_NODERECLAIM); __radix_tree_delete_node(&mapping->page_tree, node, - workingset_update_node, mapping); + __workingset_update_node, mapping); @@ -150,7 +150,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> spin_lock(lru_lock); return ret; } -@@ -497,9 +498,9 @@ static unsigned long scan_shadow_nodes(s +@@ -493,9 +494,9 @@ static unsigned long scan_shadow_nodes(s unsigned long ret; /* list_lru lock nests inside IRQ-safe mapping->tree_lock */ @@ -163,7 +163,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return ret; } -@@ -537,7 +538,7 @@ static int __init workingset_init(void) +@@ -533,7 +534,7 @@ static int __init workingset_init(void) pr_info("workingset: timestamp_bits=%d max_order=%d bucket_order=%u\n", timestamp_bits, max_order, bucket_order); @@ -172,7 +172,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (ret) goto err; ret = register_shrinker(&workingset_shadow_shrinker); -@@ -545,7 +546,7 @@ static int __init workingset_init(void) +@@ -541,7 +542,7 @@ static int __init workingset_init(void) goto err_list_lru; return 0; err_list_lru: diff --git a/patches/mm_zsmalloc_copy_with_get_cpu_var_and_locking.patch b/patches/mm_zsmalloc_copy_with_get_cpu_var_and_locking.patch index 8c42f6781770..41f9e21496be 100644 --- a/patches/mm_zsmalloc_copy_with_get_cpu_var_and_locking.patch +++ b/patches/mm_zsmalloc_copy_with_get_cpu_var_and_locking.patch @@ -49,7 +49,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * Object location (<PFN>, <obj_idx>) is encoded as * as single (unsigned long) handle value. -@@ -323,7 +337,7 @@ static void SetZsPageMovable(struct zs_p +@@ -320,7 +334,7 @@ static void SetZsPageMovable(struct zs_p static int create_cache(struct zs_pool *pool) { @@ -58,7 +58,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> 0, 0, NULL); if (!pool->handle_cachep) return 1; -@@ -347,10 +361,27 @@ static void destroy_cache(struct zs_pool +@@ -344,10 +358,27 @@ static void destroy_cache(struct zs_pool static unsigned long cache_alloc_handle(struct zs_pool *pool, gfp_t gfp) { @@ -88,7 +88,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static void cache_free_handle(struct zs_pool *pool, unsigned long handle) { kmem_cache_free(pool->handle_cachep, (void *)handle); -@@ -369,12 +400,18 @@ static void cache_free_zspage(struct zs_ +@@ -366,12 +397,18 @@ static void cache_free_zspage(struct zs_ static void record_obj(unsigned long handle, unsigned long obj) { @@ -107,7 +107,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } /* zpool driver */ -@@ -463,6 +500,7 @@ MODULE_ALIAS("zpool-zsmalloc"); +@@ -460,6 +497,7 @@ MODULE_ALIAS("zpool-zsmalloc"); /* per-cpu VM mapping areas for zspage accesses that cross page boundaries */ static DEFINE_PER_CPU(struct mapping_area, zs_map_area); @@ -115,7 +115,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static bool is_zspage_isolated(struct zspage *zspage) { -@@ -898,7 +936,13 @@ static unsigned long location_to_obj(str +@@ -895,7 +933,13 @@ static unsigned long location_to_obj(str static unsigned long handle_to_obj(unsigned long handle) { @@ -129,7 +129,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } static unsigned long obj_to_head(struct page *page, void *obj) -@@ -912,22 +956,46 @@ static unsigned long obj_to_head(struct +@@ -909,22 +953,46 @@ static unsigned long obj_to_head(struct static inline int testpin_tag(unsigned long handle) { @@ -176,7 +176,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } static void reset_page(struct page *page) -@@ -1376,7 +1444,7 @@ void *zs_map_object(struct zs_pool *pool +@@ -1362,7 +1430,7 @@ void *zs_map_object(struct zs_pool *pool class = pool->size_class[class_idx]; off = (class->size * obj_idx) & ~PAGE_MASK; @@ -185,7 +185,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> area->vm_mm = mm; if (off + class->size <= PAGE_SIZE) { /* this object is contained entirely within a page */ -@@ -1430,7 +1498,7 @@ void zs_unmap_object(struct zs_pool *poo +@@ -1416,7 +1484,7 @@ void zs_unmap_object(struct zs_pool *poo __zs_unmap_object(area, pages, off, class->size); } diff --git a/patches/mmci-remove-bogus-irq-save.patch b/patches/mmci-remove-bogus-irq-save.patch index 6ee92924ebe8..f7f4487aefab 100644 --- a/patches/mmci-remove-bogus-irq-save.patch +++ b/patches/mmci-remove-bogus-irq-save.patch @@ -12,7 +12,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c -@@ -1204,15 +1204,12 @@ static irqreturn_t mmci_pio_irq(int irq, +@@ -1200,15 +1200,12 @@ static irqreturn_t mmci_pio_irq(int irq, struct sg_mapping_iter *sg_miter = &host->sg_miter; struct variant_data *variant = host->variant; void __iomem *base = host->base; @@ -28,7 +28,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> do { unsigned int remain, len; char *buffer; -@@ -1252,8 +1249,6 @@ static irqreturn_t mmci_pio_irq(int irq, +@@ -1248,8 +1245,6 @@ static irqreturn_t mmci_pio_irq(int irq, sg_miter_stop(sg_miter); diff --git a/patches/net-Have-__napi_schedule_irqoff-disable-interrupts-o.patch b/patches/net-Have-__napi_schedule_irqoff-disable-interrupts-o.patch index 3f670877d50f..7531bfe218e7 100644 --- a/patches/net-Have-__napi_schedule_irqoff-disable-interrupts-o.patch +++ b/patches/net-Have-__napi_schedule_irqoff-disable-interrupts-o.patch @@ -50,7 +50,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> { --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -4972,6 +4972,7 @@ bool napi_schedule_prep(struct napi_stru +@@ -5196,6 +5196,7 @@ bool napi_schedule_prep(struct napi_stru } EXPORT_SYMBOL(napi_schedule_prep); @@ -58,7 +58,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /** * __napi_schedule_irqoff - schedule for receive * @n: entry to schedule -@@ -4983,6 +4984,7 @@ void __napi_schedule_irqoff(struct napi_ +@@ -5207,6 +5208,7 @@ void __napi_schedule_irqoff(struct napi_ ____napi_schedule(this_cpu_ptr(&softnet_data), n); } EXPORT_SYMBOL(__napi_schedule_irqoff); diff --git a/patches/net-Qdisc-use-a-seqlock-instead-seqcount.patch b/patches/net-Qdisc-use-a-seqlock-instead-seqcount.patch index 2ebf380ccc0d..f240506e3db4 100644 --- a/patches/net-Qdisc-use-a-seqlock-instead-seqcount.patch +++ b/patches/net-Qdisc-use-a-seqlock-instead-seqcount.patch @@ -98,15 +98,15 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +#endif --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h -@@ -10,6 +10,7 @@ - #include <linux/dynamic_queue_limits.h> +@@ -12,6 +12,7 @@ + #include <linux/refcount.h> #include <net/gen_stats.h> #include <net/rtnetlink.h> +#include <net/net_seq_lock.h> struct Qdisc_ops; struct qdisc_walker; -@@ -86,7 +87,7 @@ struct Qdisc { +@@ -89,7 +90,7 @@ struct Qdisc { struct sk_buff *gso_skb ____cacheline_aligned_in_smp; struct qdisc_skb_head q; struct gnet_stats_basic_packed bstats; @@ -115,9 +115,9 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> struct gnet_stats_queue qstats; unsigned long state; struct Qdisc *next_sched; -@@ -98,13 +99,22 @@ struct Qdisc { - spinlock_t busylock ____cacheline_aligned_in_smp; - }; +@@ -108,13 +109,22 @@ static inline void qdisc_refcount_inc(st + refcount_inc(&qdisc->refcnt); + } -static inline bool qdisc_is_running(const struct Qdisc *qdisc) +static inline bool qdisc_is_running(struct Qdisc *qdisc) @@ -139,7 +139,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (qdisc_is_running(qdisc)) return false; /* Variant of write_seqcount_begin() telling lockdep a trylock -@@ -113,11 +123,16 @@ static inline bool qdisc_run_begin(struc +@@ -123,11 +133,16 @@ static inline bool qdisc_run_begin(struc raw_write_seqcount_begin(&qdisc->running); seqcount_acquire(&qdisc->running.dep_map, 0, 1, _RET_IP_); return true; @@ -156,7 +156,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } static inline bool qdisc_may_bulk(const struct Qdisc *qdisc) -@@ -308,7 +323,7 @@ static inline spinlock_t *qdisc_root_sle +@@ -337,7 +352,7 @@ static inline spinlock_t *qdisc_root_sle return qdisc_lock(root); } @@ -229,7 +229,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> struct gnet_stats_basic_packed *b) --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c -@@ -980,7 +980,7 @@ static struct Qdisc *qdisc_create(struct +@@ -988,7 +988,7 @@ static struct Qdisc *qdisc_create(struct rcu_assign_pointer(sch->stab, stab); } if (tca[TCA_RATE]) { diff --git a/patches/net-add-a-lock-around-icmp_sk.patch b/patches/net-add-a-lock-around-icmp_sk.patch index f4b60069faf2..4d552af76e03 100644 --- a/patches/net-add-a-lock-around-icmp_sk.patch +++ b/patches/net-add-a-lock-around-icmp_sk.patch @@ -47,7 +47,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> local_bh_enable(); } -@@ -673,6 +678,7 @@ void icmp_send(struct sk_buff *skb_in, i +@@ -656,6 +661,7 @@ void icmp_send(struct sk_buff *skb_in, i /* Needed by both icmp_global_allow and icmp_xmit_lock */ local_bh_disable(); @@ -55,7 +55,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* Check global sysctl_icmp_msgs_per_sec ratelimit, unless * incoming dev is loopback. If outgoing dev change to not be -@@ -761,6 +767,7 @@ void icmp_send(struct sk_buff *skb_in, i +@@ -744,6 +750,7 @@ void icmp_send(struct sk_buff *skb_in, i out_unlock: icmp_xmit_unlock(sk); out_bh_enable: diff --git a/patches/net-add-back-the-missing-serialization-in-ip_send_un.patch b/patches/net-add-back-the-missing-serialization-in-ip_send_un.patch index 4d66b9506f4c..2103a23e8ec3 100644 --- a/patches/net-add-back-the-missing-serialization-in-ip_send_un.patch +++ b/patches/net-add-back-the-missing-serialization-in-ip_send_un.patch @@ -50,7 +50,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #include <net/net_namespace.h> #include <net/icmp.h> -@@ -583,6 +584,7 @@ void tcp_v4_send_check(struct sock *sk, +@@ -582,6 +583,7 @@ void tcp_v4_send_check(struct sock *sk, } EXPORT_SYMBOL(tcp_v4_send_check); @@ -58,7 +58,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * This routine will send an RST to the other tcp. * -@@ -711,6 +713,7 @@ static void tcp_v4_send_reset(const stru +@@ -710,6 +712,7 @@ static void tcp_v4_send_reset(const stru arg.tos = ip_hdr(skb)->tos; arg.uid = sock_net_uid(net, sk && sk_fullsock(sk) ? sk : NULL); @@ -66,7 +66,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> local_bh_disable(); ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk), skb, &TCP_SKB_CB(skb)->header.h4.opt, -@@ -720,6 +723,7 @@ static void tcp_v4_send_reset(const stru +@@ -719,6 +722,7 @@ static void tcp_v4_send_reset(const stru __TCP_INC_STATS(net, TCP_MIB_OUTSEGS); __TCP_INC_STATS(net, TCP_MIB_OUTRSTS); local_bh_enable(); @@ -74,7 +74,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #ifdef CONFIG_TCP_MD5SIG out: -@@ -797,6 +801,7 @@ static void tcp_v4_send_ack(const struct +@@ -796,6 +800,7 @@ static void tcp_v4_send_ack(const struct arg.bound_dev_if = oif; arg.tos = tos; arg.uid = sock_net_uid(net, sk_fullsock(sk) ? sk : NULL); @@ -82,7 +82,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> local_bh_disable(); ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk), skb, &TCP_SKB_CB(skb)->header.h4.opt, -@@ -805,6 +810,7 @@ static void tcp_v4_send_ack(const struct +@@ -804,6 +809,7 @@ static void tcp_v4_send_ack(const struct __TCP_INC_STATS(net, TCP_MIB_OUTSEGS); local_bh_enable(); diff --git a/patches/net-core-cpuhotplug-drain-input_pkt_queue-lockless.patch b/patches/net-core-cpuhotplug-drain-input_pkt_queue-lockless.patch index 07edeb3da1ec..181706640532 100644 --- a/patches/net-core-cpuhotplug-drain-input_pkt_queue-lockless.patch +++ b/patches/net-core-cpuhotplug-drain-input_pkt_queue-lockless.patch @@ -35,7 +35,7 @@ Cc: stable-rt@vger.kernel.org --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -8108,7 +8108,7 @@ static int dev_cpu_dead(unsigned int old +@@ -8370,7 +8370,7 @@ static int dev_cpu_dead(unsigned int old netif_rx_ni(skb); input_queue_head_incr(oldsd); } diff --git a/patches/net-core-protect-users-of-napi_alloc_cache-against-r.patch b/patches/net-core-protect-users-of-napi_alloc_cache-against-r.patch index d5cf0e7c1ce0..2d6cb2251efb 100644 --- a/patches/net-core-protect-users-of-napi_alloc_cache-against-r.patch +++ b/patches/net-core-protect-users-of-napi_alloc_cache-against-r.patch @@ -73,7 +73,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> skb->pfmemalloc = 1; skb->head_frag = 1; -@@ -761,23 +770,26 @@ EXPORT_SYMBOL(consume_skb); +@@ -768,23 +777,26 @@ void __consume_stateless_skb(struct sk_b void __kfree_skb_flush(void) { @@ -102,7 +102,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* record skb to CPU local list */ nc->skb_cache[nc->skb_count++] = skb; -@@ -792,6 +804,7 @@ static inline void _kfree_skb_defer(stru +@@ -799,6 +811,7 @@ static inline void _kfree_skb_defer(stru nc->skb_cache); nc->skb_count = 0; } diff --git a/patches/net-core-remove-explicit-do_softirq-from-busy_poll_s.patch b/patches/net-core-remove-explicit-do_softirq-from-busy_poll_s.patch deleted file mode 100644 index b62ce0524651..000000000000 --- a/patches/net-core-remove-explicit-do_softirq-from-busy_poll_s.patch +++ /dev/null @@ -1,27 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Mon, 22 May 2017 21:08:08 +0200 -Subject: net/core: remove explicit do_softirq() from busy_poll_stop() - -Since commit 217f69743681 ("net: busy-poll: allow preemption in -sk_busy_loop()") there is an explicit do_softirq() invocation after -local_bh_enable() has been invoked. -I don't understand why we need this because local_bh_enable() will -invoke do_softirq() once the softirq counter reached zero and we have -softirq-related work pending. - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - net/core/dev.c | 2 -- - 1 file changed, 2 deletions(-) - ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -5070,8 +5070,6 @@ static void busy_poll_stop(struct napi_s - if (rc == BUSY_POLL_BUDGET) - __napi_schedule(napi); - local_bh_enable(); -- if (local_softirq_pending()) -- do_softirq(); - } - - bool sk_busy_loop(struct sock *sk, int nonblock) diff --git a/patches/net-dev-always-take-qdisc-s-busylock-in-__dev_xmit_s.patch b/patches/net-dev-always-take-qdisc-s-busylock-in-__dev_xmit_s.patch index 2081b0b4bc76..fc03714dfd35 100644 --- a/patches/net-dev-always-take-qdisc-s-busylock-in-__dev_xmit_s.patch +++ b/patches/net-dev-always-take-qdisc-s-busylock-in-__dev_xmit_s.patch @@ -20,7 +20,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -3078,7 +3078,11 @@ static inline int __dev_xmit_skb(struct +@@ -3162,7 +3162,11 @@ static inline int __dev_xmit_skb(struct * This permits qdisc->running owner to get the lock more * often and dequeue packets faster. */ diff --git a/patches/net-make-devnet_rename_seq-a-mutex.patch b/patches/net-make-devnet_rename_seq-a-mutex.patch index bf05acbd9e98..b254fb6f74b9 100644 --- a/patches/net-make-devnet_rename_seq-a-mutex.patch +++ b/patches/net-make-devnet_rename_seq-a-mutex.patch @@ -21,7 +21,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -189,6 +189,7 @@ static unsigned int napi_gen_id = NR_CPU +@@ -194,6 +194,7 @@ static unsigned int napi_gen_id = NR_CPU static DEFINE_READ_MOSTLY_HASHTABLE(napi_hash, 8); static seqcount_t devnet_rename_seq; @@ -29,7 +29,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> static inline void dev_base_seq_inc(struct net *net) { -@@ -889,7 +890,8 @@ int netdev_get_name(struct net *net, cha +@@ -919,7 +920,8 @@ int netdev_get_name(struct net *net, cha strcpy(name, dev->name); rcu_read_unlock(); if (read_seqcount_retry(&devnet_rename_seq, seq)) { @@ -39,7 +39,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> goto retry; } -@@ -1158,20 +1160,17 @@ int dev_change_name(struct net_device *d +@@ -1188,20 +1190,17 @@ int dev_change_name(struct net_device *d if (dev->flags & IFF_UP) return -EBUSY; @@ -66,7 +66,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> if (oldname[0] && !strchr(oldname, '%')) netdev_info(dev, "renamed from %s\n", oldname); -@@ -1184,11 +1183,12 @@ int dev_change_name(struct net_device *d +@@ -1214,11 +1213,12 @@ int dev_change_name(struct net_device *d if (ret) { memcpy(dev->name, oldname, IFNAMSIZ); dev->name_assign_type = old_assign_type; @@ -82,7 +82,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> netdev_adjacent_rename_links(dev, oldname); -@@ -1209,7 +1209,8 @@ int dev_change_name(struct net_device *d +@@ -1239,7 +1239,8 @@ int dev_change_name(struct net_device *d /* err >= 0 after dev_alloc_name() or stores the first errno */ if (err >= 0) { err = ret; @@ -92,7 +92,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> memcpy(dev->name, oldname, IFNAMSIZ); memcpy(oldname, newname, IFNAMSIZ); dev->name_assign_type = old_assign_type; -@@ -1222,6 +1223,11 @@ int dev_change_name(struct net_device *d +@@ -1252,6 +1253,11 @@ int dev_change_name(struct net_device *d } return err; diff --git a/patches/net-move-xmit_recursion-to-per-task-variable-on-RT.patch b/patches/net-move-xmit_recursion-to-per-task-variable-on-RT.patch index 7ef11e59318f..478d1fe810ec 100644 --- a/patches/net-move-xmit_recursion-to-per-task-variable-on-RT.patch +++ b/patches/net-move-xmit_recursion-to-per-task-variable-on-RT.patch @@ -23,7 +23,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h -@@ -2428,14 +2428,53 @@ void netdev_freemem(struct net_device *d +@@ -2443,14 +2443,53 @@ void netdev_freemem(struct net_device *d void synchronize_net(void); int init_dummy_netdev(struct net_device *dev); @@ -80,7 +80,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex); --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -1061,6 +1061,9 @@ struct task_struct { +@@ -1096,6 +1096,9 @@ struct task_struct { #ifdef CONFIG_DEBUG_ATOMIC_SLEEP unsigned long task_state_change; #endif @@ -92,7 +92,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> struct task_struct *oom_reaper_list; --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -3141,8 +3141,10 @@ static void skb_update_prio(struct sk_bu +@@ -3225,8 +3225,10 @@ static void skb_update_prio(struct sk_bu #define skb_update_prio(skb) #endif @@ -103,7 +103,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /** * dev_loopback_xmit - loop back @skb -@@ -3382,8 +3384,7 @@ static int __dev_queue_xmit(struct sk_bu +@@ -3467,8 +3469,7 @@ static int __dev_queue_xmit(struct sk_bu int cpu = smp_processor_id(); /* ok because BHs are off */ if (txq->xmit_lock_owner != cpu) { @@ -113,7 +113,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> goto recursion_alert; skb = validate_xmit_skb(skb, dev); -@@ -3393,9 +3394,9 @@ static int __dev_queue_xmit(struct sk_bu +@@ -3478,9 +3479,9 @@ static int __dev_queue_xmit(struct sk_bu HARD_TX_LOCK(dev, txq, cpu); if (!netif_xmit_stopped(txq)) { @@ -127,7 +127,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> goto out; --- a/net/core/filter.c +++ b/net/core/filter.c -@@ -1652,7 +1652,7 @@ static inline int __bpf_tx_skb(struct ne +@@ -1680,7 +1680,7 @@ static inline int __bpf_tx_skb(struct ne { int ret; @@ -136,7 +136,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> net_crit_ratelimited("bpf: recursion limit reached on datapath, buggy bpf program?\n"); kfree_skb(skb); return -ENETDOWN; -@@ -1660,9 +1660,9 @@ static inline int __bpf_tx_skb(struct ne +@@ -1688,9 +1688,9 @@ static inline int __bpf_tx_skb(struct ne skb->dev = dev; diff --git a/patches/net-prevent-abba-deadlock.patch b/patches/net-prevent-abba-deadlock.patch index 562d7f1052a7..992a12e4abe8 100644 --- a/patches/net-prevent-abba-deadlock.patch +++ b/patches/net-prevent-abba-deadlock.patch @@ -95,7 +95,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/net/core/sock.c +++ b/net/core/sock.c -@@ -2541,12 +2541,11 @@ void lock_sock_nested(struct sock *sk, i +@@ -2704,12 +2704,11 @@ void lock_sock_nested(struct sock *sk, i if (sk->sk_lock.owned) __lock_sock(sk); sk->sk_lock.owned = 1; diff --git a/patches/net-provide-a-way-to-delegate-processing-a-softirq-t.patch b/patches/net-provide-a-way-to-delegate-processing-a-softirq-t.patch index d4ee5fd864cc..6edeb42a034f 100644 --- a/patches/net-provide-a-way-to-delegate-processing-a-softirq-t.patch +++ b/patches/net-provide-a-way-to-delegate-processing-a-softirq-t.patch @@ -20,7 +20,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h -@@ -508,6 +508,14 @@ extern void thread_do_softirq(void); +@@ -517,6 +517,14 @@ extern void thread_do_softirq(void); extern void open_softirq(int nr, void (*action)(struct softirq_action *)); extern void softirq_init(void); extern void __raise_softirq_irqoff(unsigned int nr); @@ -67,7 +67,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> void raise_softirq_irqoff(unsigned int nr) --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -5378,7 +5378,7 @@ static __latent_entropy void net_rx_acti +@@ -5601,7 +5601,7 @@ static __latent_entropy void net_rx_acti list_splice_tail(&repoll, &list); list_splice(&list, &sd->poll_list); if (!list_empty(&sd->poll_list)) diff --git a/patches/net-sched-dev_deactivate_many-use-msleep-1-instead-o.patch b/patches/net-sched-dev_deactivate_many-use-msleep-1-instead-o.patch index c4368692fbcd..24b22d11537f 100644 --- a/patches/net-sched-dev_deactivate_many-use-msleep-1-instead-o.patch +++ b/patches/net-sched-dev_deactivate_many-use-msleep-1-instead-o.patch @@ -46,7 +46,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c -@@ -925,7 +925,7 @@ void dev_deactivate_many(struct list_hea +@@ -926,7 +926,7 @@ void dev_deactivate_many(struct list_hea /* Wait for outstanding qdisc_run calls. */ list_for_each_entry(dev, head, close_list) while (some_qdisc_is_busy(dev)) diff --git a/patches/net-take-the-tcp_sk_lock-lock-with-BH-disabled.patch b/patches/net-take-the-tcp_sk_lock-lock-with-BH-disabled.patch index 75af4f5f788b..dea3e8fe68bf 100644 --- a/patches/net-take-the-tcp_sk_lock-lock-with-BH-disabled.patch +++ b/patches/net-take-the-tcp_sk_lock-lock-with-BH-disabled.patch @@ -26,7 +26,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c -@@ -713,8 +713,8 @@ static void tcp_v4_send_reset(const stru +@@ -712,8 +712,8 @@ static void tcp_v4_send_reset(const stru arg.tos = ip_hdr(skb)->tos; arg.uid = sock_net_uid(net, sk && sk_fullsock(sk) ? sk : NULL); @@ -36,7 +36,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ip_send_unicast_reply(*this_cpu_ptr(net->ipv4.tcp_sk), skb, &TCP_SKB_CB(skb)->header.h4.opt, ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, -@@ -722,8 +722,8 @@ static void tcp_v4_send_reset(const stru +@@ -721,8 +721,8 @@ static void tcp_v4_send_reset(const stru __TCP_INC_STATS(net, TCP_MIB_OUTSEGS); __TCP_INC_STATS(net, TCP_MIB_OUTRSTS); @@ -46,7 +46,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #ifdef CONFIG_TCP_MD5SIG out: -@@ -801,16 +801,16 @@ static void tcp_v4_send_ack(const struct +@@ -800,16 +800,16 @@ static void tcp_v4_send_ack(const struct arg.bound_dev_if = oif; arg.tos = tos; arg.uid = sock_net_uid(net, sk_fullsock(sk) ? sk : NULL); diff --git a/patches/net-use-trylock-in-icmp_sk.patch b/patches/net-use-trylock-in-icmp_sk.patch index 3e706f3c8ede..ba7cc66834f3 100644 --- a/patches/net-use-trylock-in-icmp_sk.patch +++ b/patches/net-use-trylock-in-icmp_sk.patch @@ -55,7 +55,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> local_bh_enable(); } -@@ -678,7 +681,6 @@ void icmp_send(struct sk_buff *skb_in, i +@@ -661,7 +664,6 @@ void icmp_send(struct sk_buff *skb_in, i /* Needed by both icmp_global_allow and icmp_xmit_lock */ local_bh_disable(); @@ -63,7 +63,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* Check global sysctl_icmp_msgs_per_sec ratelimit, unless * incoming dev is loopback. If outgoing dev change to not be -@@ -767,7 +769,6 @@ void icmp_send(struct sk_buff *skb_in, i +@@ -750,7 +752,6 @@ void icmp_send(struct sk_buff *skb_in, i out_unlock: icmp_xmit_unlock(sk); out_bh_enable: diff --git a/patches/net-wireless-warn-nort.patch b/patches/net-wireless-warn-nort.patch index 782144a79380..a035c737ed09 100644 --- a/patches/net-wireless-warn-nort.patch +++ b/patches/net-wireless-warn-nort.patch @@ -12,7 +12,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c -@@ -4229,7 +4229,7 @@ void ieee80211_rx_napi(struct ieee80211_ +@@ -4250,7 +4250,7 @@ void ieee80211_rx_napi(struct ieee80211_ struct ieee80211_supported_band *sband; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); diff --git a/patches/net_disable_NET_RX_BUSY_POLL.patch b/patches/net_disable_NET_RX_BUSY_POLL.patch index 9a030b337efe..5d833f6db86b 100644 --- a/patches/net_disable_NET_RX_BUSY_POLL.patch +++ b/patches/net_disable_NET_RX_BUSY_POLL.patch @@ -17,7 +17,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/net/Kconfig +++ b/net/Kconfig -@@ -277,7 +277,7 @@ config CGROUP_NET_CLASSID +@@ -278,7 +278,7 @@ config CGROUP_NET_CLASSID config NET_RX_BUSY_POLL bool diff --git a/patches/oleg-signal-rt-fix.patch b/patches/oleg-signal-rt-fix.patch index 4d8c668ccf2e..18385324b9ee 100644 --- a/patches/oleg-signal-rt-fix.patch +++ b/patches/oleg-signal-rt-fix.patch @@ -76,7 +76,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #endif --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -760,6 +760,10 @@ struct task_struct { +@@ -794,6 +794,10 @@ struct task_struct { /* Restored if set_restore_sigmask() was used: */ sigset_t saved_sigmask; struct sigpending pending; @@ -89,7 +89,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> unsigned int sas_ss_flags; --- a/kernel/signal.c +++ b/kernel/signal.c -@@ -1235,8 +1235,8 @@ int do_send_sig_info(int sig, struct sig +@@ -1236,8 +1236,8 @@ int do_send_sig_info(int sig, struct sig * We don't want to have recursive SIGSEGV's etc, for example, * that is why we also clear SIGNAL_UNKILLABLE. */ @@ -100,7 +100,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> { unsigned long int flags; int ret, blocked, ignored; -@@ -1261,6 +1261,39 @@ force_sig_info(int sig, struct siginfo * +@@ -1266,6 +1266,39 @@ force_sig_info(int sig, struct siginfo * return ret; } diff --git a/patches/patch-to-introduce-rcu-bh-qs-where-safe-from-softirq.patch b/patches/patch-to-introduce-rcu-bh-qs-where-safe-from-softirq.patch index cd3ec8bb3f7a..12489119adef 100644 --- a/patches/patch-to-introduce-rcu-bh-qs-where-safe-from-softirq.patch +++ b/patches/patch-to-introduce-rcu-bh-qs-where-safe-from-softirq.patch @@ -30,7 +30,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h -@@ -303,11 +303,7 @@ static inline int rcu_preempt_depth(void +@@ -118,11 +118,7 @@ static inline int rcu_preempt_depth(void /* Internal to kernel */ void rcu_init(void); void rcu_sched_qs(void); @@ -44,7 +44,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> void rcu_cpu_starting(unsigned int cpu); --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c -@@ -262,7 +262,14 @@ void rcu_sched_qs(void) +@@ -246,7 +246,14 @@ void rcu_sched_qs(void) this_cpu_ptr(&rcu_sched_data), true); } @@ -59,7 +59,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +#else void rcu_bh_qs(void) { - if (__this_cpu_read(rcu_bh_data.cpu_no_qs.s)) { + RCU_LOCKDEP_WARN(preemptible(), "rcu_bh_qs() invoked with preemption enabled!!!"); --- a/kernel/rcu/tree_plugin.h +++ b/kernel/rcu/tree_plugin.h @@ -29,6 +29,7 @@ @@ -69,8 +69,8 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +#include <linux/jiffies.h> #include <uapi/linux/sched/types.h> #include "../time/tick-internal.h" - -@@ -1246,7 +1247,7 @@ static void rcu_prepare_kthreads(int cpu + #include "../locking/rtmutex_common.h" +@@ -1285,7 +1286,7 @@ static void rcu_prepare_kthreads(int cpu #endif /* #else #ifdef CONFIG_RCU_BOOST */ @@ -79,9 +79,9 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * Check to see if any future RCU-related work will need to be done -@@ -1263,7 +1264,9 @@ int rcu_needs_cpu(u64 basemono, u64 *nex - return IS_ENABLED(CONFIG_RCU_NOCB_CPU_ALL) - ? 0 : rcu_cpu_has_callbacks(NULL); +@@ -1301,7 +1302,9 @@ int rcu_needs_cpu(u64 basemono, u64 *nex + *nextevt = KTIME_MAX; + return rcu_cpu_has_callbacks(NULL); } +#endif /* !defined(CONFIG_RCU_FAST_NO_HZ) || defined(CONFIG_PREEMPT_RT_FULL) */ @@ -89,7 +89,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * Because we do not have RCU_FAST_NO_HZ, don't bother cleaning up * after it. -@@ -1359,6 +1362,8 @@ static bool __maybe_unused rcu_try_advan +@@ -1397,6 +1400,8 @@ static bool __maybe_unused rcu_try_advan return cbs_ready; } @@ -98,7 +98,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * Allow the CPU to enter dyntick-idle mode unless it has callbacks ready * to invoke. If the CPU has callbacks, try to advance them. Tell the -@@ -1404,6 +1409,7 @@ int rcu_needs_cpu(u64 basemono, u64 *nex +@@ -1439,6 +1444,7 @@ int rcu_needs_cpu(u64 basemono, u64 *nex *nextevt = basemono + dj * TICK_NSEC; return 0; } diff --git a/patches/pci-switchtec-Don-t-use-completion-s-wait-queue.patch b/patches/pci-switchtec-Don-t-use-completion-s-wait-queue.patch new file mode 100644 index 000000000000..d66b6b3353f8 --- /dev/null +++ b/patches/pci-switchtec-Don-t-use-completion-s-wait-queue.patch @@ -0,0 +1,107 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Wed, 4 Oct 2017 10:24:23 +0200 +Subject: [PATCH] pci/switchtec: Don't use completion's wait queue + +The poll callback is using completion's wait_queue_head_t member and +puts it in poll_wait() so the poll() caller gets a wakeup after command +completed. This does not work on RT because we don't have a +wait_queue_head_t in our completion implementation. Nobody in tree does +like that in tree so this is the only driver that breaks. + +Instead of using the completion here is waitqueue with a status flag as +suggested by Logan. + +I don't have the HW so I have no idea if it works as expected, so please +test it. + +Cc: Kurt Schwemmer <kurt.schwemmer@microsemi.com> +Cc: Logan Gunthorpe <logang@deltatee.com> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + drivers/pci/switch/switchtec.c | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +--- a/drivers/pci/switch/switchtec.c ++++ b/drivers/pci/switch/switchtec.c +@@ -306,10 +306,11 @@ struct switchtec_user { + + enum mrpc_state state; + +- struct completion comp; ++ wait_queue_head_t cmd_comp; + struct kref kref; + struct list_head list; + ++ bool cmd_done; + u32 cmd; + u32 status; + u32 return_code; +@@ -331,7 +332,7 @@ static struct switchtec_user *stuser_cre + stuser->stdev = stdev; + kref_init(&stuser->kref); + INIT_LIST_HEAD(&stuser->list); +- init_completion(&stuser->comp); ++ init_waitqueue_head(&stuser->cmd_comp); + stuser->event_cnt = atomic_read(&stdev->event_cnt); + + dev_dbg(&stdev->dev, "%s: %p\n", __func__, stuser); +@@ -414,7 +415,7 @@ static int mrpc_queue_cmd(struct switcht + kref_get(&stuser->kref); + stuser->read_len = sizeof(stuser->data); + stuser_set_state(stuser, MRPC_QUEUED); +- init_completion(&stuser->comp); ++ stuser->cmd_done = false; + list_add_tail(&stuser->list, &stdev->mrpc_queue); + + mrpc_cmd_submit(stdev); +@@ -451,7 +452,7 @@ static void mrpc_complete_cmd(struct swi + stuser->read_len); + + out: +- complete_all(&stuser->comp); ++ wake_up_interruptible(&stuser->cmd_comp); + list_del_init(&stuser->list); + stuser_put(stuser); + stdev->mrpc_busy = 0; +@@ -721,10 +722,11 @@ static ssize_t switchtec_dev_read(struct + mutex_unlock(&stdev->mrpc_mutex); + + if (filp->f_flags & O_NONBLOCK) { +- if (!try_wait_for_completion(&stuser->comp)) ++ if (!stuser->cmd_done) + return -EAGAIN; + } else { +- rc = wait_for_completion_interruptible(&stuser->comp); ++ rc = wait_event_interruptible(stuser->cmd_comp, ++ stuser->cmd_done); + if (rc < 0) + return rc; + } +@@ -772,7 +774,7 @@ static unsigned int switchtec_dev_poll(s + struct switchtec_dev *stdev = stuser->stdev; + int ret = 0; + +- poll_wait(filp, &stuser->comp.wait, wait); ++ poll_wait(filp, &stuser->cmd_comp, wait); + poll_wait(filp, &stdev->event_wq, wait); + + if (lock_mutex_and_test_alive(stdev)) +@@ -780,7 +782,7 @@ static unsigned int switchtec_dev_poll(s + + mutex_unlock(&stdev->mrpc_mutex); + +- if (try_wait_for_completion(&stuser->comp)) ++ if (stuser->cmd_done) + ret |= POLLIN | POLLRDNORM; + + if (stuser->event_cnt != atomic_read(&stdev->event_cnt)) +@@ -1255,7 +1257,8 @@ static void stdev_kill(struct switchtec_ + + /* Wake up and kill any users waiting on an MRPC request */ + list_for_each_entry_safe(stuser, tmpuser, &stdev->mrpc_queue, list) { +- complete_all(&stuser->comp); ++ stuser->cmd_done = true; ++ wake_up_interruptible(&stuser->cmd_comp); + list_del_init(&stuser->list); + stuser_put(stuser); + } diff --git a/patches/peter_zijlstra-frob-rcu.patch b/patches/peter_zijlstra-frob-rcu.patch index 85b033777069..169d38d2fd53 100644 --- a/patches/peter_zijlstra-frob-rcu.patch +++ b/patches/peter_zijlstra-frob-rcu.patch @@ -155,7 +155,7 @@ Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> --- a/kernel/rcu/tree_plugin.h +++ b/kernel/rcu/tree_plugin.h -@@ -428,7 +428,7 @@ void rcu_read_unlock_special(struct task +@@ -460,7 +460,7 @@ void rcu_read_unlock_special(struct task } /* Hardware IRQ handlers cannot block, complain if they get here. */ diff --git a/patches/peterz-percpu-rwsem-rt.patch b/patches/peterz-percpu-rwsem-rt.patch index ec31b61aaff7..f479305b5491 100644 --- a/patches/peterz-percpu-rwsem-rt.patch +++ b/patches/peterz-percpu-rwsem-rt.patch @@ -142,7 +142,7 @@ Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> locks_dispose_list(&dispose); return error; } -@@ -2532,13 +2532,13 @@ locks_remove_lease(struct file *filp, st +@@ -2495,13 +2495,13 @@ locks_remove_lease(struct file *filp, st if (list_empty(&ctx->flc_lease)) return; diff --git a/patches/ping-sysrq.patch b/patches/ping-sysrq.patch index 38eaa1ae2caf..b167ccce20d2 100644 --- a/patches/ping-sysrq.patch +++ b/patches/ping-sysrq.patch @@ -41,7 +41,7 @@ Signed-off-by: Carsten Emde <C.Emde@osadl.org> --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h -@@ -79,6 +79,7 @@ struct netns_ipv4 { +@@ -78,6 +78,7 @@ struct netns_ipv4 { int sysctl_icmp_echo_ignore_all; int sysctl_icmp_echo_ignore_broadcasts; @@ -59,7 +59,7 @@ Signed-off-by: Carsten Emde <C.Emde@osadl.org> #include <linux/socket.h> #include <linux/in.h> #include <linux/inet.h> -@@ -932,6 +933,30 @@ static bool icmp_redirect(struct sk_buff +@@ -915,6 +916,30 @@ static bool icmp_redirect(struct sk_buff } /* @@ -90,7 +90,7 @@ Signed-off-by: Carsten Emde <C.Emde@osadl.org> * Handle ICMP_ECHO ("ping") requests. * * RFC 1122: 3.2.2.6 MUST have an echo server that answers ICMP echo -@@ -958,6 +983,11 @@ static bool icmp_echo(struct sk_buff *sk +@@ -941,6 +966,11 @@ static bool icmp_echo(struct sk_buff *sk icmp_param.data_len = skb->len; icmp_param.head_len = sizeof(struct icmphdr); icmp_reply(&icmp_param, skb); @@ -104,7 +104,7 @@ Signed-off-by: Carsten Emde <C.Emde@osadl.org> return true; --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c -@@ -687,6 +687,13 @@ static struct ctl_table ipv4_net_table[] +@@ -768,6 +768,13 @@ static struct ctl_table ipv4_net_table[] .proc_handler = proc_dointvec }, { diff --git a/patches/posix-timers-no-broadcast.patch b/patches/posix-timers-no-broadcast.patch index 581dcb2885b6..df9807d87281 100644 --- a/patches/posix-timers-no-broadcast.patch +++ b/patches/posix-timers-no-broadcast.patch @@ -13,7 +13,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c -@@ -507,6 +507,7 @@ static enum hrtimer_restart posix_timer_ +@@ -433,6 +433,7 @@ static enum hrtimer_restart posix_timer_ static struct pid *good_sigevent(sigevent_t * event) { struct task_struct *rtn = current->group_leader; @@ -21,7 +21,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> if ((event->sigev_notify & SIGEV_THREAD_ID ) && (!(rtn = find_task_by_vpid(event->sigev_notify_thread_id)) || -@@ -515,7 +516,8 @@ static struct pid *good_sigevent(sigeven +@@ -441,7 +442,8 @@ static struct pid *good_sigevent(sigeven return NULL; if (((event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE) && diff --git a/patches/posix-timers-thread-posix-cpu-timers-on-rt.patch b/patches/posix-timers-thread-posix-cpu-timers-on-rt.patch index 20226ae7032f..ed187d3cd3f6 100644 --- a/patches/posix-timers-thread-posix-cpu-timers-on-rt.patch +++ b/patches/posix-timers-thread-posix-cpu-timers-on-rt.patch @@ -19,7 +19,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/include/linux/init_task.h +++ b/include/linux/init_task.h -@@ -167,6 +167,12 @@ extern struct cred init_cred; +@@ -168,6 +168,12 @@ extern struct cred init_cred; # define INIT_PERF_EVENTS(tsk) #endif @@ -31,8 +31,8 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN # define INIT_VTIME(tsk) \ - .vtime_seqcount = SEQCNT_ZERO(tsk.vtime_seqcount), \ -@@ -269,6 +275,7 @@ extern struct cred init_cred; + .vtime.seqcount = SEQCNT_ZERO(tsk.vtime.seqcount), \ +@@ -283,6 +289,7 @@ extern struct cred init_cred; INIT_CPU_TIMERS(tsk) \ .pi_lock = __RAW_SPIN_LOCK_UNLOCKED(tsk.pi_lock), \ .timer_slack_ns = 50000, /* 50 usec default slack */ \ @@ -42,7 +42,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> [PIDTYPE_PGID] = INIT_PID_LINK(PIDTYPE_PGID), \ --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -710,6 +710,9 @@ struct task_struct { +@@ -744,6 +744,9 @@ struct task_struct { #ifdef CONFIG_POSIX_TIMERS struct task_cputime cputime_expires; struct list_head cpu_timers[3]; @@ -54,7 +54,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* Process credentials: */ --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -1451,6 +1451,9 @@ static void rt_mutex_init_task(struct ta +@@ -1481,6 +1481,9 @@ static void rt_mutex_init_task(struct ta */ static void posix_cpu_timers_init(struct task_struct *tsk) { @@ -77,15 +77,15 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #include <linux/posix-timers.h> #include <linux/errno.h> #include <linux/math64.h> -@@ -12,6 +14,7 @@ - #include <trace/events/timer.h> +@@ -13,6 +15,7 @@ #include <linux/tick.h> #include <linux/workqueue.h> + #include <linux/compat.h> +#include <linux/smpboot.h> - /* - * Called after updating RLIMIT_CPU to run cpu timer and update -@@ -590,7 +593,7 @@ static int posix_cpu_timer_set(struct k_ + #include "posix-timers.h" + +@@ -602,7 +605,7 @@ static int posix_cpu_timer_set(struct k_ /* * Disarm any old timer after extracting its expiry time. */ @@ -94,16 +94,16 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ret = 0; old_incr = timer->it.cpu.incr; -@@ -1014,7 +1017,7 @@ void posix_cpu_timer_schedule(struct k_i +@@ -1035,7 +1038,7 @@ static void posix_cpu_timer_rearm(struct /* * Now re-arm for the new expiry time. */ - WARN_ON_ONCE(!irqs_disabled()); + WARN_ON_ONCE_NONRT(!irqs_disabled()); arm_timer(timer); + unlock: unlock_task_sighand(p, &flags); - -@@ -1103,13 +1106,13 @@ static inline int fastpath_timer_check(s +@@ -1120,13 +1123,13 @@ static inline int fastpath_timer_check(s * already updated our counts. We need to check if any timers fire now. * Interrupts are disabled. */ @@ -119,7 +119,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * The fast path checks that there are no expired thread or thread -@@ -1163,6 +1166,152 @@ void run_posix_cpu_timers(struct task_st +@@ -1180,6 +1183,152 @@ void run_posix_cpu_timers(struct task_st } } diff --git a/patches/power-disable-highmem-on-rt.patch b/patches/power-disable-highmem-on-rt.patch index 4eb27c466774..2034922207fd 100644 --- a/patches/power-disable-highmem-on-rt.patch +++ b/patches/power-disable-highmem-on-rt.patch @@ -11,7 +11,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig -@@ -333,7 +333,7 @@ menu "Kernel options" +@@ -382,7 +382,7 @@ menu "Kernel options" config HIGHMEM bool "High memory support" diff --git a/patches/power-use-generic-rwsem-on-rt.patch b/patches/power-use-generic-rwsem-on-rt.patch index 6e83ca92993d..a84643ef67e5 100644 --- a/patches/power-use-generic-rwsem-on-rt.patch +++ b/patches/power-use-generic-rwsem-on-rt.patch @@ -11,7 +11,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig -@@ -52,10 +52,11 @@ config LOCKDEP_SUPPORT +@@ -99,10 +99,11 @@ config LOCKDEP_SUPPORT config RWSEM_GENERIC_SPINLOCK bool diff --git a/patches/powerpc-kvm-Disable-in-kernel-MPIC-emulation-for-PRE.patch b/patches/powerpc-kvm-Disable-in-kernel-MPIC-emulation-for-PRE.patch index e50543c26c46..8b2b3a329509 100644 --- a/patches/powerpc-kvm-Disable-in-kernel-MPIC-emulation-for-PRE.patch +++ b/patches/powerpc-kvm-Disable-in-kernel-MPIC-emulation-for-PRE.patch @@ -27,7 +27,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig -@@ -175,6 +175,7 @@ config KVM_E500MC +@@ -176,6 +176,7 @@ config KVM_E500MC config KVM_MPIC bool "KVM in-kernel MPIC emulation" depends on KVM && E500 diff --git a/patches/powerpc-preempt-lazy-support.patch b/patches/powerpc-preempt-lazy-support.patch index facf5b101973..cb4bc6fa777a 100644 --- a/patches/powerpc-preempt-lazy-support.patch +++ b/patches/powerpc-preempt-lazy-support.patch @@ -15,8 +15,8 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig -@@ -155,6 +155,7 @@ config PPC - select HAVE_PERF_EVENTS_NMI if PPC64 +@@ -203,6 +203,7 @@ config PPC + select HAVE_HARDLOCKUP_DETECTOR_PERF if PERF_EVENTS && HAVE_PERF_EVENTS_NMI && !HAVE_HARDLOCKUP_DETECTOR_ARCH select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP + select HAVE_PREEMPT_LAZY @@ -25,7 +25,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> select HAVE_SYSCALL_TRACEPOINTS --- a/arch/powerpc/include/asm/thread_info.h +++ b/arch/powerpc/include/asm/thread_info.h -@@ -43,6 +43,8 @@ struct thread_info { +@@ -35,6 +35,8 @@ struct thread_info { int cpu; /* cpu we're on */ int preempt_count; /* 0 => preemptable, <0 => BUG */ @@ -34,7 +34,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> unsigned long local_flags; /* private flags for thread */ #ifdef CONFIG_LIVEPATCH unsigned long *livepatch_sp; -@@ -88,8 +90,7 @@ static inline struct thread_info *curren +@@ -80,8 +82,7 @@ static inline struct thread_info *curren #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ #define TIF_SIGPENDING 1 /* signal pending */ #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ @@ -43,8 +43,8 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +#define TIF_NEED_RESCHED_LAZY 3 /* lazy rescheduling necessary */ #define TIF_32BIT 4 /* 32 bit binary */ #define TIF_RESTORE_TM 5 /* need to restore TM FP/VEC/VSX */ - #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ -@@ -107,6 +108,8 @@ static inline struct thread_info *curren + #define TIF_PATCH_PENDING 6 /* pending live patching update */ +@@ -100,6 +101,8 @@ static inline struct thread_info *curren #if defined(CONFIG_PPC64) #define TIF_ELF2ABI 18 /* function descriptors must die! */ #endif @@ -53,7 +53,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* as above, but as bit values */ #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) -@@ -125,14 +128,16 @@ static inline struct thread_info *curren +@@ -119,14 +122,16 @@ static inline struct thread_info *curren #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) #define _TIF_EMULATE_STACK_STORE (1<<TIF_EMULATE_STACK_STORE) #define _TIF_NOHZ (1<<TIF_NOHZ) @@ -64,8 +64,8 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ _TIF_NOTIFY_RESUME | _TIF_UPROBE | \ -- _TIF_RESTORE_TM) -+ _TIF_RESTORE_TM | _TIF_NEED_RESCHED_LAZY) +- _TIF_RESTORE_TM | _TIF_PATCH_PENDING) ++ _TIF_RESTORE_TM | _TIF_PATCH_PENDING | _TIF_NEED_RESCHED_LAZY) #define _TIF_PERSYSCALL_MASK (_TIF_RESTOREALL|_TIF_NOERROR) +#define _TIF_NEED_RESCHED_MASK (_TIF_NEED_RESCHED | _TIF_NEED_RESCHED_LAZY) @@ -83,7 +83,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S -@@ -845,7 +845,14 @@ user_exc_return: /* r10 contains MSR_KE +@@ -844,7 +844,14 @@ user_exc_return: /* r10 contains MSR_KE cmpwi 0,r0,0 /* if non-zero, just restore regs and return */ bne restore andi. r8,r8,_TIF_NEED_RESCHED @@ -98,7 +98,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> lwz r3,_MSR(r1) andi. r0,r3,MSR_EE /* interrupts off? */ beq restore /* don't schedule if so */ -@@ -856,11 +863,11 @@ user_exc_return: /* r10 contains MSR_KE +@@ -855,11 +862,11 @@ user_exc_return: /* r10 contains MSR_KE */ bl trace_hardirqs_off #endif @@ -113,7 +113,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #ifdef CONFIG_TRACE_IRQFLAGS /* And now, to properly rebalance the above, we tell lockdep they * are being turned back on, which will happen when we return -@@ -1183,7 +1190,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRE +@@ -1182,7 +1189,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRE #endif /* !(CONFIG_4xx || CONFIG_BOOKE) */ do_work: /* r10 contains MSR_KERNEL here */ @@ -122,7 +122,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> beq do_user_signal do_resched: /* r10 contains MSR_KERNEL here */ -@@ -1204,7 +1211,7 @@ do_resched: /* r10 contains MSR_KERNEL +@@ -1203,7 +1210,7 @@ do_resched: /* r10 contains MSR_KERNEL MTMSRD(r10) /* disable interrupts */ CURRENT_THREAD_INFO(r9, r1) lwz r9,TI_FLAGS(r9) @@ -133,7 +133,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> beq restore_user --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S -@@ -656,7 +656,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEG +@@ -675,7 +675,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEG bl restore_math b restore #endif @@ -142,7 +142,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> beq 2f bl restore_interrupts SCHEDULE_USER -@@ -718,10 +718,18 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEG +@@ -737,10 +737,18 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEG #ifdef CONFIG_PREEMPT /* Check if we need to preempt */ @@ -162,7 +162,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> cmpwi cr1,r8,0 ld r0,SOFTE(r1) cmpdi r0,0 -@@ -738,7 +746,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEG +@@ -757,7 +765,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEG /* Re-test flags and eventually loop */ CURRENT_THREAD_INFO(r9, r1) ld r4,TI_FLAGS(r9) diff --git a/patches/preempt-lazy-support.patch b/patches/preempt-lazy-support.patch index e98d84bc008d..cada2a5562d8 100644 --- a/patches/preempt-lazy-support.patch +++ b/patches/preempt-lazy-support.patch @@ -61,10 +61,10 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> kernel/sched/fair.c | 16 ++++---- kernel/sched/features.h | 3 + kernel/sched/sched.h | 9 ++++ - kernel/trace/trace.c | 37 +++++++++++-------- + kernel/trace/trace.c | 36 ++++++++++-------- kernel/trace/trace.h | 2 + kernel/trace/trace_output.c | 14 ++++++- - 12 files changed, 227 insertions(+), 29 deletions(-) + 12 files changed, 226 insertions(+), 29 deletions(-) --- a/include/linux/preempt.h +++ b/include/linux/preempt.h @@ -140,7 +140,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -1513,6 +1513,44 @@ static inline int test_tsk_need_resched( +@@ -1559,6 +1559,44 @@ static inline int test_tsk_need_resched( return unlikely(test_tsk_thread_flag(tsk,TIF_NEED_RESCHED)); } @@ -187,7 +187,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> if (task->state & (__TASK_STOPPED | __TASK_TRACED)) --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h -@@ -74,7 +74,17 @@ static inline int test_ti_thread_flag(st +@@ -86,7 +86,17 @@ static inline int test_ti_thread_flag(st #define test_thread_flag(flag) \ test_ti_thread_flag(current_thread_info(), flag) @@ -233,7 +233,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> default PREEMPT_NONE --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -527,6 +527,48 @@ void resched_curr(struct rq *rq) +@@ -518,6 +518,48 @@ void resched_curr(struct rq *rq) trace_sched_wake_idle_without_ipi(cpu); } @@ -282,7 +282,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> void resched_cpu(int cpu) { struct rq *rq = cpu_rq(cpu); -@@ -2457,6 +2499,9 @@ int sched_fork(unsigned long clone_flags +@@ -2436,6 +2478,9 @@ int sched_fork(unsigned long clone_flags p->on_cpu = 0; #endif init_task_preempt_count(p); @@ -292,7 +292,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #ifdef CONFIG_SMP plist_node_init(&p->pushable_tasks, MAX_PRIO); RB_CLEAR_NODE(&p->pushable_dl_tasks); -@@ -3448,6 +3493,7 @@ static void __sched notrace __schedule(b +@@ -3343,6 +3388,7 @@ static void __sched notrace __schedule(b next = pick_next_task(rq, prev, &rf); clear_tsk_need_resched(prev); @@ -300,7 +300,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> clear_preempt_need_resched(); if (likely(prev != next)) { -@@ -3599,6 +3645,30 @@ static void __sched notrace preempt_sche +@@ -3518,6 +3564,30 @@ static void __sched notrace preempt_sche } while (need_resched()); } @@ -331,7 +331,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #ifdef CONFIG_PREEMPT /* * this is the entry point to schedule() from in-kernel preemption -@@ -3613,7 +3683,8 @@ asmlinkage __visible void __sched notrac +@@ -3532,7 +3602,8 @@ asmlinkage __visible void __sched notrac */ if (likely(!preemptible())) return; @@ -341,7 +341,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> preempt_schedule_common(); } NOKPROBE_SYMBOL(preempt_schedule); -@@ -3640,6 +3711,9 @@ asmlinkage __visible void __sched notrac +@@ -3559,6 +3630,9 @@ asmlinkage __visible void __sched notrac if (likely(!preemptible())) return; @@ -351,7 +351,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> do { /* * Because the function tracer can trace preempt_count_sub() -@@ -5469,7 +5543,9 @@ void init_idle(struct task_struct *idle, +@@ -5288,7 +5362,9 @@ void init_idle(struct task_struct *idle, /* Set the preempt count _outside_ the spinlocks! */ init_idle_preempt_count(idle, cpu); @@ -362,7 +362,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * The idle tasks have their own, simple scheduling class: */ -@@ -7483,6 +7559,7 @@ void migrate_disable(void) +@@ -6844,6 +6920,7 @@ void migrate_disable(void) } preempt_disable(); @@ -370,7 +370,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> pin_current_cpu(); migrate_disable_update_cpus_allowed(p); -@@ -7550,6 +7627,7 @@ void migrate_enable(void) +@@ -6911,6 +6988,7 @@ void migrate_enable(void) arg.dest_cpu = dest_cpu; unpin_current_cpu(); @@ -378,7 +378,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> preempt_enable(); stop_one_cpu(task_cpu(p), migration_cpu_stop, &arg); tlb_migrate_finish(p->mm); -@@ -7558,6 +7636,7 @@ void migrate_enable(void) +@@ -6919,6 +6997,7 @@ void migrate_enable(void) } } unpin_current_cpu(); @@ -388,7 +388,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> EXPORT_SYMBOL(migrate_enable); --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c -@@ -3742,7 +3742,7 @@ check_preempt_tick(struct cfs_rq *cfs_rq +@@ -3828,7 +3828,7 @@ check_preempt_tick(struct cfs_rq *cfs_rq ideal_runtime = sched_slice(cfs_rq, curr); delta_exec = curr->sum_exec_runtime - curr->prev_sum_exec_runtime; if (delta_exec > ideal_runtime) { @@ -397,7 +397,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * The current task ran long enough, ensure it doesn't get * re-elected due to buddy favours. -@@ -3766,7 +3766,7 @@ check_preempt_tick(struct cfs_rq *cfs_rq +@@ -3852,7 +3852,7 @@ check_preempt_tick(struct cfs_rq *cfs_rq return; if (delta > ideal_runtime) @@ -406,7 +406,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } static void -@@ -3908,7 +3908,7 @@ entity_tick(struct cfs_rq *cfs_rq, struc +@@ -3994,7 +3994,7 @@ entity_tick(struct cfs_rq *cfs_rq, struc * validating it and just reschedule. */ if (queued) { @@ -415,7 +415,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return; } /* -@@ -4090,7 +4090,7 @@ static void __account_cfs_rq_runtime(str +@@ -4176,7 +4176,7 @@ static void __account_cfs_rq_runtime(str * hierarchy can be throttled */ if (!assign_cfs_rq_runtime(cfs_rq) && likely(cfs_rq->curr)) @@ -424,7 +424,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } static __always_inline -@@ -4718,7 +4718,7 @@ static void hrtick_start_fair(struct rq +@@ -4825,7 +4825,7 @@ static void hrtick_start_fair(struct rq if (delta < 0) { if (rq->curr == p) @@ -433,7 +433,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return; } hrtick_start(rq, delta); -@@ -6194,7 +6194,7 @@ static void check_preempt_wakeup(struct +@@ -6161,7 +6161,7 @@ static void check_preempt_wakeup(struct return; preempt: @@ -442,7 +442,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * Only set the backward buddy when the current task is still * on the rq. This can happen when a wakeup gets interleaved -@@ -8969,7 +8969,7 @@ static void task_fork_fair(struct task_s +@@ -8990,7 +8990,7 @@ static void task_fork_fair(struct task_s * 'current' within the tree based on its new key value. */ swap(curr->vruntime, se->vruntime); @@ -451,7 +451,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } se->vruntime -= cfs_rq->min_vruntime; -@@ -8993,7 +8993,7 @@ prio_changed_fair(struct rq *rq, struct +@@ -9014,7 +9014,7 @@ prio_changed_fair(struct rq *rq, struct */ if (rq->curr == p) { if (p->prio > oldprio) @@ -474,7 +474,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h -@@ -1477,6 +1477,15 @@ extern void init_sched_fair_class(void); +@@ -1532,6 +1532,15 @@ extern void init_sched_fair_class(void); extern void resched_curr(struct rq *rq); extern void resched_cpu(int cpu); @@ -492,7 +492,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c -@@ -1942,6 +1942,7 @@ tracing_generic_entry_update(struct trac +@@ -2126,6 +2126,7 @@ tracing_generic_entry_update(struct trac struct task_struct *tsk = current; entry->preempt_count = pc & 0xff; @@ -500,7 +500,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> entry->pid = (tsk) ? tsk->pid : 0; entry->flags = #ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT -@@ -1952,7 +1953,8 @@ tracing_generic_entry_update(struct trac +@@ -2136,7 +2137,8 @@ tracing_generic_entry_update(struct trac ((pc & NMI_MASK ) ? TRACE_FLAG_NMI : 0) | ((pc & HARDIRQ_MASK) ? TRACE_FLAG_HARDIRQ : 0) | ((pc & SOFTIRQ_OFFSET) ? TRACE_FLAG_SOFTIRQ : 0) | @@ -510,7 +510,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> (test_preempt_need_resched() ? TRACE_FLAG_PREEMPT_RESCHED : 0); entry->migrate_disable = (tsk) ? __migrate_disabled(tsk) & 0xFF : 0; -@@ -3119,15 +3121,17 @@ get_total_entries(struct trace_buffer *b +@@ -3338,15 +3340,17 @@ get_total_entries(struct trace_buffer *b static void print_lat_help_header(struct seq_file *m) { @@ -537,26 +537,29 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } static void print_event_info(struct trace_buffer *buf, struct seq_file *m) -@@ -3153,11 +3157,14 @@ static void print_func_help_header_irq(s - print_event_info(buf, m); - seq_puts(m, "# _-----=> irqs-off\n" - "# / _----=> need-resched\n" -- "# | / _---=> hardirq/softirq\n" -- "# || / _--=> preempt-depth\n" -- "# ||| / delay\n" -- "# TASK-PID CPU# |||| TIMESTAMP FUNCTION\n" -- "# | | | |||| | |\n"); -+ "# |/ _-----=> need-resched_lazy\n" -+ "# || / _---=> hardirq/softirq\n" -+ "# ||| / _--=> preempt-depth\n" -+ "# |||| /_--=> preempt-lazy-depth\n" -+ "# ||||| _-=> migrate-disable \n" -+ "# ||||| / delay\n" -+ "# TASK-PID CPU# |||||| TIMESTAMP FUNCTION\n" -+ "# | | | |||||| | |\n"); +@@ -3382,15 +3386,17 @@ static void print_func_help_header_irq(s + tgid ? tgid_space : space); + seq_printf(m, "# %s / _----=> need-resched\n", + tgid ? tgid_space : space); +- seq_printf(m, "# %s| / _---=> hardirq/softirq\n", ++ seq_printf(m, "# %s| / _----=> need-resched_lazy\n", + tgid ? tgid_space : space); +- seq_printf(m, "# %s|| / _--=> preempt-depth\n", ++ seq_printf(m, "# %s|| / _---=> hardirq/softirq\n", + tgid ? tgid_space : space); +- seq_printf(m, "# %s||| / delay\n", ++ seq_printf(m, "# %s||| / _--=> preempt-depth\n", + tgid ? tgid_space : space); +- seq_printf(m, "# TASK-PID CPU#%s|||| TIMESTAMP FUNCTION\n", ++ seq_printf(m, "# %s|||| / delay\n", ++ tgid ? tgid_space : space); ++ seq_printf(m, "# TASK-PID CPU#%s||||| TIMESTAMP FUNCTION\n", + tgid ? " TGID " : space); +- seq_printf(m, "# | | | %s|||| | |\n", ++ seq_printf(m, "# | | | %s||||| | |\n", + tgid ? " | " : space); } - void --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -126,6 +126,7 @@ struct kretprobe_trace_entry_head { @@ -577,7 +580,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #define TRACE_BUF_SIZE 1024 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c -@@ -438,6 +438,7 @@ int trace_print_lat_fmt(struct trace_seq +@@ -447,6 +447,7 @@ int trace_print_lat_fmt(struct trace_seq { char hardsoft_irq; char need_resched; @@ -585,7 +588,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> char irqs_off; int hardirq; int softirq; -@@ -468,6 +469,9 @@ int trace_print_lat_fmt(struct trace_seq +@@ -477,6 +478,9 @@ int trace_print_lat_fmt(struct trace_seq break; } @@ -595,7 +598,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> hardsoft_irq = (nmi && hardirq) ? 'Z' : nmi ? 'z' : -@@ -476,14 +480,20 @@ int trace_print_lat_fmt(struct trace_seq +@@ -485,14 +489,20 @@ int trace_print_lat_fmt(struct trace_seq softirq ? 's' : '.' ; diff --git a/patches/printk-27force_early_printk-27-boot-param-to-help-with-debugging.patch b/patches/printk-27force_early_printk-27-boot-param-to-help-with-debugging.patch index 9883c1c91caf..a9a912fa54c2 100644 --- a/patches/printk-27force_early_printk-27-boot-param-to-help-with-debugging.patch +++ b/patches/printk-27force_early_printk-27-boot-param-to-help-with-debugging.patch @@ -15,7 +15,7 @@ Link: http://lkml.kernel.org/n/tip-ykb97nsfmobq44xketrxs977@git.kernel.org --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c -@@ -431,6 +431,13 @@ asmlinkage void early_printk(const char +@@ -430,6 +430,13 @@ asmlinkage void early_printk(const char */ static bool __read_mostly printk_killswitch; diff --git a/patches/printk-kill.patch b/patches/printk-kill.patch index 3d82464f730d..4c2f4e1e65e7 100644 --- a/patches/printk-kill.patch +++ b/patches/printk-kill.patch @@ -28,7 +28,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #ifdef CONFIG_PRINTK_NMI --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c -@@ -401,6 +401,58 @@ DEFINE_RAW_SPINLOCK(logbuf_lock); +@@ -400,6 +400,58 @@ DEFINE_RAW_SPINLOCK(logbuf_lock); printk_safe_exit_irqrestore(flags); \ } while (0) @@ -87,7 +87,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #ifdef CONFIG_PRINTK DECLARE_WAIT_QUEUE_HEAD(log_wait); /* the next printk record to read by syslog(READ) or /proc/kmsg */ -@@ -1705,6 +1757,13 @@ asmlinkage int vprintk_emit(int facility +@@ -1704,6 +1756,13 @@ asmlinkage int vprintk_emit(int facility int printed_len = 0; bool in_sched = false; @@ -101,7 +101,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> if (level == LOGLEVEL_SCHED) { level = LOGLEVEL_DEFAULT; in_sched = true; -@@ -1876,26 +1935,6 @@ static bool suppress_message_printing(in +@@ -1875,26 +1934,6 @@ static bool suppress_message_printing(in #endif /* CONFIG_PRINTK */ @@ -136,9 +136,9 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> static DEFINE_PER_CPU(struct perf_event *, watchdog_ev); +static DEFINE_RAW_SPINLOCK(watchdog_output_lock); - /* boot commands */ - /* -@@ -106,6 +107,13 @@ static void watchdog_overflow_callback(s + static unsigned long hardlockup_allcpu_dumped; + +@@ -132,6 +133,13 @@ static void watchdog_overflow_callback(s /* only print hardlockups once */ if (__this_cpu_read(hard_watchdog_warn) == true) return; @@ -152,7 +152,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> pr_emerg("Watchdog detected hard LOCKUP on cpu %d", this_cpu); print_modules(); -@@ -123,6 +131,7 @@ static void watchdog_overflow_callback(s +@@ -149,6 +157,7 @@ static void watchdog_overflow_callback(s !test_and_set_bit(0, &hardlockup_allcpu_dumped)) trigger_allbutself_cpu_backtrace(); diff --git a/patches/printk-rt-aware.patch b/patches/printk-rt-aware.patch index 882f07cd7c2f..77221aa95b5d 100644 --- a/patches/printk-rt-aware.patch +++ b/patches/printk-rt-aware.patch @@ -12,7 +12,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c -@@ -1630,6 +1630,7 @@ static void call_console_drivers(const c +@@ -1629,6 +1629,7 @@ static void call_console_drivers(const c if (!console_drivers) return; @@ -20,7 +20,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> for_each_console(con) { if (exclusive_console && con != exclusive_console) continue; -@@ -1645,6 +1646,7 @@ static void call_console_drivers(const c +@@ -1644,6 +1645,7 @@ static void call_console_drivers(const c else con->write(con, text, len); } @@ -28,7 +28,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } int printk_delay_msec __read_mostly; -@@ -1827,12 +1829,22 @@ asmlinkage int vprintk_emit(int facility +@@ -1826,12 +1828,22 @@ asmlinkage int vprintk_emit(int facility /* If called from the scheduler, we can not call up(). */ if (!in_sched) { @@ -52,7 +52,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> console_unlock(); } -@@ -2283,10 +2295,15 @@ void console_unlock(void) +@@ -2287,10 +2299,15 @@ void console_unlock(void) console_seq++; raw_spin_unlock(&logbuf_lock); diff --git a/patches/ptrace-fix-ptrace-vs-tasklist_lock-race.patch b/patches/ptrace-fix-ptrace-vs-tasklist_lock-race.patch index a464e280336c..1822a6c1cbb3 100644 --- a/patches/ptrace-fix-ptrace-vs-tasklist_lock-race.patch +++ b/patches/ptrace-fix-ptrace-vs-tasklist_lock-race.patch @@ -43,7 +43,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #define task_contributes_to_load(task) ((task->state & TASK_UNINTERRUPTIBLE) != 0 && \ (task->flags & PF_FROZEN) == 0 && \ (task->state & TASK_NOLOAD) == 0) -@@ -1506,6 +1502,51 @@ static inline int test_tsk_need_resched( +@@ -1552,6 +1548,51 @@ static inline int test_tsk_need_resched( return unlikely(test_tsk_thread_flag(tsk,TIF_NEED_RESCHED)); } @@ -115,7 +115,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> spin_unlock_irq(&task->sighand->siglock); --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -1373,6 +1373,18 @@ int migrate_swap(struct task_struct *cur +@@ -1350,6 +1350,18 @@ int migrate_swap(struct task_struct *cur return ret; } @@ -134,7 +134,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * wait_task_inactive - wait for a thread to unschedule. * -@@ -1417,7 +1429,7 @@ unsigned long wait_task_inactive(struct +@@ -1394,7 +1406,7 @@ unsigned long wait_task_inactive(struct * is actually now running somewhere else! */ while (task_running(rq, p)) { @@ -143,7 +143,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return 0; cpu_relax(); } -@@ -1432,7 +1444,8 @@ unsigned long wait_task_inactive(struct +@@ -1409,7 +1421,8 @@ unsigned long wait_task_inactive(struct running = task_running(rq, p); queued = task_on_rq_queued(p); ncsw = 0; diff --git a/patches/radix-tree-use-local-locks.patch b/patches/radix-tree-use-local-locks.patch index 9450534e4302..723777307bc0 100644 --- a/patches/radix-tree-use-local-locks.patch +++ b/patches/radix-tree-use-local-locks.patch @@ -13,8 +13,8 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- include/linux/idr.h | 5 +---- include/linux/radix-tree.h | 7 ++----- - lib/radix-tree.c | 30 ++++++++++++++++++++++-------- - 3 files changed, 25 insertions(+), 17 deletions(-) + lib/radix-tree.c | 32 +++++++++++++++++++++++--------- + 3 files changed, 26 insertions(+), 18 deletions(-) --- a/include/linux/idr.h +++ b/include/linux/idr.h @@ -87,7 +87,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * Update the allocation stack trace as this is more useful * for debugging. -@@ -475,14 +477,14 @@ static int __radix_tree_preload(gfp_t gf +@@ -475,14 +477,14 @@ static __must_check int __radix_tree_pre */ gfp_mask &= ~__GFP_ACCOUNT; @@ -136,7 +136,12 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> static unsigned radix_tree_load_root(const struct radix_tree_root *root, struct radix_tree_node **nodep, unsigned long *maxindex) { -@@ -2107,6 +2115,12 @@ void idr_preload(gfp_t gfp_mask) +@@ -2104,10 +2112,16 @@ EXPORT_SYMBOL(radix_tree_tagged); + void idr_preload(gfp_t gfp_mask) + { + if (__radix_tree_preload(gfp_mask, IDR_PRELOAD_SIZE)) +- preempt_disable(); ++ local_lock(radix_tree_preloads_lock); } EXPORT_SYMBOL(idr_preload); @@ -149,12 +154,12 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /** * ida_pre_get - reserve resources for ida allocation * @ida: ida handle -@@ -2123,7 +2137,7 @@ int ida_pre_get(struct ida *ida, gfp_t g - * ida_get_new() can return -EAGAIN, prompting the caller +@@ -2124,7 +2138,7 @@ int ida_pre_get(struct ida *ida, gfp_t g * to return to the ida_pre_get() step. */ -- preempt_enable(); -+ local_unlock(radix_tree_preloads_lock); + if (!__radix_tree_preload(gfp, IDA_PRELOAD_SIZE)) +- preempt_enable(); ++ local_unlock(radix_tree_preloads_lock); if (!this_cpu_read(ida_bitmap)) { struct ida_bitmap *bitmap = kmalloc(sizeof(*bitmap), gfp); diff --git a/patches/random-avoid-preempt_disable-ed-section.patch b/patches/random-avoid-preempt_disable-ed-section.patch index eef8df002426..e8599cf4ef60 100644 --- a/patches/random-avoid-preempt_disable-ed-section.patch +++ b/patches/random-avoid-preempt_disable-ed-section.patch @@ -22,24 +22,24 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #include <crypto/chacha20.h> #include <asm/processor.h> -@@ -2030,6 +2031,7 @@ static rwlock_t batched_entropy_reset_lo - * goal of being quite fast and not depleting entropy. +@@ -2087,6 +2088,7 @@ static rwlock_t batched_entropy_reset_lo + * at any point prior. */ static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64); +static DEFINE_LOCAL_IRQ_LOCK(batched_entropy_u64_lock); u64 get_random_u64(void) { u64 ret; -@@ -2046,7 +2048,7 @@ u64 get_random_u64(void) - return ret; - #endif +@@ -2107,7 +2109,7 @@ u64 get_random_u64(void) + warn_unseeded_randomness(&previous); + use_lock = READ_ONCE(crng_init) < 2; - batch = &get_cpu_var(batched_entropy_u64); + batch = &get_locked_var(batched_entropy_u64_lock, batched_entropy_u64); if (use_lock) read_lock_irqsave(&batched_entropy_reset_lock, flags); if (batch->position % ARRAY_SIZE(batch->entropy_u64) == 0) { -@@ -2056,12 +2058,13 @@ u64 get_random_u64(void) +@@ -2117,12 +2119,13 @@ u64 get_random_u64(void) ret = batch->entropy_u64[batch->position++]; if (use_lock) read_unlock_irqrestore(&batched_entropy_reset_lock, flags); @@ -54,16 +54,16 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> u32 get_random_u32(void) { u32 ret; -@@ -2072,7 +2075,7 @@ u32 get_random_u32(void) - if (arch_get_random_int(&ret)) - return ret; +@@ -2137,7 +2140,7 @@ u32 get_random_u32(void) + warn_unseeded_randomness(&previous); + use_lock = READ_ONCE(crng_init) < 2; - batch = &get_cpu_var(batched_entropy_u32); + batch = &get_locked_var(batched_entropy_u32_lock, batched_entropy_u32); if (use_lock) read_lock_irqsave(&batched_entropy_reset_lock, flags); if (batch->position % ARRAY_SIZE(batch->entropy_u32) == 0) { -@@ -2082,7 +2085,7 @@ u32 get_random_u32(void) +@@ -2147,7 +2150,7 @@ u32 get_random_u32(void) ret = batch->entropy_u32[batch->position++]; if (use_lock) read_unlock_irqrestore(&batched_entropy_reset_lock, flags); diff --git a/patches/random-make-it-work-on-rt.patch b/patches/random-make-it-work-on-rt.patch index b1edc8efd3e3..34fcc16d8f51 100644 --- a/patches/random-make-it-work-on-rt.patch +++ b/patches/random-make-it-work-on-rt.patch @@ -20,8 +20,8 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/drivers/char/random.c +++ b/drivers/char/random.c -@@ -1109,28 +1109,27 @@ static __u32 get_reg(struct fast_pool *f - return *(ptr + f->reg_idx++); +@@ -1113,28 +1113,27 @@ static __u32 get_reg(struct fast_pool *f + return *ptr; } -void add_interrupt_randomness(int irq, int irq_flags) @@ -56,7 +56,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> add_interrupt_bench(cycles); --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c -@@ -970,6 +970,8 @@ static void vmbus_isr(void) +@@ -964,6 +964,8 @@ static void vmbus_isr(void) void *page_addr = hv_cpu->synic_event_page; struct hv_message *msg; union hv_synic_event_flags *event; @@ -65,7 +65,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> bool handled = false; if (unlikely(page_addr == NULL)) -@@ -1013,7 +1015,7 @@ static void vmbus_isr(void) +@@ -1007,7 +1009,7 @@ static void vmbus_isr(void) tasklet_schedule(&hv_cpu->msg_dpc); } @@ -76,7 +76,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/include/linux/irqdesc.h +++ b/include/linux/irqdesc.h -@@ -66,6 +66,7 @@ struct irq_desc { +@@ -69,6 +69,7 @@ struct irq_desc { unsigned int irqs_unhandled; atomic_t threads_handled; int threads_handled_last; @@ -94,10 +94,10 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +extern void add_interrupt_randomness(int irq, int irq_flags, __u64 ip) __latent_entropy; extern void get_random_bytes(void *buf, int nbytes); - extern int add_random_ready_callback(struct random_ready_callback *rdy); + extern int wait_for_random_bytes(void); --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c -@@ -181,10 +181,16 @@ irqreturn_t handle_irq_event_percpu(stru +@@ -183,10 +183,16 @@ irqreturn_t handle_irq_event_percpu(stru { irqreturn_t retval; unsigned int flags = 0; @@ -117,7 +117,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> note_interrupt(desc, retval); --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c -@@ -1025,6 +1025,12 @@ static int irq_thread(void *data) +@@ -1000,6 +1000,12 @@ static int irq_thread(void *data) if (action_ret == IRQ_WAKE_THREAD) irq_wake_secondary(desc, action); diff --git a/patches/rcu-Eliminate-softirq-processing-from-rcutree.patch b/patches/rcu-Eliminate-softirq-processing-from-rcutree.patch index 5de6ff8522ad..6b345126b56d 100644 --- a/patches/rcu-Eliminate-softirq-processing-from-rcutree.patch +++ b/patches/rcu-Eliminate-softirq-processing-from-rcutree.patch @@ -16,17 +16,17 @@ Tested-by: Mike Galbraith <bitbucket@online.de> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - kernel/rcu/tree.c | 110 ++++++++++++++++++++++++++++++--- + kernel/rcu/tree.c | 110 ++++++++++++++++++++++++++++++---- kernel/rcu/tree.h | 5 - - kernel/rcu/tree_plugin.h | 155 ++++++----------------------------------------- - 3 files changed, 122 insertions(+), 148 deletions(-) + kernel/rcu/tree_plugin.h | 152 ++++------------------------------------------- + 3 files changed, 114 insertions(+), 153 deletions(-) --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c -@@ -57,6 +57,11 @@ - #include <linux/random.h> +@@ -58,6 +58,11 @@ #include <linux/trace_events.h> #include <linux/suspend.h> + #include <linux/ftrace.h> +#include <linux/delay.h> +#include <linux/gfp.h> +#include <linux/oom.h> @@ -35,7 +35,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #include "tree.h" #include "rcu.h" -@@ -3143,18 +3148,17 @@ static void +@@ -3042,18 +3047,17 @@ static void /* * Do RCU core processing for the current CPU. */ @@ -56,7 +56,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * Schedule RCU callback invocation. If the specified type of RCU * does not support RCU priority boosting, just do a direct call, -@@ -3166,18 +3170,105 @@ static void invoke_rcu_callbacks(struct +@@ -3065,18 +3069,105 @@ static void invoke_rcu_callbacks(struct { if (unlikely(!READ_ONCE(rcu_scheduler_fully_active))) return; @@ -168,7 +168,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * Handle any core-RCU processing required by a call_rcu() invocation. -@@ -4357,7 +4448,6 @@ void __init rcu_init(void) +@@ -4262,7 +4353,6 @@ void __init rcu_init(void) if (dump_tree) rcu_dump_rcu_node_tree(&rcu_sched_state); __rcu_init_preempt(); @@ -178,9 +178,9 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * We don't need protection against CPU-hotplug here because --- a/kernel/rcu/tree.h +++ b/kernel/rcu/tree.h -@@ -599,12 +599,10 @@ extern struct rcu_state rcu_preempt_stat - +@@ -447,12 +447,10 @@ extern struct rcu_state rcu_preempt_stat int rcu_dynticks_snap(struct rcu_dynticks *rdtp); + bool rcu_eqs_special_set(int cpu); -#ifdef CONFIG_RCU_BOOST DECLARE_PER_CPU(unsigned int, rcu_cpu_kthread_status); @@ -191,7 +191,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #ifndef RCU_TREE_NONCORE -@@ -624,10 +622,9 @@ void call_rcu(struct rcu_head *head, rcu +@@ -472,10 +470,9 @@ void call_rcu(struct rcu_head *head, rcu static void __init __rcu_init_preempt(void); static void rcu_initiate_boost(struct rcu_node *rnp, unsigned long flags); static void rcu_preempt_boost_start_gp(struct rcu_node *rnp); @@ -205,7 +205,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #endif /* #ifdef CONFIG_RCU_BOOST */ --- a/kernel/rcu/tree_plugin.h +++ b/kernel/rcu/tree_plugin.h -@@ -24,28 +24,10 @@ +@@ -24,39 +24,16 @@ * Paul E. McKenney <paulmck@linux.vnet.ibm.com> */ @@ -217,39 +217,35 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -#include <linux/jiffies.h> -#include <uapi/linux/sched/types.h> -#include "../time/tick-internal.h" -- - #ifdef CONFIG_RCU_BOOST - #include "../locking/rtmutex_common.h" --/* -- * Control variables for per-CPU and per-rcu_node kthreads. These -- * handle all flavors of RCU. -- */ --static DEFINE_PER_CPU(struct task_struct *, rcu_cpu_kthread_task); --DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_status); --DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_loops); --DEFINE_PER_CPU(char, rcu_cpu_has_work); +-#ifdef CONFIG_RCU_BOOST - - #else /* #ifdef CONFIG_RCU_BOOST */ - /* -@@ -58,6 +40,14 @@ DEFINE_PER_CPU(char, rcu_cpu_has_work); - - #endif /* #else #ifdef CONFIG_RCU_BOOST */ + * Control variables for per-CPU and per-rcu_node kthreads. These + * handle all flavors of RCU. + */ +-static DEFINE_PER_CPU(struct task_struct *, rcu_cpu_kthread_task); + DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_status); + DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_loops); + DEFINE_PER_CPU(char, rcu_cpu_has_work); -+/* -+ * Control variables for per-CPU and per-rcu_node kthreads. These -+ * handle all flavors of RCU. -+ */ -+DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_status); -+DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_loops); -+DEFINE_PER_CPU(char, rcu_cpu_has_work); -+ +-#else /* #ifdef CONFIG_RCU_BOOST */ +- +-/* +- * Some architectures do not define rt_mutexes, but if !CONFIG_RCU_BOOST, +- * all uses are in dead code. Provide a definition to keep the compiler +- * happy, but add WARN_ON_ONCE() to complain if used in the wrong place. +- * This probably needs to be excluded from -rt builds. +- */ +-#define rt_mutex_owner(a) ({ WARN_ON_ONCE(1); NULL; }) +- +-#endif /* #else #ifdef CONFIG_RCU_BOOST */ +- #ifdef CONFIG_RCU_NOCB_CPU static cpumask_var_t rcu_nocb_mask; /* CPUs to have callbacks offloaded. */ static bool have_rcu_nocb_mask; /* Was rcu_nocb_mask allocated? */ -@@ -635,15 +625,6 @@ static void rcu_preempt_check_callbacks( +@@ -668,15 +645,6 @@ static void rcu_preempt_check_callbacks( t->rcu_read_unlock_special.b.need_qs = true; } @@ -262,10 +258,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> - -#endif /* #ifdef CONFIG_RCU_BOOST */ - - /* - * Queue a preemptible-RCU callback for invocation after a grace period. - */ -@@ -832,6 +813,19 @@ void exit_rcu(void) + /** + * call_rcu() - Queue an RCU callback for invocation after a grace period. + * @head: structure to be used for queueing the RCU updates. +@@ -899,20 +867,23 @@ void exit_rcu(void) #endif /* #else #ifdef CONFIG_PREEMPT_RCU */ @@ -274,21 +270,11 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + */ +static void rcu_cpu_kthread_setup(unsigned int cpu) +{ -+#ifdef CONFIG_RCU_BOOST -+ struct sched_param sp; -+ -+ sp.sched_priority = kthread_prio; -+ sched_setscheduler_nocheck(current, SCHED_FIFO, &sp); -+#endif /* #ifdef CONFIG_RCU_BOOST */ -+} -+ #ifdef CONFIG_RCU_BOOST ++ struct sched_param sp; - #include "../locking/rtmutex_common.h" -@@ -863,16 +857,6 @@ static void rcu_initiate_boost_trace(str - - #endif /* #else #ifdef CONFIG_RCU_TRACE */ - +-#include "../locking/rtmutex_common.h" +- -static void rcu_wake_cond(struct task_struct *t, int status) -{ - /* @@ -297,12 +283,19 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> - */ - if (status != RCU_KTHREAD_YIELDING || is_idle_task(current)) - wake_up_process(t); --} -- ++ sp.sched_priority = kthread_prio; ++ sched_setscheduler_nocheck(current, SCHED_FIFO, &sp); ++#endif /* #ifdef CONFIG_RCU_BOOST */ + } + ++#ifdef CONFIG_RCU_BOOST ++ ++#include "../locking/rtmutex_common.h" ++ /* * Carry out RCU priority boosting on the task indicated by ->exp_tasks * or ->boost_tasks, advancing the pointer to the next task in the -@@ -1016,23 +1000,6 @@ static void rcu_initiate_boost(struct rc +@@ -1055,23 +1026,6 @@ static void rcu_initiate_boost(struct rc } /* @@ -326,7 +319,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> * Is the current CPU running the RCU-callbacks kthread? * Caller must have preemption disabled. */ -@@ -1086,67 +1053,6 @@ static int rcu_spawn_one_boost_kthread(s +@@ -1125,67 +1079,6 @@ static int rcu_spawn_one_boost_kthread(s return 0; } @@ -394,7 +387,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* * Set the per-rcu_node kthread's affinity to cover all CPUs that are * served by the rcu_node in question. The CPU hotplug lock is still -@@ -1177,26 +1083,12 @@ static void rcu_boost_kthread_setaffinit +@@ -1216,26 +1109,12 @@ static void rcu_boost_kthread_setaffinit free_cpumask_var(cm); } @@ -421,7 +414,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> rcu_for_each_leaf_node(rcu_state_p, rnp) (void)rcu_spawn_one_boost_kthread(rcu_state_p, rnp); } -@@ -1219,11 +1111,6 @@ static void rcu_initiate_boost(struct rc +@@ -1258,11 +1137,6 @@ static void rcu_initiate_boost(struct rc raw_spin_unlock_irqrestore_rcu_node(rnp, flags); } diff --git a/patches/rcu-Suppress-lockdep-false-positive-boost_mtx-compla.patch b/patches/rcu-Suppress-lockdep-false-positive-boost_mtx-compla.patch new file mode 100644 index 000000000000..1e6c829100d7 --- /dev/null +++ b/patches/rcu-Suppress-lockdep-false-positive-boost_mtx-compla.patch @@ -0,0 +1,49 @@ +From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> +Date: Tue, 19 Sep 2017 15:36:42 -0700 +Subject: [PATCH] rcu: Suppress lockdep false-positive ->boost_mtx complaints + +Upstream commit bcda31a2659497df39d6bedfbdf17498b4f4ac89 + +RCU priority boosting uses rt_mutex_init_proxy_locked() to initialize an +rt_mutex structure in locked state held by some other task. When that +other task releases it, lockdep complains (quite accurately, but a bit +uselessly) that the other task never acquired it. This complaint can +suppress other, more helpful, lockdep complaints, and in any case it is +a false positive. + +This commit therefore switches from rt_mutex_unlock() to +rt_mutex_futex_unlock(), thereby avoiding the lockdep annotations. +Of course, if lockdep ever learns about rt_mutex_init_proxy_locked(), +addtional adjustments will be required. + +Suggested-by: Peter Zijlstra <peterz@infradead.org> +Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + kernel/rcu/tree_plugin.h | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/kernel/rcu/tree_plugin.h ++++ b/kernel/rcu/tree_plugin.h +@@ -31,11 +31,10 @@ + #include <linux/smpboot.h> + #include <uapi/linux/sched/types.h> + #include "../time/tick-internal.h" ++#include "../locking/rtmutex_common.h" + + #ifdef CONFIG_RCU_BOOST + +-#include "../locking/rtmutex_common.h" +- + /* + * Control variables for per-CPU and per-rcu_node kthreads. These + * handle all flavors of RCU. +@@ -523,7 +522,7 @@ void rcu_read_unlock_special(struct task + + /* Unboost if we were boosted. */ + if (IS_ENABLED(CONFIG_RCU_BOOST) && drop_boost_mutex) +- rt_mutex_unlock(&rnp->boost_mtx); ++ rt_mutex_futex_unlock(&rnp->boost_mtx); + + /* + * If this was the last task on the expedited lists, diff --git a/patches/rcu-disable-rcu-fast-no-hz-on-rt.patch b/patches/rcu-disable-rcu-fast-no-hz-on-rt.patch index bb3cc11c220d..b687c5275d54 100644 --- a/patches/rcu-disable-rcu-fast-no-hz-on-rt.patch +++ b/patches/rcu-disable-rcu-fast-no-hz-on-rt.patch @@ -8,12 +8,12 @@ code. Disable it for now to prevent wreckage. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- - init/Kconfig | 2 +- + kernel/rcu/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -622,7 +622,7 @@ config RCU_FANOUT_LEAF +--- a/kernel/rcu/Kconfig ++++ b/kernel/rcu/Kconfig +@@ -173,7 +173,7 @@ config RCU_FANOUT_LEAF config RCU_FAST_NO_HZ bool "Accelerate last non-dyntick-idle CPU's grace periods" diff --git a/patches/rcu-enable-rcu_normal_after_boot-by-default-for-RT.patch b/patches/rcu-enable-rcu_normal_after_boot-by-default-for-RT.patch index 1f45e1c6094b..ad00b652fefe 100644 --- a/patches/rcu-enable-rcu_normal_after_boot-by-default-for-RT.patch +++ b/patches/rcu-enable-rcu_normal_after_boot-by-default-for-RT.patch @@ -18,9 +18,9 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/rcu/update.c +++ b/kernel/rcu/update.c -@@ -64,7 +64,7 @@ - #ifndef CONFIG_TINY_RCU +@@ -66,7 +66,7 @@ extern int rcu_expedited; /* from sysctl module_param(rcu_expedited, int, 0); + extern int rcu_normal; /* from sysctl */ module_param(rcu_normal, int, 0); -static int rcu_normal_after_boot; +static int rcu_normal_after_boot = IS_ENABLED(CONFIG_PREEMPT_RT_FULL); diff --git a/patches/rcu-make-RCU_BOOST-default-on-RT.patch b/patches/rcu-make-RCU_BOOST-default-on-RT.patch index 9c343b466d1e..b0694274f767 100644 --- a/patches/rcu-make-RCU_BOOST-default-on-RT.patch +++ b/patches/rcu-make-RCU_BOOST-default-on-RT.patch @@ -9,12 +9,12 @@ someone knows better. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - init/Kconfig | 4 ++-- + kernel/rcu/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) ---- a/init/Kconfig -+++ b/init/Kconfig -@@ -506,7 +506,7 @@ config TINY_RCU +--- a/kernel/rcu/Kconfig ++++ b/kernel/rcu/Kconfig +@@ -36,7 +36,7 @@ config TINY_RCU config RCU_EXPERT bool "Make expert-level adjustments to RCU configuration" @@ -23,7 +23,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> help This option needs to be enabled if you wish to make expert-level adjustments to RCU configuration. By default, -@@ -649,7 +649,7 @@ config TREE_RCU_TRACE +@@ -192,7 +192,7 @@ config RCU_FAST_NO_HZ config RCU_BOOST bool "Enable RCU priority boosting" depends on RT_MUTEXES && PREEMPT_RCU && RCU_EXPERT diff --git a/patches/rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch b/patches/rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch index af6e8e692d42..b0237ff4c0e2 100644 --- a/patches/rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch +++ b/patches/rcu-merge-rcu-bh-into-rcu-preempt-for-rt.patch @@ -25,34 +25,29 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- include/linux/rcupdate.h | 23 +++++++++++++++++++++++ - include/linux/rcutree.h | 21 ++++++++++++++++++--- + include/linux/rcutree.h | 8 ++++++++ + kernel/rcu/rcu.h | 14 +++++++++++--- kernel/rcu/rcutorture.c | 7 +++++++ kernel/rcu/tree.c | 24 ++++++++++++++++++++++++ kernel/rcu/tree.h | 2 ++ kernel/rcu/update.c | 2 ++ - 6 files changed, 76 insertions(+), 3 deletions(-) + 7 files changed, 77 insertions(+), 3 deletions(-) --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h -@@ -178,6 +178,9 @@ void call_rcu(struct rcu_head *head, - +@@ -56,7 +56,11 @@ void call_rcu(struct rcu_head *head, rcu + #define call_rcu call_rcu_sched #endif /* #else #ifdef CONFIG_PREEMPT_RCU */ +#ifdef CONFIG_PREEMPT_RT_FULL +#define call_rcu_bh call_rcu +#else - /** - * call_rcu_bh() - Queue an RCU for invocation after a quicker grace period. - * @head: structure to be used for queueing the RCU updates. -@@ -201,6 +204,7 @@ void call_rcu(struct rcu_head *head, - */ - void call_rcu_bh(struct rcu_head *head, - rcu_callback_t func); + void call_rcu_bh(struct rcu_head *head, rcu_callback_t func); +#endif - - /** - * call_rcu_sched() - Queue an RCU for invocation after sched grace period. -@@ -299,7 +303,11 @@ static inline int rcu_preempt_depth(void + void call_rcu_sched(struct rcu_head *head, rcu_callback_t func); + void synchronize_sched(void); + void call_rcu_tasks(struct rcu_head *head, rcu_callback_t func); +@@ -114,7 +118,11 @@ static inline int rcu_preempt_depth(void /* Internal to kernel */ void rcu_init(void); void rcu_sched_qs(void); @@ -64,9 +59,9 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> void rcu_check_callbacks(int user); void rcu_report_dead(unsigned int cpu); void rcu_cpu_starting(unsigned int cpu); -@@ -473,7 +481,14 @@ extern struct lockdep_map rcu_callback_m +@@ -258,7 +266,14 @@ extern struct lockdep_map rcu_sched_lock + extern struct lockdep_map rcu_callback_map; int debug_lockdep_rcu_enabled(void); - int rcu_read_lock_held(void); +#ifdef CONFIG_PREEMPT_RT_FULL +static inline int rcu_read_lock_bh_held(void) @@ -76,10 +71,10 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +#else int rcu_read_lock_bh_held(void); +#endif + int rcu_read_lock_sched_held(void); - /** - * rcu_read_lock_sched_held() - might we be in RCU-sched read-side critical section? -@@ -871,10 +886,14 @@ static inline void rcu_read_unlock(void) + #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */ +@@ -645,10 +660,14 @@ static inline void rcu_read_unlock(void) static inline void rcu_read_lock_bh(void) { local_bh_disable(); @@ -94,7 +89,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } /* -@@ -884,10 +903,14 @@ static inline void rcu_read_lock_bh(void +@@ -658,10 +677,14 @@ static inline void rcu_read_lock_bh(void */ static inline void rcu_read_unlock_bh(void) { @@ -112,7 +107,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/include/linux/rcutree.h +++ b/include/linux/rcutree.h @@ -44,7 +44,11 @@ static inline void rcu_virt_note_context - rcu_note_context_switch(); + rcu_note_context_switch(false); } +#ifdef CONFIG_PREEMPT_RT_FULL @@ -135,7 +130,9 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> void rcu_barrier_sched(void); unsigned long get_state_synchronize_rcu(void); void cond_synchronize_rcu(unsigned long oldstate); -@@ -82,17 +90,14 @@ void cond_synchronize_sched(unsigned lon +--- a/kernel/rcu/rcu.h ++++ b/kernel/rcu/rcu.h +@@ -550,18 +550,26 @@ static inline void show_rcu_gp_kthreads( extern unsigned long rcutorture_testseq; extern unsigned long rcutorture_vernum; unsigned long rcu_batches_started(void); @@ -146,17 +143,12 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> unsigned long rcu_batches_completed_sched(void); unsigned long rcu_exp_batches_completed(void); unsigned long rcu_exp_batches_completed_sched(void); + unsigned long srcu_batches_completed(struct srcu_struct *sp); void show_rcu_gp_kthreads(void); - void rcu_force_quiescent_state(void); -void rcu_bh_force_quiescent_state(void); void rcu_sched_force_quiescent_state(void); - - void rcu_idle_enter(void); -@@ -109,6 +114,16 @@ extern int rcu_scheduler_active __read_m - - bool rcu_is_watching(void); - ++ +#ifndef CONFIG_PREEMPT_RT_FULL +void rcu_bh_force_quiescent_state(void); +unsigned long rcu_batches_started_bh(void); @@ -167,12 +159,12 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +# define rcu_batches_started_bh rcu_batches_completed +#endif + - void rcu_all_qs(void); + #endif /* #else #ifdef CONFIG_TINY_RCU */ - /* RCUtree hotplug events */ + #ifdef CONFIG_RCU_NOCB_CPU --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c -@@ -414,6 +414,7 @@ static struct rcu_torture_ops rcu_ops = +@@ -416,6 +416,7 @@ static struct rcu_torture_ops rcu_ops = .name = "rcu" }; @@ -180,7 +172,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * Definitions for rcu_bh torture testing. */ -@@ -453,6 +454,12 @@ static struct rcu_torture_ops rcu_bh_ops +@@ -455,6 +456,12 @@ static struct rcu_torture_ops rcu_bh_ops .name = "rcu_bh" }; @@ -195,23 +187,23 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> * The names includes "busted", and they really means it! --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c -@@ -262,6 +262,7 @@ void rcu_sched_qs(void) +@@ -246,6 +246,7 @@ void rcu_sched_qs(void) this_cpu_ptr(&rcu_sched_data), true); } +#ifndef CONFIG_PREEMPT_RT_FULL void rcu_bh_qs(void) { - if (__this_cpu_read(rcu_bh_data.cpu_no_qs.s)) { -@@ -271,6 +272,7 @@ void rcu_bh_qs(void) + RCU_LOCKDEP_WARN(preemptible(), "rcu_bh_qs() invoked with preemption enabled!!!"); +@@ -256,6 +257,7 @@ void rcu_bh_qs(void) __this_cpu_write(rcu_bh_data.cpu_no_qs.b.norm, false); } } +#endif - static DEFINE_PER_CPU(int, rcu_sched_qs_mask); - -@@ -557,11 +559,13 @@ EXPORT_SYMBOL_GPL(rcu_batches_started_sc + /* + * Steal a bit from the bottom of ->dynticks for idle entry/exit +@@ -567,11 +569,13 @@ EXPORT_SYMBOL_GPL(rcu_batches_started_sc /* * Return the number of RCU BH batches started thus far for debug & stats. */ @@ -225,7 +217,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * Return the number of RCU batches completed thus far for debug & stats. -@@ -581,6 +585,7 @@ unsigned long rcu_batches_completed_sche +@@ -591,6 +595,7 @@ unsigned long rcu_batches_completed_sche } EXPORT_SYMBOL_GPL(rcu_batches_completed_sched); @@ -233,7 +225,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * Return the number of RCU BH batches completed thus far for debug & stats. */ -@@ -589,6 +594,7 @@ unsigned long rcu_batches_completed_bh(v +@@ -599,6 +604,7 @@ unsigned long rcu_batches_completed_bh(v return rcu_bh_state.completed; } EXPORT_SYMBOL_GPL(rcu_batches_completed_bh); @@ -241,7 +233,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * Return the number of RCU expedited batches completed thus far for -@@ -612,6 +618,7 @@ unsigned long rcu_exp_batches_completed_ +@@ -622,6 +628,7 @@ unsigned long rcu_exp_batches_completed_ } EXPORT_SYMBOL_GPL(rcu_exp_batches_completed_sched); @@ -249,7 +241,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * Force a quiescent state. */ -@@ -630,6 +637,13 @@ void rcu_bh_force_quiescent_state(void) +@@ -640,6 +647,13 @@ void rcu_bh_force_quiescent_state(void) } EXPORT_SYMBOL_GPL(rcu_bh_force_quiescent_state); @@ -263,7 +255,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * Force a quiescent state for RCU-sched. */ -@@ -680,9 +694,11 @@ void rcutorture_get_gp_data(enum rcutort +@@ -690,9 +704,11 @@ void rcutorture_get_gp_data(enum rcutort case RCU_FLAVOR: rsp = rcu_state_p; break; @@ -275,15 +267,15 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> case RCU_SCHED_FLAVOR: rsp = &rcu_sched_state; break; -@@ -3289,6 +3305,7 @@ void call_rcu_sched(struct rcu_head *hea +@@ -3208,6 +3224,7 @@ void call_rcu_sched(struct rcu_head *hea } EXPORT_SYMBOL_GPL(call_rcu_sched); +#ifndef CONFIG_PREEMPT_RT_FULL - /* - * Queue an RCU callback for invocation after a quicker grace period. - */ -@@ -3297,6 +3314,7 @@ void call_rcu_bh(struct rcu_head *head, + /** + * call_rcu_bh() - Queue an RCU for invocation after a quicker grace period. + * @head: structure to be used for queueing the RCU updates. +@@ -3234,6 +3251,7 @@ void call_rcu_bh(struct rcu_head *head, __call_rcu(head, func, &rcu_bh_state, -1, 0); } EXPORT_SYMBOL_GPL(call_rcu_bh); @@ -291,7 +283,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * Queue an RCU callback for lazy invocation after a grace period. -@@ -3388,6 +3406,7 @@ void synchronize_sched(void) +@@ -3319,6 +3337,7 @@ void synchronize_sched(void) } EXPORT_SYMBOL_GPL(synchronize_sched); @@ -299,7 +291,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /** * synchronize_rcu_bh - wait until an rcu_bh grace period has elapsed. * -@@ -3414,6 +3433,7 @@ void synchronize_rcu_bh(void) +@@ -3345,6 +3364,7 @@ void synchronize_rcu_bh(void) wait_rcu_gp(call_rcu_bh); } EXPORT_SYMBOL_GPL(synchronize_rcu_bh); @@ -307,7 +299,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /** * get_state_synchronize_rcu - Snapshot current RCU state -@@ -3790,6 +3810,7 @@ static void _rcu_barrier(struct rcu_stat +@@ -3692,6 +3712,7 @@ static void _rcu_barrier(struct rcu_stat mutex_unlock(&rsp->barrier_mutex); } @@ -315,7 +307,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /** * rcu_barrier_bh - Wait until all in-flight call_rcu_bh() callbacks complete. */ -@@ -3798,6 +3819,7 @@ void rcu_barrier_bh(void) +@@ -3700,6 +3721,7 @@ void rcu_barrier_bh(void) _rcu_barrier(&rcu_bh_state); } EXPORT_SYMBOL_GPL(rcu_barrier_bh); @@ -323,7 +315,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /** * rcu_barrier_sched - Wait for in-flight call_rcu_sched() callbacks. -@@ -4316,7 +4338,9 @@ void __init rcu_init(void) +@@ -4225,7 +4247,9 @@ void __init rcu_init(void) rcu_bootup_announce(); rcu_init_geometry(); @@ -335,7 +327,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> rcu_dump_rcu_node_tree(&rcu_sched_state); --- a/kernel/rcu/tree.h +++ b/kernel/rcu/tree.h -@@ -589,7 +589,9 @@ extern struct list_head rcu_struct_flavo +@@ -436,7 +436,9 @@ extern struct list_head rcu_struct_flavo */ extern struct rcu_state rcu_sched_state; @@ -347,7 +339,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> extern struct rcu_state rcu_preempt_state; --- a/kernel/rcu/update.c +++ b/kernel/rcu/update.c -@@ -298,6 +298,7 @@ int rcu_read_lock_held(void) +@@ -333,6 +333,7 @@ int rcu_read_lock_held(void) } EXPORT_SYMBOL_GPL(rcu_read_lock_held); @@ -355,7 +347,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /** * rcu_read_lock_bh_held() - might we be in RCU-bh read-side critical section? * -@@ -324,6 +325,7 @@ int rcu_read_lock_bh_held(void) +@@ -359,6 +360,7 @@ int rcu_read_lock_bh_held(void) return in_softirq() || irqs_disabled(); } EXPORT_SYMBOL_GPL(rcu_read_lock_bh_held); diff --git a/patches/rcu-segcblist-include-rcupdate.h.patch b/patches/rcu-segcblist-include-rcupdate.h.patch new file mode 100644 index 000000000000..af666d6b1884 --- /dev/null +++ b/patches/rcu-segcblist-include-rcupdate.h.patch @@ -0,0 +1,21 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Fri, 22 Sep 2017 15:01:46 +0200 +Subject: [PATCH] rcu/segcblist: include rcupdate.h + +The RT build on ARM complains about non-existing ULONG_CMP_LT. + +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + kernel/rcu/rcu_segcblist.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/kernel/rcu/rcu_segcblist.c ++++ b/kernel/rcu/rcu_segcblist.c +@@ -23,6 +23,7 @@ + #include <linux/types.h> + #include <linux/kernel.h> + #include <linux/interrupt.h> ++#include <linux/rcupdate.h> + + #include "rcu_segcblist.h" + diff --git a/patches/rcutree-rcu_bh_qs-disable-irq-while-calling-rcu_pree.patch b/patches/rcutree-rcu_bh_qs-disable-irq-while-calling-rcu_pree.patch index ae2c5b679a35..9e8e79d3c782 100644 --- a/patches/rcutree-rcu_bh_qs-disable-irq-while-calling-rcu_pree.patch +++ b/patches/rcutree-rcu_bh_qs-disable-irq-while-calling-rcu_pree.patch @@ -33,7 +33,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c -@@ -267,7 +267,12 @@ static void rcu_preempt_qs(void); +@@ -251,7 +251,12 @@ static void rcu_preempt_qs(void); void rcu_bh_qs(void) { diff --git a/patches/rt-Increase-decrease-the-nr-of-migratory-tasks-when-.patch b/patches/rt-Increase-decrease-the-nr-of-migratory-tasks-when-.patch index 3efe6bb93b74..0122e29729c2 100644 --- a/patches/rt-Increase-decrease-the-nr-of-migratory-tasks-when-.patch +++ b/patches/rt-Increase-decrease-the-nr-of-migratory-tasks-when-.patch @@ -80,7 +80,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -7448,6 +7448,47 @@ const u32 sched_prio_to_wmult[40] = { +@@ -6807,6 +6807,47 @@ const u32 sched_prio_to_wmult[40] = { #if defined(CONFIG_PREEMPT_COUNT) && defined(CONFIG_SMP) @@ -128,7 +128,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> void migrate_disable(void) { struct task_struct *p = current; -@@ -7468,10 +7509,9 @@ void migrate_disable(void) +@@ -6827,10 +6868,9 @@ void migrate_disable(void) } preempt_disable(); @@ -141,7 +141,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> preempt_enable(); } -@@ -7500,9 +7540,8 @@ void migrate_enable(void) +@@ -6859,9 +6899,8 @@ void migrate_enable(void) preempt_disable(); diff --git a/patches/rt-add-rt-locks.patch b/patches/rt-add-rt-locks.patch deleted file mode 100644 index 89e706c8cc53..000000000000 --- a/patches/rt-add-rt-locks.patch +++ /dev/null @@ -1,2400 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Sun, 26 Jul 2009 19:39:56 +0200 -Subject: rt: Add the preempt-rt lock replacement APIs - -Map spinlocks, rwlocks, rw_semaphores and semaphores to the rt_mutex -based locking functions for preempt-rt. -This also introduces RT's sleeping locks. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> - ---- - include/linux/kernel.h | 4 - include/linux/locallock.h | 6 - include/linux/mutex.h | 20 - - include/linux/mutex_rt.h | 130 +++++++++ - include/linux/rtmutex.h | 29 +- - include/linux/rwlock_rt.h | 99 +++++++ - include/linux/rwlock_types_rt.h | 33 ++ - include/linux/rwsem.h | 6 - include/linux/rwsem_rt.h | 167 ++++++++++++ - include/linux/sched.h | 8 - include/linux/sched/wake_q.h | 11 - include/linux/spinlock.h | 12 - include/linux/spinlock_api_smp.h | 4 - include/linux/spinlock_rt.h | 162 +++++++++++ - include/linux/spinlock_types.h | 11 - include/linux/spinlock_types_rt.h | 48 +++ - kernel/futex.c | 11 - kernel/locking/Makefile | 9 - kernel/locking/rt.c | 521 ++++++++++++++++++++++++++++++++++++++ - kernel/locking/rtmutex.c | 480 ++++++++++++++++++++++++++++++++--- - kernel/locking/rtmutex_common.h | 10 - kernel/locking/spinlock.c | 7 - kernel/locking/spinlock_debug.c | 5 - kernel/sched/core.c | 7 - 24 files changed, 1734 insertions(+), 66 deletions(-) - ---- a/include/linux/kernel.h -+++ b/include/linux/kernel.h -@@ -201,6 +201,9 @@ extern int _cond_resched(void); - */ - # define might_sleep() \ - do { __might_sleep(__FILE__, __LINE__, 0); might_resched(); } while (0) -+ -+# define might_sleep_no_state_check() \ -+ do { ___might_sleep(__FILE__, __LINE__, 0); might_resched(); } while (0) - # define sched_annotate_sleep() (current->task_state_change = 0) - #else - static inline void ___might_sleep(const char *file, int line, -@@ -208,6 +211,7 @@ extern int _cond_resched(void); - static inline void __might_sleep(const char *file, int line, - int preempt_offset) { } - # define might_sleep() do { might_resched(); } while (0) -+# define might_sleep_no_state_check() do { might_resched(); } while (0) - # define sched_annotate_sleep() do { } while (0) - #endif - ---- a/include/linux/locallock.h -+++ b/include/linux/locallock.h -@@ -42,9 +42,15 @@ struct local_irq_lock { - * already takes care of the migrate_disable/enable - * for CONFIG_PREEMPT_BASE map to the normal spin_* calls. - */ -+#ifdef CONFIG_PREEMPT_RT_FULL -+# define spin_lock_local(lock) rt_spin_lock__no_mg(lock) -+# define spin_trylock_local(lock) rt_spin_trylock__no_mg(lock) -+# define spin_unlock_local(lock) rt_spin_unlock__no_mg(lock) -+#else - # define spin_lock_local(lock) spin_lock(lock) - # define spin_trylock_local(lock) spin_trylock(lock) - # define spin_unlock_local(lock) spin_unlock(lock) -+#endif - - static inline void __local_lock(struct local_irq_lock *lv) - { ---- a/include/linux/mutex.h -+++ b/include/linux/mutex.h -@@ -22,6 +22,17 @@ - - struct ww_acquire_ctx; - -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+# define __DEP_MAP_MUTEX_INITIALIZER(lockname) \ -+ , .dep_map = { .name = #lockname } -+#else -+# define __DEP_MAP_MUTEX_INITIALIZER(lockname) -+#endif -+ -+#ifdef CONFIG_PREEMPT_RT_FULL -+# include <linux/mutex_rt.h> -+#else -+ - /* - * Simple, straightforward mutexes with strict semantics: - * -@@ -113,13 +124,6 @@ do { \ - __mutex_init((mutex), #mutex, &__key); \ - } while (0) - --#ifdef CONFIG_DEBUG_LOCK_ALLOC --# define __DEP_MAP_MUTEX_INITIALIZER(lockname) \ -- , .dep_map = { .name = #lockname } --#else --# define __DEP_MAP_MUTEX_INITIALIZER(lockname) --#endif -- - #define __MUTEX_INITIALIZER(lockname) \ - { .owner = ATOMIC_LONG_INIT(0) \ - , .wait_lock = __SPIN_LOCK_UNLOCKED(lockname.wait_lock) \ -@@ -227,4 +231,6 @@ mutex_trylock_recursive(struct mutex *lo - return mutex_trylock(lock); - } - -+#endif /* !PREEMPT_RT_FULL */ -+ - #endif /* __LINUX_MUTEX_H */ ---- /dev/null -+++ b/include/linux/mutex_rt.h -@@ -0,0 +1,130 @@ -+#ifndef __LINUX_MUTEX_RT_H -+#define __LINUX_MUTEX_RT_H -+ -+#ifndef __LINUX_MUTEX_H -+#error "Please include mutex.h" -+#endif -+ -+#include <linux/rtmutex.h> -+ -+/* FIXME: Just for __lockfunc */ -+#include <linux/spinlock.h> -+ -+struct mutex { -+ struct rt_mutex lock; -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+ struct lockdep_map dep_map; -+#endif -+}; -+ -+#define __MUTEX_INITIALIZER(mutexname) \ -+ { \ -+ .lock = __RT_MUTEX_INITIALIZER(mutexname.lock) \ -+ __DEP_MAP_MUTEX_INITIALIZER(mutexname) \ -+ } -+ -+#define DEFINE_MUTEX(mutexname) \ -+ struct mutex mutexname = __MUTEX_INITIALIZER(mutexname) -+ -+extern void __mutex_do_init(struct mutex *lock, const char *name, struct lock_class_key *key); -+extern void __lockfunc _mutex_lock(struct mutex *lock); -+extern void __lockfunc _mutex_lock_io(struct mutex *lock); -+extern void __lockfunc _mutex_lock_io_nested(struct mutex *lock, int subclass); -+extern int __lockfunc _mutex_lock_interruptible(struct mutex *lock); -+extern int __lockfunc _mutex_lock_killable(struct mutex *lock); -+extern void __lockfunc _mutex_lock_nested(struct mutex *lock, int subclass); -+extern void __lockfunc _mutex_lock_nest_lock(struct mutex *lock, struct lockdep_map *nest_lock); -+extern int __lockfunc _mutex_lock_interruptible_nested(struct mutex *lock, int subclass); -+extern int __lockfunc _mutex_lock_killable_nested(struct mutex *lock, int subclass); -+extern int __lockfunc _mutex_trylock(struct mutex *lock); -+extern void __lockfunc _mutex_unlock(struct mutex *lock); -+ -+#define mutex_is_locked(l) rt_mutex_is_locked(&(l)->lock) -+#define mutex_lock(l) _mutex_lock(l) -+#define mutex_lock_interruptible(l) _mutex_lock_interruptible(l) -+#define mutex_lock_killable(l) _mutex_lock_killable(l) -+#define mutex_trylock(l) _mutex_trylock(l) -+#define mutex_unlock(l) _mutex_unlock(l) -+#define mutex_lock_io(l) _mutex_lock_io(l); -+ -+#define __mutex_owner(l) ((l)->lock.owner) -+ -+#ifdef CONFIG_DEBUG_MUTEXES -+#define mutex_destroy(l) rt_mutex_destroy(&(l)->lock) -+#else -+static inline void mutex_destroy(struct mutex *lock) {} -+#endif -+ -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+# define mutex_lock_nested(l, s) _mutex_lock_nested(l, s) -+# define mutex_lock_interruptible_nested(l, s) \ -+ _mutex_lock_interruptible_nested(l, s) -+# define mutex_lock_killable_nested(l, s) \ -+ _mutex_lock_killable_nested(l, s) -+# define mutex_lock_io_nested(l, s) _mutex_lock_io_nested(l, s) -+ -+# define mutex_lock_nest_lock(lock, nest_lock) \ -+do { \ -+ typecheck(struct lockdep_map *, &(nest_lock)->dep_map); \ -+ _mutex_lock_nest_lock(lock, &(nest_lock)->dep_map); \ -+} while (0) -+ -+#else -+# define mutex_lock_nested(l, s) _mutex_lock(l) -+# define mutex_lock_interruptible_nested(l, s) \ -+ _mutex_lock_interruptible(l) -+# define mutex_lock_killable_nested(l, s) \ -+ _mutex_lock_killable(l) -+# define mutex_lock_nest_lock(lock, nest_lock) mutex_lock(lock) -+# define mutex_lock_io_nested(l, s) _mutex_lock_io(l) -+#endif -+ -+# define mutex_init(mutex) \ -+do { \ -+ static struct lock_class_key __key; \ -+ \ -+ rt_mutex_init(&(mutex)->lock); \ -+ __mutex_do_init((mutex), #mutex, &__key); \ -+} while (0) -+ -+# define __mutex_init(mutex, name, key) \ -+do { \ -+ rt_mutex_init(&(mutex)->lock); \ -+ __mutex_do_init((mutex), name, key); \ -+} while (0) -+ -+/** -+ * These values are chosen such that FAIL and SUCCESS match the -+ * values of the regular mutex_trylock(). -+ */ -+enum mutex_trylock_recursive_enum { -+ MUTEX_TRYLOCK_FAILED = 0, -+ MUTEX_TRYLOCK_SUCCESS = 1, -+ MUTEX_TRYLOCK_RECURSIVE, -+}; -+/** -+ * mutex_trylock_recursive - trylock variant that allows recursive locking -+ * @lock: mutex to be locked -+ * -+ * This function should not be used, _ever_. It is purely for hysterical GEM -+ * raisins, and once those are gone this will be removed. -+ * -+ * Returns: -+ * MUTEX_TRYLOCK_FAILED - trylock failed, -+ * MUTEX_TRYLOCK_SUCCESS - lock acquired, -+ * MUTEX_TRYLOCK_RECURSIVE - we already owned the lock. -+ */ -+int __rt_mutex_owner_current(struct rt_mutex *lock); -+ -+static inline /* __deprecated */ __must_check enum mutex_trylock_recursive_enum -+mutex_trylock_recursive(struct mutex *lock) -+{ -+ if (unlikely(__rt_mutex_owner_current(&lock->lock))) -+ return MUTEX_TRYLOCK_RECURSIVE; -+ -+ return mutex_trylock(lock); -+} -+ -+extern int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock); -+ -+#endif ---- a/include/linux/rtmutex.h -+++ b/include/linux/rtmutex.h -@@ -13,11 +13,15 @@ - #define __LINUX_RT_MUTEX_H - - #include <linux/linkage.h> --#include <linux/rbtree.h> - #include <linux/spinlock_types_raw.h> -+#include <linux/rbtree.h> - - extern int max_lock_depth; /* for sysctl */ - -+#ifdef CONFIG_DEBUG_MUTEXES -+#include <linux/debug_locks.h> -+#endif -+ - /** - * The rt_mutex structure - * -@@ -31,8 +35,8 @@ struct rt_mutex { - struct rb_root waiters; - struct rb_node *waiters_leftmost; - struct task_struct *owner; --#ifdef CONFIG_DEBUG_RT_MUTEXES - int save_state; -+#ifdef CONFIG_DEBUG_RT_MUTEXES - const char *name, *file; - int line; - void *magic; -@@ -55,22 +59,33 @@ struct hrtimer_sleeper; - # define rt_mutex_debug_check_no_locks_held(task) do { } while (0) - #endif - -+# define rt_mutex_init(mutex) \ -+ do { \ -+ raw_spin_lock_init(&(mutex)->wait_lock); \ -+ __rt_mutex_init(mutex, #mutex); \ -+ } while (0) -+ - #ifdef CONFIG_DEBUG_RT_MUTEXES - # define __DEBUG_RT_MUTEX_INITIALIZER(mutexname) \ - , .name = #mutexname, .file = __FILE__, .line = __LINE__ --# define rt_mutex_init(mutex) __rt_mutex_init(mutex, __func__) - extern void rt_mutex_debug_task_free(struct task_struct *tsk); - #else - # define __DEBUG_RT_MUTEX_INITIALIZER(mutexname) --# define rt_mutex_init(mutex) __rt_mutex_init(mutex, NULL) - # define rt_mutex_debug_task_free(t) do { } while (0) - #endif - --#define __RT_MUTEX_INITIALIZER(mutexname) \ -- { .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(mutexname.wait_lock) \ -+#define __RT_MUTEX_INITIALIZER_PLAIN(mutexname) \ -+ .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(mutexname.wait_lock) \ - , .waiters = RB_ROOT \ - , .owner = NULL \ -- __DEBUG_RT_MUTEX_INITIALIZER(mutexname)} -+ __DEBUG_RT_MUTEX_INITIALIZER(mutexname) -+ -+#define __RT_MUTEX_INITIALIZER(mutexname) \ -+ { __RT_MUTEX_INITIALIZER_PLAIN(mutexname) } -+ -+#define __RT_MUTEX_INITIALIZER_SAVE_STATE(mutexname) \ -+ { __RT_MUTEX_INITIALIZER_PLAIN(mutexname) \ -+ , .save_state = 1 } - - #define DEFINE_RT_MUTEX(mutexname) \ - struct rt_mutex mutexname = __RT_MUTEX_INITIALIZER(mutexname) ---- /dev/null -+++ b/include/linux/rwlock_rt.h -@@ -0,0 +1,99 @@ -+#ifndef __LINUX_RWLOCK_RT_H -+#define __LINUX_RWLOCK_RT_H -+ -+#ifndef __LINUX_SPINLOCK_H -+#error Do not include directly. Use spinlock.h -+#endif -+ -+#define rwlock_init(rwl) \ -+do { \ -+ static struct lock_class_key __key; \ -+ \ -+ rt_mutex_init(&(rwl)->lock); \ -+ __rt_rwlock_init(rwl, #rwl, &__key); \ -+} while (0) -+ -+extern void __lockfunc rt_write_lock(rwlock_t *rwlock); -+extern void __lockfunc rt_read_lock(rwlock_t *rwlock); -+extern int __lockfunc rt_write_trylock(rwlock_t *rwlock); -+extern int __lockfunc rt_write_trylock_irqsave(rwlock_t *trylock, unsigned long *flags); -+extern int __lockfunc rt_read_trylock(rwlock_t *rwlock); -+extern void __lockfunc rt_write_unlock(rwlock_t *rwlock); -+extern void __lockfunc rt_read_unlock(rwlock_t *rwlock); -+extern unsigned long __lockfunc rt_write_lock_irqsave(rwlock_t *rwlock); -+extern unsigned long __lockfunc rt_read_lock_irqsave(rwlock_t *rwlock); -+extern void __rt_rwlock_init(rwlock_t *rwlock, char *name, struct lock_class_key *key); -+ -+#define read_trylock(lock) __cond_lock(lock, rt_read_trylock(lock)) -+#define write_trylock(lock) __cond_lock(lock, rt_write_trylock(lock)) -+ -+#define write_trylock_irqsave(lock, flags) \ -+ __cond_lock(lock, rt_write_trylock_irqsave(lock, &flags)) -+ -+#define read_lock_irqsave(lock, flags) \ -+ do { \ -+ typecheck(unsigned long, flags); \ -+ flags = rt_read_lock_irqsave(lock); \ -+ } while (0) -+ -+#define write_lock_irqsave(lock, flags) \ -+ do { \ -+ typecheck(unsigned long, flags); \ -+ flags = rt_write_lock_irqsave(lock); \ -+ } while (0) -+ -+#define read_lock(lock) rt_read_lock(lock) -+ -+#define read_lock_bh(lock) \ -+ do { \ -+ local_bh_disable(); \ -+ rt_read_lock(lock); \ -+ } while (0) -+ -+#define read_lock_irq(lock) read_lock(lock) -+ -+#define write_lock(lock) rt_write_lock(lock) -+ -+#define write_lock_bh(lock) \ -+ do { \ -+ local_bh_disable(); \ -+ rt_write_lock(lock); \ -+ } while (0) -+ -+#define write_lock_irq(lock) write_lock(lock) -+ -+#define read_unlock(lock) rt_read_unlock(lock) -+ -+#define read_unlock_bh(lock) \ -+ do { \ -+ rt_read_unlock(lock); \ -+ local_bh_enable(); \ -+ } while (0) -+ -+#define read_unlock_irq(lock) read_unlock(lock) -+ -+#define write_unlock(lock) rt_write_unlock(lock) -+ -+#define write_unlock_bh(lock) \ -+ do { \ -+ rt_write_unlock(lock); \ -+ local_bh_enable(); \ -+ } while (0) -+ -+#define write_unlock_irq(lock) write_unlock(lock) -+ -+#define read_unlock_irqrestore(lock, flags) \ -+ do { \ -+ typecheck(unsigned long, flags); \ -+ (void) flags; \ -+ rt_read_unlock(lock); \ -+ } while (0) -+ -+#define write_unlock_irqrestore(lock, flags) \ -+ do { \ -+ typecheck(unsigned long, flags); \ -+ (void) flags; \ -+ rt_write_unlock(lock); \ -+ } while (0) -+ -+#endif ---- /dev/null -+++ b/include/linux/rwlock_types_rt.h -@@ -0,0 +1,33 @@ -+#ifndef __LINUX_RWLOCK_TYPES_RT_H -+#define __LINUX_RWLOCK_TYPES_RT_H -+ -+#ifndef __LINUX_SPINLOCK_TYPES_H -+#error "Do not include directly. Include spinlock_types.h instead" -+#endif -+ -+/* -+ * rwlocks - rtmutex which allows single reader recursion -+ */ -+typedef struct { -+ struct rt_mutex lock; -+ int read_depth; -+ unsigned int break_lock; -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+ struct lockdep_map dep_map; -+#endif -+} rwlock_t; -+ -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+# define RW_DEP_MAP_INIT(lockname) .dep_map = { .name = #lockname } -+#else -+# define RW_DEP_MAP_INIT(lockname) -+#endif -+ -+#define __RW_LOCK_UNLOCKED(name) \ -+ { .lock = __RT_MUTEX_INITIALIZER_SAVE_STATE(name.lock), \ -+ RW_DEP_MAP_INIT(name) } -+ -+#define DEFINE_RWLOCK(name) \ -+ rwlock_t name = __RW_LOCK_UNLOCKED(name) -+ -+#endif ---- a/include/linux/rwsem.h -+++ b/include/linux/rwsem.h -@@ -19,6 +19,10 @@ - #include <linux/osq_lock.h> - #endif - -+#ifdef CONFIG_PREEMPT_RT_FULL -+#include <linux/rwsem_rt.h> -+#else /* PREEMPT_RT_FULL */ -+ - struct rw_semaphore; - - #ifdef CONFIG_RWSEM_GENERIC_SPINLOCK -@@ -184,4 +188,6 @@ extern void up_read_non_owner(struct rw_ - # define up_read_non_owner(sem) up_read(sem) - #endif - -+#endif /* !PREEMPT_RT_FULL */ -+ - #endif /* _LINUX_RWSEM_H */ ---- /dev/null -+++ b/include/linux/rwsem_rt.h -@@ -0,0 +1,167 @@ -+#ifndef _LINUX_RWSEM_RT_H -+#define _LINUX_RWSEM_RT_H -+ -+#ifndef _LINUX_RWSEM_H -+#error "Include rwsem.h" -+#endif -+ -+/* -+ * RW-semaphores are a spinlock plus a reader-depth count. -+ * -+ * Note that the semantics are different from the usual -+ * Linux rw-sems, in PREEMPT_RT mode we do not allow -+ * multiple readers to hold the lock at once, we only allow -+ * a read-lock owner to read-lock recursively. This is -+ * better for latency, makes the implementation inherently -+ * fair and makes it simpler as well. -+ */ -+ -+#include <linux/rtmutex.h> -+ -+struct rw_semaphore { -+ struct rt_mutex lock; -+ int read_depth; -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+ struct lockdep_map dep_map; -+#endif -+}; -+ -+#define __RWSEM_INITIALIZER(name) \ -+ { .lock = __RT_MUTEX_INITIALIZER(name.lock), \ -+ RW_DEP_MAP_INIT(name) } -+ -+#define DECLARE_RWSEM(lockname) \ -+ struct rw_semaphore lockname = __RWSEM_INITIALIZER(lockname) -+ -+extern void __rt_rwsem_init(struct rw_semaphore *rwsem, const char *name, -+ struct lock_class_key *key); -+ -+#define __rt_init_rwsem(sem, name, key) \ -+ do { \ -+ rt_mutex_init(&(sem)->lock); \ -+ __rt_rwsem_init((sem), (name), (key));\ -+ } while (0) -+ -+#define __init_rwsem(sem, name, key) __rt_init_rwsem(sem, name, key) -+ -+# define rt_init_rwsem(sem) \ -+do { \ -+ static struct lock_class_key __key; \ -+ \ -+ __rt_init_rwsem((sem), #sem, &__key); \ -+} while (0) -+ -+extern void rt_down_write(struct rw_semaphore *rwsem); -+extern int rt_down_write_killable(struct rw_semaphore *rwsem); -+extern void rt_down_read_nested(struct rw_semaphore *rwsem, int subclass); -+extern void rt_down_write_nested(struct rw_semaphore *rwsem, int subclass); -+extern int rt_down_write_killable_nested(struct rw_semaphore *rwsem, -+ int subclass); -+extern void rt_down_write_nested_lock(struct rw_semaphore *rwsem, -+ struct lockdep_map *nest); -+extern void rt__down_read(struct rw_semaphore *rwsem); -+extern void rt_down_read(struct rw_semaphore *rwsem); -+extern int rt_down_write_trylock(struct rw_semaphore *rwsem); -+extern int rt__down_read_trylock(struct rw_semaphore *rwsem); -+extern int rt_down_read_trylock(struct rw_semaphore *rwsem); -+extern void __rt_up_read(struct rw_semaphore *rwsem); -+extern void rt_up_read(struct rw_semaphore *rwsem); -+extern void rt_up_write(struct rw_semaphore *rwsem); -+extern void rt_downgrade_write(struct rw_semaphore *rwsem); -+ -+#define init_rwsem(sem) rt_init_rwsem(sem) -+#define rwsem_is_locked(s) rt_mutex_is_locked(&(s)->lock) -+ -+static inline int rwsem_is_contended(struct rw_semaphore *sem) -+{ -+ /* rt_mutex_has_waiters() */ -+ return !RB_EMPTY_ROOT(&sem->lock.waiters); -+} -+ -+static inline void __down_read(struct rw_semaphore *sem) -+{ -+ rt__down_read(sem); -+} -+ -+static inline void down_read(struct rw_semaphore *sem) -+{ -+ rt_down_read(sem); -+} -+ -+static inline int __down_read_trylock(struct rw_semaphore *sem) -+{ -+ return rt__down_read_trylock(sem); -+} -+ -+static inline int down_read_trylock(struct rw_semaphore *sem) -+{ -+ return rt_down_read_trylock(sem); -+} -+ -+static inline void down_write(struct rw_semaphore *sem) -+{ -+ rt_down_write(sem); -+} -+ -+static inline int down_write_killable(struct rw_semaphore *sem) -+{ -+ return rt_down_write_killable(sem); -+} -+ -+static inline int down_write_trylock(struct rw_semaphore *sem) -+{ -+ return rt_down_write_trylock(sem); -+} -+ -+static inline void __up_read(struct rw_semaphore *sem) -+{ -+ __rt_up_read(sem); -+} -+ -+static inline void up_read(struct rw_semaphore *sem) -+{ -+ rt_up_read(sem); -+} -+ -+static inline void up_write(struct rw_semaphore *sem) -+{ -+ rt_up_write(sem); -+} -+ -+static inline void downgrade_write(struct rw_semaphore *sem) -+{ -+ rt_downgrade_write(sem); -+} -+ -+static inline void down_read_nested(struct rw_semaphore *sem, int subclass) -+{ -+ return rt_down_read_nested(sem, subclass); -+} -+ -+static inline void down_write_nested(struct rw_semaphore *sem, int subclass) -+{ -+ rt_down_write_nested(sem, subclass); -+} -+ -+static inline int down_write_killable_nested(struct rw_semaphore *sem, -+ int subclass) -+{ -+ return rt_down_write_killable_nested(sem, subclass); -+} -+ -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+static inline void down_write_nest_lock(struct rw_semaphore *sem, -+ struct rw_semaphore *nest_lock) -+{ -+ rt_down_write_nested_lock(sem, &nest_lock->dep_map); -+} -+ -+#else -+ -+static inline void down_write_nest_lock(struct rw_semaphore *sem, -+ struct rw_semaphore *nest_lock) -+{ -+ rt_down_write_nested_lock(sem, NULL); -+} -+#endif -+#endif ---- a/include/linux/sched.h -+++ b/include/linux/sched.h -@@ -123,6 +123,11 @@ struct task_group; - smp_store_mb(current->state, (state_value)); \ - } while (0) - -+#define __set_current_state_no_track(state_value) \ -+ current->state = (state_value); -+#define set_current_state_no_track(state_value) \ -+ smp_store_mb(current->state, (state_value)); -+ - #else - /* - * set_current_state() includes a barrier so that the write of current->state -@@ -160,6 +165,9 @@ struct task_group; - */ - #define __set_current_state(state_value) do { current->state = (state_value); } while (0) - #define set_current_state(state_value) smp_store_mb(current->state, (state_value)) -+ -+#define __set_current_state_no_track(state_value) __set_current_state(state_value) -+#define set_current_state_no_track(state_value) set_current_state(state_value) - #endif - - /* Task command name length: */ ---- a/include/linux/sched/wake_q.h -+++ b/include/linux/sched/wake_q.h -@@ -48,6 +48,15 @@ static inline void wake_q_init(struct wa - - extern void wake_q_add(struct wake_q_head *head, - struct task_struct *task); --extern void wake_up_q(struct wake_q_head *head); -+extern void __wake_up_q(struct wake_q_head *head, bool sleeper); -+static inline void wake_up_q(struct wake_q_head *head) -+{ -+ __wake_up_q(head, false); -+} -+ -+static inline void wake_up_q_sleeper(struct wake_q_head *head) -+{ -+ __wake_up_q(head, true); -+} - - #endif /* _LINUX_SCHED_WAKE_Q_H */ ---- a/include/linux/spinlock.h -+++ b/include/linux/spinlock.h -@@ -268,7 +268,11 @@ static inline void do_raw_spin_unlock(ra - #define raw_spin_can_lock(lock) (!raw_spin_is_locked(lock)) - - /* Include rwlock functions */ --#include <linux/rwlock.h> -+#ifdef CONFIG_PREEMPT_RT_FULL -+# include <linux/rwlock_rt.h> -+#else -+# include <linux/rwlock.h> -+#endif - - /* - * Pull the _spin_*()/_read_*()/_write_*() functions/declarations: -@@ -279,6 +283,10 @@ static inline void do_raw_spin_unlock(ra - # include <linux/spinlock_api_up.h> - #endif - -+#ifdef CONFIG_PREEMPT_RT_FULL -+# include <linux/spinlock_rt.h> -+#else /* PREEMPT_RT_FULL */ -+ - /* - * Map the spin_lock functions to the raw variants for PREEMPT_RT=n - */ -@@ -408,4 +416,6 @@ extern int _atomic_dec_and_lock(atomic_t - #define atomic_dec_and_lock(atomic, lock) \ - __cond_lock(lock, _atomic_dec_and_lock(atomic, lock)) - -+#endif /* !PREEMPT_RT_FULL */ -+ - #endif /* __LINUX_SPINLOCK_H */ ---- a/include/linux/spinlock_api_smp.h -+++ b/include/linux/spinlock_api_smp.h -@@ -187,6 +187,8 @@ static inline int __raw_spin_trylock_bh( - return 0; - } - --#include <linux/rwlock_api_smp.h> -+#ifndef CONFIG_PREEMPT_RT_FULL -+# include <linux/rwlock_api_smp.h> -+#endif - - #endif /* __LINUX_SPINLOCK_API_SMP_H */ ---- /dev/null -+++ b/include/linux/spinlock_rt.h -@@ -0,0 +1,162 @@ -+#ifndef __LINUX_SPINLOCK_RT_H -+#define __LINUX_SPINLOCK_RT_H -+ -+#ifndef __LINUX_SPINLOCK_H -+#error Do not include directly. Use spinlock.h -+#endif -+ -+#include <linux/bug.h> -+ -+extern void -+__rt_spin_lock_init(spinlock_t *lock, const char *name, struct lock_class_key *key); -+ -+#define spin_lock_init(slock) \ -+do { \ -+ static struct lock_class_key __key; \ -+ \ -+ rt_mutex_init(&(slock)->lock); \ -+ __rt_spin_lock_init(slock, #slock, &__key); \ -+} while (0) -+ -+void __lockfunc rt_spin_lock__no_mg(spinlock_t *lock); -+void __lockfunc rt_spin_unlock__no_mg(spinlock_t *lock); -+int __lockfunc rt_spin_trylock__no_mg(spinlock_t *lock); -+ -+extern void __lockfunc rt_spin_lock(spinlock_t *lock); -+extern unsigned long __lockfunc rt_spin_lock_trace_flags(spinlock_t *lock); -+extern void __lockfunc rt_spin_lock_nested(spinlock_t *lock, int subclass); -+extern void __lockfunc rt_spin_unlock(spinlock_t *lock); -+extern void __lockfunc rt_spin_unlock_wait(spinlock_t *lock); -+extern int __lockfunc rt_spin_trylock_irqsave(spinlock_t *lock, unsigned long *flags); -+extern int __lockfunc rt_spin_trylock_bh(spinlock_t *lock); -+extern int __lockfunc rt_spin_trylock(spinlock_t *lock); -+extern int atomic_dec_and_spin_lock(atomic_t *atomic, spinlock_t *lock); -+ -+/* -+ * lockdep-less calls, for derived types like rwlock: -+ * (for trylock they can use rt_mutex_trylock() directly. -+ */ -+extern void __lockfunc __rt_spin_lock__no_mg(struct rt_mutex *lock); -+extern void __lockfunc __rt_spin_lock(struct rt_mutex *lock); -+extern void __lockfunc __rt_spin_unlock(struct rt_mutex *lock); -+ -+#define spin_lock(lock) rt_spin_lock(lock) -+ -+#define spin_lock_bh(lock) \ -+ do { \ -+ local_bh_disable(); \ -+ rt_spin_lock(lock); \ -+ } while (0) -+ -+#define spin_lock_irq(lock) spin_lock(lock) -+ -+#define spin_do_trylock(lock) __cond_lock(lock, rt_spin_trylock(lock)) -+ -+#define spin_trylock(lock) \ -+({ \ -+ int __locked; \ -+ __locked = spin_do_trylock(lock); \ -+ __locked; \ -+}) -+ -+#ifdef CONFIG_LOCKDEP -+# define spin_lock_nested(lock, subclass) \ -+ do { \ -+ rt_spin_lock_nested(lock, subclass); \ -+ } while (0) -+ -+#define spin_lock_bh_nested(lock, subclass) \ -+ do { \ -+ local_bh_disable(); \ -+ rt_spin_lock_nested(lock, subclass); \ -+ } while (0) -+ -+# define spin_lock_irqsave_nested(lock, flags, subclass) \ -+ do { \ -+ typecheck(unsigned long, flags); \ -+ flags = 0; \ -+ rt_spin_lock_nested(lock, subclass); \ -+ } while (0) -+#else -+# define spin_lock_nested(lock, subclass) spin_lock(lock) -+# define spin_lock_bh_nested(lock, subclass) spin_lock_bh(lock) -+ -+# define spin_lock_irqsave_nested(lock, flags, subclass) \ -+ do { \ -+ typecheck(unsigned long, flags); \ -+ flags = 0; \ -+ spin_lock(lock); \ -+ } while (0) -+#endif -+ -+#define spin_lock_irqsave(lock, flags) \ -+ do { \ -+ typecheck(unsigned long, flags); \ -+ flags = 0; \ -+ spin_lock(lock); \ -+ } while (0) -+ -+static inline unsigned long spin_lock_trace_flags(spinlock_t *lock) -+{ -+ unsigned long flags = 0; -+#ifdef CONFIG_TRACE_IRQFLAGS -+ flags = rt_spin_lock_trace_flags(lock); -+#else -+ spin_lock(lock); /* lock_local */ -+#endif -+ return flags; -+} -+ -+/* FIXME: we need rt_spin_lock_nest_lock */ -+#define spin_lock_nest_lock(lock, nest_lock) spin_lock_nested(lock, 0) -+ -+#define spin_unlock(lock) rt_spin_unlock(lock) -+ -+#define spin_unlock_bh(lock) \ -+ do { \ -+ rt_spin_unlock(lock); \ -+ local_bh_enable(); \ -+ } while (0) -+ -+#define spin_unlock_irq(lock) spin_unlock(lock) -+ -+#define spin_unlock_irqrestore(lock, flags) \ -+ do { \ -+ typecheck(unsigned long, flags); \ -+ (void) flags; \ -+ spin_unlock(lock); \ -+ } while (0) -+ -+#define spin_trylock_bh(lock) __cond_lock(lock, rt_spin_trylock_bh(lock)) -+#define spin_trylock_irq(lock) spin_trylock(lock) -+ -+#define spin_trylock_irqsave(lock, flags) \ -+ rt_spin_trylock_irqsave(lock, &(flags)) -+ -+#define spin_unlock_wait(lock) rt_spin_unlock_wait(lock) -+ -+#ifdef CONFIG_GENERIC_LOCKBREAK -+# define spin_is_contended(lock) ((lock)->break_lock) -+#else -+# define spin_is_contended(lock) (((void)(lock), 0)) -+#endif -+ -+static inline int spin_can_lock(spinlock_t *lock) -+{ -+ return !rt_mutex_is_locked(&lock->lock); -+} -+ -+static inline int spin_is_locked(spinlock_t *lock) -+{ -+ return rt_mutex_is_locked(&lock->lock); -+} -+ -+static inline void assert_spin_locked(spinlock_t *lock) -+{ -+ BUG_ON(!spin_is_locked(lock)); -+} -+ -+#define atomic_dec_and_lock(atomic, lock) \ -+ atomic_dec_and_spin_lock(atomic, lock) -+ -+#endif ---- a/include/linux/spinlock_types.h -+++ b/include/linux/spinlock_types.h -@@ -11,8 +11,13 @@ - - #include <linux/spinlock_types_raw.h> - --#include <linux/spinlock_types_nort.h> -- --#include <linux/rwlock_types.h> -+#ifndef CONFIG_PREEMPT_RT_FULL -+# include <linux/spinlock_types_nort.h> -+# include <linux/rwlock_types.h> -+#else -+# include <linux/rtmutex.h> -+# include <linux/spinlock_types_rt.h> -+# include <linux/rwlock_types_rt.h> -+#endif - - #endif /* __LINUX_SPINLOCK_TYPES_H */ ---- /dev/null -+++ b/include/linux/spinlock_types_rt.h -@@ -0,0 +1,48 @@ -+#ifndef __LINUX_SPINLOCK_TYPES_RT_H -+#define __LINUX_SPINLOCK_TYPES_RT_H -+ -+#ifndef __LINUX_SPINLOCK_TYPES_H -+#error "Do not include directly. Include spinlock_types.h instead" -+#endif -+ -+#include <linux/cache.h> -+ -+/* -+ * PREEMPT_RT: spinlocks - an RT mutex plus lock-break field: -+ */ -+typedef struct spinlock { -+ struct rt_mutex lock; -+ unsigned int break_lock; -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+ struct lockdep_map dep_map; -+#endif -+} spinlock_t; -+ -+#ifdef CONFIG_DEBUG_RT_MUTEXES -+# define __RT_SPIN_INITIALIZER(name) \ -+ { \ -+ .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(name.wait_lock), \ -+ .save_state = 1, \ -+ .file = __FILE__, \ -+ .line = __LINE__ , \ -+ } -+#else -+# define __RT_SPIN_INITIALIZER(name) \ -+ { \ -+ .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(name.wait_lock), \ -+ .save_state = 1, \ -+ } -+#endif -+ -+/* -+.wait_list = PLIST_HEAD_INIT_RAW((name).lock.wait_list, (name).lock.wait_lock) -+*/ -+ -+#define __SPIN_LOCK_UNLOCKED(name) \ -+ { .lock = __RT_SPIN_INITIALIZER(name.lock), \ -+ SPIN_DEP_MAP_INIT(name) } -+ -+#define DEFINE_SPINLOCK(name) \ -+ spinlock_t name = __SPIN_LOCK_UNLOCKED(name) -+ -+#endif ---- a/kernel/futex.c -+++ b/kernel/futex.c -@@ -1400,6 +1400,7 @@ static int wake_futex_pi(u32 __user *uad - struct task_struct *new_owner; - bool postunlock = false; - DEFINE_WAKE_Q(wake_q); -+ DEFINE_WAKE_Q(wake_sleeper_q); - int ret = 0; - - new_owner = rt_mutex_next_owner(&pi_state->pi_mutex); -@@ -1461,13 +1462,13 @@ static int wake_futex_pi(u32 __user *uad - pi_state->owner = new_owner; - raw_spin_unlock(&new_owner->pi_lock); - -- postunlock = __rt_mutex_futex_unlock(&pi_state->pi_mutex, &wake_q); -- -+ postunlock = __rt_mutex_futex_unlock(&pi_state->pi_mutex, &wake_q, -+ &wake_sleeper_q); - out_unlock: - raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); - - if (postunlock) -- rt_mutex_postunlock(&wake_q); -+ rt_mutex_postunlock(&wake_q, &wake_sleeper_q); - - return ret; - } -@@ -2666,7 +2667,7 @@ static int futex_lock_pi(u32 __user *uad - goto no_block; - } - -- rt_mutex_init_waiter(&rt_waiter); -+ rt_mutex_init_waiter(&rt_waiter, false); - - /* - * On PREEMPT_RT_FULL, when hb->lock becomes an rt_mutex, we must not -@@ -3032,7 +3033,7 @@ static int futex_wait_requeue_pi(u32 __u - * The waiter is allocated on our stack, manipulated by the requeue - * code while we sleep on uaddr. - */ -- rt_mutex_init_waiter(&rt_waiter); -+ rt_mutex_init_waiter(&rt_waiter, false); - - ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, VERIFY_WRITE); - if (unlikely(ret != 0)) ---- a/kernel/locking/Makefile -+++ b/kernel/locking/Makefile -@@ -2,7 +2,7 @@ - # and is generally not a function of system call inputs. - KCOV_INSTRUMENT := n - --obj-y += mutex.o semaphore.o rwsem.o percpu-rwsem.o -+obj-y += semaphore.o percpu-rwsem.o - - ifdef CONFIG_FUNCTION_TRACER - CFLAGS_REMOVE_lockdep.o = $(CC_FLAGS_FTRACE) -@@ -11,7 +11,11 @@ CFLAGS_REMOVE_mutex-debug.o = $(CC_FLAGS - CFLAGS_REMOVE_rtmutex-debug.o = $(CC_FLAGS_FTRACE) - endif - -+ifneq ($(CONFIG_PREEMPT_RT_FULL),y) -+obj-y += mutex.o - obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o -+obj-y += rwsem.o -+endif - obj-$(CONFIG_LOCKDEP) += lockdep.o - ifeq ($(CONFIG_PROC_FS),y) - obj-$(CONFIG_LOCKDEP) += lockdep_proc.o -@@ -24,8 +28,11 @@ obj-$(CONFIG_RT_MUTEXES) += rtmutex.o - obj-$(CONFIG_DEBUG_RT_MUTEXES) += rtmutex-debug.o - obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o - obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o -+ifneq ($(CONFIG_PREEMPT_RT_FULL),y) - obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o - obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem-xadd.o -+endif -+obj-$(CONFIG_PREEMPT_RT_FULL) += rt.o - obj-$(CONFIG_QUEUED_RWLOCKS) += qrwlock.o - obj-$(CONFIG_LOCK_TORTURE_TEST) += locktorture.o - obj-$(CONFIG_WW_MUTEX_SELFTEST) += test-ww_mutex.o ---- /dev/null -+++ b/kernel/locking/rt.c -@@ -0,0 +1,521 @@ -+/* -+ * kernel/rt.c -+ * -+ * Real-Time Preemption Support -+ * -+ * started by Ingo Molnar: -+ * -+ * Copyright (C) 2004-2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> -+ * Copyright (C) 2006, Timesys Corp., Thomas Gleixner <tglx@timesys.com> -+ * -+ * historic credit for proving that Linux spinlocks can be implemented via -+ * RT-aware mutexes goes to many people: The Pmutex project (Dirk Grambow -+ * and others) who prototyped it on 2.4 and did lots of comparative -+ * research and analysis; TimeSys, for proving that you can implement a -+ * fully preemptible kernel via the use of IRQ threading and mutexes; -+ * Bill Huey for persuasively arguing on lkml that the mutex model is the -+ * right one; and to MontaVista, who ported pmutexes to 2.6. -+ * -+ * This code is a from-scratch implementation and is not based on pmutexes, -+ * but the idea of converting spinlocks to mutexes is used here too. -+ * -+ * lock debugging, locking tree, deadlock detection: -+ * -+ * Copyright (C) 2004, LynuxWorks, Inc., Igor Manyilov, Bill Huey -+ * Released under the General Public License (GPL). -+ * -+ * Includes portions of the generic R/W semaphore implementation from: -+ * -+ * Copyright (c) 2001 David Howells (dhowells@redhat.com). -+ * - Derived partially from idea by Andrea Arcangeli <andrea@suse.de> -+ * - Derived also from comments by Linus -+ * -+ * Pending ownership of locks and ownership stealing: -+ * -+ * Copyright (C) 2005, Kihon Technologies Inc., Steven Rostedt -+ * -+ * (also by Steven Rostedt) -+ * - Converted single pi_lock to individual task locks. -+ * -+ * By Esben Nielsen: -+ * Doing priority inheritance with help of the scheduler. -+ * -+ * Copyright (C) 2006, Timesys Corp., Thomas Gleixner <tglx@timesys.com> -+ * - major rework based on Esben Nielsens initial patch -+ * - replaced thread_info references by task_struct refs -+ * - removed task->pending_owner dependency -+ * - BKL drop/reacquire for semaphore style locks to avoid deadlocks -+ * in the scheduler return path as discussed with Steven Rostedt -+ * -+ * Copyright (C) 2006, Kihon Technologies Inc. -+ * Steven Rostedt <rostedt@goodmis.org> -+ * - debugged and patched Thomas Gleixner's rework. -+ * - added back the cmpxchg to the rework. -+ * - turned atomic require back on for SMP. -+ */ -+ -+#include <linux/spinlock.h> -+#include <linux/rtmutex.h> -+#include <linux/sched.h> -+#include <linux/delay.h> -+#include <linux/module.h> -+#include <linux/kallsyms.h> -+#include <linux/syscalls.h> -+#include <linux/interrupt.h> -+#include <linux/plist.h> -+#include <linux/fs.h> -+#include <linux/futex.h> -+#include <linux/hrtimer.h> -+ -+#include "rtmutex_common.h" -+ -+/* -+ * struct mutex functions -+ */ -+void __mutex_do_init(struct mutex *mutex, const char *name, -+ struct lock_class_key *key) -+{ -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+ /* -+ * Make sure we are not reinitializing a held lock: -+ */ -+ debug_check_no_locks_freed((void *)mutex, sizeof(*mutex)); -+ lockdep_init_map(&mutex->dep_map, name, key, 0); -+#endif -+ mutex->lock.save_state = 0; -+} -+EXPORT_SYMBOL(__mutex_do_init); -+ -+void __lockfunc _mutex_lock(struct mutex *lock) -+{ -+ mutex_acquire(&lock->dep_map, 0, 0, _RET_IP_); -+ rt_mutex_lock(&lock->lock); -+} -+EXPORT_SYMBOL(_mutex_lock); -+ -+void __lockfunc _mutex_lock_io(struct mutex *lock) -+{ -+ int token; -+ -+ token = io_schedule_prepare(); -+ _mutex_lock(lock); -+ io_schedule_finish(token); -+} -+EXPORT_SYMBOL_GPL(_mutex_lock_io); -+ -+int __lockfunc _mutex_lock_interruptible(struct mutex *lock) -+{ -+ int ret; -+ -+ mutex_acquire(&lock->dep_map, 0, 0, _RET_IP_); -+ ret = rt_mutex_lock_interruptible(&lock->lock); -+ if (ret) -+ mutex_release(&lock->dep_map, 1, _RET_IP_); -+ return ret; -+} -+EXPORT_SYMBOL(_mutex_lock_interruptible); -+ -+int __lockfunc _mutex_lock_killable(struct mutex *lock) -+{ -+ int ret; -+ -+ mutex_acquire(&lock->dep_map, 0, 0, _RET_IP_); -+ ret = rt_mutex_lock_killable(&lock->lock); -+ if (ret) -+ mutex_release(&lock->dep_map, 1, _RET_IP_); -+ return ret; -+} -+EXPORT_SYMBOL(_mutex_lock_killable); -+ -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+void __lockfunc _mutex_lock_nested(struct mutex *lock, int subclass) -+{ -+ mutex_acquire_nest(&lock->dep_map, subclass, 0, NULL, _RET_IP_); -+ rt_mutex_lock(&lock->lock); -+} -+EXPORT_SYMBOL(_mutex_lock_nested); -+ -+void __lockfunc _mutex_lock_io_nested(struct mutex *lock, int subclass) -+{ -+ int token; -+ -+ token = io_schedule_prepare(); -+ -+ mutex_acquire_nest(&lock->dep_map, subclass, 0, NULL, _RET_IP_); -+ rt_mutex_lock(&lock->lock); -+ -+ io_schedule_finish(token); -+} -+EXPORT_SYMBOL_GPL(_mutex_lock_io_nested); -+ -+void __lockfunc _mutex_lock_nest_lock(struct mutex *lock, struct lockdep_map *nest) -+{ -+ mutex_acquire_nest(&lock->dep_map, 0, 0, nest, _RET_IP_); -+ rt_mutex_lock(&lock->lock); -+} -+EXPORT_SYMBOL(_mutex_lock_nest_lock); -+ -+int __lockfunc _mutex_lock_interruptible_nested(struct mutex *lock, int subclass) -+{ -+ int ret; -+ -+ mutex_acquire_nest(&lock->dep_map, subclass, 0, NULL, _RET_IP_); -+ ret = rt_mutex_lock_interruptible(&lock->lock); -+ if (ret) -+ mutex_release(&lock->dep_map, 1, _RET_IP_); -+ return ret; -+} -+EXPORT_SYMBOL(_mutex_lock_interruptible_nested); -+ -+int __lockfunc _mutex_lock_killable_nested(struct mutex *lock, int subclass) -+{ -+ int ret; -+ -+ mutex_acquire(&lock->dep_map, subclass, 0, _RET_IP_); -+ ret = rt_mutex_lock_killable(&lock->lock); -+ if (ret) -+ mutex_release(&lock->dep_map, 1, _RET_IP_); -+ return ret; -+} -+EXPORT_SYMBOL(_mutex_lock_killable_nested); -+#endif -+ -+int __lockfunc _mutex_trylock(struct mutex *lock) -+{ -+ int ret = rt_mutex_trylock(&lock->lock); -+ -+ if (ret) -+ mutex_acquire(&lock->dep_map, 0, 1, _RET_IP_); -+ -+ return ret; -+} -+EXPORT_SYMBOL(_mutex_trylock); -+ -+void __lockfunc _mutex_unlock(struct mutex *lock) -+{ -+ mutex_release(&lock->dep_map, 1, _RET_IP_); -+ rt_mutex_unlock(&lock->lock); -+} -+EXPORT_SYMBOL(_mutex_unlock); -+ -+/* -+ * rwlock_t functions -+ */ -+int __lockfunc rt_write_trylock(rwlock_t *rwlock) -+{ -+ int ret; -+ -+ migrate_disable(); -+ ret = rt_mutex_trylock(&rwlock->lock); -+ if (ret) -+ rwlock_acquire(&rwlock->dep_map, 0, 1, _RET_IP_); -+ else -+ migrate_enable(); -+ -+ return ret; -+} -+EXPORT_SYMBOL(rt_write_trylock); -+ -+int __lockfunc rt_write_trylock_irqsave(rwlock_t *rwlock, unsigned long *flags) -+{ -+ int ret; -+ -+ *flags = 0; -+ ret = rt_write_trylock(rwlock); -+ return ret; -+} -+EXPORT_SYMBOL(rt_write_trylock_irqsave); -+ -+int __lockfunc rt_read_trylock(rwlock_t *rwlock) -+{ -+ struct rt_mutex *lock = &rwlock->lock; -+ int ret = 1; -+ -+ /* -+ * recursive read locks succeed when current owns the lock, -+ * but not when read_depth == 0 which means that the lock is -+ * write locked. -+ */ -+ if (rt_mutex_owner(lock) != current) { -+ migrate_disable(); -+ ret = rt_mutex_trylock(lock); -+ if (ret) -+ rwlock_acquire(&rwlock->dep_map, 0, 1, _RET_IP_); -+ else -+ migrate_enable(); -+ -+ } else if (!rwlock->read_depth) { -+ ret = 0; -+ } -+ -+ if (ret) -+ rwlock->read_depth++; -+ -+ return ret; -+} -+EXPORT_SYMBOL(rt_read_trylock); -+ -+void __lockfunc rt_write_lock(rwlock_t *rwlock) -+{ -+ rwlock_acquire(&rwlock->dep_map, 0, 0, _RET_IP_); -+ __rt_spin_lock(&rwlock->lock); -+} -+EXPORT_SYMBOL(rt_write_lock); -+ -+void __lockfunc rt_read_lock(rwlock_t *rwlock) -+{ -+ struct rt_mutex *lock = &rwlock->lock; -+ -+ -+ /* -+ * recursive read locks succeed when current owns the lock -+ */ -+ if (rt_mutex_owner(lock) != current) { -+ rwlock_acquire(&rwlock->dep_map, 0, 0, _RET_IP_); -+ __rt_spin_lock(lock); -+ } -+ rwlock->read_depth++; -+} -+ -+EXPORT_SYMBOL(rt_read_lock); -+ -+void __lockfunc rt_write_unlock(rwlock_t *rwlock) -+{ -+ /* NOTE: we always pass in '1' for nested, for simplicity */ -+ rwlock_release(&rwlock->dep_map, 1, _RET_IP_); -+ __rt_spin_unlock(&rwlock->lock); -+ migrate_enable(); -+} -+EXPORT_SYMBOL(rt_write_unlock); -+ -+void __lockfunc rt_read_unlock(rwlock_t *rwlock) -+{ -+ /* Release the lock only when read_depth is down to 0 */ -+ if (--rwlock->read_depth == 0) { -+ rwlock_release(&rwlock->dep_map, 1, _RET_IP_); -+ __rt_spin_unlock(&rwlock->lock); -+ migrate_enable(); -+ } -+} -+EXPORT_SYMBOL(rt_read_unlock); -+ -+unsigned long __lockfunc rt_write_lock_irqsave(rwlock_t *rwlock) -+{ -+ rt_write_lock(rwlock); -+ -+ return 0; -+} -+EXPORT_SYMBOL(rt_write_lock_irqsave); -+ -+unsigned long __lockfunc rt_read_lock_irqsave(rwlock_t *rwlock) -+{ -+ rt_read_lock(rwlock); -+ -+ return 0; -+} -+EXPORT_SYMBOL(rt_read_lock_irqsave); -+ -+void __rt_rwlock_init(rwlock_t *rwlock, char *name, struct lock_class_key *key) -+{ -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+ /* -+ * Make sure we are not reinitializing a held lock: -+ */ -+ debug_check_no_locks_freed((void *)rwlock, sizeof(*rwlock)); -+ lockdep_init_map(&rwlock->dep_map, name, key, 0); -+#endif -+ rwlock->lock.save_state = 1; -+ rwlock->read_depth = 0; -+} -+EXPORT_SYMBOL(__rt_rwlock_init); -+ -+/* -+ * rw_semaphores -+ */ -+ -+void rt_up_write(struct rw_semaphore *rwsem) -+{ -+ rwsem_release(&rwsem->dep_map, 1, _RET_IP_); -+ rt_mutex_unlock(&rwsem->lock); -+} -+EXPORT_SYMBOL(rt_up_write); -+ -+void __rt_up_read(struct rw_semaphore *rwsem) -+{ -+ if (--rwsem->read_depth == 0) -+ rt_mutex_unlock(&rwsem->lock); -+} -+ -+void rt_up_read(struct rw_semaphore *rwsem) -+{ -+ rwsem_release(&rwsem->dep_map, 1, _RET_IP_); -+ __rt_up_read(rwsem); -+} -+EXPORT_SYMBOL(rt_up_read); -+ -+/* -+ * downgrade a write lock into a read lock -+ * - just wake up any readers at the front of the queue -+ */ -+void rt_downgrade_write(struct rw_semaphore *rwsem) -+{ -+ BUG_ON(rt_mutex_owner(&rwsem->lock) != current); -+ rwsem->read_depth = 1; -+} -+EXPORT_SYMBOL(rt_downgrade_write); -+ -+int rt_down_write_trylock(struct rw_semaphore *rwsem) -+{ -+ int ret = rt_mutex_trylock(&rwsem->lock); -+ -+ if (ret) -+ rwsem_acquire(&rwsem->dep_map, 0, 1, _RET_IP_); -+ return ret; -+} -+EXPORT_SYMBOL(rt_down_write_trylock); -+ -+void rt_down_write(struct rw_semaphore *rwsem) -+{ -+ rwsem_acquire(&rwsem->dep_map, 0, 0, _RET_IP_); -+ rt_mutex_lock(&rwsem->lock); -+} -+EXPORT_SYMBOL(rt_down_write); -+ -+int rt_down_write_killable(struct rw_semaphore *rwsem) -+{ -+ int ret; -+ -+ rwsem_acquire(&rwsem->dep_map, 0, 0, _RET_IP_); -+ ret = rt_mutex_lock_killable(&rwsem->lock); -+ if (ret) -+ rwsem_release(&rwsem->dep_map, 1, _RET_IP_); -+ return ret; -+} -+EXPORT_SYMBOL(rt_down_write_killable); -+ -+int rt_down_write_killable_nested(struct rw_semaphore *rwsem, int subclass) -+{ -+ int ret; -+ -+ rwsem_acquire(&rwsem->dep_map, subclass, 0, _RET_IP_); -+ ret = rt_mutex_lock_killable(&rwsem->lock); -+ if (ret) -+ rwsem_release(&rwsem->dep_map, 1, _RET_IP_); -+ return ret; -+} -+EXPORT_SYMBOL(rt_down_write_killable_nested); -+ -+void rt_down_write_nested(struct rw_semaphore *rwsem, int subclass) -+{ -+ rwsem_acquire(&rwsem->dep_map, subclass, 0, _RET_IP_); -+ rt_mutex_lock(&rwsem->lock); -+} -+EXPORT_SYMBOL(rt_down_write_nested); -+ -+void rt_down_write_nested_lock(struct rw_semaphore *rwsem, -+ struct lockdep_map *nest) -+{ -+ rwsem_acquire_nest(&rwsem->dep_map, 0, 0, nest, _RET_IP_); -+ rt_mutex_lock(&rwsem->lock); -+} -+EXPORT_SYMBOL(rt_down_write_nested_lock); -+ -+int rt__down_read_trylock(struct rw_semaphore *rwsem) -+{ -+ struct rt_mutex *lock = &rwsem->lock; -+ int ret = 1; -+ -+ /* -+ * recursive read locks succeed when current owns the rwsem, -+ * but not when read_depth == 0 which means that the rwsem is -+ * write locked. -+ */ -+ if (rt_mutex_owner(lock) != current) -+ ret = rt_mutex_trylock(&rwsem->lock); -+ else if (!rwsem->read_depth) -+ ret = 0; -+ -+ if (ret) -+ rwsem->read_depth++; -+ return ret; -+ -+} -+ -+int rt_down_read_trylock(struct rw_semaphore *rwsem) -+{ -+ int ret; -+ -+ ret = rt__down_read_trylock(rwsem); -+ if (ret) -+ rwsem_acquire(&rwsem->dep_map, 0, 1, _RET_IP_); -+ -+ return ret; -+} -+EXPORT_SYMBOL(rt_down_read_trylock); -+ -+void rt__down_read(struct rw_semaphore *rwsem) -+{ -+ struct rt_mutex *lock = &rwsem->lock; -+ -+ if (rt_mutex_owner(lock) != current) -+ rt_mutex_lock(&rwsem->lock); -+ rwsem->read_depth++; -+} -+EXPORT_SYMBOL(rt__down_read); -+ -+static void __rt_down_read(struct rw_semaphore *rwsem, int subclass) -+{ -+ rwsem_acquire_read(&rwsem->dep_map, subclass, 0, _RET_IP_); -+ rt__down_read(rwsem); -+} -+ -+void rt_down_read(struct rw_semaphore *rwsem) -+{ -+ __rt_down_read(rwsem, 0); -+} -+EXPORT_SYMBOL(rt_down_read); -+ -+void rt_down_read_nested(struct rw_semaphore *rwsem, int subclass) -+{ -+ __rt_down_read(rwsem, subclass); -+} -+EXPORT_SYMBOL(rt_down_read_nested); -+ -+void __rt_rwsem_init(struct rw_semaphore *rwsem, const char *name, -+ struct lock_class_key *key) -+{ -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+ /* -+ * Make sure we are not reinitializing a held lock: -+ */ -+ debug_check_no_locks_freed((void *)rwsem, sizeof(*rwsem)); -+ lockdep_init_map(&rwsem->dep_map, name, key, 0); -+#endif -+ rwsem->read_depth = 0; -+ rwsem->lock.save_state = 0; -+} -+EXPORT_SYMBOL(__rt_rwsem_init); -+ -+/** -+ * atomic_dec_and_mutex_lock - return holding mutex if we dec to 0 -+ * @cnt: the atomic which we are to dec -+ * @lock: the mutex to return holding if we dec to 0 -+ * -+ * return true and hold lock if we dec to 0, return false otherwise -+ */ -+int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock) -+{ -+ /* dec if we can't possibly hit 0 */ -+ if (atomic_add_unless(cnt, -1, 1)) -+ return 0; -+ /* we might hit 0, so take the lock */ -+ mutex_lock(lock); -+ if (!atomic_dec_and_test(cnt)) { -+ /* when we actually did the dec, we didn't hit 0 */ -+ mutex_unlock(lock); -+ return 0; -+ } -+ /* we hit 0, and we hold the lock */ -+ return 1; -+} -+EXPORT_SYMBOL(atomic_dec_and_mutex_lock); ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -7,6 +7,11 @@ - * Copyright (C) 2005-2006 Timesys Corp., Thomas Gleixner <tglx@timesys.com> - * Copyright (C) 2005 Kihon Technologies Inc., Steven Rostedt - * Copyright (C) 2006 Esben Nielsen -+ * Adaptive Spinlocks: -+ * Copyright (C) 2008 Novell, Inc., Gregory Haskins, Sven Dietrich, -+ * and Peter Morreale, -+ * Adaptive Spinlocks simplification: -+ * Copyright (C) 2008 Red Hat, Inc., Steven Rostedt <srostedt@redhat.com> - * - * See Documentation/locking/rt-mutex-design.txt for details. - */ -@@ -230,6 +235,9 @@ static inline bool unlock_rt_mutex_safe( - } - #endif - -+#define STEAL_NORMAL 0 -+#define STEAL_LATERAL 1 -+ - /* - * Only use with rt_mutex_waiter_{less,equal}() - */ -@@ -238,11 +246,15 @@ static inline bool unlock_rt_mutex_safe( - - static inline int - rt_mutex_waiter_less(struct rt_mutex_waiter *left, -- struct rt_mutex_waiter *right) -+ struct rt_mutex_waiter *right, int mode) - { -- if (left->prio < right->prio) -- return 1; -- -+ if (mode == STEAL_NORMAL) { -+ if (left->prio < right->prio) -+ return 1; -+ } else { -+ if (left->prio <= right->prio) -+ return 1; -+ } - /* - * If both waiters have dl_prio(), we check the deadlines of the - * associated tasks. -@@ -285,7 +297,7 @@ rt_mutex_enqueue(struct rt_mutex *lock, - while (*link) { - parent = *link; - entry = rb_entry(parent, struct rt_mutex_waiter, tree_entry); -- if (rt_mutex_waiter_less(waiter, entry)) { -+ if (rt_mutex_waiter_less(waiter, entry, STEAL_NORMAL)) { - link = &parent->rb_left; - } else { - link = &parent->rb_right; -@@ -324,7 +336,7 @@ rt_mutex_enqueue_pi(struct task_struct * - while (*link) { - parent = *link; - entry = rb_entry(parent, struct rt_mutex_waiter, pi_tree_entry); -- if (rt_mutex_waiter_less(waiter, entry)) { -+ if (rt_mutex_waiter_less(waiter, entry, STEAL_NORMAL)) { - link = &parent->rb_left; - } else { - link = &parent->rb_right; -@@ -390,6 +402,14 @@ static bool rt_mutex_cond_detect_deadloc - return debug_rt_mutex_detect_deadlock(waiter, chwalk); - } - -+static void rt_mutex_wake_waiter(struct rt_mutex_waiter *waiter) -+{ -+ if (waiter->savestate) -+ wake_up_lock_sleeper(waiter->task); -+ else -+ wake_up_process(waiter->task); -+} -+ - /* - * Max number of times we'll walk the boosting chain: - */ -@@ -715,13 +735,16 @@ static int rt_mutex_adjust_prio_chain(st - * follow here. This is the end of the chain we are walking. - */ - if (!rt_mutex_owner(lock)) { -+ struct rt_mutex_waiter *lock_top_waiter; -+ - /* - * If the requeue [7] above changed the top waiter, - * then we need to wake the new top waiter up to try - * to get the lock. - */ -- if (prerequeue_top_waiter != rt_mutex_top_waiter(lock)) -- wake_up_process(rt_mutex_top_waiter(lock)->task); -+ lock_top_waiter = rt_mutex_top_waiter(lock); -+ if (prerequeue_top_waiter != lock_top_waiter) -+ rt_mutex_wake_waiter(lock_top_waiter); - raw_spin_unlock_irq(&lock->wait_lock); - return 0; - } -@@ -824,8 +847,9 @@ static int rt_mutex_adjust_prio_chain(st - * @waiter: The waiter that is queued to the lock's wait tree if the - * callsite called task_blocked_on_lock(), otherwise NULL - */ --static int try_to_take_rt_mutex(struct rt_mutex *lock, struct task_struct *task, -- struct rt_mutex_waiter *waiter) -+static int __try_to_take_rt_mutex(struct rt_mutex *lock, -+ struct task_struct *task, -+ struct rt_mutex_waiter *waiter, int mode) - { - lockdep_assert_held(&lock->wait_lock); - -@@ -864,8 +888,10 @@ static int try_to_take_rt_mutex(struct r - * If waiter is not the highest priority waiter of - * @lock, give up. - */ -- if (waiter != rt_mutex_top_waiter(lock)) -+ if (waiter != rt_mutex_top_waiter(lock)) { -+ /* XXX rt_mutex_waiter_less() ? */ - return 0; -+ } - - /* - * We can acquire the lock. Remove the waiter from the -@@ -883,15 +909,26 @@ static int try_to_take_rt_mutex(struct r - * not need to be dequeued. - */ - if (rt_mutex_has_waiters(lock)) { -+ struct task_struct *pown = rt_mutex_top_waiter(lock)->task; -+ -+ if (task != pown) -+ return 0; -+ -+ /* -+ * Note that RT tasks are excluded from lateral-steals -+ * to prevent the introduction of an unbounded latency. -+ */ -+ if (rt_task(task)) -+ mode = STEAL_NORMAL; - /* - * If @task->prio is greater than or equal to - * the top waiter priority (kernel view), - * @task lost. - */ - if (!rt_mutex_waiter_less(task_to_waiter(task), -- rt_mutex_top_waiter(lock))) -+ rt_mutex_top_waiter(lock), -+ mode)) - return 0; -- - /* - * The current top waiter stays enqueued. We - * don't have to change anything in the lock -@@ -938,6 +975,339 @@ static int try_to_take_rt_mutex(struct r - return 1; - } - -+#ifdef CONFIG_PREEMPT_RT_FULL -+/* -+ * preemptible spin_lock functions: -+ */ -+static inline void rt_spin_lock_fastlock(struct rt_mutex *lock, -+ void (*slowfn)(struct rt_mutex *lock)) -+{ -+ might_sleep_no_state_check(); -+ -+ if (likely(rt_mutex_cmpxchg_acquire(lock, NULL, current))) -+ return; -+ else -+ slowfn(lock); -+} -+ -+static inline void rt_spin_lock_fastunlock(struct rt_mutex *lock, -+ void (*slowfn)(struct rt_mutex *lock)) -+{ -+ if (likely(rt_mutex_cmpxchg_release(lock, current, NULL))) -+ return; -+ else -+ slowfn(lock); -+} -+#ifdef CONFIG_SMP -+/* -+ * Note that owner is a speculative pointer and dereferencing relies -+ * on rcu_read_lock() and the check against the lock owner. -+ */ -+static int adaptive_wait(struct rt_mutex *lock, -+ struct task_struct *owner) -+{ -+ int res = 0; -+ -+ rcu_read_lock(); -+ for (;;) { -+ if (owner != rt_mutex_owner(lock)) -+ break; -+ /* -+ * Ensure that owner->on_cpu is dereferenced _after_ -+ * checking the above to be valid. -+ */ -+ barrier(); -+ if (!owner->on_cpu) { -+ res = 1; -+ break; -+ } -+ cpu_relax(); -+ } -+ rcu_read_unlock(); -+ return res; -+} -+#else -+static int adaptive_wait(struct rt_mutex *lock, -+ struct task_struct *orig_owner) -+{ -+ return 1; -+} -+#endif -+ -+static int task_blocks_on_rt_mutex(struct rt_mutex *lock, -+ struct rt_mutex_waiter *waiter, -+ struct task_struct *task, -+ enum rtmutex_chainwalk chwalk); -+/* -+ * Slow path lock function spin_lock style: this variant is very -+ * careful not to miss any non-lock wakeups. -+ * -+ * We store the current state under p->pi_lock in p->saved_state and -+ * the try_to_wake_up() code handles this accordingly. -+ */ -+static void noinline __sched rt_spin_lock_slowlock(struct rt_mutex *lock) -+{ -+ struct task_struct *lock_owner, *self = current; -+ struct rt_mutex_waiter waiter, *top_waiter; -+ unsigned long flags; -+ int ret; -+ -+ rt_mutex_init_waiter(&waiter, true); -+ -+ raw_spin_lock_irqsave(&lock->wait_lock, flags); -+ -+ if (__try_to_take_rt_mutex(lock, self, NULL, STEAL_LATERAL)) { -+ raw_spin_unlock_irqrestore(&lock->wait_lock, flags); -+ return; -+ } -+ -+ BUG_ON(rt_mutex_owner(lock) == self); -+ -+ /* -+ * We save whatever state the task is in and we'll restore it -+ * after acquiring the lock taking real wakeups into account -+ * as well. We are serialized via pi_lock against wakeups. See -+ * try_to_wake_up(). -+ */ -+ raw_spin_lock(&self->pi_lock); -+ self->saved_state = self->state; -+ __set_current_state_no_track(TASK_UNINTERRUPTIBLE); -+ raw_spin_unlock(&self->pi_lock); -+ -+ ret = task_blocks_on_rt_mutex(lock, &waiter, self, RT_MUTEX_MIN_CHAINWALK); -+ BUG_ON(ret); -+ -+ for (;;) { -+ /* Try to acquire the lock again. */ -+ if (__try_to_take_rt_mutex(lock, self, &waiter, STEAL_LATERAL)) -+ break; -+ -+ top_waiter = rt_mutex_top_waiter(lock); -+ lock_owner = rt_mutex_owner(lock); -+ -+ raw_spin_unlock_irqrestore(&lock->wait_lock, flags); -+ -+ debug_rt_mutex_print_deadlock(&waiter); -+ -+ if (top_waiter != &waiter || adaptive_wait(lock, lock_owner)) -+ schedule(); -+ -+ raw_spin_lock_irqsave(&lock->wait_lock, flags); -+ -+ raw_spin_lock(&self->pi_lock); -+ __set_current_state_no_track(TASK_UNINTERRUPTIBLE); -+ raw_spin_unlock(&self->pi_lock); -+ } -+ -+ /* -+ * Restore the task state to current->saved_state. We set it -+ * to the original state above and the try_to_wake_up() code -+ * has possibly updated it when a real (non-rtmutex) wakeup -+ * happened while we were blocked. Clear saved_state so -+ * try_to_wakeup() does not get confused. -+ */ -+ raw_spin_lock(&self->pi_lock); -+ __set_current_state_no_track(self->saved_state); -+ self->saved_state = TASK_RUNNING; -+ raw_spin_unlock(&self->pi_lock); -+ -+ /* -+ * try_to_take_rt_mutex() sets the waiter bit -+ * unconditionally. We might have to fix that up: -+ */ -+ fixup_rt_mutex_waiters(lock); -+ -+ BUG_ON(rt_mutex_has_waiters(lock) && &waiter == rt_mutex_top_waiter(lock)); -+ BUG_ON(!RB_EMPTY_NODE(&waiter.tree_entry)); -+ -+ raw_spin_unlock_irqrestore(&lock->wait_lock, flags); -+ -+ debug_rt_mutex_free_waiter(&waiter); -+} -+ -+static bool __sched __rt_mutex_unlock_common(struct rt_mutex *lock, -+ struct wake_q_head *wake_q, -+ struct wake_q_head *wq_sleeper); -+/* -+ * Slow path to release a rt_mutex spin_lock style -+ */ -+static void noinline __sched rt_spin_lock_slowunlock(struct rt_mutex *lock) -+{ -+ unsigned long flags; -+ DEFINE_WAKE_Q(wake_q); -+ DEFINE_WAKE_Q(wake_sleeper_q); -+ bool postunlock; -+ -+ raw_spin_lock_irqsave(&lock->wait_lock, flags); -+ postunlock = __rt_mutex_unlock_common(lock, &wake_q, &wake_sleeper_q); -+ raw_spin_unlock_irqrestore(&lock->wait_lock, flags); -+ -+ if (postunlock) -+ rt_mutex_postunlock(&wake_q, &wake_sleeper_q); -+} -+ -+void __lockfunc rt_spin_lock__no_mg(spinlock_t *lock) -+{ -+ rt_spin_lock_fastlock(&lock->lock, rt_spin_lock_slowlock); -+ spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); -+} -+EXPORT_SYMBOL(rt_spin_lock__no_mg); -+ -+void __lockfunc rt_spin_lock(spinlock_t *lock) -+{ -+ migrate_disable(); -+ rt_spin_lock_fastlock(&lock->lock, rt_spin_lock_slowlock); -+ spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); -+} -+EXPORT_SYMBOL(rt_spin_lock); -+ -+void __lockfunc __rt_spin_lock(struct rt_mutex *lock) -+{ -+ migrate_disable(); -+ rt_spin_lock_fastlock(lock, rt_spin_lock_slowlock); -+} -+EXPORT_SYMBOL(__rt_spin_lock); -+ -+void __lockfunc __rt_spin_lock__no_mg(struct rt_mutex *lock) -+{ -+ rt_spin_lock_fastlock(lock, rt_spin_lock_slowlock); -+} -+EXPORT_SYMBOL(__rt_spin_lock__no_mg); -+ -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+void __lockfunc rt_spin_lock_nested(spinlock_t *lock, int subclass) -+{ -+ migrate_disable(); -+ rt_spin_lock_fastlock(&lock->lock, rt_spin_lock_slowlock); -+ spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_); -+} -+EXPORT_SYMBOL(rt_spin_lock_nested); -+#endif -+ -+void __lockfunc rt_spin_unlock__no_mg(spinlock_t *lock) -+{ -+ /* NOTE: we always pass in '1' for nested, for simplicity */ -+ spin_release(&lock->dep_map, 1, _RET_IP_); -+ rt_spin_lock_fastunlock(&lock->lock, rt_spin_lock_slowunlock); -+} -+EXPORT_SYMBOL(rt_spin_unlock__no_mg); -+ -+void __lockfunc rt_spin_unlock(spinlock_t *lock) -+{ -+ /* NOTE: we always pass in '1' for nested, for simplicity */ -+ spin_release(&lock->dep_map, 1, _RET_IP_); -+ rt_spin_lock_fastunlock(&lock->lock, rt_spin_lock_slowunlock); -+ migrate_enable(); -+} -+EXPORT_SYMBOL(rt_spin_unlock); -+ -+void __lockfunc __rt_spin_unlock(struct rt_mutex *lock) -+{ -+ rt_spin_lock_fastunlock(lock, rt_spin_lock_slowunlock); -+} -+EXPORT_SYMBOL(__rt_spin_unlock); -+ -+/* -+ * Wait for the lock to get unlocked: instead of polling for an unlock -+ * (like raw spinlocks do), we lock and unlock, to force the kernel to -+ * schedule if there's contention: -+ */ -+void __lockfunc rt_spin_unlock_wait(spinlock_t *lock) -+{ -+ spin_lock(lock); -+ spin_unlock(lock); -+} -+EXPORT_SYMBOL(rt_spin_unlock_wait); -+ -+int __lockfunc rt_spin_trylock__no_mg(spinlock_t *lock) -+{ -+ int ret; -+ -+ ret = rt_mutex_trylock(&lock->lock); -+ if (ret) -+ spin_acquire(&lock->dep_map, 0, 1, _RET_IP_); -+ return ret; -+} -+EXPORT_SYMBOL(rt_spin_trylock__no_mg); -+ -+int __lockfunc rt_spin_trylock(spinlock_t *lock) -+{ -+ int ret; -+ -+ migrate_disable(); -+ ret = rt_mutex_trylock(&lock->lock); -+ if (ret) -+ spin_acquire(&lock->dep_map, 0, 1, _RET_IP_); -+ else -+ migrate_enable(); -+ return ret; -+} -+EXPORT_SYMBOL(rt_spin_trylock); -+ -+int __lockfunc rt_spin_trylock_bh(spinlock_t *lock) -+{ -+ int ret; -+ -+ local_bh_disable(); -+ ret = rt_mutex_trylock(&lock->lock); -+ if (ret) { -+ migrate_disable(); -+ spin_acquire(&lock->dep_map, 0, 1, _RET_IP_); -+ } else -+ local_bh_enable(); -+ return ret; -+} -+EXPORT_SYMBOL(rt_spin_trylock_bh); -+ -+int __lockfunc rt_spin_trylock_irqsave(spinlock_t *lock, unsigned long *flags) -+{ -+ int ret; -+ -+ *flags = 0; -+ ret = rt_mutex_trylock(&lock->lock); -+ if (ret) { -+ migrate_disable(); -+ spin_acquire(&lock->dep_map, 0, 1, _RET_IP_); -+ } -+ return ret; -+} -+EXPORT_SYMBOL(rt_spin_trylock_irqsave); -+ -+int atomic_dec_and_spin_lock(atomic_t *atomic, spinlock_t *lock) -+{ -+ /* Subtract 1 from counter unless that drops it to 0 (ie. it was 1) */ -+ if (atomic_add_unless(atomic, -1, 1)) -+ return 0; -+ rt_spin_lock(lock); -+ if (atomic_dec_and_test(atomic)) -+ return 1; -+ rt_spin_unlock(lock); -+ return 0; -+} -+EXPORT_SYMBOL(atomic_dec_and_spin_lock); -+ -+ void -+__rt_spin_lock_init(spinlock_t *lock, char *name, struct lock_class_key *key) -+{ -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+ /* -+ * Make sure we are not reinitializing a held lock: -+ */ -+ debug_check_no_locks_freed((void *)lock, sizeof(*lock)); -+ lockdep_init_map(&lock->dep_map, name, key, 0); -+#endif -+} -+EXPORT_SYMBOL(__rt_spin_lock_init); -+ -+#endif /* PREEMPT_RT_FULL */ -+ -+static inline int -+try_to_take_rt_mutex(struct rt_mutex *lock, struct task_struct *task, -+ struct rt_mutex_waiter *waiter) -+{ -+ return __try_to_take_rt_mutex(lock, task, waiter, STEAL_NORMAL); -+} -+ - /* - * Task blocks on lock. - * -@@ -1053,6 +1423,7 @@ static int task_blocks_on_rt_mutex(struc - * Called with lock->wait_lock held and interrupts disabled. - */ - static void mark_wakeup_next_waiter(struct wake_q_head *wake_q, -+ struct wake_q_head *wake_sleeper_q, - struct rt_mutex *lock) - { - struct rt_mutex_waiter *waiter; -@@ -1092,7 +1463,10 @@ static void mark_wakeup_next_waiter(stru - * Pairs with preempt_enable() in rt_mutex_postunlock(); - */ - preempt_disable(); -- wake_q_add(wake_q, waiter->task); -+ if (waiter->savestate) -+ wake_q_add(wake_sleeper_q, waiter->task); -+ else -+ wake_q_add(wake_q, waiter->task); - raw_spin_unlock(¤t->pi_lock); - } - -@@ -1176,21 +1550,22 @@ void rt_mutex_adjust_pi(struct task_stru - return; - } - next_lock = waiter->lock; -- raw_spin_unlock_irqrestore(&task->pi_lock, flags); - - /* gets dropped in rt_mutex_adjust_prio_chain()! */ - get_task_struct(task); - -+ raw_spin_unlock_irqrestore(&task->pi_lock, flags); - rt_mutex_adjust_prio_chain(task, RT_MUTEX_MIN_CHAINWALK, NULL, - next_lock, NULL, task); - } - --void rt_mutex_init_waiter(struct rt_mutex_waiter *waiter) -+void rt_mutex_init_waiter(struct rt_mutex_waiter *waiter, bool savestate) - { - debug_rt_mutex_init_waiter(waiter); - RB_CLEAR_NODE(&waiter->pi_tree_entry); - RB_CLEAR_NODE(&waiter->tree_entry); - waiter->task = NULL; -+ waiter->savestate = savestate; - } - - /** -@@ -1270,7 +1645,7 @@ rt_mutex_slowlock(struct rt_mutex *lock, - unsigned long flags; - int ret = 0; - -- rt_mutex_init_waiter(&waiter); -+ rt_mutex_init_waiter(&waiter, false); - - /* - * Technically we could use raw_spin_[un]lock_irq() here, but this can -@@ -1365,7 +1740,8 @@ static inline int rt_mutex_slowtrylock(s - * Return whether the current task needs to call rt_mutex_postunlock(). - */ - static bool __sched rt_mutex_slowunlock(struct rt_mutex *lock, -- struct wake_q_head *wake_q) -+ struct wake_q_head *wake_q, -+ struct wake_q_head *wake_sleeper_q) - { - unsigned long flags; - -@@ -1419,7 +1795,7 @@ static bool __sched rt_mutex_slowunlock( - * - * Queue the next waiter for wakeup once we release the wait_lock. - */ -- mark_wakeup_next_waiter(wake_q, lock); -+ mark_wakeup_next_waiter(wake_q, wake_sleeper_q, lock); - raw_spin_unlock_irqrestore(&lock->wait_lock, flags); - - return true; /* call rt_mutex_postunlock() */ -@@ -1471,9 +1847,11 @@ rt_mutex_fasttrylock(struct rt_mutex *lo - /* - * Performs the wakeup of the the top-waiter and re-enables preemption. - */ --void rt_mutex_postunlock(struct wake_q_head *wake_q) -+void rt_mutex_postunlock(struct wake_q_head *wake_q, -+ struct wake_q_head *wake_sleeper_q) - { - wake_up_q(wake_q); -+ wake_up_q_sleeper(wake_sleeper_q); - - /* Pairs with preempt_disable() in rt_mutex_slowunlock() */ - preempt_enable(); -@@ -1482,15 +1860,17 @@ void rt_mutex_postunlock(struct wake_q_h - static inline void - rt_mutex_fastunlock(struct rt_mutex *lock, - bool (*slowfn)(struct rt_mutex *lock, -- struct wake_q_head *wqh)) -+ struct wake_q_head *wqh, -+ struct wake_q_head *wq_sleeper)) - { - DEFINE_WAKE_Q(wake_q); -+ DEFINE_WAKE_Q(wake_sleeper_q); - - if (likely(rt_mutex_cmpxchg_release(lock, current, NULL))) - return; - -- if (slowfn(lock, &wake_q)) -- rt_mutex_postunlock(&wake_q); -+ if (slowfn(lock, &wake_q, &wake_sleeper_q)) -+ rt_mutex_postunlock(&wake_q, &wake_sleeper_q); - } - - /** -@@ -1609,12 +1989,9 @@ void __sched rt_mutex_unlock(struct rt_m - } - EXPORT_SYMBOL_GPL(rt_mutex_unlock); - --/** -- * Futex variant, that since futex variants do not use the fast-path, can be -- * simple and will not need to retry. -- */ --bool __sched __rt_mutex_futex_unlock(struct rt_mutex *lock, -- struct wake_q_head *wake_q) -+static bool __sched __rt_mutex_unlock_common(struct rt_mutex *lock, -+ struct wake_q_head *wake_q, -+ struct wake_q_head *wq_sleeper) - { - lockdep_assert_held(&lock->wait_lock); - -@@ -1631,22 +2008,34 @@ bool __sched __rt_mutex_futex_unlock(str - * avoid inversion prior to the wakeup. preempt_disable() - * therein pairs with rt_mutex_postunlock(). - */ -- mark_wakeup_next_waiter(wake_q, lock); -+ mark_wakeup_next_waiter(wake_q, wq_sleeper, lock); - - return true; /* call postunlock() */ - } - -+/** -+ * Futex variant, that since futex variants do not use the fast-path, can be -+ * simple and will not need to retry. -+ */ -+bool __sched __rt_mutex_futex_unlock(struct rt_mutex *lock, -+ struct wake_q_head *wake_q, -+ struct wake_q_head *wq_sleeper) -+{ -+ return __rt_mutex_unlock_common(lock, wake_q, wq_sleeper); -+} -+ - void __sched rt_mutex_futex_unlock(struct rt_mutex *lock) - { - DEFINE_WAKE_Q(wake_q); -+ DEFINE_WAKE_Q(wake_sleeper_q); - bool postunlock; - - raw_spin_lock_irq(&lock->wait_lock); -- postunlock = __rt_mutex_futex_unlock(lock, &wake_q); -+ postunlock = __rt_mutex_futex_unlock(lock, &wake_q, &wake_sleeper_q); - raw_spin_unlock_irq(&lock->wait_lock); - - if (postunlock) -- rt_mutex_postunlock(&wake_q); -+ rt_mutex_postunlock(&wake_q, &wake_sleeper_q); - } - - /** -@@ -1679,13 +2068,12 @@ EXPORT_SYMBOL_GPL(rt_mutex_destroy); - void __rt_mutex_init(struct rt_mutex *lock, const char *name) - { - lock->owner = NULL; -- raw_spin_lock_init(&lock->wait_lock); - lock->waiters = RB_ROOT; - lock->waiters_leftmost = NULL; - - debug_rt_mutex_init(lock, name); - } --EXPORT_SYMBOL_GPL(__rt_mutex_init); -+EXPORT_SYMBOL(__rt_mutex_init); - - /** - * rt_mutex_init_proxy_locked - initialize and lock a rt_mutex on behalf of a -@@ -1704,7 +2092,7 @@ EXPORT_SYMBOL_GPL(__rt_mutex_init); - void rt_mutex_init_proxy_locked(struct rt_mutex *lock, - struct task_struct *proxy_owner) - { -- __rt_mutex_init(lock, NULL); -+ rt_mutex_init(lock); - debug_rt_mutex_proxy_lock(lock, proxy_owner); - rt_mutex_set_owner(lock, proxy_owner); - } -@@ -1925,3 +2313,25 @@ bool rt_mutex_cleanup_proxy_lock(struct - - return cleanup; - } -+ -+#ifdef CONFIG_PREEMPT_RT_FULL -+struct ww_mutex { -+}; -+struct ww_acquire_ctx { -+}; -+int __ww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ww_ctx) -+{ -+ BUG(); -+} -+EXPORT_SYMBOL_GPL(__ww_mutex_lock); -+int __ww_mutex_lock_interruptible(struct ww_mutex *lock, struct ww_acquire_ctx *ww_ctx) -+{ -+ BUG(); -+} -+EXPORT_SYMBOL_GPL(__ww_mutex_lock_interruptible); -+void __sched ww_mutex_unlock(struct ww_mutex *lock) -+{ -+ BUG(); -+} -+EXPORT_SYMBOL_GPL(ww_mutex_unlock); -+#endif ---- a/kernel/locking/rtmutex_common.h -+++ b/kernel/locking/rtmutex_common.h -@@ -14,6 +14,7 @@ - - #include <linux/rtmutex.h> - #include <linux/sched/wake_q.h> -+#include <linux/sched/debug.h> - - /* - * This is the control structure for tasks blocked on a rt_mutex, -@@ -28,6 +29,7 @@ struct rt_mutex_waiter { - struct rb_node pi_tree_entry; - struct task_struct *task; - struct rt_mutex *lock; -+ bool savestate; - #ifdef CONFIG_DEBUG_RT_MUTEXES - unsigned long ip; - struct pid *deadlock_task_pid; -@@ -107,7 +109,7 @@ extern void rt_mutex_init_proxy_locked(s - struct task_struct *proxy_owner); - extern void rt_mutex_proxy_unlock(struct rt_mutex *lock, - struct task_struct *proxy_owner); --extern void rt_mutex_init_waiter(struct rt_mutex_waiter *waiter); -+extern void rt_mutex_init_waiter(struct rt_mutex_waiter *waiter, bool savetate); - extern int __rt_mutex_start_proxy_lock(struct rt_mutex *lock, - struct rt_mutex_waiter *waiter, - struct task_struct *task); -@@ -124,9 +126,11 @@ extern int rt_mutex_futex_trylock(struct - - extern void rt_mutex_futex_unlock(struct rt_mutex *lock); - extern bool __rt_mutex_futex_unlock(struct rt_mutex *lock, -- struct wake_q_head *wqh); -+ struct wake_q_head *wqh, -+ struct wake_q_head *wq_sleeper); - --extern void rt_mutex_postunlock(struct wake_q_head *wake_q); -+extern void rt_mutex_postunlock(struct wake_q_head *wake_q, -+ struct wake_q_head *wake_sleeper_q); - - #ifdef CONFIG_DEBUG_RT_MUTEXES - # include "rtmutex-debug.h" ---- a/kernel/locking/spinlock.c -+++ b/kernel/locking/spinlock.c -@@ -124,8 +124,11 @@ void __lockfunc __raw_##op##_lock_bh(loc - * __[spin|read|write]_lock_bh() - */ - BUILD_LOCK_OPS(spin, raw_spinlock); -+ -+#ifndef CONFIG_PREEMPT_RT_FULL - BUILD_LOCK_OPS(read, rwlock); - BUILD_LOCK_OPS(write, rwlock); -+#endif - - #endif - -@@ -209,6 +212,8 @@ void __lockfunc _raw_spin_unlock_bh(raw_ - EXPORT_SYMBOL(_raw_spin_unlock_bh); - #endif - -+#ifndef CONFIG_PREEMPT_RT_FULL -+ - #ifndef CONFIG_INLINE_READ_TRYLOCK - int __lockfunc _raw_read_trylock(rwlock_t *lock) - { -@@ -353,6 +358,8 @@ void __lockfunc _raw_write_unlock_bh(rwl - EXPORT_SYMBOL(_raw_write_unlock_bh); - #endif - -+#endif /* !PREEMPT_RT_FULL */ -+ - #ifdef CONFIG_DEBUG_LOCK_ALLOC - - void __lockfunc _raw_spin_lock_nested(raw_spinlock_t *lock, int subclass) ---- a/kernel/locking/spinlock_debug.c -+++ b/kernel/locking/spinlock_debug.c -@@ -31,6 +31,7 @@ void __raw_spin_lock_init(raw_spinlock_t - - EXPORT_SYMBOL(__raw_spin_lock_init); - -+#ifndef CONFIG_PREEMPT_RT_FULL - void __rwlock_init(rwlock_t *lock, const char *name, - struct lock_class_key *key) - { -@@ -48,6 +49,7 @@ void __rwlock_init(rwlock_t *lock, const - } - - EXPORT_SYMBOL(__rwlock_init); -+#endif - - static void spin_dump(raw_spinlock_t *lock, const char *msg) - { -@@ -135,6 +137,7 @@ void do_raw_spin_unlock(raw_spinlock_t * - arch_spin_unlock(&lock->raw_lock); - } - -+#ifndef CONFIG_PREEMPT_RT_FULL - static void rwlock_bug(rwlock_t *lock, const char *msg) - { - if (!debug_locks_off()) -@@ -224,3 +227,5 @@ void do_raw_write_unlock(rwlock_t *lock) - debug_write_unlock(lock); - arch_write_unlock(&lock->raw_lock); - } -+ -+#endif ---- a/kernel/sched/core.c -+++ b/kernel/sched/core.c -@@ -460,7 +460,7 @@ void wake_q_add(struct wake_q_head *head - head->lastp = &node->next; - } - --void wake_up_q(struct wake_q_head *head) -+void __wake_up_q(struct wake_q_head *head, bool sleeper) - { - struct wake_q_node *node = head->first; - -@@ -477,7 +477,10 @@ void wake_up_q(struct wake_q_head *head) - * wake_up_process() implies a wmb() to pair with the queueing - * in wake_q_add() so as not to miss wakeups. - */ -- wake_up_process(task); -+ if (sleeper) -+ wake_up_lock_sleeper(task); -+ else -+ wake_up_process(task); - put_task_struct(task); - } - } diff --git a/patches/rt-introduce-cpu-chill.patch b/patches/rt-introduce-cpu-chill.patch index 51b2ac0ed9cb..282b10ea751d 100644 --- a/patches/rt-introduce-cpu-chill.patch +++ b/patches/rt-introduce-cpu-chill.patch @@ -100,9 +100,9 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #endif /* defined(_LINUX_DELAY_H) */ --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c -@@ -1807,6 +1807,25 @@ SYSCALL_DEFINE2(nanosleep, struct timesp - return hrtimer_nanosleep(&tu, rmtp, HRTIMER_MODE_REL, CLOCK_MONOTONIC); +@@ -1825,6 +1825,25 @@ COMPAT_SYSCALL_DEFINE2(nanosleep, struct } + #endif +#ifdef CONFIG_PREEMPT_RT_FULL +/* @@ -110,13 +110,13 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + */ +void cpu_chill(void) +{ -+ struct timespec tu = { ++ struct timespec64 tu = { + .tv_nsec = NSEC_PER_MSEC, + }; + unsigned int freeze_flag = current->flags & PF_NOFREEZE; + + current->flags |= PF_NOFREEZE; -+ hrtimer_nanosleep(&tu, NULL, HRTIMER_MODE_REL, CLOCK_MONOTONIC_HARD); ++ hrtimer_nanosleep(&tu, HRTIMER_MODE_REL, CLOCK_MONOTONIC_HARD); + if (!freeze_flag) + current->flags &= ~PF_NOFREEZE; +} diff --git a/patches/rt-local-irq-lock.patch b/patches/rt-local-irq-lock.patch index b529ef37a3a4..f1435ee1ed62 100644 --- a/patches/rt-local-irq-lock.patch +++ b/patches/rt-local-irq-lock.patch @@ -12,13 +12,13 @@ is held and the owner is preempted. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- - include/linux/locallock.h | 266 ++++++++++++++++++++++++++++++++++++++++++++++ - include/linux/percpu.h | 29 +++++ - 2 files changed, 295 insertions(+) + include/linux/locallock.h | 271 ++++++++++++++++++++++++++++++++++++++++++++++ + include/linux/percpu.h | 29 ++++ + 2 files changed, 300 insertions(+) --- /dev/null +++ b/include/linux/locallock.h -@@ -0,0 +1,266 @@ +@@ -0,0 +1,271 @@ +#ifndef _LINUX_LOCALLOCK_H +#define _LINUX_LOCALLOCK_H + @@ -57,20 +57,10 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + spin_lock_init(&per_cpu(lvar, __cpu).lock); \ + } while (0) + -+/* -+ * spin_lock|trylock|unlock_local flavour that does not migrate disable -+ * used for __local_lock|trylock|unlock where get_local_var/put_local_var -+ * already takes care of the migrate_disable/enable -+ * for CONFIG_PREEMPT_BASE map to the normal spin_* calls. -+ */ -+# define spin_lock_local(lock) spin_lock(lock) -+# define spin_trylock_local(lock) spin_trylock(lock) -+# define spin_unlock_local(lock) spin_unlock(lock) -+ +static inline void __local_lock(struct local_irq_lock *lv) +{ + if (lv->owner != current) { -+ spin_lock_local(&lv->lock); ++ spin_lock(&lv->lock); + LL_WARN(lv->owner); + LL_WARN(lv->nestcnt); + lv->owner = current; @@ -81,14 +71,20 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +#define local_lock(lvar) \ + do { __local_lock(&get_local_var(lvar)); } while (0) + ++#define local_lock_on(lvar, cpu) \ ++ do { __local_lock(&per_cpu(lvar, cpu)); } while (0) ++ +static inline int __local_trylock(struct local_irq_lock *lv) +{ -+ if (lv->owner != current && spin_trylock_local(&lv->lock)) { ++ if (lv->owner != current && spin_trylock(&lv->lock)) { + LL_WARN(lv->owner); + LL_WARN(lv->nestcnt); + lv->owner = current; + lv->nestcnt = 1; + return 1; ++ } else if (lv->owner == current) { ++ lv->nestcnt++; ++ return 1; + } + return 0; +} @@ -110,7 +106,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + return; + + lv->owner = NULL; -+ spin_unlock_local(&lv->lock); ++ spin_unlock(&lv->lock); +} + +#define local_unlock(lvar) \ @@ -119,6 +115,9 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + put_local_var(lvar); \ + } while (0) + ++#define local_unlock_on(lvar, cpu) \ ++ do { __local_unlock(&per_cpu(lvar, cpu)); } while (0) ++ +static inline void __local_lock_irq(struct local_irq_lock *lv) +{ + spin_lock_irqsave(&lv->lock, lv->flags); @@ -259,6 +258,12 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + +static inline void local_irq_lock_init(int lvar) { } + ++#define local_trylock(lvar) \ ++ ({ \ ++ preempt_disable(); \ ++ 1; \ ++ }) ++ +#define local_lock(lvar) preempt_disable() +#define local_unlock(lvar) preempt_enable() +#define local_lock_irq(lvar) local_irq_disable() diff --git a/patches/rt-locking--Consolidate-lock-functions.patch b/patches/rt-locking--Consolidate-lock-functions.patch deleted file mode 100644 index 8340f8ec99a0..000000000000 --- a/patches/rt-locking--Consolidate-lock-functions.patch +++ /dev/null @@ -1,178 +0,0 @@ -Subject: rt/locking: Consolidate lock functions -From: Thomas Gleixner <tglx@linutronix.de> -Date: Fri, 28 Jul 2017 12:26:59 +0200 - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - include/linux/locallock.h | 22 +++------------------- - include/linux/spinlock_rt.h | 7 ++----- - kernel/locking/rt.c | 3 +++ - kernel/locking/rtmutex.c | 36 +----------------------------------- - 4 files changed, 9 insertions(+), 59 deletions(-) - ---- a/include/linux/locallock.h -+++ b/include/linux/locallock.h -@@ -36,26 +36,10 @@ struct local_irq_lock { - spin_lock_init(&per_cpu(lvar, __cpu).lock); \ - } while (0) - --/* -- * spin_lock|trylock|unlock_local flavour that does not migrate disable -- * used for __local_lock|trylock|unlock where get_local_var/put_local_var -- * already takes care of the migrate_disable/enable -- * for CONFIG_PREEMPT_BASE map to the normal spin_* calls. -- */ --#ifdef CONFIG_PREEMPT_RT_FULL --# define spin_lock_local(lock) rt_spin_lock__no_mg(lock) --# define spin_trylock_local(lock) rt_spin_trylock__no_mg(lock) --# define spin_unlock_local(lock) rt_spin_unlock__no_mg(lock) --#else --# define spin_lock_local(lock) spin_lock(lock) --# define spin_trylock_local(lock) spin_trylock(lock) --# define spin_unlock_local(lock) spin_unlock(lock) --#endif -- - static inline void __local_lock(struct local_irq_lock *lv) - { - if (lv->owner != current) { -- spin_lock_local(&lv->lock); -+ spin_lock(&lv->lock); - LL_WARN(lv->owner); - LL_WARN(lv->nestcnt); - lv->owner = current; -@@ -71,7 +55,7 @@ static inline void __local_lock(struct l - - static inline int __local_trylock(struct local_irq_lock *lv) - { -- if (lv->owner != current && spin_trylock_local(&lv->lock)) { -+ if (lv->owner != current && spin_trylock(&lv->lock)) { - LL_WARN(lv->owner); - LL_WARN(lv->nestcnt); - lv->owner = current; -@@ -101,7 +85,7 @@ static inline void __local_unlock(struct - return; - - lv->owner = NULL; -- spin_unlock_local(&lv->lock); -+ spin_unlock(&lv->lock); - } - - #define local_unlock(lvar) \ ---- a/include/linux/spinlock_rt.h -+++ b/include/linux/spinlock_rt.h -@@ -18,10 +18,6 @@ do { \ - __rt_spin_lock_init(slock, #slock, &__key); \ - } while (0) - --void __lockfunc rt_spin_lock__no_mg(spinlock_t *lock); --void __lockfunc rt_spin_unlock__no_mg(spinlock_t *lock); --int __lockfunc rt_spin_trylock__no_mg(spinlock_t *lock); -- - extern void __lockfunc rt_spin_lock(spinlock_t *lock); - extern unsigned long __lockfunc rt_spin_lock_trace_flags(spinlock_t *lock); - extern void __lockfunc rt_spin_lock_nested(spinlock_t *lock, int subclass); -@@ -35,9 +31,10 @@ extern int atomic_dec_and_spin_lock(atom - /* - * lockdep-less calls, for derived types like rwlock: - * (for trylock they can use rt_mutex_trylock() directly. -+ * Migrate disable handling must be done at the call site. - */ --extern void __lockfunc __rt_spin_lock__no_mg(struct rt_mutex *lock); - extern void __lockfunc __rt_spin_lock(struct rt_mutex *lock); -+extern void __lockfunc __rt_spin_trylock(struct rt_mutex *lock); - extern void __lockfunc __rt_spin_unlock(struct rt_mutex *lock); - - #define spin_lock(lock) rt_spin_lock(lock) ---- a/kernel/locking/rt.c -+++ b/kernel/locking/rt.c -@@ -239,6 +239,7 @@ EXPORT_SYMBOL(rt_read_trylock); - - void __lockfunc rt_write_lock(rwlock_t *rwlock) - { -+ migrate_disable(); - rwlock_acquire(&rwlock->dep_map, 0, 0, _RET_IP_); - __rt_spin_lock(&rwlock->lock); - } -@@ -248,9 +249,11 @@ void __lockfunc rt_read_lock(rwlock_t *r - { - struct rt_mutex *lock = &rwlock->lock; - -+ migrate_disable(); - rwlock_acquire(&rwlock->dep_map, 0, 0, _RET_IP_); - __rt_spin_lock(lock); - } -+ - EXPORT_SYMBOL(rt_read_lock); - - void __lockfunc rt_write_unlock(rwlock_t *rwlock) ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -1146,13 +1146,6 @@ static void noinline __sched rt_spin_lo - rt_mutex_postunlock(&wake_q, &wake_sleeper_q); - } - --void __lockfunc rt_spin_lock__no_mg(spinlock_t *lock) --{ -- rt_spin_lock_fastlock(&lock->lock, rt_spin_lock_slowlock); -- spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); --} --EXPORT_SYMBOL(rt_spin_lock__no_mg); -- - void __lockfunc rt_spin_lock(spinlock_t *lock) - { - migrate_disable(); -@@ -1163,35 +1156,19 @@ EXPORT_SYMBOL(rt_spin_lock); - - void __lockfunc __rt_spin_lock(struct rt_mutex *lock) - { -- migrate_disable(); - rt_spin_lock_fastlock(lock, rt_spin_lock_slowlock); - } --EXPORT_SYMBOL(__rt_spin_lock); -- --void __lockfunc __rt_spin_lock__no_mg(struct rt_mutex *lock) --{ -- rt_spin_lock_fastlock(lock, rt_spin_lock_slowlock); --} --EXPORT_SYMBOL(__rt_spin_lock__no_mg); - - #ifdef CONFIG_DEBUG_LOCK_ALLOC - void __lockfunc rt_spin_lock_nested(spinlock_t *lock, int subclass) - { - migrate_disable(); -- rt_spin_lock_fastlock(&lock->lock, rt_spin_lock_slowlock); - spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_); -+ rt_spin_lock_fastlock(&lock->lock, rt_spin_lock_slowlock); - } - EXPORT_SYMBOL(rt_spin_lock_nested); - #endif - --void __lockfunc rt_spin_unlock__no_mg(spinlock_t *lock) --{ -- /* NOTE: we always pass in '1' for nested, for simplicity */ -- spin_release(&lock->dep_map, 1, _RET_IP_); -- rt_spin_lock_fastunlock(&lock->lock, rt_spin_lock_slowunlock); --} --EXPORT_SYMBOL(rt_spin_unlock__no_mg); -- - void __lockfunc rt_spin_unlock(spinlock_t *lock) - { - /* NOTE: we always pass in '1' for nested, for simplicity */ -@@ -1219,17 +1196,6 @@ void __lockfunc rt_spin_unlock_wait(spin - } - EXPORT_SYMBOL(rt_spin_unlock_wait); - --int __lockfunc rt_spin_trylock__no_mg(spinlock_t *lock) --{ -- int ret; -- -- ret = rt_mutex_trylock(&lock->lock); -- if (ret) -- spin_acquire(&lock->dep_map, 0, 1, _RET_IP_); -- return ret; --} --EXPORT_SYMBOL(rt_spin_trylock__no_mg); -- - int __lockfunc rt_spin_trylock(spinlock_t *lock) - { - int ret; diff --git a/patches/rt-locking--Consolidate-rwlock-variants.patch b/patches/rt-locking--Consolidate-rwlock-variants.patch deleted file mode 100644 index 2cc908b13bd0..000000000000 --- a/patches/rt-locking--Consolidate-rwlock-variants.patch +++ /dev/null @@ -1,262 +0,0 @@ -Subject: rt/locking: Consolidate rwlock variants -From: Thomas Gleixner <tglx@linutronix.de> -Date: Fri, 28 Jul 2017 15:55:41 +0200 - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - kernel/locking/rt.c | 85 ------------------------------------ - kernel/locking/rwlock-rt.c | 104 ++++++++++++++++++++++++++++++++++++++++----- - 2 files changed, 94 insertions(+), 95 deletions(-) - ---- a/kernel/locking/rt.c -+++ b/kernel/locking/rt.c -@@ -198,91 +198,6 @@ void __lockfunc _mutex_unlock(struct mut - } - EXPORT_SYMBOL(_mutex_unlock); - --#ifndef CONFIG_RWLOCK_RT_READER_BIASED --/* -- * rwlock_t functions -- */ --int __lockfunc rt_write_trylock(rwlock_t *rwlock) --{ -- int ret; -- -- migrate_disable(); -- ret = rt_mutex_trylock(&rwlock->lock); -- if (ret) -- rwlock_acquire(&rwlock->dep_map, 0, 1, _RET_IP_); -- else -- migrate_enable(); -- return ret; --} --EXPORT_SYMBOL(rt_write_trylock); -- --int __lockfunc rt_read_trylock(rwlock_t *rwlock) --{ -- struct rt_mutex *lock = &rwlock->lock; -- int ret; -- -- migrate_disable(); -- ret = rt_mutex_trylock(lock); -- if (ret) -- rwlock_acquire(&rwlock->dep_map, 0, 1, _RET_IP_); -- else -- migrate_enable(); -- return ret; --} --EXPORT_SYMBOL(rt_read_trylock); -- --void __lockfunc rt_write_lock(rwlock_t *rwlock) --{ -- migrate_disable(); -- rwlock_acquire(&rwlock->dep_map, 0, 0, _RET_IP_); -- __rt_spin_lock(&rwlock->lock); --} --EXPORT_SYMBOL(rt_write_lock); -- --void __lockfunc rt_read_lock(rwlock_t *rwlock) --{ -- struct rt_mutex *lock = &rwlock->lock; -- -- migrate_disable(); -- rwlock_acquire(&rwlock->dep_map, 0, 0, _RET_IP_); -- __rt_spin_lock(lock); --} -- --EXPORT_SYMBOL(rt_read_lock); -- --void __lockfunc rt_write_unlock(rwlock_t *rwlock) --{ -- /* NOTE: we always pass in '1' for nested, for simplicity */ -- rwlock_release(&rwlock->dep_map, 1, _RET_IP_); -- __rt_spin_unlock(&rwlock->lock); -- migrate_enable(); --} --EXPORT_SYMBOL(rt_write_unlock); -- --void __lockfunc rt_read_unlock(rwlock_t *rwlock) --{ -- rwlock_release(&rwlock->dep_map, 1, _RET_IP_); -- __rt_spin_unlock(&rwlock->lock); -- migrate_enable(); --} --EXPORT_SYMBOL(rt_read_unlock); -- --void __rt_rwlock_init(rwlock_t *rwlock, char *name, struct lock_class_key *key) --{ -- rt_mutex_init(&rwlock->lock); -- --#ifdef CONFIG_DEBUG_LOCK_ALLOC -- /* -- * Make sure we are not reinitializing a held lock: -- */ -- debug_check_no_locks_freed((void *)rwlock, sizeof(*rwlock)); -- lockdep_init_map(&rwlock->dep_map, name, key, 0); --#endif -- rwlock->lock.save_state = 1; --} --EXPORT_SYMBOL(__rt_rwlock_init); --#endif -- - /** - * atomic_dec_and_mutex_lock - return holding mutex if we dec to 0 - * @cnt: the atomic which we are to dec ---- a/kernel/locking/rwlock-rt.c -+++ b/kernel/locking/rwlock-rt.c -@@ -245,14 +245,100 @@ void __write_rt_unlock(struct rt_rw_lock - __write_unlock_common(lock, WRITER_BIAS, flags); - } - --#ifdef CONFIG_RWLOCK_RT_READER_BIASED -+#ifndef CONFIG_RWLOCK_RT_READER_BIASED -+/* Map the single reader implementation */ -+static inline int do_read_rt_trylock(rwlock_t *rwlock) -+{ -+ return rt_mutex_trylock(&rwlock->lock); -+} -+ -+static inline int do_write_rt_trylock(rwlock_t *rwlock) -+{ -+ return rt_mutex_trylock(&rwlock->lock); -+} -+ -+static inline void do_read_rt_lock(rwlock_t *rwlock) -+{ -+ __rt_spin_lock(&rwlock->lock); -+} -+ -+static inline void do_write_rt_lock(rwlock_t *rwlock) -+{ -+ __rt_spin_lock(&rwlock->lock); -+} -+ -+static inline void do_read_rt_unlock(rwlock_t *rwlock) -+{ -+ __rt_spin_unlock(&rwlock->lock); -+} - -+static inline void do_write_rt_unlock(rwlock_t *rwlock) -+{ -+ __rt_spin_unlock(&rwlock->lock); -+} -+ -+static inline void do_rwlock_rt_init(rwlock_t *rwlock, const char *name, -+ struct lock_class_key *key) -+{ -+#ifdef CONFIG_DEBUG_LOCK_ALLOC -+ /* -+ * Make sure we are not reinitializing a held lock: -+ */ -+ debug_check_no_locks_freed((void *)rwlock, sizeof(*rwlock)); -+ lockdep_init_map(&rwlock->dep_map, name, key, 0); -+#endif -+ rt_mutex_init(&rwlock->lock); -+ rwlock->lock.save_state = 1; -+} -+ -+#else -+/* Map the reader biased implementation */ -+static inline int do_read_rt_trylock(rwlock_t *rwlock) -+{ -+ return __read_rt_trylock(rwlock); -+} -+ -+static inline int do_write_rt_trylock(rwlock_t *rwlock) -+{ -+ return __write_rt_trylock(rwlock); -+} -+ -+static inline void do_read_rt_lock(rwlock_t *rwlock) -+{ -+ __read_rt_lock(rwlock); -+} -+ -+static inline void do_write_rt_lock(rwlock_t *rwlock) -+{ -+ __write_rt_lock(rwlock); -+} -+ -+static inline void do_read_rt_unlock(rwlock_t *rwlock) -+{ -+ __read_rt_unlock(rwlock); -+} -+ -+static inline void do_write_rt_unlock(rwlock_t *rwlock) -+{ -+ __write_rt_unlock(rwlock); -+} -+ -+static inline void do_rwlock_rt_init(rwlock_t *rwlock, const char *name, -+ struct lock_class_key *key) -+{ -+ __rwlock_biased_rt_init(rwlock, name, key); -+} -+#endif -+ -+/* -+ * The common functions which get wrapped into the rwlock API. -+ */ - int __lockfunc rt_read_trylock(rwlock_t *rwlock) - { - int ret; - - migrate_disable(); -- ret = __read_rt_trylock(rwlock); -+ ret = do_read_rt_trylock(rwlock); - if (ret) - rwlock_acquire_read(&rwlock->dep_map, 0, 1, _RET_IP_); - else -@@ -266,7 +352,7 @@ int __lockfunc rt_write_trylock(rwlock_t - int ret; - - migrate_disable(); -- ret = __write_rt_trylock(rwlock); -+ ret = do_write_rt_trylock(rwlock); - if (ret) - rwlock_acquire(&rwlock->dep_map, 0, 1, _RET_IP_); - else -@@ -279,7 +365,7 @@ void __lockfunc rt_read_lock(rwlock_t *r - { - migrate_disable(); - rwlock_acquire_read(&rwlock->dep_map, 0, 0, _RET_IP_); -- __read_rt_lock(rwlock); -+ do_read_rt_lock(rwlock); - } - EXPORT_SYMBOL(rt_read_lock); - -@@ -287,14 +373,14 @@ void __lockfunc rt_write_lock(rwlock_t * - { - migrate_disable(); - rwlock_acquire(&rwlock->dep_map, 0, 0, _RET_IP_); -- __write_rt_lock(rwlock); -+ do_write_rt_lock(rwlock); - } - EXPORT_SYMBOL(rt_write_lock); - - void __lockfunc rt_read_unlock(rwlock_t *rwlock) - { - rwlock_release(&rwlock->dep_map, 1, _RET_IP_); -- __read_rt_unlock(rwlock); -+ do_read_rt_unlock(rwlock); - migrate_enable(); - } - EXPORT_SYMBOL(rt_read_unlock); -@@ -302,15 +388,13 @@ EXPORT_SYMBOL(rt_read_unlock); - void __lockfunc rt_write_unlock(rwlock_t *rwlock) - { - rwlock_release(&rwlock->dep_map, 1, _RET_IP_); -- __write_rt_unlock(rwlock); -+ do_write_rt_unlock(rwlock); - migrate_enable(); - } - EXPORT_SYMBOL(rt_write_unlock); - - void __rt_rwlock_init(rwlock_t *rwlock, char *name, struct lock_class_key *key) - { -- __rwlock_biased_rt_init(rwlock, name, key); -+ do_rwlock_rt_init(rwlock, name, key); - } - EXPORT_SYMBOL(__rt_rwlock_init); -- --#endif diff --git a/patches/rt-locking--Simplify-rt-rwlock.patch b/patches/rt-locking--Simplify-rt-rwlock.patch deleted file mode 100644 index 9e9de5eb40ce..000000000000 --- a/patches/rt-locking--Simplify-rt-rwlock.patch +++ /dev/null @@ -1,104 +0,0 @@ -Subject: rt/locking: Simplify rt rwlock -From: Thomas Gleixner <tglx@linutronix.de> -Date: Fri, 28 Jul 2017 15:05:51 +0200 - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - include/linux/rwlock_rt.h | 21 +++++++++++++-------- - kernel/locking/rt.c | 23 ++--------------------- - 2 files changed, 15 insertions(+), 29 deletions(-) - ---- a/include/linux/rwlock_rt.h -+++ b/include/linux/rwlock_rt.h -@@ -9,37 +9,42 @@ - do { \ - static struct lock_class_key __key; \ - \ -- rt_mutex_init(&(rwl)->lock); \ - __rt_rwlock_init(rwl, #rwl, &__key); \ - } while (0) - - extern void __lockfunc rt_write_lock(rwlock_t *rwlock); - extern void __lockfunc rt_read_lock(rwlock_t *rwlock); - extern int __lockfunc rt_write_trylock(rwlock_t *rwlock); --extern int __lockfunc rt_write_trylock_irqsave(rwlock_t *trylock, unsigned long *flags); - extern int __lockfunc rt_read_trylock(rwlock_t *rwlock); - extern void __lockfunc rt_write_unlock(rwlock_t *rwlock); - extern void __lockfunc rt_read_unlock(rwlock_t *rwlock); --extern unsigned long __lockfunc rt_write_lock_irqsave(rwlock_t *rwlock); --extern unsigned long __lockfunc rt_read_lock_irqsave(rwlock_t *rwlock); - extern void __rt_rwlock_init(rwlock_t *rwlock, char *name, struct lock_class_key *key); - - #define read_trylock(lock) __cond_lock(lock, rt_read_trylock(lock)) - #define write_trylock(lock) __cond_lock(lock, rt_write_trylock(lock)) - --#define write_trylock_irqsave(lock, flags) \ -- __cond_lock(lock, rt_write_trylock_irqsave(lock, &flags)) -+static inline int __write_trylock_rt_irqsave(rwlock_t *lock, unsigned long *flags) -+{ -+ /* XXX ARCH_IRQ_ENABLED */ -+ *flags = 0; -+ return rt_write_trylock(lock); -+} -+ -+#define write_trylock_irqsave(lock, flags) \ -+ __cond_lock(lock, __write_trylock_rt_irqsave(lock, &(flags))) - - #define read_lock_irqsave(lock, flags) \ - do { \ - typecheck(unsigned long, flags); \ -- flags = rt_read_lock_irqsave(lock); \ -+ rt_read_lock(lock); \ -+ flags = 0; \ - } while (0) - - #define write_lock_irqsave(lock, flags) \ - do { \ - typecheck(unsigned long, flags); \ -- flags = rt_write_lock_irqsave(lock); \ -+ rt_write_lock(lock); \ -+ flags = 0; \ - } while (0) - - #define read_lock(lock) rt_read_lock(lock) ---- a/kernel/locking/rt.c -+++ b/kernel/locking/rt.c -@@ -215,13 +215,6 @@ int __lockfunc rt_write_trylock(rwlock_t - } - EXPORT_SYMBOL(rt_write_trylock); - --int __lockfunc rt_write_trylock_irqsave(rwlock_t *rwlock, unsigned long *flags) --{ -- *flags = 0; -- return rt_write_trylock(rwlock); --} --EXPORT_SYMBOL(rt_write_trylock_irqsave); -- - int __lockfunc rt_read_trylock(rwlock_t *rwlock) - { - struct rt_mutex *lock = &rwlock->lock; -@@ -273,22 +266,10 @@ void __lockfunc rt_read_unlock(rwlock_t - } - EXPORT_SYMBOL(rt_read_unlock); - --unsigned long __lockfunc rt_write_lock_irqsave(rwlock_t *rwlock) --{ -- rt_write_lock(rwlock); -- return 0; --} --EXPORT_SYMBOL(rt_write_lock_irqsave); -- --unsigned long __lockfunc rt_read_lock_irqsave(rwlock_t *rwlock) --{ -- rt_read_lock(rwlock); -- return 0; --} --EXPORT_SYMBOL(rt_read_lock_irqsave); -- - void __rt_rwlock_init(rwlock_t *rwlock, char *name, struct lock_class_key *key) - { -+ rt_mutex_init(&rwlock->lock); -+ - #ifdef CONFIG_DEBUG_LOCK_ALLOC - /* - * Make sure we are not reinitializing a held lock: diff --git a/patches/rt-locking-allow-recursive-local_trylock.patch b/patches/rt-locking-allow-recursive-local_trylock.patch deleted file mode 100644 index 82521dd7e4c6..000000000000 --- a/patches/rt-locking-allow-recursive-local_trylock.patch +++ /dev/null @@ -1,38 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Thu, 21 Sep 2017 14:39:56 +0200 -Subject: rt/locking: allow recursive local_trylock() - -required for following networking patch which does recursive try-lock. -While at it, add the !RT version of it because it did not yet exist. - -Cc: rt-stable@vger.kernel.org -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - include/linux/locallock.h | 9 +++++++++ - 1 file changed, 9 insertions(+) - ---- a/include/linux/locallock.h -+++ b/include/linux/locallock.h -@@ -68,6 +68,9 @@ static inline int __local_trylock(struct - lv->owner = current; - lv->nestcnt = 1; - return 1; -+ } else if (lv->owner == current) { -+ lv->nestcnt++; -+ return 1; - } - return 0; - } -@@ -238,6 +241,12 @@ static inline int __local_unlock_irqrest - - static inline void local_irq_lock_init(int lvar) { } - -+#define local_trylock(lvar) \ -+ ({ \ -+ preempt_disable(); \ -+ 1; \ -+ }) -+ - #define local_lock(lvar) preempt_disable() - #define local_unlock(lvar) preempt_enable() - #define local_lock_irq(lvar) local_irq_disable() diff --git a/patches/rt-rwlock--Remove-recursive-support.patch b/patches/rt-rwlock--Remove-recursive-support.patch deleted file mode 100644 index c5451cb0c8e1..000000000000 --- a/patches/rt-rwlock--Remove-recursive-support.patch +++ /dev/null @@ -1,135 +0,0 @@ -Subject: rt/rwlock: Remove recursive support -From: Thomas Gleixner <tglx@linutronix.de> -Date: Fri, 28 Jul 2017 12:35:23 +0200 - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ---- - include/linux/rwlock_types_rt.h | 1 - kernel/locking/rt.c | 56 ++++++++-------------------------------- - 2 files changed, 12 insertions(+), 45 deletions(-) - ---- a/include/linux/rwlock_types_rt.h -+++ b/include/linux/rwlock_types_rt.h -@@ -10,7 +10,6 @@ - */ - typedef struct { - struct rt_mutex lock; -- int read_depth; - unsigned int break_lock; - #ifdef CONFIG_DEBUG_LOCK_ALLOC - struct lockdep_map dep_map; ---- a/kernel/locking/rt.c -+++ b/kernel/locking/rt.c -@@ -211,46 +211,28 @@ int __lockfunc rt_write_trylock(rwlock_t - rwlock_acquire(&rwlock->dep_map, 0, 1, _RET_IP_); - else - migrate_enable(); -- - return ret; - } - EXPORT_SYMBOL(rt_write_trylock); - - int __lockfunc rt_write_trylock_irqsave(rwlock_t *rwlock, unsigned long *flags) - { -- int ret; -- - *flags = 0; -- ret = rt_write_trylock(rwlock); -- return ret; -+ return rt_write_trylock(rwlock); - } - EXPORT_SYMBOL(rt_write_trylock_irqsave); - - int __lockfunc rt_read_trylock(rwlock_t *rwlock) - { - struct rt_mutex *lock = &rwlock->lock; -- int ret = 1; -- -- /* -- * recursive read locks succeed when current owns the lock, -- * but not when read_depth == 0 which means that the lock is -- * write locked. -- */ -- if (rt_mutex_owner(lock) != current) { -- migrate_disable(); -- ret = rt_mutex_trylock(lock); -- if (ret) -- rwlock_acquire(&rwlock->dep_map, 0, 1, _RET_IP_); -- else -- migrate_enable(); -- -- } else if (!rwlock->read_depth) { -- ret = 0; -- } -+ int ret; - -+ migrate_disable(); -+ ret = rt_mutex_trylock(lock); - if (ret) -- rwlock->read_depth++; -- -+ rwlock_acquire(&rwlock->dep_map, 0, 1, _RET_IP_); -+ else -+ migrate_enable(); - return ret; - } - EXPORT_SYMBOL(rt_read_trylock); -@@ -266,17 +248,9 @@ void __lockfunc rt_read_lock(rwlock_t *r - { - struct rt_mutex *lock = &rwlock->lock; - -- -- /* -- * recursive read locks succeed when current owns the lock -- */ -- if (rt_mutex_owner(lock) != current) { -- rwlock_acquire(&rwlock->dep_map, 0, 0, _RET_IP_); -- __rt_spin_lock(lock); -- } -- rwlock->read_depth++; -+ rwlock_acquire(&rwlock->dep_map, 0, 0, _RET_IP_); -+ __rt_spin_lock(lock); - } -- - EXPORT_SYMBOL(rt_read_lock); - - void __lockfunc rt_write_unlock(rwlock_t *rwlock) -@@ -290,19 +264,15 @@ EXPORT_SYMBOL(rt_write_unlock); - - void __lockfunc rt_read_unlock(rwlock_t *rwlock) - { -- /* Release the lock only when read_depth is down to 0 */ -- if (--rwlock->read_depth == 0) { -- rwlock_release(&rwlock->dep_map, 1, _RET_IP_); -- __rt_spin_unlock(&rwlock->lock); -- migrate_enable(); -- } -+ rwlock_release(&rwlock->dep_map, 1, _RET_IP_); -+ __rt_spin_unlock(&rwlock->lock); -+ migrate_enable(); - } - EXPORT_SYMBOL(rt_read_unlock); - - unsigned long __lockfunc rt_write_lock_irqsave(rwlock_t *rwlock) - { - rt_write_lock(rwlock); -- - return 0; - } - EXPORT_SYMBOL(rt_write_lock_irqsave); -@@ -310,7 +280,6 @@ EXPORT_SYMBOL(rt_write_lock_irqsave); - unsigned long __lockfunc rt_read_lock_irqsave(rwlock_t *rwlock) - { - rt_read_lock(rwlock); -- - return 0; - } - EXPORT_SYMBOL(rt_read_lock_irqsave); -@@ -325,7 +294,6 @@ void __rt_rwlock_init(rwlock_t *rwlock, - lockdep_init_map(&rwlock->dep_map, name, key, 0); - #endif - rwlock->lock.save_state = 1; -- rwlock->read_depth = 0; - } - EXPORT_SYMBOL(__rt_rwlock_init); - diff --git a/patches/rtmutex--Handle-non-enqueued-waiters-gracefully.patch b/patches/rtmutex--Handle-non-enqueued-waiters-gracefully.patch index 8b8dee043188..1673b3cfdb46 100644 --- a/patches/rtmutex--Handle-non-enqueued-waiters-gracefully.patch +++ b/patches/rtmutex--Handle-non-enqueued-waiters-gracefully.patch @@ -21,7 +21,7 @@ Cc: stable-rt@vger.kernel.org --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c -@@ -1707,7 +1707,7 @@ int __rt_mutex_start_proxy_lock(struct r +@@ -1729,7 +1729,7 @@ int __rt_mutex_start_proxy_lock(struct r ret = 0; } diff --git a/patches/rtmutex-Fix-lock-stealing-logic.patch b/patches/rtmutex-Fix-lock-stealing-logic.patch deleted file mode 100644 index 6321ecf740d8..000000000000 --- a/patches/rtmutex-Fix-lock-stealing-logic.patch +++ /dev/null @@ -1,161 +0,0 @@ -From: Mike Galbraith <efault@gmx.de> -Date: Fri, 23 Jun 2017 09:37:14 +0200 -Subject: rtmutex: Fix lock stealing logic - -1. When trying to acquire an rtmutex, we first try to grab it without -queueing the waiter, and explicitly check for that initial attempt -in the !waiter path of __try_to_take_rt_mutex(). Checking whether -the lock taker is top waiter before allowing a steal attempt in that -path is a thinko: the lock taker has not yet blocked. - -2. It seems wrong to change the definition of rt_mutex_waiter_less() -to mean less or perhaps equal when we have an rt_mutex_waiter_equal(). - -Remove the thinko, restore rt_mutex_waiter_less(), implement and use -rt_mutex_steal() based upon rt_mutex_waiter_less/equal(), moving all -qualification criteria into the function itself. - -Reviewed-by: Steven Rostedt (VMware) <rostedt@goodmis.org> -Signed-off-by: Mike Galbraith <efault@gmx.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/locking/rtmutex.c | 75 +++++++++++++++++++++++------------------------ - 1 file changed, 37 insertions(+), 38 deletions(-) - ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -235,26 +235,19 @@ static inline bool unlock_rt_mutex_safe( - } - #endif - --#define STEAL_NORMAL 0 --#define STEAL_LATERAL 1 -- - /* - * Only use with rt_mutex_waiter_{less,equal}() - */ --#define task_to_waiter(p) \ -- &(struct rt_mutex_waiter){ .prio = (p)->prio, .deadline = (p)->dl.deadline } -+#define task_to_waiter(p) &(struct rt_mutex_waiter) \ -+ { .prio = (p)->prio, .deadline = (p)->dl.deadline, .task = (p) } - - static inline int - rt_mutex_waiter_less(struct rt_mutex_waiter *left, -- struct rt_mutex_waiter *right, int mode) -+ struct rt_mutex_waiter *right) - { -- if (mode == STEAL_NORMAL) { -- if (left->prio < right->prio) -- return 1; -- } else { -- if (left->prio <= right->prio) -- return 1; -- } -+ if (left->prio < right->prio) -+ return 1; -+ - /* - * If both waiters have dl_prio(), we check the deadlines of the - * associated tasks. -@@ -286,6 +279,27 @@ rt_mutex_waiter_equal(struct rt_mutex_wa - return 1; - } - -+#define STEAL_NORMAL 0 -+#define STEAL_LATERAL 1 -+ -+static inline int -+rt_mutex_steal(struct rt_mutex *lock, struct rt_mutex_waiter *waiter, int mode) -+{ -+ struct rt_mutex_waiter *top_waiter = rt_mutex_top_waiter(lock); -+ -+ if (waiter == top_waiter || rt_mutex_waiter_less(waiter, top_waiter)) -+ return 1; -+ -+ /* -+ * Note that RT tasks are excluded from lateral-steals -+ * to prevent the introduction of an unbounded latency. -+ */ -+ if (mode == STEAL_NORMAL || rt_task(waiter->task)) -+ return 0; -+ -+ return rt_mutex_waiter_equal(waiter, top_waiter); -+} -+ - static void - rt_mutex_enqueue(struct rt_mutex *lock, struct rt_mutex_waiter *waiter) - { -@@ -297,7 +311,7 @@ rt_mutex_enqueue(struct rt_mutex *lock, - while (*link) { - parent = *link; - entry = rb_entry(parent, struct rt_mutex_waiter, tree_entry); -- if (rt_mutex_waiter_less(waiter, entry, STEAL_NORMAL)) { -+ if (rt_mutex_waiter_less(waiter, entry)) { - link = &parent->rb_left; - } else { - link = &parent->rb_right; -@@ -336,7 +350,7 @@ rt_mutex_enqueue_pi(struct task_struct * - while (*link) { - parent = *link; - entry = rb_entry(parent, struct rt_mutex_waiter, pi_tree_entry); -- if (rt_mutex_waiter_less(waiter, entry, STEAL_NORMAL)) { -+ if (rt_mutex_waiter_less(waiter, entry)) { - link = &parent->rb_left; - } else { - link = &parent->rb_right; -@@ -846,6 +860,7 @@ static int rt_mutex_adjust_prio_chain(st - * @task: The task which wants to acquire the lock - * @waiter: The waiter that is queued to the lock's wait tree if the - * callsite called task_blocked_on_lock(), otherwise NULL -+ * @mode: Lock steal mode (STEAL_NORMAL, STEAL_LATERAL) - */ - static int __try_to_take_rt_mutex(struct rt_mutex *lock, - struct task_struct *task, -@@ -885,14 +900,11 @@ static int __try_to_take_rt_mutex(struct - */ - if (waiter) { - /* -- * If waiter is not the highest priority waiter of -- * @lock, give up. -+ * If waiter is not the highest priority waiter of @lock, -+ * or its peer when lateral steal is allowed, give up. - */ -- if (waiter != rt_mutex_top_waiter(lock)) { -- /* XXX rt_mutex_waiter_less() ? */ -+ if (!rt_mutex_steal(lock, waiter, mode)) - return 0; -- } -- - /* - * We can acquire the lock. Remove the waiter from the - * lock waiters tree. -@@ -909,25 +921,12 @@ static int __try_to_take_rt_mutex(struct - * not need to be dequeued. - */ - if (rt_mutex_has_waiters(lock)) { -- struct task_struct *pown = rt_mutex_top_waiter(lock)->task; -- -- if (task != pown) -- return 0; -- -- /* -- * Note that RT tasks are excluded from lateral-steals -- * to prevent the introduction of an unbounded latency. -- */ -- if (rt_task(task)) -- mode = STEAL_NORMAL; - /* -- * If @task->prio is greater than or equal to -- * the top waiter priority (kernel view), -- * @task lost. -+ * If @task->prio is greater than the top waiter -+ * priority (kernel view), or equal to it when a -+ * lateral steal is forbidden, @task lost. - */ -- if (!rt_mutex_waiter_less(task_to_waiter(task), -- rt_mutex_top_waiter(lock), -- mode)) -+ if (!rt_mutex_steal(lock, task_to_waiter(task), mode)) - return 0; - /* - * The current top waiter stays enqueued. We diff --git a/patches/rtmutex-Make-lock_killable-work.patch b/patches/rtmutex-Make-lock_killable-work.patch index 38bde9b0c31a..aad1dd8f6a68 100644 --- a/patches/rtmutex-Make-lock_killable-work.patch +++ b/patches/rtmutex-Make-lock_killable-work.patch @@ -16,7 +16,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c -@@ -1215,18 +1215,13 @@ static int __sched +@@ -1213,18 +1213,13 @@ static int __sched if (try_to_take_rt_mutex(lock, current, waiter)) break; diff --git a/patches/rtmutex-Provide-rt_mutex_lock_state.patch b/patches/rtmutex-Provide-rt_mutex_lock_state.patch deleted file mode 100644 index 3be875875aa7..000000000000 --- a/patches/rtmutex-Provide-rt_mutex_lock_state.patch +++ /dev/null @@ -1,111 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Sat, 1 Apr 2017 12:51:00 +0200 -Subject: [PATCH] rtmutex: Provide rt_mutex_lock_state() - -Allow rtmutex to be locked with arbitrary states. Preparatory patch for the -rt rwsem rework. - -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - include/linux/rtmutex.h | 1 + - kernel/locking/rtmutex.c | 44 +++++++++++++++++++++++++------------------- - 2 files changed, 26 insertions(+), 19 deletions(-) - ---- a/include/linux/rtmutex.h -+++ b/include/linux/rtmutex.h -@@ -105,6 +105,7 @@ extern void __rt_mutex_init(struct rt_mu - extern void rt_mutex_destroy(struct rt_mutex *lock); - - extern void rt_mutex_lock(struct rt_mutex *lock); -+extern int rt_mutex_lock_state(struct rt_mutex *lock, int state); - extern int rt_mutex_lock_interruptible(struct rt_mutex *lock); - extern int rt_mutex_lock_killable(struct rt_mutex *lock); - extern int rt_mutex_timed_lock(struct rt_mutex *lock, ---- a/kernel/locking/rtmutex.c -+++ b/kernel/locking/rtmutex.c -@@ -2019,21 +2019,32 @@ rt_mutex_fastunlock(struct rt_mutex *loc - } - - /** -+ * rt_mutex_lock_state - lock a rt_mutex with a given state -+ * -+ * @lock: The rt_mutex to be locked -+ * @state: The state to set when blocking on the rt_mutex -+ */ -+int __sched rt_mutex_lock_state(struct rt_mutex *lock, int state) -+{ -+ might_sleep(); -+ -+ return rt_mutex_fastlock(lock, state, NULL, rt_mutex_slowlock); -+} -+ -+/** - * rt_mutex_lock - lock a rt_mutex - * - * @lock: the rt_mutex to be locked - */ - void __sched rt_mutex_lock(struct rt_mutex *lock) - { -- might_sleep(); -- -- rt_mutex_fastlock(lock, TASK_UNINTERRUPTIBLE, NULL, rt_mutex_slowlock); -+ rt_mutex_lock_state(lock, TASK_UNINTERRUPTIBLE); - } - EXPORT_SYMBOL_GPL(rt_mutex_lock); - - /** - * rt_mutex_lock_interruptible - lock a rt_mutex interruptible -- * -+ ** - * @lock: the rt_mutex to be locked - * - * Returns: -@@ -2042,20 +2053,10 @@ EXPORT_SYMBOL_GPL(rt_mutex_lock); - */ - int __sched rt_mutex_lock_interruptible(struct rt_mutex *lock) - { -- might_sleep(); -- -- return rt_mutex_fastlock(lock, TASK_INTERRUPTIBLE, NULL, rt_mutex_slowlock); -+ return rt_mutex_lock_state(lock, TASK_INTERRUPTIBLE); - } - EXPORT_SYMBOL_GPL(rt_mutex_lock_interruptible); - --/* -- * Futex variant, must not use fastpath. -- */ --int __sched rt_mutex_futex_trylock(struct rt_mutex *lock) --{ -- return rt_mutex_slowtrylock(lock); --} -- - /** - * rt_mutex_lock_killable - lock a rt_mutex killable - * -@@ -2065,16 +2066,21 @@ int __sched rt_mutex_futex_trylock(struc - * Returns: - * 0 on success - * -EINTR when interrupted by a signal -- * -EDEADLK when the lock would deadlock (when deadlock detection is on) - */ - int __sched rt_mutex_lock_killable(struct rt_mutex *lock) - { -- might_sleep(); -- -- return rt_mutex_fastlock(lock, TASK_KILLABLE, NULL, rt_mutex_slowlock); -+ return rt_mutex_lock_state(lock, TASK_KILLABLE); - } - EXPORT_SYMBOL_GPL(rt_mutex_lock_killable); - -+/* -+ * Futex variant, must not use fastpath. -+ */ -+int __sched rt_mutex_futex_trylock(struct rt_mutex *lock) -+{ -+ return rt_mutex_slowtrylock(lock); -+} -+ - /** - * rt_mutex_timed_lock - lock a rt_mutex interruptible - * the timeout structure is provided diff --git a/patches/rtmutex-Provide-locked-slowpath.patch b/patches/rtmutex-Provide-rt_mutex_slowlock_locked.patch index 02c417da3c7f..df98a55a3fdb 100644 --- a/patches/rtmutex-Provide-locked-slowpath.patch +++ b/patches/rtmutex-Provide-rt_mutex_slowlock_locked.patch @@ -1,26 +1,21 @@ From: Thomas Gleixner <tglx@linutronix.de> -Date: Sat, 1 Apr 2017 12:51:01 +0200 -Subject: [PATCH] rtmutex: Provide locked slowpath +Date: Thu, 12 Oct 2017 16:14:22 +0200 +Subject: rtmutex: Provide rt_mutex_slowlock_locked() -The new rt rwsem implementation needs rtmutex::wait_lock to protect struct -rw_semaphore. Dropping the lock and reaquiring it for locking the rtmutex -would open a race window. - -Split out the inner workings of the locked slowpath so it can be called with -wait_lock held. +This is the inner-part of rt_mutex_slowlock(), required for rwsem-rt. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - kernel/locking/rtmutex.c | 72 +++++++++++++++++++++++----------------- - kernel/locking/rtmutex_common.h | 8 ++++ - 2 files changed, 50 insertions(+), 30 deletions(-) + kernel/locking/rtmutex.c | 70 ++++++++++++++++++++++------------------ + kernel/locking/rtmutex_common.h | 6 +++ + 2 files changed, 46 insertions(+), 30 deletions(-) --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c -@@ -1751,30 +1751,13 @@ static void ww_mutex_account_lock(struct +@@ -1256,35 +1256,16 @@ static void rt_mutex_handle_deadlock(int + } } - #endif -/* - * Slow path lock function: @@ -28,19 +23,17 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -static int __sched -rt_mutex_slowlock(struct rt_mutex *lock, int state, - struct hrtimer_sleeper *timeout, -- enum rtmutex_chainwalk chwalk, -- struct ww_acquire_ctx *ww_ctx) +- enum rtmutex_chainwalk chwalk) +int __sched rt_mutex_slowlock_locked(struct rt_mutex *lock, int state, + struct hrtimer_sleeper *timeout, + enum rtmutex_chainwalk chwalk, -+ struct ww_acquire_ctx *ww_ctx, + struct rt_mutex_waiter *waiter) { - struct rt_mutex_waiter waiter; - unsigned long flags; - int ret = 0; - -- rt_mutex_init_waiter(&waiter, false); +- rt_mutex_init_waiter(&waiter); - - /* - * Technically we could use raw_spin_[un]lock_irq() here, but this can @@ -53,17 +46,16 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> - raw_spin_lock_irqsave(&lock->wait_lock, flags); + int ret; - #ifdef CONFIG_PREEMPT_RT_FULL - if (ww_ctx) { -@@ -1790,7 +1773,6 @@ rt_mutex_slowlock(struct rt_mutex *lock, - if (try_to_take_rt_mutex(lock, current, NULL)) { - if (ww_ctx) - ww_mutex_account_lock(lock, ww_ctx); + /* Try to acquire the lock again: */ +- if (try_to_take_rt_mutex(lock, current, NULL)) { - raw_spin_unlock_irqrestore(&lock->wait_lock, flags); ++ if (try_to_take_rt_mutex(lock, current, NULL)) return 0; - } +- } -@@ -1800,13 +1782,13 @@ rt_mutex_slowlock(struct rt_mutex *lock, + set_current_state(state); + +@@ -1292,17 +1273,18 @@ rt_mutex_slowlock(struct rt_mutex *lock, if (unlikely(timeout)) hrtimer_start_expires(&timeout->timer, HRTIMER_MODE_ABS); @@ -73,28 +65,21 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> - if (likely(!ret)) + if (likely(!ret)) { /* sleep on the mutex */ -- ret = __rt_mutex_slowlock(lock, state, timeout, &waiter, -+ ret = __rt_mutex_slowlock(lock, state, timeout, waiter, - ww_ctx); -- else if (ww_ctx) { -+ } else if (ww_ctx) { - /* ww_mutex received EDEADLK, let it become EALREADY */ - ret = __mutex_lock_check_stamp(lock, ww_ctx); - BUG_ON(!ret); -@@ -1815,10 +1797,10 @@ rt_mutex_slowlock(struct rt_mutex *lock, +- ret = __rt_mutex_slowlock(lock, state, timeout, &waiter); ++ ret = __rt_mutex_slowlock(lock, state, timeout, waiter); ++ } + if (unlikely(ret)) { __set_current_state(TASK_RUNNING); if (rt_mutex_has_waiters(lock)) - remove_waiter(lock, &waiter); +- rt_mutex_handle_deadlock(ret, chwalk, &waiter); + remove_waiter(lock, waiter); - /* ww_mutex want to report EDEADLK/EALREADY, let them */ - if (!ww_ctx) -- rt_mutex_handle_deadlock(ret, chwalk, &waiter); -+ rt_mutex_handle_deadlock(ret, chwalk, waiter); - } else if (ww_ctx) { - ww_mutex_account_lock(lock, ww_ctx); ++ /* ww_mutex want to report EDEADLK/EALREADY, let them */ } -@@ -1828,6 +1810,36 @@ rt_mutex_slowlock(struct rt_mutex *lock, + + /* +@@ -1310,6 +1292,34 @@ rt_mutex_slowlock(struct rt_mutex *lock, * unconditionally. We might have to fix that up. */ fixup_rt_mutex_waiters(lock); @@ -107,14 +92,13 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +static int __sched +rt_mutex_slowlock(struct rt_mutex *lock, int state, + struct hrtimer_sleeper *timeout, -+ enum rtmutex_chainwalk chwalk, -+ struct ww_acquire_ctx *ww_ctx) ++ enum rtmutex_chainwalk chwalk) +{ + struct rt_mutex_waiter waiter; + unsigned long flags; + int ret = 0; + -+ rt_mutex_init_waiter(&waiter, false); ++ rt_mutex_init_waiter(&waiter); + + /* + * Technically we could use raw_spin_[un]lock_irq() here, but this can @@ -126,24 +110,21 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + */ + raw_spin_lock_irqsave(&lock->wait_lock, flags); + -+ ret = rt_mutex_slowlock_locked(lock, state, timeout, chwalk, ww_ctx, -+ &waiter); ++ ret = rt_mutex_slowlock_locked(lock, state, timeout, chwalk, &waiter); raw_spin_unlock_irqrestore(&lock->wait_lock, flags); --- a/kernel/locking/rtmutex_common.h +++ b/kernel/locking/rtmutex_common.h -@@ -131,6 +131,14 @@ extern bool __rt_mutex_futex_unlock(stru +@@ -127,6 +127,12 @@ extern bool __rt_mutex_futex_unlock(stru + struct wake_q_head *wqh); - extern void rt_mutex_postunlock(struct wake_q_head *wake_q, - struct wake_q_head *wake_sleeper_q); + extern void rt_mutex_postunlock(struct wake_q_head *wake_q); +/* RW semaphore special interface */ -+struct ww_acquire_ctx; + +int __sched rt_mutex_slowlock_locked(struct rt_mutex *lock, int state, + struct hrtimer_sleeper *timeout, + enum rtmutex_chainwalk chwalk, -+ struct ww_acquire_ctx *ww_ctx, + struct rt_mutex_waiter *waiter); #ifdef CONFIG_DEBUG_RT_MUTEXES diff --git a/patches/rtmutex-add-mutex-implementation-based-on-rtmutex.patch b/patches/rtmutex-add-mutex-implementation-based-on-rtmutex.patch new file mode 100644 index 000000000000..783831268eeb --- /dev/null +++ b/patches/rtmutex-add-mutex-implementation-based-on-rtmutex.patch @@ -0,0 +1,372 @@ +From: Thomas Gleixner <tglx@linutronix.de> +Date: Thu, 12 Oct 2017 17:17:03 +0200 +Subject: rtmutex: add mutex implementation based on rtmutex + +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + include/linux/mutex_rt.h | 130 ++++++++++++++++++++++++++ + kernel/locking/mutex-rt.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 353 insertions(+) + create mode 100644 include/linux/mutex_rt.h + create mode 100644 kernel/locking/mutex-rt.c + +--- /dev/null ++++ b/include/linux/mutex_rt.h +@@ -0,0 +1,130 @@ ++#ifndef __LINUX_MUTEX_RT_H ++#define __LINUX_MUTEX_RT_H ++ ++#ifndef __LINUX_MUTEX_H ++#error "Please include mutex.h" ++#endif ++ ++#include <linux/rtmutex.h> ++ ++/* FIXME: Just for __lockfunc */ ++#include <linux/spinlock.h> ++ ++struct mutex { ++ struct rt_mutex lock; ++#ifdef CONFIG_DEBUG_LOCK_ALLOC ++ struct lockdep_map dep_map; ++#endif ++}; ++ ++#define __MUTEX_INITIALIZER(mutexname) \ ++ { \ ++ .lock = __RT_MUTEX_INITIALIZER(mutexname.lock) \ ++ __DEP_MAP_MUTEX_INITIALIZER(mutexname) \ ++ } ++ ++#define DEFINE_MUTEX(mutexname) \ ++ struct mutex mutexname = __MUTEX_INITIALIZER(mutexname) ++ ++extern void __mutex_do_init(struct mutex *lock, const char *name, struct lock_class_key *key); ++extern void __lockfunc _mutex_lock(struct mutex *lock); ++extern void __lockfunc _mutex_lock_io(struct mutex *lock); ++extern void __lockfunc _mutex_lock_io_nested(struct mutex *lock, int subclass); ++extern int __lockfunc _mutex_lock_interruptible(struct mutex *lock); ++extern int __lockfunc _mutex_lock_killable(struct mutex *lock); ++extern void __lockfunc _mutex_lock_nested(struct mutex *lock, int subclass); ++extern void __lockfunc _mutex_lock_nest_lock(struct mutex *lock, struct lockdep_map *nest_lock); ++extern int __lockfunc _mutex_lock_interruptible_nested(struct mutex *lock, int subclass); ++extern int __lockfunc _mutex_lock_killable_nested(struct mutex *lock, int subclass); ++extern int __lockfunc _mutex_trylock(struct mutex *lock); ++extern void __lockfunc _mutex_unlock(struct mutex *lock); ++ ++#define mutex_is_locked(l) rt_mutex_is_locked(&(l)->lock) ++#define mutex_lock(l) _mutex_lock(l) ++#define mutex_lock_interruptible(l) _mutex_lock_interruptible(l) ++#define mutex_lock_killable(l) _mutex_lock_killable(l) ++#define mutex_trylock(l) _mutex_trylock(l) ++#define mutex_unlock(l) _mutex_unlock(l) ++#define mutex_lock_io(l) _mutex_lock_io(l); ++ ++#define __mutex_owner(l) ((l)->lock.owner) ++ ++#ifdef CONFIG_DEBUG_MUTEXES ++#define mutex_destroy(l) rt_mutex_destroy(&(l)->lock) ++#else ++static inline void mutex_destroy(struct mutex *lock) {} ++#endif ++ ++#ifdef CONFIG_DEBUG_LOCK_ALLOC ++# define mutex_lock_nested(l, s) _mutex_lock_nested(l, s) ++# define mutex_lock_interruptible_nested(l, s) \ ++ _mutex_lock_interruptible_nested(l, s) ++# define mutex_lock_killable_nested(l, s) \ ++ _mutex_lock_killable_nested(l, s) ++# define mutex_lock_io_nested(l, s) _mutex_lock_io_nested(l, s) ++ ++# define mutex_lock_nest_lock(lock, nest_lock) \ ++do { \ ++ typecheck(struct lockdep_map *, &(nest_lock)->dep_map); \ ++ _mutex_lock_nest_lock(lock, &(nest_lock)->dep_map); \ ++} while (0) ++ ++#else ++# define mutex_lock_nested(l, s) _mutex_lock(l) ++# define mutex_lock_interruptible_nested(l, s) \ ++ _mutex_lock_interruptible(l) ++# define mutex_lock_killable_nested(l, s) \ ++ _mutex_lock_killable(l) ++# define mutex_lock_nest_lock(lock, nest_lock) mutex_lock(lock) ++# define mutex_lock_io_nested(l, s) _mutex_lock_io(l) ++#endif ++ ++# define mutex_init(mutex) \ ++do { \ ++ static struct lock_class_key __key; \ ++ \ ++ rt_mutex_init(&(mutex)->lock); \ ++ __mutex_do_init((mutex), #mutex, &__key); \ ++} while (0) ++ ++# define __mutex_init(mutex, name, key) \ ++do { \ ++ rt_mutex_init(&(mutex)->lock); \ ++ __mutex_do_init((mutex), name, key); \ ++} while (0) ++ ++/** ++ * These values are chosen such that FAIL and SUCCESS match the ++ * values of the regular mutex_trylock(). ++ */ ++enum mutex_trylock_recursive_enum { ++ MUTEX_TRYLOCK_FAILED = 0, ++ MUTEX_TRYLOCK_SUCCESS = 1, ++ MUTEX_TRYLOCK_RECURSIVE, ++}; ++/** ++ * mutex_trylock_recursive - trylock variant that allows recursive locking ++ * @lock: mutex to be locked ++ * ++ * This function should not be used, _ever_. It is purely for hysterical GEM ++ * raisins, and once those are gone this will be removed. ++ * ++ * Returns: ++ * MUTEX_TRYLOCK_FAILED - trylock failed, ++ * MUTEX_TRYLOCK_SUCCESS - lock acquired, ++ * MUTEX_TRYLOCK_RECURSIVE - we already owned the lock. ++ */ ++int __rt_mutex_owner_current(struct rt_mutex *lock); ++ ++static inline /* __deprecated */ __must_check enum mutex_trylock_recursive_enum ++mutex_trylock_recursive(struct mutex *lock) ++{ ++ if (unlikely(__rt_mutex_owner_current(&lock->lock))) ++ return MUTEX_TRYLOCK_RECURSIVE; ++ ++ return mutex_trylock(lock); ++} ++ ++extern int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock); ++ ++#endif +--- /dev/null ++++ b/kernel/locking/mutex-rt.c +@@ -0,0 +1,223 @@ ++/* ++ * kernel/rt.c ++ * ++ * Real-Time Preemption Support ++ * ++ * started by Ingo Molnar: ++ * ++ * Copyright (C) 2004-2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> ++ * Copyright (C) 2006, Timesys Corp., Thomas Gleixner <tglx@timesys.com> ++ * ++ * historic credit for proving that Linux spinlocks can be implemented via ++ * RT-aware mutexes goes to many people: The Pmutex project (Dirk Grambow ++ * and others) who prototyped it on 2.4 and did lots of comparative ++ * research and analysis; TimeSys, for proving that you can implement a ++ * fully preemptible kernel via the use of IRQ threading and mutexes; ++ * Bill Huey for persuasively arguing on lkml that the mutex model is the ++ * right one; and to MontaVista, who ported pmutexes to 2.6. ++ * ++ * This code is a from-scratch implementation and is not based on pmutexes, ++ * but the idea of converting spinlocks to mutexes is used here too. ++ * ++ * lock debugging, locking tree, deadlock detection: ++ * ++ * Copyright (C) 2004, LynuxWorks, Inc., Igor Manyilov, Bill Huey ++ * Released under the General Public License (GPL). ++ * ++ * Includes portions of the generic R/W semaphore implementation from: ++ * ++ * Copyright (c) 2001 David Howells (dhowells@redhat.com). ++ * - Derived partially from idea by Andrea Arcangeli <andrea@suse.de> ++ * - Derived also from comments by Linus ++ * ++ * Pending ownership of locks and ownership stealing: ++ * ++ * Copyright (C) 2005, Kihon Technologies Inc., Steven Rostedt ++ * ++ * (also by Steven Rostedt) ++ * - Converted single pi_lock to individual task locks. ++ * ++ * By Esben Nielsen: ++ * Doing priority inheritance with help of the scheduler. ++ * ++ * Copyright (C) 2006, Timesys Corp., Thomas Gleixner <tglx@timesys.com> ++ * - major rework based on Esben Nielsens initial patch ++ * - replaced thread_info references by task_struct refs ++ * - removed task->pending_owner dependency ++ * - BKL drop/reacquire for semaphore style locks to avoid deadlocks ++ * in the scheduler return path as discussed with Steven Rostedt ++ * ++ * Copyright (C) 2006, Kihon Technologies Inc. ++ * Steven Rostedt <rostedt@goodmis.org> ++ * - debugged and patched Thomas Gleixner's rework. ++ * - added back the cmpxchg to the rework. ++ * - turned atomic require back on for SMP. ++ */ ++ ++#include <linux/spinlock.h> ++#include <linux/rtmutex.h> ++#include <linux/sched.h> ++#include <linux/delay.h> ++#include <linux/module.h> ++#include <linux/kallsyms.h> ++#include <linux/syscalls.h> ++#include <linux/interrupt.h> ++#include <linux/plist.h> ++#include <linux/fs.h> ++#include <linux/futex.h> ++#include <linux/hrtimer.h> ++ ++#include "rtmutex_common.h" ++ ++/* ++ * struct mutex functions ++ */ ++void __mutex_do_init(struct mutex *mutex, const char *name, ++ struct lock_class_key *key) ++{ ++#ifdef CONFIG_DEBUG_LOCK_ALLOC ++ /* ++ * Make sure we are not reinitializing a held lock: ++ */ ++ debug_check_no_locks_freed((void *)mutex, sizeof(*mutex)); ++ lockdep_init_map(&mutex->dep_map, name, key, 0); ++#endif ++ mutex->lock.save_state = 0; ++} ++EXPORT_SYMBOL(__mutex_do_init); ++ ++void __lockfunc _mutex_lock(struct mutex *lock) ++{ ++ mutex_acquire(&lock->dep_map, 0, 0, _RET_IP_); ++ __rt_mutex_lock_state(&lock->lock, TASK_UNINTERRUPTIBLE); ++} ++EXPORT_SYMBOL(_mutex_lock); ++ ++void __lockfunc _mutex_lock_io(struct mutex *lock) ++{ ++ int token; ++ ++ token = io_schedule_prepare(); ++ _mutex_lock(lock); ++ io_schedule_finish(token); ++} ++EXPORT_SYMBOL_GPL(_mutex_lock_io); ++ ++int __lockfunc _mutex_lock_interruptible(struct mutex *lock) ++{ ++ int ret; ++ ++ mutex_acquire(&lock->dep_map, 0, 0, _RET_IP_); ++ ret = __rt_mutex_lock_state(&lock->lock, TASK_INTERRUPTIBLE); ++ if (ret) ++ mutex_release(&lock->dep_map, 1, _RET_IP_); ++ return ret; ++} ++EXPORT_SYMBOL(_mutex_lock_interruptible); ++ ++int __lockfunc _mutex_lock_killable(struct mutex *lock) ++{ ++ int ret; ++ ++ mutex_acquire(&lock->dep_map, 0, 0, _RET_IP_); ++ ret = __rt_mutex_lock_state(&lock->lock, TASK_KILLABLE); ++ if (ret) ++ mutex_release(&lock->dep_map, 1, _RET_IP_); ++ return ret; ++} ++EXPORT_SYMBOL(_mutex_lock_killable); ++ ++#ifdef CONFIG_DEBUG_LOCK_ALLOC ++void __lockfunc _mutex_lock_nested(struct mutex *lock, int subclass) ++{ ++ mutex_acquire_nest(&lock->dep_map, subclass, 0, NULL, _RET_IP_); ++ __rt_mutex_lock_state(&lock->lock, TASK_UNINTERRUPTIBLE); ++} ++EXPORT_SYMBOL(_mutex_lock_nested); ++ ++void __lockfunc _mutex_lock_io_nested(struct mutex *lock, int subclass) ++{ ++ int token; ++ ++ token = io_schedule_prepare(); ++ ++ mutex_acquire_nest(&lock->dep_map, subclass, 0, NULL, _RET_IP_); ++ __rt_mutex_lock_state(&lock->lock, TASK_UNINTERRUPTIBLE); ++ ++ io_schedule_finish(token); ++} ++EXPORT_SYMBOL_GPL(_mutex_lock_io_nested); ++ ++void __lockfunc _mutex_lock_nest_lock(struct mutex *lock, struct lockdep_map *nest) ++{ ++ mutex_acquire_nest(&lock->dep_map, 0, 0, nest, _RET_IP_); ++ __rt_mutex_lock_state(&lock->lock, TASK_UNINTERRUPTIBLE); ++} ++EXPORT_SYMBOL(_mutex_lock_nest_lock); ++ ++int __lockfunc _mutex_lock_interruptible_nested(struct mutex *lock, int subclass) ++{ ++ int ret; ++ ++ mutex_acquire_nest(&lock->dep_map, subclass, 0, NULL, _RET_IP_); ++ ret = __rt_mutex_lock_state(&lock->lock, TASK_INTERRUPTIBLE); ++ if (ret) ++ mutex_release(&lock->dep_map, 1, _RET_IP_); ++ return ret; ++} ++EXPORT_SYMBOL(_mutex_lock_interruptible_nested); ++ ++int __lockfunc _mutex_lock_killable_nested(struct mutex *lock, int subclass) ++{ ++ int ret; ++ ++ mutex_acquire(&lock->dep_map, subclass, 0, _RET_IP_); ++ ret = __rt_mutex_lock_state(&lock->lock, TASK_KILLABLE); ++ if (ret) ++ mutex_release(&lock->dep_map, 1, _RET_IP_); ++ return ret; ++} ++EXPORT_SYMBOL(_mutex_lock_killable_nested); ++#endif ++ ++int __lockfunc _mutex_trylock(struct mutex *lock) ++{ ++ int ret = __rt_mutex_trylock(&lock->lock); ++ ++ if (ret) ++ mutex_acquire(&lock->dep_map, 0, 1, _RET_IP_); ++ ++ return ret; ++} ++EXPORT_SYMBOL(_mutex_trylock); ++ ++void __lockfunc _mutex_unlock(struct mutex *lock) ++{ ++ mutex_release(&lock->dep_map, 1, _RET_IP_); ++ __rt_mutex_unlock(&lock->lock); ++} ++EXPORT_SYMBOL(_mutex_unlock); ++ ++/** ++ * atomic_dec_and_mutex_lock - return holding mutex if we dec to 0 ++ * @cnt: the atomic which we are to dec ++ * @lock: the mutex to return holding if we dec to 0 ++ * ++ * return true and hold lock if we dec to 0, return false otherwise ++ */ ++int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock) ++{ ++ /* dec if we can't possibly hit 0 */ ++ if (atomic_add_unless(cnt, -1, 1)) ++ return 0; ++ /* we might hit 0, so take the lock */ ++ mutex_lock(lock); ++ if (!atomic_dec_and_test(cnt)) { ++ /* when we actually did the dec, we didn't hit 0 */ ++ mutex_unlock(lock); ++ return 0; ++ } ++ /* we hit 0, and we hold the lock */ ++ return 1; ++} ++EXPORT_SYMBOL(atomic_dec_and_mutex_lock); diff --git a/patches/locking-rt-rwlock--Provide-reader-biased-rwlock-for-RT.patch b/patches/rtmutex-add-rwlock-implementation-based-on-rtmutex.patch index 93baeaca73c9..35ac0af12a2a 100644 --- a/patches/locking-rt-rwlock--Provide-reader-biased-rwlock-for-RT.patch +++ b/patches/rtmutex-add-rwlock-implementation-based-on-rtmutex.patch @@ -1,21 +1,131 @@ -Subject: locking/rt/rwlock: Provide reader biased rwlock for RT From: Thomas Gleixner <tglx@linutronix.de> -Date: Wed, 12 Jul 2017 09:50:11 +0200 +Date: Thu, 12 Oct 2017 17:18:06 +0200 +Subject: rtmutex: add rwlock implementation based on rtmutex + +The implementation is bias-based, similar to the rwsem implementation. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - include/linux/rwlock_rt.h | 10 + - include/linux/rwlock_types_rt.h | 42 ++++++ - kernel/locking/Makefile | 2 - kernel/locking/rwlock-rt.c | 246 ++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 299 insertions(+), 1 deletion(-) + include/linux/rwlock_rt.h | 119 ++++++++++++ + include/linux/rwlock_types_rt.h | 55 +++++ + kernel/locking/rwlock-rt.c | 368 ++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 542 insertions(+) + create mode 100644 include/linux/rwlock_rt.h + create mode 100644 include/linux/rwlock_types_rt.h + create mode 100644 kernel/locking/rwlock-rt.c ---- a/include/linux/rwlock_rt.h +--- /dev/null +++ b/include/linux/rwlock_rt.h -@@ -101,4 +101,14 @@ static inline int __write_trylock_rt_irq - rt_write_unlock(lock); \ - } while (0) - +@@ -0,0 +1,119 @@ ++#ifndef __LINUX_RWLOCK_RT_H ++#define __LINUX_RWLOCK_RT_H ++ ++#ifndef __LINUX_SPINLOCK_H ++#error Do not include directly. Use spinlock.h ++#endif ++ ++extern void __lockfunc rt_write_lock(rwlock_t *rwlock); ++extern void __lockfunc rt_read_lock(rwlock_t *rwlock); ++extern int __lockfunc rt_write_trylock(rwlock_t *rwlock); ++extern int __lockfunc rt_read_trylock(rwlock_t *rwlock); ++extern void __lockfunc rt_write_unlock(rwlock_t *rwlock); ++extern void __lockfunc rt_read_unlock(rwlock_t *rwlock); ++extern int __lockfunc rt_read_can_lock(rwlock_t *rwlock); ++extern int __lockfunc rt_write_can_lock(rwlock_t *rwlock); ++extern void __rt_rwlock_init(rwlock_t *rwlock, char *name, struct lock_class_key *key); ++ ++#define read_can_lock(rwlock) rt_read_can_lock(rwlock) ++#define write_can_lock(rwlock) rt_write_can_lock(rwlock) ++ ++#define read_trylock(lock) __cond_lock(lock, rt_read_trylock(lock)) ++#define write_trylock(lock) __cond_lock(lock, rt_write_trylock(lock)) ++ ++static inline int __write_trylock_rt_irqsave(rwlock_t *lock, unsigned long *flags) ++{ ++ /* XXX ARCH_IRQ_ENABLED */ ++ *flags = 0; ++ return rt_write_trylock(lock); ++} ++ ++#define write_trylock_irqsave(lock, flags) \ ++ __cond_lock(lock, __write_trylock_rt_irqsave(lock, &(flags))) ++ ++#define read_lock_irqsave(lock, flags) \ ++ do { \ ++ typecheck(unsigned long, flags); \ ++ rt_read_lock(lock); \ ++ flags = 0; \ ++ } while (0) ++ ++#define write_lock_irqsave(lock, flags) \ ++ do { \ ++ typecheck(unsigned long, flags); \ ++ rt_write_lock(lock); \ ++ flags = 0; \ ++ } while (0) ++ ++#define read_lock(lock) rt_read_lock(lock) ++ ++#define read_lock_bh(lock) \ ++ do { \ ++ local_bh_disable(); \ ++ rt_read_lock(lock); \ ++ } while (0) ++ ++#define read_lock_irq(lock) read_lock(lock) ++ ++#define write_lock(lock) rt_write_lock(lock) ++ ++#define write_lock_bh(lock) \ ++ do { \ ++ local_bh_disable(); \ ++ rt_write_lock(lock); \ ++ } while (0) ++ ++#define write_lock_irq(lock) write_lock(lock) ++ ++#define read_unlock(lock) rt_read_unlock(lock) ++ ++#define read_unlock_bh(lock) \ ++ do { \ ++ rt_read_unlock(lock); \ ++ local_bh_enable(); \ ++ } while (0) ++ ++#define read_unlock_irq(lock) read_unlock(lock) ++ ++#define write_unlock(lock) rt_write_unlock(lock) ++ ++#define write_unlock_bh(lock) \ ++ do { \ ++ rt_write_unlock(lock); \ ++ local_bh_enable(); \ ++ } while (0) ++ ++#define write_unlock_irq(lock) write_unlock(lock) ++ ++#define read_unlock_irqrestore(lock, flags) \ ++ do { \ ++ typecheck(unsigned long, flags); \ ++ (void) flags; \ ++ rt_read_unlock(lock); \ ++ } while (0) ++ ++#define write_unlock_irqrestore(lock, flags) \ ++ do { \ ++ typecheck(unsigned long, flags); \ ++ (void) flags; \ ++ rt_write_unlock(lock); \ ++ } while (0) ++ ++#define rwlock_init(rwl) \ ++do { \ ++ static struct lock_class_key __key; \ ++ \ ++ __rt_rwlock_init(rwl, #rwl, &__key); \ ++} while (0) ++ +/* + * Internal functions made global for CPU pinning + */ @@ -26,15 +136,29 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +void __read_rt_unlock(struct rt_rw_lock *lock); +void __write_rt_unlock(struct rt_rw_lock *lock); + - #endif ---- a/include/linux/rwlock_types_rt.h ++#endif +--- /dev/null +++ b/include/linux/rwlock_types_rt.h -@@ -29,4 +29,46 @@ typedef struct { - #define DEFINE_RWLOCK(name) \ - rwlock_t name = __RW_LOCK_UNLOCKED(name) - -+#define READER_BIAS (1U << 31) -+#define WRITER_BIAS (1U << 30) +@@ -0,0 +1,55 @@ ++#ifndef __LINUX_RWLOCK_TYPES_RT_H ++#define __LINUX_RWLOCK_TYPES_RT_H ++ ++#ifndef __LINUX_SPINLOCK_TYPES_H ++#error "Do not include directly. Include spinlock_types.h instead" ++#endif ++ ++#ifdef CONFIG_DEBUG_LOCK_ALLOC ++# define RW_DEP_MAP_INIT(lockname) .dep_map = { .name = #lockname } ++#else ++# define RW_DEP_MAP_INIT(lockname) ++#endif ++ ++typedef struct rt_rw_lock rwlock_t; ++ ++#define __RW_LOCK_UNLOCKED(name) __RWLOCK_RT_INITIALIZER(name) ++ ++#define DEFINE_RWLOCK(name) \ ++ rwlock_t name = __RW_LOCK_UNLOCKED(name) + +/* + * A reader biased implementation primarily for CPU pinning. @@ -50,6 +174,9 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +#endif +}; + ++#define READER_BIAS (1U << 31) ++#define WRITER_BIAS (1U << 30) ++ +#define __RWLOCK_RT_INITIALIZER(name) \ +{ \ + .readers = ATOMIC_INIT(READER_BIAS), \ @@ -67,29 +194,10 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + __rwlock_biased_rt_init((rwlock), #rwlock, &__key); \ + } while (0) + -+int __read_rt_trylock(struct rt_rw_lock *rwlock); -+void __read_rt_lock(struct rt_rw_lock *rwlock); -+void __read_rt_unlock(struct rt_rw_lock *rwlock); -+ -+void __write_rt_lock(struct rt_rw_lock *rwlock); -+int __write_rt_trylock(struct rt_rw_lock *rwlock); -+void __write_rt_unlock(struct rt_rw_lock *rwlock); -+ - #endif ---- a/kernel/locking/Makefile -+++ b/kernel/locking/Makefile -@@ -32,7 +32,7 @@ ifneq ($(CONFIG_PREEMPT_RT_FULL),y) - obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o - obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem-xadd.o - endif --obj-$(CONFIG_PREEMPT_RT_FULL) += rt.o rwsem-rt.o -+obj-$(CONFIG_PREEMPT_RT_FULL) += rt.o rwsem-rt.o rwlock-rt.o - obj-$(CONFIG_QUEUED_RWLOCKS) += qrwlock.o - obj-$(CONFIG_LOCK_TORTURE_TEST) += locktorture.o - obj-$(CONFIG_WW_MUTEX_SELFTEST) += test-ww_mutex.o ++#endif --- /dev/null +++ b/kernel/locking/rwlock-rt.c -@@ -0,0 +1,246 @@ +@@ -0,0 +1,368 @@ +/* + */ +#include <linux/sched/debug.h> @@ -282,14 +390,14 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + /* Force readers into slow path */ + atomic_sub(READER_BIAS, &lock->readers); + -+ for (;;) { -+ raw_spin_lock_irqsave(&m->wait_lock, flags); ++ raw_spin_lock_irqsave(&m->wait_lock, flags); + -+ raw_spin_lock(&self->pi_lock); -+ self->saved_state = self->state; -+ __set_current_state_no_track(TASK_UNINTERRUPTIBLE); -+ raw_spin_unlock(&self->pi_lock); ++ raw_spin_lock(&self->pi_lock); ++ self->saved_state = self->state; ++ __set_current_state_no_track(TASK_UNINTERRUPTIBLE); ++ raw_spin_unlock(&self->pi_lock); + ++ for (;;) { + /* Have all readers left the critical region? */ + if (!atomic_read(&lock->readers)) { + atomic_set(&lock->readers, WRITER_BIAS); @@ -305,6 +413,12 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + + if (atomic_read(&lock->readers) != 0) + schedule(); ++ ++ raw_spin_lock_irqsave(&m->wait_lock, flags); ++ ++ raw_spin_lock(&self->pi_lock); ++ __set_current_state_no_track(TASK_UNINTERRUPTIBLE); ++ raw_spin_unlock(&self->pi_lock); + } +} + @@ -313,7 +427,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + struct rt_mutex *m = &lock->rtmutex; + unsigned long flags; + -+ if (!rt_mutex_trylock(m)) ++ if (!__rt_mutex_trylock(m)) + return 0; + + atomic_sub(READER_BIAS, &lock->readers); @@ -336,3 +450,119 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + raw_spin_lock_irqsave(&m->wait_lock, flags); + __write_unlock_common(lock, WRITER_BIAS, flags); +} ++ ++/* Map the reader biased implementation */ ++static inline int do_read_rt_trylock(rwlock_t *rwlock) ++{ ++ return __read_rt_trylock(rwlock); ++} ++ ++static inline int do_write_rt_trylock(rwlock_t *rwlock) ++{ ++ return __write_rt_trylock(rwlock); ++} ++ ++static inline void do_read_rt_lock(rwlock_t *rwlock) ++{ ++ __read_rt_lock(rwlock); ++} ++ ++static inline void do_write_rt_lock(rwlock_t *rwlock) ++{ ++ __write_rt_lock(rwlock); ++} ++ ++static inline void do_read_rt_unlock(rwlock_t *rwlock) ++{ ++ __read_rt_unlock(rwlock); ++} ++ ++static inline void do_write_rt_unlock(rwlock_t *rwlock) ++{ ++ __write_rt_unlock(rwlock); ++} ++ ++static inline void do_rwlock_rt_init(rwlock_t *rwlock, const char *name, ++ struct lock_class_key *key) ++{ ++ __rwlock_biased_rt_init(rwlock, name, key); ++} ++ ++int __lockfunc rt_read_can_lock(rwlock_t *rwlock) ++{ ++ return atomic_read(&rwlock->readers) < 0; ++} ++ ++int __lockfunc rt_write_can_lock(rwlock_t *rwlock) ++{ ++ return atomic_read(&rwlock->readers) == READER_BIAS; ++} ++ ++/* ++ * The common functions which get wrapped into the rwlock API. ++ */ ++int __lockfunc rt_read_trylock(rwlock_t *rwlock) ++{ ++ int ret; ++ ++ migrate_disable(); ++ ret = do_read_rt_trylock(rwlock); ++ if (ret) ++ rwlock_acquire_read(&rwlock->dep_map, 0, 1, _RET_IP_); ++ else ++ migrate_enable(); ++ return ret; ++} ++EXPORT_SYMBOL(rt_read_trylock); ++ ++int __lockfunc rt_write_trylock(rwlock_t *rwlock) ++{ ++ int ret; ++ ++ migrate_disable(); ++ ret = do_write_rt_trylock(rwlock); ++ if (ret) ++ rwlock_acquire(&rwlock->dep_map, 0, 1, _RET_IP_); ++ else ++ migrate_enable(); ++ return ret; ++} ++EXPORT_SYMBOL(rt_write_trylock); ++ ++void __lockfunc rt_read_lock(rwlock_t *rwlock) ++{ ++ migrate_disable(); ++ rwlock_acquire_read(&rwlock->dep_map, 0, 0, _RET_IP_); ++ do_read_rt_lock(rwlock); ++} ++EXPORT_SYMBOL(rt_read_lock); ++ ++void __lockfunc rt_write_lock(rwlock_t *rwlock) ++{ ++ migrate_disable(); ++ rwlock_acquire(&rwlock->dep_map, 0, 0, _RET_IP_); ++ do_write_rt_lock(rwlock); ++} ++EXPORT_SYMBOL(rt_write_lock); ++ ++void __lockfunc rt_read_unlock(rwlock_t *rwlock) ++{ ++ rwlock_release(&rwlock->dep_map, 1, _RET_IP_); ++ do_read_rt_unlock(rwlock); ++ migrate_enable(); ++} ++EXPORT_SYMBOL(rt_read_unlock); ++ ++void __lockfunc rt_write_unlock(rwlock_t *rwlock) ++{ ++ rwlock_release(&rwlock->dep_map, 1, _RET_IP_); ++ do_write_rt_unlock(rwlock); ++ migrate_enable(); ++} ++EXPORT_SYMBOL(rt_write_unlock); ++ ++void __rt_rwlock_init(rwlock_t *rwlock, char *name, struct lock_class_key *key) ++{ ++ do_rwlock_rt_init(rwlock, name, key); ++} ++EXPORT_SYMBOL(__rt_rwlock_init); diff --git a/patches/rwsem-rt-Lift-single-reader-restriction.patch b/patches/rtmutex-add-rwsem-implementation-based-on-rtmutex.patch index df0e1452a372..39f2284f8017 100644 --- a/patches/rwsem-rt-Lift-single-reader-restriction.patch +++ b/patches/rtmutex-add-rwsem-implementation-based-on-rtmutex.patch @@ -1,6 +1,6 @@ From: Thomas Gleixner <tglx@linutronix.de> -Date: Sat, 1 Apr 2017 12:51:02 +0200 -Subject: [PATCH] rwsem/rt: Lift single reader restriction +Date: Thu, 12 Oct 2017 17:28:34 +0200 +Subject: rtmutex: add rwsem implementation based on rtmutex The RT specific R/W semaphore implementation restricts the number of readers to one because a writer cannot block on multiple readers and inherit its @@ -41,220 +41,72 @@ the approach. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - include/linux/rwsem.h | 9 + - include/linux/rwsem_rt.h | 166 +++++----------------------- - kernel/locking/Makefile | 4 - kernel/locking/rt.c | 167 ---------------------------- + include/linux/rwsem_rt.h | 67 +++++++++++ kernel/locking/rwsem-rt.c | 269 ++++++++++++++++++++++++++++++++++++++++++++++ - 5 files changed, 311 insertions(+), 304 deletions(-) + 2 files changed, 336 insertions(+) + create mode 100644 include/linux/rwsem_rt.h create mode 100644 kernel/locking/rwsem-rt.c ---- a/include/linux/rwsem.h -+++ b/include/linux/rwsem.h -@@ -110,6 +110,13 @@ static inline int rwsem_is_contended(str - return !list_empty(&sem->wait_list); - } - -+#endif /* !PREEMPT_RT_FULL */ +--- /dev/null ++++ b/include/linux/rwsem_rt.h +@@ -0,0 +1,67 @@ ++#ifndef _LINUX_RWSEM_RT_H ++#define _LINUX_RWSEM_RT_H + -+/* -+ * The functions below are the same for all rwsem implementations including -+ * the RT specific variant. -+ */ ++#ifndef _LINUX_RWSEM_H ++#error "Include rwsem.h" ++#endif + - /* - * lock for reading - */ -@@ -188,6 +195,4 @@ extern void up_read_non_owner(struct rw_ - # define up_read_non_owner(sem) up_read(sem) - #endif - --#endif /* !PREEMPT_RT_FULL */ -- - #endif /* _LINUX_RWSEM_H */ ---- a/include/linux/rwsem_rt.h -+++ b/include/linux/rwsem_rt.h -@@ -5,163 +5,63 @@ - #error "Include rwsem.h" - #endif - --/* -- * RW-semaphores are a spinlock plus a reader-depth count. -- * -- * Note that the semantics are different from the usual -- * Linux rw-sems, in PREEMPT_RT mode we do not allow -- * multiple readers to hold the lock at once, we only allow -- * a read-lock owner to read-lock recursively. This is -- * better for latency, makes the implementation inherently -- * fair and makes it simpler as well. -- */ -- - #include <linux/rtmutex.h> ++#include <linux/rtmutex.h> +#include <linux/swait.h> + +#define READER_BIAS (1U << 31) +#define WRITER_BIAS (1U << 30) - - struct rw_semaphore { -- struct rt_mutex lock; -- int read_depth; ++ ++struct rw_semaphore { + atomic_t readers; + struct rt_mutex rtmutex; - #ifdef CONFIG_DEBUG_LOCK_ALLOC - struct lockdep_map dep_map; - #endif - }; - --#define __RWSEM_INITIALIZER(name) \ -- { .lock = __RT_MUTEX_INITIALIZER(name.lock), \ -- RW_DEP_MAP_INIT(name) } ++#ifdef CONFIG_DEBUG_LOCK_ALLOC ++ struct lockdep_map dep_map; ++#endif ++}; ++ +#define __RWSEM_INITIALIZER(name) \ +{ \ + .readers = ATOMIC_INIT(READER_BIAS), \ + .rtmutex = __RT_MUTEX_INITIALIZER(name.rtmutex), \ + RW_DEP_MAP_INIT(name) \ +} - - #define DECLARE_RWSEM(lockname) \ - struct rw_semaphore lockname = __RWSEM_INITIALIZER(lockname) - --extern void __rt_rwsem_init(struct rw_semaphore *rwsem, const char *name, -- struct lock_class_key *key); -- --#define __rt_init_rwsem(sem, name, key) \ -- do { \ -- rt_mutex_init(&(sem)->lock); \ -- __rt_rwsem_init((sem), (name), (key));\ -- } while (0) ++ ++#define DECLARE_RWSEM(lockname) \ ++ struct rw_semaphore lockname = __RWSEM_INITIALIZER(lockname) ++ +extern void __rwsem_init(struct rw_semaphore *rwsem, const char *name, + struct lock_class_key *key); - --#define __init_rwsem(sem, name, key) __rt_init_rwsem(sem, name, key) ++ +#define __init_rwsem(sem, name, key) \ +do { \ + rt_mutex_init(&(sem)->rtmutex); \ + __rwsem_init((sem), (name), (key)); \ +} while (0) - --# define rt_init_rwsem(sem) \ ++ +#define init_rwsem(sem) \ - do { \ - static struct lock_class_key __key; \ - \ -- __rt_init_rwsem((sem), #sem, &__key); \ ++do { \ ++ static struct lock_class_key __key; \ ++ \ + __init_rwsem((sem), #sem, &__key); \ - } while (0) - --extern void rt_down_write(struct rw_semaphore *rwsem); --extern int rt_down_write_killable(struct rw_semaphore *rwsem); --extern void rt_down_read_nested(struct rw_semaphore *rwsem, int subclass); --extern void rt_down_write_nested(struct rw_semaphore *rwsem, int subclass); --extern int rt_down_write_killable_nested(struct rw_semaphore *rwsem, -- int subclass); --extern void rt_down_write_nested_lock(struct rw_semaphore *rwsem, -- struct lockdep_map *nest); --extern void rt__down_read(struct rw_semaphore *rwsem); --extern void rt_down_read(struct rw_semaphore *rwsem); --extern int rt_down_write_trylock(struct rw_semaphore *rwsem); --extern int rt__down_read_trylock(struct rw_semaphore *rwsem); --extern int rt_down_read_trylock(struct rw_semaphore *rwsem); --extern void __rt_up_read(struct rw_semaphore *rwsem); --extern void rt_up_read(struct rw_semaphore *rwsem); --extern void rt_up_write(struct rw_semaphore *rwsem); --extern void rt_downgrade_write(struct rw_semaphore *rwsem); -- --#define init_rwsem(sem) rt_init_rwsem(sem) --#define rwsem_is_locked(s) rt_mutex_is_locked(&(s)->lock) -- --static inline int rwsem_is_contended(struct rw_semaphore *sem) --{ -- /* rt_mutex_has_waiters() */ -- return !RB_EMPTY_ROOT(&sem->lock.waiters); --} -- --static inline void __down_read(struct rw_semaphore *sem) --{ -- rt__down_read(sem); --} -- --static inline void down_read(struct rw_semaphore *sem) --{ -- rt_down_read(sem); --} -- --static inline int __down_read_trylock(struct rw_semaphore *sem) --{ -- return rt__down_read_trylock(sem); --} -- --static inline int down_read_trylock(struct rw_semaphore *sem) --{ -- return rt_down_read_trylock(sem); --} -- --static inline void down_write(struct rw_semaphore *sem) --{ -- rt_down_write(sem); --} -- --static inline int down_write_killable(struct rw_semaphore *sem) --{ -- return rt_down_write_killable(sem); --} -- --static inline int down_write_trylock(struct rw_semaphore *sem) --{ -- return rt_down_write_trylock(sem); --} -- --static inline void __up_read(struct rw_semaphore *sem) --{ -- __rt_up_read(sem); --} -- --static inline void up_read(struct rw_semaphore *sem) --{ -- rt_up_read(sem); --} -- --static inline void up_write(struct rw_semaphore *sem) --{ -- rt_up_write(sem); --} -- --static inline void downgrade_write(struct rw_semaphore *sem) ++} while (0) ++ +static inline int rwsem_is_locked(struct rw_semaphore *sem) - { -- rt_downgrade_write(sem); ++{ + return atomic_read(&sem->readers) != READER_BIAS; - } - --static inline void down_read_nested(struct rw_semaphore *sem, int subclass) --{ -- return rt_down_read_nested(sem, subclass); --} -- --static inline void down_write_nested(struct rw_semaphore *sem, int subclass) --{ -- rt_down_write_nested(sem, subclass); --} -- --static inline int down_write_killable_nested(struct rw_semaphore *sem, -- int subclass) --{ -- return rt_down_write_killable_nested(sem, subclass); --} -- --#ifdef CONFIG_DEBUG_LOCK_ALLOC --static inline void down_write_nest_lock(struct rw_semaphore *sem, -- struct rw_semaphore *nest_lock) ++} ++ +static inline int rwsem_is_contended(struct rw_semaphore *sem) - { -- rt_down_write_nested_lock(sem, &nest_lock->dep_map); ++{ + return atomic_read(&sem->readers) > 0; - } - --#else ++} ++ +extern void __down_read(struct rw_semaphore *sem); +extern int __down_read_trylock(struct rw_semaphore *sem); +extern void __down_write(struct rw_semaphore *sem); @@ -263,211 +115,8 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +extern void __up_read(struct rw_semaphore *sem); +extern void __up_write(struct rw_semaphore *sem); +extern void __downgrade_write(struct rw_semaphore *sem); - --static inline void down_write_nest_lock(struct rw_semaphore *sem, -- struct rw_semaphore *nest_lock) --{ -- rt_down_write_nested_lock(sem, NULL); --} --#endif - #endif ---- a/kernel/locking/Makefile -+++ b/kernel/locking/Makefile -@@ -14,8 +14,8 @@ endif - ifneq ($(CONFIG_PREEMPT_RT_FULL),y) - obj-y += mutex.o - obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o --obj-y += rwsem.o - endif -+obj-y += rwsem.o - obj-$(CONFIG_LOCKDEP) += lockdep.o - ifeq ($(CONFIG_PROC_FS),y) - obj-$(CONFIG_LOCKDEP) += lockdep_proc.o -@@ -32,7 +32,7 @@ ifneq ($(CONFIG_PREEMPT_RT_FULL),y) - obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o - obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem-xadd.o - endif --obj-$(CONFIG_PREEMPT_RT_FULL) += rt.o -+obj-$(CONFIG_PREEMPT_RT_FULL) += rt.o rwsem-rt.o - obj-$(CONFIG_QUEUED_RWLOCKS) += qrwlock.o - obj-$(CONFIG_LOCK_TORTURE_TEST) += locktorture.o - obj-$(CONFIG_WW_MUTEX_SELFTEST) += test-ww_mutex.o ---- a/kernel/locking/rt.c -+++ b/kernel/locking/rt.c -@@ -329,173 +329,6 @@ void __rt_rwlock_init(rwlock_t *rwlock, - } - EXPORT_SYMBOL(__rt_rwlock_init); - --/* -- * rw_semaphores -- */ -- --void rt_up_write(struct rw_semaphore *rwsem) --{ -- rwsem_release(&rwsem->dep_map, 1, _RET_IP_); -- rt_mutex_unlock(&rwsem->lock); --} --EXPORT_SYMBOL(rt_up_write); -- --void __rt_up_read(struct rw_semaphore *rwsem) --{ -- if (--rwsem->read_depth == 0) -- rt_mutex_unlock(&rwsem->lock); --} -- --void rt_up_read(struct rw_semaphore *rwsem) --{ -- rwsem_release(&rwsem->dep_map, 1, _RET_IP_); -- __rt_up_read(rwsem); --} --EXPORT_SYMBOL(rt_up_read); -- --/* -- * downgrade a write lock into a read lock -- * - just wake up any readers at the front of the queue -- */ --void rt_downgrade_write(struct rw_semaphore *rwsem) --{ -- BUG_ON(rt_mutex_owner(&rwsem->lock) != current); -- rwsem->read_depth = 1; --} --EXPORT_SYMBOL(rt_downgrade_write); -- --int rt_down_write_trylock(struct rw_semaphore *rwsem) --{ -- int ret = rt_mutex_trylock(&rwsem->lock); -- -- if (ret) -- rwsem_acquire(&rwsem->dep_map, 0, 1, _RET_IP_); -- return ret; --} --EXPORT_SYMBOL(rt_down_write_trylock); -- --void rt_down_write(struct rw_semaphore *rwsem) --{ -- rwsem_acquire(&rwsem->dep_map, 0, 0, _RET_IP_); -- rt_mutex_lock(&rwsem->lock); --} --EXPORT_SYMBOL(rt_down_write); -- --int rt_down_write_killable(struct rw_semaphore *rwsem) --{ -- int ret; -- -- rwsem_acquire(&rwsem->dep_map, 0, 0, _RET_IP_); -- ret = rt_mutex_lock_killable(&rwsem->lock); -- if (ret) -- rwsem_release(&rwsem->dep_map, 1, _RET_IP_); -- return ret; --} --EXPORT_SYMBOL(rt_down_write_killable); -- --int rt_down_write_killable_nested(struct rw_semaphore *rwsem, int subclass) --{ -- int ret; -- -- rwsem_acquire(&rwsem->dep_map, subclass, 0, _RET_IP_); -- ret = rt_mutex_lock_killable(&rwsem->lock); -- if (ret) -- rwsem_release(&rwsem->dep_map, 1, _RET_IP_); -- return ret; --} --EXPORT_SYMBOL(rt_down_write_killable_nested); -- --void rt_down_write_nested(struct rw_semaphore *rwsem, int subclass) --{ -- rwsem_acquire(&rwsem->dep_map, subclass, 0, _RET_IP_); -- rt_mutex_lock(&rwsem->lock); --} --EXPORT_SYMBOL(rt_down_write_nested); -- --void rt_down_write_nested_lock(struct rw_semaphore *rwsem, -- struct lockdep_map *nest) --{ -- rwsem_acquire_nest(&rwsem->dep_map, 0, 0, nest, _RET_IP_); -- rt_mutex_lock(&rwsem->lock); --} --EXPORT_SYMBOL(rt_down_write_nested_lock); -- --int rt__down_read_trylock(struct rw_semaphore *rwsem) --{ -- struct rt_mutex *lock = &rwsem->lock; -- int ret = 1; -- -- /* -- * recursive read locks succeed when current owns the rwsem, -- * but not when read_depth == 0 which means that the rwsem is -- * write locked. -- */ -- if (rt_mutex_owner(lock) != current) -- ret = rt_mutex_trylock(&rwsem->lock); -- else if (!rwsem->read_depth) -- ret = 0; -- -- if (ret) -- rwsem->read_depth++; -- return ret; -- --} -- --int rt_down_read_trylock(struct rw_semaphore *rwsem) --{ -- int ret; -- -- ret = rt__down_read_trylock(rwsem); -- if (ret) -- rwsem_acquire(&rwsem->dep_map, 0, 1, _RET_IP_); -- -- return ret; --} --EXPORT_SYMBOL(rt_down_read_trylock); -- --void rt__down_read(struct rw_semaphore *rwsem) --{ -- struct rt_mutex *lock = &rwsem->lock; -- -- if (rt_mutex_owner(lock) != current) -- rt_mutex_lock(&rwsem->lock); -- rwsem->read_depth++; --} --EXPORT_SYMBOL(rt__down_read); -- --static void __rt_down_read(struct rw_semaphore *rwsem, int subclass) --{ -- rwsem_acquire_read(&rwsem->dep_map, subclass, 0, _RET_IP_); -- rt__down_read(rwsem); --} -- --void rt_down_read(struct rw_semaphore *rwsem) --{ -- __rt_down_read(rwsem, 0); --} --EXPORT_SYMBOL(rt_down_read); -- --void rt_down_read_nested(struct rw_semaphore *rwsem, int subclass) --{ -- __rt_down_read(rwsem, subclass); --} --EXPORT_SYMBOL(rt_down_read_nested); -- --void __rt_rwsem_init(struct rw_semaphore *rwsem, const char *name, -- struct lock_class_key *key) --{ --#ifdef CONFIG_DEBUG_LOCK_ALLOC -- /* -- * Make sure we are not reinitializing a held lock: -- */ -- debug_check_no_locks_freed((void *)rwsem, sizeof(*rwsem)); -- lockdep_init_map(&rwsem->dep_map, name, key, 0); --#endif -- rwsem->read_depth = 0; -- rwsem->lock.save_state = 0; --} --EXPORT_SYMBOL(__rt_rwsem_init); -- - /** - * atomic_dec_and_mutex_lock - return holding mutex if we dec to 0 - * @cnt: the atomic which we are to dec ++ ++#endif --- /dev/null +++ b/kernel/locking/rwsem-rt.c @@ -0,0 +1,269 @@ @@ -603,7 +252,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + */ + rt_mutex_init_waiter(&waiter, false); + rt_mutex_slowlock_locked(m, TASK_UNINTERRUPTIBLE, NULL, -+ RT_MUTEX_MIN_CHAINWALK, NULL, ++ RT_MUTEX_MIN_CHAINWALK, + &waiter); + /* + * The slowlock() above is guaranteed to return with the rtmutex is @@ -612,7 +261,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + */ + atomic_inc(&sem->readers); + raw_spin_unlock_irq(&m->wait_lock); -+ rt_mutex_unlock(m); ++ __rt_mutex_unlock(m); + + debug_rt_mutex_free_waiter(&waiter); +} @@ -651,7 +300,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + + atomic_add(READER_BIAS - bias, &sem->readers); + raw_spin_unlock_irqrestore(&m->wait_lock, flags); -+ rt_mutex_unlock(m); ++ __rt_mutex_unlock(m); +} + +static int __sched __down_write_common(struct rw_semaphore *sem, int state) @@ -660,7 +309,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + unsigned long flags; + + /* Take the rtmutex as a first step */ -+ if (rt_mutex_lock_state(m, state)) ++ if (__rt_mutex_lock_state(m, state)) + return -EINTR; + + /* Force readers into slow path */ @@ -707,7 +356,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> + struct rt_mutex *m = &sem->rtmutex; + unsigned long flags; + -+ if (!rt_mutex_trylock(m)) ++ if (!__rt_mutex_trylock(m)) + return 0; + + atomic_sub(READER_BIAS, &sem->readers); diff --git a/patches/rtmutex-add-sleeping-lock-implementation.patch b/patches/rtmutex-add-sleeping-lock-implementation.patch new file mode 100644 index 000000000000..defdb62ebfbf --- /dev/null +++ b/patches/rtmutex-add-sleeping-lock-implementation.patch @@ -0,0 +1,1195 @@ +From: Thomas Gleixner <tglx@linutronix.de> +Date: Thu, 12 Oct 2017 17:11:19 +0200 +Subject: rtmutex: add sleeping lock implementation + +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + include/linux/kernel.h | 4 + include/linux/rtmutex.h | 20 + + include/linux/sched.h | 9 + include/linux/sched/wake_q.h | 27 ++ + include/linux/spinlock_rt.h | 159 +++++++++++++ + include/linux/spinlock_types_rt.h | 48 ++++ + kernel/fork.c | 1 + kernel/futex.c | 11 + kernel/locking/rtmutex.c | 449 ++++++++++++++++++++++++++++++++++---- + kernel/locking/rtmutex_common.h | 15 + + kernel/sched/core.c | 28 +- + 11 files changed, 712 insertions(+), 59 deletions(-) + create mode 100644 include/linux/spinlock_rt.h + create mode 100644 include/linux/spinlock_types_rt.h + +--- a/include/linux/kernel.h ++++ b/include/linux/kernel.h +@@ -203,6 +203,9 @@ extern int _cond_resched(void); + */ + # define might_sleep() \ + do { __might_sleep(__FILE__, __LINE__, 0); might_resched(); } while (0) ++ ++# define might_sleep_no_state_check() \ ++ do { ___might_sleep(__FILE__, __LINE__, 0); might_resched(); } while (0) + # define sched_annotate_sleep() (current->task_state_change = 0) + #else + static inline void ___might_sleep(const char *file, int line, +@@ -210,6 +213,7 @@ extern int _cond_resched(void); + static inline void __might_sleep(const char *file, int line, + int preempt_offset) { } + # define might_sleep() do { might_resched(); } while (0) ++# define might_sleep_no_state_check() do { might_resched(); } while (0) + # define sched_annotate_sleep() do { } while (0) + #endif + +--- a/include/linux/rtmutex.h ++++ b/include/linux/rtmutex.h +@@ -13,11 +13,15 @@ + #define __LINUX_RT_MUTEX_H + + #include <linux/linkage.h> +-#include <linux/rbtree.h> + #include <linux/spinlock_types_raw.h> ++#include <linux/rbtree.h> + + extern int max_lock_depth; /* for sysctl */ + ++#ifdef CONFIG_DEBUG_MUTEXES ++#include <linux/debug_locks.h> ++#endif ++ + /** + * The rt_mutex structure + * +@@ -31,8 +35,8 @@ struct rt_mutex { + struct rb_root waiters; + struct rb_node *waiters_leftmost; + struct task_struct *owner; +-#ifdef CONFIG_DEBUG_RT_MUTEXES + int save_state; ++#ifdef CONFIG_DEBUG_RT_MUTEXES + const char *name, *file; + int line; + void *magic; +@@ -82,16 +86,22 @@ do { \ + #define __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname) + #endif + +-#define __RT_MUTEX_INITIALIZER(mutexname) \ +- { .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(mutexname.wait_lock) \ ++#define __RT_MUTEX_INITIALIZER_PLAIN(mutexname) \ ++ .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(mutexname.wait_lock) \ + , .waiters = RB_ROOT \ + , .owner = NULL \ + __DEBUG_RT_MUTEX_INITIALIZER(mutexname) \ +- __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname)} ++ __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname) ++ ++#define __RT_MUTEX_INITIALIZER(mutexname) \ ++ { __RT_MUTEX_INITIALIZER_PLAIN(mutexname) } + + #define DEFINE_RT_MUTEX(mutexname) \ + struct rt_mutex mutexname = __RT_MUTEX_INITIALIZER(mutexname) + ++#define __RT_MUTEX_INITIALIZER_SAVE_STATE(mutexname) \ ++ { __RT_MUTEX_INITIALIZER_PLAIN(mutexname) \ ++ , .save_state = 1 } + /** + * rt_mutex_is_locked - is the mutex locked + * @lock: the mutex to be queried +--- a/include/linux/sched.h ++++ b/include/linux/sched.h +@@ -123,6 +123,11 @@ struct task_group; + smp_store_mb(current->state, (state_value)); \ + } while (0) + ++#define __set_current_state_no_track(state_value) \ ++ current->state = (state_value); ++#define set_current_state_no_track(state_value) \ ++ smp_store_mb(current->state, (state_value)); ++ + #else + /* + * set_current_state() includes a barrier so that the write of current->state +@@ -160,6 +165,9 @@ struct task_group; + */ + #define __set_current_state(state_value) do { current->state = (state_value); } while (0) + #define set_current_state(state_value) smp_store_mb(current->state, (state_value)) ++ ++#define __set_current_state_no_track(state_value) __set_current_state(state_value) ++#define set_current_state_no_track(state_value) set_current_state(state_value) + #endif + + /* Task command name length: */ +@@ -826,6 +834,7 @@ struct task_struct { + raw_spinlock_t pi_lock; + + struct wake_q_node wake_q; ++ struct wake_q_node wake_q_sleeper; + + #ifdef CONFIG_RT_MUTEXES + /* PI waiters blocked on a rt_mutex held by this task: */ +--- a/include/linux/sched/wake_q.h ++++ b/include/linux/sched/wake_q.h +@@ -46,8 +46,29 @@ static inline void wake_q_init(struct wa + head->lastp = &head->first; + } + +-extern void wake_q_add(struct wake_q_head *head, +- struct task_struct *task); +-extern void wake_up_q(struct wake_q_head *head); ++extern void __wake_q_add(struct wake_q_head *head, ++ struct task_struct *task, bool sleeper); ++static inline void wake_q_add(struct wake_q_head *head, ++ struct task_struct *task) ++{ ++ __wake_q_add(head, task, false); ++} ++ ++static inline void wake_q_add_sleeper(struct wake_q_head *head, ++ struct task_struct *task) ++{ ++ __wake_q_add(head, task, true); ++} ++ ++extern void __wake_up_q(struct wake_q_head *head, bool sleeper); ++static inline void wake_up_q(struct wake_q_head *head) ++{ ++ __wake_up_q(head, false); ++} ++ ++static inline void wake_up_q_sleeper(struct wake_q_head *head) ++{ ++ __wake_up_q(head, true); ++} + + #endif /* _LINUX_SCHED_WAKE_Q_H */ +--- /dev/null ++++ b/include/linux/spinlock_rt.h +@@ -0,0 +1,159 @@ ++#ifndef __LINUX_SPINLOCK_RT_H ++#define __LINUX_SPINLOCK_RT_H ++ ++#ifndef __LINUX_SPINLOCK_H ++#error Do not include directly. Use spinlock.h ++#endif ++ ++#include <linux/bug.h> ++ ++extern void ++__rt_spin_lock_init(spinlock_t *lock, const char *name, struct lock_class_key *key); ++ ++#define spin_lock_init(slock) \ ++do { \ ++ static struct lock_class_key __key; \ ++ \ ++ rt_mutex_init(&(slock)->lock); \ ++ __rt_spin_lock_init(slock, #slock, &__key); \ ++} while (0) ++ ++extern void __lockfunc rt_spin_lock(spinlock_t *lock); ++extern unsigned long __lockfunc rt_spin_lock_trace_flags(spinlock_t *lock); ++extern void __lockfunc rt_spin_lock_nested(spinlock_t *lock, int subclass); ++extern void __lockfunc rt_spin_unlock(spinlock_t *lock); ++extern void __lockfunc rt_spin_unlock_wait(spinlock_t *lock); ++extern int __lockfunc rt_spin_trylock_irqsave(spinlock_t *lock, unsigned long *flags); ++extern int __lockfunc rt_spin_trylock_bh(spinlock_t *lock); ++extern int __lockfunc rt_spin_trylock(spinlock_t *lock); ++extern int atomic_dec_and_spin_lock(atomic_t *atomic, spinlock_t *lock); ++ ++/* ++ * lockdep-less calls, for derived types like rwlock: ++ * (for trylock they can use rt_mutex_trylock() directly. ++ * Migrate disable handling must be done at the call site. ++ */ ++extern void __lockfunc __rt_spin_lock(struct rt_mutex *lock); ++extern void __lockfunc __rt_spin_trylock(struct rt_mutex *lock); ++extern void __lockfunc __rt_spin_unlock(struct rt_mutex *lock); ++ ++#define spin_lock(lock) rt_spin_lock(lock) ++ ++#define spin_lock_bh(lock) \ ++ do { \ ++ local_bh_disable(); \ ++ rt_spin_lock(lock); \ ++ } while (0) ++ ++#define spin_lock_irq(lock) spin_lock(lock) ++ ++#define spin_do_trylock(lock) __cond_lock(lock, rt_spin_trylock(lock)) ++ ++#define spin_trylock(lock) \ ++({ \ ++ int __locked; \ ++ __locked = spin_do_trylock(lock); \ ++ __locked; \ ++}) ++ ++#ifdef CONFIG_LOCKDEP ++# define spin_lock_nested(lock, subclass) \ ++ do { \ ++ rt_spin_lock_nested(lock, subclass); \ ++ } while (0) ++ ++#define spin_lock_bh_nested(lock, subclass) \ ++ do { \ ++ local_bh_disable(); \ ++ rt_spin_lock_nested(lock, subclass); \ ++ } while (0) ++ ++# define spin_lock_irqsave_nested(lock, flags, subclass) \ ++ do { \ ++ typecheck(unsigned long, flags); \ ++ flags = 0; \ ++ rt_spin_lock_nested(lock, subclass); \ ++ } while (0) ++#else ++# define spin_lock_nested(lock, subclass) spin_lock(lock) ++# define spin_lock_bh_nested(lock, subclass) spin_lock_bh(lock) ++ ++# define spin_lock_irqsave_nested(lock, flags, subclass) \ ++ do { \ ++ typecheck(unsigned long, flags); \ ++ flags = 0; \ ++ spin_lock(lock); \ ++ } while (0) ++#endif ++ ++#define spin_lock_irqsave(lock, flags) \ ++ do { \ ++ typecheck(unsigned long, flags); \ ++ flags = 0; \ ++ spin_lock(lock); \ ++ } while (0) ++ ++static inline unsigned long spin_lock_trace_flags(spinlock_t *lock) ++{ ++ unsigned long flags = 0; ++#ifdef CONFIG_TRACE_IRQFLAGS ++ flags = rt_spin_lock_trace_flags(lock); ++#else ++ spin_lock(lock); /* lock_local */ ++#endif ++ return flags; ++} ++ ++/* FIXME: we need rt_spin_lock_nest_lock */ ++#define spin_lock_nest_lock(lock, nest_lock) spin_lock_nested(lock, 0) ++ ++#define spin_unlock(lock) rt_spin_unlock(lock) ++ ++#define spin_unlock_bh(lock) \ ++ do { \ ++ rt_spin_unlock(lock); \ ++ local_bh_enable(); \ ++ } while (0) ++ ++#define spin_unlock_irq(lock) spin_unlock(lock) ++ ++#define spin_unlock_irqrestore(lock, flags) \ ++ do { \ ++ typecheck(unsigned long, flags); \ ++ (void) flags; \ ++ spin_unlock(lock); \ ++ } while (0) ++ ++#define spin_trylock_bh(lock) __cond_lock(lock, rt_spin_trylock_bh(lock)) ++#define spin_trylock_irq(lock) spin_trylock(lock) ++ ++#define spin_trylock_irqsave(lock, flags) \ ++ rt_spin_trylock_irqsave(lock, &(flags)) ++ ++#define spin_unlock_wait(lock) rt_spin_unlock_wait(lock) ++ ++#ifdef CONFIG_GENERIC_LOCKBREAK ++# define spin_is_contended(lock) ((lock)->break_lock) ++#else ++# define spin_is_contended(lock) (((void)(lock), 0)) ++#endif ++ ++static inline int spin_can_lock(spinlock_t *lock) ++{ ++ return !rt_mutex_is_locked(&lock->lock); ++} ++ ++static inline int spin_is_locked(spinlock_t *lock) ++{ ++ return rt_mutex_is_locked(&lock->lock); ++} ++ ++static inline void assert_spin_locked(spinlock_t *lock) ++{ ++ BUG_ON(!spin_is_locked(lock)); ++} ++ ++#define atomic_dec_and_lock(atomic, lock) \ ++ atomic_dec_and_spin_lock(atomic, lock) ++ ++#endif +--- /dev/null ++++ b/include/linux/spinlock_types_rt.h +@@ -0,0 +1,48 @@ ++#ifndef __LINUX_SPINLOCK_TYPES_RT_H ++#define __LINUX_SPINLOCK_TYPES_RT_H ++ ++#ifndef __LINUX_SPINLOCK_TYPES_H ++#error "Do not include directly. Include spinlock_types.h instead" ++#endif ++ ++#include <linux/cache.h> ++ ++/* ++ * PREEMPT_RT: spinlocks - an RT mutex plus lock-break field: ++ */ ++typedef struct spinlock { ++ struct rt_mutex lock; ++ unsigned int break_lock; ++#ifdef CONFIG_DEBUG_LOCK_ALLOC ++ struct lockdep_map dep_map; ++#endif ++} spinlock_t; ++ ++#ifdef CONFIG_DEBUG_RT_MUTEXES ++# define __RT_SPIN_INITIALIZER(name) \ ++ { \ ++ .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(name.wait_lock), \ ++ .save_state = 1, \ ++ .file = __FILE__, \ ++ .line = __LINE__ , \ ++ } ++#else ++# define __RT_SPIN_INITIALIZER(name) \ ++ { \ ++ .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(name.wait_lock), \ ++ .save_state = 1, \ ++ } ++#endif ++ ++/* ++.wait_list = PLIST_HEAD_INIT_RAW((name).lock.wait_list, (name).lock.wait_lock) ++*/ ++ ++#define __SPIN_LOCK_UNLOCKED(name) \ ++ { .lock = __RT_SPIN_INITIALIZER(name.lock), \ ++ SPIN_DEP_MAP_INIT(name) } ++ ++#define DEFINE_SPINLOCK(name) \ ++ spinlock_t name = __SPIN_LOCK_UNLOCKED(name) ++ ++#endif +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -592,6 +592,7 @@ static struct task_struct *dup_task_stru + tsk->splice_pipe = NULL; + tsk->task_frag.page = NULL; + tsk->wake_q.next = NULL; ++ tsk->wake_q_sleeper.next = NULL; + + account_kernel_stack(tsk, 1); + +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -1411,6 +1411,7 @@ static int wake_futex_pi(u32 __user *uad + struct task_struct *new_owner; + bool postunlock = false; + DEFINE_WAKE_Q(wake_q); ++ DEFINE_WAKE_Q(wake_sleeper_q); + int ret = 0; + + new_owner = rt_mutex_next_owner(&pi_state->pi_mutex); +@@ -1472,13 +1473,13 @@ static int wake_futex_pi(u32 __user *uad + pi_state->owner = new_owner; + raw_spin_unlock(&new_owner->pi_lock); + +- postunlock = __rt_mutex_futex_unlock(&pi_state->pi_mutex, &wake_q); +- ++ postunlock = __rt_mutex_futex_unlock(&pi_state->pi_mutex, &wake_q, ++ &wake_sleeper_q); + out_unlock: + raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); + + if (postunlock) +- rt_mutex_postunlock(&wake_q); ++ rt_mutex_postunlock(&wake_q, &wake_sleeper_q); + + return ret; + } +@@ -2677,7 +2678,7 @@ static int futex_lock_pi(u32 __user *uad + goto no_block; + } + +- rt_mutex_init_waiter(&rt_waiter); ++ rt_mutex_init_waiter(&rt_waiter, false); + + /* + * On PREEMPT_RT_FULL, when hb->lock becomes an rt_mutex, we must not +@@ -3043,7 +3044,7 @@ static int futex_wait_requeue_pi(u32 __u + * The waiter is allocated on our stack, manipulated by the requeue + * code while we sleep on uaddr. + */ +- rt_mutex_init_waiter(&rt_waiter); ++ rt_mutex_init_waiter(&rt_waiter, false); + + ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, VERIFY_WRITE); + if (unlikely(ret != 0)) +--- a/kernel/locking/rtmutex.c ++++ b/kernel/locking/rtmutex.c +@@ -7,6 +7,11 @@ + * Copyright (C) 2005-2006 Timesys Corp., Thomas Gleixner <tglx@timesys.com> + * Copyright (C) 2005 Kihon Technologies Inc., Steven Rostedt + * Copyright (C) 2006 Esben Nielsen ++ * Adaptive Spinlocks: ++ * Copyright (C) 2008 Novell, Inc., Gregory Haskins, Sven Dietrich, ++ * and Peter Morreale, ++ * Adaptive Spinlocks simplification: ++ * Copyright (C) 2008 Red Hat, Inc., Steven Rostedt <srostedt@redhat.com> + * + * See Documentation/locking/rt-mutex-design.txt for details. + */ +@@ -234,7 +239,7 @@ static inline bool unlock_rt_mutex_safe( + * Only use with rt_mutex_waiter_{less,equal}() + */ + #define task_to_waiter(p) \ +- &(struct rt_mutex_waiter){ .prio = (p)->prio, .deadline = (p)->dl.deadline } ++ &(struct rt_mutex_waiter){ .prio = (p)->prio, .deadline = (p)->dl.deadline, .task = (p) } + + static inline int + rt_mutex_waiter_less(struct rt_mutex_waiter *left, +@@ -274,6 +279,27 @@ rt_mutex_waiter_equal(struct rt_mutex_wa + return 1; + } + ++#define STEAL_NORMAL 0 ++#define STEAL_LATERAL 1 ++ ++static inline int ++rt_mutex_steal(struct rt_mutex *lock, struct rt_mutex_waiter *waiter, int mode) ++{ ++ struct rt_mutex_waiter *top_waiter = rt_mutex_top_waiter(lock); ++ ++ if (waiter == top_waiter || rt_mutex_waiter_less(waiter, top_waiter)) ++ return 1; ++ ++ /* ++ * Note that RT tasks are excluded from lateral-steals ++ * to prevent the introduction of an unbounded latency. ++ */ ++ if (mode == STEAL_NORMAL || rt_task(waiter->task)) ++ return 0; ++ ++ return rt_mutex_waiter_equal(waiter, top_waiter); ++} ++ + static void + rt_mutex_enqueue(struct rt_mutex *lock, struct rt_mutex_waiter *waiter) + { +@@ -390,6 +416,14 @@ static bool rt_mutex_cond_detect_deadloc + return debug_rt_mutex_detect_deadlock(waiter, chwalk); + } + ++static void rt_mutex_wake_waiter(struct rt_mutex_waiter *waiter) ++{ ++ if (waiter->savestate) ++ wake_up_lock_sleeper(waiter->task); ++ else ++ wake_up_process(waiter->task); ++} ++ + /* + * Max number of times we'll walk the boosting chain: + */ +@@ -715,13 +749,16 @@ static int rt_mutex_adjust_prio_chain(st + * follow here. This is the end of the chain we are walking. + */ + if (!rt_mutex_owner(lock)) { ++ struct rt_mutex_waiter *lock_top_waiter; ++ + /* + * If the requeue [7] above changed the top waiter, + * then we need to wake the new top waiter up to try + * to get the lock. + */ +- if (prerequeue_top_waiter != rt_mutex_top_waiter(lock)) +- wake_up_process(rt_mutex_top_waiter(lock)->task); ++ lock_top_waiter = rt_mutex_top_waiter(lock); ++ if (prerequeue_top_waiter != lock_top_waiter) ++ rt_mutex_wake_waiter(lock_top_waiter); + raw_spin_unlock_irq(&lock->wait_lock); + return 0; + } +@@ -823,9 +860,11 @@ static int rt_mutex_adjust_prio_chain(st + * @task: The task which wants to acquire the lock + * @waiter: The waiter that is queued to the lock's wait tree if the + * callsite called task_blocked_on_lock(), otherwise NULL ++ * @mode: Lock steal mode (STEAL_NORMAL, STEAL_LATERAL) + */ +-static int try_to_take_rt_mutex(struct rt_mutex *lock, struct task_struct *task, +- struct rt_mutex_waiter *waiter) ++static int __try_to_take_rt_mutex(struct rt_mutex *lock, ++ struct task_struct *task, ++ struct rt_mutex_waiter *waiter, int mode) + { + lockdep_assert_held(&lock->wait_lock); + +@@ -861,12 +900,11 @@ static int try_to_take_rt_mutex(struct r + */ + if (waiter) { + /* +- * If waiter is not the highest priority waiter of +- * @lock, give up. ++ * If waiter is not the highest priority waiter of @lock, ++ * or its peer when lateral steal is allowed, give up. + */ +- if (waiter != rt_mutex_top_waiter(lock)) ++ if (!rt_mutex_steal(lock, waiter, mode)) + return 0; +- + /* + * We can acquire the lock. Remove the waiter from the + * lock waiters tree. +@@ -884,14 +922,12 @@ static int try_to_take_rt_mutex(struct r + */ + if (rt_mutex_has_waiters(lock)) { + /* +- * If @task->prio is greater than or equal to +- * the top waiter priority (kernel view), +- * @task lost. ++ * If @task->prio is greater than the top waiter ++ * priority (kernel view), or equal to it when a ++ * lateral steal is forbidden, @task lost. + */ +- if (!rt_mutex_waiter_less(task_to_waiter(task), +- rt_mutex_top_waiter(lock))) ++ if (!rt_mutex_steal(lock, task_to_waiter(task), mode)) + return 0; +- + /* + * The current top waiter stays enqueued. We + * don't have to change anything in the lock +@@ -938,6 +974,309 @@ static int try_to_take_rt_mutex(struct r + return 1; + } + ++#ifdef CONFIG_PREEMPT_RT_FULL ++/* ++ * preemptible spin_lock functions: ++ */ ++static inline void rt_spin_lock_fastlock(struct rt_mutex *lock, ++ void (*slowfn)(struct rt_mutex *lock)) ++{ ++ might_sleep_no_state_check(); ++ ++ if (likely(rt_mutex_cmpxchg_acquire(lock, NULL, current))) ++ return; ++ else ++ slowfn(lock); ++} ++ ++static inline void rt_spin_lock_fastunlock(struct rt_mutex *lock, ++ void (*slowfn)(struct rt_mutex *lock)) ++{ ++ if (likely(rt_mutex_cmpxchg_release(lock, current, NULL))) ++ return; ++ else ++ slowfn(lock); ++} ++#ifdef CONFIG_SMP ++/* ++ * Note that owner is a speculative pointer and dereferencing relies ++ * on rcu_read_lock() and the check against the lock owner. ++ */ ++static int adaptive_wait(struct rt_mutex *lock, ++ struct task_struct *owner) ++{ ++ int res = 0; ++ ++ rcu_read_lock(); ++ for (;;) { ++ if (owner != rt_mutex_owner(lock)) ++ break; ++ /* ++ * Ensure that owner->on_cpu is dereferenced _after_ ++ * checking the above to be valid. ++ */ ++ barrier(); ++ if (!owner->on_cpu) { ++ res = 1; ++ break; ++ } ++ cpu_relax(); ++ } ++ rcu_read_unlock(); ++ return res; ++} ++#else ++static int adaptive_wait(struct rt_mutex *lock, ++ struct task_struct *orig_owner) ++{ ++ return 1; ++} ++#endif ++ ++static int task_blocks_on_rt_mutex(struct rt_mutex *lock, ++ struct rt_mutex_waiter *waiter, ++ struct task_struct *task, ++ enum rtmutex_chainwalk chwalk); ++/* ++ * Slow path lock function spin_lock style: this variant is very ++ * careful not to miss any non-lock wakeups. ++ * ++ * We store the current state under p->pi_lock in p->saved_state and ++ * the try_to_wake_up() code handles this accordingly. ++ */ ++void __sched rt_spin_lock_slowlock_locked(struct rt_mutex *lock, ++ struct rt_mutex_waiter *waiter, ++ unsigned long flags) ++{ ++ struct task_struct *lock_owner, *self = current; ++ struct rt_mutex_waiter *top_waiter; ++ int ret; ++ ++ if (__try_to_take_rt_mutex(lock, self, NULL, STEAL_LATERAL)) ++ return; ++ ++ BUG_ON(rt_mutex_owner(lock) == self); ++ ++ /* ++ * We save whatever state the task is in and we'll restore it ++ * after acquiring the lock taking real wakeups into account ++ * as well. We are serialized via pi_lock against wakeups. See ++ * try_to_wake_up(). ++ */ ++ raw_spin_lock(&self->pi_lock); ++ self->saved_state = self->state; ++ __set_current_state_no_track(TASK_UNINTERRUPTIBLE); ++ raw_spin_unlock(&self->pi_lock); ++ ++ ret = task_blocks_on_rt_mutex(lock, waiter, self, RT_MUTEX_MIN_CHAINWALK); ++ BUG_ON(ret); ++ ++ for (;;) { ++ /* Try to acquire the lock again. */ ++ if (__try_to_take_rt_mutex(lock, self, waiter, STEAL_LATERAL)) ++ break; ++ ++ top_waiter = rt_mutex_top_waiter(lock); ++ lock_owner = rt_mutex_owner(lock); ++ ++ raw_spin_unlock_irqrestore(&lock->wait_lock, flags); ++ ++ debug_rt_mutex_print_deadlock(waiter); ++ ++ if (top_waiter != waiter || adaptive_wait(lock, lock_owner)) ++ schedule(); ++ ++ raw_spin_lock_irqsave(&lock->wait_lock, flags); ++ ++ raw_spin_lock(&self->pi_lock); ++ __set_current_state_no_track(TASK_UNINTERRUPTIBLE); ++ raw_spin_unlock(&self->pi_lock); ++ } ++ ++ /* ++ * Restore the task state to current->saved_state. We set it ++ * to the original state above and the try_to_wake_up() code ++ * has possibly updated it when a real (non-rtmutex) wakeup ++ * happened while we were blocked. Clear saved_state so ++ * try_to_wakeup() does not get confused. ++ */ ++ raw_spin_lock(&self->pi_lock); ++ __set_current_state_no_track(self->saved_state); ++ self->saved_state = TASK_RUNNING; ++ raw_spin_unlock(&self->pi_lock); ++ ++ /* ++ * try_to_take_rt_mutex() sets the waiter bit ++ * unconditionally. We might have to fix that up: ++ */ ++ fixup_rt_mutex_waiters(lock); ++ ++ BUG_ON(rt_mutex_has_waiters(lock) && waiter == rt_mutex_top_waiter(lock)); ++ BUG_ON(!RB_EMPTY_NODE(&waiter->tree_entry)); ++} ++ ++static void noinline __sched rt_spin_lock_slowlock(struct rt_mutex *lock) ++{ ++ struct rt_mutex_waiter waiter; ++ unsigned long flags; ++ ++ rt_mutex_init_waiter(&waiter, true); ++ ++ raw_spin_lock_irqsave(&lock->wait_lock, flags); ++ rt_spin_lock_slowlock_locked(lock, &waiter, flags); ++ raw_spin_unlock_irqrestore(&lock->wait_lock, flags); ++ debug_rt_mutex_free_waiter(&waiter); ++} ++ ++static bool __sched __rt_mutex_unlock_common(struct rt_mutex *lock, ++ struct wake_q_head *wake_q, ++ struct wake_q_head *wq_sleeper); ++/* ++ * Slow path to release a rt_mutex spin_lock style ++ */ ++void __sched rt_spin_lock_slowunlock(struct rt_mutex *lock) ++{ ++ unsigned long flags; ++ DEFINE_WAKE_Q(wake_q); ++ DEFINE_WAKE_Q(wake_sleeper_q); ++ bool postunlock; ++ ++ raw_spin_lock_irqsave(&lock->wait_lock, flags); ++ postunlock = __rt_mutex_unlock_common(lock, &wake_q, &wake_sleeper_q); ++ raw_spin_unlock_irqrestore(&lock->wait_lock, flags); ++ ++ if (postunlock) ++ rt_mutex_postunlock(&wake_q, &wake_sleeper_q); ++} ++ ++void __lockfunc rt_spin_lock(spinlock_t *lock) ++{ ++ migrate_disable(); ++ spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); ++ rt_spin_lock_fastlock(&lock->lock, rt_spin_lock_slowlock); ++} ++EXPORT_SYMBOL(rt_spin_lock); ++ ++void __lockfunc __rt_spin_lock(struct rt_mutex *lock) ++{ ++ rt_spin_lock_fastlock(lock, rt_spin_lock_slowlock); ++} ++ ++#ifdef CONFIG_DEBUG_LOCK_ALLOC ++void __lockfunc rt_spin_lock_nested(spinlock_t *lock, int subclass) ++{ ++ migrate_disable(); ++ spin_acquire(&lock->dep_map, subclass, 0, _RET_IP_); ++ rt_spin_lock_fastlock(&lock->lock, rt_spin_lock_slowlock); ++} ++EXPORT_SYMBOL(rt_spin_lock_nested); ++#endif ++ ++void __lockfunc rt_spin_unlock(spinlock_t *lock) ++{ ++ /* NOTE: we always pass in '1' for nested, for simplicity */ ++ spin_release(&lock->dep_map, 1, _RET_IP_); ++ rt_spin_lock_fastunlock(&lock->lock, rt_spin_lock_slowunlock); ++ migrate_enable(); ++} ++EXPORT_SYMBOL(rt_spin_unlock); ++ ++void __lockfunc __rt_spin_unlock(struct rt_mutex *lock) ++{ ++ rt_spin_lock_fastunlock(lock, rt_spin_lock_slowunlock); ++} ++EXPORT_SYMBOL(__rt_spin_unlock); ++ ++/* ++ * Wait for the lock to get unlocked: instead of polling for an unlock ++ * (like raw spinlocks do), we lock and unlock, to force the kernel to ++ * schedule if there's contention: ++ */ ++void __lockfunc rt_spin_unlock_wait(spinlock_t *lock) ++{ ++ spin_lock(lock); ++ spin_unlock(lock); ++} ++EXPORT_SYMBOL(rt_spin_unlock_wait); ++ ++int __lockfunc rt_spin_trylock(spinlock_t *lock) ++{ ++ int ret; ++ ++ migrate_disable(); ++ ret = __rt_mutex_trylock(&lock->lock); ++ if (ret) ++ spin_acquire(&lock->dep_map, 0, 1, _RET_IP_); ++ else ++ migrate_enable(); ++ return ret; ++} ++EXPORT_SYMBOL(rt_spin_trylock); ++ ++int __lockfunc rt_spin_trylock_bh(spinlock_t *lock) ++{ ++ int ret; ++ ++ local_bh_disable(); ++ ret = __rt_mutex_trylock(&lock->lock); ++ if (ret) { ++ migrate_disable(); ++ spin_acquire(&lock->dep_map, 0, 1, _RET_IP_); ++ } else ++ local_bh_enable(); ++ return ret; ++} ++EXPORT_SYMBOL(rt_spin_trylock_bh); ++ ++int __lockfunc rt_spin_trylock_irqsave(spinlock_t *lock, unsigned long *flags) ++{ ++ int ret; ++ ++ *flags = 0; ++ ret = __rt_mutex_trylock(&lock->lock); ++ if (ret) { ++ migrate_disable(); ++ spin_acquire(&lock->dep_map, 0, 1, _RET_IP_); ++ } ++ return ret; ++} ++EXPORT_SYMBOL(rt_spin_trylock_irqsave); ++ ++int atomic_dec_and_spin_lock(atomic_t *atomic, spinlock_t *lock) ++{ ++ /* Subtract 1 from counter unless that drops it to 0 (ie. it was 1) */ ++ if (atomic_add_unless(atomic, -1, 1)) ++ return 0; ++ rt_spin_lock(lock); ++ if (atomic_dec_and_test(atomic)) ++ return 1; ++ rt_spin_unlock(lock); ++ return 0; ++} ++EXPORT_SYMBOL(atomic_dec_and_spin_lock); ++ ++void ++__rt_spin_lock_init(spinlock_t *lock, const char *name, struct lock_class_key *key) ++{ ++#ifdef CONFIG_DEBUG_LOCK_ALLOC ++ /* ++ * Make sure we are not reinitializing a held lock: ++ */ ++ debug_check_no_locks_freed((void *)lock, sizeof(*lock)); ++ lockdep_init_map(&lock->dep_map, name, key, 0); ++#endif ++} ++EXPORT_SYMBOL(__rt_spin_lock_init); ++ ++#endif /* PREEMPT_RT_FULL */ ++ ++static inline int ++try_to_take_rt_mutex(struct rt_mutex *lock, struct task_struct *task, ++ struct rt_mutex_waiter *waiter) ++{ ++ return __try_to_take_rt_mutex(lock, task, waiter, STEAL_NORMAL); ++} ++ + /* + * Task blocks on lock. + * +@@ -1051,6 +1390,7 @@ static int task_blocks_on_rt_mutex(struc + * Called with lock->wait_lock held and interrupts disabled. + */ + static void mark_wakeup_next_waiter(struct wake_q_head *wake_q, ++ struct wake_q_head *wake_sleeper_q, + struct rt_mutex *lock) + { + struct rt_mutex_waiter *waiter; +@@ -1090,7 +1430,10 @@ static void mark_wakeup_next_waiter(stru + * Pairs with preempt_enable() in rt_mutex_postunlock(); + */ + preempt_disable(); +- wake_q_add(wake_q, waiter->task); ++ if (waiter->savestate) ++ wake_q_add_sleeper(wake_sleeper_q, waiter->task); ++ else ++ wake_q_add(wake_q, waiter->task); + raw_spin_unlock(¤t->pi_lock); + } + +@@ -1174,21 +1517,22 @@ void rt_mutex_adjust_pi(struct task_stru + return; + } + next_lock = waiter->lock; +- raw_spin_unlock_irqrestore(&task->pi_lock, flags); + + /* gets dropped in rt_mutex_adjust_prio_chain()! */ + get_task_struct(task); + ++ raw_spin_unlock_irqrestore(&task->pi_lock, flags); + rt_mutex_adjust_prio_chain(task, RT_MUTEX_MIN_CHAINWALK, NULL, + next_lock, NULL, task); + } + +-void rt_mutex_init_waiter(struct rt_mutex_waiter *waiter) ++void rt_mutex_init_waiter(struct rt_mutex_waiter *waiter, bool savestate) + { + debug_rt_mutex_init_waiter(waiter); + RB_CLEAR_NODE(&waiter->pi_tree_entry); + RB_CLEAR_NODE(&waiter->tree_entry); + waiter->task = NULL; ++ waiter->savestate = savestate; + } + + /** +@@ -1307,7 +1651,7 @@ rt_mutex_slowlock(struct rt_mutex *lock, + unsigned long flags; + int ret = 0; + +- rt_mutex_init_waiter(&waiter); ++ rt_mutex_init_waiter(&waiter, false); + + /* + * Technically we could use raw_spin_[un]lock_irq() here, but this can +@@ -1373,7 +1717,8 @@ static inline int rt_mutex_slowtrylock(s + * Return whether the current task needs to call rt_mutex_postunlock(). + */ + static bool __sched rt_mutex_slowunlock(struct rt_mutex *lock, +- struct wake_q_head *wake_q) ++ struct wake_q_head *wake_q, ++ struct wake_q_head *wake_sleeper_q) + { + unsigned long flags; + +@@ -1427,7 +1772,7 @@ static bool __sched rt_mutex_slowunlock( + * + * Queue the next waiter for wakeup once we release the wait_lock. + */ +- mark_wakeup_next_waiter(wake_q, lock); ++ mark_wakeup_next_waiter(wake_q, wake_sleeper_q, lock); + raw_spin_unlock_irqrestore(&lock->wait_lock, flags); + + return true; /* call rt_mutex_postunlock() */ +@@ -1479,9 +1824,11 @@ rt_mutex_fasttrylock(struct rt_mutex *lo + /* + * Performs the wakeup of the the top-waiter and re-enables preemption. + */ +-void rt_mutex_postunlock(struct wake_q_head *wake_q) ++void rt_mutex_postunlock(struct wake_q_head *wake_q, ++ struct wake_q_head *wake_sleeper_q) + { + wake_up_q(wake_q); ++ wake_up_q_sleeper(wake_sleeper_q); + + /* Pairs with preempt_disable() in rt_mutex_slowunlock() */ + preempt_enable(); +@@ -1490,15 +1837,17 @@ void rt_mutex_postunlock(struct wake_q_h + static inline void + rt_mutex_fastunlock(struct rt_mutex *lock, + bool (*slowfn)(struct rt_mutex *lock, +- struct wake_q_head *wqh)) ++ struct wake_q_head *wqh, ++ struct wake_q_head *wq_sleeper)) + { + DEFINE_WAKE_Q(wake_q); ++ DEFINE_WAKE_Q(wake_sleeper_q); + + if (likely(rt_mutex_cmpxchg_release(lock, current, NULL))) + return; + +- if (slowfn(lock, &wake_q)) +- rt_mutex_postunlock(&wake_q); ++ if (slowfn(lock, &wake_q, &wake_sleeper_q)) ++ rt_mutex_postunlock(&wake_q, &wake_sleeper_q); + } + + int __sched __rt_mutex_lock_state(struct rt_mutex *lock, int state) +@@ -1653,16 +2002,13 @@ void __sched __rt_mutex_unlock(struct rt + void __sched rt_mutex_unlock(struct rt_mutex *lock) + { + mutex_release(&lock->dep_map, 1, _RET_IP_); +- rt_mutex_fastunlock(lock, rt_mutex_slowunlock); ++ __rt_mutex_unlock(lock); + } + EXPORT_SYMBOL_GPL(rt_mutex_unlock); + +-/** +- * Futex variant, that since futex variants do not use the fast-path, can be +- * simple and will not need to retry. +- */ +-bool __sched __rt_mutex_futex_unlock(struct rt_mutex *lock, +- struct wake_q_head *wake_q) ++static bool __sched __rt_mutex_unlock_common(struct rt_mutex *lock, ++ struct wake_q_head *wake_q, ++ struct wake_q_head *wq_sleeper) + { + lockdep_assert_held(&lock->wait_lock); + +@@ -1679,22 +2025,34 @@ bool __sched __rt_mutex_futex_unlock(str + * avoid inversion prior to the wakeup. preempt_disable() + * therein pairs with rt_mutex_postunlock(). + */ +- mark_wakeup_next_waiter(wake_q, lock); ++ mark_wakeup_next_waiter(wake_q, wq_sleeper, lock); + + return true; /* call postunlock() */ + } + ++/** ++ * Futex variant, that since futex variants do not use the fast-path, can be ++ * simple and will not need to retry. ++ */ ++bool __sched __rt_mutex_futex_unlock(struct rt_mutex *lock, ++ struct wake_q_head *wake_q, ++ struct wake_q_head *wq_sleeper) ++{ ++ return __rt_mutex_unlock_common(lock, wake_q, wq_sleeper); ++} ++ + void __sched rt_mutex_futex_unlock(struct rt_mutex *lock) + { + DEFINE_WAKE_Q(wake_q); ++ DEFINE_WAKE_Q(wake_sleeper_q); + bool postunlock; + + raw_spin_lock_irq(&lock->wait_lock); +- postunlock = __rt_mutex_futex_unlock(lock, &wake_q); ++ postunlock = __rt_mutex_futex_unlock(lock, &wake_q, &wake_sleeper_q); + raw_spin_unlock_irq(&lock->wait_lock); + + if (postunlock) +- rt_mutex_postunlock(&wake_q); ++ rt_mutex_postunlock(&wake_q, &wake_sleeper_q); + } + + /** +@@ -1734,7 +2092,7 @@ void __rt_mutex_init(struct rt_mutex *lo + if (name && key) + debug_rt_mutex_init(lock, name, key); + } +-EXPORT_SYMBOL_GPL(__rt_mutex_init); ++EXPORT_SYMBOL(__rt_mutex_init); + + /** + * rt_mutex_init_proxy_locked - initialize and lock a rt_mutex on behalf of a +@@ -1903,6 +2261,7 @@ int rt_mutex_wait_proxy_lock(struct rt_m + struct hrtimer_sleeper *to, + struct rt_mutex_waiter *waiter) + { ++ struct task_struct *tsk = current; + int ret; + + raw_spin_lock_irq(&lock->wait_lock); +@@ -1914,6 +2273,24 @@ int rt_mutex_wait_proxy_lock(struct rt_m + * have to fix that up. + */ + fixup_rt_mutex_waiters(lock); ++ /* ++ * RT has a problem here when the wait got interrupted by a timeout ++ * or a signal. task->pi_blocked_on is still set. The task must ++ * acquire the hash bucket lock when returning from this function. ++ * ++ * If the hash bucket lock is contended then the ++ * BUG_ON(rt_mutex_real_waiter(task->pi_blocked_on)) in ++ * task_blocks_on_rt_mutex() will trigger. This can be avoided by ++ * clearing task->pi_blocked_on which removes the task from the ++ * boosting chain of the rtmutex. That's correct because the task ++ * is not longer blocked on it. ++ */ ++ if (ret) { ++ raw_spin_lock(&tsk->pi_lock); ++ tsk->pi_blocked_on = NULL; ++ raw_spin_unlock(&tsk->pi_lock); ++ } ++ + raw_spin_unlock_irq(&lock->wait_lock); + + return ret; +--- a/kernel/locking/rtmutex_common.h ++++ b/kernel/locking/rtmutex_common.h +@@ -14,6 +14,7 @@ + + #include <linux/rtmutex.h> + #include <linux/sched/wake_q.h> ++#include <linux/sched/debug.h> + + /* + * This is the control structure for tasks blocked on a rt_mutex, +@@ -28,6 +29,7 @@ struct rt_mutex_waiter { + struct rb_node pi_tree_entry; + struct task_struct *task; + struct rt_mutex *lock; ++ bool savestate; + #ifdef CONFIG_DEBUG_RT_MUTEXES + unsigned long ip; + struct pid *deadlock_task_pid; +@@ -107,7 +109,7 @@ extern void rt_mutex_init_proxy_locked(s + struct task_struct *proxy_owner); + extern void rt_mutex_proxy_unlock(struct rt_mutex *lock, + struct task_struct *proxy_owner); +-extern void rt_mutex_init_waiter(struct rt_mutex_waiter *waiter); ++extern void rt_mutex_init_waiter(struct rt_mutex_waiter *waiter, bool savetate); + extern int __rt_mutex_start_proxy_lock(struct rt_mutex *lock, + struct rt_mutex_waiter *waiter, + struct task_struct *task); +@@ -124,9 +126,12 @@ extern int rt_mutex_futex_trylock(struct + + extern void rt_mutex_futex_unlock(struct rt_mutex *lock); + extern bool __rt_mutex_futex_unlock(struct rt_mutex *lock, +- struct wake_q_head *wqh); ++ struct wake_q_head *wqh, ++ struct wake_q_head *wq_sleeper); ++ ++extern void rt_mutex_postunlock(struct wake_q_head *wake_q, ++ struct wake_q_head *wake_sleeper_q); + +-extern void rt_mutex_postunlock(struct wake_q_head *wake_q); + /* RW semaphore special interface */ + + extern int __rt_mutex_lock_state(struct rt_mutex *lock, int state); +@@ -136,6 +141,10 @@ int __sched rt_mutex_slowlock_locked(str + struct hrtimer_sleeper *timeout, + enum rtmutex_chainwalk chwalk, + struct rt_mutex_waiter *waiter); ++void __sched rt_spin_lock_slowlock_locked(struct rt_mutex *lock, ++ struct rt_mutex_waiter *waiter, ++ unsigned long flags); ++void __sched rt_spin_lock_slowunlock(struct rt_mutex *lock); + + #ifdef CONFIG_DEBUG_RT_MUTEXES + # include "rtmutex-debug.h" +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -427,9 +427,15 @@ static bool set_nr_if_polling(struct tas + #endif + #endif + +-void wake_q_add(struct wake_q_head *head, struct task_struct *task) ++void __wake_q_add(struct wake_q_head *head, struct task_struct *task, ++ bool sleeper) + { +- struct wake_q_node *node = &task->wake_q; ++ struct wake_q_node *node; ++ ++ if (sleeper) ++ node = &task->wake_q_sleeper; ++ else ++ node = &task->wake_q; + + /* + * Atomically grab the task, if ->wake_q is !nil already it means +@@ -451,24 +457,32 @@ void wake_q_add(struct wake_q_head *head + head->lastp = &node->next; + } + +-void wake_up_q(struct wake_q_head *head) ++void __wake_up_q(struct wake_q_head *head, bool sleeper) + { + struct wake_q_node *node = head->first; + + while (node != WAKE_Q_TAIL) { + struct task_struct *task; + +- task = container_of(node, struct task_struct, wake_q); ++ if (sleeper) ++ task = container_of(node, struct task_struct, wake_q_sleeper); ++ else ++ task = container_of(node, struct task_struct, wake_q); + BUG_ON(!task); + /* Task can safely be re-inserted now: */ + node = node->next; +- task->wake_q.next = NULL; +- ++ if (sleeper) ++ task->wake_q_sleeper.next = NULL; ++ else ++ task->wake_q.next = NULL; + /* + * wake_up_process() implies a wmb() to pair with the queueing + * in wake_q_add() so as not to miss wakeups. + */ +- wake_up_process(task); ++ if (sleeper) ++ wake_up_lock_sleeper(task); ++ else ++ wake_up_process(task); + put_task_struct(task); + } + } diff --git a/patches/rtmutex-add-a-first-shot-of-ww_mutex.patch b/patches/rtmutex-add-ww_mutex-addon-for-mutex-rt.patch index eb991c15e0ef..466b9d7da8fd 100644 --- a/patches/rtmutex-add-a-first-shot-of-ww_mutex.patch +++ b/patches/rtmutex-add-ww_mutex-addon-for-mutex-rt.patch @@ -1,29 +1,13 @@ -From: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> -Date: Mon, 28 Oct 2013 09:36:37 +0100 -Subject: rtmutex: Add RT aware ww locks +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Thu, 12 Oct 2017 17:34:38 +0200 +Subject: rtmutex: add ww_mutex addon for mutex-rt -lockdep says: -| -------------------------------------------------------------------------- -| | Wound/wait tests | -| --------------------- -| ww api failures: ok | ok | ok | -| ww contexts mixing: ok | ok | -| finishing ww context: ok | ok | ok | ok | -| locking mismatches: ok | ok | ok | -| EDEADLK handling: ok | ok | ok | ok | ok | ok | ok | ok | ok | ok | -| spinlock nest unlocked: ok | -| ----------------------------------------------------- -| |block | try |context| -| ----------------------------------------------------- -| context: ok | ok | ok | -| try: ok | ok | ok | -| block: ok | ok | ok | -| spinlock: ok | ok | ok | - -Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- - kernel/locking/rtmutex.c | 273 ++++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 247 insertions(+), 26 deletions(-) + kernel/locking/rtmutex.c | 265 ++++++++++++++++++++++++++++++++++++++-- + kernel/locking/rtmutex_common.h | 2 + kernel/locking/rwsem-rt.c | 2 + 3 files changed, 258 insertions(+), 11 deletions(-) --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c @@ -35,18 +19,7 @@ Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> #include "rtmutex_common.h" -@@ -1285,8 +1286,8 @@ int atomic_dec_and_spin_lock(atomic_t *a - } - EXPORT_SYMBOL(atomic_dec_and_spin_lock); - -- void --__rt_spin_lock_init(spinlock_t *lock, char *name, struct lock_class_key *key) -+void -+__rt_spin_lock_init(spinlock_t *lock, const char *name, struct lock_class_key *key) - { - #ifdef CONFIG_DEBUG_LOCK_ALLOC - /* -@@ -1300,6 +1301,40 @@ EXPORT_SYMBOL(__rt_spin_lock_init); +@@ -1270,6 +1271,40 @@ EXPORT_SYMBOL(__rt_spin_lock_init); #endif /* PREEMPT_RT_FULL */ @@ -87,7 +60,7 @@ Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> static inline int try_to_take_rt_mutex(struct rt_mutex *lock, struct task_struct *task, struct rt_mutex_waiter *waiter) -@@ -1580,7 +1615,8 @@ void rt_mutex_init_waiter(struct rt_mute +@@ -1548,7 +1583,8 @@ void rt_mutex_init_waiter(struct rt_mute static int __sched __rt_mutex_slowlock(struct rt_mutex *lock, int state, struct hrtimer_sleeper *timeout, @@ -97,7 +70,7 @@ Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> { int ret = 0; -@@ -1598,6 +1634,12 @@ static int __sched +@@ -1566,6 +1602,12 @@ static int __sched break; } @@ -110,7 +83,7 @@ Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> raw_spin_unlock_irq(&lock->wait_lock); debug_rt_mutex_print_deadlock(waiter); -@@ -1632,13 +1674,91 @@ static void rt_mutex_handle_deadlock(int +@@ -1600,16 +1642,107 @@ static void rt_mutex_handle_deadlock(int } } @@ -191,21 +164,13 @@ Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> +} +#endif + - /* - * Slow path lock function: - */ - static int __sched - rt_mutex_slowlock(struct rt_mutex *lock, int state, - struct hrtimer_sleeper *timeout, -- enum rtmutex_chainwalk chwalk) -+ enum rtmutex_chainwalk chwalk, -+ struct ww_acquire_ctx *ww_ctx) + int __sched rt_mutex_slowlock_locked(struct rt_mutex *lock, int state, + struct hrtimer_sleeper *timeout, + enum rtmutex_chainwalk chwalk, ++ struct ww_acquire_ctx *ww_ctx, + struct rt_mutex_waiter *waiter) { - struct rt_mutex_waiter waiter; - unsigned long flags; -@@ -1656,8 +1776,20 @@ rt_mutex_slowlock(struct rt_mutex *lock, - */ - raw_spin_lock_irqsave(&lock->wait_lock, flags); + int ret; +#ifdef CONFIG_PREEMPT_RT_FULL + if (ww_ctx) { @@ -218,39 +183,61 @@ Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> +#endif + /* Try to acquire the lock again: */ - if (try_to_take_rt_mutex(lock, current, NULL)) { +- if (try_to_take_rt_mutex(lock, current, NULL)) ++ if (try_to_take_rt_mutex(lock, current, NULL)) { + if (ww_ctx) + ww_mutex_account_lock(lock, ww_ctx); - raw_spin_unlock_irqrestore(&lock->wait_lock, flags); return 0; - } -@@ -1672,13 +1804,23 @@ rt_mutex_slowlock(struct rt_mutex *lock, ++ } - if (likely(!ret)) + set_current_state(state); + +@@ -1621,7 +1754,12 @@ int __sched rt_mutex_slowlock_locked(str + + if (likely(!ret)) { /* sleep on the mutex */ -- ret = __rt_mutex_slowlock(lock, state, timeout, &waiter); -+ ret = __rt_mutex_slowlock(lock, state, timeout, &waiter, +- ret = __rt_mutex_slowlock(lock, state, timeout, waiter); ++ ret = __rt_mutex_slowlock(lock, state, timeout, waiter, + ww_ctx); -+ else if (ww_ctx) { ++ } else if (ww_ctx) { + /* ww_mutex received EDEADLK, let it become EALREADY */ + ret = __mutex_lock_check_stamp(lock, ww_ctx); + BUG_ON(!ret); -+ } + } if (unlikely(ret)) { - __set_current_state(TASK_RUNNING); +@@ -1629,6 +1767,10 @@ int __sched rt_mutex_slowlock_locked(str if (rt_mutex_has_waiters(lock)) - remove_waiter(lock, &waiter); -- rt_mutex_handle_deadlock(ret, chwalk, &waiter); -+ /* ww_mutex want to report EDEADLK/EALREADY, let them */ + remove_waiter(lock, waiter); + /* ww_mutex want to report EDEADLK/EALREADY, let them */ + if (!ww_ctx) -+ rt_mutex_handle_deadlock(ret, chwalk, &waiter); ++ rt_mutex_handle_deadlock(ret, chwalk, waiter); + } else if (ww_ctx) { + ww_mutex_account_lock(lock, ww_ctx); } /* -@@ -1808,29 +1950,33 @@ static bool __sched rt_mutex_slowunlock( +@@ -1645,7 +1787,8 @@ int __sched rt_mutex_slowlock_locked(str + static int __sched + rt_mutex_slowlock(struct rt_mutex *lock, int state, + struct hrtimer_sleeper *timeout, +- enum rtmutex_chainwalk chwalk) ++ enum rtmutex_chainwalk chwalk, ++ struct ww_acquire_ctx *ww_ctx) + { + struct rt_mutex_waiter waiter; + unsigned long flags; +@@ -1663,7 +1806,8 @@ rt_mutex_slowlock(struct rt_mutex *lock, + */ + raw_spin_lock_irqsave(&lock->wait_lock, flags); + +- ret = rt_mutex_slowlock_locked(lock, state, timeout, chwalk, &waiter); ++ ret = rt_mutex_slowlock_locked(lock, state, timeout, chwalk, ww_ctx, ++ &waiter); + + raw_spin_unlock_irqrestore(&lock->wait_lock, flags); + +@@ -1786,29 +1930,33 @@ static bool __sched rt_mutex_slowunlock( */ static inline int rt_mutex_fastlock(struct rt_mutex *lock, int state, @@ -288,42 +275,15 @@ Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> } static inline int -@@ -1881,7 +2027,7 @@ void __sched rt_mutex_lock(struct rt_mut - { - might_sleep(); - -- rt_mutex_fastlock(lock, TASK_UNINTERRUPTIBLE, rt_mutex_slowlock); -+ rt_mutex_fastlock(lock, TASK_UNINTERRUPTIBLE, NULL, rt_mutex_slowlock); - } - EXPORT_SYMBOL_GPL(rt_mutex_lock); - -@@ -1898,7 +2044,7 @@ int __sched rt_mutex_lock_interruptible( - { - might_sleep(); - -- return rt_mutex_fastlock(lock, TASK_INTERRUPTIBLE, rt_mutex_slowlock); -+ return rt_mutex_fastlock(lock, TASK_INTERRUPTIBLE, NULL, rt_mutex_slowlock); - } - EXPORT_SYMBOL_GPL(rt_mutex_lock_interruptible); - -@@ -1925,7 +2071,7 @@ int __sched rt_mutex_lock_killable(struc - { - might_sleep(); - -- return rt_mutex_fastlock(lock, TASK_KILLABLE, rt_mutex_slowlock); -+ return rt_mutex_fastlock(lock, TASK_KILLABLE, NULL, rt_mutex_slowlock); - } - EXPORT_SYMBOL_GPL(rt_mutex_lock_killable); - -@@ -1949,6 +2095,7 @@ rt_mutex_timed_lock(struct rt_mutex *loc - - return rt_mutex_timed_fastlock(lock, TASK_INTERRUPTIBLE, timeout, +@@ -1946,6 +2094,7 @@ rt_mutex_timed_lock(struct rt_mutex *loc + mutex_acquire(&lock->dep_map, 0, 0, _RET_IP_); + ret = rt_mutex_timed_fastlock(lock, TASK_INTERRUPTIBLE, timeout, RT_MUTEX_MIN_CHAINWALK, + NULL, rt_mutex_slowlock); - } - EXPORT_SYMBOL_GPL(rt_mutex_timed_lock); -@@ -2246,7 +2393,7 @@ int rt_mutex_wait_proxy_lock(struct rt_m + if (ret) + mutex_release(&lock->dep_map, 1, _RET_IP_); +@@ -2267,7 +2416,7 @@ int rt_mutex_wait_proxy_lock(struct rt_m raw_spin_lock_irq(&lock->wait_lock); /* sleep on the mutex */ set_current_state(TASK_INTERRUPTIBLE); @@ -332,10 +292,11 @@ Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> /* * try_to_take_rt_mutex() sets the waiter bit unconditionally. We might * have to fix that up. -@@ -2313,24 +2460,98 @@ bool rt_mutex_cleanup_proxy_lock(struct +@@ -2351,3 +2500,99 @@ bool rt_mutex_cleanup_proxy_lock(struct + return cleanup; } - ++ +static inline int +ww_mutex_deadlock_injection(struct ww_mutex *lock, struct ww_acquire_ctx *ctx) +{ @@ -362,16 +323,10 @@ Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> + return 0; +} + - #ifdef CONFIG_PREEMPT_RT_FULL --struct ww_mutex { --}; --struct ww_acquire_ctx { --}; --int __ww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ww_ctx) ++#ifdef CONFIG_PREEMPT_RT_FULL +int __sched +ww_mutex_lock_interruptible(struct ww_mutex *lock, struct ww_acquire_ctx *ctx) - { -- BUG(); ++{ + int ret; + + might_sleep(); @@ -386,15 +341,12 @@ Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> + return ww_mutex_deadlock_injection(lock, ctx); + + return ret; - } --EXPORT_SYMBOL_GPL(__ww_mutex_lock); --int __ww_mutex_lock_interruptible(struct ww_mutex *lock, struct ww_acquire_ctx *ww_ctx) ++} +EXPORT_SYMBOL_GPL(ww_mutex_lock_interruptible); + +int __sched +ww_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ctx) - { -- BUG(); ++{ + int ret; + + might_sleep(); @@ -409,13 +361,11 @@ Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> + return ww_mutex_deadlock_injection(lock, ctx); + + return ret; - } --EXPORT_SYMBOL_GPL(__ww_mutex_lock_interruptible); ++} +EXPORT_SYMBOL_GPL(ww_mutex_lock); + - void __sched ww_mutex_unlock(struct ww_mutex *lock) - { -- BUG(); ++void __sched ww_mutex_unlock(struct ww_mutex *lock) ++{ + int nest = !!lock->ctx; + + /* @@ -432,14 +382,42 @@ Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc> + } + + mutex_release(&lock->base.dep_map, nest, _RET_IP_); -+ rt_mutex_unlock(&lock->base.lock); ++ __rt_mutex_unlock(&lock->base.lock); +} +EXPORT_SYMBOL(ww_mutex_unlock); + +int __rt_mutex_owner_current(struct rt_mutex *lock) +{ + return rt_mutex_owner(lock) == current; - } --EXPORT_SYMBOL_GPL(ww_mutex_unlock); ++} +EXPORT_SYMBOL(__rt_mutex_owner_current); - #endif ++#endif +--- a/kernel/locking/rtmutex_common.h ++++ b/kernel/locking/rtmutex_common.h +@@ -133,6 +133,7 @@ extern void rt_mutex_postunlock(struct w + struct wake_q_head *wake_sleeper_q); + + /* RW semaphore special interface */ ++struct ww_acquire_ctx; + + extern int __rt_mutex_lock_state(struct rt_mutex *lock, int state); + extern int __rt_mutex_trylock(struct rt_mutex *lock); +@@ -140,6 +141,7 @@ extern void __rt_mutex_unlock(struct rt_ + int __sched rt_mutex_slowlock_locked(struct rt_mutex *lock, int state, + struct hrtimer_sleeper *timeout, + enum rtmutex_chainwalk chwalk, ++ struct ww_acquire_ctx *ww_ctx, + struct rt_mutex_waiter *waiter); + void __sched rt_spin_lock_slowlock_locked(struct rt_mutex *lock, + struct rt_mutex_waiter *waiter, +--- a/kernel/locking/rwsem-rt.c ++++ b/kernel/locking/rwsem-rt.c +@@ -130,7 +130,7 @@ void __sched __down_read(struct rw_semap + */ + rt_mutex_init_waiter(&waiter, false); + rt_mutex_slowlock_locked(m, TASK_UNINTERRUPTIBLE, NULL, +- RT_MUTEX_MIN_CHAINWALK, ++ RT_MUTEX_MIN_CHAINWALK, NULL, + &waiter); + /* + * The slowlock() above is guaranteed to return with the rtmutex is diff --git a/patches/rtmutex-export-lockdep-less-version-of-rt_mutex-s-lo.patch b/patches/rtmutex-export-lockdep-less-version-of-rt_mutex-s-lo.patch new file mode 100644 index 000000000000..f7c3d58cdeab --- /dev/null +++ b/patches/rtmutex-export-lockdep-less-version-of-rt_mutex-s-lo.patch @@ -0,0 +1,150 @@ +From: Thomas Gleixner <tglx@linutronix.de> +Date: Thu, 12 Oct 2017 16:36:39 +0200 +Subject: rtmutex: export lockdep-less version of rt_mutex's lock, + trylock and unlock + +Required for lock implementation ontop of rtmutex. + +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + kernel/locking/rtmutex.c | 70 +++++++++++++++++++++++++--------------- + kernel/locking/rtmutex_common.h | 3 + + 2 files changed, 47 insertions(+), 26 deletions(-) + +--- a/kernel/locking/rtmutex.c ++++ b/kernel/locking/rtmutex.c +@@ -1501,6 +1501,29 @@ rt_mutex_fastunlock(struct rt_mutex *loc + rt_mutex_postunlock(&wake_q); + } + ++int __sched __rt_mutex_lock_state(struct rt_mutex *lock, int state) ++{ ++ might_sleep(); ++ return rt_mutex_fastlock(lock, state, NULL, rt_mutex_slowlock); ++} ++ ++/** ++ * rt_mutex_lock_state - lock a rt_mutex with a given state ++ * ++ * @lock: The rt_mutex to be locked ++ * @state: The state to set when blocking on the rt_mutex ++ */ ++static int __sched rt_mutex_lock_state(struct rt_mutex *lock, int state) ++{ ++ int ret; ++ ++ mutex_acquire(&lock->dep_map, 0, 0, _RET_IP_); ++ ret = __rt_mutex_lock_state(lock, state); ++ if (ret) ++ mutex_release(&lock->dep_map, 1, _RET_IP_); ++ return ret; ++} ++ + /** + * rt_mutex_lock - lock a rt_mutex + * +@@ -1508,10 +1531,7 @@ rt_mutex_fastunlock(struct rt_mutex *loc + */ + void __sched rt_mutex_lock(struct rt_mutex *lock) + { +- might_sleep(); +- +- mutex_acquire(&lock->dep_map, 0, 0, _RET_IP_); +- rt_mutex_fastlock(lock, TASK_UNINTERRUPTIBLE, rt_mutex_slowlock); ++ rt_mutex_lock_state(lock, TASK_UNINTERRUPTIBLE); + } + EXPORT_SYMBOL_GPL(rt_mutex_lock); + +@@ -1526,16 +1546,7 @@ EXPORT_SYMBOL_GPL(rt_mutex_lock); + */ + int __sched rt_mutex_lock_interruptible(struct rt_mutex *lock) + { +- int ret; +- +- might_sleep(); +- +- mutex_acquire(&lock->dep_map, 0, 0, _RET_IP_); +- ret = rt_mutex_fastlock(lock, TASK_INTERRUPTIBLE, rt_mutex_slowlock); +- if (ret) +- mutex_release(&lock->dep_map, 1, _RET_IP_); +- +- return ret; ++ return rt_mutex_lock_state(lock, TASK_INTERRUPTIBLE); + } + EXPORT_SYMBOL_GPL(rt_mutex_lock_interruptible); + +@@ -1556,13 +1567,10 @@ int __sched rt_mutex_futex_trylock(struc + * Returns: + * 0 on success + * -EINTR when interrupted by a signal +- * -EDEADLK when the lock would deadlock (when deadlock detection is on) + */ + int __sched rt_mutex_lock_killable(struct rt_mutex *lock) + { +- might_sleep(); +- +- return rt_mutex_fastlock(lock, TASK_KILLABLE, rt_mutex_slowlock); ++ return rt_mutex_lock_state(lock, TASK_KILLABLE); + } + EXPORT_SYMBOL_GPL(rt_mutex_lock_killable); + +@@ -1597,6 +1605,18 @@ rt_mutex_timed_lock(struct rt_mutex *loc + } + EXPORT_SYMBOL_GPL(rt_mutex_timed_lock); + ++int __sched __rt_mutex_trylock(struct rt_mutex *lock) ++{ ++#ifdef CONFIG_PREEMPT_RT_FULL ++ if (WARN_ON_ONCE(in_irq() || in_nmi())) ++#else ++ if (WARN_ON_ONCE(in_irq() || in_nmi() || in_serving_softirq())) ++#endif ++ return 0; ++ ++ return rt_mutex_fasttrylock(lock, rt_mutex_slowtrylock); ++} ++ + /** + * rt_mutex_trylock - try to lock a rt_mutex + * +@@ -1612,14 +1632,7 @@ int __sched rt_mutex_trylock(struct rt_m + { + int ret; + +-#ifdef CONFIG_PREEMPT_RT_FULL +- if (WARN_ON_ONCE(in_irq() || in_nmi())) +-#else +- if (WARN_ON_ONCE(in_irq() || in_nmi() || in_serving_softirq())) +-#endif +- return 0; +- +- ret = rt_mutex_fasttrylock(lock, rt_mutex_slowtrylock); ++ ret = __rt_mutex_trylock(lock); + if (ret) + mutex_acquire(&lock->dep_map, 0, 1, _RET_IP_); + +@@ -1627,6 +1640,11 @@ int __sched rt_mutex_trylock(struct rt_m + } + EXPORT_SYMBOL_GPL(rt_mutex_trylock); + ++void __sched __rt_mutex_unlock(struct rt_mutex *lock) ++{ ++ rt_mutex_fastunlock(lock, rt_mutex_slowunlock); ++} ++ + /** + * rt_mutex_unlock - unlock a rt_mutex + * +--- a/kernel/locking/rtmutex_common.h ++++ b/kernel/locking/rtmutex_common.h +@@ -129,6 +129,9 @@ extern bool __rt_mutex_futex_unlock(stru + extern void rt_mutex_postunlock(struct wake_q_head *wake_q); + /* RW semaphore special interface */ + ++extern int __rt_mutex_lock_state(struct rt_mutex *lock, int state); ++extern int __rt_mutex_trylock(struct rt_mutex *lock); ++extern void __rt_mutex_unlock(struct rt_mutex *lock); + int __sched rt_mutex_slowlock_locked(struct rt_mutex *lock, int state, + struct hrtimer_sleeper *timeout, + enum rtmutex_chainwalk chwalk, diff --git a/patches/rtmutex-futex-prepare-rt.patch b/patches/rtmutex-futex-prepare-rt.patch index ec7838e96bd3..06b03f3c6207 100644 --- a/patches/rtmutex-futex-prepare-rt.patch +++ b/patches/rtmutex-futex-prepare-rt.patch @@ -9,13 +9,13 @@ therefor not disabling preemption. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- kernel/futex.c | 77 ++++++++++++++++++++++++++++++++-------- - kernel/locking/rtmutex.c | 37 ++++++++++++++++--- + kernel/locking/rtmutex.c | 36 +++++++++++++++--- kernel/locking/rtmutex_common.h | 2 + - 3 files changed, 95 insertions(+), 21 deletions(-) + 3 files changed, 94 insertions(+), 21 deletions(-) --- a/kernel/futex.c +++ b/kernel/futex.c -@@ -2013,6 +2013,16 @@ static int futex_requeue(u32 __user *uad +@@ -2024,6 +2024,16 @@ static int futex_requeue(u32 __user *uad requeue_pi_wake_futex(this, &key2, hb2); drop_count++; continue; @@ -32,7 +32,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } else if (ret) { /* * rt_mutex_start_proxy_lock() detected a -@@ -2996,7 +3006,7 @@ static int futex_wait_requeue_pi(u32 __u +@@ -3007,7 +3017,7 @@ static int futex_wait_requeue_pi(u32 __u struct hrtimer_sleeper timeout, *to = NULL; struct futex_pi_state *pi_state = NULL; struct rt_mutex_waiter rt_waiter; @@ -41,7 +41,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> union futex_key key2 = FUTEX_KEY_INIT; struct futex_q q = futex_q_init; int res, ret; -@@ -3051,20 +3061,55 @@ static int futex_wait_requeue_pi(u32 __u +@@ -3062,20 +3072,55 @@ static int futex_wait_requeue_pi(u32 __u /* Queue the futex_q, drop the hb lock, wait for wakeup. */ futex_wait_queue_me(hb, &q, to); @@ -108,7 +108,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* Check if the requeue code acquired the second futex for us. */ if (!q.rt_waiter) { -@@ -3073,7 +3118,8 @@ static int futex_wait_requeue_pi(u32 __u +@@ -3084,7 +3129,8 @@ static int futex_wait_requeue_pi(u32 __u * did a lock-steal - fix up the PI-state in that case. */ if (q.pi_state && (q.pi_state->owner != current)) { @@ -118,7 +118,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> ret = fixup_pi_state_owner(uaddr2, &q, current); if (ret && rt_mutex_owner(&q.pi_state->pi_mutex) == current) { pi_state = q.pi_state; -@@ -3084,7 +3130,7 @@ static int futex_wait_requeue_pi(u32 __u +@@ -3095,7 +3141,7 @@ static int futex_wait_requeue_pi(u32 __u * the requeue_pi() code acquired for us. */ put_pi_state(q.pi_state); @@ -127,7 +127,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } } else { struct rt_mutex *pi_mutex; -@@ -3098,7 +3144,8 @@ static int futex_wait_requeue_pi(u32 __u +@@ -3109,7 +3155,8 @@ static int futex_wait_requeue_pi(u32 __u pi_mutex = &q.pi_state->pi_mutex; ret = rt_mutex_wait_proxy_lock(pi_mutex, to, &rt_waiter); @@ -170,11 +170,10 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> goto out_unlock_pi; /* -@@ -963,6 +969,23 @@ static int task_blocks_on_rt_mutex(struc +@@ -963,6 +969,22 @@ static int task_blocks_on_rt_mutex(struc return -EDEADLK; raw_spin_lock(&task->pi_lock); -+ + /* + * In the case of futex requeue PI, this will be a proxy + * lock. The task will wake unaware that it is enqueueed on @@ -189,12 +188,12 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + return -EAGAIN; + } + -+ BUG_ON(rt_mutex_real_waiter(task->pi_blocked_on)); ++ BUG_ON(rt_mutex_real_waiter(task->pi_blocked_on)); + - rt_mutex_adjust_prio(task); waiter->task = task; waiter->lock = lock; -@@ -987,7 +1010,7 @@ static int task_blocks_on_rt_mutex(struc + waiter->prio = task->prio; +@@ -986,7 +1008,7 @@ static int task_blocks_on_rt_mutex(struc rt_mutex_enqueue_pi(owner, waiter); rt_mutex_adjust_prio(owner); @@ -203,7 +202,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> chain_walk = 1; } else if (rt_mutex_cond_detect_deadlock(waiter, chwalk)) { chain_walk = 1; -@@ -1083,7 +1106,7 @@ static void remove_waiter(struct rt_mute +@@ -1082,7 +1104,7 @@ static void remove_waiter(struct rt_mute { bool is_top_waiter = (waiter == rt_mutex_top_waiter(lock)); struct task_struct *owner = rt_mutex_owner(lock); @@ -212,7 +211,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> lockdep_assert_held(&lock->wait_lock); -@@ -1109,7 +1132,8 @@ static void remove_waiter(struct rt_mute +@@ -1108,7 +1130,8 @@ static void remove_waiter(struct rt_mute rt_mutex_adjust_prio(owner); /* Store the lock on which owner is blocked or NULL */ @@ -222,7 +221,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> raw_spin_unlock(&owner->pi_lock); -@@ -1145,7 +1169,8 @@ void rt_mutex_adjust_pi(struct task_stru +@@ -1144,7 +1167,8 @@ void rt_mutex_adjust_pi(struct task_stru raw_spin_lock_irqsave(&task->pi_lock, flags); waiter = task->pi_blocked_on; diff --git a/patches/rtmutex-lock-killable.patch b/patches/rtmutex-lock-killable.patch index cbda846a4f32..77e42285f528 100644 --- a/patches/rtmutex-lock-killable.patch +++ b/patches/rtmutex-lock-killable.patch @@ -13,7 +13,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/include/linux/rtmutex.h +++ b/include/linux/rtmutex.h -@@ -91,6 +91,7 @@ extern void rt_mutex_destroy(struct rt_m +@@ -108,6 +108,7 @@ extern void rt_mutex_destroy(struct rt_m extern void rt_mutex_lock(struct rt_mutex *lock); extern int rt_mutex_lock_interruptible(struct rt_mutex *lock); @@ -23,7 +23,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c -@@ -1537,6 +1537,25 @@ int __sched rt_mutex_futex_trylock(struc +@@ -1543,6 +1543,25 @@ int __sched rt_mutex_futex_trylock(struc } /** diff --git a/patches/rtmutex-trylock-is-okay-on-RT.patch b/patches/rtmutex-trylock-is-okay-on-RT.patch index cfa95fd2df38..55da027d3868 100644 --- a/patches/rtmutex-trylock-is-okay-on-RT.patch +++ b/patches/rtmutex-trylock-is-okay-on-RT.patch @@ -13,10 +13,10 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c -@@ -1547,7 +1547,11 @@ EXPORT_SYMBOL_GPL(rt_mutex_timed_lock); - */ - int __sched rt_mutex_trylock(struct rt_mutex *lock) +@@ -1563,7 +1563,11 @@ int __sched rt_mutex_trylock(struct rt_m { + int ret; + +#ifdef CONFIG_PREEMPT_RT_FULL + if (WARN_ON_ONCE(in_irq() || in_nmi())) +#else @@ -24,4 +24,4 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +#endif return 0; - return rt_mutex_fasttrylock(lock, rt_mutex_slowtrylock); + ret = rt_mutex_fasttrylock(lock, rt_mutex_slowtrylock); diff --git a/patches/rtmutex-wire-up-RT-s-locking.patch b/patches/rtmutex-wire-up-RT-s-locking.patch new file mode 100644 index 000000000000..201b93a02eb8 --- /dev/null +++ b/patches/rtmutex-wire-up-RT-s-locking.patch @@ -0,0 +1,248 @@ +From: Thomas Gleixner <tglx@linutronix.de> +Date: Thu, 12 Oct 2017 17:31:14 +0200 +Subject: rtmutex: wire up RT's locking + +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + include/linux/mutex.h | 20 +++++++++++++------- + include/linux/rwsem.h | 11 +++++++++++ + include/linux/spinlock.h | 12 +++++++++++- + include/linux/spinlock_api_smp.h | 4 +++- + include/linux/spinlock_types.h | 11 ++++++++--- + kernel/locking/Makefile | 9 ++++++++- + kernel/locking/spinlock.c | 7 +++++++ + kernel/locking/spinlock_debug.c | 5 +++++ + 8 files changed, 66 insertions(+), 13 deletions(-) + +--- a/include/linux/mutex.h ++++ b/include/linux/mutex.h +@@ -22,6 +22,17 @@ + + struct ww_acquire_ctx; + ++#ifdef CONFIG_DEBUG_LOCK_ALLOC ++# define __DEP_MAP_MUTEX_INITIALIZER(lockname) \ ++ , .dep_map = { .name = #lockname } ++#else ++# define __DEP_MAP_MUTEX_INITIALIZER(lockname) ++#endif ++ ++#ifdef CONFIG_PREEMPT_RT_FULL ++# include <linux/mutex_rt.h> ++#else ++ + /* + * Simple, straightforward mutexes with strict semantics: + * +@@ -113,13 +124,6 @@ do { \ + __mutex_init((mutex), #mutex, &__key); \ + } while (0) + +-#ifdef CONFIG_DEBUG_LOCK_ALLOC +-# define __DEP_MAP_MUTEX_INITIALIZER(lockname) \ +- , .dep_map = { .name = #lockname } +-#else +-# define __DEP_MAP_MUTEX_INITIALIZER(lockname) +-#endif +- + #define __MUTEX_INITIALIZER(lockname) \ + { .owner = ATOMIC_LONG_INIT(0) \ + , .wait_lock = __SPIN_LOCK_UNLOCKED(lockname.wait_lock) \ +@@ -227,4 +231,6 @@ mutex_trylock_recursive(struct mutex *lo + return mutex_trylock(lock); + } + ++#endif /* !PREEMPT_RT_FULL */ ++ + #endif /* __LINUX_MUTEX_H */ +--- a/include/linux/rwsem.h ++++ b/include/linux/rwsem.h +@@ -19,6 +19,10 @@ + #include <linux/osq_lock.h> + #endif + ++#ifdef CONFIG_PREEMPT_RT_FULL ++#include <linux/rwsem_rt.h> ++#else /* PREEMPT_RT_FULL */ ++ + struct rw_semaphore; + + #ifdef CONFIG_RWSEM_GENERIC_SPINLOCK +@@ -106,6 +110,13 @@ static inline int rwsem_is_contended(str + return !list_empty(&sem->wait_list); + } + ++#endif /* !PREEMPT_RT_FULL */ ++ ++/* ++ * The functions below are the same for all rwsem implementations including ++ * the RT specific variant. ++ */ ++ + /* + * lock for reading + */ +--- a/include/linux/spinlock.h ++++ b/include/linux/spinlock.h +@@ -268,7 +268,11 @@ static inline void do_raw_spin_unlock(ra + #define raw_spin_can_lock(lock) (!raw_spin_is_locked(lock)) + + /* Include rwlock functions */ +-#include <linux/rwlock.h> ++#ifdef CONFIG_PREEMPT_RT_FULL ++# include <linux/rwlock_rt.h> ++#else ++# include <linux/rwlock.h> ++#endif + + /* + * Pull the _spin_*()/_read_*()/_write_*() functions/declarations: +@@ -279,6 +283,10 @@ static inline void do_raw_spin_unlock(ra + # include <linux/spinlock_api_up.h> + #endif + ++#ifdef CONFIG_PREEMPT_RT_FULL ++# include <linux/spinlock_rt.h> ++#else /* PREEMPT_RT_FULL */ ++ + /* + * Map the spin_lock functions to the raw variants for PREEMPT_RT=n + */ +@@ -428,4 +436,6 @@ extern int _atomic_dec_and_lock(atomic_t + #define atomic_dec_and_lock(atomic, lock) \ + __cond_lock(lock, _atomic_dec_and_lock(atomic, lock)) + ++#endif /* !PREEMPT_RT_FULL */ ++ + #endif /* __LINUX_SPINLOCK_H */ +--- a/include/linux/spinlock_api_smp.h ++++ b/include/linux/spinlock_api_smp.h +@@ -187,6 +187,8 @@ static inline int __raw_spin_trylock_bh( + return 0; + } + +-#include <linux/rwlock_api_smp.h> ++#ifndef CONFIG_PREEMPT_RT_FULL ++# include <linux/rwlock_api_smp.h> ++#endif + + #endif /* __LINUX_SPINLOCK_API_SMP_H */ +--- a/include/linux/spinlock_types.h ++++ b/include/linux/spinlock_types.h +@@ -11,8 +11,13 @@ + + #include <linux/spinlock_types_raw.h> + +-#include <linux/spinlock_types_nort.h> +- +-#include <linux/rwlock_types.h> ++#ifndef CONFIG_PREEMPT_RT_FULL ++# include <linux/spinlock_types_nort.h> ++# include <linux/rwlock_types.h> ++#else ++# include <linux/rtmutex.h> ++# include <linux/spinlock_types_rt.h> ++# include <linux/rwlock_types_rt.h> ++#endif + + #endif /* __LINUX_SPINLOCK_TYPES_H */ +--- a/kernel/locking/Makefile ++++ b/kernel/locking/Makefile +@@ -2,7 +2,7 @@ + # and is generally not a function of system call inputs. + KCOV_INSTRUMENT := n + +-obj-y += mutex.o semaphore.o rwsem.o percpu-rwsem.o ++obj-y += semaphore.o percpu-rwsem.o + + ifdef CONFIG_FUNCTION_TRACER + CFLAGS_REMOVE_lockdep.o = $(CC_FLAGS_FTRACE) +@@ -11,7 +11,11 @@ CFLAGS_REMOVE_mutex-debug.o = $(CC_FLAGS + CFLAGS_REMOVE_rtmutex-debug.o = $(CC_FLAGS_FTRACE) + endif + ++ifneq ($(CONFIG_PREEMPT_RT_FULL),y) ++obj-y += mutex.o + obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o ++endif ++obj-y += rwsem.o + obj-$(CONFIG_LOCKDEP) += lockdep.o + ifeq ($(CONFIG_PROC_FS),y) + obj-$(CONFIG_LOCKDEP) += lockdep_proc.o +@@ -24,8 +28,11 @@ obj-$(CONFIG_RT_MUTEXES) += rtmutex.o + obj-$(CONFIG_DEBUG_RT_MUTEXES) += rtmutex-debug.o + obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o + obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o ++ifneq ($(CONFIG_PREEMPT_RT_FULL),y) + obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o + obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem-xadd.o ++endif ++obj-$(CONFIG_PREEMPT_RT_FULL) += mutex-rt.o rwsem-rt.o rwlock-rt.o + obj-$(CONFIG_QUEUED_RWLOCKS) += qrwlock.o + obj-$(CONFIG_LOCK_TORTURE_TEST) += locktorture.o + obj-$(CONFIG_WW_MUTEX_SELFTEST) += test-ww_mutex.o +--- a/kernel/locking/spinlock.c ++++ b/kernel/locking/spinlock.c +@@ -124,8 +124,11 @@ void __lockfunc __raw_##op##_lock_bh(loc + * __[spin|read|write]_lock_bh() + */ + BUILD_LOCK_OPS(spin, raw_spinlock); ++ ++#ifndef CONFIG_PREEMPT_RT_FULL + BUILD_LOCK_OPS(read, rwlock); + BUILD_LOCK_OPS(write, rwlock); ++#endif + + #endif + +@@ -209,6 +212,8 @@ void __lockfunc _raw_spin_unlock_bh(raw_ + EXPORT_SYMBOL(_raw_spin_unlock_bh); + #endif + ++#ifndef CONFIG_PREEMPT_RT_FULL ++ + #ifndef CONFIG_INLINE_READ_TRYLOCK + int __lockfunc _raw_read_trylock(rwlock_t *lock) + { +@@ -353,6 +358,8 @@ void __lockfunc _raw_write_unlock_bh(rwl + EXPORT_SYMBOL(_raw_write_unlock_bh); + #endif + ++#endif /* !PREEMPT_RT_FULL */ ++ + #ifdef CONFIG_DEBUG_LOCK_ALLOC + + void __lockfunc _raw_spin_lock_nested(raw_spinlock_t *lock, int subclass) +--- a/kernel/locking/spinlock_debug.c ++++ b/kernel/locking/spinlock_debug.c +@@ -31,6 +31,7 @@ void __raw_spin_lock_init(raw_spinlock_t + + EXPORT_SYMBOL(__raw_spin_lock_init); + ++#ifndef CONFIG_PREEMPT_RT_FULL + void __rwlock_init(rwlock_t *lock, const char *name, + struct lock_class_key *key) + { +@@ -48,6 +49,7 @@ void __rwlock_init(rwlock_t *lock, const + } + + EXPORT_SYMBOL(__rwlock_init); ++#endif + + static void spin_dump(raw_spinlock_t *lock, const char *msg) + { +@@ -135,6 +137,7 @@ void do_raw_spin_unlock(raw_spinlock_t * + arch_spin_unlock(&lock->raw_lock); + } + ++#ifndef CONFIG_PREEMPT_RT_FULL + static void rwlock_bug(rwlock_t *lock, const char *msg) + { + if (!debug_locks_off()) +@@ -224,3 +227,5 @@ void do_raw_write_unlock(rwlock_t *lock) + debug_write_unlock(lock); + arch_write_unlock(&lock->raw_lock); + } ++ ++#endif diff --git a/patches/rtmutex_dont_include_rcu.patch b/patches/rtmutex_dont_include_rcu.patch index 2cbfd2fd83cb..e9bd19e7e460 100644 --- a/patches/rtmutex_dont_include_rcu.patch +++ b/patches/rtmutex_dont_include_rcu.patch @@ -93,15 +93,15 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +#endif --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h -@@ -45,6 +45,7 @@ - #include <linux/compiler.h> - #include <linux/ktime.h> - #include <linux/irqflags.h> +@@ -42,6 +42,7 @@ + #include <linux/lockdep.h> + #include <asm/processor.h> + #include <linux/cpumask.h> +#include <linux/rcu_assign_pointer.h> - #include <asm/barrier.h> - -@@ -593,54 +594,6 @@ static inline void rcu_preempt_sleep_che + #define ULONG_CMP_GE(a, b) (ULONG_MAX / 2 >= (a) - (b)) + #define ULONG_CMP_LT(a, b) (ULONG_MAX / 2 < (a) - (b)) +@@ -367,54 +368,6 @@ static inline void rcu_preempt_sleep_che }) /** diff --git a/patches/sched-Prevent-task-state-corruption-by-spurious-lock.patch b/patches/sched-Prevent-task-state-corruption-by-spurious-lock.patch index 3b023c4f240e..84e70e764848 100644 --- a/patches/sched-Prevent-task-state-corruption-by-spurious-lock.patch +++ b/patches/sched-Prevent-task-state-corruption-by-spurious-lock.patch @@ -66,7 +66,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -2205,7 +2205,7 @@ EXPORT_SYMBOL(wake_up_process); +@@ -2198,7 +2198,7 @@ EXPORT_SYMBOL(wake_up_process); */ int wake_up_lock_sleeper(struct task_struct *p) { diff --git a/patches/sched-clock-Initialize-all-per-CPU-state-before-swit.patch b/patches/sched-clock-Initialize-all-per-CPU-state-before-swit.patch deleted file mode 100644 index 30a598e48ada..000000000000 --- a/patches/sched-clock-Initialize-all-per-CPU-state-before-swit.patch +++ /dev/null @@ -1,120 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Fri, 21 Apr 2017 12:11:53 +0200 -Subject: [PATCH] sched/clock: Initialize all per-CPU state before switching - (back) to unstable - -commit cf15ca8deda86b27b66e27848b4b0fe58098fc0b upstream. - -In preparation for not keeping the sched_clock_tick() active for -stable TSC, we need to explicitly initialize all per-CPU state -before switching back to unstable. - -Note: this patch looses the __gtod_offset calculation; it will be -restored in the next one. - -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: Linus Torvalds <torvalds@linux-foundation.org> -Cc: Mike Galbraith <efault@gmx.de> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Thomas Gleixner <tglx@linutronix.de> -Cc: linux-kernel@vger.kernel.org -Signed-off-by: Ingo Molnar <mingo@kernel.org> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/sched/clock.c | 60 +++++++++++++++++++++++++++++++++------------------ - 1 file changed, 39 insertions(+), 21 deletions(-) - ---- a/kernel/sched/clock.c -+++ b/kernel/sched/clock.c -@@ -124,6 +124,12 @@ int sched_clock_stable(void) - return static_branch_likely(&__sched_clock_stable); - } - -+static void __scd_stamp(struct sched_clock_data *scd) -+{ -+ scd->tick_gtod = ktime_get_ns(); -+ scd->tick_raw = sched_clock(); -+} -+ - static void __set_sched_clock_stable(void) - { - struct sched_clock_data *scd = this_scd(); -@@ -141,8 +147,37 @@ static void __set_sched_clock_stable(voi - tick_dep_clear(TICK_DEP_BIT_CLOCK_UNSTABLE); - } - -+/* -+ * If we ever get here, we're screwed, because we found out -- typically after -+ * the fact -- that TSC wasn't good. This means all our clocksources (including -+ * ktime) could have reported wrong values. -+ * -+ * What we do here is an attempt to fix up and continue sort of where we left -+ * off in a coherent manner. -+ * -+ * The only way to fully avoid random clock jumps is to boot with: -+ * "tsc=unstable". -+ */ - static void __sched_clock_work(struct work_struct *work) - { -+ struct sched_clock_data *scd; -+ int cpu; -+ -+ /* take a current timestamp and set 'now' */ -+ preempt_disable(); -+ scd = this_scd(); -+ __scd_stamp(scd); -+ scd->clock = scd->tick_gtod + __gtod_offset; -+ preempt_enable(); -+ -+ /* clone to all CPUs */ -+ for_each_possible_cpu(cpu) -+ per_cpu(sched_clock_data, cpu) = *scd; -+ -+ printk(KERN_INFO "sched_clock: Marking unstable (%lld, %lld)<-(%lld, %lld)\n", -+ scd->tick_gtod, __gtod_offset, -+ scd->tick_raw, __sched_clock_offset); -+ - static_branch_disable(&__sched_clock_stable); - } - -@@ -150,27 +185,11 @@ static DECLARE_WORK(sched_clock_work, __ - - static void __clear_sched_clock_stable(void) - { -- struct sched_clock_data *scd = this_scd(); -- -- /* -- * Attempt to make the stable->unstable transition continuous. -- * -- * Trouble is, this is typically called from the TSC watchdog -- * timer, which is late per definition. This means the tick -- * values can already be screwy. -- * -- * Still do what we can. -- */ -- __gtod_offset = (scd->tick_raw + __sched_clock_offset) - (scd->tick_gtod); -- -- printk(KERN_INFO "sched_clock: Marking unstable (%lld, %lld)<-(%lld, %lld)\n", -- scd->tick_gtod, __gtod_offset, -- scd->tick_raw, __sched_clock_offset); -+ if (!sched_clock_stable()) -+ return; - - tick_dep_set(TICK_DEP_BIT_CLOCK_UNSTABLE); -- -- if (sched_clock_stable()) -- schedule_work(&sched_clock_work); -+ schedule_work(&sched_clock_work); - } - - void clear_sched_clock_stable(void) -@@ -357,8 +376,7 @@ void sched_clock_tick(void) - * XXX arguably we can skip this if we expose tsc_clocksource_reliable - */ - scd = this_scd(); -- scd->tick_raw = sched_clock(); -- scd->tick_gtod = ktime_get_ns(); -+ __scd_stamp(scd); - - if (!sched_clock_stable() && likely(sched_clock_running)) - sched_clock_local(scd); diff --git a/patches/sched-debug-Inform-the-number-of-rt-dl-task-that-can.patch b/patches/sched-debug-Inform-the-number-of-rt-dl-task-that-can.patch deleted file mode 100644 index 0ca8e3971542..000000000000 --- a/patches/sched-debug-Inform-the-number-of-rt-dl-task-that-can.patch +++ /dev/null @@ -1,83 +0,0 @@ -From: Daniel Bristot de Oliveira <bristot@redhat.com> -Date: Mon, 26 Jun 2017 17:07:14 +0200 -Subject: sched/debug: Inform the number of rt/dl task that can migrate - -Add the value of the rt_rq.rt_nr_migratory and dl_rq.dl_nr_migratory -to the sched_debug output, for instance: - -rt_rq[0]: - .rt_nr_running : 2 - .rt_nr_migratory : 1 <--- Like this - .rt_throttled : 0 - .rt_time : 828.645877 - .rt_runtime : 1000.000000 - -This is useful to debug problems related to the dl/rt schedulers. - -This also fixes the format of some variables, that were unsigned, rather -than signed. - -Signed-off-by: Daniel Bristot de Oliveira <bristot@redhat.com> -Cc: Luis Claudio R. Goncalves <lgoncalv@redhat.com> -Cc: Clark Williams <williams@redhat.com> -Cc: Luiz Capitulino <lcapitulino@redhat.com> -Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Cc: Thomas Gleixner <tglx@linutronix.de> -Cc: Steven Rostedt <rostedt@goodmis.org> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Ingo Molnar <mingo@kernel.org> -Cc: LKML <linux-kernel@vger.kernel.org> -Cc: linux-rt-users <linux-rt-users@vger.kernel.org> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/sched/debug.c | 17 +++++++++++++++-- - 1 file changed, 15 insertions(+), 2 deletions(-) - ---- a/kernel/sched/debug.c -+++ b/kernel/sched/debug.c -@@ -552,15 +552,21 @@ void print_rt_rq(struct seq_file *m, int - - #define P(x) \ - SEQ_printf(m, " .%-30s: %Ld\n", #x, (long long)(rt_rq->x)) -+#define PU(x) \ -+ SEQ_printf(m, " .%-30s: %lu\n", #x, (unsigned long)(rt_rq->x)) - #define PN(x) \ - SEQ_printf(m, " .%-30s: %Ld.%06ld\n", #x, SPLIT_NS(rt_rq->x)) - -- P(rt_nr_running); -+ PU(rt_nr_running); -+#ifdef CONFIG_SMP -+ PU(rt_nr_migratory); -+#endif - P(rt_throttled); - PN(rt_time); - PN(rt_runtime); - - #undef PN -+#undef PU - #undef P - } - -@@ -569,14 +575,21 @@ void print_dl_rq(struct seq_file *m, int - struct dl_bw *dl_bw; - - SEQ_printf(m, "\ndl_rq[%d]:\n", cpu); -- SEQ_printf(m, " .%-30s: %ld\n", "dl_nr_running", dl_rq->dl_nr_running); -+ -+#define PU(x) \ -+ SEQ_printf(m, " .%-30s: %lu\n", #x, (unsigned long)(dl_rq->x)) -+ -+ PU(dl_nr_running); - #ifdef CONFIG_SMP -+ PU(dl_nr_migratory); - dl_bw = &cpu_rq(cpu)->rd->dl_bw; - #else - dl_bw = &dl_rq->dl_bw; - #endif - SEQ_printf(m, " .%-30s: %lld\n", "dl_bw->bw", dl_bw->bw); - SEQ_printf(m, " .%-30s: %lld\n", "dl_bw->total_bw", dl_bw->total_bw); -+ -+#undef PU - } - - extern __read_mostly int sched_clock_running; diff --git a/patches/sched-delay-put-task.patch b/patches/sched-delay-put-task.patch index 38f628b5dfca..8f7709b6b478 100644 --- a/patches/sched-delay-put-task.patch +++ b/patches/sched-delay-put-task.patch @@ -8,13 +8,13 @@ burden random tasks with that. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- include/linux/sched.h | 3 +++ - include/linux/sched/task.h | 10 ++++++++++ + include/linux/sched/task.h | 11 ++++++++++- kernel/fork.c | 15 ++++++++++++++- - 3 files changed, 27 insertions(+), 1 deletion(-) + 3 files changed, 27 insertions(+), 2 deletions(-) --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -1047,6 +1047,9 @@ struct task_struct { +@@ -1082,6 +1082,9 @@ struct task_struct { unsigned int sequential_io; unsigned int sequential_io_avg; #endif @@ -26,7 +26,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #endif --- a/include/linux/sched/task.h +++ b/include/linux/sched/task.h -@@ -86,6 +86,15 @@ extern void sched_exec(void); +@@ -88,6 +88,15 @@ extern void sched_exec(void); #define get_task_struct(tsk) do { atomic_inc(&(tsk)->usage); } while(0) @@ -42,17 +42,18 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> extern void __put_task_struct(struct task_struct *t); static inline void put_task_struct(struct task_struct *t) -@@ -93,6 +102,7 @@ static inline void put_task_struct(struc +@@ -95,7 +104,7 @@ static inline void put_task_struct(struc if (atomic_dec_and_test(&t->usage)) __put_task_struct(t); } +- +#endif - struct task_struct *task_rcu_dereference(struct task_struct **ptask); - struct task_struct *try_get_task_struct(struct task_struct **ptask); + + #ifdef CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -389,7 +389,9 @@ static inline void put_signal_struct(str +@@ -402,7 +402,9 @@ static inline void put_signal_struct(str if (atomic_dec_and_test(&sig->sigcnt)) free_signal_struct(sig); } @@ -63,7 +64,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> void __put_task_struct(struct task_struct *tsk) { WARN_ON(!tsk->exit_state); -@@ -406,7 +408,18 @@ void __put_task_struct(struct task_struc +@@ -419,7 +421,18 @@ void __put_task_struct(struct task_struc if (!profile_handoff_task(tsk)) free_task(tsk); } diff --git a/patches/sched-disable-rt-group-sched-on-rt.patch b/patches/sched-disable-rt-group-sched-on-rt.patch index ba61099d6e13..b99d7c6fb838 100644 --- a/patches/sched-disable-rt-group-sched-on-rt.patch +++ b/patches/sched-disable-rt-group-sched-on-rt.patch @@ -18,7 +18,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/init/Kconfig +++ b/init/Kconfig -@@ -1052,6 +1052,7 @@ config CFS_BANDWIDTH +@@ -744,6 +744,7 @@ config CFS_BANDWIDTH config RT_GROUP_SCHED bool "Group scheduling for SCHED_RR/FIFO" depends on CGROUP_SCHED diff --git a/patches/sched-limit-nr-migrate.patch b/patches/sched-limit-nr-migrate.patch index dc639213105c..18bdc4601d39 100644 --- a/patches/sched-limit-nr-migrate.patch +++ b/patches/sched-limit-nr-migrate.patch @@ -12,7 +12,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -58,7 +58,11 @@ const_debug unsigned int sysctl_sched_fe +@@ -59,7 +59,11 @@ const_debug unsigned int sysctl_sched_fe * Number of tasks to iterate in a single balance run. * Limited because this is done with IRQs disabled. */ diff --git a/patches/sched-might-sleep-do-not-account-rcu-depth.patch b/patches/sched-might-sleep-do-not-account-rcu-depth.patch index cfd979ca4872..c40bff6072bd 100644 --- a/patches/sched-might-sleep-do-not-account-rcu-depth.patch +++ b/patches/sched-might-sleep-do-not-account-rcu-depth.patch @@ -13,7 +13,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h -@@ -261,6 +261,11 @@ void synchronize_rcu(void); +@@ -76,6 +76,11 @@ void synchronize_rcu(void); * types of kernel builds, the rcu_read_lock() nesting depth is unknowable. */ #define rcu_preempt_depth() (current->rcu_read_lock_nesting) @@ -25,7 +25,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #else /* #ifdef CONFIG_PREEMPT_RCU */ -@@ -286,6 +291,8 @@ static inline int rcu_preempt_depth(void +@@ -101,6 +106,8 @@ static inline int rcu_preempt_depth(void return 0; } @@ -36,7 +36,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* Internal to kernel */ --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -6270,7 +6270,7 @@ void __init sched_init(void) +@@ -6006,7 +6006,7 @@ void __init sched_init(void) #ifdef CONFIG_DEBUG_ATOMIC_SLEEP static inline int preempt_count_equals(int preempt_offset) { diff --git a/patches/sched-mmdrop-delayed.patch b/patches/sched-mmdrop-delayed.patch index e95dd5aaf02e..a4d581afb61a 100644 --- a/patches/sched-mmdrop-delayed.patch +++ b/patches/sched-mmdrop-delayed.patch @@ -23,8 +23,8 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #include <linux/page-flags-layout.h> #include <linux/workqueue.h> -@@ -491,6 +492,9 @@ struct mm_struct { - bool tlb_flush_pending; +@@ -498,6 +499,9 @@ struct mm_struct { + bool tlb_flush_batched; #endif struct uprobes_state uprobes_state; +#ifdef CONFIG_PREEMPT_RT_BASE @@ -55,7 +55,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> struct mm_struct *mm = container_of(work, struct mm_struct, async_put_work); --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -885,6 +885,19 @@ void __mmdrop(struct mm_struct *mm) +@@ -915,6 +915,19 @@ void __mmdrop(struct mm_struct *mm) } EXPORT_SYMBOL_GPL(__mmdrop); @@ -77,7 +77,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> VM_BUG_ON(atomic_read(&mm->mm_users)); --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -2784,8 +2784,12 @@ static struct rq *finish_task_switch(str +@@ -2677,8 +2677,12 @@ static struct rq *finish_task_switch(str finish_arch_post_lock_switch(); fire_sched_in_preempt_notifiers(current); @@ -91,7 +91,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> if (unlikely(prev_state == TASK_DEAD)) { if (prev->sched_class->task_dead) prev->sched_class->task_dead(prev); -@@ -5611,6 +5615,8 @@ void sched_setnuma(struct task_struct *p +@@ -5390,6 +5394,8 @@ void sched_setnuma(struct task_struct *p #endif /* CONFIG_NUMA_BALANCING */ #ifdef CONFIG_HOTPLUG_CPU @@ -100,7 +100,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * Ensure that the idle task is using init_mm right before its CPU goes * offline. -@@ -5625,7 +5631,12 @@ void idle_task_exit(void) +@@ -5404,7 +5410,12 @@ void idle_task_exit(void) switch_mm(mm, &init_mm, current); finish_arch_post_lock_switch(); } @@ -114,7 +114,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } /* -@@ -5952,6 +5963,10 @@ int sched_cpu_dying(unsigned int cpu) +@@ -5707,6 +5718,10 @@ int sched_cpu_dying(unsigned int cpu) update_max_interval(); nohz_balance_exit_idle(cpu); hrtick_clear(rq); diff --git a/patches/sched-rt-mutex-wakeup.patch b/patches/sched-rt-mutex-wakeup.patch index ad8c997cdb11..c01c4cfb1d40 100644 --- a/patches/sched-rt-mutex-wakeup.patch +++ b/patches/sched-rt-mutex-wakeup.patch @@ -17,16 +17,16 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -490,6 +490,8 @@ struct task_struct { +@@ -526,6 +526,8 @@ struct task_struct { #endif /* -1 unrunnable, 0 runnable, >0 stopped: */ volatile long state; + /* saved state for "spinlock sleepers" */ + volatile long saved_state; - void *stack; - atomic_t usage; - /* Per task flags (PF_*), defined further below: */ -@@ -1420,6 +1422,7 @@ extern struct task_struct *find_task_by_ + + /* + * This begins the randomizable portion of task_struct. Only +@@ -1466,6 +1468,7 @@ extern struct task_struct *find_task_by_ extern int wake_up_state(struct task_struct *tsk, unsigned int state); extern int wake_up_process(struct task_struct *tsk); @@ -36,7 +36,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #ifdef CONFIG_SMP --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -2012,8 +2012,25 @@ try_to_wake_up(struct task_struct *p, un +@@ -2007,8 +2007,25 @@ try_to_wake_up(struct task_struct *p, un */ smp_mb__before_spinlock(); raw_spin_lock_irqsave(&p->pi_lock, flags); @@ -63,7 +63,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> trace_sched_waking(p); -@@ -2179,6 +2196,18 @@ int wake_up_process(struct task_struct * +@@ -2172,6 +2189,18 @@ int wake_up_process(struct task_struct * } EXPORT_SYMBOL(wake_up_process); @@ -84,7 +84,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return try_to_wake_up(p, state, 0); --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h -@@ -1293,6 +1293,7 @@ static inline void finish_lock_switch(st +@@ -1340,6 +1340,7 @@ static inline void finish_lock_switch(st #define WF_SYNC 0x01 /* waker goes to sleep after wakeup */ #define WF_FORK 0x02 /* child wakeup after fork */ #define WF_MIGRATED 0x4 /* internal use, task got migrated */ diff --git a/patches/sched-ttwu-ensure-success-return-is-correct.patch b/patches/sched-ttwu-ensure-success-return-is-correct.patch index e39bc8be6233..d384984c3f9b 100644 --- a/patches/sched-ttwu-ensure-success-return-is-correct.patch +++ b/patches/sched-ttwu-ensure-success-return-is-correct.patch @@ -20,7 +20,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -2019,8 +2019,10 @@ try_to_wake_up(struct task_struct *p, un +@@ -2014,8 +2014,10 @@ try_to_wake_up(struct task_struct *p, un * if the wakeup condition is true. */ if (!(wake_flags & WF_LOCK_SLEEPER)) { diff --git a/patches/sched-workqueue-Only-wake-up-idle-workers-if-not-blo.patch b/patches/sched-workqueue-Only-wake-up-idle-workers-if-not-blo.patch index 95e46ed209a1..55dbac74ecbf 100644 --- a/patches/sched-workqueue-Only-wake-up-idle-workers-if-not-blo.patch +++ b/patches/sched-workqueue-Only-wake-up-idle-workers-if-not-blo.patch @@ -23,7 +23,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -3473,8 +3473,10 @@ static void __sched notrace __schedule(b +@@ -3369,8 +3369,10 @@ static void __sched notrace __schedule(b * If a worker went to sleep, notify and ask workqueue * whether it wants to wake up a task to maintain * concurrency. diff --git a/patches/scsi-fcoe-rt-aware.patch b/patches/scsi-fcoe-rt-aware.patch index 8742dafd9443..f5f4bd62d894 100644 --- a/patches/scsi-fcoe-rt-aware.patch +++ b/patches/scsi-fcoe-rt-aware.patch @@ -70,7 +70,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c -@@ -836,7 +836,7 @@ static unsigned long fcoe_ctlr_age_fcfs( +@@ -835,7 +835,7 @@ static unsigned long fcoe_ctlr_age_fcfs( INIT_LIST_HEAD(&del_list); @@ -79,7 +79,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> list_for_each_entry_safe(fcf, next, &fip->fcfs, list) { deadline = fcf->time + fcf->fka_period + fcf->fka_period / 2; -@@ -872,7 +872,7 @@ static unsigned long fcoe_ctlr_age_fcfs( +@@ -871,7 +871,7 @@ static unsigned long fcoe_ctlr_age_fcfs( sel_time = fcf->time; } } diff --git a/patches/seqlock-prevent-rt-starvation.patch b/patches/seqlock-prevent-rt-starvation.patch index 82b410ab807c..4700d37a21d4 100644 --- a/patches/seqlock-prevent-rt-starvation.patch +++ b/patches/seqlock-prevent-rt-starvation.patch @@ -158,7 +158,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/include/net/neighbour.h +++ b/include/net/neighbour.h -@@ -446,7 +446,7 @@ static inline int neigh_hh_bridge(struct +@@ -449,7 +449,7 @@ static inline int neigh_hh_bridge(struct } #endif @@ -166,8 +166,8 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +static inline int neigh_hh_output(struct hh_cache *hh, struct sk_buff *skb) { unsigned int seq; - int hh_len; -@@ -470,7 +470,7 @@ static inline int neigh_hh_output(const + unsigned int hh_len; +@@ -473,7 +473,7 @@ static inline int neigh_hh_output(const static inline int neigh_output(struct neighbour *n, struct sk_buff *skb) { @@ -176,7 +176,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> if ((n->nud_state & NUD_CONNECTED) && hh->hh_len) return neigh_hh_output(hh, skb); -@@ -511,7 +511,7 @@ struct neighbour_cb { +@@ -514,7 +514,7 @@ struct neighbour_cb { #define NEIGH_CB(skb) ((struct neighbour_cb *)(skb)->cb) diff --git a/patches/series b/patches/series index 17eb43e9eef9..7c910bffd0c6 100644 --- a/patches/series +++ b/patches/series @@ -5,122 +5,15 @@ ############################################################ # UPSTREAM changes queued ############################################################ -sched-clock-Initialize-all-per-CPU-state-before-swit.patch -x86-tsc-sched-clock-clocksource-Use-clocksource-watc.patch +rcu-Suppress-lockdep-false-positive-boost_mtx-compla.patch ############################################################ # UPSTREAM FIXES, patches pending ############################################################ -timer-make-the-base-lock-raw.patch ############################################################ # Stuff broken upstream, patches submitted ############################################################ -lockdep-Handle-statically-initialized-PER_CPU-locks-.patch -lockdep-Fix-compilation-error-for-CONFIG_MODULES-and.patch -lockdep-Fix-per-cpu-static-objects.patch - -0001-futex-Cleanup-variable-names-for-futex_top_waiter.patch -0002-futex-Use-smp_store_release-in-mark_wake_futex.patch -0003-futex-Remove-rt_mutex_deadlock_account_.patch -0004-futex-rt_mutex-Provide-futex-specific-rt_mutex-API.patch -0005-futex-Change-locking-rules.patch -0006-futex-Cleanup-refcounting.patch -0007-futex-Rework-inconsistent-rt_mutex-futex_q-state.patch -0008-futex-Pull-rt_mutex_futex_unlock-out-from-under-hb-l.patch -0009-futex-rt_mutex-Introduce-rt_mutex_init_waiter.patch -0010-futex-rt_mutex-Restructure-rt_mutex_finish_proxy_loc.patch -0011-futex-Rework-futex_lock_pi-to-use-rt_mutex_-_proxy_l.patch -0012-futex-Futex_unlock_pi-determinism.patch -0013-futex-Drop-hb-lock-before-enqueueing-on-the-rtmutex.patch -0001-rtmutex-Deboost-before-waking-up-the-top-waiter.patch -0002-sched-rtmutex-deadline-Fix-a-PI-crash-for-deadline-t.patch -0003-sched-deadline-rtmutex-Dont-miss-the-dl_runtime-dl_p.patch -0004-rtmutex-Clean-up.patch -0005-sched-rtmutex-Refactor-rt_mutex_setprio.patch -0006-sched-tracing-Update-trace_sched_pi_setprio.patch -0007-rtmutex-Fix-PI-chain-order-integrity.patch -0008-rtmutex-Fix-more-prio-comparisons.patch -0009-rtmutex-Plug-preempt-count-leak-in-rt_mutex_futex_un.patch -0001-futex-Avoid-freeing-an-active-timer.patch -0002-futex-Fix-small-and-harmless-looking-inconsistencies.patch -0003-futex-Clarify-mark_wake_futex-memory-barrier-usage.patch -0004-MAINTAINERS-Add-FUTEX-SUBSYSTEM.patch -futex-rt_mutex-Fix-rt_mutex_cleanup_proxy_lock.patch - -arm64-cpufeature-don-t-use-mutex-in-bringup-path.patch -smp-hotplug-Move-unparking-of-percpu-threads-to-the-.patch - -### -# get_online_cpus() rework. -# cpus_allowed queue from sched/core -0001-ia64-topology-Remove-cpus_allowed-manipulation.patch -0002-workqueue-Provide-work_on_cpu_safe.patch -0003-ia64-salinfo-Replace-racy-task-affinity-logic.patch -0004-ia64-sn-hwperf-Replace-racy-task-affinity-logic.patch -0005-powerpc-smp-Replace-open-coded-task-affinity-logic.patch -0006-sparc-sysfs-Replace-racy-task-affinity-logic.patch -0007-ACPI-processor-Fix-error-handling-in-__acpi_processo.patch -0008-ACPI-processor-Replace-racy-task-affinity-logic.patch -0009-cpufreq-ia64-Replace-racy-task-affinity-logic.patch -0010-cpufreq-sh-Replace-racy-task-affinity-logic.patch -0011-cpufreq-sparc-us3-Replace-racy-task-affinity-logic.patch -0012-cpufreq-sparc-us2e-Replace-racy-task-affinity-logic.patch -0013-crypto-N2-Replace-racy-task-affinity-logic.patch - -# a few patches from tip's sched/core -0001-sched-clock-Fix-early-boot-preempt-assumption-in-__s.patch -0001-init-Pin-init-task-to-the-boot-CPU-initially.patch -0002-arm-Adjust-system_state-check.patch -0003-arm64-Adjust-system_state-check.patch -0004-x86-smp-Adjust-system_state-check.patch -0005-metag-Adjust-system_state-check.patch -0006-powerpc-Adjust-system_state-check.patch -0007-ACPI-Adjust-system_state-check.patch -0008-mm-Adjust-system_state-check.patch -0009-cpufreq-pasemi-Adjust-system_state-check.patch -0010-iommu-vt-d-Adjust-system_state-checks.patch -0012-async-Adjust-system_state-checks.patch -0013-extable-Adjust-system_state-checks.patch -0014-printk-Adjust-system_state-checks.patch -0015-mm-vmscan-Adjust-system_state-checks.patch -0016-init-Introduce-SYSTEM_SCHEDULING-state.patch -0017-sched-core-Enable-might_sleep-and-smp_processor_id-c.patch - -# recursive get_online_cpus() invocations from smp/hotplug -0001-cpu-hotplug-Provide-cpus_read-write_-un-lock.patch -0002-cpu-hotplug-Provide-lockdep_assert_cpus_held.patch -0003-cpu-hotplug-Provide-cpuhp_setup-remove_state-_nocall.patch -0004-cpu-hotplug-Add-__cpuhp_state_add_instance_cpuslocke.patch -0005-stop_machine-Provide-stop_machine_cpuslocked.patch -0006-padata-Make-padata_alloc-static.patch -0007-padata-Avoid-nested-calls-to-cpus_read_lock-in-pcryp.patch -0008-x86-mtrr-Remove-get_online_cpus-from-mtrr_save_state.patch -0009-cpufreq-Use-cpuhp_setup_state_nocalls_cpuslocked.patch -0010-KVM-PPC-Book3S-HV-Use-cpuhp_setup_state_nocalls_cpus.patch -0011-hwtracing-coresight-etm3x-Use-cpuhp_setup_state_noca.patch -0012-hwtracing-coresight-etm4x-Use-cpuhp_setup_state_noca.patch -0013-perf-x86-intel-cqm-Use-cpuhp_setup_state_cpuslocked.patch -0014-ARM-hw_breakpoint-Use-cpuhp_setup_state_cpuslocked.patch -0015-s390-kernel-Use-stop_machine_cpuslocked.patch -0016-powerpc-powernv-Use-stop_machine_cpuslocked.patch -0017-cpu-hotplug-Use-stop_machine_cpuslocked-in-takedown_.patch -0018-x86-perf-Drop-EXPORT-of-perf_check_microcode.patch -0019-perf-x86-intel-Drop-get_online_cpus-in-intel_snb_che.patch -0020-PCI-Use-cpu_hotplug_disable-instead-of-get_online_cp.patch -0021-PCI-Replace-the-racy-recursion-prevention.patch -0022-ACPI-processor-Use-cpu_hotplug_disable-instead-of-ge.patch -0023-perf-tracing-cpuhotplug-Fix-locking-order.patch -0024-jump_label-Reorder-hotplug-lock-and-jump_label_lock.patch -0025-kprobes-Cure-hotplug-lock-ordering-issues.patch -0026-arm64-Prevent-cpu-hotplug-rwsem-recursion.patch -0027-arm-Prevent-hotplug-rwsem-recursion.patch -0028-s390-Prevent-hotplug-rwsem-recursion.patch -0029-cpu-hotplug-Convert-hotplug-locking-to-percpu-rwsem.patch -0030-sched-Provide-is_percpu_thread-helper.patch -0031-acpi-processor-Prevent-cpu-hotplug-deadlock.patch -0032-cpuhotplug-Link-lock-stacks-for-hotplug-callbacks.patch -### # soft hrtimer patches (v1) 0001-hrtimer-Use-predefined-function-for-updating-next_ti.patch @@ -129,7 +22,6 @@ smp-hotplug-Move-unparking-of-percpu-threads-to-the-.patch 0004-hrtimer-Cleanup-clock-argument-in-schedule_hrtimeout.patch 0005-hrtimer-Switch-for-loop-to-_ffs-evaluation.patch 0006-hrtimer-Store-running-timer-in-hrtimer_clock_base.patch -hrtimer-Remove-hrtimer_peek_ahead_timers-leftovers.patch 0007-hrtimer-Reduce-conditional-code-hres_active.patch 0008-hrtimer-Reduce-conditional-code-expires_next-next_ti.patch 0009-hrtimer-Reduce-conditional-code-hrtimer_reprogram.patch @@ -162,12 +54,10 @@ rfc-arm-smp-__cpu_disable-fix-sleeping-function-called-from-invalid-context.patc ############################################################ rtmutex--Handle-non-enqueued-waiters-gracefully.patch rbtree-include-rcu.h-because-we-use-it.patch -fs-dcache-init-in_lookup_hashtable.patch -iommu-iova-don-t-disable-preempt-around-this_cpu_ptr.patch -iommu-vt-d-don-t-disable-preemption-while-accessing-.patch rxrpc-remove-unused-static-variables.patch -mm-swap-don-t-disable-preemption-while-taking-the-pe.patch cpu_pm-replace-raw_notifier-to-atomic_notifier.patch +mfd-syscon-atmel-smc-include-string.h.patch +pci-switchtec-Don-t-use-completion-s-wait-queue.patch # Wants a different fix for upstream NFSv4-replace-seqcount_t-with-a-seqlock_t.patch @@ -177,11 +67,15 @@ NFSv4-replace-seqcount_t-with-a-seqlock_t.patch ############################################################ Bluetooth-avoid-recursive-locking-in-hci_send_to_cha.patch iommu-amd-Use-raw_cpu_ptr-instead-of-get_cpu_ptr-for.patch +arm-xen-don-t-inclide-rwlock.h-directly.patch +greybus-audio-don-t-inclide-rwlock.h-directly.patch +xen-9pfs-don-t-inclide-rwlock.h-directly.patch # SPARC part of erly printk consolidation sparc64-use-generic-rwsem-spinlocks-rt.patch # SRCU +# XXX kernel-SRCU-provide-a-static-initializer.patch ############################################################ @@ -211,7 +105,6 @@ kernel-SRCU-provide-a-static-initializer.patch ############################################################ # Stuff which should go upstream ASAP ############################################################ -CPUFREQ-Loongson2-drop-set_cpus_allowed_ptr.patch kernel-sched-Provide-a-pointer-to-the-valid-CPU-mask.patch add_migrate_disable.patch @@ -222,7 +115,6 @@ add_migrate_disable.patch 0004-tracing-Add-hist_field_name-accessor.patch 0005-tracing-Reimplement-log2.patch 0006-ring-buffer-Add-interface-for-setting-absolute-time-.patch -0007-tracing-Apply-absolute-timestamps-to-instance-max-bu.patch 0008-ring-buffer-Redefine-the-unimplemented-RINGBUF_TIME_.patch 0009-tracing-Give-event-triggers-access-to-ring_buffer_ev.patch 0010-tracing-Add-ring-buffer-event-param-to-hist-field-fu.patch @@ -302,7 +194,6 @@ suspend-prevernt-might-sleep-splats.patch # NETWORKING net-prevent-abba-deadlock.patch net-sched-dev_deactivate_many-use-msleep-1-instead-o.patch -net-core-remove-explicit-do_softirq-from-busy_poll_s.patch net_disable_NET_RX_BUSY_POLL.patch # X86 @@ -348,8 +239,6 @@ preempt-nort-rt-variants.patch # local locks & migrate disable futex-workaround-migrate_disable-enable-in-different.patch rt-local-irq-lock.patch -rt-locking-allow-recursive-local_trylock.patch -locallock-add-local_lock_on.patch # ANNOTATE local_irq_disable sites ata-disable-interrupts-if-non-rt.patch @@ -412,7 +301,6 @@ slub-disable-SLUB_CPU_PARTIAL.patch mm-page-alloc-use-local-lock-on-target-cpu.patch mm-memcontrol-Don-t-call-schedule_work_on-in-preempt.patch mm-memcontrol-do_not_disable_irq.patch -mm-memcontrol-mem_cgroup_migrate-replace-another-loc.patch mm-backing-dev-don-t-disable-IRQs-in-wb_congested_pu.patch mm_zsmalloc_copy_with_get_cpu_var_and_locking.patch @@ -433,8 +321,6 @@ x86-kvm-require-const-tsc-for-rt.patch hrtimer-consolidate-hrtimer_init-hrtimer_init_sleepe.patch hrtimers-prepare-full-preemption.patch hrtimer-by-timers-by-default-into-the-softirq-context.patch -time-hrtimer-use-a-MONOTIC-clock-for-relative-REALTI.patch -time-hrtimer-Use-softirq-based-wakeups-for-non-RT-th.patch timer-fd-avoid-live-lock.patch # POSIX-CPU-TIMERS @@ -455,7 +341,6 @@ sched-disable-ttwu-queue.patch sched-disable-rt-group-sched-on-rt.patch sched-ttwu-ensure-success-return-is-correct.patch sched-workqueue-Only-wake-up-idle-workers-if-not-blo.patch -sched-debug-Inform-the-number-of-rt-dl-task-that-can.patch rt-Increase-decrease-the-nr-of-migratory-tasks-when-.patch # STOP MACHINE @@ -471,6 +356,7 @@ ftrace-migrate-disable-tracing.patch # LOCKDEP lockdep-no-softirq-accounting-on-rt.patch +lockdep-disable-self-test.patch # SOFTIRQ mutex-no-spin-on-rt.patch @@ -502,26 +388,17 @@ rtmutex-Make-lock_killable-work.patch spinlock-types-separate-raw.patch rtmutex-avoid-include-hell.patch rtmutex_dont_include_rcu.patch -rt-add-rt-locks.patch -rtmutex-Fix-lock-stealing-logic.patch -kernel-locking-use-an-exclusive-wait_q-for-sleeper.patch -rtmutex-add-a-first-shot-of-ww_mutex.patch -rtmutex-Provide-rt_mutex_lock_state.patch -rtmutex-Provide-locked-slowpath.patch -futex-rtmutex-Cure-RT-double-blocking-issue.patch -rwsem-rt-Lift-single-reader-restriction.patch +rtmutex-Provide-rt_mutex_slowlock_locked.patch +rtmutex-export-lockdep-less-version-of-rt_mutex-s-lo.patch +rtmutex-add-sleeping-lock-implementation.patch +rtmutex-add-mutex-implementation-based-on-rtmutex.patch +rtmutex-add-rwsem-implementation-based-on-rtmutex.patch +rtmutex-add-rwlock-implementation-based-on-rtmutex.patch +rtmutex-wire-up-RT-s-locking.patch +rtmutex-add-ww_mutex-addon-for-mutex-rt.patch ptrace-fix-ptrace-vs-tasklist_lock-race.patch - -# RWLOCK redo, fold into back +RCU-we-need-to-skip-that-warning-but-only-on-sleepin.patch locking-don-t-check-for-__LINUX_SPINLOCK_TYPES_H-on-.patch -rt-rwlock--Remove-recursive-support.patch -rt-locking--Consolidate-lock-functions.patch -rt-locking--Simplify-rt-rwlock.patch -locking-rtmutex--Make-inner-working-of-rt_spin_slow_lock---accessible.patch -locking-rt-rwlock--Provide-reader-biased-rwlock-for-RT.patch -locking-rt-rwlock--Make-reader-biased-rwlocks-selectable.patch -rt-locking--Consolidate-rwlock-variants.patch -locking-rwlock-rt-do-not-save-state-multiple-times-i.patch # RCU peter_zijlstra-frob-rcu.patch @@ -550,6 +427,7 @@ mm-protect-activate-switch-mm.patch fs-block-rt-support.patch fs-ntfs-disable-interrupt-non-rt.patch fs-jbd2-pull-your-plug-when-waiting-for-space.patch +fs-dcache-bringt-back-explicit-INIT_HLIST_BL_HEAD-in.patch # X86 x86-mce-timer-hrtimer.patch @@ -698,6 +576,7 @@ net-fix-iptable-xt-write-recseq-begin-rt-fallout.patch net-make-devnet_rename_seq-a-mutex.patch # CRYPTO +# XXX peterz-srcu-crypto-chain.patch # LOCKDEP @@ -707,6 +586,10 @@ lockdep-selftest-fix-warnings-due-to-missing-PREEMPT.patch # PERF # RCU +srcu-use-cpu_online-instead-custom-check.patch +srcu-Prohibit-call_srcu-use-under-raw-spinlocks.patch +srcu-replace-local_irqsave-with-a-locallock.patch +rcu-segcblist-include-rcupdate.h.patch rcu-disable-rcu-fast-no-hz-on-rt.patch rcu-Eliminate-softirq-processing-from-rcutree.patch rcu-make-RCU_BOOST-default-on-RT.patch @@ -732,7 +615,6 @@ drivers-zram-Don-t-disable-preemption-in-zcomp_strea.patch drivers-zram-fix-zcomp_stream_get-smp_processor_id-u.patch # I915 -drm-i915-drop-trace_i915_gem_ring_dispatch-onrt.patch i915-bogus-warning-from-i915-when-running-on-PREEMPT.patch drmradeoni915_Use_preempt_disableenable_rt()_where_recommended.patch drmi915_Use_local_lockunlock_irq()_in_intel_pipe_update_startend().patch diff --git a/patches/signal-fix-up-rcu-wreckage.patch b/patches/signal-fix-up-rcu-wreckage.patch index d67bdfacae0f..fd6185d6a175 100644 --- a/patches/signal-fix-up-rcu-wreckage.patch +++ b/patches/signal-fix-up-rcu-wreckage.patch @@ -12,7 +12,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/kernel/signal.c +++ b/kernel/signal.c -@@ -1295,12 +1295,12 @@ struct sighand_struct *__lock_task_sigha +@@ -1300,12 +1300,12 @@ struct sighand_struct *__lock_task_sigha * Disable interrupts early to avoid deadlocks. * See rcu_read_unlock() comment header for details. */ @@ -27,7 +27,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> break; } /* -@@ -1321,7 +1321,7 @@ struct sighand_struct *__lock_task_sigha +@@ -1326,7 +1326,7 @@ struct sighand_struct *__lock_task_sigha } spin_unlock(&sighand->siglock); rcu_read_unlock(); diff --git a/patches/signal-revert-ptrace-preempt-magic.patch b/patches/signal-revert-ptrace-preempt-magic.patch index 08ca72063a39..9ea3c2d6bd55 100644 --- a/patches/signal-revert-ptrace-preempt-magic.patch +++ b/patches/signal-revert-ptrace-preempt-magic.patch @@ -13,7 +13,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/kernel/signal.c +++ b/kernel/signal.c -@@ -1865,15 +1865,7 @@ static void ptrace_stop(int exit_code, i +@@ -1874,15 +1874,7 @@ static void ptrace_stop(int exit_code, i if (gstop_done && ptrace_reparented(current)) do_notify_parent_cldstop(current, false, why); diff --git a/patches/signals-allow-rt-tasks-to-cache-one-sigqueue-struct.patch b/patches/signals-allow-rt-tasks-to-cache-one-sigqueue-struct.patch index 4cd09372d11e..12f2887a2469 100644 --- a/patches/signals-allow-rt-tasks-to-cache-one-sigqueue-struct.patch +++ b/patches/signals-allow-rt-tasks-to-cache-one-sigqueue-struct.patch @@ -17,7 +17,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -753,6 +753,8 @@ struct task_struct { +@@ -787,6 +787,8 @@ struct task_struct { /* Signal handlers: */ struct signal_struct *signal; struct sighand_struct *sighand; @@ -28,7 +28,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* Restored if set_restore_sigmask() was used: */ --- a/include/linux/signal.h +++ b/include/linux/signal.h -@@ -231,6 +231,7 @@ static inline void init_sigpending(struc +@@ -228,6 +228,7 @@ static inline void init_sigpending(struc } extern void flush_sigqueue(struct sigpending *queue); @@ -49,7 +49,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -1607,6 +1607,7 @@ static __latent_entropy struct task_stru +@@ -1637,6 +1637,7 @@ static __latent_entropy struct task_stru spin_lock_init(&p->alloc_lock); init_sigpending(&p->pending); @@ -67,7 +67,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #include <linux/fs.h> #include <linux/tty.h> #include <linux/binfmts.h> -@@ -357,13 +358,30 @@ static bool task_participate_group_stop( +@@ -358,13 +359,30 @@ static bool task_participate_group_stop( return false; } @@ -99,7 +99,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> { struct sigqueue *q = NULL; struct user_struct *user; -@@ -380,7 +398,10 @@ static struct sigqueue * +@@ -381,7 +399,10 @@ static struct sigqueue * if (override_rlimit || atomic_read(&user->sigpending) <= task_rlimit(t, RLIMIT_SIGPENDING)) { @@ -111,7 +111,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } else { print_dropped_signal(sig); } -@@ -397,6 +418,13 @@ static struct sigqueue * +@@ -398,6 +419,13 @@ static struct sigqueue * return q; } @@ -125,7 +125,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> static void __sigqueue_free(struct sigqueue *q) { if (q->flags & SIGQUEUE_PREALLOC) -@@ -406,6 +434,21 @@ static void __sigqueue_free(struct sigqu +@@ -407,6 +435,21 @@ static void __sigqueue_free(struct sigqu kmem_cache_free(sigqueue_cachep, q); } @@ -147,7 +147,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> void flush_sigqueue(struct sigpending *queue) { struct sigqueue *q; -@@ -419,6 +462,21 @@ void flush_sigqueue(struct sigpending *q +@@ -420,6 +463,21 @@ void flush_sigqueue(struct sigpending *q } /* @@ -169,7 +169,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> * Flush all pending signals for this kthread. */ void flush_signals(struct task_struct *t) -@@ -539,7 +597,7 @@ static void collect_signal(int sig, stru +@@ -540,7 +598,7 @@ static void collect_signal(int sig, stru (info->si_code == SI_TIMER) && (info->si_sys_private); @@ -178,7 +178,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } else { /* * Ok, it wasn't in the queue. This must be -@@ -575,6 +633,8 @@ int dequeue_signal(struct task_struct *t +@@ -576,6 +634,8 @@ int dequeue_signal(struct task_struct *t bool resched_timer = false; int signr; @@ -187,7 +187,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* We only dequeue private signals from ourselves, we don't let * signalfd steal them */ -@@ -1504,7 +1564,8 @@ EXPORT_SYMBOL(kill_pid); +@@ -1513,7 +1573,8 @@ EXPORT_SYMBOL(kill_pid); */ struct sigqueue *sigqueue_alloc(void) { diff --git a/patches/skbufhead-raw-lock.patch b/patches/skbufhead-raw-lock.patch index 8a507d8a08cc..1129981695bf 100644 --- a/patches/skbufhead-raw-lock.patch +++ b/patches/skbufhead-raw-lock.patch @@ -15,7 +15,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h -@@ -2768,6 +2768,7 @@ struct softnet_data { +@@ -2782,6 +2782,7 @@ struct softnet_data { unsigned int dropped; struct sk_buff_head input_pkt_queue; struct napi_struct backlog; @@ -25,7 +25,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h -@@ -285,6 +285,7 @@ struct sk_buff_head { +@@ -287,6 +287,7 @@ struct sk_buff_head { __u32 qlen; spinlock_t lock; @@ -33,7 +33,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> }; struct sk_buff; -@@ -1587,6 +1588,12 @@ static inline void skb_queue_head_init(s +@@ -1573,6 +1574,12 @@ static inline void skb_queue_head_init(s __skb_queue_head_init(list); } @@ -48,7 +48,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> { --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -211,14 +211,14 @@ static inline struct hlist_head *dev_ind +@@ -216,14 +216,14 @@ static inline struct hlist_head *dev_ind static inline void rps_lock(struct softnet_data *sd) { #ifdef CONFIG_RPS @@ -65,7 +65,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #endif } -@@ -4319,7 +4319,7 @@ static void flush_backlog(struct work_st +@@ -4540,7 +4540,7 @@ static void flush_backlog(struct work_st skb_queue_walk_safe(&sd->input_pkt_queue, skb, tmp) { if (skb->dev->reg_state == NETREG_UNREGISTERING) { __skb_unlink(skb, &sd->input_pkt_queue); @@ -74,7 +74,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> input_queue_head_incr(sd); } } -@@ -4329,11 +4329,14 @@ static void flush_backlog(struct work_st +@@ -4550,11 +4550,14 @@ static void flush_backlog(struct work_st skb_queue_walk_safe(&sd->process_queue, skb, tmp) { if (skb->dev->reg_state == NETREG_UNREGISTERING) { __skb_unlink(skb, &sd->process_queue); @@ -90,7 +90,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } static void flush_all_backlogs(void) -@@ -4877,7 +4880,9 @@ static int process_backlog(struct napi_s +@@ -5101,7 +5104,9 @@ static int process_backlog(struct napi_s while (again) { struct sk_buff *skb; @@ -100,7 +100,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> rcu_read_lock(); __netif_receive_skb(skb); rcu_read_unlock(); -@@ -4885,9 +4890,9 @@ static int process_backlog(struct napi_s +@@ -5109,9 +5114,9 @@ static int process_backlog(struct napi_s if (++work >= quota) return work; @@ -111,9 +111,9 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> rps_lock(sd); if (skb_queue_empty(&sd->input_pkt_queue)) { /* -@@ -5328,13 +5333,21 @@ static __latent_entropy void net_rx_acti - struct softnet_data *sd = this_cpu_ptr(&softnet_data); - unsigned long time_limit = jiffies + 2; +@@ -5551,13 +5556,21 @@ static __latent_entropy void net_rx_acti + unsigned long time_limit = jiffies + + usecs_to_jiffies(netdev_budget_usecs); int budget = netdev_budget; + struct sk_buff_head tofree_q; + struct sk_buff *skb; @@ -133,7 +133,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> for (;;) { struct napi_struct *n; -@@ -8099,6 +8112,9 @@ static int dev_cpu_dead(unsigned int old +@@ -8361,6 +8374,9 @@ static int dev_cpu_dead(unsigned int old netif_rx_ni(skb); input_queue_head_incr(oldsd); } @@ -143,7 +143,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return 0; } -@@ -8402,8 +8418,9 @@ static int __init net_dev_init(void) +@@ -8664,8 +8680,9 @@ static int __init net_dev_init(void) INIT_WORK(flush, flush_backlog); diff --git a/patches/slub-disable-SLUB_CPU_PARTIAL.patch b/patches/slub-disable-SLUB_CPU_PARTIAL.patch index b785ad0c55bc..ccb4abf7b1b4 100644 --- a/patches/slub-disable-SLUB_CPU_PARTIAL.patch +++ b/patches/slub-disable-SLUB_CPU_PARTIAL.patch @@ -36,7 +36,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/init/Kconfig +++ b/init/Kconfig -@@ -1865,7 +1865,7 @@ config SLAB_FREELIST_RANDOM +@@ -1575,7 +1575,7 @@ config SLAB_FREELIST_RANDOM config SLUB_CPU_PARTIAL default y diff --git a/patches/smp-hotplug-Move-unparking-of-percpu-threads-to-the-.patch b/patches/smp-hotplug-Move-unparking-of-percpu-threads-to-the-.patch deleted file mode 100644 index b60a80420803..000000000000 --- a/patches/smp-hotplug-Move-unparking-of-percpu-threads-to-the-.patch +++ /dev/null @@ -1,157 +0,0 @@ -From: Thomas Gleixner <tglx@linutronix.de> -Date: Thu, 6 Jul 2017 01:57:55 -0700 -Subject: [PATCH] smp/hotplug: Move unparking of percpu threads to the control - CPU - -Upstream commit 9cd4f1a4e7a858849e889a081a99adff83e08e4c - -Vikram reported the following backtrace: - - BUG: scheduling while atomic: swapper/7/0/0x00000002 - CPU: 7 PID: 0 Comm: swapper/7 Not tainted 4.9.32-perf+ #680 - schedule - schedule_hrtimeout_range_clock - schedule_hrtimeout - wait_task_inactive - __kthread_bind_mask - __kthread_bind - __kthread_unpark - kthread_unpark - cpuhp_online_idle - cpu_startup_entry - secondary_start_kernel - -He analyzed correctly that a parked cpu hotplug thread of an offlined CPU -was still on the runqueue when the CPU came back online and tried to unpark -it. This causes the thread which invoked kthread_unpark() to call -wait_task_inactive() and subsequently schedule() with preemption disabled. -His proposed workaround was to "make sure" that a parked thread has -scheduled out when the CPU goes offline, so the situation cannot happen. - -But that's still wrong because the root cause is not the fact that the -percpu thread is still on the runqueue and neither that preemption is -disabled, which could be simply solved by enabling preemption before -calling kthread_unpark(). - -The real issue is that the calling thread is the idle task of the upcoming -CPU, which is not supposed to call anything which might sleep. The moron, -who wrote that code, missed completely that kthread_unpark() might end up -in schedule(). - -The solution is simpler than expected. The thread which controls the -hotplug operation is waiting for the CPU to call complete() on the hotplug -state completion. So the idle task of the upcoming CPU can set its state to -CPUHP_AP_ONLINE_IDLE and invoke complete(). This in turn wakes the control -task on a different CPU, which then can safely do the unpark and kick the -now unparked hotplug thread of the upcoming CPU to complete the bringup to -the final target state. - -Control CPU AP - -bringup_cpu(); - __cpu_up() ------------> - bringup_ap(); - bringup_wait_for_ap() - wait_for_completion(); - cpuhp_online_idle(); - <------------ complete(); - unpark(AP->stopper); - unpark(AP->hotplugthread); - while(1) - do_idle(); - kick(AP->hotplugthread); - wait_for_completion(); hotplug_thread() - run_online_callbacks(); - complete(); - -Fixes: 8df3e07e7f21 ("cpu/hotplug: Let upcoming cpu bring itself fully up") -Reported-by: Vikram Mulukutla <markivx@codeaurora.org> -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Acked-by: Peter Zijlstra <peterz@infradead.org> -Cc: Sebastian Sewior <bigeasy@linutronix.de> -Cc: Rusty Russell <rusty@rustcorp.com.au> -Cc: Tejun Heo <tj@kernel.org> -Cc: Andrew Morton <akpm@linux-foundation.org> -Link: http://lkml.kernel.org/r/alpine.DEB.2.20.1707042218020.2131@nanos -Signed-off-by: Thomas Gleixner <tglx@linutronix.de> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/cpu.c | 37 ++++++++++++++++++------------------- - 1 file changed, 18 insertions(+), 19 deletions(-) - ---- a/kernel/cpu.c -+++ b/kernel/cpu.c -@@ -344,13 +344,25 @@ void cpu_hotplug_enable(void) - EXPORT_SYMBOL_GPL(cpu_hotplug_enable); - #endif /* CONFIG_HOTPLUG_CPU */ - --/* Notifier wrappers for transitioning to state machine */ -+static void __cpuhp_kick_ap_work(struct cpuhp_cpu_state *st); - - static int bringup_wait_for_ap(unsigned int cpu) - { - struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu); - -+ /* Wait for the CPU to reach CPUHP_AP_ONLINE_IDLE */ - wait_for_completion(&st->done); -+ BUG_ON(!cpu_online(cpu)); -+ -+ /* Unpark the stopper thread and the hotplug thread of the target cpu */ -+ stop_machine_unpark(cpu); -+ kthread_unpark(st->thread); -+ -+ /* Should we go further up ? */ -+ if (st->target > CPUHP_AP_ONLINE_IDLE) { -+ __cpuhp_kick_ap_work(st); -+ wait_for_completion(&st->done); -+ } - return st->result; - } - -@@ -371,9 +383,7 @@ static int bringup_cpu(unsigned int cpu) - irq_unlock_sparse(); - if (ret) - return ret; -- ret = bringup_wait_for_ap(cpu); -- BUG_ON(!cpu_online(cpu)); -- return ret; -+ return bringup_wait_for_ap(cpu); - } - - /* -@@ -859,31 +869,20 @@ void notify_cpu_starting(unsigned int cp - } - - /* -- * Called from the idle task. We need to set active here, so we can kick off -- * the stopper thread and unpark the smpboot threads. If the target state is -- * beyond CPUHP_AP_ONLINE_IDLE we kick cpuhp thread and let it bring up the -- * cpu further. -+ * Called from the idle task. Wake up the controlling task which brings the -+ * stopper and the hotplug thread of the upcoming CPU up and then delegates -+ * the rest of the online bringup to the hotplug thread. - */ - void cpuhp_online_idle(enum cpuhp_state state) - { - struct cpuhp_cpu_state *st = this_cpu_ptr(&cpuhp_state); -- unsigned int cpu = smp_processor_id(); - - /* Happens for the boot cpu */ - if (state != CPUHP_AP_ONLINE_IDLE) - return; - - st->state = CPUHP_AP_ONLINE_IDLE; -- -- /* Unpark the stopper thread and the hotplug thread of this cpu */ -- stop_machine_unpark(cpu); -- kthread_unpark(st->thread); -- -- /* Should we go further up ? */ -- if (st->target > CPUHP_AP_ONLINE_IDLE) -- __cpuhp_kick_ap_work(st); -- else -- complete(&st->done); -+ complete(&st->done); - } - - /* Requires cpu_add_remove_lock to be held */ diff --git a/patches/snd-pcm-fix-snd_pcm_stream_lock-irqs_disabled-splats.patch b/patches/snd-pcm-fix-snd_pcm_stream_lock-irqs_disabled-splats.patch index 92557121d3cd..b8329c157422 100644 --- a/patches/snd-pcm-fix-snd_pcm_stream_lock-irqs_disabled-splats.patch +++ b/patches/snd-pcm-fix-snd_pcm_stream_lock-irqs_disabled-splats.patch @@ -31,7 +31,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c -@@ -136,7 +136,7 @@ EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock) +@@ -148,7 +148,7 @@ EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock) void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream) { if (!substream->pcm->nonatomic) @@ -40,7 +40,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> snd_pcm_stream_lock(substream); } EXPORT_SYMBOL_GPL(snd_pcm_stream_lock_irq); -@@ -151,7 +151,7 @@ void snd_pcm_stream_unlock_irq(struct sn +@@ -163,7 +163,7 @@ void snd_pcm_stream_unlock_irq(struct sn { snd_pcm_stream_unlock(substream); if (!substream->pcm->nonatomic) @@ -49,7 +49,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irq); -@@ -159,7 +159,7 @@ unsigned long _snd_pcm_stream_lock_irqsa +@@ -171,7 +171,7 @@ unsigned long _snd_pcm_stream_lock_irqsa { unsigned long flags = 0; if (!substream->pcm->nonatomic) @@ -58,7 +58,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> snd_pcm_stream_lock(substream); return flags; } -@@ -177,7 +177,7 @@ void snd_pcm_stream_unlock_irqrestore(st +@@ -189,7 +189,7 @@ void snd_pcm_stream_unlock_irqrestore(st { snd_pcm_stream_unlock(substream); if (!substream->pcm->nonatomic) diff --git a/patches/softirq-disable-softirq-stacks-for-rt.patch b/patches/softirq-disable-softirq-stacks-for-rt.patch index d8de0279dec1..e0b5f22ba5ca 100644 --- a/patches/softirq-disable-softirq-stacks-for-rt.patch +++ b/patches/softirq-disable-softirq-stacks-for-rt.patch @@ -19,7 +19,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c -@@ -638,6 +638,7 @@ void irq_ctx_init(void) +@@ -670,6 +670,7 @@ void irq_ctx_init(void) } } @@ -27,7 +27,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> void do_softirq_own_stack(void) { struct thread_info *curtp, *irqtp; -@@ -655,6 +656,7 @@ void do_softirq_own_stack(void) +@@ -687,6 +688,7 @@ void do_softirq_own_stack(void) if (irqtp->flags) set_bits(irqtp->flags, &curtp->flags); } @@ -109,7 +109,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> void fixup_irqs(void) --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S -@@ -889,6 +889,7 @@ EXPORT_SYMBOL(native_load_gs_index) +@@ -888,6 +888,7 @@ EXPORT_SYMBOL(native_load_gs_index) jmp 2b .previous @@ -117,7 +117,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* Call softirq on interrupt stack. Interrupts are off. */ ENTRY(do_softirq_own_stack) pushq %rbp -@@ -901,6 +902,7 @@ ENTRY(do_softirq_own_stack) +@@ -900,6 +901,7 @@ ENTRY(do_softirq_own_stack) decl PER_CPU_VAR(irq_count) ret END(do_softirq_own_stack) @@ -145,7 +145,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> { --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h -@@ -484,7 +484,7 @@ struct softirq_action +@@ -493,7 +493,7 @@ struct softirq_action asmlinkage void do_softirq(void); asmlinkage void __do_softirq(void); diff --git a/patches/softirq-preempt-fix-3-re.patch b/patches/softirq-preempt-fix-3-re.patch index 82ccd5093e8f..404890cbdbe4 100644 --- a/patches/softirq-preempt-fix-3-re.patch +++ b/patches/softirq-preempt-fix-3-re.patch @@ -111,7 +111,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -2404,6 +2404,7 @@ static void __netif_reschedule(struct Qd +@@ -2434,6 +2434,7 @@ static void __netif_reschedule(struct Qd sd->output_queue_tailp = &q->next_sched; raise_softirq_irqoff(NET_TX_SOFTIRQ); local_irq_restore(flags); @@ -119,7 +119,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } void __netif_schedule(struct Qdisc *q) -@@ -2466,6 +2467,7 @@ void __dev_kfree_skb_irq(struct sk_buff +@@ -2496,6 +2497,7 @@ void __dev_kfree_skb_irq(struct sk_buff __this_cpu_write(softnet_data.completion_queue, skb); raise_softirq_irqoff(NET_TX_SOFTIRQ); local_irq_restore(flags); @@ -127,7 +127,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } EXPORT_SYMBOL(__dev_kfree_skb_irq); -@@ -3773,6 +3775,7 @@ static int enqueue_to_backlog(struct sk_ +@@ -3859,6 +3861,7 @@ static int enqueue_to_backlog(struct sk_ rps_unlock(sd); local_irq_restore(flags); @@ -135,15 +135,14 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> atomic_long_inc(&skb->dev->rx_dropped); kfree_skb(skb); -@@ -4832,6 +4835,7 @@ static void net_rps_action_and_irq_enabl +@@ -5063,12 +5066,14 @@ static void net_rps_action_and_irq_enabl sd->rps_ipi_list = NULL; local_irq_enable(); + preempt_check_resched_rt(); /* Send pending IPI's to kick RPS processing on remote cpus. */ - while (remsd) { -@@ -4845,6 +4849,7 @@ static void net_rps_action_and_irq_enabl + net_rps_send_ipi(remsd); } else #endif local_irq_enable(); @@ -151,7 +150,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } static bool sd_has_rps_ipi_waiting(struct softnet_data *sd) -@@ -4922,6 +4927,7 @@ void __napi_schedule(struct napi_struct +@@ -5146,6 +5151,7 @@ void __napi_schedule(struct napi_struct local_irq_save(flags); ____napi_schedule(this_cpu_ptr(&softnet_data), n); local_irq_restore(flags); @@ -159,11 +158,11 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } EXPORT_SYMBOL(__napi_schedule); -@@ -8084,6 +8090,7 @@ static int dev_cpu_dead(unsigned int old +@@ -8339,6 +8345,7 @@ static int dev_cpu_dead(unsigned int old raise_softirq_irqoff(NET_TX_SOFTIRQ); local_irq_enable(); + preempt_check_resched_rt(); - /* Process offline CPU's input_pkt_queue */ - while ((skb = __skb_dequeue(&oldsd->process_queue))) { + #ifdef CONFIG_RPS + remsd = oldsd->rps_ipi_list; diff --git a/patches/softirq-split-locks.patch b/patches/softirq-split-locks.patch index 95bea40b1505..693153a9d444 100644 --- a/patches/softirq-split-locks.patch +++ b/patches/softirq-split-locks.patch @@ -85,7 +85,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #endif /* _LINUX_BH_H */ --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h -@@ -481,10 +481,11 @@ struct softirq_action +@@ -490,10 +490,11 @@ struct softirq_action void (*action)(struct softirq_action *); }; @@ -99,7 +99,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> void do_softirq_own_stack(void); #else static inline void do_softirq_own_stack(void) -@@ -492,6 +493,9 @@ static inline void do_softirq_own_stack( +@@ -501,6 +502,9 @@ static inline void do_softirq_own_stack( __do_softirq(); } #endif @@ -109,7 +109,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> extern void open_softirq(int nr, void (*action)(struct softirq_action *)); extern void softirq_init(void); -@@ -499,6 +503,7 @@ extern void __raise_softirq_irqoff(unsig +@@ -508,6 +512,7 @@ extern void __raise_softirq_irqoff(unsig extern void raise_softirq_irqoff(unsigned int nr); extern void raise_softirq(unsigned int nr); @@ -117,7 +117,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> DECLARE_PER_CPU(struct task_struct *, ksoftirqd); -@@ -631,6 +636,12 @@ extern void tasklet_kill_immediate(struc +@@ -640,6 +645,12 @@ extern void tasklet_kill_immediate(struc extern void tasklet_init(struct tasklet_struct *t, void (*func)(unsigned long), unsigned long data); @@ -172,7 +172,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_OFFSET))) --- a/include/linux/sched.h +++ b/include/linux/sched.h -@@ -1050,6 +1050,8 @@ struct task_struct { +@@ -1085,6 +1085,8 @@ struct task_struct { #endif #ifdef CONFIG_PREEMPT_RT_BASE struct rcu_head put_rcu; @@ -181,7 +181,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #endif #ifdef CONFIG_DEBUG_ATOMIC_SLEEP unsigned long task_state_change; -@@ -1222,6 +1224,7 @@ extern struct pid *cad_pid; +@@ -1272,6 +1274,7 @@ extern struct pid *cad_pid; /* * Per process flags */ @@ -191,7 +191,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #define PF_EXITPIDONE 0x00000008 /* PI exit done on shut down */ --- a/init/main.c +++ b/init/main.c -@@ -537,6 +537,7 @@ asmlinkage __visible void __init start_k +@@ -538,6 +538,7 @@ asmlinkage __visible void __init start_k setup_command_line(command_line); setup_nr_cpu_ids(); setup_per_cpu_areas(); @@ -506,7 +506,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + lockdep_softirq_exit(); + current->flags &= ~PF_IN_SOFTIRQ; + vtime_account_irq_enter(current); -+ tsk_restore_flags(current, old_flags, PF_MEMALLOC); ++ current_restore_flags(old_flags, PF_MEMALLOC); +} + +/* @@ -798,7 +798,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> .thread_comm = "ksoftirqd/%u", --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c -@@ -881,14 +881,7 @@ static bool can_stop_idle_tick(int cpu, +@@ -895,14 +895,7 @@ static bool can_stop_idle_tick(int cpu, return false; if (unlikely(local_softirq_pending() && cpu_online(cpu))) { @@ -816,7 +816,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -3845,11 +3845,9 @@ int netif_rx_ni(struct sk_buff *skb) +@@ -3931,11 +3931,9 @@ int netif_rx_ni(struct sk_buff *skb) trace_netif_rx_ni_entry(skb); diff --git a/patches/sparc64-use-generic-rwsem-spinlocks-rt.patch b/patches/sparc64-use-generic-rwsem-spinlocks-rt.patch index 7b7c1ca29164..84f960733568 100644 --- a/patches/sparc64-use-generic-rwsem-spinlocks-rt.patch +++ b/patches/sparc64-use-generic-rwsem-spinlocks-rt.patch @@ -10,7 +10,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig -@@ -199,12 +199,10 @@ config NR_CPUS +@@ -204,12 +204,10 @@ config NR_CPUS source kernel/Kconfig.hz config RWSEM_GENERIC_SPINLOCK diff --git a/patches/srcu-Prohibit-call_srcu-use-under-raw-spinlocks.patch b/patches/srcu-Prohibit-call_srcu-use-under-raw-spinlocks.patch new file mode 100644 index 000000000000..0dd7519d2e33 --- /dev/null +++ b/patches/srcu-Prohibit-call_srcu-use-under-raw-spinlocks.patch @@ -0,0 +1,412 @@ +From: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> +Date: Tue, 10 Oct 2017 13:52:30 -0700 +Subject: [PATCH] srcu: Prohibit call_srcu() use under raw spinlocks + +commit 7c4b15340e4e23668cb3cadbf4f76795ee495085 + +Invoking queue_delayed_work() while holding a raw spinlock is forbidden +in -rt kernels, which is exactly what __call_srcu() does, indirectly via +srcu_funnel_gp_start(). This commit therefore downgrades Tree SRCU's +locking from raw to non-raw spinlocks, which works because call_srcu() +is not ever called while holding a raw spinlock. + +Reported-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + include/linux/srcutree.h | 8 +-- + kernel/rcu/srcutree.c | 118 ++++++++++++++++++++++++++++++----------------- + 2 files changed, 81 insertions(+), 45 deletions(-) + +--- a/include/linux/srcutree.h ++++ b/include/linux/srcutree.h +@@ -40,7 +40,7 @@ struct srcu_data { + unsigned long srcu_unlock_count[2]; /* Unlocks per CPU. */ + + /* Update-side state. */ +- raw_spinlock_t __private lock ____cacheline_internodealigned_in_smp; ++ spinlock_t __private lock ____cacheline_internodealigned_in_smp; + struct rcu_segcblist srcu_cblist; /* List of callbacks.*/ + unsigned long srcu_gp_seq_needed; /* Furthest future GP needed. */ + unsigned long srcu_gp_seq_needed_exp; /* Furthest future exp GP. */ +@@ -58,7 +58,7 @@ struct srcu_data { + * Node in SRCU combining tree, similar in function to rcu_data. + */ + struct srcu_node { +- raw_spinlock_t __private lock; ++ spinlock_t __private lock; + unsigned long srcu_have_cbs[4]; /* GP seq for children */ + /* having CBs, but only */ + /* is > ->srcu_gq_seq. */ +@@ -78,7 +78,7 @@ struct srcu_struct { + struct srcu_node *level[RCU_NUM_LVLS + 1]; + /* First node at each level. */ + struct mutex srcu_cb_mutex; /* Serialize CB preparation. */ +- raw_spinlock_t __private lock; /* Protect counters */ ++ spinlock_t __private lock; /* Protect counters */ + struct mutex srcu_gp_mutex; /* Serialize GP work. */ + unsigned int srcu_idx; /* Current rdr array element. */ + unsigned long srcu_gp_seq; /* Grace-period seq #. */ +@@ -109,7 +109,7 @@ void process_srcu(struct work_struct *wo + #define __SRCU_STRUCT_INIT(name, pcpu_name) \ + { \ + .sda = &pcpu_name, \ +- .lock = __RAW_SPIN_LOCK_UNLOCKED(name.lock), \ ++ .lock = __SPIN_LOCK_UNLOCKED(name.lock), \ + .srcu_gp_seq_needed = 0 - 1, \ + __SRCU_DEP_MAP_INIT(name) \ + } +--- a/kernel/rcu/srcutree.c ++++ b/kernel/rcu/srcutree.c +@@ -53,6 +53,42 @@ module_param(counter_wrap_check, ulong, + static void srcu_invoke_callbacks(struct work_struct *work); + static void srcu_reschedule(struct srcu_struct *sp, unsigned long delay); + ++/* Wrappers for lock acquisition and release, see raw_spin_lock_rcu_node(). */ ++#define spin_lock_rcu_node(p) \ ++do { \ ++ spin_lock(&ACCESS_PRIVATE(p, lock)); \ ++ smp_mb__after_unlock_lock(); \ ++} while (0) ++ ++#define spin_unlock_rcu_node(p) spin_unlock(&ACCESS_PRIVATE(p, lock)) ++ ++#define spin_lock_irq_rcu_node(p) \ ++do { \ ++ spin_lock_irq(&ACCESS_PRIVATE(p, lock)); \ ++ smp_mb__after_unlock_lock(); \ ++} while (0) ++ ++#define spin_unlock_irq_rcu_node(p) \ ++ spin_unlock_irq(&ACCESS_PRIVATE(p, lock)) ++ ++#define spin_lock_irqsave_rcu_node(p, flags) \ ++do { \ ++ spin_lock_irqsave(&ACCESS_PRIVATE(p, lock), flags); \ ++ smp_mb__after_unlock_lock(); \ ++} while (0) ++ ++#define spin_unlock_irqrestore_rcu_node(p, flags) \ ++ spin_unlock_irqrestore(&ACCESS_PRIVATE(p, lock), flags) \ ++ ++#define spin_trylock_rcu_node(p) \ ++({ \ ++ bool ___locked = spin_trylock(&ACCESS_PRIVATE(p, lock)); \ ++ \ ++ if (___locked) \ ++ smp_mb__after_unlock_lock(); \ ++ ___locked; \ ++}) ++ + /* + * Initialize SRCU combining tree. Note that statically allocated + * srcu_struct structures might already have srcu_read_lock() and +@@ -77,7 +113,7 @@ static void init_srcu_struct_nodes(struc + + /* Each pass through this loop initializes one srcu_node structure. */ + rcu_for_each_node_breadth_first(sp, snp) { +- raw_spin_lock_init(&ACCESS_PRIVATE(snp, lock)); ++ spin_lock_init(&ACCESS_PRIVATE(snp, lock)); + WARN_ON_ONCE(ARRAY_SIZE(snp->srcu_have_cbs) != + ARRAY_SIZE(snp->srcu_data_have_cbs)); + for (i = 0; i < ARRAY_SIZE(snp->srcu_have_cbs); i++) { +@@ -111,7 +147,7 @@ static void init_srcu_struct_nodes(struc + snp_first = sp->level[level]; + for_each_possible_cpu(cpu) { + sdp = per_cpu_ptr(sp->sda, cpu); +- raw_spin_lock_init(&ACCESS_PRIVATE(sdp, lock)); ++ spin_lock_init(&ACCESS_PRIVATE(sdp, lock)); + rcu_segcblist_init(&sdp->srcu_cblist); + sdp->srcu_cblist_invoking = false; + sdp->srcu_gp_seq_needed = sp->srcu_gp_seq; +@@ -170,7 +206,7 @@ int __init_srcu_struct(struct srcu_struc + /* Don't re-initialize a lock while it is held. */ + debug_check_no_locks_freed((void *)sp, sizeof(*sp)); + lockdep_init_map(&sp->dep_map, name, key, 0); +- raw_spin_lock_init(&ACCESS_PRIVATE(sp, lock)); ++ spin_lock_init(&ACCESS_PRIVATE(sp, lock)); + return init_srcu_struct_fields(sp, false); + } + EXPORT_SYMBOL_GPL(__init_srcu_struct); +@@ -187,7 +223,7 @@ EXPORT_SYMBOL_GPL(__init_srcu_struct); + */ + int init_srcu_struct(struct srcu_struct *sp) + { +- raw_spin_lock_init(&ACCESS_PRIVATE(sp, lock)); ++ spin_lock_init(&ACCESS_PRIVATE(sp, lock)); + return init_srcu_struct_fields(sp, false); + } + EXPORT_SYMBOL_GPL(init_srcu_struct); +@@ -210,13 +246,13 @@ static void check_init_srcu_struct(struc + /* The smp_load_acquire() pairs with the smp_store_release(). */ + if (!rcu_seq_state(smp_load_acquire(&sp->srcu_gp_seq_needed))) /*^^^*/ + return; /* Already initialized. */ +- raw_spin_lock_irqsave_rcu_node(sp, flags); ++ spin_lock_irqsave_rcu_node(sp, flags); + if (!rcu_seq_state(sp->srcu_gp_seq_needed)) { +- raw_spin_unlock_irqrestore_rcu_node(sp, flags); ++ spin_unlock_irqrestore_rcu_node(sp, flags); + return; + } + init_srcu_struct_fields(sp, true); +- raw_spin_unlock_irqrestore_rcu_node(sp, flags); ++ spin_unlock_irqrestore_rcu_node(sp, flags); + } + + /* +@@ -498,7 +534,7 @@ static void srcu_gp_end(struct srcu_stru + mutex_lock(&sp->srcu_cb_mutex); + + /* End the current grace period. */ +- raw_spin_lock_irq_rcu_node(sp); ++ spin_lock_irq_rcu_node(sp); + idx = rcu_seq_state(sp->srcu_gp_seq); + WARN_ON_ONCE(idx != SRCU_STATE_SCAN2); + cbdelay = srcu_get_delay(sp); +@@ -507,7 +543,7 @@ static void srcu_gp_end(struct srcu_stru + gpseq = rcu_seq_current(&sp->srcu_gp_seq); + if (ULONG_CMP_LT(sp->srcu_gp_seq_needed_exp, gpseq)) + sp->srcu_gp_seq_needed_exp = gpseq; +- raw_spin_unlock_irq_rcu_node(sp); ++ spin_unlock_irq_rcu_node(sp); + mutex_unlock(&sp->srcu_gp_mutex); + /* A new grace period can start at this point. But only one. */ + +@@ -515,7 +551,7 @@ static void srcu_gp_end(struct srcu_stru + idx = rcu_seq_ctr(gpseq) % ARRAY_SIZE(snp->srcu_have_cbs); + idxnext = (idx + 1) % ARRAY_SIZE(snp->srcu_have_cbs); + rcu_for_each_node_breadth_first(sp, snp) { +- raw_spin_lock_irq_rcu_node(snp); ++ spin_lock_irq_rcu_node(snp); + cbs = false; + if (snp >= sp->level[rcu_num_lvls - 1]) + cbs = snp->srcu_have_cbs[idx] == gpseq; +@@ -525,7 +561,7 @@ static void srcu_gp_end(struct srcu_stru + snp->srcu_gp_seq_needed_exp = gpseq; + mask = snp->srcu_data_have_cbs[idx]; + snp->srcu_data_have_cbs[idx] = 0; +- raw_spin_unlock_irq_rcu_node(snp); ++ spin_unlock_irq_rcu_node(snp); + if (cbs) + srcu_schedule_cbs_snp(sp, snp, mask, cbdelay); + +@@ -533,11 +569,11 @@ static void srcu_gp_end(struct srcu_stru + if (!(gpseq & counter_wrap_check)) + for (cpu = snp->grplo; cpu <= snp->grphi; cpu++) { + sdp = per_cpu_ptr(sp->sda, cpu); +- raw_spin_lock_irqsave_rcu_node(sdp, flags); ++ spin_lock_irqsave_rcu_node(sdp, flags); + if (ULONG_CMP_GE(gpseq, + sdp->srcu_gp_seq_needed + 100)) + sdp->srcu_gp_seq_needed = gpseq; +- raw_spin_unlock_irqrestore_rcu_node(sdp, flags); ++ spin_unlock_irqrestore_rcu_node(sdp, flags); + } + } + +@@ -545,17 +581,17 @@ static void srcu_gp_end(struct srcu_stru + mutex_unlock(&sp->srcu_cb_mutex); + + /* Start a new grace period if needed. */ +- raw_spin_lock_irq_rcu_node(sp); ++ spin_lock_irq_rcu_node(sp); + gpseq = rcu_seq_current(&sp->srcu_gp_seq); + if (!rcu_seq_state(gpseq) && + ULONG_CMP_LT(gpseq, sp->srcu_gp_seq_needed)) { + srcu_gp_start(sp); +- raw_spin_unlock_irq_rcu_node(sp); ++ spin_unlock_irq_rcu_node(sp); + /* Throttle expedited grace periods: Should be rare! */ + srcu_reschedule(sp, rcu_seq_ctr(gpseq) & 0x3ff + ? 0 : SRCU_INTERVAL); + } else { +- raw_spin_unlock_irq_rcu_node(sp); ++ spin_unlock_irq_rcu_node(sp); + } + } + +@@ -575,18 +611,18 @@ static void srcu_funnel_exp_start(struct + if (rcu_seq_done(&sp->srcu_gp_seq, s) || + ULONG_CMP_GE(READ_ONCE(snp->srcu_gp_seq_needed_exp), s)) + return; +- raw_spin_lock_irqsave_rcu_node(snp, flags); ++ spin_lock_irqsave_rcu_node(snp, flags); + if (ULONG_CMP_GE(snp->srcu_gp_seq_needed_exp, s)) { +- raw_spin_unlock_irqrestore_rcu_node(snp, flags); ++ spin_unlock_irqrestore_rcu_node(snp, flags); + return; + } + WRITE_ONCE(snp->srcu_gp_seq_needed_exp, s); +- raw_spin_unlock_irqrestore_rcu_node(snp, flags); ++ spin_unlock_irqrestore_rcu_node(snp, flags); + } +- raw_spin_lock_irqsave_rcu_node(sp, flags); ++ spin_lock_irqsave_rcu_node(sp, flags); + if (!ULONG_CMP_LT(sp->srcu_gp_seq_needed_exp, s)) + sp->srcu_gp_seq_needed_exp = s; +- raw_spin_unlock_irqrestore_rcu_node(sp, flags); ++ spin_unlock_irqrestore_rcu_node(sp, flags); + } + + /* +@@ -608,12 +644,12 @@ static void srcu_funnel_gp_start(struct + for (; snp != NULL; snp = snp->srcu_parent) { + if (rcu_seq_done(&sp->srcu_gp_seq, s) && snp != sdp->mynode) + return; /* GP already done and CBs recorded. */ +- raw_spin_lock_irqsave_rcu_node(snp, flags); ++ spin_lock_irqsave_rcu_node(snp, flags); + if (ULONG_CMP_GE(snp->srcu_have_cbs[idx], s)) { + snp_seq = snp->srcu_have_cbs[idx]; + if (snp == sdp->mynode && snp_seq == s) + snp->srcu_data_have_cbs[idx] |= sdp->grpmask; +- raw_spin_unlock_irqrestore_rcu_node(snp, flags); ++ spin_unlock_irqrestore_rcu_node(snp, flags); + if (snp == sdp->mynode && snp_seq != s) { + srcu_schedule_cbs_sdp(sdp, do_norm + ? SRCU_INTERVAL +@@ -629,11 +665,11 @@ static void srcu_funnel_gp_start(struct + snp->srcu_data_have_cbs[idx] |= sdp->grpmask; + if (!do_norm && ULONG_CMP_LT(snp->srcu_gp_seq_needed_exp, s)) + snp->srcu_gp_seq_needed_exp = s; +- raw_spin_unlock_irqrestore_rcu_node(snp, flags); ++ spin_unlock_irqrestore_rcu_node(snp, flags); + } + + /* Top of tree, must ensure the grace period will be started. */ +- raw_spin_lock_irqsave_rcu_node(sp, flags); ++ spin_lock_irqsave_rcu_node(sp, flags); + if (ULONG_CMP_LT(sp->srcu_gp_seq_needed, s)) { + /* + * Record need for grace period s. Pair with load +@@ -652,7 +688,7 @@ static void srcu_funnel_gp_start(struct + queue_delayed_work(system_power_efficient_wq, &sp->work, + srcu_get_delay(sp)); + } +- raw_spin_unlock_irqrestore_rcu_node(sp, flags); ++ spin_unlock_irqrestore_rcu_node(sp, flags); + } + + /* +@@ -815,7 +851,7 @@ void __call_srcu(struct srcu_struct *sp, + rhp->func = func; + local_irq_save(flags); + sdp = this_cpu_ptr(sp->sda); +- raw_spin_lock_rcu_node(sdp); ++ spin_lock_rcu_node(sdp); + rcu_segcblist_enqueue(&sdp->srcu_cblist, rhp, false); + rcu_segcblist_advance(&sdp->srcu_cblist, + rcu_seq_current(&sp->srcu_gp_seq)); +@@ -829,7 +865,7 @@ void __call_srcu(struct srcu_struct *sp, + sdp->srcu_gp_seq_needed_exp = s; + needexp = true; + } +- raw_spin_unlock_irqrestore_rcu_node(sdp, flags); ++ spin_unlock_irqrestore_rcu_node(sdp, flags); + if (needgp) + srcu_funnel_gp_start(sp, sdp, s, do_norm); + else if (needexp) +@@ -885,7 +921,7 @@ static void __synchronize_srcu(struct sr + + /* + * Make sure that later code is ordered after the SRCU grace +- * period. This pairs with the raw_spin_lock_irq_rcu_node() ++ * period. This pairs with the spin_lock_irq_rcu_node() + * in srcu_invoke_callbacks(). Unlike Tree RCU, this is needed + * because the current CPU might have been totally uninvolved with + * (and thus unordered against) that grace period. +@@ -1009,7 +1045,7 @@ void srcu_barrier(struct srcu_struct *sp + */ + for_each_possible_cpu(cpu) { + sdp = per_cpu_ptr(sp->sda, cpu); +- raw_spin_lock_irq_rcu_node(sdp); ++ spin_lock_irq_rcu_node(sdp); + atomic_inc(&sp->srcu_barrier_cpu_cnt); + sdp->srcu_barrier_head.func = srcu_barrier_cb; + debug_rcu_head_queue(&sdp->srcu_barrier_head); +@@ -1018,7 +1054,7 @@ void srcu_barrier(struct srcu_struct *sp + debug_rcu_head_unqueue(&sdp->srcu_barrier_head); + atomic_dec(&sp->srcu_barrier_cpu_cnt); + } +- raw_spin_unlock_irq_rcu_node(sdp); ++ spin_unlock_irq_rcu_node(sdp); + } + + /* Remove the initial count, at which point reaching zero can happen. */ +@@ -1067,17 +1103,17 @@ static void srcu_advance_state(struct sr + */ + idx = rcu_seq_state(smp_load_acquire(&sp->srcu_gp_seq)); /* ^^^ */ + if (idx == SRCU_STATE_IDLE) { +- raw_spin_lock_irq_rcu_node(sp); ++ spin_lock_irq_rcu_node(sp); + if (ULONG_CMP_GE(sp->srcu_gp_seq, sp->srcu_gp_seq_needed)) { + WARN_ON_ONCE(rcu_seq_state(sp->srcu_gp_seq)); +- raw_spin_unlock_irq_rcu_node(sp); ++ spin_unlock_irq_rcu_node(sp); + mutex_unlock(&sp->srcu_gp_mutex); + return; + } + idx = rcu_seq_state(READ_ONCE(sp->srcu_gp_seq)); + if (idx == SRCU_STATE_IDLE) + srcu_gp_start(sp); +- raw_spin_unlock_irq_rcu_node(sp); ++ spin_unlock_irq_rcu_node(sp); + if (idx != SRCU_STATE_IDLE) { + mutex_unlock(&sp->srcu_gp_mutex); + return; /* Someone else started the grace period. */ +@@ -1126,19 +1162,19 @@ static void srcu_invoke_callbacks(struct + sdp = container_of(work, struct srcu_data, work.work); + sp = sdp->sp; + rcu_cblist_init(&ready_cbs); +- raw_spin_lock_irq_rcu_node(sdp); ++ spin_lock_irq_rcu_node(sdp); + rcu_segcblist_advance(&sdp->srcu_cblist, + rcu_seq_current(&sp->srcu_gp_seq)); + if (sdp->srcu_cblist_invoking || + !rcu_segcblist_ready_cbs(&sdp->srcu_cblist)) { +- raw_spin_unlock_irq_rcu_node(sdp); ++ spin_unlock_irq_rcu_node(sdp); + return; /* Someone else on the job or nothing to do. */ + } + + /* We are on the job! Extract and invoke ready callbacks. */ + sdp->srcu_cblist_invoking = true; + rcu_segcblist_extract_done_cbs(&sdp->srcu_cblist, &ready_cbs); +- raw_spin_unlock_irq_rcu_node(sdp); ++ spin_unlock_irq_rcu_node(sdp); + rhp = rcu_cblist_dequeue(&ready_cbs); + for (; rhp != NULL; rhp = rcu_cblist_dequeue(&ready_cbs)) { + debug_rcu_head_unqueue(rhp); +@@ -1151,13 +1187,13 @@ static void srcu_invoke_callbacks(struct + * Update counts, accelerate new callbacks, and if needed, + * schedule another round of callback invocation. + */ +- raw_spin_lock_irq_rcu_node(sdp); ++ spin_lock_irq_rcu_node(sdp); + rcu_segcblist_insert_count(&sdp->srcu_cblist, &ready_cbs); + (void)rcu_segcblist_accelerate(&sdp->srcu_cblist, + rcu_seq_snap(&sp->srcu_gp_seq)); + sdp->srcu_cblist_invoking = false; + more = rcu_segcblist_ready_cbs(&sdp->srcu_cblist); +- raw_spin_unlock_irq_rcu_node(sdp); ++ spin_unlock_irq_rcu_node(sdp); + if (more) + srcu_schedule_cbs_sdp(sdp, 0); + } +@@ -1170,7 +1206,7 @@ static void srcu_reschedule(struct srcu_ + { + bool pushgp = true; + +- raw_spin_lock_irq_rcu_node(sp); ++ spin_lock_irq_rcu_node(sp); + if (ULONG_CMP_GE(sp->srcu_gp_seq, sp->srcu_gp_seq_needed)) { + if (!WARN_ON_ONCE(rcu_seq_state(sp->srcu_gp_seq))) { + /* All requests fulfilled, time to go idle. */ +@@ -1180,7 +1216,7 @@ static void srcu_reschedule(struct srcu_ + /* Outstanding request and no GP. Start one. */ + srcu_gp_start(sp); + } +- raw_spin_unlock_irq_rcu_node(sp); ++ spin_unlock_irq_rcu_node(sp); + + if (pushgp) + queue_delayed_work(system_power_efficient_wq, &sp->work, delay); diff --git a/patches/srcu-replace-local_irqsave-with-a-locallock.patch b/patches/srcu-replace-local_irqsave-with-a-locallock.patch new file mode 100644 index 000000000000..08e2eddef775 --- /dev/null +++ b/patches/srcu-replace-local_irqsave-with-a-locallock.patch @@ -0,0 +1,70 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Thu, 12 Oct 2017 18:37:12 +0200 +Subject: [PATCH] srcu: replace local_irqsave() with a locallock + +There are two instances which disable interrupts in order to become a +stable this_cpu_ptr() pointer. The restore part is coupled with +spin_unlock_irqrestore() which does not work on RT. +Replace the local_irq_save() call with the appropriate local_lock() +version of it. + +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + kernel/rcu/srcutree.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +--- a/kernel/rcu/srcutree.c ++++ b/kernel/rcu/srcutree.c +@@ -37,6 +37,7 @@ + #include <linux/module.h> + #include <linux/srcu.h> + #include <linux/cpu.h> ++#include <linux/locallock.h> + + #include "rcu.h" + #include "rcu_segcblist.h" +@@ -757,6 +758,8 @@ static void srcu_flip(struct srcu_struct + * negligible when amoritized over that time period, and the extra latency + * of a needlessly non-expedited grace period is similarly negligible. + */ ++static DEFINE_LOCAL_IRQ_LOCK(sp_llock); ++ + static bool srcu_might_be_idle(struct srcu_struct *sp) + { + unsigned long curseq; +@@ -765,13 +768,13 @@ static bool srcu_might_be_idle(struct sr + unsigned long t; + + /* If the local srcu_data structure has callbacks, not idle. */ +- local_irq_save(flags); ++ local_lock_irqsave(sp_llock, flags); + sdp = this_cpu_ptr(sp->sda); + if (rcu_segcblist_pend_cbs(&sdp->srcu_cblist)) { +- local_irq_restore(flags); ++ local_unlock_irqrestore(sp_llock, flags); + return false; /* Callbacks already present, so not idle. */ + } +- local_irq_restore(flags); ++ local_unlock_irqrestore(sp_llock, flags); + + /* + * No local callbacks, so probabalistically probe global state. +@@ -849,7 +852,7 @@ void __call_srcu(struct srcu_struct *sp, + return; + } + rhp->func = func; +- local_irq_save(flags); ++ local_lock_irqsave(sp_llock, flags); + sdp = this_cpu_ptr(sp->sda); + spin_lock_rcu_node(sdp); + rcu_segcblist_enqueue(&sdp->srcu_cblist, rhp, false); +@@ -865,7 +868,8 @@ void __call_srcu(struct srcu_struct *sp, + sdp->srcu_gp_seq_needed_exp = s; + needexp = true; + } +- spin_unlock_irqrestore_rcu_node(sdp, flags); ++ spin_unlock_rcu_node(sdp); ++ local_unlock_irqrestore(sp_llock, flags); + if (needgp) + srcu_funnel_gp_start(sp, sdp, s, do_norm); + else if (needexp) diff --git a/patches/srcu-use-cpu_online-instead-custom-check.patch b/patches/srcu-use-cpu_online-instead-custom-check.patch new file mode 100644 index 000000000000..c143b790a031 --- /dev/null +++ b/patches/srcu-use-cpu_online-instead-custom-check.patch @@ -0,0 +1,99 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Wed, 13 Sep 2017 14:43:41 +0200 +Subject: [PATCH] srcu: use cpu_online() instead custom check + +The current check via srcu_online is slightly racy because after looking +at srcu_online there could be an interrupt that interrupted us long +enough until the CPU we checked against went offline. +An alternative would be to hold the hotplug rwsem (so the CPUs don't +change their state) and then check based on cpu_online() if we queue it +on a specific CPU or not. queue_work_on() itself can handle if something +is enqueued on an offline CPU but a timer which is enqueued on an offline +CPU won't fire until the CPU is back online. + +I am not sure if the removal in rcu_init() is okay or not. I assume that +SRCU won't enqueue a work item before SRCU is up and ready. + +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + kernel/rcu/srcutree.c | 22 ++++------------------ + kernel/rcu/tree.c | 6 ------ + 2 files changed, 4 insertions(+), 24 deletions(-) + +--- a/kernel/rcu/srcutree.c ++++ b/kernel/rcu/srcutree.c +@@ -36,6 +36,7 @@ + #include <linux/delay.h> + #include <linux/module.h> + #include <linux/srcu.h> ++#include <linux/cpu.h> + + #include "rcu.h" + #include "rcu_segcblist.h" +@@ -424,21 +425,6 @@ static void srcu_gp_start(struct srcu_st + } + + /* +- * Track online CPUs to guide callback workqueue placement. +- */ +-DEFINE_PER_CPU(bool, srcu_online); +- +-void srcu_online_cpu(unsigned int cpu) +-{ +- WRITE_ONCE(per_cpu(srcu_online, cpu), true); +-} +- +-void srcu_offline_cpu(unsigned int cpu) +-{ +- WRITE_ONCE(per_cpu(srcu_online, cpu), false); +-} +- +-/* + * Place the workqueue handler on the specified CPU if online, otherwise + * just run it whereever. This is useful for placing workqueue handlers + * that are to invoke the specified CPU's callbacks. +@@ -449,12 +435,12 @@ static bool srcu_queue_delayed_work_on(i + { + bool ret; + +- preempt_disable(); +- if (READ_ONCE(per_cpu(srcu_online, cpu))) ++ cpus_read_lock(); ++ if (cpu_online(cpu)) + ret = queue_delayed_work_on(cpu, wq, dwork, delay); + else + ret = queue_delayed_work(wq, dwork, delay); +- preempt_enable(); ++ cpus_read_unlock(); + return ret; + } + +--- a/kernel/rcu/tree.c ++++ b/kernel/rcu/tree.c +@@ -3868,8 +3868,6 @@ int rcutree_online_cpu(unsigned int cpu) + { + sync_sched_exp_online_cleanup(cpu); + rcutree_affinity_setting(cpu, -1); +- if (IS_ENABLED(CONFIG_TREE_SRCU)) +- srcu_online_cpu(cpu); + return 0; + } + +@@ -3880,8 +3878,6 @@ int rcutree_online_cpu(unsigned int cpu) + int rcutree_offline_cpu(unsigned int cpu) + { + rcutree_affinity_setting(cpu, cpu); +- if (IS_ENABLED(CONFIG_TREE_SRCU)) +- srcu_offline_cpu(cpu); + return 0; + } + +@@ -4277,8 +4273,6 @@ void __init rcu_init(void) + for_each_online_cpu(cpu) { + rcutree_prepare_cpu(cpu); + rcu_cpu_starting(cpu); +- if (IS_ENABLED(CONFIG_TREE_SRCU)) +- srcu_online_cpu(cpu); + } + } + diff --git a/patches/suspend-prevernt-might-sleep-splats.patch b/patches/suspend-prevernt-might-sleep-splats.patch index 069930c49634..6a2637911e99 100644 --- a/patches/suspend-prevernt-might-sleep-splats.patch +++ b/patches/suspend-prevernt-might-sleep-splats.patch @@ -25,7 +25,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/include/linux/kernel.h +++ b/include/linux/kernel.h -@@ -499,6 +499,7 @@ extern enum system_states { +@@ -502,6 +502,7 @@ extern enum system_states { SYSTEM_HALT, SYSTEM_POWER_OFF, SYSTEM_RESTART, @@ -86,7 +86,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Enable_cpus: --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c -@@ -384,6 +384,8 @@ static int suspend_enter(suspend_state_t +@@ -407,6 +407,8 @@ static int suspend_enter(suspend_state_t arch_suspend_disable_irqs(); BUG_ON(!irqs_disabled()); @@ -95,7 +95,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> error = syscore_suspend(); if (!error) { *wakeup = pm_wakeup_pending(); -@@ -400,6 +402,8 @@ static int suspend_enter(suspend_state_t +@@ -423,6 +425,8 @@ static int suspend_enter(suspend_state_t syscore_resume(); } diff --git a/patches/sysfs-realtime-entry.patch b/patches/sysfs-realtime-entry.patch index e06abca2f27d..85c90149d1e3 100644 --- a/patches/sysfs-realtime-entry.patch +++ b/patches/sysfs-realtime-entry.patch @@ -19,13 +19,13 @@ Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> --- a/kernel/ksysfs.c +++ b/kernel/ksysfs.c -@@ -136,6 +136,15 @@ KERNEL_ATTR_RO(vmcoreinfo); +@@ -140,6 +140,15 @@ KERNEL_ATTR_RO(vmcoreinfo); - #endif /* CONFIG_KEXEC_CORE */ + #endif /* CONFIG_CRASH_CORE */ +#if defined(CONFIG_PREEMPT_RT_FULL) -+static ssize_t realtime_show(struct kobject *kobj, -+ struct kobj_attribute *attr, char *buf) ++static ssize_t realtime_show(struct kobject *kobj, ++ struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", 1); +} @@ -35,7 +35,7 @@ Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> /* whether file capabilities are enabled */ static ssize_t fscaps_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) -@@ -225,6 +234,9 @@ static struct attribute * kernel_attrs[] +@@ -231,6 +240,9 @@ static struct attribute * kernel_attrs[] &rcu_expedited_attr.attr, &rcu_normal_attr.attr, #endif diff --git a/patches/tasklet-rt-prevent-tasklets-from-going-into-infinite-spin-in-rt.patch b/patches/tasklet-rt-prevent-tasklets-from-going-into-infinite-spin-in-rt.patch index 23674c93211d..d1796546d29b 100644 --- a/patches/tasklet-rt-prevent-tasklets-from-going-into-infinite-spin-in-rt.patch +++ b/patches/tasklet-rt-prevent-tasklets-from-going-into-infinite-spin-in-rt.patch @@ -43,7 +43,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h -@@ -520,8 +520,9 @@ static inline struct task_struct *this_c +@@ -529,8 +529,9 @@ static inline struct task_struct *this_c to be executed on some cpu at least once after this. * If the tasklet is already scheduled, but its execution is still not started, it will be executed only once. @@ -55,7 +55,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> * Tasklet is strictly serialized wrt itself, but not wrt another tasklets. If client needs some intertask synchronization, he makes it with spinlocks. -@@ -546,27 +547,36 @@ struct tasklet_struct name = { NULL, 0, +@@ -555,27 +556,36 @@ struct tasklet_struct name = { NULL, 0, enum { TASKLET_STATE_SCHED, /* Tasklet is scheduled for execution */ @@ -98,7 +98,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #define tasklet_unlock_wait(t) do { } while (0) #define tasklet_unlock(t) do { } while (0) #endif -@@ -615,12 +625,7 @@ static inline void tasklet_disable(struc +@@ -624,12 +634,7 @@ static inline void tasklet_disable(struc smp_mb(); } diff --git a/patches/time-hrtimer-Use-softirq-based-wakeups-for-non-RT-th.patch b/patches/time-hrtimer-Use-softirq-based-wakeups-for-non-RT-th.patch deleted file mode 100644 index 26a9dbd0e997..000000000000 --- a/patches/time-hrtimer-Use-softirq-based-wakeups-for-non-RT-th.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Wed, 4 Oct 2017 16:47:19 +0200 -Subject: [PATCH RT] time/hrtimer: Use softirq based wakeups for non-RT threads - -Normal wake ups (like clock_nanosleep()) which are performed by normal -users can easily lead to 2ms latency spikes if (enough) hrtimer wakeups -are synchronized. -This patch moves all hrtimers wakeups to the softirq queue unless the -caller has a RT priority. - -Reported-by: Gratian Crisan <gratian.crisan@ni.com> -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/time/hrtimer.c | 21 +++++++++++++++++++-- - 1 file changed, 19 insertions(+), 2 deletions(-) - ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -1606,14 +1606,31 @@ static enum hrtimer_restart hrtimer_wake - return HRTIMER_NORESTART; - } - -+#ifdef CONFIG_PREEMPT_RT_FULL -+static bool task_is_elevated(struct task_struct *tsk) -+{ -+ int policy = tsk->policy; -+ -+ if (policy == SCHED_FIFO || policy == SCHED_RR) -+ return true; -+ if (policy == SCHED_DEADLINE) -+ return true; -+ return false; -+} -+#endif -+ - static void __hrtimer_init_sleeper(struct hrtimer_sleeper *sl, - clockid_t clock_id, - enum hrtimer_mode mode, - struct task_struct *task) - { - #ifdef CONFIG_PREEMPT_RT_FULL -- if (!(clock_id & HRTIMER_BASE_SOFT_MASK)) -- clock_id |= HRTIMER_BASE_HARD_MASK; -+ if (!(clock_id & (HRTIMER_BASE_HARD_MASK | HRTIMER_BASE_SOFT_MASK))) { -+ if (task_is_elevated(current) || system_state != SYSTEM_RUNNING) -+ clock_id |= HRTIMER_BASE_HARD_MASK; -+ else -+ clock_id |= HRTIMER_BASE_SOFT_MASK; -+ } - #endif - __hrtimer_init(&sl->timer, clock_id, mode); - sl->timer.function = hrtimer_wakeup; diff --git a/patches/time-hrtimer-use-a-MONOTIC-clock-for-relative-REALTI.patch b/patches/time-hrtimer-use-a-MONOTIC-clock-for-relative-REALTI.patch deleted file mode 100644 index 829fb928a733..000000000000 --- a/patches/time-hrtimer-use-a-MONOTIC-clock-for-relative-REALTI.patch +++ /dev/null @@ -1,26 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Wed, 11 Oct 2017 10:23:00 +0200 -Subject: [PATCH] time/hrtimer: use a MONOTIC clock for "relative" REALTIME - sleep - -clock_nanosleep(CLOCK_REALTIME, ) with a relative delay/time should not -be effected by clock_settime(CLOCK_REALTIME,) thus we need to use -CLOCK_MONOTONIC instead. This is already done for the clock itself and -for the SOFT-irq based clock but was forgotten for the HARD-irq clock. - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/time/hrtimer.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/kernel/time/hrtimer.c -+++ b/kernel/time/hrtimer.c -@@ -1234,6 +1234,8 @@ static void __hrtimer_init(struct hrtime - clock_id = CLOCK_MONOTONIC; - else if (clock_id == CLOCK_REALTIME_SOFT) - clock_id = CLOCK_MONOTONIC_SOFT; -+ else if (clock_id == CLOCK_REALTIME_HARD) -+ clock_id = CLOCK_MONOTONIC_HARD; - } - - base = hrtimer_clockid_to_base(clock_id); diff --git a/patches/timekeeping-split-jiffies-lock.patch b/patches/timekeeping-split-jiffies-lock.patch index 44860444fa46..1f30043f19cd 100644 --- a/patches/timekeeping-split-jiffies-lock.patch +++ b/patches/timekeeping-split-jiffies-lock.patch @@ -114,7 +114,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return period; } -@@ -672,10 +677,10 @@ static ktime_t tick_nohz_stop_sched_tick +@@ -684,10 +689,10 @@ static ktime_t tick_nohz_stop_sched_tick /* Read jiffies and the time when jiffies were updated last */ do { @@ -129,7 +129,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> if (rcu_needs_cpu(basemono, &next_rcu) || --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c -@@ -2323,8 +2323,10 @@ EXPORT_SYMBOL(hardpps); +@@ -2326,8 +2326,10 @@ EXPORT_SYMBOL(hardpps); */ void xtime_update(unsigned long ticks) { diff --git a/patches/timer-delay-waking-softirqs-from-the-jiffy-tick.patch b/patches/timer-delay-waking-softirqs-from-the-jiffy-tick.patch index 720089a460de..627ea936f4ef 100644 --- a/patches/timer-delay-waking-softirqs-from-the-jiffy-tick.patch +++ b/patches/timer-delay-waking-softirqs-from-the-jiffy-tick.patch @@ -58,7 +58,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/kernel/time/timer.c +++ b/kernel/time/timer.c -@@ -1601,13 +1601,13 @@ void update_process_times(int user_tick) +@@ -1620,13 +1620,13 @@ void update_process_times(int user_tick) /* Note: this timer irq context must be accounted for as well. */ account_process_tick(p, user_tick); diff --git a/patches/timer-fd-avoid-live-lock.patch b/patches/timer-fd-avoid-live-lock.patch index 31a9b1b5ea4a..40bc39571447 100644 --- a/patches/timer-fd-avoid-live-lock.patch +++ b/patches/timer-fd-avoid-live-lock.patch @@ -16,7 +16,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/fs/timerfd.c +++ b/fs/timerfd.c -@@ -471,7 +471,10 @@ static int do_timerfd_settime(int ufd, i +@@ -470,7 +470,10 @@ static int do_timerfd_settime(int ufd, i break; } spin_unlock_irq(&ctx->wqh.lock); diff --git a/patches/timer-make-the-base-lock-raw.patch b/patches/timer-make-the-base-lock-raw.patch deleted file mode 100644 index f3f6f8800276..000000000000 --- a/patches/timer-make-the-base-lock-raw.patch +++ /dev/null @@ -1,180 +0,0 @@ -From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> -Date: Wed, 13 Jul 2016 18:22:23 +0200 -Subject: [PATCH] timer: make the base lock raw - -The part where the base lock is held got more predictable / shorter after the -timer rework. One reason is the lack of re-cascading. -That means the lock can be made raw and held in IRQ context. - -Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> ---- - kernel/time/timer.c | 48 ++++++++++++++++++++++++------------------------ - 1 file changed, 24 insertions(+), 24 deletions(-) - ---- a/kernel/time/timer.c -+++ b/kernel/time/timer.c -@@ -195,7 +195,7 @@ EXPORT_SYMBOL(jiffies_64); - #endif - - struct timer_base { -- spinlock_t lock; -+ raw_spinlock_t lock; - struct timer_list *running_timer; - unsigned long clk; - unsigned long next_expiry; -@@ -913,10 +913,10 @@ static struct timer_base *lock_timer_bas - - if (!(tf & TIMER_MIGRATING)) { - base = get_timer_base(tf); -- spin_lock_irqsave(&base->lock, *flags); -+ raw_spin_lock_irqsave(&base->lock, *flags); - if (timer->flags == tf) - return base; -- spin_unlock_irqrestore(&base->lock, *flags); -+ raw_spin_unlock_irqrestore(&base->lock, *flags); - } - cpu_relax(); - } -@@ -986,9 +986,9 @@ static inline int - /* See the comment in lock_timer_base() */ - timer->flags |= TIMER_MIGRATING; - -- spin_unlock(&base->lock); -+ raw_spin_unlock(&base->lock); - base = new_base; -- spin_lock(&base->lock); -+ raw_spin_lock(&base->lock); - WRITE_ONCE(timer->flags, - (timer->flags & ~TIMER_BASEMASK) | base->cpu); - } -@@ -1013,7 +1013,7 @@ static inline int - } - - out_unlock: -- spin_unlock_irqrestore(&base->lock, flags); -+ raw_spin_unlock_irqrestore(&base->lock, flags); - - return ret; - } -@@ -1106,16 +1106,16 @@ void add_timer_on(struct timer_list *tim - if (base != new_base) { - timer->flags |= TIMER_MIGRATING; - -- spin_unlock(&base->lock); -+ raw_spin_unlock(&base->lock); - base = new_base; -- spin_lock(&base->lock); -+ raw_spin_lock(&base->lock); - WRITE_ONCE(timer->flags, - (timer->flags & ~TIMER_BASEMASK) | cpu); - } - - debug_activate(timer, timer->expires); - internal_add_timer(base, timer); -- spin_unlock_irqrestore(&base->lock, flags); -+ raw_spin_unlock_irqrestore(&base->lock, flags); - } - EXPORT_SYMBOL_GPL(add_timer_on); - -@@ -1141,7 +1141,7 @@ int del_timer(struct timer_list *timer) - if (timer_pending(timer)) { - base = lock_timer_base(timer, &flags); - ret = detach_if_pending(timer, base, true); -- spin_unlock_irqrestore(&base->lock, flags); -+ raw_spin_unlock_irqrestore(&base->lock, flags); - } - - return ret; -@@ -1168,7 +1168,7 @@ int try_to_del_timer_sync(struct timer_l - if (base->running_timer != timer) - ret = detach_if_pending(timer, base, true); - -- spin_unlock_irqrestore(&base->lock, flags); -+ raw_spin_unlock_irqrestore(&base->lock, flags); - - return ret; - } -@@ -1299,13 +1299,13 @@ static void expire_timers(struct timer_b - data = timer->data; - - if (timer->flags & TIMER_IRQSAFE) { -- spin_unlock(&base->lock); -+ raw_spin_unlock(&base->lock); - call_timer_fn(timer, fn, data); -- spin_lock(&base->lock); -+ raw_spin_lock(&base->lock); - } else { -- spin_unlock_irq(&base->lock); -+ raw_spin_unlock_irq(&base->lock); - call_timer_fn(timer, fn, data); -- spin_lock_irq(&base->lock); -+ raw_spin_lock_irq(&base->lock); - } - } - } -@@ -1474,7 +1474,7 @@ u64 get_next_timer_interrupt(unsigned lo - if (cpu_is_offline(smp_processor_id())) - return expires; - -- spin_lock(&base->lock); -+ raw_spin_lock(&base->lock); - nextevt = __next_timer_interrupt(base); - is_max_delta = (nextevt == base->clk + NEXT_TIMER_MAX_DELTA); - base->next_expiry = nextevt; -@@ -1502,7 +1502,7 @@ u64 get_next_timer_interrupt(unsigned lo - if ((expires - basem) > TICK_NSEC) - base->is_idle = true; - } -- spin_unlock(&base->lock); -+ raw_spin_unlock(&base->lock); - - return cmp_next_hrtimer_event(basem, expires); - } -@@ -1590,7 +1590,7 @@ static inline void __run_timers(struct t - if (!time_after_eq(jiffies, base->clk)) - return; - -- spin_lock_irq(&base->lock); -+ raw_spin_lock_irq(&base->lock); - - while (time_after_eq(jiffies, base->clk)) { - -@@ -1601,7 +1601,7 @@ static inline void __run_timers(struct t - expire_timers(base, heads + levels); - } - base->running_timer = NULL; -- spin_unlock_irq(&base->lock); -+ raw_spin_unlock_irq(&base->lock); - } - - /* -@@ -1786,16 +1786,16 @@ int timers_dead_cpu(unsigned int cpu) - * The caller is globally serialized and nobody else - * takes two locks at once, deadlock is not possible. - */ -- spin_lock_irq(&new_base->lock); -- spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING); -+ raw_spin_lock_irq(&new_base->lock); -+ raw_spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING); - - BUG_ON(old_base->running_timer); - - for (i = 0; i < WHEEL_SIZE; i++) - migrate_timer_list(new_base, old_base->vectors + i); - -- spin_unlock(&old_base->lock); -- spin_unlock_irq(&new_base->lock); -+ raw_spin_unlock(&old_base->lock); -+ raw_spin_unlock_irq(&new_base->lock); - put_cpu_ptr(&timer_bases); - } - return 0; -@@ -1811,7 +1811,7 @@ static void __init init_timer_cpu(int cp - for (i = 0; i < NR_BASES; i++) { - base = per_cpu_ptr(&timer_bases[i], cpu); - base->cpu = cpu; -- spin_lock_init(&base->lock); -+ raw_spin_lock_init(&base->lock); - base->clk = jiffies; - } - } diff --git a/patches/timers-prepare-for-full-preemption.patch b/patches/timers-prepare-for-full-preemption.patch index 31d72aebf301..6af63f6d67a5 100644 --- a/patches/timers-prepare-for-full-preemption.patch +++ b/patches/timers-prepare-for-full-preemption.patch @@ -28,7 +28,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> # define del_timer_sync(t) del_timer(t) --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -532,11 +532,14 @@ void resched_cpu(int cpu) +@@ -523,11 +523,14 @@ void resched_cpu(int cpu) */ int get_nohz_timer_target(void) { @@ -45,7 +45,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> rcu_read_lock(); for_each_domain(cpu, sd) { -@@ -555,6 +558,8 @@ int get_nohz_timer_target(void) +@@ -546,6 +549,8 @@ int get_nohz_timer_target(void) cpu = housekeeping_any_cpu(); unlock: rcu_read_unlock(); @@ -74,7 +74,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> unsigned long clk; unsigned long next_expiry; unsigned int cpu; -@@ -1119,6 +1123,33 @@ void add_timer_on(struct timer_list *tim +@@ -1132,6 +1136,33 @@ void add_timer_on(struct timer_list *tim } EXPORT_SYMBOL_GPL(add_timer_on); @@ -92,7 +92,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> + + base = get_timer_base(tf); + swait_event(base->wait_for_running_timer, -+ base->running_timer != timer); ++ base->running_timer != timer); +} + +# define wakeup_timer_waiters(b) swake_up_all(&(b)->wait_for_running_timer) @@ -106,9 +106,9 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +#endif + /** - * del_timer - deactive a timer. + * del_timer - deactivate a timer. * @timer: the timer to be deactivated -@@ -1174,7 +1205,7 @@ int try_to_del_timer_sync(struct timer_l +@@ -1187,7 +1218,7 @@ int try_to_del_timer_sync(struct timer_l } EXPORT_SYMBOL(try_to_del_timer_sync); @@ -117,7 +117,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /** * del_timer_sync - deactivate a timer and wait for the handler to finish. * @timer: the timer to be deactivated -@@ -1234,7 +1265,7 @@ int del_timer_sync(struct timer_list *ti +@@ -1247,7 +1278,7 @@ int del_timer_sync(struct timer_list *ti int ret = try_to_del_timer_sync(timer); if (ret >= 0) return ret; @@ -126,7 +126,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } } EXPORT_SYMBOL(del_timer_sync); -@@ -1298,13 +1329,16 @@ static void expire_timers(struct timer_b +@@ -1311,13 +1342,16 @@ static void expire_timers(struct timer_b fn = timer->function; data = timer->data; @@ -144,7 +144,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> raw_spin_lock_irq(&base->lock); } } -@@ -1600,8 +1634,8 @@ static inline void __run_timers(struct t +@@ -1619,8 +1653,8 @@ static inline void __run_timers(struct t while (levels--) expire_timers(base, heads + levels); } @@ -154,7 +154,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } /* -@@ -1813,6 +1847,9 @@ static void __init init_timer_cpu(int cp +@@ -1845,6 +1879,9 @@ static void __init init_timer_cpu(int cp base->cpu = cpu; raw_spin_lock_init(&base->lock); base->clk = jiffies; diff --git a/patches/tracing-account-for-preempt-off-in-preempt_schedule.patch b/patches/tracing-account-for-preempt-off-in-preempt_schedule.patch index ed02d08e40bf..a0a8d090338a 100644 --- a/patches/tracing-account-for-preempt-off-in-preempt_schedule.patch +++ b/patches/tracing-account-for-preempt-off-in-preempt_schedule.patch @@ -27,7 +27,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -3654,7 +3654,16 @@ asmlinkage __visible void __sched notrac +@@ -3571,7 +3571,16 @@ asmlinkage __visible void __sched notrac * an infinite recursion. */ prev_ctx = exception_enter(); diff --git a/patches/tty-serial-8250-don-t-take-the-trylock-during-oops.patch b/patches/tty-serial-8250-don-t-take-the-trylock-during-oops.patch index 609e361caa6c..2e55c765cd47 100644 --- a/patches/tty-serial-8250-don-t-take-the-trylock-during-oops.patch +++ b/patches/tty-serial-8250-don-t-take-the-trylock-during-oops.patch @@ -14,7 +14,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c -@@ -3179,10 +3179,8 @@ void serial8250_console_write(struct uar +@@ -3189,10 +3189,8 @@ void serial8250_console_write(struct uar serial8250_rpm_get(up); diff --git a/patches/upstream-net-rt-remove-preemption-disabling-in-netif_rx.patch b/patches/upstream-net-rt-remove-preemption-disabling-in-netif_rx.patch index c29771a0373f..d0c0b2e7a2de 100644 --- a/patches/upstream-net-rt-remove-preemption-disabling-in-netif_rx.patch +++ b/patches/upstream-net-rt-remove-preemption-disabling-in-netif_rx.patch @@ -37,7 +37,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/net/core/dev.c +++ b/net/core/dev.c -@@ -3799,7 +3799,7 @@ static int netif_rx_internal(struct sk_b +@@ -3885,7 +3885,7 @@ static int netif_rx_internal(struct sk_b struct rps_dev_flow voidflow, *rflow = &voidflow; int cpu; @@ -46,7 +46,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> rcu_read_lock(); cpu = get_rps_cpu(skb->dev, skb, &rflow); -@@ -3809,14 +3809,14 @@ static int netif_rx_internal(struct sk_b +@@ -3895,14 +3895,14 @@ static int netif_rx_internal(struct sk_b ret = enqueue_to_backlog(skb, cpu, &rflow->last_qtail); rcu_read_unlock(); diff --git a/patches/usb-use-_nort-in-giveback.patch b/patches/usb-use-_nort-in-giveback.patch index 3f470e136b68..c05d4d70c508 100644 --- a/patches/usb-use-_nort-in-giveback.patch +++ b/patches/usb-use-_nort-in-giveback.patch @@ -43,7 +43,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c -@@ -1764,9 +1764,9 @@ static void __usb_hcd_giveback_urb(struc +@@ -1775,9 +1775,9 @@ static void __usb_hcd_giveback_urb(struc * and no one may trigger the above deadlock situation when * running complete() in tasklet. */ diff --git a/patches/wait.h-include-atomic.h.patch b/patches/wait.h-include-atomic.h.patch index 147eb733c945..4c101b8c3d6d 100644 --- a/patches/wait.h-include-atomic.h.patch +++ b/patches/wait.h-include-atomic.h.patch @@ -28,5 +28,5 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> #include <uapi/linux/wait.h> +#include <linux/atomic.h> - typedef struct __wait_queue wait_queue_t; - typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, void *key); + typedef struct wait_queue_entry wait_queue_entry_t; + diff --git a/patches/work-simple-Simple-work-queue-implemenation.patch b/patches/work-simple-Simple-work-queue-implemenation.patch index 3ca550e0228e..dbaa1ab13eb8 100644 --- a/patches/work-simple-Simple-work-queue-implemenation.patch +++ b/patches/work-simple-Simple-work-queue-implemenation.patch @@ -47,10 +47,10 @@ Signed-off-by: Daniel Wagner <daniel.wagner@bmw-carit.de> @@ -17,7 +17,7 @@ endif obj-y += core.o loadavg.o clock.o cputime.o - obj-y += idle_task.o fair.o rt.o deadline.o stop_task.o --obj-y += wait.o swait.o completion.o idle.o -+obj-y += wait.o swait.o swork.o completion.o idle.o - obj-$(CONFIG_SMP) += cpupri.o cpudeadline.o topology.o + obj-y += idle_task.o fair.o rt.o deadline.o +-obj-y += wait.o wait_bit.o swait.o completion.o idle.o ++obj-y += wait.o wait_bit.o swait.o swork.o completion.o idle.o + obj-$(CONFIG_SMP) += cpupri.o cpudeadline.o topology.o stop_task.o obj-$(CONFIG_SCHED_AUTOGROUP) += autogroup.o obj-$(CONFIG_SCHEDSTATS) += stats.o --- /dev/null diff --git a/patches/workqueue-distangle-from-rq-lock.patch b/patches/workqueue-distangle-from-rq-lock.patch index f0366227c246..db5f6e22e052 100644 --- a/patches/workqueue-distangle-from-rq-lock.patch +++ b/patches/workqueue-distangle-from-rq-lock.patch @@ -24,14 +24,14 @@ Link: http://lkml.kernel.org/r/20110622174919.135236139@linutronix.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- - kernel/sched/core.c | 86 +++++++------------------------------------- - kernel/workqueue.c | 52 +++++++++++--------------- + kernel/sched/core.c | 84 +++++++------------------------------------- + kernel/workqueue.c | 52 ++++++++++++--------------- kernel/workqueue_internal.h | 5 +- - 3 files changed, 41 insertions(+), 102 deletions(-) + 3 files changed, 41 insertions(+), 100 deletions(-) --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -1700,10 +1700,6 @@ static inline void ttwu_activate(struct +@@ -1707,10 +1707,6 @@ static inline void ttwu_activate(struct { activate_task(rq, p, en_flags); p->on_rq = TASK_ON_RQ_QUEUED; @@ -42,13 +42,13 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } /* -@@ -2156,58 +2152,6 @@ try_to_wake_up(struct task_struct *p, un +@@ -2151,56 +2147,6 @@ try_to_wake_up(struct task_struct *p, un } /** - * try_to_wake_up_local - try to wake up a local task with rq lock held - * @p: the thread to be awakened -- * @cookie: context's cookie for pinning +- * @rf: request-queue flags for pinning - * - * Put @p on the run-queue if it's not already there. The caller must - * ensure that this_rq() is locked, @p is bound to this_rq() and not @@ -71,11 +71,9 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> - * disabled avoiding further scheduler activity on it and we've - * not yet picked a replacement task. - */ -- rq_unpin_lock(rq, rf); -- raw_spin_unlock(&rq->lock); +- rq_unlock(rq, rf); - raw_spin_lock(&p->pi_lock); -- raw_spin_lock(&rq->lock); -- rq_repin_lock(rq, rf); +- rq_relock(rq, rf); - } - - if (!(p->state & TASK_NORMAL)) @@ -88,7 +86,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> - delayacct_blkio_end(); - atomic_dec(&rq->nr_iowait); - } -- ttwu_activate(rq, p, ENQUEUE_WAKEUP); +- ttwu_activate(rq, p, ENQUEUE_WAKEUP | ENQUEUE_NOCLOCK); - } - - ttwu_do_wakeup(rq, p, 0, rf); @@ -101,7 +99,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> * wake_up_process - Wake up a specific process * @p: The process to be woken up. * -@@ -3495,21 +3439,6 @@ static void __sched notrace __schedule(b +@@ -3391,21 +3337,6 @@ static void __sched notrace __schedule(b atomic_inc(&rq->nr_iowait); delayacct_blkio_start(); } @@ -123,7 +121,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } switch_count = &prev->nvcsw; } -@@ -3574,6 +3503,14 @@ static inline void sched_submit_work(str +@@ -3466,6 +3397,14 @@ static inline void sched_submit_work(str { if (!tsk->state || tsk_is_pi_blocked(tsk)) return; @@ -138,7 +136,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> /* * If we are going to sleep and we have plugged IO queued, * make sure to submit it to avoid deadlocks. -@@ -3582,6 +3519,12 @@ static inline void sched_submit_work(str +@@ -3474,6 +3413,12 @@ static inline void sched_submit_work(str blk_schedule_flush_plug(tsk); } @@ -151,7 +149,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> asmlinkage __visible void __sched schedule(void) { struct task_struct *tsk = current; -@@ -3592,6 +3535,7 @@ asmlinkage __visible void __sched schedu +@@ -3484,6 +3429,7 @@ asmlinkage __visible void __sched schedu __schedule(false); sched_preempt_enable_no_resched(); } while (need_resched()); diff --git a/patches/workqueue-prevent-deadlock-stall.patch b/patches/workqueue-prevent-deadlock-stall.patch index c889fd1d09e3..ea68e89ea3f3 100644 --- a/patches/workqueue-prevent-deadlock-stall.patch +++ b/patches/workqueue-prevent-deadlock-stall.patch @@ -43,7 +43,7 @@ Cc: Steven Rostedt <rostedt@goodmis.org> --- a/kernel/sched/core.c +++ b/kernel/sched/core.c -@@ -3547,9 +3547,8 @@ void __noreturn do_task_dead(void) +@@ -3441,9 +3441,8 @@ void __noreturn do_task_dead(void) static inline void sched_submit_work(struct task_struct *tsk) { @@ -54,7 +54,7 @@ Cc: Steven Rostedt <rostedt@goodmis.org> /* * If a worker went to sleep, notify and ask workqueue whether * it wants to wake up a task to maintain concurrency. -@@ -3557,6 +3556,10 @@ static inline void sched_submit_work(str +@@ -3451,6 +3450,10 @@ static inline void sched_submit_work(str if (tsk->flags & PF_WQ_WORKER) wq_worker_sleeping(tsk); diff --git a/patches/workqueue-use-rcu.patch b/patches/workqueue-use-rcu.patch index 0e4370c589b2..fe6251b9ab49 100644 --- a/patches/workqueue-use-rcu.patch +++ b/patches/workqueue-use-rcu.patch @@ -207,7 +207,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return false; } -@@ -3258,7 +3263,7 @@ static void rcu_free_pool(struct rcu_hea +@@ -3257,7 +3262,7 @@ static void rcu_free_pool(struct rcu_hea * put_unbound_pool - put a worker_pool * @pool: worker_pool to put * @@ -216,7 +216,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> * safe manner. get_unbound_pool() calls this function on its failure path * and this function should be able to release pools which went through, * successfully or not, init_worker_pool(). -@@ -3312,8 +3317,8 @@ static void put_unbound_pool(struct work +@@ -3311,8 +3316,8 @@ static void put_unbound_pool(struct work del_timer_sync(&pool->idle_timer); del_timer_sync(&pool->mayday_timer); @@ -227,7 +227,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } /** -@@ -3420,14 +3425,14 @@ static void pwq_unbound_release_workfn(s +@@ -3419,14 +3424,14 @@ static void pwq_unbound_release_workfn(s put_unbound_pool(pool); mutex_unlock(&wq_pool_mutex); @@ -244,7 +244,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } /** -@@ -4081,7 +4086,7 @@ void destroy_workqueue(struct workqueue_ +@@ -4101,7 +4106,7 @@ void destroy_workqueue(struct workqueue_ * The base ref is never dropped on per-cpu pwqs. Directly * schedule RCU free. */ @@ -253,7 +253,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } else { /* * We're the sole accessor of @wq at this point. Directly -@@ -4174,7 +4179,8 @@ bool workqueue_congested(int cpu, struct +@@ -4195,7 +4200,8 @@ bool workqueue_congested(int cpu, struct struct pool_workqueue *pwq; bool ret; @@ -263,7 +263,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> if (cpu == WORK_CPU_UNBOUND) cpu = smp_processor_id(); -@@ -4185,7 +4191,8 @@ bool workqueue_congested(int cpu, struct +@@ -4206,7 +4212,8 @@ bool workqueue_congested(int cpu, struct pwq = unbound_pwq_by_node(wq, cpu_to_node(cpu)); ret = !list_empty(&pwq->delayed_works); @@ -273,7 +273,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return ret; } -@@ -4211,15 +4218,15 @@ unsigned int work_busy(struct work_struc +@@ -4232,15 +4239,15 @@ unsigned int work_busy(struct work_struc if (work_pending(work)) ret |= WORK_BUSY_PENDING; @@ -293,7 +293,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return ret; } -@@ -4408,7 +4415,7 @@ void show_workqueue_state(void) +@@ -4429,7 +4436,7 @@ void show_workqueue_state(void) unsigned long flags; int pi; @@ -302,7 +302,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> pr_info("Showing busy workqueues and worker pools:\n"); -@@ -4461,7 +4468,7 @@ void show_workqueue_state(void) +@@ -4482,7 +4489,7 @@ void show_workqueue_state(void) spin_unlock_irqrestore(&pool->lock, flags); } @@ -311,7 +311,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } /* -@@ -4822,16 +4829,16 @@ bool freeze_workqueues_busy(void) +@@ -4843,16 +4850,16 @@ bool freeze_workqueues_busy(void) * nr_active is monotonically decreasing. It's safe * to peek without lock. */ @@ -331,7 +331,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> } out_unlock: mutex_unlock(&wq_pool_mutex); -@@ -5021,7 +5028,8 @@ static ssize_t wq_pool_ids_show(struct d +@@ -5042,7 +5049,8 @@ static ssize_t wq_pool_ids_show(struct d const char *delim = ""; int node, written = 0; @@ -341,7 +341,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> for_each_node(node) { written += scnprintf(buf + written, PAGE_SIZE - written, "%s%d:%d", delim, node, -@@ -5029,7 +5037,8 @@ static ssize_t wq_pool_ids_show(struct d +@@ -5050,7 +5058,8 @@ static ssize_t wq_pool_ids_show(struct d delim = " "; } written += scnprintf(buf + written, PAGE_SIZE - written, "\n"); diff --git a/patches/x86-UV-raw_spinlock-conversion.patch b/patches/x86-UV-raw_spinlock-conversion.patch index fe5fe849833f..33a21cb8fd32 100644 --- a/patches/x86-UV-raw_spinlock-conversion.patch +++ b/patches/x86-UV-raw_spinlock-conversion.patch @@ -15,7 +15,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/arch/x86/include/asm/uv/uv_bau.h +++ b/arch/x86/include/asm/uv/uv_bau.h -@@ -624,9 +624,9 @@ struct bau_control { +@@ -643,9 +643,9 @@ struct bau_control { cycles_t send_message; cycles_t period_end; cycles_t period_time; @@ -28,7 +28,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> /* tunables */ int max_concurr; int max_concurr_const; -@@ -815,15 +815,15 @@ static inline int atom_asr(short i, stru +@@ -847,15 +847,15 @@ static inline int atom_asr(short i, stru * to be lowered below the current 'v'. atomic_add_unless can only stop * on equal. */ @@ -50,7 +50,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- a/arch/x86/platform/uv/tlb_uv.c +++ b/arch/x86/platform/uv/tlb_uv.c -@@ -747,9 +747,9 @@ static void destination_plugged(struct b +@@ -740,9 +740,9 @@ static void destination_plugged(struct b quiesce_local_uvhub(hmaster); @@ -62,7 +62,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> end_uvhub_quiesce(hmaster); -@@ -769,9 +769,9 @@ static void destination_timeout(struct b +@@ -762,9 +762,9 @@ static void destination_timeout(struct b quiesce_local_uvhub(hmaster); @@ -74,7 +74,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> end_uvhub_quiesce(hmaster); -@@ -792,7 +792,7 @@ static void disable_for_period(struct ba +@@ -785,7 +785,7 @@ static void disable_for_period(struct ba cycles_t tm1; hmaster = bcp->uvhub_master; @@ -83,7 +83,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (!bcp->baudisabled) { stat->s_bau_disabled++; tm1 = get_cycles(); -@@ -805,7 +805,7 @@ static void disable_for_period(struct ba +@@ -798,7 +798,7 @@ static void disable_for_period(struct ba } } } @@ -92,7 +92,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> } static void count_max_concurr(int stat, struct bau_control *bcp, -@@ -868,7 +868,7 @@ static void record_send_stats(cycles_t t +@@ -861,7 +861,7 @@ static void record_send_stats(cycles_t t */ static void uv1_throttle(struct bau_control *hmaster, struct ptc_stats *stat) { @@ -101,7 +101,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> atomic_t *v; v = &hmaster->active_descriptor_count; -@@ -1001,7 +1001,7 @@ static int check_enable(struct bau_contr +@@ -995,7 +995,7 @@ static int check_enable(struct bau_contr struct bau_control *hmaster; hmaster = bcp->uvhub_master; @@ -110,7 +110,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> if (bcp->baudisabled && (get_cycles() >= bcp->set_bau_on_time)) { stat->s_bau_reenabled++; for_each_present_cpu(tcpu) { -@@ -1013,10 +1013,10 @@ static int check_enable(struct bau_contr +@@ -1007,10 +1007,10 @@ static int check_enable(struct bau_contr tbcp->period_giveups = 0; } } @@ -123,7 +123,7 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> return -1; } -@@ -1938,9 +1938,9 @@ static void __init init_per_cpu_tunables +@@ -1941,9 +1941,9 @@ static void __init init_per_cpu_tunables bcp->cong_reps = congested_reps; bcp->disabled_period = sec_2_cycles(disabled_period); bcp->giveup_limit = giveup_limit; diff --git a/patches/x86-crypto-reduce-preempt-disabled-regions.patch b/patches/x86-crypto-reduce-preempt-disabled-regions.patch index 3bade762e020..c6686dad6a49 100644 --- a/patches/x86-crypto-reduce-preempt-disabled-regions.patch +++ b/patches/x86-crypto-reduce-preempt-disabled-regions.patch @@ -18,7 +18,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/arch/x86/crypto/aesni-intel_glue.c +++ b/arch/x86/crypto/aesni-intel_glue.c -@@ -374,14 +374,14 @@ static int ecb_encrypt(struct skcipher_r +@@ -386,14 +386,14 @@ static int ecb_encrypt(struct skcipher_r err = skcipher_walk_virt(&walk, req, true); @@ -35,7 +35,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return err; } -@@ -396,14 +396,14 @@ static int ecb_decrypt(struct skcipher_r +@@ -408,14 +408,14 @@ static int ecb_decrypt(struct skcipher_r err = skcipher_walk_virt(&walk, req, true); @@ -52,7 +52,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return err; } -@@ -418,14 +418,14 @@ static int cbc_encrypt(struct skcipher_r +@@ -430,14 +430,14 @@ static int cbc_encrypt(struct skcipher_r err = skcipher_walk_virt(&walk, req, true); @@ -69,7 +69,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return err; } -@@ -440,14 +440,14 @@ static int cbc_decrypt(struct skcipher_r +@@ -452,14 +452,14 @@ static int cbc_decrypt(struct skcipher_r err = skcipher_walk_virt(&walk, req, true); @@ -86,7 +86,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> return err; } -@@ -497,18 +497,20 @@ static int ctr_crypt(struct skcipher_req +@@ -509,18 +509,20 @@ static int ctr_crypt(struct skcipher_req err = skcipher_walk_virt(&walk, req, true); diff --git a/patches/x86-io-apic-migra-no-unmask.patch b/patches/x86-io-apic-migra-no-unmask.patch index 2d8afd851adf..30457f5b67fc 100644 --- a/patches/x86-io-apic-migra-no-unmask.patch +++ b/patches/x86-io-apic-migra-no-unmask.patch @@ -15,7 +15,7 @@ xXx --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c -@@ -1711,7 +1711,8 @@ static bool io_apic_level_ack_pending(st +@@ -1689,7 +1689,8 @@ static bool io_apic_level_ack_pending(st static inline bool ioapic_irqd_mask(struct irq_data *data) { /* If we are moving the irq we need to mask it */ diff --git a/patches/x86-kvm-require-const-tsc-for-rt.patch b/patches/x86-kvm-require-const-tsc-for-rt.patch index 916812dca44c..76b7e5e2052f 100644 --- a/patches/x86-kvm-require-const-tsc-for-rt.patch +++ b/patches/x86-kvm-require-const-tsc-for-rt.patch @@ -14,7 +14,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c -@@ -6118,6 +6118,13 @@ int kvm_arch_init(void *opaque) +@@ -6115,6 +6115,13 @@ int kvm_arch_init(void *opaque) goto out; } diff --git a/patches/x86-mce-timer-hrtimer.patch b/patches/x86-mce-timer-hrtimer.patch index 6002f4f1dd06..5da8d272cf4b 100644 --- a/patches/x86-mce-timer-hrtimer.patch +++ b/patches/x86-mce-timer-hrtimer.patch @@ -26,7 +26,7 @@ fold in: --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c -@@ -41,6 +41,7 @@ +@@ -42,6 +42,7 @@ #include <linux/debugfs.h> #include <linux/irq_work.h> #include <linux/export.h> @@ -34,7 +34,7 @@ fold in: #include <linux/jump_label.h> #include <asm/intel-family.h> -@@ -1315,7 +1316,7 @@ int memory_failure(unsigned long pfn, in +@@ -1345,7 +1346,7 @@ int memory_failure(unsigned long pfn, in static unsigned long check_interval = INITIAL_CHECK_INTERVAL; static DEFINE_PER_CPU(unsigned long, mce_next_interval); /* in jiffies */ @@ -43,7 +43,7 @@ fold in: static unsigned long mce_adjust_timer_default(unsigned long interval) { -@@ -1324,27 +1325,19 @@ static unsigned long mce_adjust_timer_de +@@ -1354,27 +1355,19 @@ static unsigned long mce_adjust_timer_de static unsigned long (*mce_adjust_timer)(unsigned long interval) = mce_adjust_timer_default; @@ -77,7 +77,7 @@ fold in: iv = __this_cpu_read(mce_next_interval); if (mce_available(this_cpu_ptr(&cpu_info))) { -@@ -1367,7 +1360,11 @@ static void mce_timer_fn(unsigned long d +@@ -1397,7 +1390,11 @@ static void mce_timer_fn(unsigned long d done: __this_cpu_write(mce_next_interval, iv); @@ -90,7 +90,7 @@ fold in: } /* -@@ -1375,7 +1372,7 @@ static void mce_timer_fn(unsigned long d +@@ -1405,7 +1402,7 @@ static void mce_timer_fn(unsigned long d */ void mce_timer_kick(unsigned long interval) { @@ -99,7 +99,7 @@ fold in: unsigned long iv = __this_cpu_read(mce_next_interval); __start_timer(t, interval); -@@ -1390,7 +1387,7 @@ static void mce_timer_delete_all(void) +@@ -1420,7 +1417,7 @@ static void mce_timer_delete_all(void) int cpu; for_each_online_cpu(cpu) @@ -107,8 +107,8 @@ fold in: + hrtimer_cancel(&per_cpu(mce_timer, cpu)); } - static void mce_do_trigger(struct work_struct *work) -@@ -1725,7 +1722,7 @@ static void __mcheck_cpu_clear_vendor(st + /* +@@ -1749,7 +1746,7 @@ static void __mcheck_cpu_clear_vendor(st } } @@ -117,7 +117,7 @@ fold in: { unsigned long iv = check_interval * HZ; -@@ -1738,18 +1735,19 @@ static void mce_start_timer(struct timer +@@ -1762,18 +1759,19 @@ static void mce_start_timer(struct timer static void __mcheck_cpu_setup_timer(void) { @@ -143,7 +143,7 @@ fold in: mce_start_timer(t); } -@@ -2509,7 +2507,7 @@ static int mce_cpu_dead(unsigned int cpu +@@ -2270,7 +2268,7 @@ static int mce_cpu_dead(unsigned int cpu static int mce_cpu_online(unsigned int cpu) { @@ -152,7 +152,7 @@ fold in: int ret; mce_device_create(cpu); -@@ -2526,10 +2524,10 @@ static int mce_cpu_online(unsigned int c +@@ -2287,10 +2285,10 @@ static int mce_cpu_online(unsigned int c static int mce_cpu_pre_down(unsigned int cpu) { diff --git a/patches/x86-mce-use-swait-queue-for-mce-wakeups.patch b/patches/x86-mce-use-swait-queue-for-mce-wakeups.patch index f73ec82d4507..380795b0f85f 100644 --- a/patches/x86-mce-use-swait-queue-for-mce-wakeups.patch +++ b/patches/x86-mce-use-swait-queue-for-mce-wakeups.patch @@ -55,43 +55,31 @@ Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> [wagi: use work-simple framework to defer work to a kthread] Signed-off-by: Daniel Wagner <daniel.wagner@bmw-carit.de> --- - arch/x86/kernel/cpu/mcheck/mce.c | 68 ++++++++++++++++++++++++++++++++------- - 1 file changed, 56 insertions(+), 12 deletions(-) + arch/x86/kernel/cpu/mcheck/dev-mcelog.c | 37 +++++++++++++++++++++++++++++--- + 1 file changed, 34 insertions(+), 3 deletions(-) ---- a/arch/x86/kernel/cpu/mcheck/mce.c -+++ b/arch/x86/kernel/cpu/mcheck/mce.c -@@ -42,6 +42,7 @@ - #include <linux/irq_work.h> - #include <linux/export.h> - #include <linux/jiffies.h> +--- a/arch/x86/kernel/cpu/mcheck/dev-mcelog.c ++++ b/arch/x86/kernel/cpu/mcheck/dev-mcelog.c +@@ -14,6 +14,7 @@ + #include <linux/slab.h> + #include <linux/kmod.h> + #include <linux/poll.h> +#include <linux/swork.h> - #include <linux/jump_label.h> - #include <asm/intel-family.h> -@@ -1397,6 +1398,56 @@ static void mce_do_trigger(struct work_s + #include "mce-internal.h" + +@@ -105,13 +106,43 @@ static void mce_do_trigger(struct work_s static DECLARE_WORK(mce_trigger_work, mce_do_trigger); -+static void __mce_notify_work(struct swork_event *event) -+{ -+ /* Not more than two messages every minute */ -+ static DEFINE_RATELIMIT_STATE(ratelimit, 60*HZ, 2); -+ -+ /* wake processes polling /dev/mcelog */ -+ wake_up_interruptible(&mce_chrdev_wait); -+ -+ /* -+ * There is no risk of missing notifications because -+ * work_pending is always cleared before the function is -+ * executed. -+ */ -+ if (mce_helper[0] && !work_pending(&mce_trigger_work)) -+ schedule_work(&mce_trigger_work); -+ -+ if (__ratelimit(&ratelimit)) -+ pr_info(HW_ERR "Machine check events logged\n"); -+} -+ +- +-void mce_work_trigger(void) ++static void __mce_work_trigger(struct swork_event *event) + { + if (mce_helper[0]) + schedule_work(&mce_trigger_work); + } + +#ifdef CONFIG_PREEMPT_RT_FULL +static bool notify_work_ready __read_mostly; +static struct swork_event notify_work; @@ -104,56 +92,34 @@ Signed-off-by: Daniel Wagner <daniel.wagner@bmw-carit.de> + if (err) + return err; + -+ INIT_SWORK(¬ify_work, __mce_notify_work); ++ INIT_SWORK(¬ify_work, __mce_work_trigger); + notify_work_ready = true; + return 0; +} + -+static void mce_notify_work(void) ++void mce_work_trigger(void) +{ + if (notify_work_ready) + swork_queue(¬ify_work); +} ++ +#else -+static void mce_notify_work(void) ++void mce_work_trigger(void) +{ -+ __mce_notify_work(NULL); ++ __mce_work_trigger(NULL); +} +static inline int mce_notify_work_init(void) { return 0; } +#endif + - /* - * Notify the user(s) about new machine check events. - * Can be called from interrupt context, but not from machine check/NMI -@@ -1404,19 +1455,8 @@ static DECLARE_WORK(mce_trigger_work, mc - */ - int mce_notify_irq(void) + static ssize_t + show_trigger(struct device *s, struct device_attribute *attr, char *buf) { -- /* Not more than two messages every minute */ -- static DEFINE_RATELIMIT_STATE(ratelimit, 60*HZ, 2); -- - if (test_and_clear_bit(0, &mce_need_notify)) { -- /* wake processes polling /dev/mcelog */ -- wake_up_interruptible(&mce_chrdev_wait); -- -- if (mce_helper[0]) -- schedule_work(&mce_trigger_work); -- -- if (__ratelimit(&ratelimit)) -- pr_info(HW_ERR "Machine check events logged\n"); -- -+ mce_notify_work(); - return 1; +@@ -423,7 +454,7 @@ static __init int dev_mcelog_init_device + + return err; } +- ++ mce_notify_work_init(); + mce_register_decode_chain(&dev_mcelog_nb); return 0; -@@ -2561,6 +2601,10 @@ static __init int mcheck_init_device(voi - goto err_out; - } - -+ err = mce_notify_work_init(); -+ if (err) -+ goto err_out; -+ - if (!zalloc_cpumask_var(&mce_device_initialized, GFP_KERNEL)) { - err = -ENOMEM; - goto err_out; + } diff --git a/patches/x86-preempt-lazy.patch b/patches/x86-preempt-lazy.patch index de5b8740b309..5bc941b09ed6 100644 --- a/patches/x86-preempt-lazy.patch +++ b/patches/x86-preempt-lazy.patch @@ -17,22 +17,22 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig -@@ -160,6 +160,7 @@ config X86 - select HAVE_PERF_REGS +@@ -169,6 +169,7 @@ config X86 select HAVE_PERF_USER_STACK_DUMP select HAVE_REGS_AND_STACK_ACCESS_API + select HAVE_RELIABLE_STACKTRACE if X86_64 && FRAME_POINTER && STACK_VALIDATION + select HAVE_PREEMPT_LAZY select HAVE_STACK_VALIDATION if X86_64 select HAVE_SYSCALL_TRACEPOINTS select HAVE_UNSTABLE_SCHED_CLOCK --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c -@@ -130,7 +130,7 @@ static long syscall_trace_enter(struct p +@@ -131,7 +131,7 @@ static long syscall_trace_enter(struct p #define EXIT_TO_USERMODE_LOOP_FLAGS \ (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_UPROBE | \ -- _TIF_NEED_RESCHED | _TIF_USER_RETURN_NOTIFY) -+ _TIF_NEED_RESCHED_MASK | _TIF_USER_RETURN_NOTIFY) +- _TIF_NEED_RESCHED | _TIF_USER_RETURN_NOTIFY | _TIF_PATCH_PENDING) ++ _TIF_NEED_RESCHED_MASK | _TIF_USER_RETURN_NOTIFY | _TIF_PATCH_PENDING) static void exit_to_usermode_loop(struct pt_regs *regs, u32 cached_flags) { @@ -47,7 +47,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #ifdef ARCH_RT_DELAYS_SIGNAL_SEND --- a/arch/x86/entry/entry_32.S +++ b/arch/x86/entry/entry_32.S -@@ -340,8 +340,25 @@ END(ret_from_exception) +@@ -337,8 +337,25 @@ END(ret_from_exception) ENTRY(resume_kernel) DISABLE_INTERRUPTS(CLBR_ANY) .Lneed_resched: @@ -75,7 +75,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> call preempt_schedule_irq --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S -@@ -541,7 +541,23 @@ GLOBAL(retint_user) +@@ -539,7 +539,23 @@ GLOBAL(retint_user) bt $9, EFLAGS(%rsp) /* were interrupts off? */ jnc 1f 0: cmpl $0, PER_CPU_VAR(__preempt_count) @@ -177,23 +177,23 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> #endif /* -@@ -85,6 +92,7 @@ struct thread_info { +@@ -82,6 +89,7 @@ struct thread_info { #define TIF_SYSCALL_EMU 6 /* syscall emulation active */ #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ #define TIF_SECCOMP 8 /* secure computing */ +#define TIF_NEED_RESCHED_LAZY 9 /* lazy rescheduling necessary */ #define TIF_USER_RETURN_NOTIFY 11 /* notify kernel of userspace return */ #define TIF_UPROBE 12 /* breakpointed or singlestepping */ - #define TIF_NOTSC 16 /* TSC is not accessible in userland */ -@@ -108,6 +116,7 @@ struct thread_info { + #define TIF_PATCH_PENDING 13 /* pending live patching update */ +@@ -107,6 +115,7 @@ struct thread_info { #define _TIF_SYSCALL_EMU (1 << TIF_SYSCALL_EMU) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) #define _TIF_SECCOMP (1 << TIF_SECCOMP) +#define _TIF_NEED_RESCHED_LAZY (1 << TIF_NEED_RESCHED_LAZY) #define _TIF_USER_RETURN_NOTIFY (1 << TIF_USER_RETURN_NOTIFY) #define _TIF_UPROBE (1 << TIF_UPROBE) - #define _TIF_NOTSC (1 << TIF_NOTSC) -@@ -143,6 +152,8 @@ struct thread_info { + #define _TIF_PATCH_PENDING (1 << TIF_PATCH_PENDING) +@@ -146,6 +155,8 @@ struct thread_info { #define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW|_TIF_USER_RETURN_NOTIFY) #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW) diff --git a/patches/x86-stackprot-no-random-on-rt.patch b/patches/x86-stackprot-no-random-on-rt.patch index 5a110414f970..7b423aeb0786 100644 --- a/patches/x86-stackprot-no-random-on-rt.patch +++ b/patches/x86-stackprot-no-random-on-rt.patch @@ -14,8 +14,8 @@ Reported-by: Carsten Emde <carsten.emde@osadl.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- - arch/x86/include/asm/stackprotector.h | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) + arch/x86/include/asm/stackprotector.h | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) --- a/arch/x86/include/asm/stackprotector.h +++ b/arch/x86/include/asm/stackprotector.h @@ -28,11 +28,10 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> u64 tsc; #ifdef CONFIG_X86_64 -@@ -70,8 +70,15 @@ static __always_inline void boot_init_st +@@ -70,8 +70,14 @@ static __always_inline void boot_init_st * of randomness. The TSC only matters for very early init, * there it already has some randomness on most systems. Later * on during the bootup the random pool has true entropy too. -+ * + * For preempt-rt we need to weaken the randomness a bit, as + * we can't call into the random generator from atomic context + * due to locking constraints. We just leave canary @@ -43,4 +42,4 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +#endif tsc = rdtsc(); canary += tsc + (tsc << 32UL); - + canary &= CANARY_MASK; diff --git a/patches/x86-tsc-sched-clock-clocksource-Use-clocksource-watc.patch b/patches/x86-tsc-sched-clock-clocksource-Use-clocksource-watc.patch deleted file mode 100644 index b93dd4f855a5..000000000000 --- a/patches/x86-tsc-sched-clock-clocksource-Use-clocksource-watc.patch +++ /dev/null @@ -1,149 +0,0 @@ -From: Peter Zijlstra <peterz@infradead.org> -Date: Fri, 21 Apr 2017 12:14:13 +0200 -Subject: [PATCH] x86/tsc, sched/clock, clocksource: Use clocksource watchdog - to provide stable sync points - -commit b421b22b00b0011f6a2ce3561176c4e79e640c49 upstream. - -Currently we keep sched_clock_tick() active for stable TSC in order to -keep the per-CPU state semi up-to-date. The (obvious) problem is that -by the time we detect TSC is borked, our per-CPU state is also borked. - -So hook into the clocksource watchdog and call a method after we've -found it to still be stable. - -There's the obvious race where the TSC goes wonky between finding it -stable and us running the callback, but closing that is too much work -and not really worth it, since we're already detecting TSC wobbles -after the fact, so we cannot, per definition, fully avoid funny clock -values. - -And since the watchdog runs less often than the tick, this is also an -optimization. - -Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> -Cc: Linus Torvalds <torvalds@linux-foundation.org> -Cc: Mike Galbraith <efault@gmx.de> -Cc: Peter Zijlstra <peterz@infradead.org> -Cc: Thomas Gleixner <tglx@linutronix.de> -Cc: linux-kernel@vger.kernel.org -Signed-off-by: Ingo Molnar <mingo@kernel.org> - ---- - arch/x86/kernel/tsc.c | 10 ++++++++++ - include/linux/clocksource.h | 1 + - include/linux/sched/clock.h | 2 +- - kernel/sched/clock.c | 36 +++++++++++++++++++++++++++--------- - kernel/time/clocksource.c | 3 +++ - 5 files changed, 42 insertions(+), 10 deletions(-) - ---- a/arch/x86/kernel/tsc.c -+++ b/arch/x86/kernel/tsc.c -@@ -1127,6 +1127,15 @@ static void tsc_cs_mark_unstable(struct - pr_info("Marking TSC unstable due to clocksource watchdog\n"); - } - -+static void tsc_cs_tick_stable(struct clocksource *cs) -+{ -+ if (tsc_unstable) -+ return; -+ -+ if (using_native_sched_clock()) -+ sched_clock_tick_stable(); -+} -+ - /* - * .mask MUST be CLOCKSOURCE_MASK(64). See comment above read_tsc() - */ -@@ -1140,6 +1149,7 @@ static struct clocksource clocksource_ts - .archdata = { .vclock_mode = VCLOCK_TSC }, - .resume = tsc_resume, - .mark_unstable = tsc_cs_mark_unstable, -+ .tick_stable = tsc_cs_tick_stable, - }; - - void mark_tsc_unstable(char *reason) ---- a/include/linux/clocksource.h -+++ b/include/linux/clocksource.h -@@ -96,6 +96,7 @@ struct clocksource { - void (*suspend)(struct clocksource *cs); - void (*resume)(struct clocksource *cs); - void (*mark_unstable)(struct clocksource *cs); -+ void (*tick_stable)(struct clocksource *cs); - - /* private: */ - #ifdef CONFIG_CLOCKSOURCE_WATCHDOG ---- a/include/linux/sched/clock.h -+++ b/include/linux/sched/clock.h -@@ -63,8 +63,8 @@ extern void clear_sched_clock_stable(voi - */ - extern u64 __sched_clock_offset; - -- - extern void sched_clock_tick(void); -+extern void sched_clock_tick_stable(void); - extern void sched_clock_idle_sleep_event(void); - extern void sched_clock_idle_wakeup_event(u64 delta_ns); - ---- a/kernel/sched/clock.c -+++ b/kernel/sched/clock.c -@@ -366,20 +366,38 @@ void sched_clock_tick(void) - { - struct sched_clock_data *scd; - -+ if (sched_clock_stable()) -+ return; -+ -+ if (unlikely(!sched_clock_running)) -+ return; -+ - WARN_ON_ONCE(!irqs_disabled()); - -- /* -- * Update these values even if sched_clock_stable(), because it can -- * become unstable at any point in time at which point we need some -- * values to fall back on. -- * -- * XXX arguably we can skip this if we expose tsc_clocksource_reliable -- */ - scd = this_scd(); - __scd_stamp(scd); -+ sched_clock_local(scd); -+} - -- if (!sched_clock_stable() && likely(sched_clock_running)) -- sched_clock_local(scd); -+void sched_clock_tick_stable(void) -+{ -+ u64 gtod, clock; -+ -+ if (!sched_clock_stable()) -+ return; -+ -+ /* -+ * Called under watchdog_lock. -+ * -+ * The watchdog just found this TSC to (still) be stable, so now is a -+ * good moment to update our __gtod_offset. Because once we find the -+ * TSC to be unstable, any computation will be computing crap. -+ */ -+ local_irq_disable(); -+ gtod = ktime_get_ns(); -+ clock = sched_clock(); -+ __gtod_offset = (clock + __sched_clock_offset) - gtod; -+ local_irq_enable(); - } - - /* ---- a/kernel/time/clocksource.c -+++ b/kernel/time/clocksource.c -@@ -233,6 +233,9 @@ static void clocksource_watchdog(unsigne - continue; - } - -+ if (cs == curr_clocksource && cs->tick_stable) -+ cs->tick_stable(cs); -+ - if (!(cs->flags & CLOCK_SOURCE_VALID_FOR_HRES) && - (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS) && - (watchdog->flags & CLOCK_SOURCE_IS_CONTINUOUS)) { diff --git a/patches/x86-use-gen-rwsem-spinlocks-rt.patch b/patches/x86-use-gen-rwsem-spinlocks-rt.patch index 28194c7a053e..caf096ca41ed 100644 --- a/patches/x86-use-gen-rwsem-spinlocks-rt.patch +++ b/patches/x86-use-gen-rwsem-spinlocks-rt.patch @@ -13,7 +13,7 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de> --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig -@@ -242,8 +242,11 @@ config ARCH_MAY_HAVE_PC_FDC +@@ -252,8 +252,11 @@ config ARCH_MAY_HAVE_PC_FDC def_bool y depends on ISA_DMA_API diff --git a/patches/xen-9pfs-don-t-inclide-rwlock.h-directly.patch b/patches/xen-9pfs-don-t-inclide-rwlock.h-directly.patch new file mode 100644 index 000000000000..8c36bf8c7927 --- /dev/null +++ b/patches/xen-9pfs-don-t-inclide-rwlock.h-directly.patch @@ -0,0 +1,28 @@ +From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Date: Thu, 5 Oct 2017 14:38:52 +0200 +Subject: [PATCH] xen/9pfs: don't inclide rwlock.h directly. + +rwlock.h should not be included directly. Instead linux/splinlock.h +should be included. One thing it does is to break the RT build. + +Cc: Eric Van Hensbergen <ericvh@gmail.com> +Cc: Ron Minnich <rminnich@sandia.gov> +Cc: Latchesar Ionkov <lucho@ionkov.net> +Cc: "David S. Miller" <davem@davemloft.net> +Cc: v9fs-developer@lists.sourceforge.net +Cc: netdev@vger.kernel.org +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +--- + net/9p/trans_xen.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/net/9p/trans_xen.c ++++ b/net/9p/trans_xen.c +@@ -38,7 +38,6 @@ + + #include <linux/module.h> + #include <linux/spinlock.h> +-#include <linux/rwlock.h> + #include <net/9p/9p.h> + #include <net/9p/client.h> + #include <net/9p/transport.h> |