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

Last change on this file since 582 was 567, checked in by alain, 6 years ago

Complete restructuration of kernel locks.

File size: 12.2 KB
RevLine 
[1]1/*
[567]2 * ppm.h - Per-cluster Physical Pages Manager definition.
[18]3 *
[1]4 * Authors  Ghassan Almaless (2008,2009,2010,2011,2012)
[567]5 *          Alain Greiner    (2016,2017,2018)
[1]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
[457]28#include <hal_kernel_types.h>
[1]29#include <list.h>
[567]30#include <busylock.h>
31#include <queuelock.h>
[1]32#include <boot_info.h>
33#include <page.h>
34
35
36/*****************************************************************************************
[409]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
[567]39 * contains an integer number of pages, defined by the <pages_nr> field in the
[50]40 * boot_info structure. It is split in three parts:
41 * - the "kernel_code" section contains the kernel code, loaded by the boot-loader.
42 *   It starts at PPN = 0 and the size is defined by the <pages_offset> field in the
43 *   boot_info structure.
44 * - the "pages_tbl" section contains the physical page descriptors array. It starts
45 *   at PPN = pages_offset, and it contains one entry per small physical page in cluster.
[567]46 *   It is created and initialized by the hal_ppm_create() function.
[50]47 * - The "kernel_heap" section contains all physical pages that are are not in the
[567]48 *   kernel_code and pages_tbl sections, and that have not been reserved by the
[50]49 *   architecture specific bootloader. The reserved pages are defined in the boot_info
50 *   structure.
[160]51 *
[50]52 * The main service provided by the PMM is the dynamic allocation of physical pages
[567]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 save all dirty pages on disk.
62 * This dirty list is protected by a specific local queuelock.
[1]63 ****************************************************************************************/
[50]64
[1]65typedef struct ppm_s
66{
[567]67        busylock_t     free_lock;               /*! lock protecting free_pages[] lists      */
[1]68        list_entry_t   free_pages_root[CONFIG_PPM_MAX_ORDER];  /*! roots of free lists      */
69        uint32_t       free_pages_nr[CONFIG_PPM_MAX_ORDER];    /*! numbers of free pages    */
70        page_t       * pages_tbl;               /*! pointer on page descriptors array       */
[50]71        uint32_t       pages_nr;                /*! total number of small physical page     */
[567]72    queuelock_t    dirty_lock;              /*! lock protecting dirty pages list        */
[1]73    list_entry_t   dirty_root;              /*! root of dirty pages list                */
[160]74    void         * vaddr_base;              /*! pointer on local physical memory base   */
[1]75}
76ppm_t;
77
[567]78/************** functions to allocate / release physical pages  *************************/
79
[1]80/*****************************************************************************************
81 * This is the low-level physical pages allocation function.
82 * It allocates N contiguous physical pages. N is a power of 2.
[18]83 * In normal use, you don't need to call it directly, as the recommended way to get
[1]84 * physical pages is to call the generic allocator defined in kmem.h.
[7]85 *****************************************************************************************
[1]86 * @ order        : ln2( number of 4 Kbytes pages)
87 * @ returns a pointer on the page descriptor if success / NULL otherwise
[50]88 **************************************************************************************à))**/
[1]89page_t * ppm_alloc_pages( uint32_t order );
90
91/*****************************************************************************************
[53]92 * This is the low-level physical pages release function. It takes the lock protecting
93 * the free_list before register the released page in the relevant free_list.
[18]94 * In normal use, you do not need to call it directly, as the recommended way to free
[1]95 * physical pages is to call the generic allocator defined in kmem.h.
[7]96 *****************************************************************************************
[1]97 * @ page         : pointer to the page descriptor to be released
98 ****************************************************************************************/
99void ppm_free_pages( page_t * page );
100
101/*****************************************************************************************
[53]102 * This function does the same as the ppm_free_page() function, without taking the lock.
103 * It is used by the hal_ppm_init() function to initialize the pages_tbl[] array, when
104 * there is no concurrent access issue.
105 *****************************************************************************************
106 * @ page         : pointer to the page descriptor to be released
107 ****************************************************************************************/
108void ppm_free_pages_nolock( page_t * page );
109
110/*****************************************************************************************
[50]111 * This function check if a page descriptor pointer is valid.
[7]112 *****************************************************************************************
[1]113 * @ page         : pointer on a page descriptor
114 * @ returns true if valid / false otherwise.
115 ****************************************************************************************/
116inline bool_t ppm_page_is_valid( page_t * page );
117
[315]118
[567]119/************** functions to translate [ page <->  base <-> ppn ] ***********************/
[315]120
[1]121/*****************************************************************************************
[315]122 * Get extended pointer on page base from extended pointer on page descriptor.
[7]123 *****************************************************************************************
[315]124 * @ page_xp    : extended pointer to page descriptor
125 * @ returns extended pointer on page base.
[1]126 ****************************************************************************************/
[315]127inline xptr_t ppm_page2base( xptr_t page_xp );
[1]128
129/*****************************************************************************************
[315]130 * Get extended pointer on page descriptor from extended pointer on page base.
[7]131 *****************************************************************************************
[315]132 * @ base_xp   : extended pointer to page base.
133 * @ returns extended pointer on page descriptor
[1]134 ****************************************************************************************/
[315]135inline xptr_t ppm_base2page( xptr_t base_xp );
[1]136
[315]137
138
[1]139/*****************************************************************************************
[407]140 * Get extended pointer on page base from global PPN.
[315]141 *****************************************************************************************
142 * @ ppn    : global physical page number.
143 * @ returns extended pointer on page base.
144 ****************************************************************************************/
145inline xptr_t ppm_ppn2base( ppn_t ppn );
146
147/*****************************************************************************************
148 * Get global PPN from extended pointer on page base.
149 *****************************************************************************************
150 * @ base_xp   : extended pointer to page base.
151 * @ returns global physical page number.
152 ****************************************************************************************/
153inline ppn_t ppm_base2ppn( xptr_t base_xp );
154
155
156
157/*****************************************************************************************
158 * Get global PPN from extended pointer on page descriptor.
159 *****************************************************************************************
160 * @ page_xp   : pointer to page descriptor
161 * @ returns global physical page number.
162 ****************************************************************************************/
163inline ppn_t ppm_page2ppn( xptr_t page_xp );
164
165/*****************************************************************************************
166 * Get extended pointer on page descriptor from global PPN.
167 *****************************************************************************************
168 * @ ppn       : global physical page number
169 * @ returns extended pointer on page descriptor.
170 ****************************************************************************************/
171inline xptr_t ppm_ppn2page( ppn_t ppn );
172
173
174
175/*****************************************************************************************
[433]176 * This function prints the PPM allocator status in the calling thread cluster.
[1]177 ****************************************************************************************/
[486]178void ppm_print( void );
[1]179
180/*****************************************************************************************
181 * This function checks PPM allocator consistency.
[7]182 *****************************************************************************************
[1]183 * @ ppm      : pointer on PPM allocator.
[53]184 * @ return 0 if PPM is OK / return -1 if PPM not consistent.
[1]185 ****************************************************************************************/
[53]186error_t ppm_assert_order( ppm_t * ppm );
[1]187
[567]188
189/*********** functions to handle dirty pages  *******************************************/
190
191/*****************************************************************************************
192 * This function registers a physical page as dirty.
193 * - it takes the queuelock protecting the PPM dirty_list.
194 * - it test the PG_DIRTY flag in the page descriptor.
195 *   . if page already dirty => do nothing
196 *   . it page not dirty => set the PG_DIRTY flag and register page in PPM dirty list.
197 * - it releases the queuelock protecting the PPM dirty_list.
198 *****************************************************************************************
199 * @ page     : pointer on page descriptor.
200 * @ returns true if page was not dirty / returns false if page was dirty
201 ****************************************************************************************/
202bool_t ppm_page_do_dirty( page_t * page );
203
204/*****************************************************************************************
205 * This function unregisters a physical page as dirty.
206 * - it takes the queuelock protecting the PPM dirty_list.
207 * - it test the PG_DIRTY flag in the page descriptor.
208 *   . if page not dirty => do nothing
209 *   . it page dirty => reset the PG_DIRTY flag and remove page from PPM dirty list.
210 * - it releases the queuelock protecting the PPM dirty_list.
211 *****************************************************************************************
212 * @ page     : pointer on page descriptor.
213 * @ returns true if page was dirty / returns false if page was not dirty
214 ****************************************************************************************/
215bool_t ppm_page_undo_dirty( page_t * page );
216
217/*****************************************************************************************
218 * This function synchronizes (i.e. update the disk) all dirty pages in a cluster.
219 * - it takes the queuelock protecting the PPM dirty_list.
220 * - it scans the PPM dirty list, and for each page:
221 *   . it takes the lock protecting the page.
222 *   . it removes the page from the PPM dirty_list.
223 *   . it reset the PG_DIRTY flag.
224 *   . it releases the lock protecting the page.
225 * - it releases the queuelock protecting the PPM dirty_list.
226 $ The PPM dirty_list is empty when the sync operation completes.
227 ****************************************************************************************/
228void ppm_sync_all_pages( void );
229
[1]230#endif  /* _PPM_H_ */
Note: See TracBrowser for help on using the repository browser.