Commit 0b0986c3 authored by Philippe Gerum's avatar Philippe Gerum

ipipe: add generic pipeline core

parent 51a2a68f
/* -*- linux-c -*-
* include/asm-generic/ipipe.h
*
* Copyright (C) 2002-2017 Philippe Gerum.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
* USA; either version 2 of the License, or (at your option) any later
* version.
*/
#ifndef __ASM_GENERIC_IPIPE_H
#define __ASM_GENERIC_IPIPE_H
#ifdef CONFIG_IPIPE
#if defined(CONFIG_DEBUG_ATOMIC_SLEEP) || defined(CONFIG_PROVE_LOCKING) || \
defined(CONFIG_PREEMPT_VOLUNTARY) || defined(CONFIG_IPIPE_DEBUG_CONTEXT)
void __ipipe_uaccess_might_fault(void);
#else
#define __ipipe_uaccess_might_fault() might_fault()
#endif
#define hard_cond_local_irq_enable() hard_local_irq_enable()
#define hard_cond_local_irq_disable() hard_local_irq_disable()
#define hard_cond_local_irq_save() hard_local_irq_save()
#define hard_cond_local_irq_restore(flags) hard_local_irq_restore(flags)
#ifdef CONFIG_IPIPE_DEBUG_CONTEXT
void ipipe_root_only(void);
#else /* !CONFIG_IPIPE_DEBUG_CONTEXT */
static inline void ipipe_root_only(void) { }
#endif /* !CONFIG_IPIPE_DEBUG_CONTEXT */
void ipipe_stall_root(void);
void ipipe_unstall_root(void);
unsigned long ipipe_test_and_stall_root(void);
unsigned long ipipe_test_root(void);
void ipipe_restore_root(unsigned long x);
#else /* !CONFIG_IPIPE */
#define hard_local_irq_save() arch_local_irq_save()
#define hard_local_irq_restore(x) arch_local_irq_restore(x)
#define hard_local_irq_enable() arch_local_irq_enable()
#define hard_local_irq_disable() arch_local_irq_disable()
#define hard_irqs_disabled() irqs_disabled()
#define hard_cond_local_irq_enable() do { } while(0)
#define hard_cond_local_irq_disable() do { } while(0)
#define hard_cond_local_irq_save() 0
#define hard_cond_local_irq_restore(flags) do { (void)(flags); } while(0)
#define __ipipe_uaccess_might_fault() might_fault()
static inline void ipipe_root_only(void) { }
#endif /* !CONFIG_IPIPE */
#if defined(CONFIG_SMP) && defined(CONFIG_IPIPE)
#define hard_smp_local_irq_save() hard_local_irq_save()
#define hard_smp_local_irq_restore(flags) hard_local_irq_restore(flags)
#else /* !CONFIG_SMP */
#define hard_smp_local_irq_save() 0
#define hard_smp_local_irq_restore(flags) do { (void)(flags); } while(0)
#endif /* CONFIG_SMP */
#endif
......@@ -44,11 +44,33 @@ extern unsigned long __per_cpu_offset[NR_CPUS];
#define arch_raw_cpu_ptr(ptr) SHIFT_PERCPU_PTR(ptr, __my_cpu_offset)
#endif
#ifdef CONFIG_IPIPE
#if defined(CONFIG_IPIPE_DEBUG_INTERNAL) && defined(CONFIG_SMP)
extern int __ipipe_check_percpu_access(void);
#define __ipipe_cpu_offset \
({ \
WARN_ON_ONCE(__ipipe_check_percpu_access()); \
__my_cpu_offset; \
})
#else
#define __ipipe_cpu_offset __my_cpu_offset
#endif
#ifndef __ipipe_raw_cpu_ptr
#define __ipipe_raw_cpu_ptr(ptr) SHIFT_PERCPU_PTR(ptr, __ipipe_cpu_offset)
#endif
#define __ipipe_raw_cpu_read(var) (*__ipipe_raw_cpu_ptr(&(var)))
#endif /* CONFIG_IPIPE */
#ifdef CONFIG_HAVE_SETUP_PER_CPU_AREA
extern void setup_per_cpu_areas(void);
#endif
#endif /* SMP */
#else /* !SMP */
#define __ipipe_raw_cpu_ptr(ptr) VERIFY_PERCPU_PTR(ptr)
#define __ipipe_raw_cpu_read(var) (*__ipipe_raw_cpu_ptr(&(var)))
#endif /* !SMP */
#ifndef PER_CPU_BASE_SECTION
#ifdef CONFIG_SMP
......@@ -148,9 +170,9 @@ do { \
#define this_cpu_generic_to_op(pcp, val, op) \
do { \
unsigned long __flags; \
raw_local_irq_save(__flags); \
__flags = hard_local_irq_save(); \
raw_cpu_generic_to_op(pcp, val, op); \
raw_local_irq_restore(__flags); \
hard_local_irq_restore(__flags); \
} while (0)
......@@ -158,9 +180,9 @@ do { \
({ \
typeof(pcp) __ret; \
unsigned long __flags; \
raw_local_irq_save(__flags); \
__flags = hard_local_irq_save(); \
__ret = raw_cpu_generic_add_return(pcp, val); \
raw_local_irq_restore(__flags); \
hard_local_irq_restore(__flags); \
__ret; \
})
......@@ -168,9 +190,9 @@ do { \
({ \
typeof(pcp) __ret; \
unsigned long __flags; \
raw_local_irq_save(__flags); \
__flags = hard_local_irq_save(); \
__ret = raw_cpu_generic_xchg(pcp, nval); \
raw_local_irq_restore(__flags); \
hard_local_irq_restore(__flags); \
__ret; \
})
......@@ -178,9 +200,9 @@ do { \
({ \
typeof(pcp) __ret; \
unsigned long __flags; \
raw_local_irq_save(__flags); \
__flags = hard_local_irq_save(); \
__ret = raw_cpu_generic_cmpxchg(pcp, oval, nval); \
raw_local_irq_restore(__flags); \
hard_local_irq_restore(__flags); \
__ret; \
})
......@@ -188,10 +210,10 @@ do { \
({ \
int __ret; \
unsigned long __flags; \
raw_local_irq_save(__flags); \
__flags = hard_local_irq_save(); \
__ret = raw_cpu_generic_cmpxchg_double(pcp1, pcp2, \
oval1, oval2, nval1, nval2); \
raw_local_irq_restore(__flags); \
hard_local_irq_restore(__flags); \
__ret; \
})
......
#ifndef _IPIPE_SETUP_H
#define _IPIPE_SETUP_H
/*
* Placeholders for setup hooks defined by client domains.
*/
static inline void __ipipe_early_client_setup(void) { }
#endif /* !_IPIPE_SETUP_H */
#ifndef _IPIPE_THREAD_INFO_H
#define _IPIPE_THREAD_INFO_H
/*
* Placeholder for private thread information defined by client
* domains.
*/
struct ipipe_threadinfo {
};
#define __ipipe_init_threadinfo(__p) do { } while (0)
#endif /* !_IPIPE_THREAD_INFO_H */
This diff is collapsed.
/* -*- linux-c -*-
* include/linux/ipipe_base.h
*
* Copyright (C) 2002-2014 Philippe Gerum.
* 2007 Jan Kiszka.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
* USA; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __LINUX_IPIPE_BASE_H
#define __LINUX_IPIPE_BASE_H
struct kvm_vcpu;
struct ipipe_vm_notifier;
struct irq_desc;
#ifdef CONFIG_IPIPE
#define IPIPE_CORE_APIREV CONFIG_IPIPE_CORE_APIREV
#include <linux/ipipe_domain.h>
#include <linux/compiler.h>
#include <linux/linkage.h>
#include <asm/ipipe_base.h>
struct pt_regs;
struct ipipe_domain;
struct ipipe_trap_data {
int exception;
struct pt_regs *regs;
};
struct ipipe_vm_notifier {
void (*handler)(struct ipipe_vm_notifier *nfy);
};
static inline int ipipe_virtual_irq_p(unsigned int irq)
{
return irq >= IPIPE_VIRQ_BASE && irq < IPIPE_NR_IRQS;
}
void __ipipe_init_early(void);
void __ipipe_init(void);
#ifdef CONFIG_PROC_FS
void __ipipe_init_proc(void);
#ifdef CONFIG_IPIPE_TRACE
void __ipipe_init_tracer(void);
#else /* !CONFIG_IPIPE_TRACE */
static inline void __ipipe_init_tracer(void) { }
#endif /* CONFIG_IPIPE_TRACE */
#else /* !CONFIG_PROC_FS */
static inline void __ipipe_init_proc(void) { }
#endif /* CONFIG_PROC_FS */
void __ipipe_restore_root_nosync(unsigned long x);
#define IPIPE_IRQF_NOACK 0x1
#define IPIPE_IRQF_NOSYNC 0x2
void __ipipe_dispatch_irq(unsigned int irq, int flags);
void __ipipe_do_sync_stage(void);
void __ipipe_do_sync_pipeline(struct ipipe_domain *top);
void __ipipe_lock_irq(unsigned int irq);
void __ipipe_unlock_irq(unsigned int irq);
void __ipipe_do_critical_sync(unsigned int irq, void *cookie);
void __ipipe_ack_edge_irq(struct irq_desc *desc);
void __ipipe_nop_irq(struct irq_desc *desc);
static inline void __ipipe_idle(void)
{
ipipe_unstall_root();
}
#ifndef __ipipe_sync_check
#define __ipipe_sync_check 1
#endif
static inline void __ipipe_sync_stage(void)
{
if (likely(__ipipe_sync_check))
__ipipe_do_sync_stage();
}
#ifndef __ipipe_run_irqtail
#define __ipipe_run_irqtail(irq) do { } while(0)
#endif
int __ipipe_log_printk(const char *fmt, va_list args);
void __ipipe_flush_printk(unsigned int irq, void *cookie);
#define __ipipe_get_cpu(flags) ({ (flags) = hard_preempt_disable(); ipipe_processor_id(); })
#define __ipipe_put_cpu(flags) hard_preempt_enable(flags)
int __ipipe_notify_syscall(struct pt_regs *regs);
int __ipipe_notify_trap(int exception, struct pt_regs *regs);
int __ipipe_notify_kevent(int event, void *data);
#define __ipipe_report_trap(exception, regs) \
__ipipe_notify_trap(exception, regs)
#define __ipipe_report_sigwake(p) \
do { \
if (ipipe_notifier_enabled_p(p)) \
__ipipe_notify_kevent(IPIPE_KEVT_SIGWAKE, p); \
} while (0)
struct ipipe_cpu_migration_data {
struct task_struct *task;
int dest_cpu;
};
#define __ipipe_report_setaffinity(__p, __dest_cpu) \
do { \
struct ipipe_cpu_migration_data d = { \
.task = (__p), \
.dest_cpu = (__dest_cpu), \
}; \
if (ipipe_notifier_enabled_p(__p)) \
__ipipe_notify_kevent(IPIPE_KEVT_SETAFFINITY, &d); \
} while (0)
#define __ipipe_report_exit(p) \
do { \
if (ipipe_notifier_enabled_p(p)) \
__ipipe_notify_kevent(IPIPE_KEVT_EXIT, p); \
} while (0)
#define __ipipe_report_setsched(p) \
do { \
if (ipipe_notifier_enabled_p(p)) \
__ipipe_notify_kevent(IPIPE_KEVT_SETSCHED, p); \
} while (0)
#define __ipipe_report_schedule(prev, next) \
do { \
if (ipipe_notifier_enabled_p(next) || \
ipipe_notifier_enabled_p(prev)) { \
__this_cpu_write(ipipe_percpu.rqlock_owner, prev); \
__ipipe_notify_kevent(IPIPE_KEVT_SCHEDULE, next); \
} \
} while (0)
#define __ipipe_report_cleanup(mm) \
__ipipe_notify_kevent(IPIPE_KEVT_CLEANUP, mm)
#define __ipipe_report_clockfreq_update(freq) \
__ipipe_notify_kevent(IPIPE_KEVT_CLOCKFREQ, &(freq))
void __ipipe_notify_vm_preemption(void);
void __ipipe_call_mayday(struct pt_regs *regs);
static inline void __ipipe_init_taskinfo(struct task_struct *p) { }
#define __ipipe_serial_debug(__fmt, __args...) raw_printk(__fmt, ##__args)
#else /* !CONFIG_IPIPE */
struct task_struct;
struct mm_struct;
static inline void __ipipe_init_early(void) { }
static inline void __ipipe_init(void) { }
static inline void __ipipe_init_proc(void) { }
static inline void __ipipe_idle(void) { }
static inline void __ipipe_report_sigwake(struct task_struct *p) { }
static inline void __ipipe_report_setaffinity(struct task_struct *p,
int dest_cpu) { }
static inline void __ipipe_report_setsched(struct task_struct *p) { }
static inline void __ipipe_report_exit(struct task_struct *p) { }
static inline void __ipipe_report_cleanup(struct mm_struct *mm) { }
#define __ipipe_report_trap(exception, regs) 0
static inline void __ipipe_init_taskinfo(struct task_struct *p) { }
#define hard_preempt_disable() ({ preempt_disable(); 0; })
#define hard_preempt_enable(flags) ({ preempt_enable(); (void)(flags); })
#define __ipipe_get_cpu(flags) ({ (void)(flags); get_cpu(); })
#define __ipipe_put_cpu(flags) \
do { \
(void)(flags); \
put_cpu(); \
} while (0)
#define __ipipe_root_tick_p(regs) 1
#define ipipe_handle_demuxed_irq(irq) generic_handle_irq(irq)
#define __ipipe_enter_vm(vmf) do { } while (0)
static inline void __ipipe_exit_vm(void) { }
static inline void __ipipe_notify_vm_preemption(void) { }
#define __ipipe_serial_debug(__fmt, __args...) do { } while (0)
#endif /* !CONFIG_IPIPE */
#ifdef CONFIG_IPIPE_WANT_PTE_PINNING
void __ipipe_pin_mapping_globally(unsigned long start,
unsigned long end);
#else
static inline void __ipipe_pin_mapping_globally(unsigned long start,
unsigned long end)
{ }
#endif
#endif /* !__LINUX_IPIPE_BASE_H */
/* -*- linux-c -*-
* include/linux/ipipe_debug.h
*
* Copyright (C) 2012 Philippe Gerum <rpm@xenomai.org>.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
* USA; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __LINUX_IPIPE_DEBUG_H
#define __LINUX_IPIPE_DEBUG_H
#include <linux/ipipe_domain.h>
#ifdef CONFIG_IPIPE_DEBUG_CONTEXT
#include <asm/bug.h>
static inline int ipipe_disable_context_check(void)
{
return xchg(raw_cpu_ptr(&ipipe_percpu.context_check), 0);
}
static inline void ipipe_restore_context_check(int old_state)
{
__this_cpu_write(ipipe_percpu.context_check, old_state);
}
static inline void ipipe_context_check_off(void)
{
int cpu;
for_each_online_cpu(cpu)
per_cpu(ipipe_percpu, cpu).context_check = 0;
}
static inline void ipipe_save_context_nmi(void)
{
int state = ipipe_disable_context_check();
__this_cpu_write(ipipe_percpu.context_check_saved, state);
}
static inline void ipipe_restore_context_nmi(void)
{
ipipe_restore_context_check(__this_cpu_read(ipipe_percpu.context_check_saved));
}
#else /* !CONFIG_IPIPE_DEBUG_CONTEXT */
static inline int ipipe_disable_context_check(void)
{
return 0;
}
static inline void ipipe_restore_context_check(int old_state) { }
static inline void ipipe_context_check_off(void) { }
static inline void ipipe_save_context_nmi(void) { }
static inline void ipipe_restore_context_nmi(void) { }
#endif /* !CONFIG_IPIPE_DEBUG_CONTEXT */
#ifdef CONFIG_IPIPE_DEBUG
#define ipipe_check_irqoff() \
do { \
if (WARN_ON_ONCE(!hard_irqs_disabled())) \
hard_local_irq_disable(); \
} while (0)
#else /* !CONFIG_IPIPE_DEBUG */
static inline void ipipe_check_irqoff(void) { }
#endif /* !CONFIG_IPIPE_DEBUG */
#ifdef CONFIG_IPIPE_DEBUG_INTERNAL
#define IPIPE_WARN(c) WARN_ON(c)
#define IPIPE_WARN_ONCE(c) WARN_ON_ONCE(c)
#define IPIPE_BUG_ON(c) BUG_ON(c)
#else
#define IPIPE_WARN(c) do { (void)(c); } while (0)
#define IPIPE_WARN_ONCE(c) do { (void)(c); } while (0)
#define IPIPE_BUG_ON(c) do { (void)(c); } while (0)
#endif
#endif /* !__LINUX_IPIPE_DEBUG_H */
This diff is collapsed.
This diff is collapsed.
/* -*- linux-c -*-
* include/linux/ipipe_tickdev.h
*
* Copyright (C) 2007 Philippe Gerum.
* Copyright (C) 2012 Gilles Chanteperdrix
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
* USA; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __LINUX_IPIPE_TICKDEV_H
#define __LINUX_IPIPE_TICKDEV_H
#include <linux/list.h>
#include <linux/cpumask.h>
#include <linux/clockchips.h>
#include <linux/ipipe_domain.h>
#include <linux/clocksource.h>
#include <linux/timekeeper_internal.h>
#ifdef CONFIG_IPIPE
struct clock_event_device;
struct ipipe_hostrt_data {
short live;
seqcount_t seqcount;
time_t wall_time_sec;
u32 wall_time_nsec;
struct timespec wall_to_monotonic;
u64 cycle_last;
u64 mask;
u32 mult;
u32 shift;
};
enum clock_event_mode {
CLOCK_EVT_MODE_PERIODIC,
CLOCK_EVT_MODE_ONESHOT,
CLOCK_EVT_MODE_UNUSED,
CLOCK_EVT_MODE_SHUTDOWN,
};
struct ipipe_timer {
int irq;
void (*request)(struct ipipe_timer *timer, int steal);
int (*set)(unsigned long ticks, void *timer);
void (*ack)(void);
void (*release)(struct ipipe_timer *timer);
/* Only if registering a timer directly */
const char *name;
unsigned rating;
unsigned long freq;
unsigned min_delay_ticks;
const struct cpumask *cpumask;
/* For internal use */
void *timer_set; /* pointer passed to ->set() callback */
struct clock_event_device *host_timer;
struct list_head link;
/* Conversions between clock frequency and timer frequency */
unsigned c2t_integ;
unsigned c2t_frac;
/* For clockevent interception */
u32 real_mult;
u32 real_shift;
void (*mode_handler)(enum clock_event_mode mode,
struct clock_event_device *);
int orig_mode;
int (*orig_set_state_periodic)(struct clock_event_device *);
int (*orig_set_state_oneshot)(struct clock_event_device *);
int (*orig_set_state_oneshot_stopped)(struct clock_event_device *);
int (*orig_set_state_shutdown)(struct clock_event_device *);
int (*orig_set_next_event)(unsigned long evt,
struct clock_event_device *cdev);
unsigned int (*refresh_freq)(void);
};
#define __ipipe_hrtimer_irq __ipipe_raw_cpu_read(ipipe_percpu.hrtimer_irq)
extern unsigned long __ipipe_hrtimer_freq;
/*
* Called by clockevents_register_device, to register a piggybacked
* ipipe timer, if there is one
*/
void ipipe_host_timer_register(struct clock_event_device *clkevt);
/*
* Register a standalone ipipe timer
*/
void ipipe_timer_register(struct ipipe_timer *timer);
/*
* Chooses the best timer for each cpu. Take over its handling.
*/
int ipipe_select_timers(const struct cpumask *mask);
/*
* Release the per-cpu timers
*/
void ipipe_timers_release(void);
/*
* Start handling the per-cpu timer irq, and intercepting the linux clockevent
* device callbacks.
*/
int ipipe_timer_start(void (*tick_handler)(void),
void (*emumode)(enum clock_event_mode mode,
struct clock_event_device *cdev),
int (*emutick)(unsigned long evt,
struct clock_event_device *cdev),
unsigned cpu);
/*
* Stop handling a per-cpu timer
*/
void ipipe_timer_stop(unsigned cpu);
/*
* Program the timer
*/
void ipipe_timer_set(unsigned long delay);
const char *ipipe_timer_name(void);
unsigned ipipe_timer_ns2ticks(struct ipipe_timer *timer, unsigned ns);
void __ipipe_timer_refresh_freq(unsigned int hrclock_freq);
#else /* !CONFIG_IPIPE */
#define ipipe_host_timer_register(clkevt) do { } while (0)
#endif /* !CONFIG_IPIPE */
#ifdef CONFIG_IPIPE_HAVE_HOSTRT
void ipipe_update_hostrt(struct timekeeper *tk);
#else
static inline void
ipipe_update_hostrt(struct timekeeper *tk) {}
#endif
#endif /* __LINUX_IPIPE_TICKDEV_H */
/* -*- linux-c -*-
* include/linux/ipipe_trace.h
*
* Copyright (C) 2005 Luotao Fu.
* 2005-2007 Jan Kiszka.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
* USA; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _LINUX_IPIPE_TRACE_H
#define _LINUX_IPIPE_TRACE_H
#ifdef CONFIG_IPIPE_TRACE
#include <linux/types.h>
#ifndef BROKEN_BUILTIN_RETURN_ADDRESS
#define __BUILTIN_RETURN_ADDRESS0 ((unsigned long)__builtin_return_address(0))
#define __BUILTIN_RETURN_ADDRESS1 ((unsigned long)__builtin_return_address(1))
#endif /* !BUILTIN_RETURN_ADDRESS */
struct pt_regs;
void ipipe_trace_begin(unsigned long v);
void ipipe_trace_end(unsigned long v);
void ipipe_trace_freeze(unsigned long v);
void ipipe_trace_special(unsigned char special_id, unsigned long v);
void ipipe_trace_pid(pid_t pid, short prio);
void ipipe_trace_event(unsigned char id, unsigned long delay_tsc);
int ipipe_trace_max_reset(void);
int ipipe_trace_frozen_reset(void);
void ipipe_trace_irqbegin(int irq, struct pt_regs *regs);
void ipipe_trace_irqend(int irq, struct pt_regs *regs);
#else /* !CONFIG_IPIPE_TRACE */
#define ipipe_trace_begin(v) do { (void)(v); } while(0)
#define ipipe_trace_end(v) do { (void)(v); } while(0)