mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-28 16:52:18 +00:00
4835f747d3
Implement support for storing page allocation tag references directly in the page flags instead of page extensions. sysctl.vm.mem_profiling boot parameter it extended to provide a way for a user to request this mode. Enabling compression eliminates memory overhead caused by page_ext and results in better performance for page allocations. However this mode will not work if the number of available page flag bits is insufficient to address all kernel allocations. Such condition can happen during boot or when loading a module. If this condition is detected, memory allocation profiling gets disabled with an appropriate warning. By default compression mode is disabled. Link: https://lkml.kernel.org/r/20241023170759.999909-7-surenb@google.com Signed-off-by: Suren Baghdasaryan <surenb@google.com> Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com> Cc: Ard Biesheuvel <ardb@kernel.org> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Borislav Petkov (AMD) <bp@alien8.de> Cc: Christoph Hellwig <hch@infradead.org> Cc: Daniel Gomez <da.gomez@samsung.com> Cc: David Hildenbrand <david@redhat.com> Cc: Davidlohr Bueso <dave@stgolabs.net> Cc: David Rientjes <rientjes@google.com> Cc: Dennis Zhou <dennis@kernel.org> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: John Hubbard <jhubbard@nvidia.com> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com> Cc: Kalesh Singh <kaleshsingh@google.com> Cc: Kees Cook <keescook@chromium.org> Cc: Kent Overstreet <kent.overstreet@linux.dev> Cc: Liam R. Howlett <Liam.Howlett@Oracle.com> Cc: Luis Chamberlain <mcgrof@kernel.org> Cc: Matthew Wilcox <willy@infradead.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Mike Rapoport (Microsoft) <rppt@kernel.org> Cc: Minchan Kim <minchan@google.com> Cc: Paul E. McKenney <paulmck@kernel.org> Cc: Petr Pavlu <petr.pavlu@suse.com> Cc: Roman Gushchin <roman.gushchin@linux.dev> Cc: Sami Tolvanen <samitolvanen@google.com> Cc: Sourav Panda <souravpanda@google.com> Cc: Steven Rostedt (Google) <rostedt@goodmis.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Thomas Huth <thuth@redhat.com> Cc: Uladzislau Rezki (Sony) <urezki@gmail.com> Cc: Vlastimil Babka <vbabka@suse.cz> Cc: Xiongwei Song <xiongwei.song@windriver.com> Cc: Yu Zhao <yuzhao@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
112 lines
3.4 KiB
C
112 lines
3.4 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* code tagging framework
|
|
*/
|
|
#ifndef _LINUX_CODETAG_H
|
|
#define _LINUX_CODETAG_H
|
|
|
|
#include <linux/types.h>
|
|
|
|
struct codetag_iterator;
|
|
struct codetag_type;
|
|
struct codetag_module;
|
|
struct seq_buf;
|
|
struct module;
|
|
|
|
#define CODETAG_SECTION_START_PREFIX "__start_"
|
|
#define CODETAG_SECTION_STOP_PREFIX "__stop_"
|
|
|
|
/*
|
|
* An instance of this structure is created in a special ELF section at every
|
|
* code location being tagged. At runtime, the special section is treated as
|
|
* an array of these.
|
|
*/
|
|
struct codetag {
|
|
unsigned int flags; /* used in later patches */
|
|
unsigned int lineno;
|
|
const char *modname;
|
|
const char *function;
|
|
const char *filename;
|
|
} __aligned(8);
|
|
|
|
union codetag_ref {
|
|
struct codetag *ct;
|
|
};
|
|
|
|
struct codetag_type_desc {
|
|
const char *section;
|
|
size_t tag_size;
|
|
void (*module_load)(struct codetag_type *cttype,
|
|
struct codetag_module *cmod);
|
|
void (*module_unload)(struct codetag_type *cttype,
|
|
struct codetag_module *cmod);
|
|
#ifdef CONFIG_MODULES
|
|
void (*module_replaced)(struct module *mod, struct module *new_mod);
|
|
bool (*needs_section_mem)(struct module *mod, unsigned long size);
|
|
void *(*alloc_section_mem)(struct module *mod, unsigned long size,
|
|
unsigned int prepend, unsigned long align);
|
|
void (*free_section_mem)(struct module *mod, bool used);
|
|
#endif
|
|
};
|
|
|
|
struct codetag_iterator {
|
|
struct codetag_type *cttype;
|
|
struct codetag_module *cmod;
|
|
unsigned long mod_id;
|
|
struct codetag *ct;
|
|
};
|
|
|
|
#ifdef MODULE
|
|
#define CT_MODULE_NAME KBUILD_MODNAME
|
|
#else
|
|
#define CT_MODULE_NAME NULL
|
|
#endif
|
|
|
|
#define CODE_TAG_INIT { \
|
|
.modname = CT_MODULE_NAME, \
|
|
.function = __func__, \
|
|
.filename = __FILE__, \
|
|
.lineno = __LINE__, \
|
|
.flags = 0, \
|
|
}
|
|
|
|
void codetag_lock_module_list(struct codetag_type *cttype, bool lock);
|
|
bool codetag_trylock_module_list(struct codetag_type *cttype);
|
|
struct codetag_iterator codetag_get_ct_iter(struct codetag_type *cttype);
|
|
struct codetag *codetag_next_ct(struct codetag_iterator *iter);
|
|
|
|
void codetag_to_text(struct seq_buf *out, struct codetag *ct);
|
|
|
|
struct codetag_type *
|
|
codetag_register_type(const struct codetag_type_desc *desc);
|
|
|
|
#if defined(CONFIG_CODE_TAGGING) && defined(CONFIG_MODULES)
|
|
|
|
bool codetag_needs_module_section(struct module *mod, const char *name,
|
|
unsigned long size);
|
|
void *codetag_alloc_module_section(struct module *mod, const char *name,
|
|
unsigned long size, unsigned int prepend,
|
|
unsigned long align);
|
|
void codetag_free_module_sections(struct module *mod);
|
|
void codetag_module_replaced(struct module *mod, struct module *new_mod);
|
|
void codetag_load_module(struct module *mod);
|
|
void codetag_unload_module(struct module *mod);
|
|
|
|
#else /* defined(CONFIG_CODE_TAGGING) && defined(CONFIG_MODULES) */
|
|
|
|
static inline bool
|
|
codetag_needs_module_section(struct module *mod, const char *name,
|
|
unsigned long size) { return false; }
|
|
static inline void *
|
|
codetag_alloc_module_section(struct module *mod, const char *name,
|
|
unsigned long size, unsigned int prepend,
|
|
unsigned long align) { return NULL; }
|
|
static inline void codetag_free_module_sections(struct module *mod) {}
|
|
static inline void codetag_module_replaced(struct module *mod, struct module *new_mod) {}
|
|
static inline void codetag_load_module(struct module *mod) {}
|
|
static inline void codetag_unload_module(struct module *mod) {}
|
|
|
|
#endif /* defined(CONFIG_CODE_TAGGING) && defined(CONFIG_MODULES) */
|
|
|
|
#endif /* _LINUX_CODETAG_H */
|