* Re: [syzbot] [mm?] INFO: rcu detected stall in validate_mm (3)
2024-05-12 9:19 [syzbot] [mm?] INFO: rcu detected stall in validate_mm (3) syzbot
@ 2024-05-12 17:28 ` Liam R. Howlett
2024-05-12 20:41 ` Liam R. Howlett
2024-07-03 7:32 ` [syzbot] Test syzbot
2024-07-03 8:24 ` syzbot
2 siblings, 1 reply; 7+ messages in thread
From: Liam R. Howlett @ 2024-05-12 17:28 UTC (permalink / raw)
To: syzbot; +Cc: akpm, linux-kernel, linux-mm, lstoakes, syzkaller-bugs, vbabka
* syzbot <syzbot+a941018a091f1a1f9546@syzkaller.appspotmail.com> [240512 05:19]:
> Hello,
>
> syzbot found the following issue on:
First, excellent timing of this report - Sunday on an -rc7 release the
day before LSF/MM/BPF.
>
> HEAD commit: dccb07f2914c Merge tag 'for-6.9-rc7-tag' of git://git.kern..
> git tree: upstream
> console output: https://syzkaller.appspot.com/x/log.txt?x=13f6734c980000
> kernel config: https://syzkaller.appspot.com/x/.config?x=7144b4fe7fbf5900
> dashboard link: https://syzkaller.appspot.com/bug?extid=a941018a091f1a1f9546
> compiler: gcc (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40
> syz repro: https://syzkaller.appspot.com/x/repro.syz?x=10306760980000
> C reproducer: https://syzkaller.appspot.com/x/repro.c?x=138c8970980000
>
> Downloadable assets:
> disk image: https://storage.googleapis.com/syzbot-assets/e1fea5a49470/disk-dccb07f2.raw.xz
> vmlinux: https://storage.googleapis.com/syzbot-assets/5f7d53577fef/vmlinux-dccb07f2.xz
> kernel image: https://storage.googleapis.com/syzbot-assets/430b18473a18/bzImage-dccb07f2.xz
>
> IMPORTANT: if you fix the issue, please add the following tag to the commit:
> Reported-by: syzbot+a941018a091f1a1f9546@syzkaller.appspotmail.com
>
> rcu: INFO: rcu_preempt detected stalls on CPUs/tasks:
> rcu: Tasks blocked on level-0 rcu_node (CPUs 0-1): P17678/1:b..l
> rcu: (detected by 1, t=10502 jiffies, g=36541, q=38 ncpus=2)
> task:syz-executor952 state:R running task stack:28968 pid:17678 tgid:17678 ppid:5114 flags:0x00000002
> Call Trace:
> <TASK>
> context_switch kernel/sched/core.c:5409 [inline]
> __schedule+0xf15/0x5d00 kernel/sched/core.c:6746
> preempt_schedule_irq+0x51/0x90 kernel/sched/core.c:7068
> irqentry_exit+0x36/0x90 kernel/entry/common.c:354
> asm_sysvec_apic_timer_interrupt+0x1a/0x20 arch/x86/include/asm/idtentry.h:702
> RIP: 0010:bytes_is_nonzero mm/kasan/generic.c:88 [inline]
> RIP: 0010:memory_is_nonzero mm/kasan/generic.c:122 [inline]
> RIP: 0010:memory_is_poisoned_n mm/kasan/generic.c:129 [inline]
> RIP: 0010:memory_is_poisoned mm/kasan/generic.c:161 [inline]
> RIP: 0010:check_region_inline mm/kasan/generic.c:180 [inline]
> RIP: 0010:kasan_check_range+0xc7/0x1a0 mm/kasan/generic.c:189
> Code: 83 c0 08 48 39 d0 0f 84 be 00 00 00 48 83 38 00 74 ed 48 8d 50 08 eb 0d 48 83 c0 01 48 39 c2 0f 84 8d 00 00 00 80 38 00 74 ee <48> 89 c2 b8 01 00 00 00 48 85 d2 74 1e 41 83 e2 07 49 39 d1 75 0a
> RSP: 0018:ffffc900031ef850 EFLAGS: 00000202
> RAX: fffffbfff2949b78 RBX: fffffbfff2949b79 RCX: ffffffff8ac92249
> RDX: fffffbfff2949b79 RSI: 0000000000000004 RDI: ffffffff94a4dbc0
> RBP: fffffbfff2949b78 R08: 0000000000000001 R09: fffffbfff2949b78
> R10: ffffffff94a4dbc3 R11: 0000000000000001 R12: 0000000000000000
> R13: 0000000000000001 R14: 0000000000000300 R15: 0000000000000000
> instrument_atomic_read_write include/linux/instrumented.h:96 [inline]
> atomic_inc include/linux/atomic/atomic-instrumented.h:435 [inline]
> mt_validate_nulls+0x5e9/0x9e0 lib/maple_tree.c:7550
> mt_validate+0x3148/0x4390 lib/maple_tree.c:7599
> validate_mm+0x9c/0x4b0 mm/mmap.c:288
> mmap_region+0x1478/0x2760 mm/mmap.c:2934
> do_mmap+0x8ae/0xf10 mm/mmap.c:1385
> vm_mmap_pgoff+0x1ab/0x3c0 mm/util.c:573
> ksys_mmap_pgoff+0x7d/0x5b0 mm/mmap.c:1431
...
I was concerned that we had somehow constructed a broken tree, but I
believe the information below rules that situation out. It appears that
the verification of a tasks maple tree has exceeded the timeout allotted
to do so. This call stack indicates it is all happening while holding
the mmap lock, so no locking or RCU issue there.
This trace seems to think we are stuck in the checking the tree for
sequential NULLs, but not in the tree operation itself. This would
indicate the issue isn't here at all - or we have a broken tree which
causes the iteration to never advance.
The adjustments of the timeouts do seem to be sufficient and I am not
getting hung on my vm running the c reproducer, yet. I am not using the
bots config, yet.
I also noticed that the git bisect is very odd and inconsistent, often
ending in "crashed: INFO: rcu detected stall in corrupted". I also
noticed that KASAN is disabled in this report?
"disabling configs for [UBSAN BUG KASAN LOCKDEP ATOMIC_SLEEP LEAK], they
are not needed"
This seems like it would be wise to enable as it seems there is
corrupted stack traces, at least? I noticed that the .config DOES have
kasan enabled, so I guess it was dropped because it didn't pick up an
issue on the initial run?
There is only one report (the initial report) that detects the hung
state in the validate_mm() test function. This is actually the less
concerning of all of the other places - because this validate function
is generally disabled on production systems.
The last change to lib/maple_tree.c went in through in
mm-stable-2024-03-13-20-04.
I cannot say that this isn't the maple tree in an infinite loop, but I
don't think it is given the information above. Considering the infinite
loop scenario would produce the same crash on reproduction but this is
not what syzbot sees on the git bisect, I think it is not an issue in
the tree but an issue somewhere else - and probably a corruption issue
that wasn't detected by kasan (is this possible?).
Thanks,
Liam
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [syzbot] [mm?] INFO: rcu detected stall in validate_mm (3)
2024-05-12 17:28 ` Liam R. Howlett
@ 2024-05-12 20:41 ` Liam R. Howlett
0 siblings, 0 replies; 7+ messages in thread
From: Liam R. Howlett @ 2024-05-12 20:41 UTC (permalink / raw)
To: syzbot, akpm, linux-kernel, linux-mm, lstoakes, syzkaller-bugs,
vbabka
* Liam R. Howlett <Liam.Howlett@oracle.com> [240512 13:28]:
> * syzbot <syzbot+a941018a091f1a1f9546@syzkaller.appspotmail.com> [240512 05:19]:
> > Hello,
> >
> > syzbot found the following issue on:
>
> First, excellent timing of this report - Sunday on an -rc7 release the
> day before LSF/MM/BPF.
>
> >
> > HEAD commit: dccb07f2914c Merge tag 'for-6.9-rc7-tag' of git://git.kern..
> > git tree: upstream
> > console output: https://syzkaller.appspot.com/x/log.txt?x=13f6734c980000
> > kernel config: https://syzkaller.appspot.com/x/.config?x=7144b4fe7fbf5900
> > dashboard link: https://syzkaller.appspot.com/bug?extid=a941018a091f1a1f9546
> > compiler: gcc (Debian 12.2.0-14) 12.2.0, GNU ld (GNU Binutils for Debian) 2.40
> > syz repro: https://syzkaller.appspot.com/x/repro.syz?x=10306760980000
> > C reproducer: https://syzkaller.appspot.com/x/repro.c?x=138c8970980000
> >
> > Downloadable assets:
> > disk image: https://storage.googleapis.com/syzbot-assets/e1fea5a49470/disk-dccb07f2.raw.xz
> > vmlinux: https://storage.googleapis.com/syzbot-assets/5f7d53577fef/vmlinux-dccb07f2.xz
> > kernel image: https://storage.googleapis.com/syzbot-assets/430b18473a18/bzImage-dccb07f2.xz
> >
> > IMPORTANT: if you fix the issue, please add the following tag to the commit:
> > Reported-by: syzbot+a941018a091f1a1f9546@syzkaller.appspotmail.com
> >
> > rcu: INFO: rcu_preempt detected stalls on CPUs/tasks:
> > rcu: Tasks blocked on level-0 rcu_node (CPUs 0-1): P17678/1:b..l
> > rcu: (detected by 1, t=10502 jiffies, g=36541, q=38 ncpus=2)
> > task:syz-executor952 state:R running task stack:28968 pid:17678 tgid:17678 ppid:5114 flags:0x00000002
...
>
> I cannot say that this isn't the maple tree in an infinite loop, but I
> don't think it is given the information above. Considering the infinite
> loop scenario would produce the same crash on reproduction but this is
> not what syzbot sees on the git bisect, I think it is not an issue in
> the tree but an issue somewhere else - and probably a corruption issue
> that wasn't detected by kasan (is this possible?).
I was able to recreate this with the provided config and reproducer (but
not my own config). My trace has no maple tree calls at all:
[ 866.380945][ C1] rcu: INFO: rcu_preempt detected stalls on CPUs/tasks:
[ 866.381464][ C1] rcu: (detected by 1, t=10502 jiffies, g=161409, q=149 ncpus=2)
[ 866.382152][ C1] rcu: All QSes seen, last rcu_preempt kthread activity 10500 (4295023801-4295013301), jiffies_till_next_fqs=1, root ->qsmask 0x0
[ 866.383324][ C1] rcu: rcu_preempt kthread starved for 10500 jiffies! g161409 f0x2 RCU_GP_WAIT_FQS(5) ->state=0x0 ->cpu=0
[ 866.384952][ C1] rcu: Unless rcu_preempt kthread gets sufficient CPU time, OOM is now expected behavior.
[ 866.385972][ C1] rcu: RCU grace-period kthread stack dump:
[ 866.386582][ C1] task:rcu_preempt state:R running task stack:27648 pid:16 tgid:16 ppid:2 flags:0x00004000
[ 866.387811][ C1] Call Trace:
[ 866.388164][ C1] <TASK>
[ 866.388475][ C1] __schedule+0xf06/0x5cb0
[ 866.388961][ C1] ? __pfx___lock_acquire+0x10/0x10
[ 866.389528][ C1] ? __pfx___schedule+0x10/0x10
[ 866.390065][ C1] ? schedule+0x298/0x350
[ 866.390541][ C1] ? __pfx_lock_release+0x10/0x10
[ 866.391090][ C1] ? __pfx___mod_timer+0x10/0x10
[ 866.391633][ C1] ? lock_acquire+0x1b1/0x560
[ 866.392133][ C1] ? lockdep_init_map_type+0x16d/0x7e0
[ 866.392709][ C1] schedule+0xe7/0x350
[ 866.393139][ C1] schedule_timeout+0x136/0x2a0
[ 866.393654][ C1] ? __pfx_schedule_timeout+0x10/0x10
[ 866.394142][ C1] ? __pfx_process_timeout+0x10/0x10
[ 866.394596][ C1] ? _raw_spin_unlock_irqrestore+0x3b/0x80
[ 866.395137][ C1] ? prepare_to_swait_event+0xf0/0x470
[ 866.395714][ C1] rcu_gp_fqs_loop+0x1ab/0xbd0
[ 866.396246][ C1] ? __pfx_rcu_gp_fqs_loop+0x10/0x10
[ 866.396852][ C1] ? rcu_gp_init+0xbdb/0x1480
[ 866.397393][ C1] ? __pfx_rcu_gp_cleanup+0x10/0x10
[ 866.397988][ C1] rcu_gp_kthread+0x271/0x380
[ 866.398493][ C1] ? __pfx_rcu_gp_kthread+0x10/0x10
[ 866.399063][ C1] ? lockdep_hardirqs_on+0x7c/0x110
[ 866.399570][ C1] ? __kthread_parkme+0x143/0x220
[ 866.400045][ C1] ? __pfx_rcu_gp_kthread+0x10/0x10
[ 866.400535][ C1] kthread+0x2c1/0x3a0
[ 866.400916][ C1] ? _raw_spin_unlock_irq+0x23/0x50
[ 866.401409][ C1] ? __pfx_kthread+0x10/0x10
[ 866.401854][ C1] ret_from_fork+0x45/0x80
[ 866.402284][ C1] ? __pfx_kthread+0x10/0x10
[ 866.402718][ C1] ret_from_fork_asm+0x1a/0x30
[ 866.403167][ C1] </TASK>
I'm going to see if I can hit the corrupted stack version with kasan enabled.
Thanks,
Liam
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [syzbot] Test
2024-05-12 9:19 [syzbot] [mm?] INFO: rcu detected stall in validate_mm (3) syzbot
2024-05-12 17:28 ` Liam R. Howlett
@ 2024-07-03 7:32 ` syzbot
2024-07-03 8:24 ` syzbot
2 siblings, 0 replies; 7+ messages in thread
From: syzbot @ 2024-07-03 7:32 UTC (permalink / raw)
To: linux-kernel, syzkaller-bugs
For archival purposes, forwarding an incoming command email to
linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com.
***
Subject: Test
Author: radoslaw.zielonek@gmail.com
#syz test https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git dccb07f2914cdab2ac3a5b6c98406f765acab803
---
include/linux/sched.h | 7 +++++++
kernel/sched/core.c | 1 +
kernel/sched/rt.c | 26 +++++++++++++++++++++++---
kernel/signal.c | 9 +++++++++
4 files changed, 40 insertions(+), 3 deletions(-)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 17cb0761ff65..123bc16ad3d0 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1121,6 +1121,13 @@ struct task_struct {
size_t sas_ss_size;
unsigned int sas_ss_flags;
+ /*
+ * Number of signals received by an RT task between scheduling ticks.
+ * This counter is used to throttle RT tasks when too many signals
+ * (e.g., POSIX timers) are sent to the task, which can cause an RCU stall.
+ */
+ atomic_t rt_signals_recv_count; /* used outside of the rq lock */
+
struct callback_head *task_works;
#ifdef CONFIG_AUDIT
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index d44efa0d0611..9def826bd35f 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -4779,6 +4779,7 @@ int sched_fork(unsigned long clone_flags, struct task_struct *p)
p->policy = SCHED_NORMAL;
p->static_prio = NICE_TO_PRIO(0);
p->rt_priority = 0;
+ atomic_set(&p->rt_signals_recv_count, 0);
} else if (PRIO_TO_NICE(p->static_prio) < 0)
p->static_prio = NICE_TO_PRIO(0);
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 3261b067b67e..9b22d67d1746 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -24,6 +24,15 @@ int sysctl_sched_rt_period = 1000000;
*/
int sysctl_sched_rt_runtime = 950000;
+/*
+ * To avoid an RCU stall due to a large number of signals received by RT tasks
+ * (e.g., POSIX timers), the RT task needs to be throttled.
+ * When the number of signals received by an RT task during a scheduling
+ * tick period exceeds the threshold, the RT task will be throttled.
+ * The value of 100 has not been thoroughly tested and may need adjustment.
+ */
+#define RT_RECV_SGINAL_THROTTLE_THRESHOLD 100
+
#ifdef CONFIG_SYSCTL
static int sysctl_sched_rr_timeslice = (MSEC_PER_SEC * RR_TIMESLICE) / HZ;
static int sched_rt_handler(struct ctl_table *table, int write, void *buffer,
@@ -951,7 +960,7 @@ static inline int rt_se_prio(struct sched_rt_entity *rt_se)
return rt_task_of(rt_se)->prio;
}
-static int sched_rt_runtime_exceeded(struct rt_rq *rt_rq)
+static int sched_rt_runtime_exceeded(struct rt_rq *rt_rq, int rt_signal_recv)
{
u64 runtime = sched_rt_runtime(rt_rq);
@@ -966,7 +975,15 @@ static int sched_rt_runtime_exceeded(struct rt_rq *rt_rq)
if (runtime == RUNTIME_INF)
return 0;
- if (rt_rq->rt_time > runtime) {
+ /*
+ * When a large number of signals are sent to this task (e.g., POSIX timers)
+ * the delta time deviates significantly from real time due to the overhead
+ * of handling signals. For RT tasks, this can cause an RCU stall.
+ * To avoid this, throttle the task when the number of signals received
+ * exceeds a certain threshold.
+ */
+ if (rt_rq->rt_time > runtime ||
+ rt_signal_recv >= RT_RECV_SGINAL_THROTTLE_THRESHOLD) {
struct rt_bandwidth *rt_b = sched_rt_bandwidth(rt_rq);
/*
@@ -1021,7 +1038,9 @@ static void update_curr_rt(struct rq *rq)
if (sched_rt_runtime(rt_rq) != RUNTIME_INF) {
raw_spin_lock(&rt_rq->rt_runtime_lock);
rt_rq->rt_time += delta_exec;
- exceeded = sched_rt_runtime_exceeded(rt_rq);
+ exceeded = sched_rt_runtime_exceeded(
+ rt_rq,
+ atomic_read(&curr->rt_signals_recv_count));
if (exceeded)
resched_curr(rq);
raw_spin_unlock(&rt_rq->rt_runtime_lock);
@@ -1029,6 +1048,7 @@ static void update_curr_rt(struct rq *rq)
do_start_rt_bandwidth(sched_rt_bandwidth(rt_rq));
}
}
+ atomic_set(&curr->rt_signals_recv_count, 0);
}
static void
diff --git a/kernel/signal.c b/kernel/signal.c
index bdca529f0f7b..d58e0ba9336c 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -629,6 +629,15 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask,
bool resched_timer = false;
int signr;
+ /*
+ * To prevent an RCU stall due to receiving too many signals by RT tasks,
+ * count all signals regardless of their type.
+ * Based on this counter, the RT scheduler will decide whether the task
+ * should be throttled or not.
+ */
+ if (tsk->policy == SCHED_FIFO || tsk->policy == SCHED_RR)
+ atomic_inc(&tsk->rt_signals_recv_count);
+
/* We only dequeue private signals from ourselves, we don't let
* signalfd steal them
*/
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [syzbot] Test
2024-05-12 9:19 [syzbot] [mm?] INFO: rcu detected stall in validate_mm (3) syzbot
2024-05-12 17:28 ` Liam R. Howlett
2024-07-03 7:32 ` [syzbot] Test syzbot
@ 2024-07-03 8:24 ` syzbot
2 siblings, 0 replies; 7+ messages in thread
From: syzbot @ 2024-07-03 8:24 UTC (permalink / raw)
To: linux-kernel, syzkaller-bugs
For archival purposes, forwarding an incoming command email to
linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com.
***
Subject: Test
Author: radoslaw.zielonek@gmail.com
#syz test
---
include/linux/sched.h | 7 +++++++
kernel/sched/core.c | 1 +
kernel/sched/rt.c | 26 +++++++++++++++++++++++---
kernel/signal.c | 9 +++++++++
4 files changed, 40 insertions(+), 3 deletions(-)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 17cb0761ff65..123bc16ad3d0 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1121,6 +1121,13 @@ struct task_struct {
size_t sas_ss_size;
unsigned int sas_ss_flags;
+ /*
+ * Number of signals received by an RT task between scheduling ticks.
+ * This counter is used to throttle RT tasks when too many signals
+ * (e.g., POSIX timers) are sent to the task, which can cause an RCU stall.
+ */
+ atomic_t rt_signals_recv_count; /* used outside of the rq lock */
+
struct callback_head *task_works;
#ifdef CONFIG_AUDIT
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index d44efa0d0611..9def826bd35f 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -4779,6 +4779,7 @@ int sched_fork(unsigned long clone_flags, struct task_struct *p)
p->policy = SCHED_NORMAL;
p->static_prio = NICE_TO_PRIO(0);
p->rt_priority = 0;
+ atomic_set(&p->rt_signals_recv_count, 0);
} else if (PRIO_TO_NICE(p->static_prio) < 0)
p->static_prio = NICE_TO_PRIO(0);
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 3261b067b67e..9b22d67d1746 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -24,6 +24,15 @@ int sysctl_sched_rt_period = 1000000;
*/
int sysctl_sched_rt_runtime = 950000;
+/*
+ * To avoid an RCU stall due to a large number of signals received by RT tasks
+ * (e.g., POSIX timers), the RT task needs to be throttled.
+ * When the number of signals received by an RT task during a scheduling
+ * tick period exceeds the threshold, the RT task will be throttled.
+ * The value of 100 has not been thoroughly tested and may need adjustment.
+ */
+#define RT_RECV_SGINAL_THROTTLE_THRESHOLD 100
+
#ifdef CONFIG_SYSCTL
static int sysctl_sched_rr_timeslice = (MSEC_PER_SEC * RR_TIMESLICE) / HZ;
static int sched_rt_handler(struct ctl_table *table, int write, void *buffer,
@@ -951,7 +960,7 @@ static inline int rt_se_prio(struct sched_rt_entity *rt_se)
return rt_task_of(rt_se)->prio;
}
-static int sched_rt_runtime_exceeded(struct rt_rq *rt_rq)
+static int sched_rt_runtime_exceeded(struct rt_rq *rt_rq, int rt_signal_recv)
{
u64 runtime = sched_rt_runtime(rt_rq);
@@ -966,7 +975,15 @@ static int sched_rt_runtime_exceeded(struct rt_rq *rt_rq)
if (runtime == RUNTIME_INF)
return 0;
- if (rt_rq->rt_time > runtime) {
+ /*
+ * When a large number of signals are sent to this task (e.g., POSIX timers)
+ * the delta time deviates significantly from real time due to the overhead
+ * of handling signals. For RT tasks, this can cause an RCU stall.
+ * To avoid this, throttle the task when the number of signals received
+ * exceeds a certain threshold.
+ */
+ if (rt_rq->rt_time > runtime ||
+ rt_signal_recv >= RT_RECV_SGINAL_THROTTLE_THRESHOLD) {
struct rt_bandwidth *rt_b = sched_rt_bandwidth(rt_rq);
/*
@@ -1021,7 +1038,9 @@ static void update_curr_rt(struct rq *rq)
if (sched_rt_runtime(rt_rq) != RUNTIME_INF) {
raw_spin_lock(&rt_rq->rt_runtime_lock);
rt_rq->rt_time += delta_exec;
- exceeded = sched_rt_runtime_exceeded(rt_rq);
+ exceeded = sched_rt_runtime_exceeded(
+ rt_rq,
+ atomic_read(&curr->rt_signals_recv_count));
if (exceeded)
resched_curr(rq);
raw_spin_unlock(&rt_rq->rt_runtime_lock);
@@ -1029,6 +1048,7 @@ static void update_curr_rt(struct rq *rq)
do_start_rt_bandwidth(sched_rt_bandwidth(rt_rq));
}
}
+ atomic_set(&curr->rt_signals_recv_count, 0);
}
static void
diff --git a/kernel/signal.c b/kernel/signal.c
index bdca529f0f7b..d58e0ba9336c 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -629,6 +629,15 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask,
bool resched_timer = false;
int signr;
+ /*
+ * To prevent an RCU stall due to receiving too many signals by RT tasks,
+ * count all signals regardless of their type.
+ * Based on this counter, the RT scheduler will decide whether the task
+ * should be throttled or not.
+ */
+ if (tsk->policy == SCHED_FIFO || tsk->policy == SCHED_RR)
+ atomic_inc(&tsk->rt_signals_recv_count);
+
/* We only dequeue private signals from ourselves, we don't let
* signalfd steal them
*/
--
2.43.0
^ permalink raw reply related [flat|nested] 7+ messages in thread