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

preempt: ipipe: : add preemption-safe hard_preempt_{enable, disable}() ops

Some inner code of the interrupt pipeline may have to traverse regular
kernel code which manipulates the preemption count, expecting full
serialization including with out-of-band contexts.

The hard_preempt_*() variants are substituted to the original
preempt_{enable, disable}() calls in these cases.
parent 0a80a322
......@@ -100,6 +100,9 @@ static inline void __ipipe_sync_stage(void)
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)
#define __ipipe_serial_debug(__fmt, __args...) raw_printk(__fmt, ##__args)
#else /* !CONFIG_IPIPE */
......@@ -115,6 +118,16 @@ static inline void __ipipe_init_proc(void) { }
static inline void __ipipe_idle(void) { }
#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_domain_irq(__domain, __hwirq, __regs) \
......
......@@ -255,7 +255,28 @@ do { \
#endif /* CONFIG_PREEMPT_COUNT */
#ifdef MODULE
#ifdef CONFIG_IPIPE
#define hard_preempt_disable() \
({ \
unsigned long __flags__; \
__flags__ = hard_local_irq_save(); \
if (__ipipe_root_p) \
preempt_disable(); \
__flags__; \
})
#define hard_preempt_enable(__flags__) \
do { \
if (__ipipe_root_p) { \
preempt_enable_no_resched(); \
hard_local_irq_restore(__flags__); \
if (!hard_irqs_disabled_flags(__flags__)) \
preempt_check_resched(); \
} else \
hard_local_irq_restore(__flags__); \
} while (0)
#elif defined(MODULE)
/*
* Modules have no business playing preemption tricks.
*/
......@@ -263,7 +284,7 @@ do { \
#undef preempt_enable_no_resched
#undef preempt_enable_no_resched_notrace
#undef preempt_check_resched
#endif
#endif /* !IPIPE && MODULE */
#define preempt_set_need_resched() \
do { \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment