Linux v4.14.172-rt78-rc1
Subsystems (8)
cover Linux v4.14.172-rt78-rc1
From: Tom Zanussi <[email protected]>
Dear RT Folks,
This is the RT stable review cycle of patch 4.14.172-rt78-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 2020-03-16.
To build 4.14.172-rt78-rc1 directly, the following patches should be applied:
https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.14.tar.xz
https://www.kernel.org/pub/linux/kernel/v4.x/patch-4.14.172.xz
https://www.kernel.org/pub/linux/kernel/projects/rt/4.14/patch-4.14.172-rt78-rc1.patch.xz
You can also build from 4.14.172-rt77 by applying the incremental patch:
https://www.kernel.org/pub/linux/kernel/projects/rt/4.14/incr/patch-4.14.172-rt77-rt78-rc1.patch.xz
Enjoy,
-- Tom
Matt Fleming (1):
mm/memcontrol: Move misplaced local_unlock_irqrestore()
Scott Wood (2):
sched: migrate_enable: Use per-cpu cpu_stop_work
sched: migrate_enable: Remove __schedule() call
Sebastian Andrzej Siewior (4):
userfaultfd: Use a seqlock instead of seqcount
locallock: Include header for the `current' macro drm/vmwgfx: Drop preempt_disable() in vmw_fifo_ping_host()
tracing: make preempt_lazy and migrate_disable counter smaller
Tom Zanussi (1):
Linux 4.14.172-rt78-rc1
drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | 2 -- fs/userfaultfd.c | 12 ++++++------ include/linux/locallock.h | 1 + include/linux/trace_events.h | 3 +-- kernel/sched/core.c | 23 ++++++++++++++--------- kernel/trace/trace_events.c | 4 ++-- localversion-rt | 2 +- mm/memcontrol.c | 2 +- 8 files changed, 26 insertions(+), 23 deletions(-)
Signature · 1 line
2.14.1
PATCH 1/8 userfaultfd: Use a seqlock instead of seqcount
From: Sebastian Andrzej Siewior <[email protected]>
v4.14.172-rt78-rc1 stable review patch.
If anyone has any objections, please let me know.
-----------
[ Upstream commit dc952a564d02997330654be9628bbe97ba2a05d3 ]
On RT write_seqcount_begin() disables preemption which leads to warning in add_wait_queue() while the spinlock_t is acquired.
The waitqueue can't be converted to swait_queue because userfaultfd_wake_function() is used as a custom wake function.
Use seqlock instead seqcount to avoid the preempt_disable() section during add_wait_queue().
--- fs/userfaultfd.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
fs/userfaultfd.c +6 -6
@@ -51,7 +51,7 @@ struct userfaultfd_ctx {/* waitqueue head for events */ wait_queue_head_t event_wqh;/* a refile sequence protected by fault_pending_wqh lock */ -struct seqcount refile_seq; +seqlock_t refile_seq;/* pseudo fd refcounting */ atomic_t refcount;/* userfaultfd syscall flags */
@@ -1047,7 +1047,7 @@ static ssize_t userfaultfd_ctx_read(struct userfaultfd_ctx *ctx, int no_wait,* waitqueue could become empty if this is the * only userfault. */ -write_seqcount_begin (&ctx->refile_seq); +write_seqlock (&ctx->refile_seq);/* * The fault_pending_wqh.lock prevents the uwq
@@ -1073,7 +1073,7 @@ static ssize_t userfaultfd_ctx_read(struct userfaultfd_ctx *ctx, int no_wait,list_del (&uwq->wq.entry);__add_wait_queue (&ctx->fault_wqh, &uwq->wq); -write_seqcount_end (&ctx->refile_seq); +write_sequnlock (&ctx->refile_seq);/* careful to always initialize msg if ret == 0 */ *msg = uwq->msg;
@@ -1246,11 +1246,11 @@ static __always_inline void wake_userfault(struct userfaultfd_ctx *ctx,* sure we've userfaults to wake. */ do { - seq =read_seqcount_begin (&ctx->refile_seq); + seq =read_seqbegin (&ctx->refile_seq); need_wakeup =waitqueue_active (&ctx->fault_pending_wqh) ||waitqueue_active (&ctx->fault_wqh);cond_resched (); - }while (read_seqcount_retry (&ctx->refile_seq, seq)); + }while (read_seqretry (&ctx->refile_seq, seq));if (need_wakeup)__wake_userfault (ctx, range); }
@@ -1915,7 +1915,7 @@ static void init_once_userfaultfd_ctx(void *mem)init_waitqueue_head (&ctx->fault_wqh);init_waitqueue_head (&ctx->event_wqh);init_waitqueue_head (&ctx->fd_wqh); -seqcount_init (&ctx->refile_seq); +seqlock_init (&ctx->refile_seq); }/**
Signature · 1 line
2.14.1
PATCH 2/8 sched: migrate_enable: Use per-cpu cpu_stop_work
In reply to [email protected]From: Scott Wood <[email protected]>
v4.14.172-rt78-rc1 stable review patch.
If anyone has any objections, please let me know.
-----------
[ Upstream commit 2dcd94b443c5dcbc20281666321b7f025f9cc85c ]
Commit e6c287b1512d ("sched: migrate_enable: Use stop_one_cpu_nowait()") adds a busy wait to deal with an edge case where the migrated thread can resume running on another CPU before the stopper has consumed cpu_stop_work. However, this is done with preemption disabled and can potentially lead to deadlock.
While it is not guaranteed that the cpu_stop_work will be consumed before the migrating thread resumes and exits the stack frame, it is guaranteed that nothing other than the stopper can run on the old cpu between the migrating thread scheduling out and the cpu_stop_work being consumed. Thus, we can store cpu_stop_work in per-cpu data without it being reused too early.
Conflicts:
kernel/sched/core.c
--- kernel/sched/core.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-)
kernel/sched/core.c +14 -8
@@ -6964,6 +6964,9 @@ static void migrate_disabled_sched(struct task_struct *p) p->migrate_disable_scheduled =1 ; } +static DEFINE_PER_CPU(struct cpu_stop_work, migrate_work); +static DEFINE_PER_CPU(struct migration_arg, migrate_arg); +void migrate_enable (void ) {struct task_struct *p = current;
@@ -7002,23 +7005,26 @@ void migrate_enable(void)WARN_ON (smp_processor_id () != cpu);if (!is_cpu_allowed (p, cpu)) { -struct migration_arg arg = { .task = p }; -struct cpu_stop_work work; +struct migration_arg __percpu *arg; +struct cpu_stop_work __percpu *work;struct rq_flags rf; + work =this_cpu_ptr (&migrate_work); + arg =this_cpu_ptr (&migrate_arg); +WARN_ON_ONCE (!arg->done && !work->disabled && work->arg); + + arg->task = p; + arg->done = false; + rq =task_rq_lock (p, &rf);update_rq_clock (rq); - arg.dest_cpu =select_fallback_rq (cpu, p); + arg->dest_cpu =select_fallback_rq (cpu, p);task_rq_unlock (rq, p, &rf);stop_one_cpu_nowait (task_cpu (p), migration_cpu_stop, - &arg, &work); + arg, work);tlb_migrate_finish (p->mm);__schedule (true); -if (!work.disabled) { -while (!arg.done) -cpu_relax (); - } } out:
Signature · 1 line
2.14.1
PATCH 3/8 sched: migrate_enable: Remove __schedule() call
In reply to [email protected]From: Scott Wood <[email protected]>
v4.14.172-rt78-rc1 stable review patch.
If anyone has any objections, please let me know.
-----------
[ Upstream commit b8162e61e9a33bd1de6452eb838fbf50a93ddd9a ]
We can rely on preempt_enable() to schedule. Besides simplifying the code, this potentially allows sequences such as the following to be permitted:
migrate_disable();preempt_disable();migrate_enable();preempt_enable();
Conflicts:
kernel/sched/core.c
--- kernel/sched/core.c | 1 - 1 file changed, 1 deletion(-)
kernel/sched/core.c +0 -1
@@ -7024,7 +7024,6 @@ void migrate_enable(void)stop_one_cpu_nowait (task_cpu (p), migration_cpu_stop, arg, work);tlb_migrate_finish (p->mm); -__schedule (true); } out:
Signature · 1 line
2.14.1
PATCH 4/8 mm/memcontrol: Move misplaced local_unlock_irqrestore()
In reply to [email protected]From: Matt Fleming <[email protected]>
v4.14.172-rt78-rc1 stable review patch.
If anyone has any objections, please let me know.
-----------
[ Upstream commit 071a1d6a6e14d0dec240a8c67b425140d7f92f6a ]
The comment about local_lock_irqsave() mentions just the counters and css_put_many()'s callback just invokes a worker so it is safe to move the unlock function after memcg_check_events() so css_put_many() can be invoked without the lock acquired.
--- mm/memcontrol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/memcontrol.c +1 -1
@@ -6102,10 +6102,10 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry)mem_cgroup_charge_statistics (memcg, page,PageTransHuge (page), -nr_entries);memcg_check_events (memcg, page); +local_unlock_irqrestore (event_lock, flags);if (!mem_cgroup_is_root (memcg))css_put_many (&memcg->css, nr_entries); -local_unlock_irqrestore (event_lock, flags); }/**
Signature · 1 line
2.14.1
PATCH 5/8 locallock: Include header for the `current' macro
In reply to [email protected]From: Sebastian Andrzej Siewior <[email protected]>
v4.14.172-rt78-rc1 stable review patch.
If anyone has any objections, please let me know.
-----------
[ Upstream commit e693075a5fd852043fa8d2b0467e078d9e5cb782 ]
Include the header for `current' macro so thatCONFIG_KERNEL_HEADER_TEST=y passes.
--- include/linux/locallock.h | 1 + 1 file changed, 1 insertion(+)
include/linux/locallock.h +1 -0
@@ -3,6 +3,7 @@#include <linux/percpu.h> #include <linux/spinlock.h> +#include <asm/current.h> #ifdef CONFIG_PREEMPT_RT_BASE
Signature · 1 line
2.14.1
PATCH 6/8 drm/vmwgfx: Drop preempt_disable() in vmw_fifo_ping_host()
In reply to [email protected]From: Sebastian Andrzej Siewior <[email protected]>
v4.14.172-rt78-rc1 stable review patch.
If anyone has any objections, please let me know.
-----------
[ Upstream commit b901491e7b9b7a676818d84e482b69be72fc142f ]
vmw_fifo_ping_host() disables preemption around a test and a register write via vmw_write(). The write function acquires a spinlock_t typed lock which is not allowed in a preempt_disable()ed section on PREEMPT_RT. This has been reported in the bugzilla.
It has been explained by Thomas Hellstrom that this preempt_disable()ed section is not required for correctness.
Remove the preempt_disable() section.
--- drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c | 2 -- 1 file changed, 2 deletions(-)
drivers/gpu/drm/vmwgfx/vmwgfx_fifo.c +0 -2
@@ -167,10 +167,8 @@ void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason) {u32 *fifo_mem = dev_priv->mmio_virt; -preempt_disable ();if (cmpxchg (fifo_mem +SVGA_FIFO_BUSY ,0 ,1 ) ==0 )vmw_write (dev_priv,SVGA_REG_SYNC , reason); -preempt_enable (); }void vmw_fifo_release (struct vmw_private *dev_priv,struct vmw_fifo_state *fifo)
Signature · 1 line
2.14.1
PATCH 7/8 tracing: make preempt_lazy and migrate_disable counter smaller
In reply to [email protected]From: Sebastian Andrzej Siewior <[email protected]>
v4.14.172-rt78-rc1 stable review patch.
If anyone has any objections, please let me know.
-----------
[ Upstream commit dd430bf5ecb40f9a89679c85868826475d71de54 ]
The migrate_disable counter should not exceed 255 so it is enough to store it in an 8bit field.
With this change we can move the preempt_lazy_count' member into the gap so the whole struct shrinks by 4 bytes to 12 bytes in total. Remove the padding' field, it is not needed.
Update the tracing fields in trace_define_common_fields() (it was missing the preempt_lazy_count field).
--- include/linux/trace_events.h | 3 +-- kernel/trace/trace_events.c | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-)
include/linux/trace_events.h +1 -2
@@ -62,8 +62,7 @@ struct trace_entry {unsigned char flags;unsigned char preempt_count;int pid; -unsigned short migrate_disable; -unsigned short padding; +unsigned char migrate_disable;unsigned char preempt_lazy_count; };
kernel/trace/trace_events.c +2 -2
@@ -187,8 +187,8 @@ static int trace_define_common_fields(void) __common_field(unsigned char, flags); __common_field(unsigned char, preempt_count);__common_field (int, pid); - __common_field(unsigned short, migrate_disable); - __common_field(unsigned short, padding); + __common_field(unsigned char, migrate_disable); + __common_field(unsigned char, preempt_lazy_count);return ret; }
Signature · 1 line
2.14.1
PATCH 8/8 Linux 4.14.172-rt78-rc1
In reply to [email protected]From: Tom Zanussi <[email protected]>
v4.14.172-rt78-rc1 stable review patch.
If anyone has any objections, please let me know.
-----------
--- localversion-rt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
localversion-rt +1 -1
@@ -1 +1 @@ --rt77 +-rt78-rc1
Signature · 1 line
2.14.1