From 59bb47985c1db229ccff8c5deebecd54fc77d2a9 Mon Sep 17 00:00:00 2001 From: Vlastimil Babka Date: Sun, 6 Oct 2019 17:58:45 -0700 Subject: mm, sl[aou]b: guarantee natural alignment for kmalloc(power-of-two) In most configurations, kmalloc() happens to return naturally aligned (i.e. aligned to the block size itself) blocks for power of two sizes. That means some kmalloc() users might unknowingly rely on that alignment, until stuff breaks when the kernel is built with e.g. CONFIG_SLUB_DEBUG or CONFIG_SLOB, and blocks stop being aligned. Then developers have to devise workaround such as own kmem caches with specified alignment [1], which is not always practical, as recently evidenced in [2]. The topic has been discussed at LSF/MM 2019 [3]. Adding a 'kmalloc_aligned()' variant would not help with code unknowingly relying on the implicit alignment. For slab implementations it would either require creating more kmalloc caches, or allocate a larger size and only give back part of it. That would be wasteful, especially with a generic alignment parameter (in contrast with a fixed alignment to size). Ideally we should provide to mm users what they need without difficult workarounds or own reimplementations, so let's make the kmalloc() alignment to size explicitly guaranteed for power-of-two sizes under all configurations. What this means for the three available allocators? * SLAB object layout happens to be mostly unchanged by the patch. The implicitly provided alignment could be compromised with CONFIG_DEBUG_SLAB due to redzoning, however SLAB disables redzoning for caches with alignment larger than unsigned long long. Practically on at least x86 this includes kmalloc caches as they use cache line alignment, which is larger than that. Still, this patch ensures alignment on all arches and cache sizes. * SLUB layout is also unchanged unless redzoning is enabled through CONFIG_SLUB_DEBUG and boot parameter for the particular kmalloc cache. With this patch, explicit alignment is guaranteed with redzoning as well. This will result in more memory being wasted, but that should be acceptable in a debugging scenario. * SLOB has no implicit alignment so this patch adds it explicitly for kmalloc(). The potential downside is increased fragmentation. While pathological allocation scenarios are certainly possible, in my testing, after booting a x86_64 kernel+userspace with virtme, around 16MB memory was consumed by slab pages both before and after the patch, with difference in the noise. [1] https://lore.kernel.org/linux-btrfs/c3157c8e8e0e7588312b40c853f65c02fe6c957a.1566399731.git.christophe.leroy@c-s.fr/ [2] https://lore.kernel.org/linux-fsdevel/20190225040904.5557-1-ming.lei@redhat.com/ [3] https://lwn.net/Articles/787740/ [akpm@linux-foundation.org: documentation fixlet, per Matthew] Link: http://lkml.kernel.org/r/20190826111627.7505-3-vbabka@suse.cz Signed-off-by: Vlastimil Babka Reviewed-by: Matthew Wilcox (Oracle) Acked-by: Michal Hocko Acked-by: Kirill A. Shutemov Acked-by: Christoph Hellwig Cc: David Sterba Cc: Christoph Lameter Cc: Pekka Enberg Cc: David Rientjes Cc: Ming Lei Cc: Dave Chinner Cc: "Darrick J . Wong" Cc: Christoph Hellwig Cc: James Bottomley Cc: Vlastimil Babka Cc: Joonsoo Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/core-api/memory-allocation.rst | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Documentation/core-api') diff --git a/Documentation/core-api/memory-allocation.rst b/Documentation/core-api/memory-allocation.rst index 7744aa3bf2e0..939e3dfc86e9 100644 --- a/Documentation/core-api/memory-allocation.rst +++ b/Documentation/core-api/memory-allocation.rst @@ -98,6 +98,10 @@ limited. The actual limit depends on the hardware and the kernel configuration, but it is a good practice to use `kmalloc` for objects smaller than page size. +The address of a chunk allocated with `kmalloc` is aligned to at least +ARCH_KMALLOC_MINALIGN bytes. For sizes which are a power of two, the +alignment is also guaranteed to be at least the respective size. + For large allocations you can use :c:func:`vmalloc` and :c:func:`vzalloc`, or directly request pages from the page allocator. The memory allocated by `vmalloc` and related functions is -- cgit v1.2.3 From fcfacb9f83745d9fa97937b8bc94a73bb0607912 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 8 Oct 2019 12:10:09 +0900 Subject: doc: move namespaces.rst from kbuild/ to core-api/ We discussed a better location for this file, and agreed that core-api/ is a good fit. Rename it to symbol-namespaces.rst for disambiguation, and also add it to index.rst and MAINTAINERS. Signed-off-by: Masahiro Yamada Acked-by: Matthias Maennich Signed-off-by: Jessica Yu --- Documentation/core-api/index.rst | 1 + Documentation/core-api/symbol-namespaces.rst | 154 +++++++++++++++++++++++++++ Documentation/kbuild/namespaces.rst | 154 --------------------------- MAINTAINERS | 1 + 4 files changed, 156 insertions(+), 154 deletions(-) create mode 100644 Documentation/core-api/symbol-namespaces.rst delete mode 100644 Documentation/kbuild/namespaces.rst (limited to 'Documentation/core-api') diff --git a/Documentation/core-api/index.rst b/Documentation/core-api/index.rst index fa16a0538dcb..ab0eae1c153a 100644 --- a/Documentation/core-api/index.rst +++ b/Documentation/core-api/index.rst @@ -38,6 +38,7 @@ Core utilities protection-keys ../RCU/index gcc-plugins + symbol-namespaces Interfaces for kernel debugging diff --git a/Documentation/core-api/symbol-namespaces.rst b/Documentation/core-api/symbol-namespaces.rst new file mode 100644 index 000000000000..982ed7b568ac --- /dev/null +++ b/Documentation/core-api/symbol-namespaces.rst @@ -0,0 +1,154 @@ +================= +Symbol Namespaces +================= + +The following document describes how to use Symbol Namespaces to structure the +export surface of in-kernel symbols exported through the family of +EXPORT_SYMBOL() macros. + +.. Table of Contents + + === 1 Introduction + === 2 How to define Symbol Namespaces + --- 2.1 Using the EXPORT_SYMBOL macros + --- 2.2 Using the DEFAULT_SYMBOL_NAMESPACE define + === 3 How to use Symbols exported in Namespaces + === 4 Loading Modules that use namespaced Symbols + === 5 Automatically creating MODULE_IMPORT_NS statements + +1. Introduction +=============== + +Symbol Namespaces have been introduced as a means to structure the export +surface of the in-kernel API. It allows subsystem maintainers to partition +their exported symbols into separate namespaces. That is useful for +documentation purposes (think of the SUBSYSTEM_DEBUG namespace) as well as for +limiting the availability of a set of symbols for use in other parts of the +kernel. As of today, modules that make use of symbols exported into namespaces, +are required to import the namespace. Otherwise the kernel will, depending on +its configuration, reject loading the module or warn about a missing import. + +2. How to define Symbol Namespaces +================================== + +Symbols can be exported into namespace using different methods. All of them are +changing the way EXPORT_SYMBOL and friends are instrumented to create ksymtab +entries. + +2.1 Using the EXPORT_SYMBOL macros +================================== + +In addition to the macros EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL(), that allow +exporting of kernel symbols to the kernel symbol table, variants of these are +available to export symbols into a certain namespace: EXPORT_SYMBOL_NS() and +EXPORT_SYMBOL_NS_GPL(). They take one additional argument: the namespace. +Please note that due to macro expansion that argument needs to be a +preprocessor symbol. E.g. to export the symbol `usb_stor_suspend` into the +namespace `USB_STORAGE`, use:: + + EXPORT_SYMBOL_NS(usb_stor_suspend, USB_STORAGE); + +The corresponding ksymtab entry struct `kernel_symbol` will have the member +`namespace` set accordingly. A symbol that is exported without a namespace will +refer to `NULL`. There is no default namespace if none is defined. `modpost` +and kernel/module.c make use the namespace at build time or module load time, +respectively. + +2.2 Using the DEFAULT_SYMBOL_NAMESPACE define +============================================= + +Defining namespaces for all symbols of a subsystem can be very verbose and may +become hard to maintain. Therefore a default define (DEFAULT_SYMBOL_NAMESPACE) +is been provided, that, if set, will become the default for all EXPORT_SYMBOL() +and EXPORT_SYMBOL_GPL() macro expansions that do not specify a namespace. + +There are multiple ways of specifying this define and it depends on the +subsystem and the maintainer's preference, which one to use. The first option +is to define the default namespace in the `Makefile` of the subsystem. E.g. to +export all symbols defined in usb-common into the namespace USB_COMMON, add a +line like this to drivers/usb/common/Makefile:: + + ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=USB_COMMON + +That will affect all EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL() statements. A +symbol exported with EXPORT_SYMBOL_NS() while this definition is present, will +still be exported into the namespace that is passed as the namespace argument +as this argument has preference over a default symbol namespace. + +A second option to define the default namespace is directly in the compilation +unit as preprocessor statement. The above example would then read:: + + #undef DEFAULT_SYMBOL_NAMESPACE + #define DEFAULT_SYMBOL_NAMESPACE USB_COMMON + +within the corresponding compilation unit before any EXPORT_SYMBOL macro is +used. + +3. How to use Symbols exported in Namespaces +============================================ + +In order to use symbols that are exported into namespaces, kernel modules need +to explicitly import these namespaces. Otherwise the kernel might reject to +load the module. The module code is required to use the macro MODULE_IMPORT_NS +for the namespaces it uses symbols from. E.g. a module using the +usb_stor_suspend symbol from above, needs to import the namespace USB_STORAGE +using a statement like:: + + MODULE_IMPORT_NS(USB_STORAGE); + +This will create a `modinfo` tag in the module for each imported namespace. +This has the side effect, that the imported namespaces of a module can be +inspected with modinfo:: + + $ modinfo drivers/usb/storage/ums-karma.ko + [...] + import_ns: USB_STORAGE + [...] + + +It is advisable to add the MODULE_IMPORT_NS() statement close to other module +metadata definitions like MODULE_AUTHOR() or MODULE_LICENSE(). Refer to section +5. for a way to create missing import statements automatically. + +4. Loading Modules that use namespaced Symbols +============================================== + +At module loading time (e.g. `insmod`), the kernel will check each symbol +referenced from the module for its availability and whether the namespace it +might be exported to has been imported by the module. The default behaviour of +the kernel is to reject loading modules that don't specify sufficient imports. +An error will be logged and loading will be failed with EINVAL. In order to +allow loading of modules that don't satisfy this precondition, a configuration +option is available: Setting MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS=y will +enable loading regardless, but will emit a warning. + +5. Automatically creating MODULE_IMPORT_NS statements +===================================================== + +Missing namespaces imports can easily be detected at build time. In fact, +modpost will emit a warning if a module uses a symbol from a namespace +without importing it. +MODULE_IMPORT_NS() statements will usually be added at a definite location +(along with other module meta data). To make the life of module authors (and +subsystem maintainers) easier, a script and make target is available to fixup +missing imports. Fixing missing imports can be done with:: + + $ make nsdeps + +A typical scenario for module authors would be:: + + - write code that depends on a symbol from a not imported namespace + - `make` + - notice the warning of modpost telling about a missing import + - run `make nsdeps` to add the import to the correct code location + +For subsystem maintainers introducing a namespace, the steps are very similar. +Again, `make nsdeps` will eventually add the missing namespace imports for +in-tree modules:: + + - move or add symbols to a namespace (e.g. with EXPORT_SYMBOL_NS()) + - `make` (preferably with an allmodconfig to cover all in-kernel + modules) + - notice the warning of modpost telling about a missing import + - run `make nsdeps` to add the import to the correct code location + diff --git a/Documentation/kbuild/namespaces.rst b/Documentation/kbuild/namespaces.rst deleted file mode 100644 index 982ed7b568ac..000000000000 --- a/Documentation/kbuild/namespaces.rst +++ /dev/null @@ -1,154 +0,0 @@ -================= -Symbol Namespaces -================= - -The following document describes how to use Symbol Namespaces to structure the -export surface of in-kernel symbols exported through the family of -EXPORT_SYMBOL() macros. - -.. Table of Contents - - === 1 Introduction - === 2 How to define Symbol Namespaces - --- 2.1 Using the EXPORT_SYMBOL macros - --- 2.2 Using the DEFAULT_SYMBOL_NAMESPACE define - === 3 How to use Symbols exported in Namespaces - === 4 Loading Modules that use namespaced Symbols - === 5 Automatically creating MODULE_IMPORT_NS statements - -1. Introduction -=============== - -Symbol Namespaces have been introduced as a means to structure the export -surface of the in-kernel API. It allows subsystem maintainers to partition -their exported symbols into separate namespaces. That is useful for -documentation purposes (think of the SUBSYSTEM_DEBUG namespace) as well as for -limiting the availability of a set of symbols for use in other parts of the -kernel. As of today, modules that make use of symbols exported into namespaces, -are required to import the namespace. Otherwise the kernel will, depending on -its configuration, reject loading the module or warn about a missing import. - -2. How to define Symbol Namespaces -================================== - -Symbols can be exported into namespace using different methods. All of them are -changing the way EXPORT_SYMBOL and friends are instrumented to create ksymtab -entries. - -2.1 Using the EXPORT_SYMBOL macros -================================== - -In addition to the macros EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL(), that allow -exporting of kernel symbols to the kernel symbol table, variants of these are -available to export symbols into a certain namespace: EXPORT_SYMBOL_NS() and -EXPORT_SYMBOL_NS_GPL(). They take one additional argument: the namespace. -Please note that due to macro expansion that argument needs to be a -preprocessor symbol. E.g. to export the symbol `usb_stor_suspend` into the -namespace `USB_STORAGE`, use:: - - EXPORT_SYMBOL_NS(usb_stor_suspend, USB_STORAGE); - -The corresponding ksymtab entry struct `kernel_symbol` will have the member -`namespace` set accordingly. A symbol that is exported without a namespace will -refer to `NULL`. There is no default namespace if none is defined. `modpost` -and kernel/module.c make use the namespace at build time or module load time, -respectively. - -2.2 Using the DEFAULT_SYMBOL_NAMESPACE define -============================================= - -Defining namespaces for all symbols of a subsystem can be very verbose and may -become hard to maintain. Therefore a default define (DEFAULT_SYMBOL_NAMESPACE) -is been provided, that, if set, will become the default for all EXPORT_SYMBOL() -and EXPORT_SYMBOL_GPL() macro expansions that do not specify a namespace. - -There are multiple ways of specifying this define and it depends on the -subsystem and the maintainer's preference, which one to use. The first option -is to define the default namespace in the `Makefile` of the subsystem. E.g. to -export all symbols defined in usb-common into the namespace USB_COMMON, add a -line like this to drivers/usb/common/Makefile:: - - ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=USB_COMMON - -That will affect all EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL() statements. A -symbol exported with EXPORT_SYMBOL_NS() while this definition is present, will -still be exported into the namespace that is passed as the namespace argument -as this argument has preference over a default symbol namespace. - -A second option to define the default namespace is directly in the compilation -unit as preprocessor statement. The above example would then read:: - - #undef DEFAULT_SYMBOL_NAMESPACE - #define DEFAULT_SYMBOL_NAMESPACE USB_COMMON - -within the corresponding compilation unit before any EXPORT_SYMBOL macro is -used. - -3. How to use Symbols exported in Namespaces -============================================ - -In order to use symbols that are exported into namespaces, kernel modules need -to explicitly import these namespaces. Otherwise the kernel might reject to -load the module. The module code is required to use the macro MODULE_IMPORT_NS -for the namespaces it uses symbols from. E.g. a module using the -usb_stor_suspend symbol from above, needs to import the namespace USB_STORAGE -using a statement like:: - - MODULE_IMPORT_NS(USB_STORAGE); - -This will create a `modinfo` tag in the module for each imported namespace. -This has the side effect, that the imported namespaces of a module can be -inspected with modinfo:: - - $ modinfo drivers/usb/storage/ums-karma.ko - [...] - import_ns: USB_STORAGE - [...] - - -It is advisable to add the MODULE_IMPORT_NS() statement close to other module -metadata definitions like MODULE_AUTHOR() or MODULE_LICENSE(). Refer to section -5. for a way to create missing import statements automatically. - -4. Loading Modules that use namespaced Symbols -============================================== - -At module loading time (e.g. `insmod`), the kernel will check each symbol -referenced from the module for its availability and whether the namespace it -might be exported to has been imported by the module. The default behaviour of -the kernel is to reject loading modules that don't specify sufficient imports. -An error will be logged and loading will be failed with EINVAL. In order to -allow loading of modules that don't satisfy this precondition, a configuration -option is available: Setting MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS=y will -enable loading regardless, but will emit a warning. - -5. Automatically creating MODULE_IMPORT_NS statements -===================================================== - -Missing namespaces imports can easily be detected at build time. In fact, -modpost will emit a warning if a module uses a symbol from a namespace -without importing it. -MODULE_IMPORT_NS() statements will usually be added at a definite location -(along with other module meta data). To make the life of module authors (and -subsystem maintainers) easier, a script and make target is available to fixup -missing imports. Fixing missing imports can be done with:: - - $ make nsdeps - -A typical scenario for module authors would be:: - - - write code that depends on a symbol from a not imported namespace - - `make` - - notice the warning of modpost telling about a missing import - - run `make nsdeps` to add the import to the correct code location - -For subsystem maintainers introducing a namespace, the steps are very similar. -Again, `make nsdeps` will eventually add the missing namespace imports for -in-tree modules:: - - - move or add symbols to a namespace (e.g. with EXPORT_SYMBOL_NS()) - - `make` (preferably with an allmodconfig to cover all in-kernel - modules) - - notice the warning of modpost telling about a missing import - - run `make nsdeps` to add the import to the correct code location - diff --git a/MAINTAINERS b/MAINTAINERS index 296de2b51c83..3dec8d53c34b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11543,6 +11543,7 @@ NSDEPS M: Matthias Maennich S: Maintained F: scripts/nsdeps +F: Documentation/core-api/symbol-namespaces.rst NTB AMD DRIVER M: Shyam Sundar S K -- cgit v1.2.3