kernel/softirq.c
Source file repositories/reference/linux-study-clean/kernel/softirq.c
File Facts
- System
- Linux kernel
- Corpus path
kernel/softirq.c- Extension
.c- Size
- 29112 bytes
- Lines
- 1202
- Domain
- Core OS
- Bucket
- Scheduler, Processes, Timers, Sync, And Syscalls
- Inferred role
- Core OS: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/export.hlinux/kernel_stat.hlinux/interrupt.hlinux/init.hlinux/local_lock.hlinux/mm.hlinux/notifier.hlinux/percpu.hlinux/cpu.hlinux/freezer.hlinux/kthread.hlinux/rcupdate.hlinux/ftrace.hlinux/smp.hlinux/smpboot.hlinux/tick.hlinux/irq.hlinux/wait_bit.hlinux/workqueue.hasm/softirq_stack.htrace/events/irq.h
Detected Declarations
struct softirq_ctrlstruct tasklet_headstruct tasklet_sync_callbackfunction wakeup_softirqdfunction local_bh_blockedfunction __local_bh_disable_ipfunction __local_bh_enablefunction __local_bh_enable_ipfunction ksoftirqd_runfunction ksoftirqd_run_endfunction softirq_handle_beginfunction invoke_softirqfunction flush_smp_call_function_queuefunction __local_bh_disable_ipfunction __local_bh_enablefunction _local_bh_enablefunction __local_bh_enable_ipfunction softirq_handle_beginfunction softirq_handle_endfunction ksoftirqd_run_beginfunction ksoftirqd_run_endfunction should_wake_ksoftirqdfunction invoke_softirqfunction do_softirqfunction need_reschedfunction lockdep_softirq_endfunction lockdep_softirq_startfunction lockdep_softirq_endfunction __do_softirqfunction irq_enter_rcufunction irq_enterfunction tick_irq_exitfunction wake_timersdfunction wake_timersdfunction irq_exit_rcufunction irq_exitfunction raise_softirq_irqofffunction raise_softirqfunction __raise_softirq_irqofffunction open_softirqfunction __tasklet_schedule_commonfunction __tasklet_schedulefunction __tasklet_hi_schedulefunction tasklet_clear_schedfunction tasklet_lock_callbackfunction tasklet_unlock_callbackfunction tasklet_callback_cancel_wait_runningfunction tasklet_callback_sync_wait_running
Annotated Snippet
struct softirq_ctrl {
local_lock_t lock;
int cnt;
};
static DEFINE_PER_CPU(struct softirq_ctrl, softirq_ctrl) = {
.lock = INIT_LOCAL_LOCK(softirq_ctrl.lock),
};
#ifdef CONFIG_DEBUG_LOCK_ALLOC
static struct lock_class_key bh_lock_key;
struct lockdep_map bh_lock_map = {
.name = "local_bh",
.key = &bh_lock_key,
.wait_type_outer = LD_WAIT_FREE,
.wait_type_inner = LD_WAIT_CONFIG, /* PREEMPT_RT makes BH preemptible. */
.lock_type = LD_LOCK_PERCPU,
};
EXPORT_SYMBOL_GPL(bh_lock_map);
#endif
/**
* local_bh_blocked() - Check for idle whether BH processing is blocked
*
* Returns false if the per CPU softirq::cnt is 0 otherwise true.
*
* This is invoked from the idle task to guard against false positive
* softirq pending warnings, which would happen when the task which holds
* softirq_ctrl::lock was the only running task on the CPU and blocks on
* some other lock.
*/
bool local_bh_blocked(void)
{
return __this_cpu_read(softirq_ctrl.cnt) != 0;
}
void __local_bh_disable_ip(unsigned long ip, unsigned int cnt)
{
unsigned long flags;
int newcnt;
WARN_ON_ONCE(in_hardirq());
lock_map_acquire_read(&bh_lock_map);
/* First entry of a task into a BH disabled section? */
if (!current->softirq_disable_cnt) {
if (preemptible()) {
if (IS_ENABLED(CONFIG_PREEMPT_RT_NEEDS_BH_LOCK))
local_lock(&softirq_ctrl.lock);
else
migrate_disable();
/* Required to meet the RCU bottomhalf requirements. */
rcu_read_lock();
} else {
DEBUG_LOCKS_WARN_ON(this_cpu_read(softirq_ctrl.cnt));
}
}
/*
* Track the per CPU softirq disabled state. On RT this is per CPU
* state to allow preemption of bottom half disabled sections.
*/
if (IS_ENABLED(CONFIG_PREEMPT_RT_NEEDS_BH_LOCK)) {
newcnt = this_cpu_add_return(softirq_ctrl.cnt, cnt);
/*
* Reflect the result in the task state to prevent recursion on the
* local lock and to make softirq_count() & al work.
*/
current->softirq_disable_cnt = newcnt;
if (IS_ENABLED(CONFIG_TRACE_IRQFLAGS) && newcnt == cnt) {
raw_local_irq_save(flags);
lockdep_softirqs_off(ip);
raw_local_irq_restore(flags);
}
} else {
bool sirq_dis = false;
if (!current->softirq_disable_cnt)
sirq_dis = true;
this_cpu_add(softirq_ctrl.cnt, cnt);
current->softirq_disable_cnt += cnt;
WARN_ON_ONCE(current->softirq_disable_cnt < 0);
if (IS_ENABLED(CONFIG_TRACE_IRQFLAGS) && sirq_dis) {
raw_local_irq_save(flags);
lockdep_softirqs_off(ip);
Annotation
- Immediate include surface: `linux/export.h`, `linux/kernel_stat.h`, `linux/interrupt.h`, `linux/init.h`, `linux/local_lock.h`, `linux/mm.h`, `linux/notifier.h`, `linux/percpu.h`.
- Detected declarations: `struct softirq_ctrl`, `struct tasklet_head`, `struct tasklet_sync_callback`, `function wakeup_softirqd`, `function local_bh_blocked`, `function __local_bh_disable_ip`, `function __local_bh_enable`, `function __local_bh_enable_ip`, `function ksoftirqd_run`, `function ksoftirqd_run_end`.
- Atlas domain: Core OS / Scheduler, Processes, Timers, Sync, And Syscalls.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.