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

Last change on this file since 673 was 672, checked in by alain, 4 years ago

1) Introduce up to 4 command lines arguments in the KSH "load" command.
These arguments are transfered to the user process through the
argc/argv mechanism, using the user space "args" vseg.

2) Introduce the named and anonymous "pipes", for inter-process communication
through the pipe() and mkfifo() syscalls.

3) Introduce the "chat" application to validate the two above mechanisms.

4) Improve printk() and assert() fonctions in printk.c.

File size: 7.4 KB
RevLine 
[1]1/*
2 * kmem.c - kernel memory allocator implementation.
3 *
[657]4 * Authors  Alain Greiner (2016,2017,2018,2019,2020)
[1]5 *
6 * Copyright (c) UPMC Sorbonne Universites
7 *
8 * This file is part of ALMOS-MKH.
9 *
10 * ALMOS-MKH is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2.0 of the License.
13 *
14 * ALMOS-MKH is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
[14]24#include <kernel_config.h>
[457]25#include <hal_kernel_types.h>
[1]26#include <hal_special.h>
27#include <printk.h>
[635]28#include <cluster.h>
[672]29#include <thread.h>
[1]30#include <memcpy.h>
31#include <khm.h>
32#include <ppm.h>
[635]33#include <kcm.h>
[1]34#include <page.h>
35#include <kmem.h>
36
[635]37/////////////////////////////////////
38void * kmem_alloc( kmem_req_t * req )
[7]39{
[635]40        uint32_t    type;    // KMEM_PPM / KMEM_KCM / KMEM_KHM
41        uint32_t    flags;   // AF_NONE / AF_ZERO / AF_KERNEL
42        uint32_t    order;   // PPM: ln(pages) / KCM: ln(bytes) / KHM: bytes
[1]43
[635]44        type  = req->type;
45        order = req->order;
46        flags = req->flags;
[7]47
[656]48    //////////////////////
[635]49        if( type == KMEM_PPM )
[159]50        {
[635]51                // allocate the number of requested pages
52                page_t * page_ptr = (void *)ppm_alloc_pages( order );
53
54                if( page_ptr == NULL )
[159]55                {
[635]56                        printk("\n[ERROR] in %s : PPM failed / order %d / cluster %x\n",
57                        __FUNCTION__ , order , local_cxy );
58                        return NULL;
[159]59                }
[7]60
[635]61        xptr_t page_xp = XPTR( local_cxy , page_ptr );
[1]62
[635]63                // reset page if requested
64                if( flags & AF_ZERO ) page_zero( page_ptr );
[619]65
[635]66        // get pointer on buffer from the page descriptor
67        void * ptr = GET_PTR( ppm_page2base( page_xp ) );
[50]68
[438]69#if DEBUG_KMEM
[635]70thread_t * this  = CURRENT_THREAD;
71uint32_t   cycle = (uint32_t)hal_get_cycles();
[438]72if( DEBUG_KMEM < cycle )
[635]73printk("\n[%s] thread[%x,%x] from PPM / %d page(s) / ppn %x / cxy %x / cycle %d\n",
74__FUNCTION__, this->process->pid, this->trdid,
751<<order, ppm_page2ppn(XPTR(local_cxy,ptr)), local_cxy, cycle );
[435]76#endif
[635]77        return ptr;
78        }
[656]79    ///////////////////////////
[635]80        else if( type == KMEM_KCM )
[159]81        {
[635]82                // allocate memory from KCM
83                void * ptr = kcm_alloc( order );
[1]84
[180]85                if( ptr == NULL )
86                {
[635]87                        printk("\n[ERROR] in %s : KCM failed / order %d / cluster %x\n",
88                    __FUNCTION__ , order , local_cxy );
[180]89                        return NULL;
90                }
[1]91
[635]92                // reset memory if requested
93                if( flags & AF_ZERO ) memset( ptr , 0 , 1<<order );
[18]94
[438]95#if DEBUG_KMEM
[635]96thread_t * this  = CURRENT_THREAD;
97uint32_t   cycle = (uint32_t)hal_get_cycles();
[438]98if( DEBUG_KMEM < cycle )
[635]99printk("\n[%s] thread [%x,%x] from KCM / %d bytes / base %x / cxy %x / cycle %d\n",
[611]100__FUNCTION__, this->process->pid, this->trdid,
[635]1011<<order, ptr, local_cxy, cycle ); 
[433]102#endif
[635]103        return ptr;
[1]104        }
[656]105    ///////////////////////////
[635]106        else if( type == KMEM_KHM )
[159]107        {
108                // allocate memory from KHM
[635]109                void * ptr = khm_alloc( &LOCAL_CLUSTER->khm , order );
110
[180]111                if( ptr == NULL )
112                {
[635]113                        printk("\n[ERROR] in %s : KHM failed / order %d / cluster %x\n",
114                        __FUNCTION__ , order , local_cxy );
[180]115                        return NULL;
116                }
[1]117
[159]118                // reset memory if requested
[635]119                if( flags & AF_ZERO ) memset( ptr , 0 , order );
[7]120
[438]121#if DEBUG_KMEM
[635]122thread_t * this  = CURRENT_THREAD;
123uint32_t   cycle = (uint32_t)hal_get_cycles();
[438]124if( DEBUG_KMEM < cycle )
[635]125printk("\n[%s] thread[%x,%x] from KHM / %d bytes / base %x / cxy %x / cycle %d\n",
[611]126__FUNCTION__, this->process->pid, this->trdid, 
[635]127order, ptr, local_cxy, cycle );
[435]128#endif
[635]129        return ptr;
130        }
131    else
132    {
133        printk("\n[ERROR] in %s : illegal allocator type\n", __FUNCTION__);
134        return NULL;
135    }
136}  // end kmem_alloc()
[435]137
[635]138//////////////////////////////////
139void kmem_free( kmem_req_t * req )
140{
141    uint32_t type = req->type;
142
[656]143    //////////////////////
[635]144        if( type == KMEM_PPM )
145        {
146        page_t * page = GET_PTR( ppm_base2page( XPTR( local_cxy , req->ptr ) ) );
147
148        ppm_free_pages( page );
149    }
[656]150    ///////////////////////////
[635]151    else if( type == KMEM_KCM )
152    {
153        kcm_free( req->ptr );
[1]154        }
[656]155    ///////////////////////////
[635]156    else if( type == KMEM_KHM )
157    {
158        khm_free( req->ptr );
159    }
160    else
161    {
162        printk("\n[ERROR] in %s : illegal allocator type\n", __FUNCTION__);
163    }
164}  // end kmem_free()
165
166///////////////////////////////////////////
167void * kmem_remote_alloc( cxy_t        cxy,
168                          kmem_req_t * req )
169{
170        uint32_t    type;    // KMEM_PPM / KMEM_KCM / KMEM_KHM
171        uint32_t    flags;   // AF_ZERO / AF_KERNEL / AF_NONE
172        uint32_t    order;   // PPM: ln(pages) / KCM: ln(bytes) / KHM: bytes
173
174        type  = req->type;
175        order = req->order;
176        flags = req->flags;
177
[656]178        //////////////////////
[635]179        if( type == KMEM_PPM )
[159]180        {
[656]181                // allocate the number of requested pages from remote cluster
182                xptr_t page_xp = ppm_remote_alloc_pages( cxy , order );
[635]183
[656]184                if( page_xp == XPTR_NULL )
[159]185                {
[635]186                        printk("\n[ERROR] in %s : failed for PPM / order %d in cluster %x\n",
187                        __FUNCTION__ , order , cxy );
188                        return NULL;
189                }
[567]190
[656]191        // get extended pointer on remote buffer
[635]192        xptr_t base_xp = ppm_page2base( page_xp );
[567]193
[635]194                // reset page if requested
195                if( flags & AF_ZERO ) hal_remote_memset( base_xp , 0 , CONFIG_PPM_PAGE_SIZE );
[1]196
[635]197
198#if DEBUG_KMEM_REMOTE
199thread_t * this = CURRENT_THREAD;
200uint32_t   cycle = (uint32_t)hal_get_cycles();
201if( DEBUG_KMEM_REMOTE < cycle )
202printk("\n[%s] thread[%x,%x] from PPM / %d page(s) / ppn %x / cxy %x / cycle %d\n",
203__FUNCTION__, this->process->pid, this->trdid,
[656]2041<<order, ppm_page2ppn( page_xp ), cxy, cycle );
[635]205#endif
[656]206        return GET_PTR( base_xp );
[635]207        }
[656]208    ///////////////////////////
[635]209        else if( type == KMEM_KCM ) 
210        {
[159]211                // allocate memory from KCM
[635]212                void * ptr = kcm_remote_alloc( cxy , order );
213
[180]214                if( ptr == NULL )
215                {
[635]216                        printk("\n[ERROR] in %s : failed for KCM / order %d in cluster %x\n",
217                    __FUNCTION__ , order , cxy );
[180]218                        return NULL;
219                }
[7]220
[159]221                // reset memory if requested
[635]222                if( flags & AF_ZERO )  hal_remote_memset( XPTR( cxy , ptr ) , 0 , 1<<order );
[7]223
[635]224#if DEBUG_KMEM_REMOTE
225thread_t * this = CURRENT_THREAD;
226uint32_t   cycle = (uint32_t)hal_get_cycles();
227if( DEBUG_KMEM_REMOTE < cycle )
228printk("\n[%s] thread [%x,%x] from KCM / %d bytes / base %x / cxy %x / cycle %d\n",
229__FUNCTION__, this->process->pid, this->trdid,
2301<<order, ptr, cxy, cycle );
[435]231#endif
[635]232        return ptr;
[1]233        }
[656]234        ///////////////////////////
[635]235        else if( type == KMEM_KHM )               
236        {
237        printk("\n[ERROR] in %s : remote access not supported for KHM\n", __FUNCTION__  );
238                return NULL;
239        }
240    else
241    {
242        printk("\n[ERROR] in %s : illegal allocator type\n", __FUNCTION__);
243        return NULL;
244    }
245}  // kmem_remote_malloc()
[1]246
[635]247////////////////////////////////////////
248void kmem_remote_free( cxy_t        cxy,
249                       kmem_req_t * req )
250{
251    uint32_t type = req->type;
[1]252
[656]253    //////////////////////
[635]254        if( type == KMEM_PPM )
[159]255        {
[635]256        page_t * page = GET_PTR( ppm_base2page( XPTR( cxy , req->ptr ) ) );
257
258        ppm_remote_free_pages( cxy , page );
259    }
[656]260    ///////////////////////////
[635]261    else if( type == KMEM_KCM )
262    {
263        kcm_remote_free( cxy , req->ptr );
[159]264        }
[656]265    ///////////////////////////
[635]266    else if( type == KMEM_KHM )
267    {
268        printk("\n[ERROR] in %s : remote access not supported for KHM\n", __FUNCTION__ );
269    }
270    else
271    {
272        printk("\n[ERROR] in %s : illegal allocator type\n", __FUNCTION__);
273    }
274}  // end kmem_remote_free()
[18]275
[1]276
277
Note: See TracBrowser for help on using the repository browser.