linux/include/linux/irqflags.h

/* SPDX-License-Identifier: GPL-2.0 */
/*
 * include/linux/irqflags.h
 *
 * IRQ flags tracing: follow the state of the hardirq and softirq flags and
 * provide callbacks for transitions between ON and OFF states.
 *
 * This file gets included from lowlevel asm headers too, to provide
 * wrapped versions of the local_irq_*() APIs, based on the
 * raw_local_irq_*() macros from the lowlevel headers.
 */
#ifndef _LINUX_TRACE_IRQFLAGS_H
#define _LINUX_TRACE_IRQFLAGS_H

#include <linux/irqflags_types.h>
#include <linux/typecheck.h>
#include <linux/cleanup.h>
#include <asm/irqflags.h>
#include <asm/percpu.h>

/* Currently lockdep_softirqs_on/off is used only by lockdep */
#ifdef CONFIG_PROVE_LOCKING
  extern void lockdep_softirqs_on(unsigned long ip);
  extern void lockdep_softirqs_off(unsigned long ip);
  extern void lockdep_hardirqs_on_prepare(void);
  extern void lockdep_hardirqs_on(unsigned long ip);
  extern void lockdep_hardirqs_off(unsigned long ip);
#else
  static inline void lockdep_softirqs_on(unsigned long ip) { }
  static inline void lockdep_softirqs_off(unsigned long ip) { }
  static inline void lockdep_hardirqs_on_prepare(void) { }
  static inline void lockdep_hardirqs_on(unsigned long ip) { }
  static inline void lockdep_hardirqs_off(unsigned long ip) { }
#endif

#ifdef CONFIG_TRACE_IRQFLAGS

DECLARE_PER_CPU(int, hardirqs_enabled);
DECLARE_PER_CPU(int, hardirq_context);

extern void trace_hardirqs_on_prepare(void);
extern void trace_hardirqs_off_finish(void);
extern void trace_hardirqs_on(void);
extern void trace_hardirqs_off(void);

#define lockdep_hardirq_context()
#define lockdep_softirq_context(p)
#define lockdep_hardirqs_enabled()
#define lockdep_softirqs_enabled(p)
#define lockdep_hardirq_enter()
#define lockdep_hardirq_threaded()
#define lockdep_hardirq_exit()

#define lockdep_hrtimer_enter(__hrtimer)

#define lockdep_hrtimer_exit(__expires_hardirq)

#define lockdep_posixtimer_enter()

#define lockdep_posixtimer_exit()

#define lockdep_irq_work_enter(_flags)
#define lockdep_irq_work_exit(_flags)

#else
#define trace_hardirqs_on_prepare
#define trace_hardirqs_off_finish
#define trace_hardirqs_on
#define trace_hardirqs_off
#define lockdep_hardirq_context
#define lockdep_softirq_context
#define lockdep_hardirqs_enabled
#define lockdep_softirqs_enabled
#define lockdep_hardirq_enter
#define lockdep_hardirq_threaded
#define lockdep_hardirq_exit
#define lockdep_softirq_enter
#define lockdep_softirq_exit
#define lockdep_hrtimer_enter
#define lockdep_hrtimer_exit
#define lockdep_posixtimer_enter
#define lockdep_posixtimer_exit
#define lockdep_irq_work_enter
#define lockdep_irq_work_exit
#endif

#if defined(CONFIG_TRACE_IRQFLAGS) && !defined(CONFIG_PREEMPT_RT)
#define lockdep_softirq_enter()
#define lockdep_softirq_exit()

#else
#define lockdep_softirq_enter
#define lockdep_softirq_exit
#endif

#if defined(CONFIG_IRQSOFF_TRACER) || \
	defined(CONFIG_PREEMPT_TRACER)
 extern void stop_critical_timings(void);
 extern void start_critical_timings(void);
#else
#define stop_critical_timings
#define start_critical_timings
#endif

#ifdef CONFIG_DEBUG_IRQFLAGS
extern void warn_bogus_irq_restore(void);
#define raw_check_bogus_irq_restore()
#else
#define raw_check_bogus_irq_restore
#endif

/*
 * Wrap the arch provided IRQ routines to provide appropriate checks.
 */
#define raw_local_irq_disable()
#define raw_local_irq_enable()
#define raw_local_irq_save(flags)
#define raw_local_irq_restore(flags)
#define raw_local_save_flags(flags)
#define raw_irqs_disabled_flags(flags)
#define raw_irqs_disabled()
#define raw_safe_halt()

/*
 * The local_irq_*() APIs are equal to the raw_local_irq*()
 * if !TRACE_IRQFLAGS.
 */
#ifdef CONFIG_TRACE_IRQFLAGS

#define local_irq_enable()

#define local_irq_disable()

#define local_irq_save(flags)

#define local_irq_restore(flags)

#define safe_halt()


#else /* !CONFIG_TRACE_IRQFLAGS */

#define local_irq_enable
#define local_irq_disable
#define local_irq_save
#define local_irq_restore
#define safe_halt

#endif /* CONFIG_TRACE_IRQFLAGS */

#define local_save_flags(flags)

/*
 * Some architectures don't define arch_irqs_disabled(), so even if either
 * definition would be fine we need to use different ones for the time being
 * to avoid build issues.
 */
#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
#define irqs_disabled()
#else /* !CONFIG_TRACE_IRQFLAGS_SUPPORT */
#define irqs_disabled
#endif /* CONFIG_TRACE_IRQFLAGS_SUPPORT */

#define irqs_disabled_flags(flags)

DEFINE_LOCK_GUARD_0(irq, local_irq_disable(), local_irq_enable())
DEFINE_LOCK_GUARD_0(irqsave,
		    local_irq_save(_T->flags),
		    local_irq_restore(_T->flags),
		    } 

#endif