|
15 | 15 | #include <asm-generic/export.h> |
16 | 16 |
|
17 | 17 | #include <asm/asm-offsets.h> |
| 18 | +#include <asm/alternative.h> |
18 | 19 | #include <asm/cpufeature.h> |
19 | 20 | #include <asm/cputype.h> |
20 | 21 | #include <asm/debug-monitors.h> |
@@ -701,19 +702,32 @@ USER(\label, ic ivau, \tmp2) // invalidate I line PoU |
701 | 702 | .endm |
702 | 703 |
|
703 | 704 | /* |
704 | | - * Check whether preempt-disabled code should yield as soon as it |
705 | | - * is able. This is the case if re-enabling preemption a single |
706 | | - * time results in a preempt count of zero, and the TIF_NEED_RESCHED |
707 | | - * flag is set. (Note that the latter is stored negated in the |
708 | | - * top word of the thread_info::preempt_count field) |
| 705 | + * Check whether preempt/bh-disabled asm code should yield as soon as |
| 706 | + * it is able. This is the case if we are currently running in task |
| 707 | + * context, and either a softirq is pending, or the TIF_NEED_RESCHED |
| 708 | + * flag is set and re-enabling preemption a single time would result in |
| 709 | + * a preempt count of zero. (Note that the TIF_NEED_RESCHED flag is |
| 710 | + * stored negated in the top word of the thread_info::preempt_count |
| 711 | + * field) |
709 | 712 | */ |
710 | | - .macro cond_yield, lbl:req, tmp:req |
711 | | -#ifdef CONFIG_PREEMPTION |
| 713 | + .macro cond_yield, lbl:req, tmp:req, tmp2:req |
712 | 714 | get_current_task \tmp |
713 | 715 | ldr \tmp, [\tmp, #TSK_TI_PREEMPT] |
| 716 | + /* |
| 717 | + * If we are serving a softirq, there is no point in yielding: the |
| 718 | + * softirq will not be preempted no matter what we do, so we should |
| 719 | + * run to completion as quickly as we can. |
| 720 | + */ |
| 721 | + tbnz \tmp, #SOFTIRQ_SHIFT, .Lnoyield_\@ |
| 722 | +#ifdef CONFIG_PREEMPTION |
714 | 723 | sub \tmp, \tmp, #PREEMPT_DISABLE_OFFSET |
715 | 724 | cbz \tmp, \lbl |
716 | 725 | #endif |
| 726 | + adr_l \tmp, irq_stat + IRQ_CPUSTAT_SOFTIRQ_PENDING |
| 727 | + this_cpu_offset \tmp2 |
| 728 | + ldr w\tmp, [\tmp, \tmp2] |
| 729 | + cbnz w\tmp, \lbl // yield on pending softirq in task context |
| 730 | +.Lnoyield_\@: |
717 | 731 | .endm |
718 | 732 |
|
719 | 733 | /* |
|
0 commit comments