v4: https://lore.kernel.org/linux-media/20211007154407.29746-1-andriy.shevchenko... v3: https://lore.kernel.org/linux-media/20211007150339.28910-1-andriy.shevchenko... v2: https://lore.kernel.org/linux-media/20211007095129.22037-1-andriy.shevchenko...
The kernel.h is a set of something which is not related to each other and often used in non-crossed compilation units, especially when drivers need only one or two macro definitions from it.
Here is the split of container_of(). The goals are the following: - untwist the dependency hell a bit - drop kernel.h inclusion where it's only used for container_of()
In v5: - dropped code duplication (Miguel) - added necessary includes into container_of.h (Joe) - dropped other header shuffling in list.h (Jonathan) - added tag (Sakari)
In v4: - dropped kobject.h change (Greg) - Cc'ed more people (as per v1)
In v3: - split patch 2 to more patches (Greg) - excluded C changes (Herbert, Greg) - measured with kcbench, see below (Greg)
Andy Shevchenko (7): kernel.h: Drop unneeded <linux/kernel.h> inclusion from other headers kernel.h: Split out container_of() and typeof_member() macros kunit: Replace kernel.h with the necessary inclusions list: Replace kernel.h with the necessary inclusions llist: Replace kernel.h with the necessary inclusions plist: Replace kernel.h with the necessary inclusions media: entity: Replace kernel.h with the necessary inclusions
include/kunit/test.h | 13 ++++++++++-- include/linux/container_of.h | 40 ++++++++++++++++++++++++++++++++++++ include/linux/kernel.h | 33 +---------------------------- include/linux/list.h | 4 +++- include/linux/llist.h | 4 +++- include/linux/plist.h | 5 ++++- include/linux/rwsem.h | 1 - include/linux/smp.h | 1 - include/linux/spinlock.h | 1 - include/media/media-entity.h | 3 ++- 10 files changed, 64 insertions(+), 41 deletions(-) create mode 100644 include/linux/container_of.h
There is no evidence we need kernel.h inclusion in certain headers. Drop unneeded <linux/kernel.h> inclusion from other headers.
Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com --- include/linux/rwsem.h | 1 - include/linux/smp.h | 1 - include/linux/spinlock.h | 1 - 3 files changed, 3 deletions(-)
diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h index 352c6127cb90..f9348769e558 100644 --- a/include/linux/rwsem.h +++ b/include/linux/rwsem.h @@ -11,7 +11,6 @@ #include <linux/linkage.h>
#include <linux/types.h> -#include <linux/kernel.h> #include <linux/list.h> #include <linux/spinlock.h> #include <linux/atomic.h> diff --git a/include/linux/smp.h b/include/linux/smp.h index 510519e8a1eb..a80ab58ae3f1 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -108,7 +108,6 @@ static inline void on_each_cpu_cond(smp_cond_func_t cond_func, #ifdef CONFIG_SMP
#include <linux/preempt.h> -#include <linux/kernel.h> #include <linux/compiler.h> #include <linux/thread_info.h> #include <asm/smp.h> diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index 76a855b3ecde..c04e99edfe92 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -57,7 +57,6 @@ #include <linux/compiler.h> #include <linux/irqflags.h> #include <linux/thread_info.h> -#include <linux/kernel.h> #include <linux/stringify.h> #include <linux/bottom_half.h> #include <linux/lockdep.h>
kernel.h is being used as a dump for all kinds of stuff for a long time. Here is the attempt cleaning it up by splitting out container_of() and typeof_member() macros.
For time being include new header back to kernel.h to avoid twisted indirected includes for existing users.
Note, there are _a lot_ of headers and modules that include kernel.h solely for one of these macros and this allows to unburden compiler for the twisted inclusion paths and to make new code cleaner in the future.
Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com --- include/linux/container_of.h | 40 ++++++++++++++++++++++++++++++++++++ include/linux/kernel.h | 33 +---------------------------- 2 files changed, 41 insertions(+), 32 deletions(-) create mode 100644 include/linux/container_of.h
diff --git a/include/linux/container_of.h b/include/linux/container_of.h new file mode 100644 index 000000000000..dd56019838c6 --- /dev/null +++ b/include/linux/container_of.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_CONTAINER_OF_H +#define _LINUX_CONTAINER_OF_H + +#include <linux/build_bug.h> +#include <linux/err.h> + +#define typeof_member(T, m) typeof(((T*)0)->m) + +/** + * container_of - cast a member of a structure out to the containing structure + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + * + */ +#define container_of(ptr, type, member) ({ \ + void *__mptr = (void *)(ptr); \ + BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \ + !__same_type(*(ptr), void), \ + "pointer type mismatch in container_of()"); \ + ((type *)(__mptr - offsetof(type, member))); }) + +/** + * container_of_safe - cast a member of a structure out to the containing structure + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + * + * If IS_ERR_OR_NULL(ptr), ptr is returned unchanged. + */ +#define container_of_safe(ptr, type, member) ({ \ + void *__mptr = (void *)(ptr); \ + BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \ + !__same_type(*(ptr), void), \ + "pointer type mismatch in container_of()"); \ + IS_ERR_OR_NULL(__mptr) ? ERR_CAST(__mptr) : \ + ((type *)(__mptr - offsetof(type, member))); }) + +#endif /* _LINUX_CONTAINER_OF_H */ diff --git a/include/linux/kernel.h b/include/linux/kernel.h index d1e74f684aa0..24df51162e3e 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -9,6 +9,7 @@ #include <linux/stddef.h> #include <linux/types.h> #include <linux/compiler.h> +#include <linux/container_of.h> #include <linux/bitops.h> #include <linux/kstrtox.h> #include <linux/log2.h> @@ -52,8 +53,6 @@ } \ )
-#define typeof_member(T, m) typeof(((T*)0)->m) - #define _RET_IP_ (unsigned long)__builtin_return_address(0) #define _THIS_IP_ ({ __label__ __here; __here: (unsigned long)&&__here; })
@@ -481,36 +480,6 @@ static inline void ftrace_dump(enum ftrace_dump_mode oops_dump_mode) { } #define __CONCAT(a, b) a ## b #define CONCATENATE(a, b) __CONCAT(a, b)
-/** - * container_of - cast a member of a structure out to the containing structure - * @ptr: the pointer to the member. - * @type: the type of the container struct this is embedded in. - * @member: the name of the member within the struct. - * - */ -#define container_of(ptr, type, member) ({ \ - void *__mptr = (void *)(ptr); \ - BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \ - !__same_type(*(ptr), void), \ - "pointer type mismatch in container_of()"); \ - ((type *)(__mptr - offsetof(type, member))); }) - -/** - * container_of_safe - cast a member of a structure out to the containing structure - * @ptr: the pointer to the member. - * @type: the type of the container struct this is embedded in. - * @member: the name of the member within the struct. - * - * If IS_ERR_OR_NULL(ptr), ptr is returned unchanged. - */ -#define container_of_safe(ptr, type, member) ({ \ - void *__mptr = (void *)(ptr); \ - BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \ - !__same_type(*(ptr), void), \ - "pointer type mismatch in container_of()"); \ - IS_ERR_OR_NULL(__mptr) ? ERR_CAST(__mptr) : \ - ((type *)(__mptr - offsetof(type, member))); }) - /* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */ #ifdef CONFIG_FTRACE_MCOUNT_RECORD # define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD
When kernel.h is used in the headers it adds a lot into dependency hell, especially when there are circular dependencies are involved.
Replace kernel.h inclusion with the list of what is really being used.
Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com --- include/kunit/test.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/include/kunit/test.h b/include/kunit/test.h index 018e776a34b9..b26400731c02 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h @@ -11,11 +11,20 @@
#include <kunit/assert.h> #include <kunit/try-catch.h> -#include <linux/kernel.h> + +#include <linux/container_of.h> +#include <linux/err.h> +#include <linux/init.h> +#include <linux/kconfig.h> +#include <linux/kref.h> +#include <linux/list.h> #include <linux/module.h> #include <linux/slab.h> +#include <linux/spinlock.h> +#include <linux/string.h> #include <linux/types.h> -#include <linux/kref.h> + +#include <asm/rwonce.h>
struct kunit_resource;
When kernel.h is used in the headers it adds a lot into dependency hell, especially when there are circular dependencies are involved.
Replace kernel.h inclusion with the list of what is really being used.
Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com --- include/linux/list.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/linux/list.h b/include/linux/list.h index f2af4b4aa4e9..6636fc07f918 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -2,11 +2,13 @@ #ifndef _LINUX_LIST_H #define _LINUX_LIST_H
+#include <linux/container_of.h> #include <linux/types.h> #include <linux/stddef.h> #include <linux/poison.h> #include <linux/const.h> -#include <linux/kernel.h> + +#include <asm/barrier.h>
/* * Circular doubly linked list implementation.
Hi Andy,
I love your patch! Yet something to improve:
[auto build test ERROR on tip/locking/core] [also build test ERROR on media-tree/master linux/master linus/master v5.15-rc5 next-20211013] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Andy-Shevchenko/kernel-h-further-sp... base: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git dd0aa2cd2e9e3e49b8c3b43924dc1a1d4e22b4d1 config: um-x86_64_defconfig (attached as .config) compiler: gcc-9 (Debian 9.3.0-22) 9.3.0 reproduce (this is a W=1 build): # https://github.com/0day-ci/linux/commit/4797f8ad0f7b6807a7af02543f77c0ee1b34... git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Andy-Shevchenko/kernel-h-further-split/20211014-010532 git checkout 4797f8ad0f7b6807a7af02543f77c0ee1b340537 # save the attached .config to linux build tree mkdir build_dir make W=1 O=build_dir ARCH=um SUBARCH=x86_64 prepare
If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot lkp@intel.com
All errors (new ones prefixed by >>):
arch/x86/um/Makefile:44: FORCE prerequisite is missing In file included from include/linux/rcupdate.h:28, from include/linux/rculist.h:11, from include/linux/pid.h:5, from include/linux/sched.h:14, from arch/x86/um/shared/sysdep/kernel-offsets.h:3, from arch/um/kernel/asm-offsets.c:1: include/linux/bottom_half.h: In function 'local_bh_disable':
include/linux/bottom_half.h:19:24: error: '_THIS_IP_' undeclared (first use in this function)
19 | __local_bh_disable_ip(_THIS_IP_, SOFTIRQ_DISABLE_OFFSET); | ^~~~~~~~~ include/linux/bottom_half.h:19:24: note: each undeclared identifier is reported only once for each function it appears in include/linux/bottom_half.h: In function 'local_bh_enable': include/linux/bottom_half.h:32:23: error: '_THIS_IP_' undeclared (first use in this function) 32 | __local_bh_enable_ip(_THIS_IP_, SOFTIRQ_DISABLE_OFFSET); | ^~~~~~~~~ In file included from arch/um/kernel/asm-offsets.c:1: arch/x86/um/shared/sysdep/kernel-offsets.h: At top level: arch/x86/um/shared/sysdep/kernel-offsets.h:9:6: warning: no previous prototype for 'foo' [-Wmissing-prototypes] 9 | void foo(void) | ^~~ make[2]: *** [scripts/Makefile.build:121: arch/um/kernel/asm-offsets.s] Error 1 make[2]: Target '__build' not remade because of errors. make[1]: *** [Makefile:1225: prepare0] Error 2 make[1]: Target 'prepare' not remade because of errors. make: *** [Makefile:219: __sub-make] Error 2 make: Target 'prepare' not remade because of errors.
vim +/_THIS_IP_ +19 include/linux/bottom_half.h
0bd3a173d71185 Peter Zijlstra 2013-11-19 16 0bd3a173d71185 Peter Zijlstra 2013-11-19 17 static inline void local_bh_disable(void) 0bd3a173d71185 Peter Zijlstra 2013-11-19 18 { 0bd3a173d71185 Peter Zijlstra 2013-11-19 @19 __local_bh_disable_ip(_THIS_IP_, SOFTIRQ_DISABLE_OFFSET); 0bd3a173d71185 Peter Zijlstra 2013-11-19 20 } 0bd3a173d71185 Peter Zijlstra 2013-11-19 21
--- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi Andy,
I love your patch! Yet something to improve:
[auto build test ERROR on tip/locking/core] [also build test ERROR on media-tree/master linux/master linus/master v5.15-rc5 next-20211013] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Andy-Shevchenko/kernel-h-further-sp... base: https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git dd0aa2cd2e9e3e49b8c3b43924dc1a1d4e22b4d1 config: riscv-randconfig-r031-20211013 (attached as .config) compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project b6a8c695542b2987eb9a203d5663a0740cb4725f) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install riscv cross compiling tool for clang build # apt-get install binutils-riscv64-linux-gnu # https://github.com/0day-ci/linux/commit/4797f8ad0f7b6807a7af02543f77c0ee1b34... git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Andy-Shevchenko/kernel-h-further-split/20211014-010532 git checkout 4797f8ad0f7b6807a7af02543f77c0ee1b340537 # save the attached .config to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv prepare
If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot lkp@intel.com
All errors (new ones prefixed by >>):
In file included from arch/riscv/kernel/asm-offsets.c:10: In file included from include/linux/sched.h:14: In file included from include/linux/pid.h:5: In file included from include/linux/rculist.h:11: In file included from include/linux/rcupdate.h:28:
include/linux/bottom_half.h:19:24: error: use of undeclared identifier '_THIS_IP_'
__local_bh_disable_ip(_THIS_IP_, SOFTIRQ_DISABLE_OFFSET); ^ include/linux/bottom_half.h:32:23: error: use of undeclared identifier '_THIS_IP_' __local_bh_enable_ip(_THIS_IP_, SOFTIRQ_DISABLE_OFFSET); ^ 2 errors generated. make[2]: *** [scripts/Makefile.build:121: arch/riscv/kernel/asm-offsets.s] Error 1 make[2]: Target '__build' not remade because of errors. make[1]: *** [Makefile:1225: prepare0] Error 2 make[1]: Target 'prepare' not remade because of errors. make: *** [Makefile:219: __sub-make] Error 2 make: Target 'prepare' not remade because of errors.
vim +/_THIS_IP_ +19 include/linux/bottom_half.h
0bd3a173d71185 Peter Zijlstra 2013-11-19 16 0bd3a173d71185 Peter Zijlstra 2013-11-19 17 static inline void local_bh_disable(void) 0bd3a173d71185 Peter Zijlstra 2013-11-19 18 { 0bd3a173d71185 Peter Zijlstra 2013-11-19 @19 __local_bh_disable_ip(_THIS_IP_, SOFTIRQ_DISABLE_OFFSET); 0bd3a173d71185 Peter Zijlstra 2013-11-19 20 } 0bd3a173d71185 Peter Zijlstra 2013-11-19 21
--- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
When kernel.h is used in the headers it adds a lot into dependency hell, especially when there are circular dependencies are involved.
Replace kernel.h inclusion with the list of what is really being used.
Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com --- include/linux/llist.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/linux/llist.h b/include/linux/llist.h index 24f207b0190b..85bda2d02d65 100644 --- a/include/linux/llist.h +++ b/include/linux/llist.h @@ -49,7 +49,9 @@ */
#include <linux/atomic.h> -#include <linux/kernel.h> +#include <linux/container_of.h> +#include <linux/stddef.h> +#include <linux/types.h>
struct llist_head { struct llist_node *first;
When kernel.h is used in the headers it adds a lot into dependency hell, especially when there are circular dependencies are involved.
Replace kernel.h inclusion with the list of what is really being used.
Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com --- include/linux/plist.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/include/linux/plist.h b/include/linux/plist.h index 66bab1bca35c..0f352c1d3c80 100644 --- a/include/linux/plist.h +++ b/include/linux/plist.h @@ -73,8 +73,11 @@ #ifndef _LINUX_PLIST_H_ #define _LINUX_PLIST_H_
-#include <linux/kernel.h> +#include <linux/container_of.h> #include <linux/list.h> +#include <linux/types.h> + +#include <asm/bug.h>
struct plist_head { struct list_head node_list;
When kernel.h is used in the headers it adds a lot into dependency hell, especially when there are circular dependencies are involved.
Replace kernel.h inclusion with the list of what is really being used.
Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Acked-by: Sakari Ailus sakari.ailus@linux.intel.com --- include/media/media-entity.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 09737b47881f..fea489f03d57 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -13,10 +13,11 @@
#include <linux/bitmap.h> #include <linux/bug.h> +#include <linux/container_of.h> #include <linux/fwnode.h> -#include <linux/kernel.h> #include <linux/list.h> #include <linux/media.h> +#include <linux/types.h>
/* Enums used internally at the media controller to represent graphs */
linux-kselftest-mirror@lists.linaro.org