diff --git a/include/linux/bottom_half.h b/include/linux/bottom_half.h index fc53e0ad56d905c820c7d2738514b75408abeadd..448bbef474564450d01a6e6b810d0bdbd0a4ee38 100644 --- a/include/linux/bottom_half.h +++ b/include/linux/bottom_half.h @@ -35,8 +35,10 @@ static inline void local_bh_enable(void) #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 */ diff --git a/kernel/softirq.c b/kernel/softirq.c index 210cf5f8d92c2c2aa99d0e14db127c26d70f7e96..4132aea5632594bfbda3d467b3e05d7991d935c0 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -247,6 +247,19 @@ void __local_bh_enable_ip(unsigned long ip, unsigned int cnt) } EXPORT_SYMBOL(__local_bh_enable_ip); +void softirq_preempt(void) +{ + if (WARN_ON_ONCE(!preemptible())) + return; + + if (WARN_ON_ONCE(__this_cpu_read(softirq_ctrl.cnt) != SOFTIRQ_OFFSET)) + return; + + __local_bh_enable(SOFTIRQ_OFFSET, true); + /* preemption point */ + __local_bh_disable_ip(_RET_IP_, SOFTIRQ_OFFSET); +} + /* * Invoked from ksoftirqd_run() outside of the interrupt disabled section * to acquire the per CPU local lock for reentrancy protection.