summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2026-06-05batman-adv: use GFP_KERNEL allocations for the wifi detection cacheSven Eckelmann
The batadv_wifi_net_device_insert() is called with ASSERT_RTNL() held, but not inside a spinlock or another context which prevents "might_sleep" functions. To relax the requirements for the allocator, use GFP_KERNEL. Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-06-05batman-adv: drop duplicated wifi_flags assignmentsSven Eckelmann
During the initialization of the batadv_wifi_net_device_state, it is enough to write the wifi_flags once before the batadv_wifi_net_device_state is added to the batadv_wifi_net_devices rhashtable. Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-06-05batman-adv: convert cancellation of work items to disable helperSven Eckelmann
With commit 86898fa6b8cd ("workqueue: Implement disable/enable for (delayed) work items"), work queues gained the ability to permanently disallow re-queuing of work items. This is particularly important during object teardown, where a work item must not be re-armed after shutdown begins. Convert all cancel_work_sync() and cancel_delayed_work_sync() call sites to their disable_* equivalents to clarify the intent to prevent re-arming after teardown. Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-06-05batman-adv: tp_meter: initialize last_recv_time during initSven Eckelmann
The last_recv_time is the most important indicator for a receiver session to figure out whether a session timed out or not. But this information was only initialized after the session was added to the tp_receiver_list and after the timer was started. In the worst case, the timer (function) could have tried to access this information before the actual initialization was reached. Like rest of the variables of the tp_meter receiver session, this field has to be filled out before any other (parallel running) context has the chance to access it. Cc: stable@kernel.org Fixes: 33a3bb4a3345 ("batman-adv: throughput meter implementation") Signed-off-by: Sven Eckelmann <sven@narfation.org>
2026-06-05simple_lookup(): use d_splice_alias() for ->lookup() return valueAl Viro
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05ecryptfs: use d_splice_alias() for ->lookup() return valueAl Viro
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05configfs_lookup(): switch to d_splice_alias()Al Viro
more idiomatic Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05tracefs: use d_splice_alias() in ->lookup() instancesAl Viro
d_add() is not wrong there (inodes are freshly allocated), but d_splice_alias() is more idiomatic. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05make cursors NORCUAl Viro
All it requires is making sure that d_walk() will skip *all* CURSOR dentries, even if somebody passes it one as an argument. Cursors are negative and unhashed all along, never get added to LRU or to shrink lists and no RCU references via ->d_sib are possible for those - dentry_unlist() makes sure that no killed dentry has ->d_sib.next left pointing to a cursor. Seeing that a cursor is allocated every time we open a directory on autofs, debugfs, devpts, etc., avoiding an RCU delay when such opened files get closed is attractive... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05nfs: get rid of fake root dentriesAl Viro
... just grab the reference to the (real) root we are about to return for the first mount of this superblock and be done with that. Once upon a time dentry tree eviction at fs shutdown used to break if ->s_root had been spliced on top of something; that hadn't been the case for years now, and these fake root dentries violate a bunch of invariants. Let's get rid of them... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05wind ->s_roots via ->d_sib instead of ->d_hashAl Viro
shrink_dcache_for_umount() is supposed to handle the possibility of some of the dentries to be evicted being in other threads shrink lists; it either kills them, leaving an empty husk to be freed by the owner of shrink list whenever it gets around to that, or it waits for the eviction in progress to get completed. That relies upon dentry remaining attached to the tree until the eviction reaches dentry_unlist() and its ->d_sib gets removed from the list. Unfortunately, the secondary roots are linked via ->d_hash, rather than ->d_sib and they become removed from that list before their inode references are dropped. If shrink_dentry_list() from another thread ends up evicting one of the secondary roots and gets to that point in dentry_kill() when shrink_dcache_for_umount() is looking for secondary roots, the latter will *not* notice anything, possibly leading to warnings about busy inodes at umount time and all kinds of breakage after that. Moreover, shrink_dcache_for_umount() walks the list of secondary roots with no protection whatsoever, so it might end up calling dget() on a dentry that already passed through lockref_mark_dead(&dentry->d_lockref); ending up with corrupted refcount and possible UAF. AFAICS, the most straightforward way to deal with that would be to have secondary roots linked via ->d_sib rather than ->d_hash; then they would remain on the list until killed, and we could use d_add_waiter() machinery to wait for eviction in progress. Changes: * secondary roots look the same as ->s_root from d_unhashed() and d_unlinked() POV now. * secondary roots are represented as "no parent, but on ->d_sib" instead of "no parent, but on ->d_hash". * since ->d_sib is a plain hlist, we protect it with per-superblock spinlock (sb->s_roots_lock) instead of the LSB of the head pointer (for non-root dentries it would be protected by ->d_lock of parent). * __d_obtain_alias() uses ->d_sib for linkage when allocating a secondary root. * d_splice_alias_ops() detects splicing of a secondary root and removes it from the list before calling __d_move(). * dentry_unlist() detects eviction of a secondary root and removes it from the list; no need to play the games for d_walk() sake, since the latter is not going to look for the next sibling of those anyway. * ___d_drop() doesn't care about ->s_roots anymore. * shrink_dcache_for_umount() uses proper locking for access to the list of secondary roots and if it runs into one that is in the middle of eviction waits for that to finish. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05shrink_dentry_tree(): unify the calls of shrink_dentry_list()Al Viro
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05shrinking rcu_read_lock() scope in d_alloc_parallel()Al Viro
The current use of rcu_read_lock() uses in d_alloc_parallel() is fairly opaque - the single large scope serves two purposes. We start with lookup in normal hash, and there rcu_read_lock() scope puts __d_lookup_rcu() and subsequent lockref_get_not_dead() into the same RCU read-side critical area. If no match is found, we proceed to lock the hash chain of in-lookup hash and scan that for a match. If we find a match, we want to grab it and wait for lookup in progress to finish. Since the bitlock we use for these hash chains has to nest inside ->d_lock, we need to unlock the chain first and use lockref_get_not_dead() on the match. That has to be done without breaking the RCU read-side critical area, and we use the same rcu_read_lock() scope to bridge over. The thing is, after having grabbed the reference (and it is very unlikely to fail) we proceed to grab ->d_lock - d_wait_lookup() and __d_lookup_unhash()/__d_wake_in_lookup_waiters() are using that for serialization. That makes lockref_get_not_dead() pointless - trying to avoid grabbing ->d_lock for refcount increment, only to grab it anyway immediately after that. If we grab ->d_lock first and replace lockref_get_not_dead() with direct check for sign and increment if non-negative we can move rcu_read_unlock() to immediately after grabbing ->d_lock. Moreover, we don't need the RCU read-side critical area to be contiguous since before earlier __d_lookup_rcu() - we can just as well terminate the earlier one ASAP and call rcu_read_lock() again only after having found a match (if any) in the in-lookup hash chain. That makes the entire thing easier to follow and the purpose of those rcu_read_lock() calls easier to describe - the first scope is for __d_lookup_rcu() + lockref_get_not_dead(), the second one bridges over from the bitlock scope to the ->d_lock scope on the match found in in-lookup hash. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05d_walk(): shrink rcu_read_lock() scopeAl Viro
we only need it to bridge over from ->d_lock scope of child to ->d_lock scope of parent; dropping ->d_lock at rename_retry doesn't need to be in rcu_read_lock() scope. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05document dentry_kill()Al Viro
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05adjust calling conventions of lock_for_kill(), fold __dentry_kill() into ↵Al Viro
dentry_kill() Pull dropping ->d_lock on lock_for_kill() failure into lock_for_kill() itself. That reduces dentry_kill() to if (!lock_for_kill(dentry)) return NULL; return __dentry_kill(dentry); at which point it's easier to move that if (...) into the beginning of __dentry_kill() itself and rename it into dentry_kill(). Document the new calling conventions of lock_for_kill(). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05Document rcu_read_lock() use in select_collect2()Al Viro
If select_collect2() finds something that is neither busy nor can be moved to shrink list, it needs to return that to caller's caller (shrink_dcache_tree()) ASAP and do so without grabbing references (among other things, it might be already dying, in which case refcount can't be incremented). We are called inside a ->d_lock scope, but that scope is going to be terminated as soon as we return to caller (d_walk()); ->d_lock will be retaken by shrink_dcache_tree(), but we need to bridge between these scopes, turning them into contiguous RCU read-side critical area. We do that with rcu_read_lock() scope - it spans from unbalanced rcu_read_lock() in select_collect2() to unbalanced rcu_read_unlock() in shrink_dcache_tree(). That works, but it really needs to be documented; it's rather unidiomatic and it had caused quite a bit of confusion - some of it in form of patches "fixing" the damn thing. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05Shift rcu_read_{,un}lock() inside fast_dput()Al Viro
Shrink rcu_read_lock() scopes surrounding fast_dput() calls. Both callers are immediately preceded and followed by rcu_read_lock()/rcu_read_unlock() resp. Shrink that down into fast_dput() itself; in case when fast_dput() ends up grabbing ->d_lock, we can pull rcu_read_unlock() up to right after spin_lock(). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05simplify safety for lock_for_kill() slowpathAl Viro
rcu_read_lock() scopes in dentry eviction machinery are too wide and badly structured; we end up with too many of those, quite a few essentially identical. Worse, quite a few of the function involved are not neutral wrt that, making them harder to reason about. rcu_read_lock() scope is not the only thing establishing an RCU read-side critical area - spin_lock scope does the same and they can be mixed - the sequence rcu_read_lock() ... spin_lock() ... rcu_read_unlock() ... rcu_read_lock() ... spun_unlock() ... rcu_read_unlock() is an unbroken RCU read-side critical area. Use of that observation allows to simplify things. First of all, lock_for_kill() relies upon being in an unbroken RCU read-side critical area. It's always called with ->d_lock held, and normally returns without having ever dropped that spinlock. We would not need rcu_read_lock() at all, if not for the slow path - if trylock of inode->i_lock fails, we need to drop and retake ->d_lock. Having all calls of lock_for_kill() inside an rcu_read_lock() scope takes care of that, but to show that lock_for_kill() slow path is safe, we need to demonstrate such rcu_read_lock() scope for any call chain leading to lock_for_kill(). Which is not fun, seeing that there are 10 such scopes, with 5 distinct beginnings between them. Case 1: opens in dput() proceeds through fast_dput() grabbing ->d_lock, returning false into dput() and there a call of finish_dput() which calls dentry_kill(), which calls lock_for_kill(); ends in dentry_kill(), either right after lock_for_kill() success or right after dropping ->d_lock on lock_for_kill() failure. ->d_lock is held continuously all the way into lock_for_kill(). Case 2: opens in dentry_kill(), where we proceed to the same call of dentry_kill() as in case 1. ->d_lock is held since before the beginning of the scope and all the way into lock_for_kill(). Case 3: opens in select_collect2(), proceeds through the return to d_walk() and to shrink_dcache_tree() where we grab ->d_lock and proceed to call shrink_kill(), which calls dentry_kill(), then as in the previous scopes. Case 4: opens in shrink_dentry_list(), followed by call of shrink_kill(), then same as in case 3. ->d_lock is held since before the beginning of the scope and all the way into lock_for_kill(). Case 5: opens in shrink_kill(), where it's immediately followed by call of dentry_kill(), then same as in the previous scopes. ->d_lock is held since before the beginning of the scope all the way into lock_for_kill(). Note that in cases 2, 4 and 5 the slow path of lock_for_kill() is the only part of rcu_read_lock() scope that is not covered by spinlock scopes. In case 1 we have the area in fast_dput() as well and in case 3 - the return path from select_collect2() and chunk in shrink_dcache_tree() up to grabbing ->d_lock. Seeing that the reasons we need rcu_read_lock() in these additional areas are completely unrelated to lock_for_kill() slow path, the things get much more straightforward with * explicit rcu_read_lock() scope surrounding the area in slow path of lock_for_kill() where ->d_lock is not held * shrink_dentry_list() dropping rcu_read_lock() as soon as it has grabbed ->d_lock. * dput() dropping rcu_read_lock() just before calling finish_dput(). * rcu_read_lock() calls in finish_dput(), shrink_kill() and shrink_dentry_list() are removed, along with rcu_read_unlock() calls in dentry_kill(). RCU read-side critical areas are unchanged by that, safety of lock_for_kill() slow path is trivial to verify and a bunch of rcu_read_lock() scopes either gone or become easier to describe. Update the comments on locking conventions and memory safety considerations, including the NORCU case. Incidentally, all calls of fast_dput() are immediately preceded by rcu_read_lock() and followed by rcu_read_unlock() now, which will allow to simplify those on the next step... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05fold lock_for_kill() and __dentry_kill() into common helperAl Viro
There are two callers of lock_for_kill() and both are followed by the same sequence of actions: * in case of failure, drop ->d_lock, do rcu_read_unlock() and go away * in case of success, do rcu_read_unlock() followed by passing dentry to __dentry_kill(); if the latter returns NULL, go away. All calls of __dentry_kill() are paired with lock_for_kill() now; let's turn that sequence into a new helper (dentry_kill()) and switch to using it. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05fold lock_for_kill() into shrink_kill()Al Viro
Both callers have exact same shape. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05shrink_dentry_list(): start with removing from shrink listAl Viro
Currently we leave dentry on the list until we are done with lock_for_kill(). That guarantees that it won't have been even scheduled for removal until we remove it from the list and drop ->d_lock. We grab ->d_lock and rcu_read_lock() and call lock_for_kill(). There are four possible cases: 1) lock_for_kill() has succeeded; dentry and its inode (if any) are locked, dentry refcount is zero and we can remove it from shrink list and feed it to shrink_kill(). 2) lock_for_kill() fails since dentry has become busy. Nothing to do, rcu_read_unlock(), remove from shrink list, drop ->d_lock and move on. 3) lock_for_kill() fails since dentry is currently being killed - already entered __dentry_kill(), but hasn't reached dentry_unlist() yet. Nothing to do, we should just do rcu_read_unlock(), remove from shrink list so that whoever's executing __dentry_kill() would free it once they are done, drop ->d_lock and move on - same actions as in case (2). 4) lock_for_kill() fails since dentry has been killed (reached dentry_unlist(), DCACHE_DENTRY_KILLED set in ->d_flags). In that case whoever had been killing it had already seen it on our shrink list and skipped freeing it. At that point it's just a passive chunk of memory; rcu_read_unlock(), remove from the list, drop ->d_lock and use dentry_free() to schedule freeing. While that works, there's a simpler way to do it: * grab ->d_lock * remove dentry from our shrink list * if DCACHE_DENTRY_KILLED is already set, drop ->d_lock, call dentry_free() and move on. * otherwise grab rcu_read_lock() and call lock_for_free() * if lock_for_kill() succeeds, feed dentry to shrink_kill(), otherwise drop the locks and move on. The end result is equivalent to the old variant. The only difference arises if at the time we grab ->d_lock dentry had refcount 0 and lock_for_kill() had failed spin_trylock() and had to drop and regain ->d_lock. Otherwise nobody can observe at which point within the unbroken ->d_lock scope dentry had been removed from the shrink list - all accesses to ->d_lru are under ->d_lock. If ->d_lock had been dropped and regained, it is possible for another thread to feed that dentry to __dentry_kill(); if it doesn't get to dentry_unlist() before we regain ->d_lock, behaviour is still identical - it's case (3) and by the time __dentry_kill() would've gotten around to checking if the victim is on shrink list, it would've been already removed from ours. If __dentry_kill() from another thread *does* get to dentry_unlist(), in the old variant we would have __dentry_kill() leave calling dentry_free() to us and in the new one __dentry_kill() would've called dentry_free() itself. Since we are under rcu_read_lock(), we are guaranteed that actual freeing won't happen until we get around to rcu_read_unlock(). IOW, the new variant is still safe wrt UAF, if not for the same reason as the old one, and overall result is the same; the only difference is which threads ends up scheduling the actual freeing of dentry. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05d_prune_aliases(): make sure to skip NORCU aliasesAl Viro
Either they are busy (in which case they won't be moved to shrink list anyway) or they have a zero refcount, in which case we really shouldn't mess with them - whoever had dropped the refcount to zero is on the way to evicting and freeing them. That way we are guaranteed that only the thread that has dropped refcount of NORCU dentry to zero might call lock_for_kill() and __dentry_kill() for those. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05kill d_dispose_if_unused()Al Viro
Rename to_shrink_list() into __move_to_shrink_list(), document and export it. Switch d_dispose_if_unused() users to that and kill d_dispose_if_unused() itself. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05make to_shrink_list() return whether it has moved dentry to listAl Viro
... and make it check the refcount for being zero in addition to dentry not being on a shrink list already. Simplifies the callers... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05select_collect(): ignore dentries on shrink lists if they have positive ↵Al Viro
refcounts If all dentries we find have positive refcounts and some happen to be on shrink lists, there's no point trying to steal them in the select_collect2() phase - we won't be able to evict any of them. Busy on shrink lists is still busy... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05find_acceptable_alias(): skip NORCU aliases with zero refcountAl Viro
similar to d_find_any_alias() situation Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05fix a race between d_find_any_alias() and final dput() of NORCU dentriesAl Viro
Refcount of a NORCU dentry must not be incremented after having dropped to zero. Otherwise we might end up with the following race: CPU1: in fast_dput(d), rcu_read_lock(); CPU1: decrements refcount of d to 0 CPU1: notice that it's unhashed CPU2: grab a reference to d CPU2: dput(d), freeing d CPU1: ... looks like we need to evict d, let's grab ->d_lock, recheck the refcount, etc. and that spin_lock(&d->d_lock) ends up a UAF, despite still being in an RCU read-side critical area started back when the refcount had been positive. If not for DCACHE_NORCU in d->d_flags freeing would've been RCU-delayed, so we'd have grabbed ->d_lock, noticed the negative value stored into refcount by __dentry_kill(), dropped the locks and that would be it. For NORCU dentries freeing is _not_ delayed, though. Most of the non-counting references are excluded for NORCU dentries - they are not allowed to be hashed, they never get placed on LRU, they never get placed into anyone's list of children and while dput_to_list() might put them into a shrink list, nobody bumps refcount of something that had been reached that way. However, inode's list of aliases can be a problem - it does not contribute to dentry refcount (for obvious reasons) and we *do* have places that grab references to something found on that list - that's precisely what d_find_alias() is. In case of d_find_alias() we are safe - it skips unhashed aliases, so all NORCU ones are ignored there. d_find_any_alias() is *not* limited to hashed ones, though, and while it's usually called for directories (which never get NORCU dentries), there are callers that use it to get something for non-directories with no hashed aliases. Having d_find_any_alias() hit a NORCU dentry is not impossible - it can be easily arranged if you have CAP_DAC_READ_SEARCH (memfd_create() + mmap() + name_to_handle_at() for /proc/self/map_files/<...> + munmap() + open_by_handle_at() will do that, and adding a second memfd_create() for mount_fd makes it possible to do that without having memfd pinned). The race window is narrow, and it's probably not feasible on bare hardware, but... It's not hard to fix, fortunately: * separate __d_find_dir_alias() (== current __d_find_any_alias()) to be used for directory inodes. * provide dget_alias_ilocked() that would return false for NORCU dentries with zero refcount and return true incrementing refcount otherwise * make __d_find_any_alias() go over the list of aliases, using dget_alias_ilocked() and returning the alias it succeeds on (normally the first one). Any NORCU alias with zero refcount is going to be evicted by the thread that had dropped the final reference; this makes __d_find_any_alias() pretend it had lost the race with eviction. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05alloc_path_pseudo(): make sure we don't end up with NORCU dentries for ↵Al Viro
directories A lot of places relies upon directories never having NORCU dentries; currently that property holds, but the proof is not straightforward and rather brittle. It's better to have that verified in the sole caller of d_alloc_pseudo(), so that any future bugs in that direction were caught early. That way we can be sure that * current directory of any process is not NORCU * root directory of any process is not NORCU * starting point of any LOOKUP_RCU pathwalk is not NORCU * dget_parent() can rely upon ->d_parent not being NORCU * d_walk() and is_subdir() can rely upon the same * alloc_file_pseudo() won't create multiple aliases for a directory without having to go through a convoluted audit. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-05VFS: use wait_var_event for waiting in d_alloc_parallel()NeilBrown
Parallel lookup starts with a call of d_alloc_parallel(). That primitive either returns a matching hashed dentry or allocates a new one in the in-lookup state and returns it to the caller. Once the caller is done with lookup, it indicates so either by call of d_{splice_alias,add}() or by call of d_done_lookup(); at that point dentry leaves the in-lookup state. If d_alloc_parallel() finds a matching in-lookup dentry, it must wait for that dentry to leave the in-lookup state, one way or another. Currently by supplying wait_queue_head to d_alloc_parallel(). If d_alloc_parallel() creates a new in-lookup dentry, the address of that wait_queue_head is stored in ->d_wait of new dentry and stays there while it's in the in-lookup; subsequent d_alloc_parallel() will wait on the queue found in the matching in-lookup dentry. Transition out of in-lookup state wakes waiters on that queue (if any). That works, but the calling conventions are inconvenient - the caller must supply wait_queue_head and make sure that it survives at least until the new in-lookup dentry leaves the in-lookup state. That amounts to boilerplate in the d_alloc_parallel() callers that are followed by a call of d_lookup_done() in the same function; in cases like nfs asynchronous unlink it gets worse than that. This patch changes d_alloc_parallel() to use wake_up_var_locked() to wake up waiters, and wait_var_event_spinlock() to wait. dentry->d_lock is used for synchronisation as it is already held and the relevant times. That eliminates the need of caller-supplied wait_queue_head, simplifying the calling conventions. Better yet, we only need one bit of information stored in dentry itself: whether there are any waiters to be woken up, and that can be easily stored in ->d_flags; ->d_wait goes away. The reason we need that bit (DCACHE_LOOKUP_WAITERS) is that with wait_var machinery the queues are shared with all kinds of stuff and there's no way tell if any of the waiters have anything to do with our dentry; most of the time none of them will be relevant, so we need to avoid the pointless wakeups. Another benefit of the new scheme comes from the fact that wakeups have to be done outside of write-side critical areas of ->i_dir_seq; with the old scheme we need to carry the value picked from ->d_wait from __d_lookup_unhash() to the place where we actually wake the waiters up. Now we can just leave DCACHE_LOOKUP_WAITERS in ->d_flags until we get to doing wakeups - that's done within the same ->d_lock scope, so we are fine; new bit is accessed only under ->d_lock and it's seen only on dentries with DCACHE_PAR_LOOKUP in ->d_flags. __d_lookup_unhash() no longer needs to re-init ->d_lru. That was previously shared (in a union) with ->d_wait but ->d_wait is now gone so it no longer corrupts ->d_lru. Co-developed-by: Al Viro <viro@zeniv.linux.org.uk> # saner handling of flags Signed-off-by: NeilBrown <neil@brown.name> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2026-06-04accel/ethosu: fix OOB write in ethosu_gem_cmdstream_copy_and_validate()Muhammad Bilal
The command stream parsing loop increments the index variable a second time when a 64-bit command word is encountered (bit 14 set), but does not re-check the loop bound before writing the second word: for (i = 0; i < size / 4; i++) { bocmds[i] = cmds[0]; if (cmd & 0x4000) { i++; bocmds[i] = cmds[1]; /* unchecked */ } } The buffer bocmds is backed by a DMA allocation of exactly size bytes from drm_gem_dma_create(ddev, size), giving valid indices [0, size/4-1]. When i == size/4 - 1 on entry to an iteration and bit 14 of cmds[0] is set, bocmds[size/4-1] is written in bounds, i is then incremented to size/4, and bocmds[size/4] writes four bytes past the end of the allocation. Userspace controls both the buffer contents and the size argument via the ioctl, making this a userspace-triggerable heap out-of-bounds write. Fix by checking the incremented index against the buffer bound before the second write and returning -EINVAL if the buffer is too small to contain the extended command. Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver") Cc: stable@vger.kernel.org Signed-off-by: Muhammad Bilal <meatuni001@gmail.com> Link: https://patch.msgid.link/20260523190843.33977-1-meatuni001@gmail.com Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
2026-06-04Merge tag 'batadv-next-pullrequest-20260603' of https://git.open-mesh.org/batadvJakub Kicinski
Simon Wunderlich says: ==================== This cleanup patchset includes the following patches, all by Sven Eckelmann: - tp_meter: fix various minor issues (8 patches) - tp_meter: split generic session type in sender and receiver type - tp_meter: consolidate locking for congestion control (2 patches) - bla: annotate lasttime access with READ/WRITE_ONCE - elp: prevent transmission interval underflow - tt: sync local and global tvlv preparation return values - tt: directly retrieve wifi flags of net_device * tag 'batadv-next-pullrequest-20260603' of https://git.open-mesh.org/batadv: batman-adv: tt: directly retrieve wifi flags of net_device batman-adv: tt: sync local and global tvlv preparation return values batman-adv: prevent ELP transmission interval underflow batman-adv: bla: annotate lasttime access with READ/WRITE_ONCE batman-adv: tp_meter: consolidate congestion control variables batman-adv: tp_meter: use locking for all congestion control variables batman-adv: tp_meter: split vars into sender and receiver types batman-adv: tp_meter: add only finished tp_vars to lists batman-adv: tp_meter: handle seqno wrap-around for fast recovery detection batman-adv: tp_meter: fix fast recovery precondition batman-adv: tp_meter: avoid divide-by-zero for dec_cwnd batman-adv: tp_meter: avoid window underflow batman-adv: tp_meter: initialize dec_cwnd explicitly batman-adv: tp_meter: initialize dup_acks explicitly batman-adv: tp_meter: keep unacked list in ascending ordered ==================== Link: https://patch.msgid.link/20260603072527.174487-1-sw@simonwunderlich.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-04net: mv643xx: fix OF node refcountBartosz Golaszewski
Platform devices created with platform_device_alloc() call platform_device_release() when the last reference to the device's kobject is dropped. This function calls of_node_put() unconditionally. This works fine for devices created with platform_device_register_full() but users of the split approach (platform_device_alloc() + platform_device_add()) must bump the reference of the of_node they assign manually. Add the missing call to of_node_get(). Cc: stable@vger.kernel.org Fixes: 76723bca2802 ("net: mv643xx_eth: add DT parsing support") Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com> Link: https://patch.msgid.link/20260602073414.22500-1-bartosz.golaszewski@oss.qualcomm.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-04net/dns_resolver: use kasprintf + kmemdup_nul to simplify dns_queryThorsten Blum
Use kasprintf() for descriptions with a query type and kmemdup_nul() otherwise to simplify dns_query(). Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev> Reviewed-by: Simon Horman <horms@kernel.org> Link: https://patch.msgid.link/20260602071343.962830-2-thorsten.blum@linux.dev Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-04octeontx2-af: kpu: Default profile updatesKiran Kumar K
Add support for parsing the following: 1. fabric path header 2. tpids 0x88a8, 0x9100 and 0x9200 parsing for first pass and second pass packets 3. parse stacked VLANs 4. RoCEv2 header with UDP destination port 4791 5. single SBTAG parsing Signed-off-by: Kiran Kumar K <kirankumark@marvell.com> Signed-off-by: Nitin Shetty J <nshettyj@marvell.com> Link: https://patch.msgid.link/20260602040535.3975769-1-nshettyj@marvell.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-04Merge branch 'selftests-rds-roce-support-follow-ups'Jakub Kicinski
Allison Henderson says: ==================== selftests: rds: ROCE support follow ups This is a follow up series to the "Add ROCE support to rds selftests" series. The first patch renames run.sh to rds_run.sh, which provides a self-describing name that appears on the netdev CI dashboard. The second patch addresses a sashiko complaint that I thought was worth circling back for. In the patch "pin RDS sockets to their intended transport," sockets are pinned to the specific transport they are meant to test. By default, socket transports are implicitly selected based on the network topology, but it is possible that they can fail back to other transports if the underlying connection could not be established. So the patch pins them to the intended transport to avoid false positives. The third patch "support RDS built as loadable modules," lifts the CONFIG_MODULES=n requirement, and updates the check_*conf_enabled() to allow modules set to "=m" and further load the backing modules for any component set as such. config.sh is updated to match. The fourth patch converts the rdma-prerequisite checks to return XFAIL rather than SKIP, since the RDMA datapath is not run in netdev CI. Questions, comments and feedback appreciated! ==================== Link: https://patch.msgid.link/20260602050657.26389-1-achender@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-04selftests: rds: report missing RDMA prereqs as XFAILAllison Henderson
Make the RDMA test return XFAIL rather than skip when RXE is not available, since the RDMA datapath is not run in netdev CI. Change the three RDMA-prerequisite checks in check_rdma_conf() and check_rdma_conf_enabled() to exit with KSFT_XFAIL (2) and tag their messages [XFAIL] instead of [SKIP]. Signed-off-by: Allison Henderson <achender@kernel.org> Link: https://patch.msgid.link/20260602050657.26389-5-achender@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-04selftests: rds: support RDS built as loadable modulesAllison Henderson
Commit 92cc6708f4a2 ("selftests: rds: config: disable modules") set CONFIG_MODULES=n since run.sh required this kconfig. But disabling modules also forces every =m option to =n rather than =y, which can silently drop unrelated features. This patch removes CONFIG_MODULES=n from the rds selftest config and updates the check_*conf_enabled() routines to accept a config as either built-in (=y) or modular (=m). A new probe_module() function is added to load the backing module when a component is set to be modular (=m). config.sh no longer forces CONFIG_MODULES=n, so a user who follows the SKIP message to run config.sh does not silently end up with modules disabled again. rds.ko itself is auto-loaded on socket creation, and rds_rdma.ko is auto-loaded when SO_RDS_TRANSPORT is set with RDS_TRANS_IB, but the TCP transport (rds_tcp.ko) is not auto-loaded on the bind path, so the backing modules are loaded explicitly here. Signed-off-by: Allison Henderson <achender@kernel.org> Link: https://patch.msgid.link/20260602050657.26389-4-achender@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-04selftests: rds: pin RDS sockets to their intended transportAllison Henderson
The RDS selftests create AF_RDS sockets but never selects a transport, so the transport is chosen implicitly based on network topology when the socket is bound. If underlying connection establishment fails, RDS can fall back to another transport (e.g. loopback) and the test still passes, silently bypassing the intended datapath it is meant to exercise. Set SO_RDS_TRANSPORT to the proper RDS_TRANS_IB or RDS_TRANS_TCP before they are bound, so the test fails loudly if the intended transport is unavailable rather than passing on a different path. Signed-off-by: Allison Henderson <achender@kernel.org> Link: https://patch.msgid.link/20260602050657.26389-3-achender@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-04selftests: rds: Rename run.sh to rds_run.shAllison Henderson
This patch renames run.sh to rds_run.sh. This gives the test a self-describing name that appears in the netdev CI dashboard. Suggested-by: Matthieu Baerts <matttbe@kernel.org> Signed-off-by: Allison Henderson <achender@kernel.org> Link: https://patch.msgid.link/20260602050657.26389-2-achender@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-04ipv6: use READ_ONCE() in ipv6_flowlabel_get()Runyu Xiao
ipv6_flowlabel_get() reads flowlabel_consistency and flowlabel_state_ranges locklessly. Use READ_ONCE() for these sysctl accesses. Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20260602002506.1519901-1-runyu.xiao@seu.edu.cn Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-04ipv6: use READ_ONCE() for bindv6only default in inet6_create()Runyu Xiao
inet6_create() reads net->ipv6.sysctl.bindv6only locklessly. Use READ_ONCE() for this sysctl access. Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20260602002414.1504106-1-runyu.xiao@seu.edu.cn Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-04inet: frags: remove redundant assignment in inet_frag_reasm_prepare()yuan.gao
The assignment is redundant because skb_clone() already copies skb->cb. Remove the unnecessary code. Signed-off-by: yuan.gao <yuan.gao@ucloud.cn> Link: https://patch.msgid.link/20260603065323.2736839-1-yuan.gao@ucloud.cn Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-04net: airoha: Report extack error to the user if airoha_tc_htb_modify_queue() ↵Lorenzo Bianconi
fails Report an extack error message in airoha_tc_htb_modify_queue routine if airoha_qdma_set_tx_rate_limit() fails. Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> Reviewed-by: Alexander Lobakin <aleksander.lobakin@intel.com> Link: https://patch.msgid.link/20260603-airoha_tc_htb_modify_queue-err-message-v1-1-33ec3ab997d9@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-04dt-bindings: net: dsa: remove obsolete dsa.txtAkash Sukhavasi
dsa.txt has been a redirect to dsa.yaml since commit bce58590d1bd ("dt-bindings: net: dsa: Add DSA yaml binding") introduced the .yaml schema. The .yaml has the same filename in the same directory, making this redirect unnecessary for discoverability. Two files still reference dsa.txt, forcing readers through an extra hop to reach the .yaml. The stub has not been touched since August 2020. Update references in lan9303.txt and Documentation/networking/dsa/dsa.rst to point directly to dsa.yaml and remove the stub. Signed-off-by: Akash Sukhavasi <akash.sukhavasi@gmail.com> Acked-by: Rob Herring (Arm) <robh@kernel.org> Link: https://patch.msgid.link/20260603-b4-remove-redirect-stubs-v2-3-c8c19876ab64@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-04dt-bindings: net: remove obsolete mdio.txtAkash Sukhavasi
mdio.txt has been a single-line redirect to mdio.yaml since commit 62d77ff7ecbf ("dt-bindings: net: Add a YAML schemas for the generic MDIO options"), which introduced the .yaml schema and reduced the .txt to a stub in the same change. The .yaml has the same filename in the same directory, making this redirect unnecessary for discoverability. No files in the tree reference mdio.txt and it has not been touched since June 2019. Remove the obsolete stub. Signed-off-by: Akash Sukhavasi <akash.sukhavasi@gmail.com> Acked-by: Rob Herring (Arm) <robh@kernel.org> Link: https://patch.msgid.link/20260603-b4-remove-redirect-stubs-v2-1-c8c19876ab64@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-04rtnetlink: use dev_isalive() in rtnl_getlink()Eric Dumazet
rtnl_getlink() uses an RCU lookup to get the netdevice pointer. When/If rtnl_lock() is used, we should check if the netdevice is not being dismantled before potentially perform illegal actions. Move dev_isalive() out of net/core/net-sysfs.c and make it available in net/core/dev.h. Return -ENODEV if rtnl_getlink() finds a device which is currently being dismantled and RTNL is requested. Fixes: e896e5c0734b ("rtnetlink: do not acquire RTNL in rtnl_getlink() with RTEXT_FILTER_NAME_ONLY") Signed-off-by: Eric Dumazet <edumazet@google.com> Suggested-by: Jakub Kicinski <kuba@kernel.org> Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev> Link: https://patch.msgid.link/20260603180831.1024716-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-04net: dsa: realtek: Use %pM format specifier for MAC addressesAndy Shevchenko
Convert to %pM instead of using custom code. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de> Reviewed-by: Linus Walleij <linusw@kernel.org> Link: https://patch.msgid.link/20260603112011.230890-1-andriy.shevchenko@linux.intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-04bridge: mcast: Synchronously shutdown port multicast timersIdo Schimmel
Currently, while four timers are set up during port multicast context initialization, only two are synchronously deleted when the context is de-initialized, just before being deleted. This is fine because the structure containing the multicast context (either a bridge port or a VLAN) is only deleted after an RCU grace period and it will not pass as long as the timers are executing. These timers are also not supposed to do any work at this stage. They acquire the bridge multicast lock, see that the multicast context was disabled and exit. Make the code more explicit and symmetric and synchronously shutdown all four timers when the multicast context is de-initialized. Use timer_shutdown_sync() to guarantee that the timers will not be re-armed given that the containing structure is being deleted. Acked-by: Nikolay Aleksandrov <nikolay@nvidia.com> Signed-off-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20260603103522.622411-1-idosch@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-04Merge branch 'rndis_host-add-le310x1-id-and-enable-low-power-handling'Jakub Kicinski
Shaoxu Liu says: ==================== rndis_host: add LE310X1 ID and enable low-power handling This series adds RNDIS support for Telit Cinterion LE310X1 and then enables USB power management for that specific ID. ==================== Link: https://patch.msgid.link/tencent_29CB862D5756CBCBAFD2EE436EBAC98A7E05@qq.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>