torvalds/linux
github.com/torvalds/linux ↗ · 3999 files · 32.7 MB · scan capped
Linux kernel ============ The Linux kernel is the core of any Linux operating system.
Overview
This is the Linux kernel source tree (torvalds/linux) at version 7.3.0-rc4, codename "Baby Opossum Posse" — the monolithic Unix-like kernel that manages hardware, memory, processes, filesystems, networking and security for all Linux userspace. It is written primarily in C (~26MB of C scanned) with a first-class Rust component under rust/ that wraps kernel APIs for in-tree Rust drivers, and is built by a recursive Kbuild system configured through hierarchical Kconfig files. The runtime boundary is the syscall ABI: per-architecture entry code (e.g. arch/x86/entry/) dispatches into generic kernel code where VFS, mm, scheduler and security (LSM) layers mediate everything userspace can do.
System map
The tree is organized as core kernel code (init/, kernel/, mm/, ipc/), a VFS layer with ~50 filesystems (fs/), networking (net/), block layer (block/), io_uring (io_uring/), drivers (drivers/), security modules (security/), crypto (crypto/), per-architecture ports (arch/, 22 architectures), Rust support (rust/), userspace tooling (tools/), documentation (Documentation/, ~4000 rst files) and scripts/ for the build. There is no single binary entrypoint: the linker composes initcall sections and start_kernel() in init/main.c is the canonical C entry after arch-specific setup. Build is driven by the top-level Makefile (VERSION=7 PATCHLEVEL=3 SUBLEVEL=0 EXTRAVERSION=-rc4) plus Kconfig; there are no CI configs in-tree. The runtime boundary is the syscall table, generated from per-arch .tbl files.
- Top-level Makefile pins the release: VERSION=7, PATCHLEVEL=3, SUBLEVEL=0, EXTRAVERSION=-rc4, NAME="Baby Opossum Posse"; requires GNU Make >= 4.0 and uses a recursive Kbuild descent where sub-Makefiles only modify their own directory.
- start_kernel() in init/main.c is the architecture-independent C entrypoint; it runs a strictly ordered bring-up — set_task_stack_end_magic, smp_setup_processor_id, boot_cpu_init, setup_arch, mm_core_init_early/mm_core_init, sched_init, rcu_init, early_irq_init, init_IRQ, timers_init, hrtimers_init — and ends by calling rest_init().
- rest_init() creates PID 1 by calling kernel_clone() with kernel_init as the thread function and creates kthreadd via kernel_thread(); the boot CPU then becomes the idle thread via schedule_preempt_disabled() and cpu_startup_entry(CPUHP_ONLINE).
- Subsystem initialization is linker-ordered: __define_initcall macros (early_initcall, core_initcall ... device_initcall, late_initcall) emit function pointers into initcall sections, and do_initcalls() walks initcall_levels[0..7] calling do_one_initcall on each entry; do_pre_smp_initcalls() runs the 'early' level before smp_init().
- The top-level Kconfig file is an aggregator that sources init/Kconfig, kernel/Kconfig.freezer, fs/Kconfig.binfmt, mm/Kconfig, net/Kconfig, drivers/Kconfig, fs/Kconfig, security/Kconfig, crypto/Kconfig, lib/Kconfig, lib/Kconfig.debug, Documentation/Kconfig and io_uring/Kconfig.
- The init/ Makefile links the boot sequence objects: main.o, version.o, mounts.o (do_mounts.o plus do_mounts_rd.o/do_mounts_initrd.o when initrd support is enabled), initramfs.o or noinitramfs.o, calibrate.o and initramfs_test.o under CONFIG_INITRAMFS_TEST.
- x86-64 syscall entry is arch/x86/entry/entry_64.S entry_SYSCALL_64, which calls do_syscall_64() in arch/x86/entry/syscall_64.c; that function wraps dispatch in syscall_enter_from_user_mode_randomize_stack()/syscall_exit_to_user_mode() and calls do_syscall_x64, which bounds-checks nr with array_index_nospec and calls x64_sys_call — a dense switch generated from <asm/syscalls_64.h> rather than the legacy sys_call_table[] pointer jump.
- Syscall numbers and their implementing symbols are declared per-architecture in table files such as arch/x86/entry/syscalls/syscall_64.tbl (e.g. nr 9 mmap -> sys_mmap, nr 16 ioctl -> sys_ioctl), which are compiled into generated headers that build both the switch dispatcher and sys_call_table[] (kept only for trace_syscalls).
- Rust is a first-class in-tree language: rust/kernel/lib.rs defines a #![no_std] 'kernel' crate that all Rust kernel code depends on, with per-subsystem modules (alloc, block, driver, fs, i2c, ...) gated by CONFIG_* cfgs; its doc comment instructs contributors to wrap missing C APIs in this crate rather than bypass it.
- The device model lives in drivers/base/: bus.c implements bus/driver/device matching and dd.c runs probing via driver_probe_device -> __driver_probe_device -> really_probe, which calls driver_sysfs_add and the driver's probe hook.
- Loadable kernel modules are handled by kernel/module/main.c: SYSCALL_DEFINE3(init_module) and SYSCALL_DEFINE3(finit_module) both call may_init_module() (CAP_SYS_MODULE + modules_disabled check) then load_module(), which validates the ELF image, checks signatures and modinfo, lays out sections and calls do_init_module().
- The LSM layer in security/security.c generates dispatch wrappers via call_int_hook()/call_void_hook() over hook lists declared in include/linux/lsm_hook_defs.h; security/lsm_init.c registers staged LSM initcalls (pure, early, core, subsys, fs) and early_security_init()/security_init() are invoked from start_kernel().
Feature catalog
User-visible features are the syscall surface plus pseudo-filesystems and kernel subsystems. The catalog spans process management (fork/clone3/execve), file I/O (openat2, read/write family, io_uring), sockets and the full network stack, loadable modules, eBPF programs/maps, namespaces and cgroups, SysV/POSIX IPC, the crypto API with AF_ALG userspace access, pluggable schedulers (including BPF-extensible sched_ext), security modules (SELinux, AppArmor, Smack, TOMOYO, Landlock, IPE, Yama, LoadPin), tracing (ftrace, perf events) and sysctl/procfs/sysfs configuration interfaces.
- File-opening syscalls open, openat, openat2 and creat are defined in fs/open.c via SYSCALL_DEFINE macros; openat2 takes an extensible struct open_how copied with copy_struct_from_user and size-bounded against OPEN_HOW_SIZE_VER0/PAGE_SIZE.
- The read/write syscall family (read, write, lseek, readv, writev, pread64, pwrite64, preadv2, pwritev2 and compat variants) is implemented in fs/read_write.c, all funneling to vfs_read/vfs_write which dispatch to f_op->read or f_op->read_iter via new_sync_read/new_sync_write.
- Process creation syscalls fork, vfork, clone and clone3 are all implemented in kernel/fork.c and converge on kernel_clone() -> copy_process(); clone3 takes a versioned struct clone_args validated by clone3_args_valid/clone3_stack_valid.
- execve program loading lives in fs/exec.c, which opens the target via do_file_open() and hands off to registered binary-format handlers such as fs/binfmt_elf.c for ELF binaries.
- The BSD socket API is implemented in net/socket.c: SYSCALL_DEFINE3(socket) -> __sys_socket -> __sys_socket_create -> __sock_create, wrapped by security_socket_create/security_socket_post_create LSM hooks, with sock_create_lite available for in-kernel sockets.
- io_uring provides the async I/O interface: SYSCALL_DEFINE2(io_uring_setup) creates the ring, SYSCALL_DEFINE6(io_uring_enter) -> io_submit_sqes consumes SQEs and calls io_issue_sqe, which dispatches per-opcode through the io_issue_defs[] table in io_uring/opdef.c.
- The bpf(2) syscall multiplexes eBPF map/program/link operations; bpf_prog_load() runs the 21k-line verifier (kernel/bpf/verifier.c) before a program may attach, and every step is gated by security_bpf* LSM hooks.
- The scheduler implements multiple classes — EEVDF/fair (fair.c), realtime (rt.c), deadline (deadline.c), idle (idle.c) — plus sched_ext in kernel/sched/ext/, which lets BPF programs implement custom scheduling policies.
- Filesystems self-register through register_filesystem()/unregister_filesystem() in fs/filesystems.c; the tree ships ~50 filesystems including ext4, btrfs, f2fs, xfs, nfs and procfs (fs/proc/root.c).
- Module administration syscalls init_module/finit_module/delete_module are exposed in kernel/module/main.c, gated on CAP_SYS_MODULE and modules_disabled, with signature enforcement under CONFIG_MODULE_SIG/MODULE_SIG_FORCE.
- System V IPC (msg.c, sem.c, shm.c) and POSIX message queues (mqueue.c) live in ipc/, with per-namespace accounting in ipc/namespace.c; process namespaces are managed in kernel/nsproxy.c and kernel/pid_namespace.c.
- Observability subsystems include ftrace/tracepoints (kernel/trace/trace.c), perf events (kernel/events/core.c) and the printk ring buffer (kernel/printk/printk.c); sysctl tables are registered through kernel/sysctl.c with subsystem additions such as mm/hugetlb_sysctl.c.
Data flow
Data enters through arch entry code (syscalls, interrupts, faults), is validated at each layer boundary, and flows through generic frameworks — VFS for files, socket layer for network, the block layer for storage, page-fault machinery for memory. Ownership is layered: user buffers are copied at syscall edges (access_ok, copy_struct_from_user), VFS resolves paths through the dentry/inode caches into struct file, LSM hooks interpose at every security-relevant hop, and the scheduler/RCU control when shared state may be mutated or reclaimed.
- Boot parameter flow: arch code fills boot_command_line; start_kernel calls setup_command_line then parse_early_param (walking __setup_start..__setup_end obs_kernel_param entries via do_early_param) and parse_args over the __param section; unknown options after '--' become init's argv via set_init_arg.
- open(2) data flow: sys_openat -> do_sys_open -> do_sys_openat2 (build_open_flags) -> do_file_open -> path_openat, which calls path_init, loops link_path_walk + open_last_lookups, then do_open; the resulting struct file is installed as an fd via FD_ADD.
- Path lookup runs lock-free RCU mode first (LOOKUP_RCU) and escalates: path_openat retries ref-walked on -ECHILD and again with LOOKUP_REVAL on -ESTALE; -EOPENSTALE from a filesystem is translated to -ECHILD/-ESTALE to trigger the retry ladder.
- Permission checking during lookup: inode_permission() -> do_inode_permission() applies POSIX mode/ACL checks, then devcgroup_inode_permission (device cgroup) and finally security_inode_permission (LSM) — three stacked authorization layers per path component.
- read(2) data flow: sys_read -> ksys_read looks up the fd's struct file, vfs_read validates FMODE_READ/FMODE_CAN_READ and access_ok on the user buffer, calls rw_verify_area, then f_op->read or new_sync_read(f_op->read_iter); on success fsnotify_access() and add_rchar/inc_syscr update accounting.
- clone/fork data flow: sys_clone3 -> clone3_args_valid -> kernel_clone normalizes flags (CLONE_EMPTY_MNTNS implies CLONE_NEWNS; CLONE_PIDFD vs CLONE_PARENT_SETTID exclusion), copy_process duplicates the task (dup_task_struct -> sched_fork -> copy_thread), then wake_up_new_task enqueues the child and optional PTRACE_EVENT_* reports fire.
- Page-fault data flow: arch fault handler -> handle_mm_fault checks arch_vma_access_permitted, calls mem_cgroup_enter_user_fault for user faults, routes to hugetlb_fault or __handle_mm_fault -> handle_pte_fault -> do_anonymous_page (anon) or do_fault -> __do_fault (vm_ops->fault for file-backed); VM_DROPPABLE VMAs get non-fatal OOM handling.
- Module-load data flow: finit_module reads the fd's ELF image, may_init_module enforces CAP_SYS_MODULE/modules_disabled, load_module calls module_sig_check, elf_validity_ehdr (magic/type/machine validation) and check_modinfo (vermagic, livepatch, retpoline), then do_init_module runs the module's init function.
- Socket creation flow: sys_socket -> __sys_socket_create -> __sock_create checks the protocol family, calls security_socket_create before allocation and security_socket_post_create after the family's create op runs; __sys_socket_file wraps the socket in a file/fd for the syscall ABI.
- io_uring submission flow: io_uring_enter -> io_submit_sqes pulls SQEs from the shared ring, io_issue_sqe reads io_issue_defs[req->opcode] for per-op flags and calls the opcode's issue handler; completion state is written back to the shared CQ ring.
- Context-switch flow: schedule() -> __schedule() takes rq->lock, updates rq clock, calls pick_next_task() (class order: stop -> deadline -> rt -> fair/ext -> idle), then context_switch() swaps the mm and register state; preemption is driven by TIF_NEED_RESCHED set in sched_tick.
- Usermode-helper flow: call_usermodehelper_exec_async runs inside a user_mode_thread, intersects the new cred's capabilities with usermodehelper_bset/usermodehelper_inheritable, then kernel_execve's the helper binary (e.g. modprobe, hotplug) — a kernel-to-userspace privilege boundary.
Behavior traces
Key flows traced end-to-end: (1) full boot from start_kernel through initcall levels to PID 1 exec of /sbin/init; (2) a syscall from entry_SYSCALL_64 through the generated dispatch switch to sys_openat and VFS path walk; (3) process creation via clone3->kernel_clone->copy_process->wake_up_new_task; (4) module load via finit_module->load_module->do_init_module; (5) scheduling via __schedule's pick_next_task/context_switch; (6) rootfs mounting via prepare_namespace->mount_root->init_mount.
- Boot trace (phase 1): start_kernel -> set_task_stack_end_magic -> smp_setup_processor_id -> boot_cpu_init -> setup_arch -> mm_core_init_early -> jump_label_init/static_call_init -> early_security_init -> setup_boot_config/setup_command_line -> parse_early_param/parse_args -> random_init_early -> trap_init -> mm_core_init -> sched_init -> early_irq_init -> init_IRQ -> timers_init -> hrtimers_init -> rest_init.
- Boot trace (phase 2): rest_init -> kernel_clone(kernel_init) creates PID 1 -> kernel_thread(kthreadd) creates PID 2 -> complete(&kthreadd_done) -> schedule_preempt_disabled -> cpu_startup_entry; the boot CPU becomes the idle loop while PID 1 continues initialization.
- Boot trace (phase 3): kernel_init -> init_userspace_fs -> wait_for_completion(kthreadd_done) -> kernel_init_freeable -> smp_prepare_cpus -> workqueue_init -> do_pre_smp_initcalls -> smp_init -> sched_init_smp -> do_basic_setup (cpuset_init_smp, ksysfs_init, driver_init, do_initcalls) -> kunit_run_all_tests -> wait_for_initramfs -> console_on_rootfs -> prepare_namespace.
- Boot trace (phase 4): after initcalls, kernel_init -> async_synchronize_full -> free_initmem -> mark_readonly (mark_rodata_ro + rodata_test under STRICT_KERNEL_RWX) -> pti_finalize -> system_state=SYSTEM_RUNNING -> run_init_process tries ramdisk_execute_command(/init), then execute_command (init= param), then CONFIG_DEFAULT_INIT, then /sbin/init, /etc/init, /bin/init, /bin/sh — panicking if none works.
- Rootfs mount trace: kernel_init_freeable -> prepare_namespace (init/do_mounts.c) -> mount_root -> mount_root_generic -> do_mount_root -> init_mount(name, "/root", fstype, flags, data) -> init_chdir("/root"); falls back through configured rootfstype list (ext4 etc.) or nfs/cifs for network roots.
- Syscall trace: userspace syscall instruction -> entry_SYSCALL_64 (entry_64.S) saves regs -> call do_syscall_64 -> syscall_enter_from_user_mode_randomize_stack -> do_syscall_x64 (nr < NR_syscalls, array_index_nospec) -> x64_sys_call switch case -> __x64_sys_* wrapper -> syscall_exit_to_user_mode; the return value of do_syscall_64 selects SYSRET vs IRET after validating cx/r11/cs/ss/ip/flags.
- openat trace: __x64_sys_openat -> do_sys_open -> do_sys_openat2 -> build_open_flags -> do_file_open -> set_nameidata -> path_openat(LOOKUP_RCU) -> path_init -> link_path_walk -> open_last_lookups -> do_open -> vfs_open -> may_open -> inode_permission -> f_op->open; retries drop LOOKUP_RCU on -ECHILD then add LOOKUP_REVAL on -ESTALE; FD_ADD installs the fd.
- clone3 trace: __x64_sys_clone3 -> clone3_args_valid (size/version checks, CSIGNAL rules, clone3_stack_valid) -> kernel_clone -> copy_process -> dup_task_struct -> sched_fork -> copy_thread -> wake_up_new_task -> returns child pid; vfork additionally blocks the parent on the vfork_done completion.
- Module-load trace: __x64_sys_finit_module -> may_init_module (CAP_SYS_MODULE) -> load_module -> module_sig_check -> elf_validity_ehdr -> layout_and_allocate -> check_modinfo (vermagic/livepatch/retpoline) -> do_init_module -> mod->init(); delete_module requires the module to be unused and !modules_disabled.
- Schedule trace: schedule() -> __schedule(SM_NONE) -> rq_lock -> update_rq_clock -> pick_next_task -> __pick_next_task iterates sched classes -> context_switch(rq, prev, next) switches address space and CPU state -> rq unlock; on the idle path cpu_startup_entry calls schedule() in a loop until a task wakes.
Testing signals
Testing is built into the tree: KUnit (lib/kunit/) is the in-kernel unit-test framework, run at boot via kunit_run_all_tests() or via the tools/testing/kunit/kunit.py harness under UML/QEMU. kselftest (tools/testing/selftests/, ~135 target dirs) provides userspace-driven syscall/feature tests emitting KTAP. Numerous ad-hoc selftest .c files live next to core code (initramfs_test.c, kallsyms_selftest.c, sysctl-test.c, dmapool_test.c, gup_test.c). There is no in-tree CI config — validation is maintainer/review driven, with checkpatch.pl/get_maintainer.pl as local gates; external systems (syzbot, kernelci, 0-day) do continuous testing.
- KUnit is the kernel unit-test framework: lib/kunit/ contains test.c, executor.c, try-catch.c, string-stream.c, debugfs.c and assertion helpers, with public headers in include/kunit/test.h.
- KUnit tests execute during boot inside kernel_init_freeable via kunit_run_all_tests(), after do_basic_setup() and before prepare_namespace(), so late-init tests run with the full kernel initialized.
- tools/testing/kunit/ provides the Python runner: kunit.py orchestrates builds (kunit_config.py) and runs kernels under QEMU (qemu_config.py, qemu_configs/), parsing KTAP output via kunit_parser.py.
- Per-subsystem .kunitconfig fragments select test builds: init/.kunitconfig sets CONFIG_KUNIT=y + CONFIG_INITRAMFS_TEST=y; rust/.kunitconfig sets CONFIG_KUNIT + CONFIG_RUST + CONFIG_RUST_KERNEL_DOCTESTS.
- kselftest lives in tools/testing/selftests/: the top Makefile aggregates ~135 TARGETS (acct, bpf, cgroup, clone3, exec, futex, memblock-adjacent dirs, net, ...), and runner.sh/run_kselftest.sh plus ksft.py/ktap_helpers.sh provide the KTAP-emitting harness.
- Ad-hoc selftests sit beside production code: init/initramfs_test.c (CONFIG_INITRAMFS_TEST), kernel/kallsyms_selftest.c, kernel/sysctl-test.c, kernel/crash_core_test.c, kernel/resource_kunit.c, mm/dmapool_test.c and mm/gup_test.c.
- tools/testing/ also hosts standalone harnesses for library code — memblock, radix-tree, rbtree, scatterlist, vma, vsock — that compile kernel sources directly in userspace for fast unit testing.
- Rust has its own test plumbing: rust/kernel/kunit.rs plus the #[kunit] proc-macro support in rust/macros/kunit.rs, an example test in lib/kunit/kunit-example-test.c style, and CONFIG_RUST_KERNEL_DOCTESTS for doc tests.
- There is no .github/, .gitlab-ci.yml or similar CI config in the tree; contribution gating is the email review flow documented in Documentation/process/submitting-patches.rst with scripts/checkpatch.pl as the pre-submit style checker.
- Coverage is uneven by construction: selftests concentrate in tools/testing/selftests and a minority of core files carry paired test modules (e.g. kernel/sysctl-test.c for kernel/sysctl.c), so most of mm/, net/ and drivers/ has no in-tree unit coverage and relies on external fuzzing/CI. (inferred)
Risk map
The highest-risk paths are the ones that cross privilege boundaries: module loading (ring-0 code injection gated by CAP_SYS_MODULE and signatures), the eBPF verifier, io_uring's single-fd multiplexer over dozens of opcodes, usermodehelper exec, seccomp filter evaluation, and every user-memory copy in syscall bodies. Concurrency hazards concentrate in the RCU path-walk retry ladder and the scheduler's rq-lock protocol. Boot is fail-hard: missing init or corrupt initmem panics the machine.
- Module loading is the most direct ring-0 injection path: may_init_module() requires CAP_SYS_MODULE and respects modules_disabled; module_sig_check enforces CONFIG_MODULE_SIG/MODULE_SIG_FORCE; elf_validity_ehdr rejects malformed images — a bypass anywhere here yields full kernel compromise.
- call_usermodehelper execs userspace binaries from kernel context with usermodehelper_bset/CAP_FULL_SET defaults; callers like request_module (kernel/module/kmod.c) make this a kernel->userspace escalation surface that must sanitize inputs.
- The eBPF verifier (kernel/bpf/verifier.c, ~21.5k lines) is the barrier between unprivileged/privileged userspace and in-kernel JIT'd code; bpf_prog_load -> bpf_check -> security_bpf_prog chains show the gating, and verifier bugs historically yield privilege escalation.
- io_uring multiplexes ~all VFS/socket/block operations through one fd via the io_issue_defs[] opcode table; BUG_ON checks in opdef.c enforce invariants at registration, but the breadth of reachable kernel code makes it a persistent CVE hotspot.
- seccomp evaluates user-supplied cBPF on every syscall via struct seccomp_filter trees linked through ->prev; filters are immutable once attached and the cache (seccomp_cache_check_allow) fast-paths 'allow' decisions — subtle bugs here weaken sandboxing.
- User-memory crossings are scattered and easy to get wrong: openat2 copy_struct_from_user for extensible open_how, vfs_read/vfs_write access_ok checks, put_user in kernel_clone for parent_tid — each is a potential info-leak/overflow if bounds slip.
- RCU path-walk retry semantics are fragile: filesystems and callers must tolerate -ECHILD/-ESTALE/-EOPENSTALE restart loops in do_file_open; code that caches dentry state across a restart risks use-after-free or TOCTOU.
- Boot integrity self-checks exist but only warn/panic: mark_readonly() under STRICT_KERNEL_RWX runs mark_rodata_ro, debug_checkwx and rodata_test; failures print warnings or panic, and CONFIG_STRICT_KERNEL_RWX can be disabled via the rodata= boot param.
- Failure mode for missing init is panic(): after trying /init, init=, CONFIG_DEFAULT_INIT, /sbin/init, /etc/init, /bin/init and /bin/sh, kernel_init calls panic("No working init found") — misconfigured rootfs/ramdisk bricks boot.
- ptrace hooks in kernel_clone (PTRACE_EVENT_FORK/VFORK/CLONE) expose every process creation to tracers; ptrace_event_enabled checks happen before copy_process, so tracer attachments change observable behavior — a classic audit/evasion concern.
- Correctness depends on out-of-tree validation: no CI config exists in the repo, selftests cover only a slice of core code, and the scheduler/mm concurrency contracts (documented in block comments like the __schedule memory-barrier notes) are enforced by review rather than automated checks. (inferred)
- The Rust/C boundary is a concentrated audit point: rust/kernel/lib.rs wraps C APIs with documented safety invariants and explicitly forbids bypassing the crate; new wrappers that misstate C contracts propagate unsoundness to every Rust driver. (inferred)
Extension points
The kernel is extension-by-design: initcall levels order boot-time registration, LSM hook tables add security policies, file_operations/inode_operations/super_operations vtables plug filesystems, struct device_driver + bus match functions plug drivers, register_filesystem adds filesystems, the syscall .tbl files add syscalls, module_init/module_exit wrap loadable code, eBPF program types (including sched_ext and bpf_struct_ops) let userspace extend behavior at runtime, and io_uring opcodes extend async I/O. Rust extensions go through the kernel crate + #[module] proc-macro.
- initcall levels are the primary boot-time extension mechanism: __define_initcall emits entries into named linker sections (early, core, postcore, arch, subsys, fs, device, late, plus *_sync variants) consumed by do_initcalls in order.
- New security modules plug in via the LSM framework: hook implementations are registered into lists declared in include/linux/lsm_hook_defs.h, dispatched by call_int_hook/call_void_hook in security/security.c, and initialized through the staged security_initcall_* initcalls in security/lsm_init.c.
- Filesystems extend via struct file_system_type registered with register_filesystem()/unregister_filesystem() in fs/filesystems.c, then implement super_operations/inode_operations/file_operations that VFS calls through f_op->read/write_iter/open.
- Drivers plug into the driver model: bus_type match functions pair devices with device_driver structs, and driver_probe_device -> really_probe invokes drv->probe plus sysfs integration (driver_sysfs_add).
- Loadable modules extend the kernel at runtime: module_init maps to device_initcall for built-ins or runs in do_init_module for loaded modules; check_modinfo enforces vermagic/license/livepatch metadata compatibility.
- eBPF is the runtime extension fabric: bpf(2) loads verified programs/maps (kernel/bpf/syscall.c), attachable to kprobes/tracepoints/LSM (bpf_lsm.c), and sched_ext (kernel/sched/ext/) exposes the CPU scheduler itself to BPF policies.
- New syscalls are added by a row in the per-arch .tbl files (e.g. arch/x86/entry/syscalls/syscall_64.tbl) plus a SYSCALL_DEFINE body; generated asm/syscalls_64.h feeds both the x64_sys_call switch and sys_call_table[].
- io_uring opcodes extend through the io_issue_defs[] table in io_uring/opdef.c: each IORING_OP_* entry declares prep/issue handlers and capability flags, with BUILD_BUG_ON/early-init validation that every opcode has both handlers.
- Rust modules are wired by the kernel crate + macros: rust/kernel/ exposes safe wrappers (driver.rs, device.rs, fs.rs) and rust/macros/module.rs generates module metadata; samples/rust/*.rs (rust_minimal.rs, rust_driver_i2c.rs, rust_driver_pci.rs, ...) are the canonical examples.
- Kconfig + Kbuild wiring is the build-time extension pattern: add a config FOO to a subsystem Kconfig (sourced via the top-level Kconfig chain) and gate objects with obj-$(CONFIG_FOO) in the directory Makefile.
- sysctl knobs are registered through kernel/sysctl.c tables, with subsystem-specific registrations such as mm/hugetlb_sysctl.c exposing runtime-tunable parameters under /proc/sys.
- kselftest suites extend by adding a directory under tools/testing/selftests and a TARGETS += entry in the top Makefile; each suite emits KTAP via kselftest/ktap_helpers.sh/ksft.py.
Contributor handoff
This is a review-driven C codebase with hard ABI boundaries (syscalls, UAPI headers, module interface) and strict process rules: coding-style.rst + checkpatch.pl for style, MAINTAINERS + get_maintainer.pl for ownership, submitting-patches.rst for the email workflow, and a dedicated coding-assistants.rst that forbids AI agents from adding Signed-off-by and prescribes an Assisted-by: LLM tag plus a reproducer-then-fix discipline. Safe first edits live in leaf drivers/ or new selftests; touching kernel/sched, mm, fs/namei or arch entry code requires reading the extensive lock-ordering and retry-protocol comments. Test with kunit.py and kselftest; build with make + Kconfig.
- Style and patch hygiene: follow Documentation/process/coding-style.rst, run scripts/checkpatch.pl on diffs, and locate reviewers via scripts/get_maintainer.pl against MAINTAINERS (M:/R:/L:/S:/F: entry format documented at the top of MAINTAINERS).
- AI-specific contribution rules exist: Documentation/process/coding-assistants.rst states agents MUST NOT add Signed-off-by (only humans certify the DCO), contributions should carry an 'Assisted-by: LLM [tools]' tag, and bug fixes require reading full process docs plus a working reproducer before submitting.
- Build from the top Makefile: 'make' runs recursive Kbuild (sub-Makefiles only touch their own dir), config via Kconfig ('make menuconfig'/'make defconfig'); per-dir objects are wired with obj-y/obj-$(CONFIG_*) lists as in init/Makefile.
- Run tests with tools/testing/kunit/kunit.py (e.g. './tools/testing/kunit/kunit.py run' under UML/QEMU) for KUnit, and tools/testing/selftests via run_kselftest.sh/runner.sh; per-subsystem .kunitconfig fragments (init/.kunitconfig, rust/.kunitconfig) show minimal configs.
- Read-first files for orientation: init/main.c (boot ordering and initcall protocol), the subsystem's Makefile+Kconfig, the relevant MAINTAINERS entry, and for syscall work arch/x86/entry/syscall_64.c + syscall_64.tbl.
- Trap — stable syscall ABI: never renumber or change entries in arch/x86/entry/syscalls/syscall_64.tbl or alter UAPI headers under include/uapi/ incompatibly; new syscalls append new numbers and new structs must be extensible like struct open_how (size-checked via copy_struct_from_user).
- Trap — __init lifetime: functions/data marked __init are freed by free_initmem() after boot (SYSTEM_FREEING_INITMEM -> SYSTEM_RUNNING); calling them post-boot crashes, and mark_readonly() then enforces STRICT_KERNEL_RWX on kernel text/rodata.
- Trap — namei retry protocol: path lookup restarts on -ECHILD (RCU->ref walk), -ESTALE (revalidation) and translates -EOPENSTALE; any code holding state across link_path_walk must handle restarts, and dcache lookups may run under RCU with no refcounting.
- Trap — scheduler locking: __schedule() holds rq->lock and documents exact memory-barrier pairings (smp_mb__after_spinlock vs signal wake-up paths); violating these or calling schedule() with preemption enabled corrupts task state.
- Privilege checks precede security hooks: kernel code calls capable()/CAP_* first (e.g. may_init_module requires CAP_SYS_MODULE), then LSM hooks (security_*) run via call_int_hook — new code must wire both layers, not just one.
- Rust contributions must go through rust/kernel wrappers — the crate docs explicitly forbid bypassing it with raw C calls — and module glue is generated by rust/macros/module.rs; study samples/rust/rust_minimal.rs before writing drivers.
- Safe edit boundaries: leaf drivers (drivers/*/*) and new tools/testing/selftests entries are low blast-radius; init/main.c, kernel/fork.c, kernel/sched/core.c, mm/memory.c, fs/namei.c and arch/*/entry/* are blast-radius hotspots where changes affect every task/syscall. (inferred)
Languages
| Language | Files | Share of source |
|---|---|---|
| C | 64536 | 97% |
| YAML | 5790 | docs/config |
| Shell | 1167 | 2% |
| JSON | 1084 | docs/config |
| Rust | 496 | 1% |
| Python | 429 | 1% |
| Markdown | 9 | docs/config |
| C++ | 7 | 0% |
Start reading here
Probable source entrypoint: lib/ — inferred from the directory tree and manifest, not the upstream docs.
Source roots
lib/ (235 files)
Repository structure
| Top-level path | Files |
|---|---|
Documentation/ | 236 |
arch/ | 236 |
tools/ | 235 |
include/ | 235 |
lib/ | 235 |
net/ | 235 |
rust/ | 235 |
fs/ | 235 |
Docs found: README
Package
tools/net/ynl/pyproject.toml — pyynl v0.0.1, 0 declared dependencies.
Structural health signals
Average score 7.8/10 across 96 analyzed source files; 12 hotspots surfaced.
rust/kernel/dma.rs— 1251 lines, score 5.9 (Large file, Deep nesting)scripts/bpf_doc.py— 1020 lines, score 5.9 (Large file, Deep nesting)rust/kernel/alloc/kvec.rs— 1575 lines, score 6.2 (Large file, Deep nesting)
These are deterministic review leads — size, churn, and structural signals — not proof of a bug in this project.
Recent history
f0100363d8c32026-09-21 — Merge tag 'xfs-fixes-7.3-rc5' of gitolite.kernel.org:/pub/scm/fs/xfs/xfs-linux93f51579e7df2026-09-20 — Linux 7.3-rc46a5719cc3ef22026-09-20 — net: qrtr: resend HELLO on MHI resumea10a019dd4c72026-09-20 — Merge tag 'dmaengine-fix-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine60ee24f055f82026-09-20 — Merge tag 'phy-fixes-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/phy/linux-phy