Files
laptops-kernel/include/linux/hardirq.h
T

143 lines
3.2 KiB
C
Raw Normal View History

/* SPDX-License-Identifier: GPL-2.0 */
2005-04-16 15:20:36 -07:00
#ifndef LINUX_HARDIRQ_H
#define LINUX_HARDIRQ_H
#include <linux/context_tracking_state.h>
#include <linux/preempt.h>
2006-07-03 00:24:50 -07:00
#include <linux/lockdep.h>
#include <linux/ftrace_irq.h>
2021-03-09 09:55:53 +01:00
#include <linux/sched.h>
#include <linux/vtime.h>
#include <asm/hardirq.h>
2005-04-16 15:20:36 -07:00
extern void synchronize_irq(unsigned int irq);
2015-02-05 14:06:23 +01:00
extern bool synchronize_hardirq(unsigned int irq);
2005-04-16 15:20:36 -07:00
#ifdef CONFIG_NO_HZ_FULL
void __rcu_irq_enter_check_tick(void);
2009-10-25 19:03:50 -07:00
#else
static inline void __rcu_irq_enter_check_tick(void) { }
2009-10-25 19:03:50 -07:00
#endif
static __always_inline void rcu_irq_enter_check_tick(void)
{
if (context_tracking_enabled())
__rcu_irq_enter_check_tick();
}
2006-07-03 00:24:42 -07:00
/*
* It is safe to do non-atomic ops on ->hardirq_context,
* because NMI handlers may not preempt and the ops are
* always balanced, so the interrupted value of ->hardirq_context
* will always be restored.
*/
#define __irq_enter() \
do { \
preempt_count_add(HARDIRQ_OFFSET); \
lockdep_hardirq_enter(); \
account_hardirq_enter(current); \
} while (0)
2020-05-21 22:05:22 +02:00
/*
* Like __irq_enter() without time accounting for fast
* interrupts, e.g. reschedule IPI where time accounting
* is more expensive than the actual interrupt.
*/
#define __irq_enter_raw() \
do { \
preempt_count_add(HARDIRQ_OFFSET); \
lockdep_hardirq_enter(); \
} while (0)
/*
* Enter irq context (on NO_HZ, update jiffies):
*/
2020-05-21 22:05:21 +02:00
void irq_enter(void);
/*
* Like irq_enter(), but RCU is already watching.
*/
void irq_enter_rcu(void);
2005-04-16 15:20:36 -07:00
2006-07-03 00:24:42 -07:00
/*
* Exit irq context without processing softirqs:
*/
#define __irq_exit() \
do { \
account_hardirq_exit(current); \
lockdep_hardirq_exit(); \
preempt_count_sub(HARDIRQ_OFFSET); \
2006-07-03 00:24:42 -07:00
} while (0)
2020-05-21 22:05:22 +02:00
/*
* Like __irq_exit() without time accounting
*/
#define __irq_exit_raw() \
do { \
lockdep_hardirq_exit(); \
preempt_count_sub(HARDIRQ_OFFSET); \
} while (0)
2006-07-03 00:24:42 -07:00
/*
* Exit irq context and process softirqs if needed:
*/
2020-05-21 22:05:21 +02:00
void irq_exit(void);
/*
* Like irq_exit(), but return with RCU watching.
*/
void irq_exit_rcu(void);
2005-04-16 15:20:36 -07:00
2019-01-31 14:58:39 +00:00
#ifndef arch_nmi_enter
#define arch_nmi_enter() do { } while (0)
#define arch_nmi_exit() do { } while (0)
#endif
/*
* NMI vs Tracing
* --------------
*
* We must not land in a tracer until (or after) we've changed preempt_count
* such that in_nmi() becomes true. To that effect all NMI C entry points must
* be marked 'notrace' and call nmi_enter() as soon as possible.
*/
2020-02-19 09:46:47 +01:00
/*
* nmi_enter() can nest up to 15 times; see NMI_BITS.
*/
2020-05-27 15:50:29 +02:00
#define __nmi_enter() \
2009-02-12 14:16:46 -05:00
do { \
2020-05-27 15:50:29 +02:00
lockdep_off(); \
2019-01-31 14:58:39 +00:00
arch_nmi_enter(); \
2020-02-19 09:46:47 +01:00
BUG_ON(in_nmi() == NMI_MASK); \
__preempt_count_add(NMI_OFFSET + HARDIRQ_OFFSET); \
2020-05-27 15:50:29 +02:00
} while (0)
#define nmi_enter() \
do { \
__nmi_enter(); \
lockdep_hardirq_enter(); \
ct_nmi_enter(); \
instrumentation_begin(); \
ftrace_nmi_enter(); \
instrumentation_end(); \
2008-10-30 16:08:32 -04:00
} while (0)
2020-05-27 15:50:29 +02:00
#define __nmi_exit() \
do { \
BUG_ON(!in_nmi()); \
__preempt_count_sub(NMI_OFFSET + HARDIRQ_OFFSET); \
arch_nmi_exit(); \
lockdep_on(); \
} while (0)
2009-02-12 14:16:46 -05:00
#define nmi_exit() \
do { \
instrumentation_begin(); \
ftrace_nmi_exit(); \
instrumentation_end(); \
ct_nmi_exit(); \
2020-05-27 15:50:29 +02:00
lockdep_hardirq_exit(); \
__nmi_exit(); \
2008-10-30 16:08:32 -04:00
} while (0)
2006-07-03 00:24:42 -07:00
2005-04-16 15:20:36 -07:00
#endif /* LINUX_HARDIRQ_H */