Changeset 683 for trunk/kernel/mm/kmem.c


Ignore:
Timestamp:
Jan 13, 2021, 12:36:17 AM (3 years ago)
Author:
alain
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/mm/kmem.c

    r672 r683  
    22 * kmem.c - kernel memory allocator implementation.
    33 *
    4  * Authors  Alain Greiner (2016,2017,2018,2019,2020)
     4 * Authors  Alain Greiner     (2016,2017,2018,2019,2020)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    2929#include <thread.h>
    3030#include <memcpy.h>
    31 #include <khm.h>
    3231#include <ppm.h>
    3332#include <kcm.h>
     
    3534#include <kmem.h>
    3635
    37 /////////////////////////////////////
    38 void * kmem_alloc( kmem_req_t * req )
    39 {
    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
    43 
    44         type  = req->type;
    45         order = req->order;
    46         flags = req->flags;
    47 
    48     //////////////////////
    49         if( type == KMEM_PPM )
    50         {
    51                 // allocate the number of requested pages
    52                 page_t * page_ptr = (void *)ppm_alloc_pages( order );
    53 
    54                 if( page_ptr == NULL )
    55                 {
    56                         printk("\n[ERROR] in %s : PPM failed / order %d / cluster %x\n",
    57                         __FUNCTION__ , order , local_cxy );
    58                         return NULL;
    59                 }
    60 
    61         xptr_t page_xp = XPTR( local_cxy , page_ptr );
    62 
    63                 // reset page if requested
    64                 if( flags & AF_ZERO ) page_zero( page_ptr );
    65 
    66         // get pointer on buffer from the page descriptor
    67         void * ptr = GET_PTR( ppm_page2base( page_xp ) );
    68 
    69 #if DEBUG_KMEM
     36///////////////////////////////////
     37void * kmem_alloc( uint32_t  order,
     38                   uint32_t  flags )
     39{
     40
     41#if DEBUG_KMEM || DEBUG_KMEM_ERROR
    7042thread_t * this  = CURRENT_THREAD;
    7143uint32_t   cycle = (uint32_t)hal_get_cycles();
    72 if( DEBUG_KMEM < cycle )
    73 printk("\n[%s] thread[%x,%x] from PPM / %d page(s) / ppn %x / cxy %x / cycle %d\n",
    74 __FUNCTION__, this->process->pid, this->trdid,
    75 1<<order, ppm_page2ppn(XPTR(local_cxy,ptr)), local_cxy, cycle );
     44#endif
     45
     46        if( order >= CONFIG_PPM_PAGE_ORDER )     // use PPM
     47        {
     48                // allocate memory from PPM
     49                page_t * page = (void *)ppm_alloc_pages( order - CONFIG_PPM_PAGE_ORDER );
     50
     51                if( page == NULL )
     52                {
     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
     59                        return NULL;
     60                }
     61
     62                // reset page if requested
     63                if( flags & AF_ZERO ) page_zero( page );
     64
     65        // get pointer on buffer from the page descriptor
     66        xptr_t page_xp = XPTR( local_cxy , page );
     67        void * ptr     = GET_PTR( ppm_page2base( page_xp ) );
     68
     69#if DEBUG_KMEM
     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",
     72__FUNCTION__, this->process->pid, this->trdid,
     73order, ppm_page2ppn(XPTR(local_cxy,ptr)), local_cxy, cycle );
    7674#endif
    7775        return ptr;
    7876        }
    79     ///////////////////////////
    80         else if( type == KMEM_KCM )
     77        else                                     // use KCM
    8178        {
    8279                // allocate memory from KCM
     
    8582                if( ptr == NULL )
    8683                {
    87                         printk("\n[ERROR] in %s : KCM failed / order %d / cluster %x\n",
    88                     __FUNCTION__ , order , local_cxy );
     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
    8990                        return NULL;
    9091                }
     
    9495
    9596#if DEBUG_KMEM
    96 thread_t * this  = CURRENT_THREAD;
    97 uint32_t   cycle = (uint32_t)hal_get_cycles();
    98 if( DEBUG_KMEM < cycle )
    99 printk("\n[%s] thread [%x,%x] from KCM / %d bytes / base %x / cxy %x / cycle %d\n",
    100 __FUNCTION__, this->process->pid, this->trdid,
    101 1<<order, ptr, local_cxy, cycle );
     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",
     99__FUNCTION__, this->process->pid, this->trdid,
     100order, ptr, local_cxy, cycle );
    102101#endif
    103102        return ptr;
    104103        }
    105     ///////////////////////////
    106         else if( type == KMEM_KHM )
    107         {
    108                 // allocate memory from KHM
    109                 void * ptr = khm_alloc( &LOCAL_CLUSTER->khm , order );
    110 
    111                 if( ptr == NULL )
    112                 {
    113                         printk("\n[ERROR] in %s : KHM failed / order %d / cluster %x\n",
    114                         __FUNCTION__ , order , local_cxy );
    115                         return NULL;
    116                 }
    117 
    118                 // reset memory if requested
    119                 if( flags & AF_ZERO ) memset( ptr , 0 , order );
    120 
    121 #if DEBUG_KMEM
    122 thread_t * this  = CURRENT_THREAD;
    123 uint32_t   cycle = (uint32_t)hal_get_cycles();
    124 if( DEBUG_KMEM < cycle )
    125 printk("\n[%s] thread[%x,%x] from KHM / %d bytes / base %x / cxy %x / cycle %d\n",
    126 __FUNCTION__, this->process->pid, this->trdid,
    127 order, ptr, local_cxy, cycle );
    128 #endif
    129         return ptr;
    130         }
    131     else
    132     {
    133         printk("\n[ERROR] in %s : illegal allocator type\n", __FUNCTION__);
    134         return NULL;
    135     }
    136104}  // end kmem_alloc()
    137105
    138 //////////////////////////////////
    139 void kmem_free( kmem_req_t * req )
    140 {
    141     uint32_t type = req->type;
    142 
    143     //////////////////////
    144         if( type == KMEM_PPM )
    145         {
    146         page_t * page = GET_PTR( ppm_base2page( XPTR( local_cxy , req->ptr ) ) );
     106//////////////////////////////
     107void kmem_free( void    * ptr,
     108                uint32_t  order )
     109{
     110        if( order >= CONFIG_PPM_PAGE_ORDER )     // use PPM
     111        {
     112        page_t * page = GET_PTR( ppm_base2page( XPTR( local_cxy , ptr ) ) );
    147113
    148114        ppm_free_pages( page );
    149115    }
    150     ///////////////////////////
    151     else if( type == KMEM_KCM )
     116        else                                     // use KCM
    152117    {
    153         kcm_free( req->ptr );
    154         }
    155     ///////////////////////////
    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     }
     118        kcm_free( ptr , order );
     119        }
    164120}  // end kmem_free()
    165121
    166 ///////////////////////////////////////////
    167 void * 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 
    178         //////////////////////
    179         if( type == KMEM_PPM )
    180         {
    181                 // allocate the number of requested pages from remote cluster
    182                 xptr_t page_xp = ppm_remote_alloc_pages( cxy , order );
     122
     123
     124////////////////////////////////////////
     125void * kmem_remote_alloc( cxy_t     cxy,
     126                          uint32_t  order,
     127                          uint32_t  flags )
     128{
     129
     130#if DEBUG_KMEM || DEBUG_KMEM_ERROR
     131thread_t * this = CURRENT_THREAD;
     132uint32_t   cycle = (uint32_t)hal_get_cycles();
     133#endif
     134
     135        if( order >= CONFIG_PPM_PAGE_ORDER )     // use PPM
     136        {
     137                // allocate memory from PPM
     138                xptr_t page_xp = ppm_remote_alloc_pages( cxy , order - CONFIG_PPM_PAGE_ORDER );
    183139
    184140                if( page_xp == XPTR_NULL )
    185141                {
    186                         printk("\n[ERROR] in %s : failed for PPM / order %d in cluster %x\n",
    187                         __FUNCTION__ , order , cxy );
     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
    188148                        return NULL;
    189149                }
     
    192152        xptr_t base_xp = ppm_page2base( page_xp );
    193153
    194                 // reset page if requested
    195                 if( flags & AF_ZERO ) hal_remote_memset( base_xp , 0 , CONFIG_PPM_PAGE_SIZE );
    196 
    197 
    198 #if DEBUG_KMEM_REMOTE
    199 thread_t * this = CURRENT_THREAD;
    200 uint32_t   cycle = (uint32_t)hal_get_cycles();
    201 if( DEBUG_KMEM_REMOTE < cycle )
    202 printk("\n[%s] thread[%x,%x] from PPM / %d page(s) / ppn %x / cxy %x / cycle %d\n",
    203 __FUNCTION__, this->process->pid, this->trdid,
    204 1<<order, ppm_page2ppn( page_xp ), cxy, cycle );
     154                // reset memory if requested
     155                if( flags & AF_ZERO ) hal_remote_memset( base_xp , 0 , 1<<order );
     156
     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",
     160__FUNCTION__, this->process->pid, this->trdid,
     161order, ppm_page2ppn( page_xp ), cxy, cycle );
    205162#endif
    206163        return GET_PTR( base_xp );
    207164        }
    208     ///////////////////////////
    209         else if( type == KMEM_KCM )
     165        else                                     // use KCM
    210166        {
    211167                // allocate memory from KCM
     
    214170                if( ptr == NULL )
    215171                {
    216                         printk("\n[ERROR] in %s : failed for KCM / order %d in cluster %x\n",
    217                     __FUNCTION__ , order , cxy );
     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
    218178                        return NULL;
    219179                }
     
    222182                if( flags & AF_ZERO )  hal_remote_memset( XPTR( cxy , ptr ) , 0 , 1<<order );
    223183
    224 #if DEBUG_KMEM_REMOTE
    225 thread_t * this = CURRENT_THREAD;
    226 uint32_t   cycle = (uint32_t)hal_get_cycles();
    227 if( DEBUG_KMEM_REMOTE < cycle )
    228 printk("\n[%s] thread [%x,%x] from KCM / %d bytes / base %x / cxy %x / cycle %d\n",
    229 __FUNCTION__, this->process->pid, this->trdid,
    230 1<<order, ptr, cxy, cycle );
     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",
     187__FUNCTION__, this->process->pid, this->trdid,
     188order, ptr, cxy, cycle );
    231189#endif
    232190        return ptr;
    233191        }
    234         ///////////////////////////
    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     }
    245192}  // kmem_remote_malloc()
    246193
    247 ////////////////////////////////////////
    248 void kmem_remote_free( cxy_t        cxy,
    249                        kmem_req_t * req )
    250 {
    251     uint32_t type = req->type;
    252 
    253     //////////////////////
    254         if( type == KMEM_PPM )
    255         {
    256         page_t * page = GET_PTR( ppm_base2page( XPTR( cxy , req->ptr ) ) );
     194/////////////////////////////////////
     195void kmem_remote_free( cxy_t     cxy,
     196                       void    * ptr,
     197                       uint32_t  order )
     198{
     199        if( order >= CONFIG_PPM_PAGE_ORDER )     // use PPM
     200        {
     201        page_t * page = GET_PTR( ppm_base2page( XPTR( cxy , ptr ) ) );
    257202
    258203        ppm_remote_free_pages( cxy , page );
    259204    }
    260     ///////////////////////////
    261     else if( type == KMEM_KCM )
     205        else                                     // use KCM
    262206    {
    263         kcm_remote_free( cxy , req->ptr );
    264         }
    265     ///////////////////////////
    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     }
     207        kcm_remote_free( cxy , ptr , order );
     208        }
    274209}  // end kmem_remote_free()
    275210
Note: See TracChangeset for help on using the changeset viewer.