v4.16.12-rt5
Subsystems (14)
Dear RT folks!
I'm pleased to announce the v4.16.12-rt5 patch set.
Changes since v4.16.12-rt4:
- Update the "suspend prevent might sleep splat" patch. The newer version also supports s2idle.
- The seqlock implementation had a missing memory barrier. Patch by Julia Cartwright.
- The new priority reported by trace_sched_pi_setprio() was wrong in case the task was de-boosted. Reported by Christian Mansky.
- Update of the refcount_t queue: The raid5 patch was replaced with the atomic interface because it does not fit for the refcount_t API.
- Since the last release softirq_count() returns the "BH disable" count. In this release I am dropping the workarounds we had because softirq_count() returned always 0.
Known issues
- A warning triggered in "rcu_note_context_switch" originated from SyS_timer_gettime(). The issue was always there, it is now visible. Reported by Grygorii Strashko and Daniel Wagner.
The delta patch against v4.16.12-rt4 is appended below and can be found here:
https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.16/incr/patch-4.16.12-rt4-rt5.patch.xz
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.16.12-rt5
The RT patch against v4.16.12 can be found here:
https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.16/older/patch-4.16.12-rt5.patch.xz
The split quilt queue is available at:
https://cdn.kernel.org/pub/linux/kernel/projects/rt/4.16/older/patches-4.16.12-rt5.tar.xz
Sebastian
drivers/base/power/wakeup.c +9 -9
@@ -57,7 +57,7 @@ static void split_counters(unsigned int *cnt, unsigned int *inpr)/* A preserved old value of the events counter. */ static unsigned int saved_count; -static DEFINE_SPINLOCK (events_lock); +static DEFINE_RAW_SPINLOCK (events_lock);static void pm_wakeup_timer_fn (struct timer_list *t);
@@ -185,9 +185,9 @@ void wakeup_source_add(struct wakeup_source *ws) ws->active = false; ws->last_time =ktime_get (); -spin_lock_irqsave (&events_lock, flags); +raw_spin_lock_irqsave (&events_lock, flags);list_add_rcu (&ws->entry, &wakeup_sources); -spin_unlock_irqrestore (&events_lock, flags); +raw_spin_unlock_irqrestore (&events_lock, flags); }EXPORT_SYMBOL_GPL (wakeup_source_add);
@@ -202,9 +202,9 @@ void wakeup_source_remove(struct wakeup_source *ws)if (WARN_ON (!ws))return ; -spin_lock_irqsave (&events_lock, flags); +raw_spin_lock_irqsave (&events_lock, flags);list_del_rcu (&ws->entry); -spin_unlock_irqrestore (&events_lock, flags); +raw_spin_unlock_irqrestore (&events_lock, flags);synchronize_srcu (&wakeup_srcu); }EXPORT_SYMBOL_GPL (wakeup_source_remove);
@@ -843,7 +843,7 @@ bool pm_wakeup_pending(void)unsigned long flags;bool ret = false; -spin_lock_irqsave (&events_lock, flags); +raw_spin_lock_irqsave (&events_lock, flags);if (events_check_enabled) {unsigned int cnt, inpr;
@@ -851,7 +851,7 @@ bool pm_wakeup_pending(void) ret = (cnt != saved_count || inpr >0 ); events_check_enabled = !ret; } -spin_unlock_irqrestore (&events_lock, flags); +raw_spin_unlock_irqrestore (&events_lock, flags);if (ret) {pr_info ("PM: Wakeup pending, aborting suspend\n" );
@@ -940,13 +940,13 @@ bool pm_save_wakeup_count(unsigned int count)unsigned long flags; events_check_enabled = false; -spin_lock_irqsave (&events_lock, flags); +raw_spin_lock_irqsave (&events_lock, flags);split_counters (&cnt, &inpr);if (cnt == count && inpr ==0 ) { saved_count = count; events_check_enabled = true; } -spin_unlock_irqrestore (&events_lock, flags); +raw_spin_unlock_irqrestore (&events_lock, flags);return events_check_enabled; }
drivers/md/raid5-cache.c +4 -4
@@ -1049,7 +1049,7 @@ int r5l_write_stripe(struct r5l_log *log, struct stripe_head *sh)* don't delay. */ clear_bit (STRIPE_DELAYED , &sh->state); -refcount_inc (&sh->count); +atomic_inc (&sh->count);mutex_lock (&log->io_mutex);/* meta + data */
@@ -1388,7 +1388,7 @@ static void r5c_flush_stripe(struct r5conf *conf, struct stripe_head *sh)lockdep_assert_held (&conf->device_lock);list_del_init (&sh->lru); -refcount_inc (&sh->count); +atomic_inc (&sh->count);set_bit (STRIPE_HANDLE , &sh->state);atomic_inc (&conf->active_stripes);
@@ -1491,7 +1491,7 @@ static void r5c_do_reclaim(struct r5conf *conf)*/ if (!list_empty (&sh->lru) && !test_bit (STRIPE_HANDLE , &sh->state) && -refcount_read (&sh->count) ==0 ) { +atomic_read (&sh->count) ==0 ) {r5c_flush_stripe (conf, sh);if (count++ >=R5C_RECLAIM_STRIPE_GROUP )break ;
@@ -2912,7 +2912,7 @@ int r5c_cache_data(struct r5l_log *log, struct stripe_head *sh)* don't delay. */ clear_bit (STRIPE_DELAYED , &sh->state); -refcount_inc (&sh->count); +atomic_inc (&sh->count);mutex_lock (&log->io_mutex);/* meta + data */
drivers/md/raid5-ppl.c +1 -1
@@ -388,7 +388,7 @@ int ppl_write_stripe(struct r5conf *conf, struct stripe_head *sh)set_bit (STRIPE_LOG_TRAPPED , &sh->state);clear_bit (STRIPE_DELAYED , &sh->state); -refcount_inc (&sh->count); +atomic_inc (&sh->count);if (ppl_log_stripe (log, sh)) {spin_lock_irq (&ppl_conf->no_mem_stripes_lock);
drivers/md/raid5.c +33 -34
240 lines not on this page · raw message
drivers/md/raid5.h +2 -2
@@ -4,7 +4,7 @@#include <linux/raid/xor.h> #include <linux/dmaengine.h> -#include <linux/refcount.h> +/* * * Each stripe contains one buffer per device. Each buffer can be in
@@ -208,7 +208,7 @@ struct stripe_head {short ddf_layout;/* use DDF ordering to calculate Q */ short hash_lock_index;unsigned long state;/* state flags */ -refcount_t count;/* nr of active thread/requests */ +atomic_t count;/* nr of active thread/requests */ int bm_seq;/* sequence number for bitmap flushes */ int disks;/* disks in stripe */ int overwrite_disks;/* total overwrite disks in stripe,
include/linux/lockdep.h +0 -11
@@ -608,22 +608,11 @@ do { \ "IRQs not disabled as expected\n"); \ } while (0) -#ifdef CONFIG_PREEMPT_RT_FULL -# define lockdep_assert_in_softirq () do { } while (0) -#else -# define lockdep_assert_in_softirq () do { \ - WARN_ONCE(debug_locks && !current->lockdep_recursion && \ - !current->softirq_context, \ - "Not in softirq context as expected\n"); \ - } while (0) -#endif - #else# define might_lock (lock) do { } while (0)# define might_lock_read (lock) do { } while (0)# define lockdep_assert_irqs_enabled () do { } while (0)# define lockdep_assert_irqs_disabled () do { } while (0) -# define lockdep_assert_in_softirq () do { } while (0)#endif #ifdef CONFIG_LOCKDEP
include/linux/seqlock.h +1 -0
@@ -461,6 +461,7 @@ static inline unsigned read_seqbegin(seqlock_t *sl)spin_unlock_wait (&sl->lock); goto repeat; } +smp_rmb ();return ret; }#endif
include/linux/spinlock.h +5 -0
@@ -419,6 +419,11 @@ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock);#define atomic_dec_and_lock (atomic, lock) \ __cond_lock(lock, _atomic_dec_and_lock(atomic, lock)) +extern int _atomic_dec_and_lock_irqsave (atomic_t *atomic,spinlock_t *lock, +unsigned long *flags); +#define atomic_dec_and_lock_irqsave (atomic, lock, flags) \ + __cond_lock(lock, _atomic_dec_and_lock_irqsave(atomic, lock, &(flags))) +int alloc_bucket_spinlocks (spinlock_t **locks,unsigned int *lock_mask,size_t max_size,unsigned int cpu_mult,gfp_t gfp);
include/trace/events/sched.h +3 -1
@@ -435,7 +435,9 @@ TRACE_EVENT(sched_pi_setprio,memcpy (__entry->comm, tsk->comm,TASK_COMM_LEN ); __entry->pid = tsk->pid; __entry->oldprio = tsk->prio; - __entry->newprio = pi_task ? pi_task->prio : tsk->prio; + __entry->newprio = pi_task ? +min (tsk->normal_prio, pi_task->prio) : + tsk->normal_prio;/* XXX SCHED_DEADLINE bits missing */ ),
kernel/power/suspend.c +12 -11
@@ -27,6 +27,7 @@#include <linux/export.h> #include <linux/suspend.h> #include <linux/syscore_ops.h> +#include <linux/swait.h> #include <linux/ftrace.h> #include <trace/events/power.h> #include <linux/compiler.h>
@@ -57,10 +58,10 @@ EXPORT_SYMBOL_GPL(pm_suspend_global_flags);static const struct platform_suspend_ops *suspend_ops;static const struct platform_s2idle_ops *s2idle_ops; -static DECLARE_WAIT_QUEUE_HEAD (s2idle_wait_head); +static DECLARE_SWAIT_QUEUE_HEAD (s2idle_wait_head);enum s2idle_states __read_mostly s2idle_state; -static DEFINE_SPINLOCK (s2idle_lock); +static DEFINE_RAW_SPINLOCK (s2idle_lock);void s2idle_set_ops (const struct platform_s2idle_ops *ops) {
@@ -78,12 +79,12 @@ static void s2idle_enter(void) {trace_suspend_resume (TPS ("machine_suspend" ),PM_SUSPEND_TO_IDLE , true); -spin_lock_irq (&s2idle_lock); +raw_spin_lock_irq (&s2idle_lock);if (pm_wakeup_pending ()) goto out; s2idle_state =S2IDLE_STATE_ENTER ; -spin_unlock_irq (&s2idle_lock); +raw_spin_unlock_irq (&s2idle_lock);get_online_cpus ();cpuidle_resume ();
@@ -91,17 +92,17 @@ static void s2idle_enter(void)/* Push all the CPUs into the idle loop. */ wake_up_all_idle_cpus ();/* Make the current CPU wait so it can enter the idle loop too. */ -wait_event (s2idle_wait_head, - s2idle_state ==S2IDLE_STATE_WAKE ); +swait_event (s2idle_wait_head, + s2idle_state ==S2IDLE_STATE_WAKE );cpuidle_pause ();put_online_cpus (); -spin_lock_irq (&s2idle_lock); +raw_spin_lock_irq (&s2idle_lock); out: s2idle_state =S2IDLE_STATE_NONE ; -spin_unlock_irq (&s2idle_lock); +raw_spin_unlock_irq (&s2idle_lock);trace_suspend_resume (TPS ("machine_suspend" ),PM_SUSPEND_TO_IDLE , false); }
@@ -156,12 +157,12 @@ void s2idle_wake(void) {unsigned long flags; -spin_lock_irqsave (&s2idle_lock, flags); +raw_spin_lock_irqsave (&s2idle_lock, flags);if (s2idle_state >S2IDLE_STATE_NONE ) { s2idle_state =S2IDLE_STATE_WAKE ; -wake_up (&s2idle_wait_head); +swake_up (&s2idle_wait_head); } -spin_unlock_irqrestore (&s2idle_lock, flags); +raw_spin_unlock_irqrestore (&s2idle_lock, flags); }EXPORT_SYMBOL_GPL (s2idle_wake);
kernel/time/tick-common.c +2 -0
@@ -492,6 +492,7 @@ void tick_freeze(void)if (tick_freeze_depth ==num_online_cpus ()) {trace_suspend_resume (TPS ("timekeeping_freeze" ),smp_processor_id (), true); + system_state =SYSTEM_SUSPEND ;timekeeping_suspend (); }else {tick_suspend_local ();
@@ -515,6 +516,7 @@ void tick_unfreeze(void)if (tick_freeze_depth ==num_online_cpus ()) {timekeeping_resume (); + system_state =SYSTEM_RUNNING ;trace_suspend_resume (TPS ("timekeeping_freeze" ),smp_processor_id (), false); }else {
lib/dec_and_lock.c +16 -0
@@ -33,3 +33,19 @@ int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) }EXPORT_SYMBOL (_atomic_dec_and_lock); + +int _atomic_dec_and_lock_irqsave (atomic_t *atomic,spinlock_t *lock, +unsigned long *flags) +{ +/* Subtract 1 from counter unless that drops it to 0 (ie. it was 1) */ +if (atomic_add_unless (atomic,-1 ,1 )) +return 0 ; + +/* Otherwise do it the slow way */ +spin_lock_irqsave (lock, *flags); +if (atomic_dec_and_test (atomic)) +return 1 ; +spin_unlock_irqrestore (lock, *flags); +return 0 ; +} +EXPORT_SYMBOL (_atomic_dec_and_lock_irqsave);
localversion-rt +1 -1
@@ -1 +1 @@ --rt4 +-rt5
net/core/dev.c +0 -3
@@ -4736,9 +4736,6 @@ static int netif_receive_skb_internal(struct sk_buff *skb)*/ int netif_receive_skb (struct sk_buff *skb) { -lockdep_assert_irqs_enabled (); -lockdep_assert_in_softirq (); -trace_netif_receive_skb_entry (skb);return netif_receive_skb_internal (skb);
net/mac80211/rx.c +2 -0
@@ -4245,6 +4245,8 @@ void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,struct ieee80211_supported_band *sband;struct ieee80211_rx_status *status =IEEE80211_SKB_RXCB (skb); +WARN_ON_ONCE (softirq_count () ==0 ); +if (WARN_ON (status->band >=NUM_NL80211_BANDS )) goto drop;
net/mac802154/rx.c +2 -0
@@ -258,6 +258,8 @@ void ieee802154_rx(struct ieee802154_local *local, struct sk_buff *skb) {u16 crc; +WARN_ON_ONCE (softirq_count () ==0 ); +if (local->suspended) goto drop;
PATCH 1/1 mm/memcontrol: Don't call schedule_work_on in preemption disabled context
Was dropping this patch unintentional?
(met the gripe in my tip-rt5 tree, so resurrected it)
From: Yang Shi <[email protected]>
The following trace is triggered when running ltp oom test cases:
BUG: sleeping function called from invalid context at kernel/rtmutex.c:659
in_atomic(): 1, irqs_disabled(): 0, pid: 17188, name: oom03 Preemption disabled at:[<ffffffff8112ba70>] mem_cgroup_reclaim+0x90/0xe0
CPU: 2 PID: 17188 Comm: oom03 Not tainted 3.10.10-rt3 #2 Hardware name: Intel Corporation Calpella platform/MATXM-CORE-411-B, BIOS 4.6.3 08/18/2010 ffff88007684d730 ffff880070df9b58 ffffffff8169918d ffff880070df9b70 ffffffff8106db31 ffff88007688b4a0 ffff880070df9b88 ffffffff8169d9c0 ffff88007688b4a0 ffff880070df9bc8 ffffffff81059da1 0000000170df9bb0 Call Trace: [<ffffffff8169918d>] dump_stack+0x19/0x1b [<ffffffff8106db31>] __might_sleep+0xf1/0x170 [<ffffffff8169d9c0>] rt_spin_lock+0x20/0x50 [<ffffffff81059da1>] queue_work_on+0x61/0x100 [<ffffffff8112b361>] drain_all_stock+0xe1/0x1c0 [<ffffffff8112ba70>] mem_cgroup_reclaim+0x90/0xe0 [<ffffffff8112beda>] __mem_cgroup_try_charge+0x41a/0xc40 [<ffffffff810f1c91>] ? release_pages+0x1b1/0x1f0 [<ffffffff8106f200>] ? sched_exec+0x40/0xb0 [<ffffffff8112cc87>] mem_cgroup_charge_common+0x37/0x70 [<ffffffff8112e2c6>] mem_cgroup_newpage_charge+0x26/0x30 [<ffffffff8110af68>] handle_pte_fault+0x618/0x840 [<ffffffff8103ecf6>] ? unpin_current_cpu+0x16/0x70 [<ffffffff81070f94>] ? migrate_enable+0xd4/0x200 [<ffffffff8110cde5>] handle_mm_fault+0x145/0x1e0 [<ffffffff810301e1>] __do_page_fault+0x1a1/0x4c0 [<ffffffff8169c9eb>] ? preempt_schedule_irq+0x4b/0x70 [<ffffffff8169e3b7>] ? retint_kernel+0x37/0x40 [<ffffffff8103053e>] do_page_fault+0xe/0x10 [<ffffffff8169e4c2>] page_fault+0x22/0x30
So, to prevent schedule_work_on from being called in preempt disabled context, replace the pair of get/put_cpu() to get/put_cpu_light().
--- mm/memcontrol.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
mm/memcontrol.c +2 -2
@@ -1786,7 +1786,7 @@ static void drain_all_stock(struct mem_cgroup *root_memcg)* as well as workers from this path always operate on the local * per-cpu data. CPU up doesn't touch memcg_stock at all. */ - curcpu =get_cpu (); + curcpu =get_cpu_light ();for_each_online_cpu (cpu) {struct memcg_stock_pcp *stock = &per_cpu (memcg_stock, cpu);struct mem_cgroup *memcg;
@@ -1806,7 +1806,7 @@ static void drain_all_stock(struct mem_cgroup *root_memcg) }css_put (&memcg->css); } -put_cpu (); +put_cpu_light ();mutex_unlock (&percpu_charge_mutex); }
Signature · 1 line
2.17.0
Re: [missing 4.16-rt5 patch ?] mm/memcontrol: Don't call schedule_work_on in preemption disabled context
Quoted 3 lines · Mike Galbraith
Was dropping this patch unintentional?
(met the gripe in my tip-rt5 tree, so resurrected it)
Not sure. I remember the local_irq_save() block was dealing with counters only and it was safe to drop it.
The schedule_work_on() part is obvious (not to mention the possible latency part).
So that css_put() is not a problem? I'm mostly curious in the callback which would run irq-off section. How does not get into that code path anyway, is there something in the LTP that would trigger that?
Sebastian
Re: [missing 4.16-rt5 patch ?] mm/memcontrol: Don't call schedule_work_on in preemption disabled context
Quoted 3 lines · Sebastian Andrzej Siewior
So that
css_put()is not a problem? I'm mostly curious in the callback which would run irq-off section. How does not get into that code path anyway, is there something in the LTP that would trigger that?
No idea. The only thing I've _met_ is the schedule_work_on() bit.
-Mike