summaryrefslogtreecommitdiff
path: root/kernel/sched/rt.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched/rt.c')
-rw-r--r--kernel/sched/rt.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 338d019d0f25..4af75994f283 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -1459,16 +1459,20 @@ select_task_rq_rt_hmp(struct task_struct *p, int cpu, int sd_flag, int flags)
/*
* Return whether the task on the given cpu is currently non-preemptible
- * while handling a softirq or is likely to block preemptions soon because
- * it is a ksoftirq thread.
+ * while handling a potentially long softint, or if the task is likely
+ * to block preemptions soon because it is a ksoftirq thread that is
+ * handling slow softints.
*/
bool
task_may_not_preempt(struct task_struct *task, int cpu)
{
+ __u32 softirqs = per_cpu(active_softirqs, cpu) |
+ __IRQ_STAT(cpu, __softirq_pending);
struct task_struct *cpu_ksoftirqd = per_cpu(ksoftirqd, cpu);
- return (task_thread_info(task)->preempt_count & SOFTIRQ_MASK) ||
- task == cpu_ksoftirqd;
+ return ((softirqs & LONG_SOFTIRQ_MASK) &&
+ (task == cpu_ksoftirqd ||
+ task_thread_info(task)->preempt_count & SOFTIRQ_MASK));
}
static int