From 5959495449caf325a0394602568e287f2b829818 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Tue, 17 Feb 2026 17:06:30 -0800 Subject: fsverity: remove fsverity_verify_page() Now that fsverity_verify_page() has no callers, remove it. Suggested-by: Linus Torvalds Reviewed-by: Christoph Hellwig Link: https://lore.kernel.org/r/20260218010630.7407-4-ebiggers@kernel.org Signed-off-by: Eric Biggers --- include/linux/fsverity.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/fsverity.h b/include/linux/fsverity.h index fed91023bea9..6de3ddf0b148 100644 --- a/include/linux/fsverity.h +++ b/include/linux/fsverity.h @@ -282,12 +282,6 @@ static inline bool fsverity_verify_folio(struct fsverity_info *vi, return fsverity_verify_blocks(vi, folio, folio_size(folio), 0); } -static inline bool fsverity_verify_page(struct fsverity_info *vi, - struct page *page) -{ - return fsverity_verify_blocks(vi, page_folio(page), PAGE_SIZE, 0); -} - /** * fsverity_file_open() - prepare to open a verity file * @inode: the inode being opened -- cgit v1.2.3 From 693680b9add63dbebb2505a553ff52f8c706c8c0 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Tue, 17 Feb 2026 17:22:44 -0800 Subject: fsverity: fix build error by adding fsverity_readahead() stub hppa-linux-gcc 9.5.0 generates a call to fsverity_readahead() in f2fs_readahead() when CONFIG_FS_VERITY=n, because it fails to do the expected dead code elimination based on vi always being NULL. Fix the build error by adding an inline stub for fsverity_readahead(). Since it's just for opportunistic readahead, just make it a no-op. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202602180838.pwICdY2r-lkp@intel.com/ Fixes: 45dcb3ac9832 ("f2fs: consolidate fsverity_info lookup") Reviewed-by: Christoph Hellwig Link: https://lore.kernel.org/r/20260218012244.18536-1-ebiggers@kernel.org Signed-off-by: Eric Biggers --- include/linux/fsverity.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/fsverity.h b/include/linux/fsverity.h index 6de3ddf0b148..a8f9aa75b792 100644 --- a/include/linux/fsverity.h +++ b/include/linux/fsverity.h @@ -195,6 +195,8 @@ int fsverity_ioctl_read_metadata(struct file *filp, const void __user *uarg); /* verify.c */ +void fsverity_readahead(struct fsverity_info *vi, pgoff_t index, + unsigned long nr_pages); bool fsverity_verify_blocks(struct fsverity_info *vi, struct folio *folio, size_t len, size_t offset); void fsverity_verify_bio(struct fsverity_info *vi, struct bio *bio); @@ -255,6 +257,11 @@ static inline int fsverity_ioctl_read_metadata(struct file *filp, /* verify.c */ +static inline void fsverity_readahead(struct fsverity_info *vi, pgoff_t index, + unsigned long nr_pages) +{ +} + static inline bool fsverity_verify_blocks(struct fsverity_info *vi, struct folio *folio, size_t len, size_t offset) @@ -303,8 +310,6 @@ static inline int fsverity_file_open(struct inode *inode, struct file *filp) } void fsverity_cleanup_inode(struct inode *inode); -void fsverity_readahead(struct fsverity_info *vi, pgoff_t index, - unsigned long nr_pages); struct page *generic_read_merkle_tree_page(struct inode *inode, pgoff_t index); void generic_readahead_merkle_tree(struct inode *inode, pgoff_t index, -- cgit v1.2.3 From 249013e673fce3506c61063c7cbedd75b4c668d8 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 18 Feb 2026 22:09:21 -0800 Subject: fsnotify: drop unused helper Remove this helper now that all users have been converted to fserror_report_metadata as of 7.0-rc1. Cc: jack@suse.cz Cc: amir73il@gmail.com Signed-off-by: Darrick J. Wong Link: https://patch.msgid.link/177148129543.716249.980530449513340111.stgit@frogsfrogsfrogs Reviewed-by: Christoph Hellwig Signed-off-by: Christian Brauner --- include/linux/fsnotify.h | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'include/linux') diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 28a9cb13fbfa..079c18bcdbde 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -495,19 +495,6 @@ static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid) fsnotify_dentry(dentry, mask); } -static inline int fsnotify_sb_error(struct super_block *sb, struct inode *inode, - int error) -{ - struct fs_error_report report = { - .error = error, - .inode = inode, - .sb = sb, - }; - - return fsnotify(FS_ERROR, &report, FSNOTIFY_EVENT_ERROR, - NULL, NULL, NULL, 0); -} - static inline void fsnotify_mnt_attach(struct mnt_namespace *ns, struct vfsmount *mnt) { fsnotify_mnt(FS_MNT_ATTACH, ns, mnt); -- cgit v1.2.3 From ea129e55c9e06a51a93c3f5ef3e32a6cfa3f8ec7 Mon Sep 17 00:00:00 2001 From: Govindarajulu Varadarajan Date: Wed, 18 Feb 2026 20:59:30 -0800 Subject: io_uring: Add size check for sqe->cmd For SQE128, sqe->cmd provides 80 bytes for uring_cmd. Add macro to check if size of user struct does not exceed 80 bytes at compile time. User doesn't have to track this manually during development. Replace io_uring_sqe_cmd() inline func with macro and add io_uring_sqe128_cmd() which checks struct size for 16 bytes cmd and 80 bytes cmd respectively. Signed-off-by: Govindarajulu Varadarajan Reviewed-by: Caleb Sander Mateos Signed-off-by: Jens Axboe --- include/linux/io_uring/cmd.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/io_uring/cmd.h b/include/linux/io_uring/cmd.h index 375fd048c4cb..331dcbefe72f 100644 --- a/include/linux/io_uring/cmd.h +++ b/include/linux/io_uring/cmd.h @@ -20,10 +20,17 @@ struct io_uring_cmd { u8 unused[8]; }; -static inline const void *io_uring_sqe_cmd(const struct io_uring_sqe *sqe) -{ - return sqe->cmd; -} +#define io_uring_sqe128_cmd(sqe, type) ({ \ + BUILD_BUG_ON(sizeof(type) > ((2 * sizeof(struct io_uring_sqe)) - \ + offsetof(struct io_uring_sqe, cmd))); \ + (const type *)(sqe)->cmd; \ +}) + +#define io_uring_sqe_cmd(sqe, type) ({ \ + BUILD_BUG_ON(sizeof(type) > (sizeof(struct io_uring_sqe) - \ + offsetof(struct io_uring_sqe, cmd))); \ + (const type *)(sqe)->cmd; \ +}) static inline void io_uring_cmd_private_sz_check(size_t cmd_sz) { -- cgit v1.2.3 From f4ff9f646a4d373f9e895c2f0073305da288bc0a Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 18 Feb 2026 10:42:44 -0500 Subject: fgraph: Do not call handlers direct when not using ftrace_ops The function graph tracer was modified to us the ftrace_ops of the function tracer. This simplified the code as well as allowed more features of the function graph tracer. Not all architectures were converted over as it required the implementation of HAVE_DYNAMIC_FTRACE_WITH_ARGS to implement. For those architectures, it still did it the old way where the function graph tracer handle was called by the function tracer trampoline. The handler then had to check the hash to see if the registered handlers wanted to be called by that function or not. In order to speed up the function graph tracer that used ftrace_ops, if only one callback was registered with function graph, it would call its function directly via a static call. Now, if the architecture does not support the use of using ftrace_ops and still has the ftrace function trampoline calling the function graph handler, then by doing a direct call it removes the check against the handler's hash (list of functions it wants callbacks to), and it may call that handler for functions that the handler did not request calls for. On 32bit x86, which does not support the ftrace_ops use with function graph tracer, it shows the issue: ~# trace-cmd start -p function -l schedule ~# trace-cmd show # tracer: function_graph # # CPU DURATION FUNCTION CALLS # | | | | | | | 2) * 11898.94 us | schedule(); 3) # 1783.041 us | schedule(); 1) | schedule() { ------------------------------------------ 1) bash-8369 => kworker-7669 ------------------------------------------ 1) | schedule() { ------------------------------------------ 1) kworker-7669 => bash-8369 ------------------------------------------ 1) + 97.004 us | } 1) | schedule() { [..] Now by starting the function tracer is another instance: ~# trace-cmd start -B foo -p function This causes the function graph tracer to trace all functions (because the function trace calls the function graph tracer for each on, and the function graph trace is doing a direct call): ~# trace-cmd show # tracer: function_graph # # CPU DURATION FUNCTION CALLS # | | | | | | | 1) 1.669 us | } /* preempt_count_sub */ 1) + 10.443 us | } /* _raw_spin_unlock_irqrestore */ 1) | tick_program_event() { 1) | clockevents_program_event() { 1) 1.044 us | ktime_get(); 1) 6.481 us | lapic_next_event(); 1) + 10.114 us | } 1) + 11.790 us | } 1) ! 181.223 us | } /* hrtimer_interrupt */ 1) ! 184.624 us | } /* __sysvec_apic_timer_interrupt */ 1) | irq_exit_rcu() { 1) 0.678 us | preempt_count_sub(); When it should still only be tracing the schedule() function. To fix this, add a macro FGRAPH_NO_DIRECT to be set to 0 when the architecture does not support function graph use of ftrace_ops, and set to 1 otherwise. Then use this macro to know to allow function graph tracer to call the handlers directly or not. Cc: stable@vger.kernel.org Cc: Masami Hiramatsu Cc: Mathieu Desnoyers Cc: Mark Rutland Link: https://patch.msgid.link/20260218104244.5f14dade@gandalf.local.home Fixes: cc60ee813b503 ("function_graph: Use static_call and branch to optimize entry function") Signed-off-by: Steven Rostedt (Google) --- include/linux/ftrace.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 1a4d36fc9085..c242fe49af4c 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -1092,10 +1092,17 @@ static inline bool is_ftrace_trampoline(unsigned long addr) #ifdef CONFIG_FUNCTION_GRAPH_TRACER #ifndef ftrace_graph_func -#define ftrace_graph_func ftrace_stub -#define FTRACE_OPS_GRAPH_STUB FTRACE_OPS_FL_STUB +# define ftrace_graph_func ftrace_stub +# define FTRACE_OPS_GRAPH_STUB FTRACE_OPS_FL_STUB +/* + * The function graph is called every time the function tracer is called. + * It must always test the ops hash and cannot just directly call + * the handler. + */ +# define FGRAPH_NO_DIRECT 1 #else -#define FTRACE_OPS_GRAPH_STUB 0 +# define FTRACE_OPS_GRAPH_STUB 0 +# define FGRAPH_NO_DIRECT 0 #endif #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ -- cgit v1.2.3 From 9678e53179aa7e907360f5b5b275769008a69b80 Mon Sep 17 00:00:00 2001 From: Petr Pavlu Date: Thu, 19 Feb 2026 17:27:02 +0100 Subject: tracing: Wake up poll waiters for hist files when removing an event The event_hist_poll() function attempts to verify whether an event file is being removed, but this check may not occur or could be unnecessarily delayed. This happens because hist_poll_wakeup() is currently invoked only from event_hist_trigger() when a hist command is triggered. If the event file is being removed, no associated hist command will be triggered and a waiter will be woken up only after an unrelated hist command is triggered. Fix the issue by adding a call to hist_poll_wakeup() in remove_event_file_dir() after setting the EVENT_FILE_FL_FREED flag. This ensures that a task polling on a hist file is woken up and receives EPOLLERR. Cc: stable@vger.kernel.org Cc: Mathieu Desnoyers Cc: Tom Zanussi Acked-by: Masami Hiramatsu (Google) Link: https://patch.msgid.link/20260219162737.314231-3-petr.pavlu@suse.com Fixes: 1bd13edbbed6 ("tracing/hist: Add poll(POLLIN) support on hist file") Signed-off-by: Petr Pavlu Signed-off-by: Steven Rostedt (Google) --- include/linux/trace_events.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h index 0a2b8229b999..37eb2f0f3dd8 100644 --- a/include/linux/trace_events.h +++ b/include/linux/trace_events.h @@ -683,6 +683,11 @@ static inline void hist_poll_wakeup(void) #define hist_poll_wait(file, wait) \ poll_wait(file, &hist_poll_wq, wait) + +#else +static inline void hist_poll_wakeup(void) +{ +} #endif #define __TRACE_EVENT_FLAGS(name, value) \ -- cgit v1.2.3 From 7bd27439a578bb7724a9f09f240337ab95d68d2b Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Thu, 20 Feb 2025 02:03:57 +0000 Subject: NTB/msi: Remove unused functions ntbm_msi_free_irq() and ntb_msi_peer_addr() were both added in 2019's commit 26b3a37b9284 ("NTB: Introduce MSI library") but have remained unused. Remove them, and the ntbm_msi_callback_match() helper that was used by ntbm_msi_free_irq(). Signed-off-by: Dr. David Alan Gilbert Signed-off-by: Jon Mason --- include/linux/ntb.h | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ntb.h b/include/linux/ntb.h index 191b524e5c0d..8ff9d663096b 100644 --- a/include/linux/ntb.h +++ b/include/linux/ntb.h @@ -1647,12 +1647,8 @@ int ntbm_msi_request_threaded_irq(struct ntb_dev *ntb, irq_handler_t handler, irq_handler_t thread_fn, const char *name, void *dev_id, struct ntb_msi_desc *msi_desc); -void ntbm_msi_free_irq(struct ntb_dev *ntb, unsigned int irq, void *dev_id); int ntb_msi_peer_trigger(struct ntb_dev *ntb, int peer, struct ntb_msi_desc *desc); -int ntb_msi_peer_addr(struct ntb_dev *ntb, int peer, - struct ntb_msi_desc *desc, - phys_addr_t *msi_addr); #else /* not CONFIG_NTB_MSI */ @@ -1674,21 +1670,11 @@ static inline int ntbm_msi_request_threaded_irq(struct ntb_dev *ntb, { return -EOPNOTSUPP; } -static inline void ntbm_msi_free_irq(struct ntb_dev *ntb, unsigned int irq, - void *dev_id) {} static inline int ntb_msi_peer_trigger(struct ntb_dev *ntb, int peer, struct ntb_msi_desc *desc) { return -EOPNOTSUPP; } -static inline int ntb_msi_peer_addr(struct ntb_dev *ntb, int peer, - struct ntb_msi_desc *desc, - phys_addr_t *msi_addr) -{ - return -EOPNOTSUPP; - -} - #endif /* CONFIG_NTB_MSI */ static inline int ntbm_msi_request_irq(struct ntb_dev *ntb, -- cgit v1.2.3 From d39a1d7486d98668dd34aaa6732aad7977c45f5a Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 20 Feb 2026 13:15:58 -0800 Subject: compiler_types: Disable __builtin_counted_by_ref for Clang Unfortunately, there is a corner case of __builtin_counted_by_ref() usage that crashes[1] Clang since support was introduced in Clang 19. Disable it prior to Clang 22. Found while tested kmalloc_obj treewide refactoring (via kmalloc_flex() usage). Link: https://github.com/llvm/llvm-project/issues/182575 [1] Signed-off-by: Kees Cook --- include/linux/compiler_types.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index b1b141394d13..890076d0974b 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -552,7 +552,8 @@ struct ftrace_likely_data { * gcc: https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-_005f_005fbuiltin_005fcounted_005fby_005fref * clang: https://clang.llvm.org/docs/LanguageExtensions.html#builtin-counted-by-ref */ -#if __has_builtin(__builtin_counted_by_ref) +#if __has_builtin(__builtin_counted_by_ref) && \ + !defined(CONFIG_CC_HAS_BROKEN_COUNTED_BY_REF) /** * __flex_counter() - Get pointer to counter member for the given * flexible array, if it was annotated with __counted_by() -- cgit v1.2.3 From 69050f8d6d075dc01af7a5f2f550a8067510366f Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 20 Feb 2026 23:49:23 -0800 Subject: treewide: Replace kmalloc with kmalloc_obj for non-scalar types This is the result of running the Coccinelle script from scripts/coccinelle/api/kmalloc_objs.cocci. The script is designed to avoid scalar types (which need careful case-by-case checking), and instead replace kmalloc-family calls that allocate struct or union object instances: Single allocations: kmalloc(sizeof(TYPE), ...) are replaced with: kmalloc_obj(TYPE, ...) Array allocations: kmalloc_array(COUNT, sizeof(TYPE), ...) are replaced with: kmalloc_objs(TYPE, COUNT, ...) Flex array allocations: kmalloc(struct_size(PTR, FAM, COUNT), ...) are replaced with: kmalloc_flex(*PTR, FAM, COUNT, ...) (where TYPE may also be *VAR) The resulting allocations no longer return "void *", instead returning "TYPE *". Signed-off-by: Kees Cook --- include/linux/acpi.h | 2 +- include/linux/bpf.h | 2 +- include/linux/crash_dump.h | 2 +- include/linux/dma-fence-chain.h | 2 +- include/linux/gameport.h | 2 +- include/linux/io-mapping.h | 2 +- include/linux/kvm_host.h | 2 +- include/linux/skmsg.h | 3 +-- include/linux/spi/spi.h | 2 +- 9 files changed, 9 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 3a412dcebc29..8b1d8993793d 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -66,7 +66,7 @@ static inline struct fwnode_handle *acpi_alloc_fwnode_static(void) { struct fwnode_handle *fwnode; - fwnode = kzalloc(sizeof(struct fwnode_handle), GFP_KERNEL); + fwnode = kzalloc_obj(struct fwnode_handle, GFP_KERNEL); if (!fwnode) return NULL; diff --git a/include/linux/bpf.h b/include/linux/bpf.h index cd9b96434904..b78b53198a2e 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -2299,7 +2299,7 @@ static inline bool bpf_map_flags_access_ok(u32 access_flags) static inline struct bpf_map_owner *bpf_map_owner_alloc(struct bpf_map *map) { - return kzalloc(sizeof(*map->owner), GFP_ATOMIC); + return kzalloc_obj(*map->owner, GFP_ATOMIC); } static inline void bpf_map_owner_free(struct bpf_map *map) diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h index dd6fc3b2133b..2cb211617ecc 100644 --- a/include/linux/crash_dump.h +++ b/include/linux/crash_dump.h @@ -136,7 +136,7 @@ struct vmcore_range { static inline int vmcore_alloc_add_range(struct list_head *list, unsigned long long paddr, unsigned long long size) { - struct vmcore_range *m = kzalloc(sizeof(*m), GFP_KERNEL); + struct vmcore_range *m = kzalloc_obj(*m, GFP_KERNEL); if (!m) return -ENOMEM; diff --git a/include/linux/dma-fence-chain.h b/include/linux/dma-fence-chain.h index 68c3c1e41014..3267ab0e8c54 100644 --- a/include/linux/dma-fence-chain.h +++ b/include/linux/dma-fence-chain.h @@ -91,7 +91,7 @@ dma_fence_chain_contained(struct dma_fence *fence) * intentional to enforce typesafety. */ #define dma_fence_chain_alloc() \ - ((struct dma_fence_chain *)kmalloc(sizeof(struct dma_fence_chain), GFP_KERNEL)) + ((struct dma_fence_chain *) kmalloc_obj(struct dma_fence_chain, GFP_KERNEL)) /** * dma_fence_chain_free diff --git a/include/linux/gameport.h b/include/linux/gameport.h index 86d62fdafd7a..09a1a59034e0 100644 --- a/include/linux/gameport.h +++ b/include/linux/gameport.h @@ -97,7 +97,7 @@ void gameport_set_phys(struct gameport *gameport, const char *fmt, ...) static inline struct gameport *gameport_allocate_port(void) { - struct gameport *gameport = kzalloc(sizeof(struct gameport), GFP_KERNEL); + struct gameport *gameport = kzalloc_obj(struct gameport, GFP_KERNEL); return gameport; } diff --git a/include/linux/io-mapping.h b/include/linux/io-mapping.h index c16353cc6e3c..ff9012c6a93a 100644 --- a/include/linux/io-mapping.h +++ b/include/linux/io-mapping.h @@ -206,7 +206,7 @@ io_mapping_create_wc(resource_size_t base, { struct io_mapping *iomap; - iomap = kmalloc(sizeof(*iomap), GFP_KERNEL); + iomap = kmalloc_obj(*iomap, GFP_KERNEL); if (!iomap) return NULL; diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index d42a95cbcfbc..dde605cb894e 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1664,7 +1664,7 @@ void kvm_arch_create_vm_debugfs(struct kvm *kvm); */ static inline struct kvm *kvm_arch_alloc_vm(void) { - return kzalloc(sizeof(struct kvm), GFP_KERNEL_ACCOUNT); + return kzalloc_obj(struct kvm, GFP_KERNEL_ACCOUNT); } #endif diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h index 829b281d6c9c..a8513e401760 100644 --- a/include/linux/skmsg.h +++ b/include/linux/skmsg.h @@ -460,8 +460,7 @@ int sk_psock_msg_verdict(struct sock *sk, struct sk_psock *psock, * intentional to enforce typesafety. */ #define sk_psock_init_link() \ - ((struct sk_psock_link *)kzalloc(sizeof(struct sk_psock_link), \ - GFP_ATOMIC | __GFP_NOWARN)) + ((struct sk_psock_link *) kzalloc_obj(struct sk_psock_link, GFP_ATOMIC | __GFP_NOWARN)) static inline void sk_psock_free_link(struct sk_psock_link *link) { diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index fd8dce4169f7..af7cfee7b8f6 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -1309,7 +1309,7 @@ static inline struct spi_message *spi_message_alloc(unsigned ntrans, gfp_t flags } *mwt; unsigned i; - mwt = kzalloc(struct_size(mwt, t, ntrans), flags); + mwt = kzalloc_flex(*mwt, t, ntrans, flags); if (!mwt) return NULL; -- cgit v1.2.3 From 7a70c15bd1449f1eb30991772edce37b41e496fb Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sat, 21 Feb 2026 00:12:19 -0800 Subject: kmalloc_obj: Clean up after treewide replacements Coccinelle doesn't handle re-indenting line escapes. Fix the 2 places where these got misaligned. Remove 2 now-redundant type casts, found with: $ git grep -P 'struct (\S+).*\)\s*k\S+alloc_(objs?|flex)\(struct \1' Signed-off-by: Kees Cook --- include/linux/dma-fence-chain.h | 2 +- include/linux/skmsg.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dma-fence-chain.h b/include/linux/dma-fence-chain.h index 3267ab0e8c54..e5f4451a6375 100644 --- a/include/linux/dma-fence-chain.h +++ b/include/linux/dma-fence-chain.h @@ -91,7 +91,7 @@ dma_fence_chain_contained(struct dma_fence *fence) * intentional to enforce typesafety. */ #define dma_fence_chain_alloc() \ - ((struct dma_fence_chain *) kmalloc_obj(struct dma_fence_chain, GFP_KERNEL)) + kmalloc_obj(struct dma_fence_chain, GFP_KERNEL) /** * dma_fence_chain_free diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h index a8513e401760..19f4f253b4f9 100644 --- a/include/linux/skmsg.h +++ b/include/linux/skmsg.h @@ -460,7 +460,7 @@ int sk_psock_msg_verdict(struct sock *sk, struct sk_psock *psock, * intentional to enforce typesafety. */ #define sk_psock_init_link() \ - ((struct sk_psock_link *) kzalloc_obj(struct sk_psock_link, GFP_ATOMIC | __GFP_NOWARN)) + kzalloc_obj(struct sk_psock_link, GFP_ATOMIC | __GFP_NOWARN) static inline void sk_psock_free_link(struct sk_psock_link *link) { -- cgit v1.2.3 From fa5c82f4d2bbde10e9fd3a32aecacfe3813919ba Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 21 Feb 2026 15:12:09 -0800 Subject: slab.h: disable completely broken overflow handling in flex allocations Commit 69050f8d6d07 ("treewide: Replace kmalloc with kmalloc_obj for non-scalar types") started using the new allocation helpers, and in the process showed that they were completely non-working. The overflow logic in overflows_flex_counter_type() is completely the wrong way around, and that broke __alloc_flex() completely. By chance, the resulting code was then such a mess that clang generated sufficiently garbage code that objtool warned about it all. Which made it somewhat quicker to narrow things down. While fixing overflows_flex_counter_type() would presumably fix this all, I'm excising the whole broken overflow logic from __alloc_flex(), because we don't want that kind of code in basic allocation functions anyway. That (no longer) broken overflows_flex_counter_type() thing needs to be inserted into the actual __set_flex_counter() logic in the unlikely case that we ever want this at all. And made conditional. Fixes: 81cee9166a90 ("compiler_types: Introduce __flex_counter() and family") Fixes: 69050f8d6d07 ("treewide: Replace kmalloc with kmalloc_obj for non-scalar types") Cc: Kees Cook Link: https://lore.kernel.org/all/CAHk-=whEd020BYzGTzYrENjD9Z5_82xx6h8HsQvH5xDSnv0=Hw@mail.gmail.com/ Signed-off-by: Linus Torvalds --- include/linux/overflow.h | 2 +- include/linux/slab.h | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/overflow.h b/include/linux/overflow.h index a5e95dbce220..eddd987a8513 100644 --- a/include/linux/overflow.h +++ b/include/linux/overflow.h @@ -570,7 +570,7 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend) * @FAM is not annotated with __counted_by(), always returns true. */ #define overflows_flex_counter_type(TYPE, FAM, COUNT) \ - (!overflows_type(COUNT, typeof_flex_counter(((TYPE *)NULL)->FAM))) + (overflows_type(COUNT, typeof_flex_counter(((TYPE *)NULL)->FAM))) /** * __set_flex_counter() - Set the counter associated with the given flexible diff --git a/include/linux/slab.h b/include/linux/slab.h index c5fde8740281..1270320b59c8 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -1003,11 +1003,7 @@ void *kmalloc_nolock_noprof(size_t size, gfp_t gfp_flags, int node); ({ \ const size_t __count = (COUNT); \ const size_t __obj_size = struct_size_t(TYPE, FAM, __count); \ - TYPE *__obj_ptr; \ - if (WARN_ON_ONCE(overflows_flex_counter_type(TYPE, FAM, __count))) \ - __obj_ptr = NULL; \ - else \ - __obj_ptr = KMALLOC(__obj_size, GFP); \ + TYPE *__obj_ptr = KMALLOC(__obj_size, GFP); \ if (__obj_ptr) \ __set_flex_counter(__obj_ptr->FAM, __count); \ __obj_ptr; \ -- cgit v1.2.3 From e19e1b480ac73c3e62ffebbca1174f0f511f43e7 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 21 Feb 2026 16:14:11 -0800 Subject: add default_gfp() helper macro and use it in the new *alloc_obj() helpers Most simple allocations use GFP_KERNEL, and with the new allocation helpers being introduced, let's just take advantage of that to simplify that default case. It's a numbers game: git grep 'alloc_obj(' | sed 's/.*\(GFP_[_A-Z]*\).*/\1/' | sort | uniq -c | sort -n | tail shows that about 90% of all those new allocator instances just use that standard GFP_KERNEL. Those helpers are already macros, and we can easily just make it be the default case when the gfp argument is missing. And yes, we could do that for all the legacy interfaces too, but let's keep it to just the new ones at least for now, since those all got converted recently anyway, so this is not any "extra" noise outside of that limited conversion. And, in fact, I want to do this before doing the -rc1 release, exactly so that we don't get extra merge conflicts. Signed-off-by: Linus Torvalds --- include/linux/gfp.h | 4 ++++ include/linux/slab.h | 48 ++++++++++++++++++++++++------------------------ 2 files changed, 28 insertions(+), 24 deletions(-) (limited to 'include/linux') diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 6ecf6dda93e0..2b30a0529d48 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -13,6 +13,10 @@ struct vm_area_struct; struct mempolicy; +/* Helper macro to avoid gfp flags if they are the default one */ +#define __default_gfp(a,...) a +#define default_gfp(...) __default_gfp(__VA_ARGS__ __VA_OPT__(,) GFP_KERNEL) + /* Convert GFP flags to their corresponding migrate type */ #define GFP_MOVABLE_MASK (__GFP_RECLAIMABLE|__GFP_MOVABLE) #define GFP_MOVABLE_SHIFT 3 diff --git a/include/linux/slab.h b/include/linux/slab.h index 1270320b59c8..a5a5e4108ae5 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -1017,8 +1017,8 @@ void *kmalloc_nolock_noprof(size_t size, gfp_t gfp_flags, int node); * Returns: newly allocated pointer to a @VAR_OR_TYPE on success, or NULL * on failure. */ -#define kmalloc_obj(VAR_OR_TYPE, GFP) \ - __alloc_objs(kmalloc, GFP, typeof(VAR_OR_TYPE), 1) +#define kmalloc_obj(VAR_OR_TYPE, ...) \ + __alloc_objs(kmalloc, default_gfp(__VA_ARGS__), typeof(VAR_OR_TYPE), 1) /** * kmalloc_objs - Allocate an array of the given type @@ -1029,8 +1029,8 @@ void *kmalloc_nolock_noprof(size_t size, gfp_t gfp_flags, int node); * Returns: newly allocated pointer to array of @VAR_OR_TYPE on success, * or NULL on failure. */ -#define kmalloc_objs(VAR_OR_TYPE, COUNT, GFP) \ - __alloc_objs(kmalloc, GFP, typeof(VAR_OR_TYPE), COUNT) +#define kmalloc_objs(VAR_OR_TYPE, COUNT, ...) \ + __alloc_objs(kmalloc, default_gfp(__VA_ARGS__), typeof(VAR_OR_TYPE), COUNT) /** * kmalloc_flex - Allocate a single instance of the given flexible structure @@ -1044,32 +1044,32 @@ void *kmalloc_nolock_noprof(size_t size, gfp_t gfp_flags, int node); * will immediately fail if @COUNT is larger than what the type of the * struct's counter variable can represent. */ -#define kmalloc_flex(VAR_OR_TYPE, FAM, COUNT, GFP) \ - __alloc_flex(kmalloc, GFP, typeof(VAR_OR_TYPE), FAM, COUNT) +#define kmalloc_flex(VAR_OR_TYPE, FAM, COUNT, ...) \ + __alloc_flex(kmalloc, default_gfp(__VA_ARGS__), typeof(VAR_OR_TYPE), FAM, COUNT) /* All kzalloc aliases for kmalloc_(obj|objs|flex). */ -#define kzalloc_obj(P, GFP) \ - __alloc_objs(kzalloc, GFP, typeof(P), 1) -#define kzalloc_objs(P, COUNT, GFP) \ - __alloc_objs(kzalloc, GFP, typeof(P), COUNT) -#define kzalloc_flex(P, FAM, COUNT, GFP) \ - __alloc_flex(kzalloc, GFP, typeof(P), FAM, COUNT) +#define kzalloc_obj(P, ...) \ + __alloc_objs(kzalloc, default_gfp(__VA_ARGS__), typeof(P), 1) +#define kzalloc_objs(P, COUNT, ...) \ + __alloc_objs(kzalloc, default_gfp(__VA_ARGS__), typeof(P), COUNT) +#define kzalloc_flex(P, FAM, COUNT, ...) \ + __alloc_flex(kzalloc, default_gfp(__VA_ARGS__), typeof(P), FAM, COUNT) /* All kvmalloc aliases for kmalloc_(obj|objs|flex). */ -#define kvmalloc_obj(P, GFP) \ - __alloc_objs(kvmalloc, GFP, typeof(P), 1) -#define kvmalloc_objs(P, COUNT, GFP) \ - __alloc_objs(kvmalloc, GFP, typeof(P), COUNT) -#define kvmalloc_flex(P, FAM, COUNT, GFP) \ - __alloc_flex(kvmalloc, GFP, typeof(P), FAM, COUNT) +#define kvmalloc_obj(P, ...) \ + __alloc_objs(kvmalloc, default_gfp(__VA_ARGS__), typeof(P), 1) +#define kvmalloc_objs(P, COUNT, ...) \ + __alloc_objs(kvmalloc, default_gfp(__VA_ARGS__), typeof(P), COUNT) +#define kvmalloc_flex(P, FAM, COUNT, ...) \ + __alloc_flex(kvmalloc, default_gfp(__VA_ARGS__), typeof(P), FAM, COUNT) /* All kvzalloc aliases for kmalloc_(obj|objs|flex). */ -#define kvzalloc_obj(P, GFP) \ - __alloc_objs(kvzalloc, GFP, typeof(P), 1) -#define kvzalloc_objs(P, COUNT, GFP) \ - __alloc_objs(kvzalloc, GFP, typeof(P), COUNT) -#define kvzalloc_flex(P, FAM, COUNT, GFP) \ - __alloc_flex(kvzalloc, GFP, typeof(P), FAM, COUNT) +#define kvzalloc_obj(P, ...) \ + __alloc_objs(kvzalloc, default_gfp(__VA_ARGS__), typeof(P), 1) +#define kvzalloc_objs(P, COUNT, ...) \ + __alloc_objs(kvzalloc, default_gfp(__VA_ARGS__), typeof(P), COUNT) +#define kvzalloc_flex(P, FAM, COUNT, ...) \ + __alloc_flex(kvzalloc, default_gfp(__VA_ARGS__), typeof(P), FAM, COUNT) #define kmem_buckets_alloc(_b, _size, _flags) \ alloc_hooks(__kmalloc_node_noprof(PASS_BUCKET_PARAMS(_size, _b), _flags, NUMA_NO_NODE)) -- cgit v1.2.3 From bf4afc53b77aeaa48b5409da5c8da6bb4eff7f43 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 21 Feb 2026 16:37:42 -0800 Subject: Convert 'alloc_obj' family to use the new default GFP_KERNEL argument This was done entirely with mindless brute force, using git grep -l '\ --- include/linux/acpi.h | 2 +- include/linux/crash_dump.h | 2 +- include/linux/dma-fence-chain.h | 2 +- include/linux/gameport.h | 2 +- include/linux/io-mapping.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 8b1d8993793d..4d2f0bed7a06 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -66,7 +66,7 @@ static inline struct fwnode_handle *acpi_alloc_fwnode_static(void) { struct fwnode_handle *fwnode; - fwnode = kzalloc_obj(struct fwnode_handle, GFP_KERNEL); + fwnode = kzalloc_obj(struct fwnode_handle); if (!fwnode) return NULL; diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h index 2cb211617ecc..8315270e27b7 100644 --- a/include/linux/crash_dump.h +++ b/include/linux/crash_dump.h @@ -136,7 +136,7 @@ struct vmcore_range { static inline int vmcore_alloc_add_range(struct list_head *list, unsigned long long paddr, unsigned long long size) { - struct vmcore_range *m = kzalloc_obj(*m, GFP_KERNEL); + struct vmcore_range *m = kzalloc_obj(*m); if (!m) return -ENOMEM; diff --git a/include/linux/dma-fence-chain.h b/include/linux/dma-fence-chain.h index e5f4451a6375..5cd3ba53b4a1 100644 --- a/include/linux/dma-fence-chain.h +++ b/include/linux/dma-fence-chain.h @@ -91,7 +91,7 @@ dma_fence_chain_contained(struct dma_fence *fence) * intentional to enforce typesafety. */ #define dma_fence_chain_alloc() \ - kmalloc_obj(struct dma_fence_chain, GFP_KERNEL) + kmalloc_obj(struct dma_fence_chain) /** * dma_fence_chain_free diff --git a/include/linux/gameport.h b/include/linux/gameport.h index 09a1a59034e0..9625347c7ac0 100644 --- a/include/linux/gameport.h +++ b/include/linux/gameport.h @@ -97,7 +97,7 @@ void gameport_set_phys(struct gameport *gameport, const char *fmt, ...) static inline struct gameport *gameport_allocate_port(void) { - struct gameport *gameport = kzalloc_obj(struct gameport, GFP_KERNEL); + struct gameport *gameport = kzalloc_obj(struct gameport); return gameport; } diff --git a/include/linux/io-mapping.h b/include/linux/io-mapping.h index ff9012c6a93a..e5a884e72f29 100644 --- a/include/linux/io-mapping.h +++ b/include/linux/io-mapping.h @@ -206,7 +206,7 @@ io_mapping_create_wc(resource_size_t base, { struct io_mapping *iomap; - iomap = kmalloc_obj(*iomap, GFP_KERNEL); + iomap = kmalloc_obj(*iomap); if (!iomap) return NULL; -- cgit v1.2.3 From 551d44200152cb26f75d2ef990aeb6185b7e37fd Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 23 Feb 2026 09:33:08 -0800 Subject: default_gfp(): avoid using the "newfangled" __VA_OPT__ trick The default_gfp() helper that I added is not wrong, but it turns out that it causes unnecessary headaches for 'sparse' which doesn't support the use of __VA_OPT__ (introduced in C++20 and C23, and supported by gcc and clang for a long time). We do already use __VA_OPT__ in some other cases in the kernel (drm/xe and btrfs), but it has been fairly limited. Now it triggers for pretty much everything, and sparse ends up not working at all. We can use the traditional gcc ',##__VA_ARGS__' syntax instead: it may not be the "C standard" way and is slightly less natural in this context, but it is the traditional model for this and avoids the sparse problem. Reported-and-tested-by: Ricardo Ribalda Reported-and-tested-by: Richard Fitzgerald Reported-by: Ben Dooks Fixes: e19e1b480ac7 ("add default_gfp() helper macro and use it in the new *alloc_obj() helpers") Signed-off-by: Linus Torvalds --- include/linux/gfp.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 2b30a0529d48..90536b2bc42e 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -14,8 +14,8 @@ struct vm_area_struct; struct mempolicy; /* Helper macro to avoid gfp flags if they are the default one */ -#define __default_gfp(a,...) a -#define default_gfp(...) __default_gfp(__VA_ARGS__ __VA_OPT__(,) GFP_KERNEL) +#define __default_gfp(a,b,...) b +#define default_gfp(...) __default_gfp(,##__VA_ARGS__,GFP_KERNEL) /* Convert GFP flags to their corresponding migrate type */ #define GFP_MOVABLE_MASK (__GFP_RECLAIMABLE|__GFP_MOVABLE) -- cgit v1.2.3