aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/rcupdate.h2
-rw-r--r--kernel/rcutree.c43
2 files changed, 45 insertions, 0 deletions
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
index d8b20bfd4795..f818dd165b44 100644
--- a/include/linux/rcupdate.h
+++ b/include/linux/rcupdate.h
@@ -193,6 +193,8 @@ extern void rcu_irq_enter(void);
193extern void rcu_irq_exit(void); 193extern void rcu_irq_exit(void);
194extern void rcu_user_enter(void); 194extern void rcu_user_enter(void);
195extern void rcu_user_exit(void); 195extern void rcu_user_exit(void);
196extern void rcu_user_enter_after_irq(void);
197extern void rcu_user_exit_after_irq(void);
196extern void exit_rcu(void); 198extern void exit_rcu(void);
197 199
198/** 200/**
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index af0dc3472a4b..4138f59fa2f4 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -426,6 +426,27 @@ void rcu_user_enter(void)
426 426
427 427
428/** 428/**
429 * rcu_user_enter_after_irq - inform RCU that we are going to resume userspace
430 * after the current irq returns.
431 *
432 * This is similar to rcu_user_enter() but in the context of a non-nesting
433 * irq. After this call, RCU enters into idle mode when the interrupt
434 * returns.
435 */
436void rcu_user_enter_after_irq(void)
437{
438 unsigned long flags;
439 struct rcu_dynticks *rdtp;
440
441 local_irq_save(flags);
442 rdtp = &__get_cpu_var(rcu_dynticks);
443 /* Ensure this irq is interrupting a non-idle RCU state. */
444 WARN_ON_ONCE(!(rdtp->dynticks_nesting & DYNTICK_TASK_MASK));
445 rdtp->dynticks_nesting = 1;
446 local_irq_restore(flags);
447}
448
449/**
429 * rcu_irq_exit - inform RCU that current CPU is exiting irq towards idle 450 * rcu_irq_exit - inform RCU that current CPU is exiting irq towards idle
430 * 451 *
431 * Exit from an interrupt handler, which might possibly result in entering 452 * Exit from an interrupt handler, which might possibly result in entering
@@ -550,6 +571,28 @@ void rcu_user_exit(void)
550} 571}
551 572
552/** 573/**
574 * rcu_user_exit_after_irq - inform RCU that we won't resume to userspace
575 * idle mode after the current non-nesting irq returns.
576 *
577 * This is similar to rcu_user_exit() but in the context of an irq.
578 * This is called when the irq has interrupted a userspace RCU idle mode
579 * context. When the current non-nesting interrupt returns after this call,
580 * the CPU won't restore the RCU idle mode.
581 */
582void rcu_user_exit_after_irq(void)
583{
584 unsigned long flags;
585 struct rcu_dynticks *rdtp;
586
587 local_irq_save(flags);
588 rdtp = &__get_cpu_var(rcu_dynticks);
589 /* Ensure we are interrupting an RCU idle mode. */
590 WARN_ON_ONCE(rdtp->dynticks_nesting & DYNTICK_TASK_NEST_MASK);
591 rdtp->dynticks_nesting += DYNTICK_TASK_EXIT_IDLE;
592 local_irq_restore(flags);
593}
594
595/**
553 * rcu_irq_enter - inform RCU that current CPU is entering irq away from idle 596 * rcu_irq_enter - inform RCU that current CPU is entering irq away from idle
554 * 597 *
555 * Enter an interrupt handler, which might possibly result in exiting 598 * Enter an interrupt handler, which might possibly result in exiting