b2d0254952
Add a functionality for the softirq handler to preempt its current work if needed. The softirq core has no particular state. It reads and resets the pending softirq bits and then processes one after the other. It can already be preempted while it invokes a certain softirq handler. By enabling the BH the softirq core releases the per-CPU bh lock which serializes all softirq handler. It is safe to do as long as the code does not expect any serialisation in between. A typical scenarion would after the invocation of callback where no state needs to be preserved before the next callback is invoked. Add functionaliry to preempt the serving softirqs. Link: https://lore.kernel.org/r/20230804113039.419794-3-bigeasy@linutronix.de Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
45 lines
1.1 KiB
C
45 lines
1.1 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _LINUX_BH_H
|
|
#define _LINUX_BH_H
|
|
|
|
#include <linux/instruction_pointer.h>
|
|
#include <linux/preempt.h>
|
|
|
|
#if defined(CONFIG_PREEMPT_RT) || defined(CONFIG_TRACE_IRQFLAGS)
|
|
extern void __local_bh_disable_ip(unsigned long ip, unsigned int cnt);
|
|
#else
|
|
static __always_inline void __local_bh_disable_ip(unsigned long ip, unsigned int cnt)
|
|
{
|
|
preempt_count_add(cnt);
|
|
barrier();
|
|
}
|
|
#endif
|
|
|
|
static inline void local_bh_disable(void)
|
|
{
|
|
__local_bh_disable_ip(_THIS_IP_, SOFTIRQ_DISABLE_OFFSET);
|
|
}
|
|
|
|
extern void _local_bh_enable(void);
|
|
extern void __local_bh_enable_ip(unsigned long ip, unsigned int cnt);
|
|
|
|
static inline void local_bh_enable_ip(unsigned long ip)
|
|
{
|
|
__local_bh_enable_ip(ip, SOFTIRQ_DISABLE_OFFSET);
|
|
}
|
|
|
|
static inline void local_bh_enable(void)
|
|
{
|
|
__local_bh_enable_ip(_THIS_IP_, SOFTIRQ_DISABLE_OFFSET);
|
|
}
|
|
|
|
#ifdef CONFIG_PREEMPT_RT
|
|
extern bool local_bh_blocked(void);
|
|
extern void softirq_preempt(void);
|
|
#else
|
|
static inline bool local_bh_blocked(void) { return false; }
|
|
static inline void softirq_preempt(void) { }
|
|
#endif
|
|
|
|
#endif /* _LINUX_BH_H */
|