Linux v5.4.182-rt71-rc1
cover Linux v5.4.182-rt71-rc1
From: Tom Zanussi <[email protected]>
Dear RT Folks,
This is the RT stable review cycle of patch 5.4.182-rt71-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 2022-03-12.
To build 5.4.182-rt71-rc1 directly, the following patches should be applied:
https://www.kernel.org/pub/linux/kernel/v5.x/linux-5.4.tar.xz
https://www.kernel.org/pub/linux/kernel/v5.x/patch-5.4.182.xz
https://www.kernel.org/pub/linux/kernel/projects/rt/5.4/patch-5.4.182-rt71-rc1.patch.xz
You can also build from 5.4.182-rt70 by applying the incremental patch:
https://www.kernel.org/pub/linux/kernel/projects/rt/5.4/incr/patch-5.4.182-rt70-rt71-rc1.patch.xz
Enjoy,
-- Tom
Thomas Gleixner (1):
eventfd: Make signal recursion protection a task bit
Tom Zanussi (1):
Linux 5.4.182-rt71-rc1
Xie Yongji (1):
aio: Fix incorrect usage of eventfd_signal_allowed()
fs/aio.c | 2 +- fs/eventfd.c | 12 +++++------- include/linux/eventfd.h | 11 +++++------ include/linux/sched.h | 12 ++++++++++++ localversion-rt | 2 +- 5 files changed, 24 insertions(+), 15 deletions(-)
Signature · 1 line
2.17.1
PATCH 1/3 eventfd: Make signal recursion protection a task bit
From: Thomas Gleixner <[email protected]>
v5.4.182-rt71-rc1 stable review patch.
If anyone has any objections, please let me know.
-----------
[ Upstream commit b542e383d8c005f06a131e2b40d5889b812f19c6 ]
The recursion protection for eventfd_signal() is based on a per CPU variable and relies on the !RT semantics of spin_lock_irqsave() for protecting this per CPU variable. On RT kernels spin_lock_irqsave() neither disables preemption nor interrupts which allows the spin lock held section to be preempted. If the preempting task invokes eventfd_signal() as well, then the recursion warning triggers.
Paolo suggested to protect the per CPU variable with a local lock, but that's heavyweight and actually not necessary. The goal of this protection is to prevent the task stack from overflowing, which can be achieved with a per task recursion protection as well.
Replace the per CPU variable with a per task bit similar to other recursion protection bits like task_struct::in_page_owner. This works on both !RT and RT kernels and removes as a side effect the extra per CPU storage.
No functional change for !RT kernels.
Conflicts:
fs/aio.c
include/linux/sched.h
--- fs/aio.c | 2 +- fs/eventfd.c | 12 +++++------- include/linux/eventfd.h | 11 +++++------ include/linux/sched.h | 12 ++++++++++++ 4 files changed, 23 insertions(+), 14 deletions(-)
fs/aio.c +1 -1
@@ -1767,7 +1767,7 @@ static int aio_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,list_del_init (&req->wait.entry);list_del (&iocb->ki_list); iocb->ki_res.res =mangle_poll (mask); -if (iocb->ki_eventfd &&eventfd_signal_count ()) { +if (iocb->ki_eventfd &&eventfd_signal_allowed ()) { iocb =NULL ;INIT_WORK (&req->work, aio_poll_put_work);schedule_work (&req->work);
fs/eventfd.c +5 -7
@@ -24,8 +24,6 @@#include <linux/seq_file.h> #include <linux/idr.h> -DEFINE_PER_CPU (int, eventfd_wake_count); -static DEFINE_IDA (eventfd_ida);struct eventfd_ctx {
@@ -66,21 +64,21 @@ __u64 eventfd_signal(struct eventfd_ctx *ctx, __u64 n)* Deadlock or stack overflow issues can happen if we recurse here * through waitqueue wakeup handlers. If the caller users potentially * nested waitqueues with custom wakeup handlers, then it should -* check eventfd_signal_count() before calling this function. If -* it returns true, the eventfd_signal() call should be deferred to a +* check eventfd_signal_allowed() before calling this function. If +* it returns false, the eventfd_signal() call should be deferred to a * safe context. */ -if (WARN_ON_ONCE (this_cpu_read (eventfd_wake_count))) +if (WARN_ON_ONCE (current->in_eventfd_signal))return 0 ;spin_lock_irqsave (&ctx->wqh.lock, flags); -this_cpu_inc (eventfd_wake_count); + current->in_eventfd_signal =1 ;if (ULLONG_MAX - ctx->count < n) n =ULLONG_MAX - ctx->count; ctx->count += n;if (waitqueue_active (&ctx->wqh))wake_up_locked_poll (&ctx->wqh,EPOLLIN ); -this_cpu_dec (eventfd_wake_count); + current->in_eventfd_signal =0 ;spin_unlock_irqrestore (&ctx->wqh.lock, flags);return n;
include/linux/eventfd.h +5 -6
@@ -14,6 +14,7 @@#include <linux/err.h> #include <linux/percpu-defs.h> #include <linux/percpu.h> +#include <linux/sched.h> /* * CAREFUL: Check include/uapi/asm-generic/fcntl.h when defining
@@ -42,11 +43,9 @@ __u64 eventfd_signal(struct eventfd_ctx *ctx, __u64 n);int eventfd_ctx_remove_wait_queue (struct eventfd_ctx *ctx,wait_queue_entry_t *wait,__u64 *cnt); -DECLARE_PER_CPU (int, eventfd_wake_count); - -static inline bool eventfd_signal_count (void ) +static inline bool eventfd_signal_allowed (void ) { -return this_cpu_read (eventfd_wake_count); +return !current->in_eventfd_signal; }#else /* CONFIG_EVENTFD */
@@ -77,9 +76,9 @@ static inline int eventfd_ctx_remove_wait_queue(struct eventfd_ctx *ctx, return -ENOSYS; } -static inline bool eventfd_signal_count (void ) +static inline bool eventfd_signal_allowed (void ) { -return false; +return true; }#endif
include/linux/sched.h +12 -0
@@ -802,6 +802,18 @@ struct task_struct {/* to be used once the psi infrastructure lands upstream. */ unsigned use_memdelay:1;#endif +#ifdef CONFIG_PSI +/* Stalled due to lack of memory */ + unsigned in_memstall:1; +#endif +#ifdef CONFIG_PAGE_OWNER +/* Used by page_owner=on to detect recursion in page tracking. */ + unsigned in_page_owner:1; +#endif +#ifdef CONFIG_EVENTFD +/* Recursion prevention for eventfd_signal() */ + unsigned in_eventfd_signal:1; +#endif unsigned long atomic_flags;/* Flags requiring atomic access. */
Signature · 1 line
2.17.1
PATCH 2/3 aio: Fix incorrect usage of eventfd_signal_allowed()
In reply to [email protected]From: Xie Yongji <[email protected]>
v5.4.182-rt71-rc1 stable review patch.
If anyone has any objections, please let me know.
-----------
[ Upstream commmit 4b3749865374899e115aa8c48681709b086fe6d3 ]
We should defer eventfd_signal() to the workqueue when eventfd_signal_allowed() return false rather than return true.
--- fs/aio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/aio.c +1 -1
@@ -1767,7 +1767,7 @@ static int aio_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,list_del_init (&req->wait.entry);list_del (&iocb->ki_list); iocb->ki_res.res =mangle_poll (mask); -if (iocb->ki_eventfd &&eventfd_signal_allowed ()) { +if (iocb->ki_eventfd && !eventfd_signal_allowed ()) { iocb =NULL ;INIT_WORK (&req->work, aio_poll_put_work);schedule_work (&req->work);
Signature · 1 line
2.17.1
PATCH 3/3 Linux 5.4.182-rt71-rc1
In reply to [email protected]From: Tom Zanussi <[email protected]>
v5.4.182-rt71-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 @@ --rt70 +-rt71-rc1
Signature · 1 line
2.17.1