Linux 4.14.109-rt58-rc1
cover Linux 4.14.109-rt58-rc1
From: Tom Zanussi <[email protected]>
Hello RT Folks!
This is the RT stable review cycle of patch 4.14.109-rt58-rc1.
Please scream at me if I messed something up. Please test the patches too.
The -rc release will be uploaded to kernel.org and will be deleted when the final release is out. This is just a review release (or release candidate).
The pre-releases will not be pushed to the git repository, only the final release is.
If all goes well, this patch will be converted to the next main release on 4/12/2019.
To build 4.14.109-rt58-rc1 directly, the following patches should be applied:
http://www.kernel.org/pub/linux/kernel/v4.x/linux-4.14.tar.xz
http://www.kernel.org/pub/linux/kernel/v4.x/patch-4.14.109.xz
http://www.kernel.org/pub/linux/kernel/projects/rt/4.14/patch-4.14.109-rt58-rc1.patch.xz
You can also build from 4.14.109-rt57 by applying the incremental patch:
http://www.kernel.org/pub/linux/kernel/projects/rt/4.14/incr/patch-4.14.109-rt57-rt58-rc1.patch.xz
Enjoy!
Tom
Changes from v4.14.109-rt57:
Julien Grall (1):
tty/sysrq: Convert show_lock to raw_spinlock_t
Peter Zijlstra (1):
sched/fair: Robustify CFS-bandwidth timer locking
Scott Wood (1):
locking/rt-mutex: Flush block plug on __down_read()
Sebastian Andrzej Siewior (9):
arm64: fpsimd: use preemp_disable in addition to local_bh_disable() sched/fair: Make the hrtimers non-hard again rtmutex/rwlock: preserve state like a sleeping lock
softirq: Avoid "local_softirq_pending" messages if ksoftirqd is
blocked
softirq: Avoid "local_softirq_pending" messages if task is in
cpu_chill()
hrtimer: Don't lose state in cpu_chill()
x86: lazy-preempt: properly check against preempt-mask
hrtimer: cpu_chill(): save task state in ->saved_state() powerpc/pseries/iommu: Use a locallock instead local_irq_save()
Tom Zanussi (1):
Linux 4.14.109-rt58
arch/arm64/kernel/fpsimd.c | 10 ++++++ arch/powerpc/platforms/pseries/iommu.c | 16 +++++---- arch/x86/include/asm/preempt.h | 2 +- drivers/tty/sysrq.c | 6 ++-- kernel/locking/rtmutex.c | 2 +- kernel/locking/rwlock-rt.c | 2 +- kernel/locking/rwsem-rt.c | 9 +++++ kernel/sched/fair.c | 34 ++++++++++--------- kernel/softirq.c | 60 +++++++++++++++++++++++++--------- kernel/time/hrtimer.c | 15 +++++++-- localversion-rt | 2 +- 11 files changed, 111 insertions(+), 47 deletions(-)
Signature · 1 line
2.14.1
PATCH 1/13 arm64: fpsimd: use preemp_disable in addition to local_bh_disable()
4.14.109-rt58-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit 3afdfe419c33c1655d0763e070350aad44416594 ]
In v4.16-RT I noticed a number of warnings from task_fpsimd_load(). The code disables BH and expects that it is not preemptible. On -RT the task remains preemptible but remains the same CPU. This may corrupt the content of the SIMD registers if the task is preempted during saving/restoring those registers.
Add preempt_disable()/enable() to enfore the required semantic on -RT.
Conflicts:
arch/arm64/kernel/fpsimd.c
--- arch/arm64/kernel/fpsimd.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
arch/arm64/kernel/fpsimd.c +10 -0
@@ -172,6 +172,7 @@ void fpsimd_flush_thread(void)if (!system_supports_fpsimd ())return ; +preempt_disable ();local_bh_disable ();memset (¤t->thread.fpsimd_state,0 ,sizeof (struct fpsimd_state ));
@@ -179,6 +180,7 @@ void fpsimd_flush_thread(void)set_thread_flag (TIF_FOREIGN_FPSTATE );local_bh_enable (); +preempt_enable (); }/*
@@ -190,12 +192,14 @@ void fpsimd_preserve_current_state(void)if (!system_supports_fpsimd ())return ; +preempt_disable ();local_bh_disable ();if (!test_thread_flag (TIF_FOREIGN_FPSTATE ))fpsimd_save_state (¤t->thread.fpsimd_state);local_bh_enable (); +preempt_enable (); }/*
@@ -208,6 +212,7 @@ void fpsimd_restore_current_state(void)if (!system_supports_fpsimd ())return ; +preempt_disable ();local_bh_disable ();if (test_and_clear_thread_flag (TIF_FOREIGN_FPSTATE )) {
@@ -219,6 +224,7 @@ void fpsimd_restore_current_state(void) }local_bh_enable (); +preempt_enable (); }/*
@@ -231,6 +237,7 @@ void fpsimd_update_current_state(struct fpsimd_state *state)if (!system_supports_fpsimd ())return ; +preempt_disable ();local_bh_disable ();fpsimd_load_state (state);
@@ -242,6 +249,7 @@ void fpsimd_update_current_state(struct fpsimd_state *state) }local_bh_enable (); +preempt_enable (); }/*
@@ -281,6 +289,7 @@ void kernel_neon_begin(void)BUG_ON (!may_use_simd ()); +preempt_disable ();local_bh_disable ();__this_cpu_write (kernel_neon_busy, true);
@@ -295,6 +304,7 @@ void kernel_neon_begin(void)preempt_disable ();local_bh_enable (); +preempt_enable (); }EXPORT_SYMBOL (kernel_neon_begin);
Signature · 1 line
2.14.1
PATCH 2/13 sched/fair: Robustify CFS-bandwidth timer locking
In reply to Tom Zanussi4.14.109-rt58-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
[ Upstream commit a44c9da61ad3334a9563102e0194d7197b222ec2 ]
Traditionally hrtimer callbacks were run with IRQs disabled, but with the introduction of HRTIMER_MODE_SOFT it is possible they run from SoftIRQ context, which does _NOT_ have IRQs disabled.
Allow for the CFS bandwidth timers (period_timer and slack_timer) to be ran from SoftIRQ context; this entails removing the assumption that IRQs are already disabled from the locking.
While mainline doesn't strictly need this, -RT forces all timers not explicitly marked with MODE_HARD into MODE_SOFT and trips over this. And marking these timers as MODE_HARD doesn't make sense as they're not required for RT operation and can potentially be quite expensive.
--- kernel/sched/fair.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-)
kernel/sched/fair.c +16 -14
@@ -4378,7 +4378,7 @@ static u64 distribute_cfs_runtime(struct cfs_bandwidth *cfs_b,struct rq *rq =rq_of (cfs_rq);struct rq_flags rf; -rq_lock (rq, &rf); +rq_lock_irqsave (rq, &rf);if (!cfs_rq_throttled (cfs_rq)) goto next;
@@ -4395,7 +4395,7 @@ static u64 distribute_cfs_runtime(struct cfs_bandwidth *cfs_b,unthrottle_cfs_rq (cfs_rq); next: -rq_unlock (rq, &rf); +rq_unlock_irqrestore (rq, &rf);if (!remaining)break ;
@@ -4411,7 +4411,7 @@ static u64 distribute_cfs_runtime(struct cfs_bandwidth *cfs_b,* period the timer is deactivated until scheduling resumes; cfs_b->idle is * used to track this state. */ -static int do_sched_cfs_period_timer (struct cfs_bandwidth *cfs_b,int overrun) +static int do_sched_cfs_period_timer (struct cfs_bandwidth *cfs_b,int overrun,unsigned long flags) {u64 runtime, runtime_expires;int throttled;
@@ -4453,11 +4453,11 @@ static int do_sched_cfs_period_timer(struct cfs_bandwidth *cfs_b, int overrun)while (throttled && cfs_b->runtime >0 && !cfs_b->distribute_running) { runtime = cfs_b->runtime; cfs_b->distribute_running =1 ; -raw_spin_unlock (&cfs_b->lock); +raw_spin_unlock_irqrestore (&cfs_b->lock, flags);/* we can't nest cfs_b->lock while distributing bandwidth */ runtime =distribute_cfs_runtime (cfs_b, runtime, runtime_expires); -raw_spin_lock (&cfs_b->lock); +raw_spin_lock_irqsave (&cfs_b->lock, flags); cfs_b->distribute_running =0 ; throttled = !list_empty (&cfs_b->throttled_cfs_rq);
@@ -4566,17 +4566,18 @@ static __always_inline void return_cfs_rq_runtime(struct cfs_rq *cfs_rq)static void do_sched_cfs_slack_timer (struct cfs_bandwidth *cfs_b) {u64 runtime =0 , slice =sched_cfs_bandwidth_slice (); +unsigned long flags;u64 expires;/* confirm we're still not at a refresh boundary */ -raw_spin_lock (&cfs_b->lock); +raw_spin_lock_irqsave (&cfs_b->lock, flags);if (cfs_b->distribute_running) { -raw_spin_unlock (&cfs_b->lock); +raw_spin_unlock_irqrestore (&cfs_b->lock, flags);return ; }if (runtime_refresh_within (cfs_b, min_bandwidth_expiration)) { -raw_spin_unlock (&cfs_b->lock); +raw_spin_unlock_irqrestore (&cfs_b->lock, flags);return ; }
@@ -4587,18 +4588,18 @@ static void do_sched_cfs_slack_timer(struct cfs_bandwidth *cfs_b)if (runtime) cfs_b->distribute_running =1 ; -raw_spin_unlock (&cfs_b->lock); +raw_spin_unlock_irqrestore (&cfs_b->lock, flags);if (!runtime)return ; runtime =distribute_cfs_runtime (cfs_b, runtime, expires); -raw_spin_lock (&cfs_b->lock); +raw_spin_lock_irqsave (&cfs_b->lock, flags);if (expires == cfs_b->runtime_expires) cfs_b->runtime -=min (runtime, cfs_b->runtime); cfs_b->distribute_running =0 ; -raw_spin_unlock (&cfs_b->lock); +raw_spin_unlock_irqrestore (&cfs_b->lock, flags); }/*
@@ -4676,20 +4677,21 @@ static enum hrtimer_restart sched_cfs_period_timer(struct hrtimer *timer) {struct cfs_bandwidth *cfs_b = container_of(timer, struct cfs_bandwidth, period_timer); +unsigned long flags;int overrun;int idle =0 ; -raw_spin_lock (&cfs_b->lock); +raw_spin_lock_irqsave (&cfs_b->lock, flags);for (;;) { overrun =hrtimer_forward_now (timer, cfs_b->period);if (!overrun)break ; - idle =do_sched_cfs_period_timer (cfs_b, overrun); + idle =do_sched_cfs_period_timer (cfs_b, overrun, flags); }if (idle) cfs_b->period_active =0 ; -raw_spin_unlock (&cfs_b->lock); +raw_spin_unlock_irqrestore (&cfs_b->lock, flags);return idle ?HRTIMER_NORESTART :HRTIMER_RESTART ; }
Signature · 1 line
2.14.1
PATCH 3/13 sched/fair: Make the hrtimers non-hard again
In reply to Tom Zanussi4.14.109-rt58-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit 73d5c2697339118cd33dc1ff1ffcb21d59cafe1a ]
Since commit "sched/fair: Robustify CFS-bandwidth timer locking" both hrtimer can run in softirq context because now interrupts are disabled as part of the locking procedure.
--- kernel/sched/fair.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/sched/fair.c +2 -2
@@ -4704,9 +4704,9 @@ void init_cfs_bandwidth(struct cfs_bandwidth *cfs_b) cfs_b->period =ns_to_ktime (default_cfs_period ());INIT_LIST_HEAD (&cfs_b->throttled_cfs_rq); -hrtimer_init (&cfs_b->period_timer,CLOCK_MONOTONIC ,HRTIMER_MODE_ABS_PINNED_HARD ); +hrtimer_init (&cfs_b->period_timer,CLOCK_MONOTONIC ,HRTIMER_MODE_ABS_PINNED ); cfs_b->period_timer.function = sched_cfs_period_timer; -hrtimer_init (&cfs_b->slack_timer,CLOCK_MONOTONIC ,HRTIMER_MODE_REL_HARD ); +hrtimer_init (&cfs_b->slack_timer,CLOCK_MONOTONIC ,HRTIMER_MODE_REL ); cfs_b->slack_timer.function = sched_cfs_slack_timer; cfs_b->distribute_running =0 ; }
Signature · 1 line
2.14.1
PATCH 4/13 locking/rt-mutex: Flush block plug on __down_read()
In reply to Tom Zanussi4.14.109-rt58-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Scott Wood <[email protected]>
[ Upstream commit 0d5d32425a0cab4a282dd79fc953d76a3ab17072 ]
__down_read() bypasses the rtmutex frontend to call rt_mutex_slowlock_locked() directly, and thus it needs to call blk_schedule_flush_flug() itself.
Conflicts:
kernel/locking/rwsem-rt.c
--- kernel/locking/rtmutex.c | 2 +- kernel/locking/rwsem-rt.c | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-)
kernel/locking/rtmutex.c +1 -1
@@ -1946,7 +1946,7 @@ rt_mutex_fastlock(struct rt_mutex *lock, int state,* If rt_mutex blocks, the function sched_submit_work will not call * blk_schedule_flush_plug (because tsk_is_pi_blocked would be true). * We must call blk_schedule_flush_plug here, if we don't call it, -* a deadlock in device mapper may happen. +* a deadlock in I/O may happen. */ if (unlikely (blk_needs_flush_plug (current)))blk_schedule_flush_plug (current);
kernel/locking/rwsem-rt.c +9 -0
@@ -1,5 +1,6 @@/* */ +#include <linux/blkdev.h> #include <linux/rwsem.h> #include <linux/sched/debug.h> #include <linux/sched/signal.h>
@@ -86,6 +87,14 @@ void __sched __down_read(struct rw_semaphore *sem)if (__down_read_trylock (sem))return ; +/* +* If rt_mutex blocks, the function sched_submit_work will not call +* blk_schedule_flush_plug (because tsk_is_pi_blocked would be true). +* We must call blk_schedule_flush_plug here, if we don't call it, +* a deadlock in I/O may happen. +*/ +if (unlikely (blk_needs_flush_plug (current))) +blk_schedule_flush_plug (current);might_sleep ();raw_spin_lock_irq (&m->wait_lock);
Signature · 1 line
2.14.1
PATCH 5/13 rtmutex/rwlock: preserve state like a sleeping lock
In reply to Tom Zanussi4.14.109-rt58-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit 4a1bf9e54a013d55ab156cb462c68054cb52ee2d ]
The rwlock is spinning while acquiring a lock. Therefore it must become a sleeping lock on RT and preserve its task state while sleeping and waiting for the lock to become available.
--- kernel/locking/rwlock-rt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/locking/rwlock-rt.c +1 -1
@@ -128,7 +128,7 @@ void __sched __read_rt_lock(struct rt_rw_lock *lock)* That would put Reader1 behind the writer waiting on * Reader2 to call read_unlock() which might be unbound. */ -rt_mutex_init_waiter (&waiter, false); +rt_mutex_init_waiter (&waiter, true);rt_spin_lock_slowlock_locked (m, &waiter, flags);/* * The slowlock() above is guaranteed to return with the rtmutex is
Signature · 1 line
2.14.1
PATCH 6/13 softirq: Avoid "local_softirq_pending" messages if ksoftirqd is blocked
In reply to Tom Zanussi4.14.109-rt58-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit 2cf32c1a3d9352df8017dbf84a1462c4a60a1826 ]
If the ksoftirqd thread has a softirq pending and is blocked on the `local_softirq_locks' lock then softirq_check_pending_idle() won't complain because the "lock owner" will mask away this softirq from the mask of pending softirqs.
If ksoftirqd has an additional softirq pending then it won't be masked out because we never look at ksoftirqd's mask.
If there are still pending softirqs while going to idle check ksoftirqd's and ktimersfotd's mask before complaining about unhandled softirqs.
--- kernel/softirq.c | 57 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 16 deletions(-)
kernel/softirq.c +41 -16
@@ -92,6 +92,31 @@ static inline void softirq_clr_runner(unsigned int sirq) sr->runner[sirq] =NULL ; } +static bool softirq_check_runner_tsk (struct task_struct *tsk, +unsigned int *pending) +{ +bool ret = false; + +if (!tsk) +return ret; + +/* +* The wakeup code in rtmutex.c wakes up the task +* _before_ it sets pi_blocked_on to NULL under +* tsk->pi_lock. So we need to check for both: state +* and pi_blocked_on. +*/ +raw_spin_lock (&tsk->pi_lock); +if (tsk->pi_blocked_on || tsk->state ==TASK_RUNNING ) { +/* Clear all bits pending in that task */ + *pending &= ~(tsk->softirqs_raised); + ret = true; + } +raw_spin_unlock (&tsk->pi_lock); + +return ret; +} +/* * On preempt-rt a softirq running context might be blocked on a * lock. There might be no other runnable task on this CPU because the
@@ -104,6 +129,7 @@ static inline void softirq_clr_runner(unsigned int sirq)*/ void softirq_check_pending_idle (void ) { +struct task_struct *tsk;static int rate_limit;struct softirq_runner *sr =this_cpu_ptr (&softirq_runners);u32 warnpending;
@@ -113,24 +139,23 @@ void softirq_check_pending_idle(void)return ; warnpending =local_softirq_pending () &SOFTIRQ_STOP_IDLE_MASK ; +if (!warnpending) +return ;for (i =0 ; i <NR_SOFTIRQS ; i++) { -struct task_struct *tsk = sr->runner[i]; + tsk = sr->runner[i]; -/* -* The wakeup code in rtmutex.c wakes up the task -* _before_ it sets pi_blocked_on to NULL under -* tsk->pi_lock. So we need to check for both: state -* and pi_blocked_on. -*/ -if (tsk) { -raw_spin_lock (&tsk->pi_lock); -if (tsk->pi_blocked_on || tsk->state ==TASK_RUNNING ) { -/* Clear all bits pending in that task */ - warnpending &= ~(tsk->softirqs_raised); - warnpending &= ~(1 << i); - } -raw_spin_unlock (&tsk->pi_lock); - } +if (softirq_check_runner_tsk (tsk, &warnpending)) + warnpending &= ~(1 << i); + } + +if (warnpending) { + tsk =__this_cpu_read (ksoftirqd); +softirq_check_runner_tsk (tsk, &warnpending); + } + +if (warnpending) { + tsk =__this_cpu_read (ktimer_softirqd); +softirq_check_runner_tsk (tsk, &warnpending); }if (warnpending) {
Signature · 1 line
2.14.1
PATCH 7/13 softirq: Avoid "local_softirq_pending" messages if task is in cpu_chill()
In reply to Tom Zanussi4.14.109-rt58-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit a3429e0147dfd3fc585f989aa49a76579c2b6565 ]
If the softirq thread enters cpu_chill() then ->state is UNINTERRUPTIBLE and has no ->pi_blocked_on set and so its mask is not taken into account.
->sleeping_lock is increased by cpu_chill() since it is also requried to avoid a splat by RCU in case cpu_chill() is used while a RCU-read lock is held. Use the same mechanism for the softirq-pending check.
--- kernel/softirq.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
kernel/softirq.c +4 -1
@@ -105,9 +105,12 @@ static bool softirq_check_runner_tsk(struct task_struct *tsk,* _before_ it sets pi_blocked_on to NULL under * tsk->pi_lock. So we need to check for both: state * and pi_blocked_on. +* The test against UNINTERRUPTIBLE + ->sleeping_lock is in case the +* task does cpu_chill(). */ raw_spin_lock (&tsk->pi_lock); -if (tsk->pi_blocked_on || tsk->state ==TASK_RUNNING ) { +if (tsk->pi_blocked_on || tsk->state ==TASK_RUNNING || + (tsk->state ==TASK_UNINTERRUPTIBLE && tsk->sleeping_lock)) {/* Clear all bits pending in that task */ *pending &= ~(tsk->softirqs_raised); ret = true;
Signature · 1 line
2.14.1
PATCH 8/13 hrtimer: Don't lose state in cpu_chill()
In reply to Tom Zanussi4.14.109-rt58-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit 585456236766349f692f9fbcc089d71411831f88 ]
In cpu_chill() the state is set to TASK_UNINTERRUPTIBLE and a timer is programmed. On return the state is always TASK_RUNNING which means we lose the state if it was something other than RUNNING. Also set_current_state() sets ->task_state_change to within cpu_chill() which is not expected.
Save the task state on entry and restore it on return. Simply set the state in order to avoid updating ->task_state_change.
--- kernel/time/hrtimer.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
kernel/time/hrtimer.c +4 -1
@@ -1866,15 +1866,18 @@ void cpu_chill(void) {ktime_t chill_time;unsigned int freeze_flag = current->flags &PF_NOFREEZE ; +long saved_state; + saved_state = current->state; chill_time =ktime_set (0 ,NSEC_PER_MSEC ); -set_current_state (TASK_UNINTERRUPTIBLE ); +__set_current_state_no_track (TASK_UNINTERRUPTIBLE ); current->flags |=PF_NOFREEZE ;sleeping_lock_inc ();schedule_hrtimeout (&chill_time,HRTIMER_MODE_REL_HARD );sleeping_lock_dec ();if (!freeze_flag) current->flags &= ~PF_NOFREEZE ; +__set_current_state_no_track (saved_state); }EXPORT_SYMBOL (cpu_chill);#endif
Signature · 1 line
2.14.1
PATCH 9/13 x86: lazy-preempt: properly check against preempt-mask
In reply to Tom Zanussi4.14.109-rt58-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit 0f8a27bb5f45cc8a66f488549cecc4ce4d4533c2 ]
should_resched() should check against preempt_offset after unmasking the need-resched-bit. Otherwise should_resched() won't work for preempt_offset != 0 and lazy-preempt set.
--- arch/x86/include/asm/preempt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/include/asm/preempt.h +1 -1
@@ -118,7 +118,7 @@ static __always_inline bool should_resched(int preempt_offset)/* preempt count == 0 ? */ tmp &= ~PREEMPT_NEED_RESCHED ; -if (tmp) +if (tmp != preempt_offset)return false;if (current_thread_info ()->preempt_lazy_count)return false;
Signature · 1 line
2.14.1
PATCH 10/13 hrtimer: cpu_chill(): save task state in ->saved_state()
In reply to Tom Zanussi4.14.109-rt58-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit d70f218ee02d6fc3832274653aa6c6e98dd9aa43 ]
In the previous change I saved the current task state on stack. This was bad because while the task is scheduled-out it might receive a wake-up. The wake up changes the task state and we must not destroy it.
Save the task-state in ->saved_state under a PI-lock to unsure that state changes during are not missed while the task temporary scheduled out.
--- kernel/time/hrtimer.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
kernel/time/hrtimer.c +13 -5
@@ -1864,20 +1864,28 @@ COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp,*/ void cpu_chill (void ) { -ktime_t chill_time;unsigned int freeze_flag = current->flags &PF_NOFREEZE ; -long saved_state; +struct task_struct *self = current; +ktime_t chill_time; - saved_state = current->state; - chill_time =ktime_set (0 ,NSEC_PER_MSEC ); +raw_spin_lock_irq (&self->pi_lock); + self->saved_state = self->state;__set_current_state_no_track (TASK_UNINTERRUPTIBLE ); +raw_spin_unlock_irq (&self->pi_lock); + + chill_time =ktime_set (0 ,NSEC_PER_MSEC ); + current->flags |=PF_NOFREEZE ;sleeping_lock_inc ();schedule_hrtimeout (&chill_time,HRTIMER_MODE_REL_HARD );sleeping_lock_dec ();if (!freeze_flag) current->flags &= ~PF_NOFREEZE ; -__set_current_state_no_track (saved_state); + +raw_spin_lock_irq (&self->pi_lock); +__set_current_state_no_track (self->saved_state); + self->saved_state =TASK_RUNNING ; +raw_spin_unlock_irq (&self->pi_lock); }EXPORT_SYMBOL (cpu_chill);#endif
Signature · 1 line
2.14.1
PATCH 11/13 tty/sysrq: Convert show_lock to raw_spinlock_t
In reply to Tom Zanussi4.14.109-rt58-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Julien Grall <[email protected]>
[ Upstream commit db80c207bffd0f49e984e9889ce62279bc3abd6c ]
Systems which don't provide arch_trigger_cpumask_backtrace() will invoke showacpu() from a smp_call_function() function which is invoked with disabled interrupts even on -RT systems.
The function acquires the show_lock lock which only purpose is to ensure that the CPUs don't print simultaneously. Otherwise the output would clash and it would be hard to tell the output from CPUx apart from CPUy.
On -RT the spin_lock() can not be acquired from this context. A raw_spin_lock() is required. It will introduce the system's latency by performing the sysrq request and other CPUs will block on the lock until the request is done. This is okay because the user asked for a backtrace of all active CPUs and under "normal circumstances in production" this path should not be triggered.
--- drivers/tty/sysrq.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/tty/sysrq.c +3 -3
@@ -215,7 +215,7 @@ static struct sysrq_key_op sysrq_showlocks_op = {#endif #ifdef CONFIG_SMP -static DEFINE_SPINLOCK (show_lock); +static DEFINE_RAW_SPINLOCK (show_lock);static void showacpu (void *dummy) {
@@ -225,10 +225,10 @@ static void showacpu(void *dummy)if (idle_cpu (smp_processor_id ()))return ; -spin_lock_irqsave (&show_lock, flags); +raw_spin_lock_irqsave (&show_lock, flags);pr_info ("CPU%d:\n" ,smp_processor_id ());show_stack (NULL ,NULL ); -spin_unlock_irqrestore (&show_lock, flags); +raw_spin_unlock_irqrestore (&show_lock, flags); }static void sysrq_showregs_othercpus (struct work_struct *dummy)
Signature · 1 line
2.14.1
PATCH 12/13 powerpc/pseries/iommu: Use a locallock instead local_irq_save()
In reply to Tom Zanussi4.14.109-rt58-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit 5c1b4cd70e2ca0c81038b65babe6dc66086322e0 ]
The locallock protects the per-CPU variable tce_page. The function attempts to allocate memory while tce_page is protected (by disabling interrupts).
Use local_irq_save() instead of local_irq_disable().
--- arch/powerpc/platforms/pseries/iommu.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
arch/powerpc/platforms/pseries/iommu.c +10 -6
@@ -38,6 +38,7 @@#include <linux/of.h> #include <linux/iommu.h> #include <linux/rculist.h> +#include <linux/locallock.h> #include <asm/io.h> #include <asm/prom.h> #include <asm/rtas.h>
@@ -213,6 +214,7 @@ static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, } static DEFINE_PER_CPU(__be64 *, tce_page); +static DEFINE_LOCAL_IRQ_LOCK (tcp_page_lock); static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages, unsigned long uaddr,
@@ -233,7 +235,8 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, direction, attrs); } -local_irq_save (flags);/* to protect tcep and the page behind it */ +/* to protect tcep and the page behind it */ +local_lock_irqsave (tcp_page_lock, flags); tcep =__this_cpu_read (tce_page);
@@ -244,7 +247,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, tcep = (__be64 *)__get_free_page (GFP_ATOMIC );/* If allocation fails, fall back to the loop implementation */ if (!tcep) { -local_irq_restore (flags); +local_unlock_irqrestore (tcp_page_lock, flags);return tce_build_pSeriesLP (tbl, tcenum, npages, uaddr, direction, attrs); }
@@ -278,7 +281,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, tcenum += limit; }while (npages >0 && !rc); -local_irq_restore (flags); +local_unlock_irqrestore (tcp_page_lock, flags);if (unlikely (rc ==H_NOT_ENOUGH_RESOURCES )) { ret = (int )rc;
@@ -436,13 +439,14 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,u64 rc =0 ;long l, limit; -local_irq_disable ();/* to protect tcep and the page behind it */ +/* to protect tcep and the page behind it */ +local_lock_irq (tcp_page_lock); tcep =__this_cpu_read (tce_page);if (!tcep) { tcep = (__be64 *)__get_free_page (GFP_ATOMIC );if (!tcep) { -local_irq_enable (); +local_unlock_irq (tcp_page_lock);return -ENOMEM ; }__this_cpu_write (tce_page, tcep);
@@ -488,7 +492,7 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,/* error cleanup: caller will clear whole range */ -local_irq_enable (); +local_unlock_irq (tcp_page_lock);return rc; }
Signature · 1 line
2.14.1
PATCH 13/13 Linux 4.14.109-rt58
In reply to Tom Zanussi4.14.109-rt58-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Tom Zanussi <[email protected]>
--- localversion-rt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
localversion-rt +1 -1
@@ -1 +1 @@ --rt57 +-rt58
Signature · 1 line
2.14.1