source: trunk/kernel/mm/mapper.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: 14.9 KB
Line 
1/*
2 * mapper.h - Kernel cache for VFS files/directories definition.
3 *
4 * Authors   Mohamed Lamine Karaoui (2015)
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-MKH 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-MKH 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-MKH; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25#ifndef _MAPPER_H_
26#define _MAPPER_H_
27
28#include <hal_kernel_types.h>
29#include <hal_atomic.h>
30#include <xlist.h>
31#include <grdxt.h>
32#include <rwlock.h>
33
34/****  Forward declarations ****/
35
36struct page_s;
37struct vfs_inode_s;
38
39/*******************************************************************************************
40 * This mapper_t object implements the kernel cache for a given VFS file or directory.
41 * There is one mapper per file/dir. It is implemented as a three levels radix tree,
42 * entirely stored in the same cluster as the inode representing the file/dir.
43 * - The fast retrieval key is the page index in the file.
44 *   The ix1_width, ix2_width, ix3_width sub-indexes are configuration parameters.
45 * - The leaves are pointers on physical page descriptors, dynamically allocated
46 *   in the local cluster.
47 * - The mapper is protected by a "remote_rwlock", to support several simultaneous
48 *   "readers", and only one "writer".
49 * - A "reader" thread, calling the mapper_remote_get_page() function to get a page
50 *   descriptor pointer from the page index in file, can be running in any cluster.
51 * - A "writer" thread, calling the mapper_handle_miss() function to handle a page miss
52 *   must be local (running in the mapper cluster).
53 * - The vfs_fs_move_page() function access the file system to handle a mapper miss,
54 *   or update a dirty page on device.
55 * - The vfs_mapper_load_all() functions is used to load all pages of a directory
56 *   into the mapper (prefetch).
57 * - the mapper_move_user() function is used to move data to or from an user buffer.
58 *   This user space buffer can be physically distributed in several clusters.
59 * - the mapper_move_kernel() function is used to move data to or from a remote kernel
60 *   buffer, that can be physically located in any cluster.
61 * - In the present implementation the cache size for a given file increases on demand,
62 *   and the  allocated memory is only released when the mapper/inode is destroyed.
63 *
64 * TODO : the mapper being only used to implement the VFS cache(s), the mapper.c
65 *        and mapper.h file should be trandfered to the fs directory.
66 ******************************************************************************************/
67
68
69/*******************************************************************************************
70 * This structure defines the mapper descriptor.
71 ******************************************************************************************/
72
73typedef struct mapper_s
74{
75        struct vfs_inode_s * inode;           /*! owner inode                                     */
76    uint32_t             type;        /*! file system type                                */
77        grdxt_t              rt;              /*! embedded pages cache descriptor (radix tree)    */
78        remote_rwlock_t      lock;        /*! several readers / only one writer               */
79        uint32_t                 refcount;    /*! several vsegs can refer the same file           */
80        xlist_entry_t        vsegs_root;  /*! root of list of vsegs refering this mapper      */
81        xlist_entry_t        wait_root;   /*! root of list of threads waiting on mapper       */
82    list_entry_t         dirty_root;  /*! root of list of dirty pages                     */
83}
84mapper_t;
85
86/*******************************************************************************************
87 * This function allocates physical memory for a mapper descriptor, and initializes it
88 * (refcount <= 0) / inode <= NULL).
89 * It must be executed by a thread running in the cluster containing the mapper.
90 *******************************************************************************************
91 * @ type   : type of the mapper to create.
92 * @ return : pointer on created mapper if success / return NULL if no memory
93 ******************************************************************************************/
94mapper_t * mapper_create( vfs_fs_type_t type );
95
96/*******************************************************************************************
97 * This function releases all physical memory allocated for a mapper.
98 * Both the mapper descriptor and the radix tree are released.
99 * It does NOT synchronize dirty pages. Use the vfs_sync_inode() function if required.
100 * It must be executed by a thread running in the cluster containing the mapper.
101 *******************************************************************************************
102 * @ mapper      : target mapper.
103 ******************************************************************************************/
104void mapper_destroy( mapper_t * mapper );
105
106/*******************************************************************************************
107 * This function load from device a missing page identified by the <page_id> argument
108 * into the mapper identified by the <mapper> local pointer.
109 * It allocates a physical page from the local cluster, initialise by accessing device,
110 * and register the page in the mapper radix tree.
111 * It must be executed by a thread running in the cluster containing the mapper.
112 * WARNING : the calling function mapper_remote_get_page() is supposed to take and release
113 * the lock protecting the mapper in WRITE_MODE.
114 *******************************************************************************************
115 * @ mapper      : [in]  target mapper.
116 * @ page_id : [in]  missing page index in file.
117 * @ page_xp : [out] buffer for extended pointer on missing page descriptor.
118 * @ return 0 if success / return -1 if a dirty page cannot be updated on device.
119 ******************************************************************************************/
120error_t mapper_handle_miss( mapper_t * mapper,
121                            uint32_t   page_id,
122                            xptr_t   * page_xp );
123
124/*******************************************************************************************
125 * This function move data between a remote mapper, identified by the <mapper_xp> argument,
126 * and a distributed user buffer. It can be called by a thread running in any cluster.
127 * It is called by the vfs_user_move() to implement sys_read() and sys_write() syscalls.
128 * If required, the data transfer is split in "fragments", where one fragment contains
129 * contiguous bytes in the same mapper page.
130 * It uses "hal_uspace" accesses to move a fragment to/from the user buffer.
131 * In case of write, the dirty bit is set for all pages written in the mapper.
132 * The mapper being an extendable cache, it is automatically extended when required.
133 * The "offset" field in the file descriptor, and the "size" field in inode descriptor
134 * are not modified by this function.
135 *******************************************************************************************
136 * @ mapper_xp    : extended pointer on mapper.
137 * @ to_buffer    : mapper -> buffer if true / buffer -> mapper if false.
138 * @ file_offset  : first byte to move in file.
139 * @ u_buf        : user space pointer on user buffer.
140 * @ size         : number of bytes to move.
141 * returns O if success / returns -1 if error.
142 ******************************************************************************************/
143error_t mapper_move_user( xptr_t     mapper_xp,
144                          bool_t     to_buffer,
145                          uint32_t   file_offset,
146                          void     * u_buf,
147                          uint32_t   size );
148
149/********************************************************************************************
150 * This function move data between a remote mapper, identified by the <mapper_xp> argument,
151 * and a localised remote kernel buffer. It can be called by a thread running any cluster.
152 * If required, the data transfer is split in "fragments", where one fragment contains
153 * contiguous bytes in the same mapper page.
154 * It uses a "remote_memcpy" to move a fragment to/from the kernel buffer.
155 * In case of write, the dirty bit is set for all pages written in the mapper.
156 *******************************************************************************************
157 * @ mapper_xp    : extended pointer on mapper.
158 * @ to_buffer    : mapper -> buffer if true / buffer -> mapper if false.
159 * @ file_offset  : first byte to move in file.
160 * @ buffer_xp    : extended pointer on kernel buffer.
161 * @ size         : number of bytes to move.
162 * returns O if success / returns -1 if error.
163 ******************************************************************************************/
164error_t mapper_move_kernel( xptr_t     mapper_xp,
165                            bool_t     to_buffer,
166                            uint32_t   file_offset,
167                            xptr_t     buffer_xp,
168                            uint32_t   size );
169
170/*******************************************************************************************
171 * This function removes a physical page from the mapper, and releases
172 * the page to the local PPM. It is called by the mapper_destroy() function.
173 * It must be executed by a thread running in the cluster containing the mapper.
174 * It takes the mapper lock in WRITE_MODE to update the mapper.
175 *******************************************************************************************
176 * @ mapper     : local pointer on the mapper.
177 * @ page       : pointer on page to remove.
178 ******************************************************************************************/
179void mapper_release_page( mapper_t      * mapper,
180                          struct page_s * page );
181
182/*******************************************************************************************
183 * This function returns an extended pointer on a page descriptor.
184 * The - possibly remote - mapper is identified by the <mapper_xp> argument.
185 * The page is identified by <page_id> argument (page index in the file).
186 * It can be executed by a thread running in any cluster, as it uses remote
187 * access primitives to scan the mapper.
188 * In case of miss, this function takes the mapper lock in WRITE_MODE, and call the
189 * mapper_handle_miss() to load the missing page from device to mapper, using an RPC
190 * when the mapper is remote.
191 *******************************************************************************************
192 * @ mapper_xp  : extended pointer on the mapper.
193 * @ page_id    : page index in file
194 * @ returns extended pointer on page descriptor if success / return XPTR_NULL if error.
195 ******************************************************************************************/
196xptr_t mapper_remote_get_page( xptr_t    mapper_xp,
197                               uint32_t  page_id );
198
199/*******************************************************************************************
200 * This function allows to read a single word in a mapper seen as and array of uint32_t.
201 * It has bee designed to support remote access to the FAT mapper of the FATFS.
202 * It can be called by any thread running in any cluster.
203 * In case of miss, it takes the mapper lock in WRITE_MODE, load the missing
204 * page from device to mapper, and release the mapper lock.
205 *******************************************************************************************
206 * @ mapper_xp  : [in]  extended pointer on the mapper.
207 * @ word_id    : [in]  32 bits word index in file.
208 * @ p_value    : [out] local pointer on destination buffer.
209 * @ returns 0 if success / return -1 if error.
210 ******************************************************************************************/
211error_t mapper_remote_get_32( xptr_t     mapper_xp,
212                              uint32_t   word_id,
213                              uint32_t * p_value );
214
215/*******************************************************************************************
216 * This function allows to write a single word to a mapper seen as and array of uint32_t.
217 * It has been designed to support remote access to the FAT mapper of the FATFS.
218 * It can be called by any thread running in any cluster.
219 * In case of miss, it takes the mapper lock in WRITE_MODE, load the missing
220 * page from device to mapper, and release the mapper lock.
221 *******************************************************************************************
222 * @ mapper_xp  : [in]  extended pointer on the mapper.
223 * @ word_id    : [in]  32 bits word index in file.
224 * @ value      : [in]  value to be written.
225 * @ returns 0 if success / return -1 if error.
226 ******************************************************************************************/
227error_t mapper_remote_set_32( xptr_t     mapper_xp,
228                              uint32_t   word_id,
229                              uint32_t   value );
230
231/*******************************************************************************************
232 * This scans all pages present in the mapper identified by the <mapper> argument,
233 * and synchronize all pages maked as dirty" on disk.
234 * These pages are unmarked and removed from the local PPM dirty_list.
235 * This function must be called by a local thread running in same cluster as the mapper.
236 * A remote thread must call the RPC_MAPPER_SYNC function.
237 *******************************************************************************************
238 * @ mapper     : [in]  local pointer on local mapper.
239 * @ returns 0 if success / return -1 if error.
240 ******************************************************************************************/
241error_t mapper_sync( mapper_t *  mapper );
242
243/*******************************************************************************************
244 * This debug function displays the content of a given page of a given mapper.
245 * - the mapper is identified by the <mapper_xp> argument.
246 * - the page is identified by the <page_id> argument.
247 * - the number of bytes to display in page is defined by the <nbytes> argument.
248 * The format is eigth (32 bits) words per line in hexadecimal.
249 * It can be called by any thread running in any cluster.
250 * In case of miss in mapper, it load the missing page from device to mapper.
251 *******************************************************************************************
252 * @ mapper_xp  : [in]  extended pointer on the mapper.
253 * @ page_id    : [in]  page index in file.
254 * @ nbytes     : [in]  value to be written.
255 * @ returns 0 if success / return -1 if error.
256 ******************************************************************************************/
257error_t mapper_display_page( xptr_t     mapper_xp,
258                             uint32_t   page_id,
259                             uint32_t   nbytes );
260
261
262#endif /* _MAPPER_H_ */
Note: See TracBrowser for help on using the repository browser.