mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-12 13:55:32 +00:00
![Frederic Weisbecker](/assets/img/avatar_default.png)
The RCU dynticks counter is going to be merged into the context tracking subsystem. Start with moving the idle extended quiescent states entrypoints to context tracking. For now those are dumb redirections to existing RCU calls. [ paulmck: Apply kernel test robot feedback. ] Signed-off-by: Frederic Weisbecker <frederic@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Neeraj Upadhyay <quic_neeraju@quicinc.com> Cc: Uladzislau Rezki <uladzislau.rezki@sony.com> Cc: Joel Fernandes <joel@joelfernandes.org> Cc: Boqun Feng <boqun.feng@gmail.com> Cc: Nicolas Saenz Julienne <nsaenz@kernel.org> Cc: Marcelo Tosatti <mtosatti@redhat.com> Cc: Xiongfeng Wang <wangxiongfeng2@huawei.com> Cc: Yu Liao <liaoyu15@huawei.com> Cc: Phil Auld <pauld@redhat.com> Cc: Paul Gortmaker<paul.gortmaker@windriver.com> Cc: Alex Belits <abelits@marvell.com> Signed-off-by: Paul E. McKenney <paulmck@kernel.org> Reviewed-by: Nicolas Saenz Julienne <nsaenzju@redhat.com> Tested-by: Nicolas Saenz Julienne <nsaenzju@redhat.com>
130 lines
3.4 KiB
C
130 lines
3.4 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _LINUX_CONTEXT_TRACKING_H
|
|
#define _LINUX_CONTEXT_TRACKING_H
|
|
|
|
#include <linux/sched.h>
|
|
#include <linux/vtime.h>
|
|
#include <linux/context_tracking_state.h>
|
|
#include <linux/instrumentation.h>
|
|
|
|
#include <asm/ptrace.h>
|
|
|
|
|
|
#ifdef CONFIG_CONTEXT_TRACKING_USER
|
|
extern void ct_cpu_track_user(int cpu);
|
|
|
|
/* Called with interrupts disabled. */
|
|
extern void __ct_user_enter(enum ctx_state state);
|
|
extern void __ct_user_exit(enum ctx_state state);
|
|
|
|
extern void ct_user_enter(enum ctx_state state);
|
|
extern void ct_user_exit(enum ctx_state state);
|
|
|
|
extern void user_enter_callable(void);
|
|
extern void user_exit_callable(void);
|
|
|
|
static inline void user_enter(void)
|
|
{
|
|
if (context_tracking_enabled())
|
|
ct_user_enter(CONTEXT_USER);
|
|
|
|
}
|
|
static inline void user_exit(void)
|
|
{
|
|
if (context_tracking_enabled())
|
|
ct_user_exit(CONTEXT_USER);
|
|
}
|
|
|
|
/* Called with interrupts disabled. */
|
|
static __always_inline void user_enter_irqoff(void)
|
|
{
|
|
if (context_tracking_enabled())
|
|
__ct_user_enter(CONTEXT_USER);
|
|
|
|
}
|
|
static __always_inline void user_exit_irqoff(void)
|
|
{
|
|
if (context_tracking_enabled())
|
|
__ct_user_exit(CONTEXT_USER);
|
|
}
|
|
|
|
static inline enum ctx_state exception_enter(void)
|
|
{
|
|
enum ctx_state prev_ctx;
|
|
|
|
if (IS_ENABLED(CONFIG_HAVE_CONTEXT_TRACKING_USER_OFFSTACK) ||
|
|
!context_tracking_enabled())
|
|
return 0;
|
|
|
|
prev_ctx = this_cpu_read(context_tracking.state);
|
|
if (prev_ctx != CONTEXT_KERNEL)
|
|
ct_user_exit(prev_ctx);
|
|
|
|
return prev_ctx;
|
|
}
|
|
|
|
static inline void exception_exit(enum ctx_state prev_ctx)
|
|
{
|
|
if (!IS_ENABLED(CONFIG_HAVE_CONTEXT_TRACKING_USER_OFFSTACK) &&
|
|
context_tracking_enabled()) {
|
|
if (prev_ctx != CONTEXT_KERNEL)
|
|
ct_user_enter(prev_ctx);
|
|
}
|
|
}
|
|
|
|
static __always_inline bool context_tracking_guest_enter(void)
|
|
{
|
|
if (context_tracking_enabled())
|
|
__ct_user_enter(CONTEXT_GUEST);
|
|
|
|
return context_tracking_enabled_this_cpu();
|
|
}
|
|
|
|
static __always_inline void context_tracking_guest_exit(void)
|
|
{
|
|
if (context_tracking_enabled())
|
|
__ct_user_exit(CONTEXT_GUEST);
|
|
}
|
|
|
|
/**
|
|
* ct_state() - return the current context tracking state if known
|
|
*
|
|
* Returns the current cpu's context tracking state if context tracking
|
|
* is enabled. If context tracking is disabled, returns
|
|
* CONTEXT_DISABLED. This should be used primarily for debugging.
|
|
*/
|
|
static __always_inline enum ctx_state ct_state(void)
|
|
{
|
|
return context_tracking_enabled() ?
|
|
this_cpu_read(context_tracking.state) : CONTEXT_DISABLED;
|
|
}
|
|
#else
|
|
static inline void user_enter(void) { }
|
|
static inline void user_exit(void) { }
|
|
static inline void user_enter_irqoff(void) { }
|
|
static inline void user_exit_irqoff(void) { }
|
|
static inline enum ctx_state exception_enter(void) { return 0; }
|
|
static inline void exception_exit(enum ctx_state prev_ctx) { }
|
|
static inline enum ctx_state ct_state(void) { return CONTEXT_DISABLED; }
|
|
static __always_inline bool context_tracking_guest_enter(void) { return false; }
|
|
static inline void context_tracking_guest_exit(void) { }
|
|
|
|
#endif /* !CONFIG_CONTEXT_TRACKING_USER */
|
|
|
|
#define CT_WARN_ON(cond) WARN_ON(context_tracking_enabled() && (cond))
|
|
|
|
#ifdef CONFIG_CONTEXT_TRACKING_USER_FORCE
|
|
extern void context_tracking_init(void);
|
|
#else
|
|
static inline void context_tracking_init(void) { }
|
|
#endif /* CONFIG_CONTEXT_TRACKING_USER_FORCE */
|
|
|
|
#ifdef CONFIG_CONTEXT_TRACKING_IDLE
|
|
extern void ct_idle_enter(void);
|
|
extern void ct_idle_exit(void);
|
|
#else
|
|
static inline void ct_idle_enter(void) { }
|
|
static inline void ct_idle_exit(void) { }
|
|
#endif /* !CONFIG_CONTEXT_TRACKING_IDLE */
|
|
|
|
#endif
|