source: trunk/kernel/mm/kmem.c @ 1

Last change on this file since 1 was 1, checked in by alain, 5 years ago

First import

File size: 6.8 KB
Line 
1/*
2 * kmem.c - kernel memory allocator implementation.
3 *
4 * Authors  Ghassan Almaless (2008,2009,2010,2011,2012)
5 *          Mohamed Lamine Karaoui (2015)
6 *          Alain Greiner (2016)
7 *
8 * Copyright (c) UPMC Sorbonne Universites
9 *
10 * This file is part of ALMOS-MKH.
11 *
12 * ALMOS-MKH is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; version 2.0 of the License.
15 *
16 * ALMOS-MKH is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
23 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <almos_config.h>
27#include <hal_types.h>
28#include <hal_special.h>
29#include <printk.h>
30#include <spinlock.h>
31#include <readlock.h>
32#include <memcpy.h>
33#include <khm.h>
34#include <ppm.h>
35#include <page.h>
36#include <cluster.h>
37#include <thread.h>
38#include <process.h>
39#include <device.h>
40#include <mapper.h>
41#include <vfs.h>
42#include <fatfs.h>
43#include <ramfs.h>
44#include <remote_sem.h>
45#include <remote_barrier.h>
46#include <mapper.h>
47#include <grdxt.h>
48#include <vseg.h>
49#include <kmem.h>
50
51/////////////////////////////////////////////////////////////////////////////////////////////
52// This global array is indexed by the Kernel Memory Object Type (defined in kmem.h)
53// It contains the size of fixed size objects type dynamically allocated by the KCMs.
54// This array should be consistent with the enum defined kmem.h.
55/////////////////////////////////////////////////////////////////////////////////////////////
56
57uint32_t  kmem_size_tbl[KMEM_TYPES_NR] =
58{
59    0,                        // 0  KMEM_PAGE is not a fixed size object
60    0,                        // 1  KMEM_GENERIC   
61    sizeof( kcm_t ),          // 2  KMEM_KCM
62    sizeof( vseg_t ),         // 3  KMEM_VSEG
63    sizeof( device_t ),       // 4  KMEM_DEVICE
64    sizeof( mapper_t ),       // 5  KMEM_MAPPER
65    sizeof( process_t ),      // 6  KMEM_PROCESS
66    0,                        // 7
67    0,                        // 8 
68    0,                        // 9 
69
70    sizeof( fatfs_inode_t ),  // 10 KMEM_FATFS_INODE
71    sizeof( fatfs_ctx_t ),    // 11 KMEM_FATFS_CTX
72    sizeof( ramfs_inode_t ),  // 12 KMEM_RAMFS_INODE
73    sizeof( ramfs_ctx_t ),    // 13 KMEM_RAMFS_CTX
74    sizeof( vfs_ctx_t ),      // 14 KMEM_VFS_CTX
75    sizeof( vfs_inode_t ),    // 15 KMEM_VFS_INODE
76    sizeof( vfs_dentry_t ),   // 16 KMEM_VFS_DENTRY
77    sizeof( vfs_file_t ),     // 17 KMEM_VFS_FILE
78    sizeof( remote_sem_t ),   // 18 KMEM_SEM
79    0,                        // 19
80
81    64,                       // 20 KMEM_64_BYTES
82    128,                      // 21 KMEM_128_BYTES
83    256,                      // 22 KMEM_256_BYTES
84    512,                      // 23 KMEM_512_BYTES
85    1024,                     // 24 KMEM_1024_BYTES
86    2048,                     // 25 KMEM_2048_BYTES
87};
88
89/////////////////////////////////////////////////////////////////////////////////////////////
90// This static function dynamically allocates and initializes a specific KCM allocator.
91// It uses the KCM allocator embedded in cluster manager, initialized by cluster_init().
92/////////////////////////////////////////////////////////////////////////////////////////////
93static error_t kmem_get_kcm( uint32_t type )
94{
95        kcm_t    * kcm;
96        error_t    error;
97
98    // check kmem object type
99    if( (type < 2) || (type >= KMEM_TYPES_NR) )
100    {
101        printk("\n[PANIC] in %s illegal request type\n", __FUNCTION__ );
102        hal_core_sleep();
103    }
104
105    cluster_t * cluster = LOCAL_CLUSTER;
106
107    // allocates memory for the requested KCM allocator
108        kcm = kcm_alloc( &cluster->kcm );
109        if( kcm == NULL )
110    {
111                printk("\n[ERROR] in %s : failed to create KCM type %d in cluster %x\n",
112               __FUNCTION__ , type , local_cxy );
113        return ENOMEM;
114    }
115
116    // initializes the new KCM allocator
117        error = kcm_init( kcm , type );
118
119        if( error )
120        {
121                printk("\n[ERROR] in %s : failed to init KCM type %d\n",
122               __FUNCTION__ , type , local_cxy );
123                return error;
124        }
125
126        cluster->kcm_tbl[type] = kcm;
127        hal_wbflush();
128
129        return 0;
130}
131 
132
133/////////////////////////////////////
134void * kmem_alloc( kmem_req_t * req )
135{
136        cluster_t * cluster = LOCAL_CLUSTER;
137
138        uint32_t    type;
139        uint32_t    size;    // ln( pages ) if PPM / bytes if KHM or BKM / unused if KCM
140        uint32_t    flags;
141        void      * ptr;     // local pointer on allocated memory buffer
142
143        type  = req->type;
144        size  = req->size;
145        flags = req->flags;
146 
147        kmem_dmsg("\n[INFO] %s in cluster %x : type %d, size %d, flags %x at cycle %d \n",
148                      __FUNCTION__, local_cxy , type, size, flags , hal_time_stamp() );
149
150        if( type >= KMEM_TYPES_NR )
151    {
152        printk("\n[PANIC] in %s illegal request type\n", __FUNCTION__ );
153        hal_core_sleep();
154    }
155 
156    // analyse request type
157        if( type ==  KMEM_PAGE )                       // PPM allocator
158    {       
159        // allocate the number of requested pages
160                ptr = (void*)ppm_alloc_pages( size );
161
162        // reset page if required
163                if( flags & AF_ZERO ) page_zero( (page_t*)ptr );
164        }
165    else if( type == KMEM_GENERIC )                // KHM allocator
166    {
167        // allocate memory from KHM
168                ptr = khm_alloc( &cluster->khm , size );
169
170        // reset memory if requested
171                if( flags & AF_ZERO ) memset( ptr , 0 , size );
172        }
173    else                                           // KCM allocator
174    {
175        uint32_t error = 0;
176
177        // initialize the KCM allocator if not already done
178            if( cluster->kcm_tbl[type] == NULL )
179            { 
180            spinlock_lock( &cluster->kcm_lock );
181                        error = kmem_get_kcm( type );
182            spinlock_unlock( &cluster->kcm_lock );
183            }
184
185        // allocate memory from KCM if success
186        if( error ) ptr = NULL;
187        else        ptr = kcm_alloc( cluster->kcm_tbl[type] );
188        }
189
190    if( ptr == NULL )
191    {
192            printk("\n[ERROR] in %s : failed for type %d, size %d, flags %x in cluster %x\n", 
193               __FUNCTION__ , type , size , flags , local_cxy );
194 
195            return NULL;
196    }
197
198        kmem_dmsg("\n[INFO] %s got ptr = %x in cluster %x at cycle %d\n",
199                  __FUNCTION__, (intptr_t)ptr , local_cxy , hal_time_stamp() );
200           
201        return ptr;
202
203} // end kmem_alloc()
204
205//////////////////////////////////
206void kmem_free( kmem_req_t * req )
207{
208        if( req->type >= KMEM_TYPES_NR )
209    {
210        printk("\n[PANIC] in %s : illegal request type\n", __FUNCTION__ );
211        hal_core_sleep();
212    }
213 
214        switch(req->type)
215        {
216            case KMEM_PAGE:
217                ppm_free_pages( (page_t*)req->ptr );
218                return;
219
220            case KMEM_GENERIC:
221            khm_free( req->ptr );
222                return;
223
224            default:
225                kcm_free( req->ptr );
226                return;
227        }
228}
229
230
Note: See TracBrowser for help on using the repository browser.