Files
erofs-linux/include/linux/codetag.h
T
Suren Baghdasaryan 4835f747d3 alloc_tag: support for page allocation tag compression
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/[email protected]
Signed-off-by: Suren Baghdasaryan <[email protected]>
Reviewed-by: Pasha Tatashin <[email protected]>
Cc: Ard Biesheuvel <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Borislav Petkov (AMD) <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Daniel Gomez <[email protected]>
Cc: David Hildenbrand <[email protected]>
Cc: Davidlohr Bueso <[email protected]>
Cc: David Rientjes <[email protected]>
Cc: Dennis Zhou <[email protected]>
Cc: Johannes Weiner <[email protected]>
Cc: John Hubbard <[email protected]>
Cc: Jonathan Corbet <[email protected]>
Cc: Joonsoo Kim <[email protected]>
Cc: Kalesh Singh <[email protected]>
Cc: Kees Cook <[email protected]>
Cc: Kent Overstreet <[email protected]>
Cc: Liam R. Howlett <[email protected]>
Cc: Luis Chamberlain <[email protected]>
Cc: Matthew Wilcox <[email protected]>
Cc: Michal Hocko <[email protected]>
Cc: Mike Rapoport (Microsoft) <[email protected]>
Cc: Minchan Kim <[email protected]>
Cc: Paul E. McKenney <[email protected]>
Cc: Petr Pavlu <[email protected]>
Cc: Roman Gushchin <[email protected]>
Cc: Sami Tolvanen <[email protected]>
Cc: Sourav Panda <[email protected]>
Cc: Steven Rostedt (Google) <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Thomas Huth <[email protected]>
Cc: Uladzislau Rezki (Sony) <[email protected]>
Cc: Vlastimil Babka <[email protected]>
Cc: Xiongwei Song <[email protected]>
Cc: Yu Zhao <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
2024-11-07 14:25:16 -08:00

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 */