diff options
Diffstat (limited to 'kernel/rcu/tree.c')
| -rw-r--r-- | kernel/rcu/tree.c | 50 | 
1 files changed, 18 insertions, 32 deletions
| diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 5c8a5796c71f..46a8e06bf03e 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c | |||
| @@ -917,34 +917,6 @@ void rcu_irq_exit_irqson(void) | |||
| 917 | } | 917 | } | 
| 918 | 918 | ||
| 919 | /* | 919 | /* | 
| 920 | * rcu_eqs_exit_common - current CPU moving away from extended quiescent state | ||
| 921 | * | ||
| 922 | * If the new value of the ->dynticks_nesting counter was previously zero, | ||
| 923 | * we really have exited idle, and must do the appropriate accounting. | ||
| 924 | * The caller must have disabled interrupts. | ||
| 925 | */ | ||
| 926 | static void rcu_eqs_exit_common(long newval, int user) | ||
| 927 | { | ||
| 928 | RCU_TRACE(struct rcu_dynticks *rdtp = this_cpu_ptr(&rcu_dynticks);) | ||
| 929 | |||
| 930 | rcu_dynticks_task_exit(); | ||
| 931 | rcu_dynticks_eqs_exit(); | ||
| 932 | rcu_cleanup_after_idle(); | ||
| 933 | trace_rcu_dyntick(TPS("End"), rdtp->dynticks_nesting, newval, rdtp->dynticks); | ||
| 934 | if (IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && | ||
| 935 | !user && !is_idle_task(current)) { | ||
| 936 | struct task_struct *idle __maybe_unused = | ||
| 937 | idle_task(smp_processor_id()); | ||
| 938 | |||
| 939 | trace_rcu_dyntick(TPS("Error on exit: not idle task"), rdtp->dynticks_nesting, newval, rdtp->dynticks); | ||
| 940 | rcu_ftrace_dump(DUMP_ORIG); | ||
| 941 | WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s", | ||
| 942 | current->pid, current->comm, | ||
| 943 | idle->pid, idle->comm); /* must be idle task! */ | ||
| 944 | } | ||
| 945 | } | ||
| 946 | |||
| 947 | /* | ||
| 948 | * Exit an RCU extended quiescent state, which can be either the | 920 | * Exit an RCU extended quiescent state, which can be either the | 
| 949 | * idle loop or adaptive-tickless usermode execution. | 921 | * idle loop or adaptive-tickless usermode execution. | 
| 950 | * | 922 | * | 
| @@ -963,11 +935,25 @@ static void rcu_eqs_exit(bool user) | |||
| 963 | WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && oldval < 0); | 935 | WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && oldval < 0); | 
| 964 | if (oldval) { | 936 | if (oldval) { | 
| 965 | rdtp->dynticks_nesting++; | 937 | rdtp->dynticks_nesting++; | 
| 966 | } else { | 938 | return; | 
| 967 | rcu_eqs_exit_common(1, user); | 939 | } | 
| 968 | WRITE_ONCE(rdtp->dynticks_nesting, 1); | 940 | rcu_dynticks_task_exit(); | 
| 969 | WRITE_ONCE(rdtp->dynticks_nmi_nesting, DYNTICK_IRQ_NONIDLE); | 941 | rcu_dynticks_eqs_exit(); | 
| 942 | rcu_cleanup_after_idle(); | ||
| 943 | trace_rcu_dyntick(TPS("End"), rdtp->dynticks_nesting, 1, rdtp->dynticks); | ||
| 944 | if (IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && | ||
| 945 | !user && !is_idle_task(current)) { | ||
| 946 | struct task_struct *idle __maybe_unused = | ||
| 947 | idle_task(smp_processor_id()); | ||
| 948 | |||
| 949 | trace_rcu_dyntick(TPS("Error on exit: not idle task"), rdtp->dynticks_nesting, 1, rdtp->dynticks); | ||
| 950 | rcu_ftrace_dump(DUMP_ORIG); | ||
| 951 | WARN_ONCE(1, "Current pid: %d comm: %s / Idle pid: %d comm: %s", | ||
| 952 | current->pid, current->comm, | ||
| 953 | idle->pid, idle->comm); /* must be idle task! */ | ||
| 970 | } | 954 | } | 
| 955 | WRITE_ONCE(rdtp->dynticks_nesting, 1); | ||
| 956 | WRITE_ONCE(rdtp->dynticks_nmi_nesting, DYNTICK_IRQ_NONIDLE); | ||
| 971 | } | 957 | } | 
| 972 | 958 | ||
| 973 | /** | 959 | /** | 
