Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) .. SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) .. _physical_memory_model:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) =====================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) Physical Memory Model
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) =====================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) Physical memory in a system may be addressed in different ways. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) simplest case is when the physical memory starts at address 0 and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) spans a contiguous range up to the maximal address. It could be,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) however, that this range contains small holes that are not accessible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) for the CPU. Then there could be several contiguous ranges at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) completely distinct addresses. And, don't forget about NUMA, where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) different memory banks are attached to different CPUs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) Linux abstracts this diversity using one of the three memory models:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) FLATMEM, DISCONTIGMEM and SPARSEMEM. Each architecture defines what
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) memory models it supports, what the default memory model is and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) whether it is possible to manually override that default.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) .. note::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)    At time of this writing, DISCONTIGMEM is considered deprecated,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)    although it is still in use by several architectures.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) All the memory models track the status of physical page frames using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) struct page arranged in one or more arrays.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) Regardless of the selected memory model, there exists one-to-one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) mapping between the physical page frame number (PFN) and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) corresponding `struct page`.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) Each memory model defines :c:func:`pfn_to_page` and :c:func:`page_to_pfn`
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) helpers that allow the conversion from PFN to `struct page` and vice
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) versa.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) FLATMEM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) =======
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) The simplest memory model is FLATMEM. This model is suitable for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) non-NUMA systems with contiguous, or mostly contiguous, physical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) In the FLATMEM memory model, there is a global `mem_map` array that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) maps the entire physical memory. For most architectures, the holes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) have entries in the `mem_map` array. The `struct page` objects
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) corresponding to the holes are never fully initialized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) To allocate the `mem_map` array, architecture specific setup code should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) call :c:func:`free_area_init` function. Yet, the mappings array is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) usable until the call to :c:func:`memblock_free_all` that hands all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) memory to the page allocator.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) If an architecture enables `CONFIG_ARCH_HAS_HOLES_MEMORYMODEL` option,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) it may free parts of the `mem_map` array that do not cover the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) actual physical pages. In such case, the architecture specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) :c:func:`pfn_valid` implementation should take the holes in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) `mem_map` into account.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) With FLATMEM, the conversion between a PFN and the `struct page` is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) straightforward: `PFN - ARCH_PFN_OFFSET` is an index to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) `mem_map` array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) The `ARCH_PFN_OFFSET` defines the first page frame number for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) systems with physical memory starting at address different from 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) DISCONTIGMEM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) ============
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) The DISCONTIGMEM model treats the physical memory as a collection of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) `nodes` similarly to how Linux NUMA support does. For each node Linux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) constructs an independent memory management subsystem represented by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) `struct pglist_data` (or `pg_data_t` for short). Among other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) things, `pg_data_t` holds the `node_mem_map` array that maps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) physical pages belonging to that node. The `node_start_pfn` field of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) `pg_data_t` is the number of the first page frame belonging to that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) The architecture setup code should call :c:func:`free_area_init_node` for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) each node in the system to initialize the `pg_data_t` object and its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) `node_mem_map`.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) Every `node_mem_map` behaves exactly as FLATMEM's `mem_map` -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) every physical page frame in a node has a `struct page` entry in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) `node_mem_map` array. When DISCONTIGMEM is enabled, a portion of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) `flags` field of the `struct page` encodes the node number of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) node hosting that page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) The conversion between a PFN and the `struct page` in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) DISCONTIGMEM model became slightly more complex as it has to determine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) which node hosts the physical page and which `pg_data_t` object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) holds the `struct page`.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) Architectures that support DISCONTIGMEM provide :c:func:`pfn_to_nid`
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) to convert PFN to the node number. The opposite conversion helper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) :c:func:`page_to_nid` is generic as it uses the node number encoded in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) page->flags.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) Once the node number is known, the PFN can be used to index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) appropriate `node_mem_map` array to access the `struct page` and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) the offset of the `struct page` from the `node_mem_map` plus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) `node_start_pfn` is the PFN of that page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) SPARSEMEM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) =========
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) SPARSEMEM is the most versatile memory model available in Linux and it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) is the only memory model that supports several advanced features such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) as hot-plug and hot-remove of the physical memory, alternative memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) maps for non-volatile memory devices and deferred initialization of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) the memory map for larger systems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) The SPARSEMEM model presents the physical memory as a collection of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) sections. A section is represented with struct mem_section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) that contains `section_mem_map` that is, logically, a pointer to an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) array of struct pages. However, it is stored with some other magic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) that aids the sections management. The section size and maximal number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) of section is specified using `SECTION_SIZE_BITS` and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) `MAX_PHYSMEM_BITS` constants defined by each architecture that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) supports SPARSEMEM. While `MAX_PHYSMEM_BITS` is an actual width of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) physical address that an architecture supports, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) `SECTION_SIZE_BITS` is an arbitrary value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) The maximal number of sections is denoted `NR_MEM_SECTIONS` and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) defined as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) .. math::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)    NR\_MEM\_SECTIONS = 2 ^ {(MAX\_PHYSMEM\_BITS - SECTION\_SIZE\_BITS)}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) The `mem_section` objects are arranged in a two-dimensional array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) called `mem_sections`. The size and placement of this array depend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) on `CONFIG_SPARSEMEM_EXTREME` and the maximal possible number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) sections:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * When `CONFIG_SPARSEMEM_EXTREME` is disabled, the `mem_sections`
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)   array is static and has `NR_MEM_SECTIONS` rows. Each row holds a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)   single `mem_section` object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * When `CONFIG_SPARSEMEM_EXTREME` is enabled, the `mem_sections`
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)   array is dynamically allocated. Each row contains PAGE_SIZE worth of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)   `mem_section` objects and the number of rows is calculated to fit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)   all the memory sections.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) The architecture setup code should call sparse_init() to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) initialize the memory sections and the memory maps.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) With SPARSEMEM there are two possible ways to convert a PFN to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) corresponding `struct page` - a "classic sparse" and "sparse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) vmemmap". The selection is made at build time and it is determined by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) the value of `CONFIG_SPARSEMEM_VMEMMAP`.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) The classic sparse encodes the section number of a page in page->flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) and uses high bits of a PFN to access the section that maps that page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) frame. Inside a section, the PFN is the index to the array of pages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) The sparse vmemmap uses a virtually mapped memory map to optimize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) pfn_to_page and page_to_pfn operations. There is a global `struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) page *vmemmap` pointer that points to a virtually contiguous array of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) `struct page` objects. A PFN is an index to that array and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) offset of the `struct page` from `vmemmap` is the PFN of that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) To use vmemmap, an architecture has to reserve a range of virtual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) addresses that will map the physical pages containing the memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) map and make sure that `vmemmap` points to that range. In addition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) the architecture should implement :c:func:`vmemmap_populate` method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) that will allocate the physical memory and create page tables for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) virtual memory map. If an architecture does not have any special
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) requirements for the vmemmap mappings, it can use default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) :c:func:`vmemmap_populate_basepages` provided by the generic memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) management.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) The virtually mapped memory map allows storing `struct page` objects
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) for persistent memory devices in pre-allocated storage on those
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) devices. This storage is represented with struct vmem_altmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) that is eventually passed to vmemmap_populate() through a long chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) of function calls. The vmemmap_populate() implementation may use the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) `vmem_altmap` along with :c:func:`vmemmap_alloc_block_buf` helper to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) allocate memory map on the persistent memory device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) ZONE_DEVICE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) ===========
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) The `ZONE_DEVICE` facility builds upon `SPARSEMEM_VMEMMAP` to offer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) `struct page` `mem_map` services for device driver identified physical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) address ranges. The "device" aspect of `ZONE_DEVICE` relates to the fact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) that the page objects for these address ranges are never marked online,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) and that a reference must be taken against the device, not just the page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) to keep the memory pinned for active use. `ZONE_DEVICE`, via
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) :c:func:`devm_memremap_pages`, performs just enough memory hotplug to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) turn on :c:func:`pfn_to_page`, :c:func:`page_to_pfn`, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) :c:func:`get_user_pages` service for the given range of pfns. Since the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) page reference count never drops below 1 the page is never tracked as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) free memory and the page's `struct list_head lru` space is repurposed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) for back referencing to the host device / driver that mapped the memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) While `SPARSEMEM` presents memory as a collection of sections,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) optionally collected into memory blocks, `ZONE_DEVICE` users have a need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) for smaller granularity of populating the `mem_map`. Given that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) `ZONE_DEVICE` memory is never marked online it is subsequently never
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) subject to its memory ranges being exposed through the sysfs memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) hotplug api on memory block boundaries. The implementation relies on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) this lack of user-api constraint to allow sub-section sized memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ranges to be specified to :c:func:`arch_add_memory`, the top-half of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) memory hotplug. Sub-section support allows for 2MB as the cross-arch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) common alignment granularity for :c:func:`devm_memremap_pages`.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) The users of `ZONE_DEVICE` are:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * pmem: Map platform persistent memory to be used as a direct-I/O target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)   via DAX mappings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * hmm: Extend `ZONE_DEVICE` with `->page_fault()` and `->page_free()`
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)   event callbacks to allow a device-driver to coordinate memory management
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)   events related to device-memory, typically GPU memory. See
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)   Documentation/vm/hmm.rst.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * p2pdma: Create `struct page` objects to allow peer devices in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)   PCI/-E topology to coordinate direct-DMA operations between themselves,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)   i.e. bypass host memory.