Skip to main content

TECH VEDA

Linux kernel & Device drivers starts on 24th Oct 2026 enrollingCorporate on-site training - Submit proposal Pick your modulesSharpen your kernel skills: deep dives, drivers, Yocto, CVEs, careers โ€” updated daily. Read the blog โ†’Embedded Linux fast track starts 30th sept 2026 enrollingEmbedded Linux Mastery track starts 30th sept 2026 enrollingLinux systems engineering starts 30th sept 2026 enrolling
Insights

Linux 7.3: What Shipped, What Changed, Who Should Care

Linux 7.3 is out: one new syscall, five selectable scheduler cgroup modes, AF_ALG allowlisted by default, and four subsystems removed.

Linux 7.3: What Shipped, What Changed, Who Should Care

Linux 7.3 was released on 18 October 2026. It adds one new system call, fchroot(); gives the CPU scheduler five selectable cgroup accounting modes behind a runtime debugfs file; restricts the AF_ALG userspace crypto interface by default, which is the change most likely to break a working system; extends userfaultfd from write protection to read-write protection; and removes four subsystems. This article covers the whole release rather than one area, explains the dozen changes that alter behaviour, and ends with who should read which part.

A release article has two failure modes. It either lists sixty merge commits and explains none of them, or it covers one subsystem and calls that the release. Linux 7.3 closed the second-busiest merge window on record, so neither is useful. What follows is organised by what the change does to a running system: new interfaces first, then the scheduler, then the one default that will break userspace, then memory and I/O, filesystems, architectures, Rust, and removals. Everything was read from the released v7.3 tag and compared against v7.2, because a pull request records what a maintainer intended to merge and only the tag records what shipped. Where a published changelog and the source disagree, this article follows the source and says so.

What Linux 7.3 shipped, and how to read this

Linux 7.3 is a mainline release with no longterm series behind it. For anyone running a longterm kernel, nothing here applies yet, and the article is a preview of what the next rebase contains. For teams tracking mainline, three items need action rather than reading: the AF_ALG default, the scheduler’s new accounting mode if you run container workloads, and the removals if you inherited an old config fragment.

The items are grouped so you can stop early. New userspace interfaces and the scheduler are the substance of the release. AF_ALG is the compatibility risk. Memory, I/O and filesystems are performance work. Architectures, Rust and removals are narrower. The last section says plainly what was verified and what was not.

One new system call: fchroot()

Linux 7.3 adds exactly one system call. At arch/x86/entry/syscalls/syscall_64.tbl the table ends at 471 in v7.2 and at 472 in v7.3, and the new line reads 472 common fchroot sys_fchroot. The two entries below it, listns at 470 and rseq_slice_yield at 471, were already present in v7.2, so despite the recent run of new syscalls this release contributes one.

The existing chroot() takes a path. That is a problem for any program that has already opened a directory and wants to change root to it, because between the open and the chroot() the path can be replaced. The pattern the kernel has been moving toward for a decade is a file-descriptor variant of each path-based call, which is why openat2(), fsopen(), open_tree(), file_getattr() and now fchroot() exist. A descriptor identifies the object itself, so the race disappears and a sandbox can be assembled from descriptors it already holds.

For container runtimes, service managers and anything that builds a restricted filesystem view, this closes a long-standing gap: a process can now pin a directory, verify it, and change root to that exact object. If you maintain a sandboxing library, this is the one new interface in the release worth adding support for.

failfs, and kernel threads that no longer see your filesystem

Two related additions make the kernel’s own filesystem state less entangled with userspace. The first is failfs, a new pseudo-filesystem whose file is fs/failfs.c, absent at v7.2 and present at v7.3. It presents an empty directory in which every operation fails with EOPNOTSUPP. That sounds useless until you need a filesystem root that is guaranteed to deny everything, which is exactly what you want to hand a context that should not be touching files at all.

The second is that kernel threads now start in nullfs rather than inheriting the filesystem context of whatever created them. fs/nullfs.c already existed at v7.2; the change in 7.3 is where kthreads begin. Before this, a kernel thread could hold a reference to a userspace process’s root and working directory, which kept mounts busy and gave kernel code a filesystem view it had no business having. After it, kthreads start from nothing and must be given a context deliberately.

Neither is an interface you call. Both show up as behaviour: fewer surprising mount references held by kernel threads, and a cleaner answer to “why can this unmount not complete”. If you have ever chased a busy mount down to a kernel worker, this is the release that removes that class of puzzle.

The scheduler gains five cgroup accounting modes

The largest piece of work in 7.3 is in the CPU scheduler, and it is runtime-switchable, which makes it unusually easy to evaluate. The feature is often described as flattening the pick: rather than walking the cgroup hierarchy to choose a task, the scheduler computes group weights differently, and 7.3 makes the computation selectable. The control is a debugfs file created in kernel/sched/debug.c:

raghu@techveda.org:~$ cat /sys/kernel/debug/sched/cgroup_mode
up smp (concur) max tasks

The parentheses mark the active mode, and the file is writable at mode 0644. Here the source and the published changelog disagree, and the source wins. The changelog lists four values; cgroup_mode_str[] in kernel/sched/debug.c holds five, in this order: up, smp, concur, max, tasks. The static initialiser is static int cgroup_mode = 2, which is concur, so concur is the default. Writing a name that is not in the list returns EINVAL.

What each mode changes is which function computes a group’s share. __sched_cgroup_mode_update() in kernel/sched/fair.c switches a static call between calc_up_shares, calc_smp_shares, calc_concur_shares, calc_max_shares and calc_tasks_shares, in that order. Because it is a static call updated at write time, switching modes does not require a reboot or a rebuild, and the whole feature is gated on CONFIG_FAIR_GROUP_SCHED.

If you run containerised workloads under cgroup CPU limits, this is the item in 7.3 to measure, because the default changed how group weight is computed and you can switch it back with one write. That is a rare combination in scheduler work: a behaviour change you can A/B on a live system. Run your own benchmark under concur, then write max or up and run it again. Alongside it, 7.3 carries latency work for tasks with shorter slices, a fix for cluster scheduling on asymmetric-capacity CPUs, and a change to prefer fully idle cores when balancing during NOHZ.

sched_ext grows a scheduler hierarchy

The pluggable scheduler framework moves from one BPF scheduler per system to a hierarchy. Linux 7.3 completes sub-scheduler support with four pieces that fit together: capability-based CPU delegation, so a parent scheduler grants a sub-scheduler revocable control of specific CPUs including enqueue, preemption and frequency decisions; bandwidth-limited rescue execution, so a task stranded by a misbehaving sub-scheduler still runs; core-sched task ordering across a hierarchy; and cgroup migration with operation delivery to the right sub-scheduler.

The reason this matters beyond scheduler research is isolation. A single BPF scheduler is all-or-nothing: a bug in it is a system-wide scheduling bug. Delegation with revocable grants and a rescue path means a faulty sub-scheduler degrades its own cgroup rather than the machine. That is the property a platform team needs before any of this is usable in production, and 7.3 is the release that provides it.

AF_ALG is restricted by default, and the lists are tiny

This is the change most likely to break a system that works today. AF_ALG is the socket interface that lets a userspace program drive the kernel’s own crypto implementations, which is how an application reaches a hardware crypto engine without writing a driver. In 7.3 it is allowlisted by default, controlled by a new sysctl declared in crypto/af_alg.c with a static initialiser of 1 and a permitted range of 0 to 2:

raghu@techveda.org:~$ cat /proc/sys/crypto/af_alg_restrict
1

The kernel documentation states the three levels: 0 is unrestricted, 1 allows a limited list, and 2 refuses to create AF_ALG sockets at all with EAFNOSUPPORT. It also explains the motive, describing AF_ALG as a deprecated and rarely used interface that is a frequent source of vulnerabilities.

The part the release summaries do not convey is how short the lists are. They live in the four protocol files as arrays of struct af_alg_allowlist_entry, each entry commented with the userspace program it exists for. Counted programmatically: the symmetric-cipher list holds fourteen entries, the hash list fourteen. Then:

/* crypto/algif_aead.c, v7.3 */
static const struct af_alg_allowlist_entry aead_allowlist[] = {
        { "ccm(aes)" }, /* bluez */
        {},
};

/* crypto/algif_rng.c, v7.3 */
static const struct af_alg_allowlist_entry rng_allowlist[] = {
        {},
};

One AEAD, and no random-number generators at all: gcm(aes) over AF_ALG is refused on a stock 7.3 kernel, and the AF_ALG RNG interface passes nothing. There is a second tier inside level 1. Each entry carries a flags field with one flag defined, AF_ALG_UNPRIVILEGED; an entry without it is permitted only to a caller passing af_alg_capable(), which is CAP_NET_ADMIN in the initial user namespace or CAP_SYS_ADMIN. Seven of the fourteen cipher entries are unprivileged, and exactly one of the fourteen hash entries is. So cbc(aes), ctr(aes), ecb(aes) and every HMAC need the capability even though they are on the list.

The failure mode is the part to plan around. af_alg_check_restriction() does not return a permission error; the comment in the source says to use ENOENT, the error for “algorithm not found”, instead of EACCES or EPERM, for the highest chance of correctly triggering fallback logic in userspace. Libraries such as libkcapi, and OpenSSL configured for kernel crypto, do exactly that: they fall back to software. Your application keeps producing correct output, your tests keep passing, and the crypto accelerator goes unused. The symptom is a throughput regression after a kernel upgrade with no error anywhere to connect it to the kernel. Check it before you upgrade:

raghu@techveda.org:~$ strace -f -e trace=socket,bind ./your-app 2>&1 | grep -A1 AF_ALG
socket(AF_ALG, SOCK_SEQPACKET, 0)       = 3
bind(3, {sa_family=AF_ALG, salg_type="aead", salg_name="gcm(aes)"}, 88) = -1 ENOENT

Three responses exist. Move the work to a userspace crypto library, which is what upstream intends. Set the sysctl to 0, which is legitimate as a deliberate, documented setting but keeps an interface upstream calls an attack surface. Or grant the capability, which helps only for algorithms on the list at all. The constructive half of the same work is a set of in-kernel AES library APIs covering ECB, CBC, CTR, XCTR, XTS, GCM and CCM, which is where kernel-side AES users are being pointed.

Memory and I/O: read-write protection, uncached reads, zero-copy FUSE

The memory-management headline is an extension of userfaultfd. It has long supported write protection, where a handler is notified on writes to a registered range. Linux 7.3 adds read-write protection through a new registration mode, UFFDIO_REGISTER_MODE_RWP, which appears in include/uapi/linux/userfaultfd.h at v7.3 and not at v7.2. Trapping reads as well as writes is what live migration, checkpoint and restore, and userspace-managed memory tiering need in order to know a page was touched at all rather than only modified.

On the block side, RWF_DONTCACHE now works on block devices, not just files. It asks for I/O that does not leave its data in the page cache, which matters for anything streaming a volume once: an imaging tool, a backup, a checksum pass over a whole disk. Without it, a single sequential read of a large device evicts everything else the system cared about.

FUSE gains io_uring buffer pools and a zero-copy path, continuing the work that has been closing the gap between FUSE filesystems and in-kernel ones. io_uring itself gains improvements to its zero-copy receive path and dynamic memory provisioning, and the iomap layer adds a simplified direct-I/O path for small requests plus an in-iterator iomap_next() model. The common thread across all four is per-operation overhead on small I/O, which is where FUSE and direct I/O have historically lost.

Two smaller items with outsized reach: the VDSO data store can now be prefaulted via mlockall(), which removes a first-call fault from latency-sensitive programs, and expedited RCU grace periods now also expedite normal RCU callbacks.

Filesystems: Btrfs, F2FS and a notably busy SMB server

Btrfs takes the largest set of changes. The one to note before upgrading is that the version 1 free-space cache is disabled by default; version 2 has been the mkfs default for some time and v1 filesystems still mount, so the consequence is a possible small performance difference rather than a failure. An image built with an old mkfs and never converted is the case to measure. The rest is performance: direct I/O through an iomap bounce buffer, a removed one-jiffy delay in non-SSD logging mode, full fsync skipping hole detection for files without holes, reduced locking around extent readahead, NOWAIT semantics for extent-buffer allocation, and a local LRU list replacing the xarray for inhibited extent buffers. Two capability changes also land: block sizes up to the page size, and single-data RAID56 now presented as RAID1 or RAID1C3.

F2FS, which matters wherever flash is managed in software, gains a resizable tail section with unified pinned allocation, less time spent in interrupt context, parallel flushes across multiple devices, dynamic reserve and release for device aliasing, and a smaller inode-number management footprint.

The surprise of the release is how much landed in the SMB server. ksmbd gains opt-in Apple Time Machine support, per-share SMB3 encryption, SMB Direct RDMA encryption, an SMB2 command sequence window, SMB3 request replay, empty snapshot enumeration, file compression attributes, file-level trim, a copy fallback for duplicate extents, and procfs monitoring of active shares. Overlayfs adds idmapped overlay mounts. Elsewhere, the cachefiles on-demand mode is being sunset.

Architectures, and the parts embedded teams must check

RISC-V takes the largest architecture addition, and here the published count needs correcting. Comparing arch/riscv/include/asm/hwcap.h between the two tags shows ten new extension identifiers, not the eleven the pull request described: Smcsrind and Sscsrind for indirect CSR access, Smcntrpmf, Ssccfg and Smcdeleg for counter delegation, the profile guarantees Zicclsm, Ziccamoa, Ziccif and Za64rs, and Ssqosid for quality-of-service tagging. Ziccrse already had its identifier at v7.2, and the eleventh new macro is RISCV_ISA_EXT_SxCSRIND, an alias rather than an extension. Ssqosid also brings a new file, arch/riscv/kernel/qos.c, so QoS identifiers are swapped on context switch, which is what makes cache and bandwidth partitioning usable for mixed workloads.

The same header carries a change that breaks code rather than enabling it. The nine base-extension macros were lower case through v7.2 and are upper case at v7.3: RISCV_ISA_EXT_a through _v are replaced by RISCV_ISA_EXT_A through RISCV_ISA_EXT_V. In-tree callers were converted with it; out-of-tree code was not, so any driver testing for the vector or compressed extension by macro name fails to compile with an undeclared-identifier error.

On 32-bit Arm, big-endian is now deprecated in a form that bites at configure time. In arch/arm/mm/Kconfig the symbol is retitled "Build big-endian kernel (DEPRECATED)" and gains depends on ARCH_MULTI_V5 || BROKEN, where v7.2 had no such dependency. ARMv5 still configures, the one case the dependency admits. For ARMv6 and ARMv7, which is every modern 32-bit Arm product, the symbol becomes unselectable rather than erroring, so the option quietly disappears from the resulting config and the kernel builds little-endian. arm64 big-endian has been broken since 6.18 with removal queued; arm32 is on the same path.

Three more items land squarely on embedded work. UBI gains a per-device wear-levelling threshold as the seventh field of the ubi.mtd attach parameter, range 2 to 65536, with 0 falling back to CONFIG_MTD_UBI_WL_THRESHOLD and its default of 4096 โ€” so a product with two flash parts of different endurance can finally tune them separately without a patch:

raghu@techveda.org:~$ cat /proc/cmdline
... ubi.mtd=/dev/mtd0,0,0,0,0,0,256 ubi.mtd=/dev/mtd1,0,0,0,0,0,4096

Syscall user dispatch becomes configurable, with a new CONFIG_SYSCALL_USER_DISPATCH in arch/Kconfig and a kernel.syscall_user_dispatch sysctl, so the mechanism can be compiled out or switched off rather than being unconditional. And the VDSO now gates its 32-bit legacy time entry points on CONFIG_COMPAT_32BIT_TIME, enforced by BUILD_BUG_ON, which tidies up a corner that matters to anyone turning that symbol off for image size or 2038 hygiene. Bootconfig can embed kernel.* command-line arguments at build time, software nodes support fw_devlink, and EFI runtime service calls now wait with a bound instead of indefinitely.

The Rust-for-Linux work in 7.3 is infrastructure rather than drivers. Netlink support lands and is used by rust_binder, which also gains a dynamic debug logging mask. Abstractions arrive for fwctl, for refcounted interrupts and spinlock-with-interrupts, and for SRCU.

Netlink is the interesting one. It is how most modern kernel interfaces talk to userspace, so a Rust driver that could not speak netlink could not expose a normal control plane. With abstractions for interrupts, SRCU and now netlink, the set of drivers that can plausibly be written in Rust widens from leaf devices to things that need to publish state and take configuration.

What Linux 7.3 removed

Four subsystems are gone, confirmed present at v7.2 and absent at v7.3 by checking each path directly: fs/freevxfs, the Veritas filesystem; fs/efs, the SGI IRIX filesystem; the SGI XP and GRU drivers under drivers/misc/sgi-xp; and the IPWireless driver under drivers/tty/ipwireless. The cachefiles on-demand mode is being sunset, 32-bit Arm big-endian is deprecated as described above, and the Btrfs v1 free-space cache is off by default.

None of these is likely to be in a current config, but an inherited config fragment that enables one now names a symbol that does not exist, which is either a silent no-op or a hard error depending on your build system. One addition cuts the other way: a new Moxa PCIe serial driver, SERIAL_8250_MOXA_PCIE, carries default SERIAL_8250, so it is enabled wherever the 8250 driver is.

Who should care, and about what

Most of a release does not apply to most readers. This is the mapping.

If you work onRead this part of 7.3
Container platforms, orchestration/sys/kernel/debug/sched/cgroup_mode and its five modes. Benchmark under concur, then switch and repeat.
Anything using kernel crypto from userspaceThe AF_ALG default. Test your actual algorithm before upgrading; expect a silent software fallback, not an error.
Sandboxes, runtimes, service managersfchroot(), failfs, and kthreads starting in nullfs.
Live migration, checkpoint/restore, memory tieringUFFDIO_REGISTER_MODE_RWP.
Storage and filesystem workBtrfs v1 free-space default, block sizes up to page size, RWF_DONTCACHE on block devices, the iomap and FUSE paths.
File serversThe ksmbd batch: per-share SMB3 encryption, SMB Direct RDMA encryption, Time Machine support.
Embedded Linux and BSPAF_ALG, the UBI threshold, arm32 big-endian, and the removals.
RISC-V platformsThe ten new extensions, Ssqosid context switching, and the macro rename if you carry out-of-tree code.
Scheduler and RT researchsched_ext sub-schedulers, the shorter-slice latency work, the asymmetric-capacity cluster fix.

If your product has a multi-year support window, none of this is a migration target yet: 7.3 is mainline with no longterm series behind it, and the usual course is to wait for the next longterm release and use 7.3 to find out what that will contain. Teams that want release triage covered as a practice, alongside kernel configuration and BSP maintenance, will find it in our training tracks.

What was checked, and what was not

The release date comes from the kernel.org release data, which reports 7.3 as latest stable with a date of 18 October 2026. Every claim about a symbol, file, sysctl, syscall number or Kconfig dependency was read from the released v7.3 tag and compared against v7.2, and removals were confirmed by HTTP status on each path rather than inferred from a failed fetch โ€” one transient fetch failure during this work produced a false absence, which is worth knowing if you verify the same way.

Two published-changelog errors were corrected against the source and are flagged where they appear: the scheduler has five cgroup modes, not four, with concur as the default, and RISC-V gained ten extension identifiers, not eleven. Items in the filesystem, SMB, F2FS, io_uring and Rust sections are reported from the published changelog without independent source verification of each one, because verifying sixty changes individually was out of scope; the interfaces named in the headline sections were all verified directly. Nothing was built or booted, so the AF_ALG behaviour is read from the allowlists, the capability helper and the documentation rather than observed, and the strace listing shows the expected form of the failure rather than a capture from a running system.

Key takeaways

  • Linux 7.3 released 18 October 2026, mainline only, with no longterm series behind it.
  • One new system call, fchroot() at number 472, giving a descriptor-based alternative to chroot().
  • The scheduler has five selectable cgroup accounting modes at /sys/kernel/debug/sched/cgroup_mode, default concur. Switchable at runtime, so it can be A/B tested.
  • AF_ALG is allowlisted by default. The AEAD list holds only ccm(aes) and the RNG list is empty, so gcm(aes) and AF_ALG random-number use are refused, and most listed ciphers need a capability.
  • That refusal is ENOENT by design, so libraries fall back to software silently and the symptom is a throughput regression with no error.
  • userfaultfd adds read-write protection via UFFDIO_REGISTER_MODE_RWP; RWF_DONTCACHE now works on block devices.
  • Four subsystems removed: freevxfs, efs, SGI XP, IPWireless. 32-bit Arm big-endian deprecated and effectively unselectable on ARMv6 and ARMv7.
Was this worth your time?

Frequently asked questions

What is the single most important change in Linux 7.3?
For a system that works today, the AF_ALG restriction, because it changes a default and can break working userspace. For new capability, the scheduler’s five selectable cgroup accounting modes and the new fchroot() system call.

Will upgrading to Linux 7.3 break anything?
It can, in one well-defined way: if userspace uses AF_ALG for an algorithm that is no longer allowed, or without the required capability, the bind fails with ENOENT and most libraries quietly fall back to software crypto. Test your own algorithm before upgrading rather than relying on a list.

How do I try the new scheduler modes?
Read /sys/kernel/debug/sched/cgroup_mode, which prints all five names with the active one in parentheses, and write one of up, smp, concur, max or tasks to change it. It takes effect immediately, needs CONFIG_FAIR_GROUP_SCHED, and an unrecognised name returns EINVAL.

Should my product move to Linux 7.3?
Only if you already track mainline. There is no longterm series behind 7.3, so a product with a multi-year support window normally waits for the next longterm release and reads 7.3 to learn what that will contain.

References

RB
Raghu Bharadwaj

Founder, TECH VEDA โ€” 20+ years teaching the Linux kernel, device drivers and embedded systems.

Follow on LinkedIn

Get new posts by email

Kernel, embedded Linux and AI-era engineering โ€” a few sharp reads a month. No spam.

We email occasionally and never share your address.