Something went wrong. Try again.
(I'm so sorry!) Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242/* SPDX-License-Identifier: GPL-2.0 *//* * include/linux/memory.h - generic memory definition * * This is mainly for topological representation. We define the * basic "struct memory_block" here, which can be embedded in per-arch * definitions or NUMA information. * * Basic handling of the devices is done in drivers/base/memory.c * and system devices are handled in drivers/base/sys.c. * * Memory block are exported via sysfs in the class/memory/devices/ * directory. * */#ifndef _LINUX_MEMORY_H_#define _LINUX_MEMORY_H_
#include <linux/node.h>#include <linux/compiler.h>#include <linux/mutex.h>#include <linux/memory_hotplug.h>#include <linux/range.h>
#define MIN_MEMORY_BLOCK_SIZE (1UL << SECTION_SIZE_BITS)
/** * struct memory_group - a logical group of memory blocks * @nid: The node id for all memory blocks inside the memory group. * @memory_blocks: List of all memory blocks belonging to this memory group. * @present_kernel_pages: Present (online) memory outside ZONE_MOVABLE of this * memory group. * @present_movable_pages: Present (online) memory in ZONE_MOVABLE of this * memory group. * @is_dynamic: The memory group type: static vs. dynamic * @s.max_pages: Valid with &memory_group.is_dynamic == false. The maximum * number of pages we'll have in this static memory group. * @d.unit_pages: Valid with &memory_group.is_dynamic == true. Unit in pages * in which memory is added/removed in this dynamic memory group. * This granularity defines the alignment of a unit in physical * address space; it has to be at least as big as a single * memory block. * * A memory group logically groups memory blocks; each memory block * belongs to at most one memory group. A memory group corresponds to * a memory device, such as a DIMM or a NUMA node, which spans multiple * memory blocks and might even span multiple non-contiguous physical memory * ranges. * * Modification of members after registration is serialized by memory * hot(un)plug code. */struct memory_group { int nid; struct list_head memory_blocks; unsigned long present_kernel_pages; unsigned long present_movable_pages; bool is_dynamic; union { struct { unsigned long max_pages; } s; struct { unsigned long unit_pages; } d; };};
enum memory_block_state { /* These states are exposed to userspace as text strings in sysfs */ MEM_ONLINE, /* exposed to userspace */ MEM_GOING_OFFLINE, /* exposed to userspace */ MEM_OFFLINE, /* exposed to userspace */ MEM_GOING_ONLINE, MEM_CANCEL_ONLINE, MEM_CANCEL_OFFLINE,};
struct memory_block { unsigned long start_section_nr; enum memory_block_state state; /* serialized by the dev->lock */ enum mmop online_type; /* for passing data to online routine */ int nid; /* NID for this memory block */ /* * The single zone of this memory block if all PFNs of this memory block * that are System RAM (not a memory hole, not ZONE_DEVICE ranges) are * managed by a single zone. NULL if multiple zones (including nodes) * apply. */ struct zone *zone; struct device dev; struct vmem_altmap *altmap; struct memory_group *group; /* group (if any) for this block */ struct list_head group_next; /* next block inside memory group */#if defined(CONFIG_MEMORY_FAILURE) && defined(CONFIG_MEMORY_HOTPLUG) atomic_long_t nr_hwpoison;#endif};
int arch_get_memory_phys_device(unsigned long start_pfn);unsigned long memory_block_size_bytes(void);int set_memory_block_size_order(unsigned int order);
/** * memory_block_aligned_range - align a physical address range to memory blocks * @range: the input range to align * * Aligns the start address up and the end address down to memory block * boundaries. This is required for memory hotplug operations which must * operate on memory-block aligned ranges. * * Returns the aligned range. Callers should check that the returned * range is valid (aligned.start < aligned.end) before using it. */static inline struct range memory_block_aligned_range(const struct range *range){ struct range aligned;
aligned.start = ALIGN(range->start, memory_block_size_bytes()); aligned.end = ALIGN_DOWN(range->end + 1, memory_block_size_bytes()); /* No whole block fits (e.g. range below the first boundary): empty. */ if (aligned.end <= aligned.start) aligned.start = aligned.end; else aligned.end -= 1;
return aligned;}
struct memory_notify { unsigned long start_pfn; unsigned long nr_pages;};
struct notifier_block;struct mem_section;
/* * Priorities for the hotplug memory callback routines. Invoked from * high to low. Higher priorities correspond to higher numbers. */#define DEFAULT_CALLBACK_PRI 0#define SLAB_CALLBACK_PRI 1#define CXL_CALLBACK_PRI 5#define HMAT_CALLBACK_PRI 6#define MM_COMPUTE_BATCH_PRI 10#define CPUSET_CALLBACK_PRI 10#define MEMTIER_HOTPLUG_PRI 100#define KSM_CALLBACK_PRI 100
#ifndef CONFIG_MEMORY_HOTPLUGstatic inline void memory_dev_init(void){ return;}static inline int register_memory_notifier(struct notifier_block *nb){ return 0;}static inline void unregister_memory_notifier(struct notifier_block *nb){}static inline int memory_notify(enum memory_block_state state, void *v){ return 0;}static inline int hotplug_memory_notifier(notifier_fn_t fn, int pri){ return 0;}static inline int memory_block_advise_max_size(unsigned long size){ return -ENODEV;}static inline unsigned long memory_block_advised_max_size(void){ return 0;}#else /* CONFIG_MEMORY_HOTPLUG */extern int register_memory_notifier(struct notifier_block *nb);extern void unregister_memory_notifier(struct notifier_block *nb);int create_memory_block_devices(unsigned long start, unsigned long size, int nid, struct vmem_altmap *altmap, struct memory_group *group);void remove_memory_block_devices(unsigned long start, unsigned long size);extern void memory_dev_init(void);extern int memory_notify(enum memory_block_state state, void *v);struct memory_block *memory_block_get(unsigned long block_id);static inline void memory_block_put(struct memory_block *mem){ put_device(&mem->dev);}typedef int (*walk_memory_blocks_func_t)(struct memory_block *, void *);extern int walk_memory_blocks(unsigned long start, unsigned long size, void *arg, walk_memory_blocks_func_t func);extern int for_each_memory_block(void *arg, walk_memory_blocks_func_t func);
extern int memory_group_register_static(int nid, unsigned long max_pages);extern int memory_group_register_dynamic(int nid, unsigned long unit_pages);extern int memory_group_unregister(int mgid);struct memory_group *memory_group_find_by_id(int mgid);typedef int (*walk_memory_groups_func_t)(struct memory_group *, void *);int walk_dynamic_memory_groups(int nid, walk_memory_groups_func_t func, struct memory_group *excluded, void *arg);#define hotplug_memory_notifier(fn, pri) ({ \ static __meminitdata struct notifier_block fn##_mem_nb =\ { .notifier_call = fn, .priority = pri };\ register_memory_notifier(&fn##_mem_nb); \})
extern int sections_per_block;
static inline unsigned long memory_block_id(unsigned long section_nr){ return section_nr / sections_per_block;}
static inline unsigned long pfn_to_block_id(unsigned long pfn){ return memory_block_id(pfn_to_section_nr(pfn));}
static inline unsigned long phys_to_block_id(unsigned long phys){ return pfn_to_block_id(PFN_DOWN(phys));}
#ifdef CONFIG_NUMAvoid memory_block_add_nid_early(struct memory_block *mem, int nid);#endif /* CONFIG_NUMA */int memory_block_advise_max_size(unsigned long size);unsigned long memory_block_advised_max_size(void);#endif /* CONFIG_MEMORY_HOTPLUG */
/* * Kernel text modification mutex, used for code patching. Users of this lock * can sleep. */extern struct mutex text_mutex;
#endif /* _LINUX_MEMORY_H_ */