source: trunk/kernel/mm/ppm.h @ 625

Last change on this file since 625 was 625, checked in by alain, 2 years ago

Fix a bug in the vmm_remove_vseg() function: the physical pages
associated to an user DATA vseg were released to the kernel when
the target process descriptor was in the reference cluster.
This physical pages release should be done only when the page
forks counter value is zero.
All other modifications are cosmetic.

File size: 12.9 KB
Line 
1/*
2 * ppm.h - Per-cluster Physical Pages Manager definition.
3 *
4 * Authors  Ghassan Almaless (2008,2009,2010,2011,2012)
5 *          Alain Greiner    (2016,2017,2018,2019)
6 *
7 * Copyright (c) UPMC Sorbonne Universites
8 *
9 * This file is part of ALMOS-MKH.
10 *
11 * ALMOS-kernel is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2.0 of the License.
14 *
15 * ALMOS-kernel is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with ALMOS-kernel; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25#ifndef _PPM_H_
26#define _PPM_H_
27
28#include <hal_kernel_types.h>
29#include <list.h>
30#include <busylock.h>
31#include <remote_queuelock.h>
32#include <boot_info.h>
33#include <page.h>
34
35
36/*****************************************************************************************
37 * This structure defines the Physical Pages Manager in a cluster.
38 * In each cluster, the physical memory bank starts at local physical address 0 and
39 * contains an integer number of small pages, defined by the <pages_nr> field in the
40 * boot_info structure. It is split in three parts:
41 *
42 * - the "kernel_code" section contains the kernel code, loaded by the boot-loader.
43 *   It starts at local PPN = 0 and the size is defined by the <pages_offset> field
44 *   in the boot_info structure.
45 * - the local "pages_tbl" section contains the physical page descriptors array.
46 *   It starts at local PPN = pages_offset, and it contains one entry per small page.
47 *   It is created and initialized by the hal_ppm_create() function.
48 * - The "kernel_heap" section contains all physical pages that are are not in the
49 *   "kernel_code" and "pages_tbl" sections, and that have not been reserved.
50 *   The reserved pages are defined in the boot_info structure.
51 *
52 * The main service provided by the PMM is the dynamic allocation of physical pages
53 * from the "kernel_heap" section. This low-level allocator implements the buddy
54 * algorithm: an allocated block is an integer number n of small pages, where n
55 * is a power of 2, and ln(n) is called order.
56 * This allocator being shared by the local threads, the free_page lists rooted
57 * in the PPM descriptor are protected by a local busylock, because it is used
58 * by the idle_thread during kernel_init().
59 *
60 * Another service is to register the dirty pages in a specific dirty_list, that is
61 * also rooted in the PPM, in order to be able to synchronize all dirty pages on disk.
62 * This dirty list is protected by a specific remote_queuelock, because it can be
63 * modified by a remote thread, but it contains only local pages.
64 ****************************************************************************************/
65
66typedef struct ppm_s
67{
68        busylock_t          free_lock;          /*! lock protecting free_pages[] lists      */
69        list_entry_t        free_pages_root[CONFIG_PPM_MAX_ORDER];  /*! roots of free lists */
70        uint32_t            free_pages_nr[CONFIG_PPM_MAX_ORDER];    /*! free pages number   */
71        page_t            * pages_tbl;          /*! pointer on page descriptors array       */
72        uint32_t            pages_nr;           /*! total number of small physical page     */
73    remote_queuelock_t  dirty_lock;         /*! lock protecting dirty pages list        */
74    list_entry_t        dirty_root;         /*! root of dirty pages list                */
75    void              * vaddr_base;         /*! pointer on local physical memory base   */
76}
77ppm_t;
78
79/************** functions to allocate / release physical pages  *************************/
80
81/*****************************************************************************************
82 * This is the low-level physical pages allocation function.
83 * It allocates N contiguous physical pages. N is a power of 2.
84 * In normal use, it should not be called directly, as the recommended way to get
85 * physical pages is to call the generic allocator defined in kmem.h.
86 *****************************************************************************************
87 * @ order        : ln2( number of 4 Kbytes pages)
88 * @ returns a pointer on the page descriptor if success / NULL otherwise
89 ****************************************************************************************/
90page_t * ppm_alloc_pages( uint32_t order );
91
92/*****************************************************************************************
93 * This is the low-level physical pages release function. It takes the lock protecting
94 * the free_list before register the released page in the relevant free_list.
95 * In normal use, you do not need to call it directly, as the recommended way to free
96 * physical pages is to call the generic allocator defined in kmem.h.
97 *****************************************************************************************
98 * @ page         : pointer to the page descriptor to be released
99 ****************************************************************************************/
100void ppm_free_pages( page_t * page );
101
102/*****************************************************************************************
103 * This function does the same as the ppm_free_page() function, without taking the lock.
104 * It is used by the hal_ppm_init() function to initialize the pages_tbl[] array, when
105 * there is no concurrent access issue.
106 *****************************************************************************************
107 * @ page         : pointer to the page descriptor to be released
108 ****************************************************************************************/
109void ppm_free_pages_nolock( page_t * page );
110
111/*****************************************************************************************
112 * This function check if a page descriptor pointer is valid.
113 *****************************************************************************************
114 * @ page         : pointer on a page descriptor
115 * @ returns true if valid / false otherwise.
116 ****************************************************************************************/
117inline bool_t ppm_page_is_valid( page_t * page );
118
119
120/************** functions to translate [ page <->  base <-> ppn ] ***********************/
121
122/*****************************************************************************************
123 * Get extended pointer on page base from extended pointer on page descriptor.
124 *****************************************************************************************
125 * @ page_xp    : extended pointer to page descriptor
126 * @ returns extended pointer on page base.
127 ****************************************************************************************/
128inline xptr_t ppm_page2base( xptr_t page_xp );
129
130/*****************************************************************************************
131 * Get extended pointer on page descriptor from extended pointer on page base.
132 *****************************************************************************************
133 * @ base_xp   : extended pointer to page base.
134 * @ returns extended pointer on page descriptor
135 ****************************************************************************************/
136inline xptr_t ppm_base2page( xptr_t base_xp );
137
138/*****************************************************************************************
139 * Get extended pointer on page base from global PPN.
140 *****************************************************************************************
141 * @ ppn    : global physical page number.
142 * @ returns extended pointer on page base.
143 ****************************************************************************************/
144inline xptr_t ppm_ppn2base( ppn_t ppn );
145
146/*****************************************************************************************
147 * Get global PPN from extended pointer on page base.
148 *****************************************************************************************
149 * @ base_xp   : extended pointer to page base.
150 * @ returns global physical page number.
151 ****************************************************************************************/
152inline ppn_t ppm_base2ppn( xptr_t base_xp );
153
154/*****************************************************************************************
155 * Get global PPN from extended pointer on page descriptor.
156 *****************************************************************************************
157 * @ page_xp   : pointer to page descriptor
158 * @ returns global physical page number.
159 ****************************************************************************************/
160inline ppn_t ppm_page2ppn( xptr_t page_xp );
161
162/*****************************************************************************************
163 * Get extended pointer on page descriptor from global PPN.
164 *****************************************************************************************
165 * @ ppn       : global physical page number
166 * @ returns extended pointer on page descriptor.
167 ****************************************************************************************/
168inline xptr_t ppm_ppn2page( ppn_t ppn );
169
170
171/*********** debug  functions  **********************************************************/
172
173/*****************************************************************************************
174 * This function prints the PPM allocator status in the calling thread cluster.
175 *****************************************************************************************
176 * string   : character string printed in header
177 ****************************************************************************************/
178void ppm_display( void );
179
180/*****************************************************************************************
181 * This function checks PPM allocator consistency.
182 *****************************************************************************************
183 * @ ppm      : pointer on PPM allocator.
184 * @ return 0 if PPM is OK / return -1 if PPM not consistent.
185 ****************************************************************************************/
186error_t ppm_assert_order( ppm_t * ppm );
187
188
189/*********** functions to handle dirty pages  *******************************************/
190
191/*****************************************************************************************
192 * This function registers a page identified by the <page_xp> argument as dirty.
193 * It can be called by a thread running in any cluster.
194 * - it takes the queuelock protecting the PPM dirty_list.
195 * - it takes the busylock protecting the page flags.
196 * - it test the PG_DIRTY flag in the page descriptor.
197 *   . if page already dirty => do nothing
198 *   . it page not dirty => set the PG_DIRTY flag and register page in PPM dirty list.
199 * - it releases the busylock protecting the page flags.
200 * - it releases the queuelock protecting the PPM dirty_list.
201 *****************************************************************************************
202 * @ page_xp  : extended pointer on page descriptor.
203 * @ returns true if page was not dirty / returns false if page was dirty
204 ****************************************************************************************/
205bool_t ppm_page_do_dirty( xptr_t page_xp );
206
207/*****************************************************************************************
208 * This function unregisters a page identified by the <page_xp> argument as dirty.
209 * It can be called by a thread running in any cluster.
210 * - it takes the queuelock protecting the PPM dirty_list.
211 * - it takes the busylock protecting the page flags.
212 * - it test the PG_DIRTY flag in the page descriptor.
213 *   . if page not dirty => do nothing
214 *   . it page dirty => reset the PG_DIRTY flag and remove page from PPM dirty list.
215 * - it releases the busylock protecting the page flags.
216 * - it releases the queuelock protecting the PPM dirty_list.
217 *****************************************************************************************
218 * @ page_xp  : extended pointer on page descriptor.
219 * @ returns true if page was dirty / returns false if page was not dirty
220 ****************************************************************************************/
221bool_t ppm_page_undo_dirty( xptr_t page_xp );
222
223/*****************************************************************************************
224 * This function synchronizes (i.e. update the IOC device) all dirty pages in a cluster.
225 * - it takes the queuelock protecting the PPM dirty_list.
226 * - it scans the PPM dirty list, and for each page:
227 *   . it takes the lock protecting the page.
228 *   . it removes the page from the PPM dirty_list.
229 *   . it reset the PG_DIRTY flag.
230 *   . it releases the lock protecting the page.
231 * - it releases the queuelock protecting the PPM dirty_list.
232 $ The PPM dirty_list is empty when the sync operation completes.
233 ****************************************************************************************/
234void ppm_sync_dirty_pages( void );
235
236#endif  /* _PPM_H_ */
Note: See TracBrowser for help on using the repository browser.