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

Last change on this file since 690 was 683, checked in by alain, 3 years ago

All modifications required to support the <tcp_chat> application
including error recovery in case of packet loss.A

File size: 6.0 KB
RevLine 
[1]1/*
2 * kmem.c - kernel memory allocator implementation.
3 *
[683]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 <ppm.h>
[635]32#include <kcm.h>
[1]33#include <page.h>
34#include <kmem.h>
35
[683]36///////////////////////////////////
37void * kmem_alloc( uint32_t  order,
38                   uint32_t  flags )
[7]39{
[1]40
[683]41#if DEBUG_KMEM || DEBUG_KMEM_ERROR
42thread_t * this  = CURRENT_THREAD;
43uint32_t   cycle = (uint32_t)hal_get_cycles();
44#endif
[7]45
[683]46        if( order >= CONFIG_PPM_PAGE_ORDER )     // use PPM
[159]47        {
[683]48                // allocate memory from PPM
49                page_t * page = (void *)ppm_alloc_pages( order - CONFIG_PPM_PAGE_ORDER );
[635]50
[683]51                if( page == NULL )
[159]52                {
[683]53
54#if DEBUG_KMEM_ERROR
55if (DEBUG_KMEM_ERROR < cycle)
56printk("\n[ERROR] in %s : thread[%x,%x] failed for PPM / order %d / cluster %x / cycle %d\n",
57__FUNCTION__ , this->process->pid , this->trdid , order , local_cxy , cycle );
58#endif
[635]59                        return NULL;
[159]60                }
[7]61
[635]62                // reset page if requested
[683]63                if( flags & AF_ZERO ) page_zero( page );
[619]64
[635]65        // get pointer on buffer from the page descriptor
[683]66        xptr_t page_xp = XPTR( local_cxy , page );
67        void * ptr     = GET_PTR( ppm_page2base( page_xp ) );
[50]68
[438]69#if DEBUG_KMEM
[683]70if( (DEBUG_KMEM < cycle) && (DEBUG_KMEM_CXY == local_cxy) && (DEBUG_KMEM_ORDER == order) )
71printk("\n[%s] thread[%x,%x] from PPM / order %d / ppn %x / cxy %x / cycle %d\n",
[635]72__FUNCTION__, this->process->pid, this->trdid,
[683]73order, ppm_page2ppn(XPTR(local_cxy,ptr)), local_cxy, cycle );
[435]74#endif
[635]75        return ptr;
76        }
[683]77        else                                     // use KCM
[159]78        {
[635]79                // allocate memory from KCM
80                void * ptr = kcm_alloc( order );
[1]81
[180]82                if( ptr == NULL )
83                {
[683]84
85#if DEBUG_KMEM_ERROR
86if (DEBUG_KMEM_ERROR < cycle)
87printk("\n[ERROR] in %s : thread[%x,%x] failed for KCM / order %d / cluster %x / cycle %d\n",
88__FUNCTION__ , this->process->pid , this->trdid , order , local_cxy , cycle );
89#endif
[180]90                        return NULL;
91                }
[1]92
[635]93                // reset memory if requested
94                if( flags & AF_ZERO ) memset( ptr , 0 , 1<<order );
[18]95
[438]96#if DEBUG_KMEM
[683]97if( (DEBUG_KMEM < cycle) && (DEBUG_KMEM_CXY == local_cxy) && (DEBUG_KMEM_ORDER == order) )
98printk("\n[%s] thread [%x,%x] from KCM / order %d / base %x / cxy %x / cycle %d\n",
[611]99__FUNCTION__, this->process->pid, this->trdid,
[683]100order, ptr, local_cxy, cycle ); 
[433]101#endif
[635]102        return ptr;
[1]103        }
[635]104}  // end kmem_alloc()
[435]105
[683]106//////////////////////////////
107void kmem_free( void    * ptr,
108                uint32_t  order )
[635]109{
[683]110        if( order >= CONFIG_PPM_PAGE_ORDER )     // use PPM
[635]111        {
[683]112        page_t * page = GET_PTR( ppm_base2page( XPTR( local_cxy , ptr ) ) );
[635]113
114        ppm_free_pages( page );
115    }
[683]116        else                                     // use KCM
[635]117    {
[683]118        kcm_free( ptr , order );
[1]119        }
[635]120}  // end kmem_free()
121
[683]122
123
124////////////////////////////////////////
125void * kmem_remote_alloc( cxy_t     cxy,
126                          uint32_t  order,
127                          uint32_t  flags )
[635]128{
129
[683]130#if DEBUG_KMEM || DEBUG_KMEM_ERROR
131thread_t * this = CURRENT_THREAD;
132uint32_t   cycle = (uint32_t)hal_get_cycles();
133#endif
[635]134
[683]135        if( order >= CONFIG_PPM_PAGE_ORDER )     // use PPM
[159]136        {
[683]137                // allocate memory from PPM
138                xptr_t page_xp = ppm_remote_alloc_pages( cxy , order - CONFIG_PPM_PAGE_ORDER );
[635]139
[656]140                if( page_xp == XPTR_NULL )
[159]141                {
[683]142
143#if DEBUG_KMEM_ERROR
144if( DEBUG_KMEM_ERROR < cycle )
145printk("\n[ERROR] in %s : thread[%x,%x] failed for PPM / order %d / cluster %x / cycle %d\n",
146__FUNCTION__ , this->process->pid , this->trdid , order , cxy , cycle );
147#endif
[635]148                        return NULL;
149                }
[567]150
[656]151        // get extended pointer on remote buffer
[635]152        xptr_t base_xp = ppm_page2base( page_xp );
[567]153
[683]154                // reset memory if requested
155                if( flags & AF_ZERO ) hal_remote_memset( base_xp , 0 , 1<<order );
[1]156
[683]157#if DEBUG_KMEM
158if( (DEBUG_KMEM < cycle) && (DEBUG_KMEM_CXY == local_cxy) && (DEBUG_KMEM_ORDER == order) )
159printk("\n[%s] thread[%x,%x] from PPM / order %d / ppn %x / cxy %x / cycle %d\n",
[635]160__FUNCTION__, this->process->pid, this->trdid,
[683]161order, ppm_page2ppn( page_xp ), cxy, cycle );
[635]162#endif
[656]163        return GET_PTR( base_xp );
[635]164        }
[683]165        else                                     // use KCM
[635]166        {
[159]167                // allocate memory from KCM
[635]168                void * ptr = kcm_remote_alloc( cxy , order );
169
[180]170                if( ptr == NULL )
171                {
[683]172
173#if DEBUG_KMEM_ERROR
174if( DEBUG_KMEM_ERROR < cycle )
175printk("\n[ERROR] in %s : thread[%x,%x] failed for KCM / order %d / cluster %x / cycle %d\n",
176__FUNCTION__ , this->process->pid , this->trdid , order , cxy , cycle );
177#endif
[180]178                        return NULL;
179                }
[7]180
[159]181                // reset memory if requested
[635]182                if( flags & AF_ZERO )  hal_remote_memset( XPTR( cxy , ptr ) , 0 , 1<<order );
[7]183
[683]184#if DEBUG_KMEM
185if( (DEBUG_KMEM < cycle) && (DEBUG_KMEM_CXY == local_cxy) && (DEBUG_KMEM_ORDER == order) )
186printk("\n[%s] thread [%x,%x] from KCM / order %d / base %x / cxy %x / cycle %d\n",
[635]187__FUNCTION__, this->process->pid, this->trdid,
[683]188order, ptr, cxy, cycle );
[435]189#endif
[635]190        return ptr;
[1]191        }
[635]192}  // kmem_remote_malloc()
[1]193
[683]194/////////////////////////////////////
195void kmem_remote_free( cxy_t     cxy,
196                       void    * ptr,
197                       uint32_t  order )
[635]198{
[683]199        if( order >= CONFIG_PPM_PAGE_ORDER )     // use PPM
[159]200        {
[683]201        page_t * page = GET_PTR( ppm_base2page( XPTR( cxy , ptr ) ) );
[635]202
203        ppm_remote_free_pages( cxy , page );
204    }
[683]205        else                                     // use KCM
[635]206    {
[683]207        kcm_remote_free( cxy , ptr , order );
[159]208        }
[635]209}  // end kmem_remote_free()
[18]210
[1]211
212
Note: See TracBrowser for help on using the repository browser.