diff options
| author | Linux Build Service Account <lnxbuild@quicinc.com> | 2017-08-25 15:30:51 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-08-25 15:30:51 -0700 |
| commit | ccfef7e7014e9d3b62ff718030f54f6886f2f39e (patch) | |
| tree | 5b8ddabb4132f460cdb12d9ea29778f1b6cf8028 /kernel | |
| parent | cac55e7f09a17f7c6344b587302ffddf0d586c7e (diff) | |
| parent | a66b3eb5aff1536bc32e5e5eb60393610a21dd06 (diff) | |
Merge "softirq: defer softirq processing to ksoftirqd if CPU is busy with RT"
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/sched/cpupri.c | 11 | ||||
| -rw-r--r-- | kernel/softirq.c | 5 |
2 files changed, 15 insertions, 1 deletions
diff --git a/kernel/sched/cpupri.c b/kernel/sched/cpupri.c index 1d00cf8c00fa..14225d5d8617 100644 --- a/kernel/sched/cpupri.c +++ b/kernel/sched/cpupri.c @@ -279,3 +279,14 @@ void cpupri_cleanup(struct cpupri *cp) for (i = 0; i < CPUPRI_NR_PRIORITIES; i++) free_cpumask_var(cp->pri_to_cpu[i].mask); } + +/* + * cpupri_check_rt - check if CPU has a RT task + * should be called from rcu-sched read section. + */ +bool cpupri_check_rt(void) +{ + int cpu = raw_smp_processor_id(); + + return cpu_rq(cpu)->rd->cpupri.cpu_to_pri[cpu] > CPUPRI_NORMAL; +} diff --git a/kernel/softirq.c b/kernel/softirq.c index 39ffd41594ce..9029227e5f57 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -234,6 +234,8 @@ static inline bool lockdep_softirq_start(void) { return false; } static inline void lockdep_softirq_end(bool in_hardirq) { } #endif +#define long_softirq_pending() (local_softirq_pending() & LONG_SOFTIRQ_MASK) +#define defer_for_rt() (long_softirq_pending() && cpupri_check_rt()) asmlinkage __visible void __do_softirq(void) { unsigned long end = jiffies + MAX_SOFTIRQ_TIME; @@ -297,6 +299,7 @@ restart: pending = local_softirq_pending(); if (pending) { if (time_before(jiffies, end) && !need_resched() && + !defer_for_rt() && --max_restart) goto restart; @@ -349,7 +352,7 @@ void irq_enter(void) static inline void invoke_softirq(void) { - if (!force_irqthreads) { + if (!force_irqthreads && !defer_for_rt()) { #ifdef CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK /* * We can safely execute softirq on the current stack if |
