In-depth understanding of Linux memory Management Learning notes (ii) version 0.01

Source: Internet
Author: User
Initialize Mem_map

Mem_map is an array of struct page that manages all the physical memory pages in the system. Create and assign Mem_map memory areas during system startup. In the UMA architecture, the free_area_init () function assigns the NODE_MEM_MAP member to the global MEM_MAP variable in the system's unique struct node object contig_page_data. Diagram of the call:

The main core function, Free_area_init_core (), allocates the local Lmem_map (NODE->NODE_MEM_MAP) for the node initialization process. The memory of the array is allocated in the boot Memory Alloc_bootmem_node () function. In the UMA architecture, this newly allocated lmem_map becomes the global mem_map. For NUMA systems, Lmem_map is assigned to each node's Node_mem_map member, and in this case mem_map is simply assigned to Page_offset (read the original English version for more information about the NUMA architecture.) In the UMA system, the zone_mem_map of each zone in the node points to some element in the Mem_map as the address of the first page managed by zone. Middle Segment Ad

Linux Culture T-shirts, Taobao sales, interested in can buy.

Taobao Store Address:

Http://list.taobao.com/browse/search_auction.htm?user=b0ccaa7bfdc57fdec4594501767832b6&commend=all Page

Each physical page in the system is represented by a struct page data structure object, and the status of the page is tracked: (omitting some of the members used by a particular platform)

struct Page {
unsigned long flags;
atomic_t _count;
Union {
atomic_t _mapcount;
unsigned int inuse;
};
Union {
struct {
unsigned long private;
struct Address_space *mapping;
};
struct Kmem_cache *slab; /* Slub:pointer to Slab * *
struct page *first_page; /* Compound Tail pages * *
};
Union {
pgoff_t index; /* Our offset within mapping. */
void *freelist; /* slub:freelist req. Slab Lock/*
};
struct List_head LRU;

#if defined
(want_page_virtual
)
void *virtual;

};

Union {
atomic_t _mapcount;
unsigned int inuse;
: The PTE chain associated with page table conversions, as described in the following sections.

Index: This member has 2 possible meanings based on the purpose of page usage. The first scenario: if the page is part of the file mapping, it indicates the offset in the document. If the page is an Exchange cache, it indicates an offset in the object declared by Address_space: Swapper_space (the swap address space). Second: If this page is a page block that a particular process will release, this is the sequence value of the page block that will be freed, which is set in the __FREE_PAGE_OK () function.

Mapping: When a file or device requires a memory map, the Inode object for the file or device has a member of the Address_space type. If the page belongs to this file or device, mapping points to this member in the Inode. If the page does not belong to any file or device, but the mapping is set, mapping points to a Address_space type Swapper_space object, then the page is used to manage the swap address spaces (swap space).

Lru:page Exchange scheduling policy is used. Page may be dispatched to the Active_list or inactive_list queue. is to use LRU this list_head.

Private: This saves some specific information related to mapping (file mapping to memory). If the page is a buffer page, it saves a pointer to the Buffer_head.

Virtual: No longer used to map the high memory to the Zone_normal area, except for some other architectures that are used outside.

The Count:page access count, when 0 is, indicates that page is idle, and when greater than 0, the page is actually used by one or more processes or kernel is used to wait for I/O.

Flag information for the Flags:page status. The kernel code defines a large number of macros for setting, and clearly detects the page state information represented by the individual bits in the flag member. Specifically, setpageuptodate (), it needs to invoke an architecture-related function: Arch_set_page_uptodate ().

Map page to Zone (Mapping page to zones)

Before 2.4.18 the kernel, there was a member of the zone in the struct page data structure, which later proved wasteful to waste a lot of memory because there would be a lot of page objects in the system, so there would be no such members in later versions of the page, but an index that This index is stored in some bits in the flag member, which occupies 8 bits. A global zone array is established in the 2.6.19 version of the kernel system:

struct zone
 *zone_table
[1 << zonetable_shift
] __read_mostly
;
Export_symbol
(zone_table
);
The role of Export_symbol macros is to allow zone_table to be used by other loaded modules. The Free_area_init_core () function initializes all the page in node.
Zone_table[nid * Max_nr_zones + j] = Zone; Initialize the zone_table.
Nid is the node ID. J is the index of the zone.
For each page call Set_page_zone () initializes the index value (in Page->flag) of the zone in the page.
Set_page_zone (page, nid * Max_nr_zones + j);

But after 2.6.20 do not use this set, mm/sparse.c file to do a set of management system. The new method is to manage multiple page components.

Here is a little description, interested, you can read the SPARSE.C source code in detail. Kernel divides all the page into section management, and for the x86 platform, there are 64 sections, each of which manages (1<<26) or (1<<30) memory areas (for PAE-enabled cases).

Here are a few of the major define:

Include/asm-x86/sparsemem_32.h:

#ifdef CONFIG_X86_PAE
#define SECTION_SIZE_BITS 30
#define MAX_PHYSADDR_BITS 36
#define MAX_PHYSMEM_BITS 36
#else
#define SECTION_SIZE_BITS 26
#define MAX_PHYSADDR_BITS 32
#define MAX_PHYSMEM_BITS 32
#endifinclude/linux/mmzone.h: #define SECTIONS_SHIFT (max_physmem_bits-section_size_bits) #define Nr_mem_sections (1UL << sections_shift) #ifdef Config_sparsemem_extreme
#define SECTIONS_PER_ROOT (page_size/sizeof (struct mem_section))
#else
#define SECTIONS_PER_ROOT 1
#endif #define Section_nr_to_root (sec) (sec)/sections_per_root)
#define NR_SECTION_ROOTS (Nr_mem_sections/sections_per_root)
#define SECTION_ROOT_MASK (SECTIONS_PER_ROOT-1)

First, a global array of mem_section is declared.
struct Mem_section *mem_section[nr_section_roots];

Call the Sparse_add_one_section () function, assign the mem_section, and initialize it.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.