Node descriptor structure pg_data_t is declared in kernel header mmzone.h:
/* include/linux/mmzone.h */
typedef struct pglist_data {
struct zone node_zones[MAX_NR_ZONES];
struct zonelist node_zonelists[MAX_ZONELISTS];
int nr_zones;
#ifdef CONFIG_FLAT_NODE_MEM_MAP /* means !SPARSEMEM */
struct page *node_mem_map;
#ifdef CONFIG_PAGE_EXTENSION
struct page_ext *node_page_ext;
#endif
#endif
#ifndef CONFIG_NO_BOOTMEM
struct bootmem_data *bdata;
#endif
#ifdef CONFIG_MEMORY_HOTPLUG
spinlock_t node_size_lock;
#endif
unsigned long node_start_pfn;
unsigned long node_present_pages; /* total number of physical pages */
unsigned long node_spanned_pages;
int node_id;
wait_queue_head_t kswapd_wait;
wait_queue_head_t pfmemalloc_wait;
struct task_struct *kswapd;
int kswapd_order;
enum zone_type kswapd_classzone_idx;
#ifdef CONFIG_COMPACTION
int kcompactd_max_order;
enum zone_type kcompactd_classzone_idx;
wait_queue_head_t kcompactd_wait;
struct task_struct *kcompactd;
#endif
#ifdef CONFIG_NUMA_BALANCING
spinlock_t numabalancing_migrate_lock;
unsigned long numabalancing_migrate_next_window;
unsigned long numabalancing_migrate_nr_pages;
#endif
unsigned long totalreserve_pages;
#ifdef CONFIG_NUMA
unsigned long min_unmapped_pages;
unsigned long min_slab_pages;
#endif /* CONFIG_NUMA */
ZONE_PADDING(_pad1_)
spinlock_t lru_lock;
#ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
unsigned long first_deferred_pfn;
#endif /* CONFIG_DEFERRED_STRUCT_PAGE_INIT */
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
spinlock_t split_queue_lock;
struct list_head split_queue;
unsigned long split_queue_len;
#endif
unsigned int inactive_ratio;
unsigned long flags;
ZONE_PADDING(_pad2_)
struct per_cpu_nodestat __percpu *per_cpu_nodestats;
atomic_long_t vm_stat[NR_VM_NODE_STAT_ITEMS];
} pg_data_t;
Depending on the type of machine and kernel configuration chosen, various elements are compiled into this structure. We'll look at few important elements:
Field | Description |
node_zones | An array that holds zone instances for pages in this node. |
node_zonelists | An array that specifies preferred allocation order for zones in the node. |
nr_zones | Count of zones in the current node. |
node_mem_map | Pointer to list of page descriptors in the current node. |
bdata | Pointer to boot memory descriptor (discussed in later section) |
node_start_pfn | Holds frame number of the first physical page in this node; this value would be zero for UMA systems. |
node_present_pages | Total count of pages in the node |
node_spanned_pages | Total size of physical page range, including holes if any. |
node_id | Holds unique node identifier (nodes are numbered from zero) |
kswapd_wait | Wait queue of kswapd kernel thread |
kswapd | Pointer to task structure of kswapd kernel thread |
totalreserve_pages | Count of reserve pages not used for user space allocations |