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


Ignore:
Timestamp:
Jan 13, 2021, 12:36:17 AM (13 months 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/kcm.c

    r672 r683  
    3636#include <kcm.h>
    3737
     38///////////////////////////////////////////////////////////////////////////////////////////
     39//         global variables
     40///////////////////////////////////////////////////////////////////////////////////////////
     41
     42extern chdev_directory_t    chdev_dir;          // allocated in kernel_init.c
     43
    3844
    3945/////////////////////////////////////////////////////////////////////////////////////
     
    4248
    4349//////////////////////////////////////////////////////////////////////////////////////
    44 // This static function must be called by a local thread.
     50// This static function is called by the kcm_alloc() function.
    4551// It returns a pointer on a block allocated from an active kcm_page.
    4652// It makes a panic if no block is available in the selected page.
     
    5561{
    5662    // initialise variables
    57     uint32_t size   = 1 << kcm->order;
    58     uint32_t max    = kcm->max_blocks;
     63    uint32_t order  = kcm->order;
    5964    uint32_t count  = kcm_page->count;
    6065    uint64_t status = kcm_page->status;
    6166
    62 assert( __FUNCTION__, (count < max) , "kcm_page should not be full" );
     67// check kcm page not full
     68assert( __FUNCTION__, (count < 63) ,
     69"kcm_page should not be full / cxy %x / order %d / count %d", local_cxy, order, count );
    6370
    6471    uint32_t index  = 1;
     
    6774        // allocate first free block in kcm_page, update status,
    6875    // and count , compute index of allocated block in kcm_page
    69     while( index <= max )
     76    while( index <= 63 )
    7077    {
    7178        if( (status & mask) == 0 )   // block found
     
    8188    }
    8289
    83     // change the page list if found block is the last
    84     if( count == max-1 )
     90    // switch page to full if last block
     91    if( (count + 1) == 63 )
    8592    {
    8693                list_unlink( &kcm_page->list);
     
    9299
    93100        // compute return pointer
    94         void * ptr = (void *)((intptr_t)kcm_page + (index * size) );
    95 
    96 #if DEBUG_KCM
    97 thread_t * this  = CURRENT_THREAD;
    98 uint32_t   cycle = (uint32_t)hal_get_cycles();
    99 if( DEBUG_KCM < cycle )
    100 printk("\n[%s] thread[%x,%x] allocated block %x in page %x / size %d / count %d / cycle %d\n",
    101 __FUNCTION__, this->process->pid, this->trdid, ptr, kcm_page, size, count + 1, cycle );
    102 #endif
     101        void * ptr = (void *)((intptr_t)kcm_page + (index << order));
    103102
    104103        return ptr;
     
    107106
    108107/////////////////////////////////////////////////////////////////////////////////////
    109 // This private static function must be called by a local thread.
     108// This static function is called by the kcm_free() function.
    110109// It releases a previously allocated block to the relevant kcm_page.
    111110// It makes a panic if the released block is not allocated in this page.
     
    121120{
    122121    // initialise variables
    123     uint32_t max    = kcm->max_blocks;
    124     uint32_t size   = 1 << kcm->order;
     122    uint32_t order  = kcm->order;
    125123    uint32_t count  = kcm_page->count;
    126124    uint64_t status = kcm_page->status;
    127125   
    128         // compute block index from block pointer
    129         uint32_t index = ((intptr_t)block_ptr - (intptr_t)kcm_page) / size;
     126        // compute block index from block pointer and kcm_page pointer
     127        uint32_t index = ((intptr_t)block_ptr - (intptr_t)kcm_page) >> order;
    130128
    131129    // compute mask in bit vector
     
    136134        printk("\n[WARNING] in %s : block[%x,%x] not allocated / kcm %x / kcm_page %x\n",
    137135        __FUNCTION__, local_cxy, block_ptr, kcm, kcm_page );
    138         printk("   status %L / mask %L / sts & msk %L\n", status, mask, (status & mask) );
    139136        kcm_remote_display( local_cxy , kcm );
    140137        return;
     
    145142        kcm_page->count  = count - 1;
    146143
    147         // change the page mode if page was full
    148         if( count == max )
     144        // switch page to active if it was full
     145        if( count == 63 )
    149146        {
    150147                list_unlink( &kcm_page->list );
     
    155152        }
    156153
    157 #if DEBUG_KCM
    158 thread_t * this  = CURRENT_THREAD;
    159 uint32_t   cycle = (uint32_t)hal_get_cycles();
    160 if( DEBUG_KCM < cycle )
    161 printk("\n[%s] thread[%x,%x] block %x / page %x / size %d / count %d / cycle %d\n",
    162 __FUNCTION__, this->process->pid, this->trdid, block_ptr, kcm_page, size, count - 1, cycle );
    163 #endif
    164 
    165154}  // kcm_put_block()
    166155
    167156/////////////////////////////////////////////////////////////////////////////////////
    168 // This static function must be called by a local thread.
    169 // It returns one non-full kcm_page with the following policy :
     157// This static function  returns one non-full kcm_page with the following policy :
    170158// - if the "active_list" is non empty, it returns the first "active" page,
    171159//   without modifying the KCM state.
     
    188176    else                            // allocate a new page from PPM
    189177        {
    190         // get one 4 Kbytes page from local PPM
    191         page_t * page = ppm_alloc_pages( 0 );
     178        // get KCM order
     179        uint32_t order = kcm->order;
     180
     181        // get one kcm_page from  PPM
     182        page_t * page = ppm_alloc_pages( order + 6 - CONFIG_PPM_PAGE_ORDER );
    192183
    193184            if( page == NULL )
    194185            {
    195                     printk("\n[ERROR] in %s : failed to allocate page in cluster %x\n",
    196                 __FUNCTION__ , local_cxy );
    197 
     186
     187#if DEBUG_KCM_ERROR
     188printk("\n[ERROR] in %s : failed to allocate page in cluster %x\n",
     189__FUNCTION__ , local_cxy );
     190#endif
    198191                    return NULL;
    199192        }
     
    202195            xptr_t base_xp = ppm_page2base( XPTR( local_cxy , page ) );
    203196
    204         // get local pointer on kcm_page
     197        // get local pointer on kcm_page 
    205198            kcm_page = GET_PTR( base_xp );
    206199
     
    225218{
    226219
    227 assert( __FUNCTION__, ((order > 5) && (order < 12)) , "order must be in [6,11]" );
    228 
    229 assert( __FUNCTION__, (CONFIG_PPM_PAGE_SHIFT == 12) , "check status bit_vector width" );
     220// check argument
     221assert( __FUNCTION__, (order < CONFIG_PPM_PAGE_ORDER),
     222"order argument %d too large", order );
     223
     224assert( __FUNCTION__, (order >= CONFIG_CACHE_LINE_ORDER),
     225"order argument %d too small", order );
    230226
    231227        // initialize lock
     
    238234        list_root_init( &kcm->active_root );
    239235
    240         // initialize order and max_blocks
    241         kcm->order      = order;
    242     kcm->max_blocks = ( CONFIG_PPM_PAGE_SIZE >> order ) - 1;
     236        // initialize order
     237        kcm->order = order;
    243238 
    244239#if DEBUG_KCM
    245 thread_t * this  = CURRENT_THREAD;
    246 uint32_t   cycle = (uint32_t)hal_get_cycles();
    247 if( DEBUG_KCM < cycle )
    248 printk("\n[%s] thread[%x,%x] initialised KCM / order %d / max_blocks %d\n",
    249 __FUNCTION__, this->process->pid, this->trdid, order, kcm->max_blocks );
     240if( (DEBUG_KCM_ORDER == order) && (DEBUG_KCM_CXY == local_cxy) )
     241printk("\n[%s] cxy %x / order %d\n",
     242__FUNCTION__, local_cxy, order );
    250243#endif
    251244
     
    287280void * kcm_alloc( uint32_t order )
    288281{
    289     kcm_t      * kcm_ptr;
     282    kcm_t      * kcm;
    290283        kcm_page_t * kcm_page;
    291         void       * block_ptr;
    292 
    293    // min block size is 64 bytes
    294     if( order < 6 ) order = 6;
    295 
    296 assert( __FUNCTION__, (order < 12) , "order = %d / must be less than 12" , order );
     284        void       * block;
     285
     286// check argument
     287assert( __FUNCTION__, (order < CONFIG_PPM_PAGE_ORDER),
     288"order argument %d too large", order );
     289
     290#if DEBUG_KCM
     291uint32_t cycle = (uint32_t)hal_get_cycles();
     292#endif
     293
     294    // smallest block size is a cache line
     295    if (order < CONFIG_CACHE_LINE_ORDER) order = CONFIG_CACHE_LINE_ORDER;
    297296
    298297    // get local pointer on relevant KCM allocator
    299     kcm_ptr = &LOCAL_CLUSTER->kcm[order - 6];
     298    kcm = &LOCAL_CLUSTER->kcm[order - CONFIG_CACHE_LINE_ORDER];
    300299
    301300    // build extended pointer on local KCM lock
    302     xptr_t lock_xp = XPTR( local_cxy , &kcm_ptr->lock );
     301    xptr_t lock_xp = XPTR( local_cxy , &kcm->lock );
    303302
    304303        // get KCM lock
     
    306305
    307306    // get a non-full kcm_page
    308     kcm_page = kcm_get_page( kcm_ptr );
    309 
    310 #if DEBUG_KCM
    311 thread_t * this  = CURRENT_THREAD;
    312 uint32_t   cycle = (uint32_t)hal_get_cycles();
    313 if( DEBUG_KCM < cycle )
    314 {
    315 printk("\n[%s] thread[%x,%x] enters / order %d / page %x / kcm %x / page_status (%x|%x)\n",
    316 __FUNCTION__, this->process->pid, this->trdid, order, kcm_page, kcm_ptr,
    317 GET_CXY( kcm_page->status ), GET_PTR( kcm_page->status ) );
    318 kcm_remote_display( local_cxy , kcm_ptr );
    319 }
    320 #endif
     307    kcm_page = kcm_get_page( kcm );
    321308
    322309    if( kcm_page == NULL )
     
    326313        }
    327314
    328         // get a block from selected active page
    329         block_ptr = kcm_get_block( kcm_ptr , kcm_page );
     315#if DEBUG_KCM
     316if( (DEBUG_KCM_ORDER == order) && (DEBUG_KCM_CXY == local_cxy) && (DEBUG_KCM < cycle) )
     317printk("\n[%s] enter / order %d / kcm[%x,%x] / nb_full %d / nb_active %d\n"
     318"    page %x / status [%x,%x] / count %d\n",
     319__FUNCTION__, order, local_cxy, kcm, kcm->full_pages_nr, kcm->active_pages_nr,
     320kcm_page, (uint32_t)(kcm_page->status>>32), (uint32_t)(kcm_page->status), kcm_page->count );
     321#endif
     322
     323        // allocate a block from selected active page
     324        block = kcm_get_block( kcm , kcm_page );
     325
     326#if DEBUG_KCM
     327if( (DEBUG_KCM_ORDER == order) && (DEBUG_KCM_CXY == local_cxy) && (DEBUG_KCM < cycle) )
     328printk("\n[%s] exit  / order %d / kcm[%x,%x] / nb_full %d / nb_active %d\n"
     329"    page %x / status [%x,%x] / count %d\n",
     330__FUNCTION__, order, local_cxy, kcm, kcm->full_pages_nr, kcm->active_pages_nr,
     331kcm_page, (uint32_t)(kcm_page->status>>32), (uint32_t)(kcm_page->status), kcm_page->count );
     332#endif
    330333
    331334        // release lock
    332335        remote_busylock_release( lock_xp );
    333336
    334 #if DEBUG_KCM
    335 if( DEBUG_KCM < cycle )
    336 printk("\n[%s] thread[%x,%x] exit / order %d / block %x / kcm %x / page_status (%x|%x)\n",
    337 __FUNCTION__, this->process->pid, this->trdid, order, block_ptr, kcm_ptr,
    338 GET_CXY( kcm_page->status ), GET_PTR( kcm_page->status ) );
    339 #endif
    340 
    341         return block_ptr;
     337        return block;
    342338
    343339}  // end kcm_alloc()
    344340
    345 /////////////////////////////////
    346 void kcm_free( void * block_ptr )
    347 {
    348     kcm_t      * kcm_ptr;
     341///////////////////////////////
     342void kcm_free( void    * block,
     343               uint32_t  order )
     344{
     345    kcm_t      * kcm;
    349346        kcm_page_t * kcm_page;
    350347
    351348// check argument
    352 assert( __FUNCTION__, (block_ptr != NULL) , "block pointer cannot be NULL" );
     349assert( __FUNCTION__, (block != NULL),
     350"block pointer cannot be NULL" );
     351
     352#if DEBUG_KCM
     353uint32_t cycle = (uint32_t)hal_get_cycles();
     354#endif
     355
     356    // smallest block size is a cache line
     357    if (order < CONFIG_CACHE_LINE_ORDER) order = CONFIG_CACHE_LINE_ORDER;
     358
     359    // get local pointer on relevant KCM allocator
     360    kcm = &LOCAL_CLUSTER->kcm[order - CONFIG_CACHE_LINE_ORDER];
    353361
    354362    // get local pointer on KCM page
    355         kcm_page = (kcm_page_t *)((intptr_t)block_ptr & ~CONFIG_PPM_PAGE_MASK);
    356 
    357     // get local pointer on KCM descriptor
    358         kcm_ptr = kcm_page->kcm;
    359 
    360 #if DEBUG_KCM
    361 thread_t * this  = CURRENT_THREAD;
    362 uint32_t   cycle = (uint32_t)hal_get_cycles();
    363 if( (DEBUG_KCM < cycle) && (local_cxy == 1) )
    364 {
    365 printk("\n[%s] thread[%x,%x] enters / order %d / block %x / page %x / kcm %x / status [%x,%x]\n",
    366 __FUNCTION__, this->process->pid, this->trdid, kcm_ptr->order, block_ptr, kcm_page, kcm_ptr,
    367 GET_CXY(kcm_page->status), GET_PTR(kcm_page->status) );
    368 kcm_remote_display( local_cxy , kcm_ptr );
    369 }
    370 #endif
     363    intptr_t kcm_page_mask = (1 << (order + 6)) - 1;
     364        kcm_page = (kcm_page_t *)((intptr_t)block & ~kcm_page_mask);
    371365
    372366    // build extended pointer on local KCM lock
    373     xptr_t lock_xp = XPTR( local_cxy , &kcm_ptr->lock );
     367    xptr_t lock_xp = XPTR( local_cxy , &kcm->lock );
    374368
    375369        // get lock
    376370        remote_busylock_acquire( lock_xp );
    377371
    378         // release block
    379         kcm_put_block( kcm_ptr , kcm_page , block_ptr );
     372#if DEBUG_KCM
     373if( (DEBUG_KCM_ORDER == order) && (DEBUG_KCM_CXY == local_cxy) && (DEBUG_KCM < cycle) )
     374printk("\n[%s] exit  / order %d / kcm[%x,%x] / nb_full %d / nb_active %d\n"
     375"    page %x / status [%x,%x] / count %d\n",
     376__FUNCTION__, order, local_cxy, kcm, kcm->full_pages_nr, kcm->active_pages_nr,
     377kcm_page, (uint32_t)(kcm_page->status>>32), (uint32_t)(kcm_page->status), kcm_page->count );
     378#endif
     379
     380        // release the block to the relevant page
     381        kcm_put_block( kcm , kcm_page , block );
     382
     383#if DEBUG_KCM
     384if( (DEBUG_KCM_ORDER == order) && (DEBUG_KCM_CXY == local_cxy) && (DEBUG_KCM < cycle) )
     385printk("\n[%s] exit  / order %d / kcm[%x,%x] / nb_full %d / nb_active %d\n"
     386"    page %x / status [%x,%x] / count %d\n",
     387__FUNCTION__, order, local_cxy, kcm, kcm->full_pages_nr, kcm->active_pages_nr,
     388kcm_page, (uint32_t)(kcm_page->status>>32), (uint32_t)(kcm_page->status), kcm_page->count );
     389#endif
    380390
    381391        // release lock
    382392        remote_busylock_release( lock_xp );
    383393
    384 #if DEBUG_KCM
    385 if( (DEBUG_KCM < cycle) && (local_cxy == 1) )
    386 {
    387 printk("\n[%s] thread[%x,%x] exit / order %d / page %x / status [%x,%x]\n",
    388 __FUNCTION__, this->process->pid, this->trdid, kcm_ptr->order, kcm_ptr,
    389 GET_CXY(kcm_page->status), GET_PTR(kcm_page->status) );
    390 kcm_remote_display( local_cxy , kcm_ptr );
    391 }
    392 #endif
    393 
    394394}  // end kcm_free()
    395395
     
    400400
    401401/////////////////////////////////////////////////////////////////////////////////////
    402 // This static function can be called by any thread running in any cluster.
     402// This static function is called by the kcm_remote_alloc() function.
     403// It can be called by any thread running in any cluster.
    403404// It returns a local pointer on a block allocated from an active kcm_page.
    404405// It makes a panic if no block available in the selected kcm_page.
     
    415416{
    416417    uint32_t order  = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->order ) );
    417     uint32_t max    = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->max_blocks ) );
    418418    uint32_t count  = hal_remote_l32( XPTR( kcm_cxy , &kcm_page->count ) );
    419419    uint64_t status = hal_remote_l64( XPTR( kcm_cxy , &kcm_page->status ) );
    420     uint32_t size   = 1 << order;
    421 
    422 assert( __FUNCTION__, (count < max) , "kcm_page should not be full" );
     420
     421// check kcm_page not full
     422assert( __FUNCTION__, (count < 63) ,
     423"kcm_page should not be full / cxy %x / order %d / count %d", kcm_cxy, order, count );
    423424
    424425    uint32_t index  = 1;
     
    427428        // allocate first free block in kcm_page, update status,
    428429    // and count , compute index of allocated block in kcm_page
    429     while( index <= max )
     430    while( index <= 63 )
    430431    {
    431432        if( (status & mask) == 0 )   // block found
     
    440441    }
    441442
    442         // change the page list if found block is the last
    443         if( count == max-1 )
     443        // swich the page to full if last block
     444        if( (count + 1) == 63 )
    444445        {
    445446                list_remote_unlink( kcm_cxy , &kcm_page->list );
     
    451452
    452453        // compute return pointer
    453         void * ptr = (void *)((intptr_t)kcm_page + (index * size) );
    454 
    455 #if DEBUG_KCM_REMOTE
    456 thread_t * this  = CURRENT_THREAD;
    457 uint32_t   cycle = (uint32_t)hal_get_cycles();
    458 if( DEBUG_KCM_REMOTE < cycle )
    459 printk("\n[%s] thread[%x,%x] get block %x in page %x / cluster %x / size %x / count %d\n",
    460 __FUNCTION__, this->process->pid, this->trdid,
    461 ptr, kcm_page, kcm_cxy, size, count + 1 );
    462 #endif
     454        void * ptr = (void *)((intptr_t)kcm_page + (index << order));
    463455
    464456        return ptr;
     
    467459
    468460/////////////////////////////////////////////////////////////////////////////////////
    469 // This private static function can be called by any thread running in any cluster.
     461// This static function is called by the kcm_remote_free() function.
     462// It can be called by any thread running in any cluster.
    470463// It releases a previously allocated block to the relevant kcm_page.
    471464// It changes the kcm_page status as required.
     
    481474                                                             void       * block_ptr )
    482475{
    483     uint32_t max    = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->max_blocks ) );
    484476    uint32_t order  = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->order ) );
    485477    uint32_t count  = hal_remote_l32( XPTR( kcm_cxy , &kcm_page->count ) );
    486478    uint64_t status = hal_remote_l64( XPTR( kcm_cxy , &kcm_page->status ) );
    487     uint32_t size   = 1 << order;
    488479   
    489         // compute block index from block pointer
    490         uint32_t index = ((intptr_t)block_ptr - (intptr_t)kcm_page) / size;
     480        // compute block index from block pointer and kcm_page pointer
     481        uint32_t index = ((intptr_t)block_ptr - (intptr_t)kcm_page) >> order;
    491482
    492483    // compute mask in bit vector
     
    497488        printk("\n[WARNING] in %s : block[%x,%x] not allocated / kcm %x / kcm_page %x\n",
    498489        __FUNCTION__, kcm_cxy, block_ptr, kcm_ptr, kcm_page );
    499         printk("   status %L / mask %L / sts & msk %L\n", status, mask, (status & mask) );
    500490        kcm_remote_display( kcm_cxy , kcm_ptr );
    501491        return;
     
    506496        hal_remote_s32( XPTR( kcm_cxy , &kcm_page->count  ) , count - 1 );
    507497
    508         // change the page list if page was full
    509         if( count == max )
     498        // switch the page to active if page was full
     499        if( count == 63 )
    510500        {
    511501                list_remote_unlink( kcm_cxy , &kcm_page->list );
     
    516506        }
    517507
    518 #if (DEBUG_KCM_REMOTE & 1)
    519 thread_t * this  = CURRENT_THREAD;
    520 uint32_t   cycle = (uint32_t)hal_get_cycles();
    521 if( DEBUG_KCM_REMOTE < cycle )
    522 printk("\n[%s] thread[%x,%x] block %x / page %x / cluster %x / size %x / count %d\n",
    523 __FUNCTION__, this->process->pid, this->trdid, block_ptr, kcm_page, size, count - 1 )
    524 #endif
    525 
    526508}  // end kcm_remote_put_block()
    527509
    528510/////////////////////////////////////////////////////////////////////////////////////
    529 // This private static function can be called by any thread running in any cluster.
     511// This static function can be called by any thread running in any cluster.
    530512// It gets one non-full KCM page from the remote KCM.
    531513// It allocates a page from remote PPM to populate the freelist, and initialises
     
    545527    else                            // allocate a new page from PPM
    546528        {
    547         // get one 4 Kbytes page from remote PPM
    548         xptr_t page_xp = ppm_remote_alloc_pages( kcm_cxy , 0 );
    549 
     529        // get KCM order
     530        uint32_t order = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->order ));
     531
     532        // get one kcm_page from PPM
     533        xptr_t page_xp = ppm_remote_alloc_pages( kcm_cxy,
     534                                                 order + 6 - CONFIG_PPM_PAGE_ORDER );
    550535            if( page_xp == XPTR_NULL )
    551536            {
    552                     printk("\n[ERROR] in %s : failed to allocate page in cluster %x\n",
    553                 __FUNCTION__ , kcm_cxy );
    554 
     537
     538#if DEBUG_KCM_ERROR
     539printk("\n[ERROR] in %s : failed to allocate page in cluster %x\n",
     540__FUNCTION__ , kcm_cxy );
     541#endif
    555542                    return NULL;
    556543        }
     
    585572    void       * block_ptr;
    586573
    587     if( order < 6 ) order = 6;
    588 
    589 assert( __FUNCTION__, (order < 12) , "order = %d / must be less than 12" , order );
    590 
    591     // get local pointer on relevant KCM allocator
     574// check kcm_cxy argument
     575assert( __FUNCTION__, cluster_is_active( kcm_cxy ),
     576"cluster %x not active", kcm_cxy );
     577
     578// check order argument
     579assert( __FUNCTION__, (order < CONFIG_PPM_PAGE_ORDER) ,
     580"order argument %d too large", order );
     581
     582    // smallest size is a cache line
     583    if( order < CONFIG_CACHE_LINE_ORDER ) order = CONFIG_CACHE_LINE_ORDER;
     584
     585    // get local pointer on relevant KCM allocator (same in all clusters)
    592586    kcm_ptr = &LOCAL_CLUSTER->kcm[order - 6];
    593587
     
    607601        }
    608602
     603#if DEBUG_KCM
     604uint32_t cycle     = (uint32_t)hal_get_cycles();
     605uint32_t nb_full   = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->full_pages_nr ));
     606uint32_t nb_active = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->active_pages_nr ));
     607uint64_t status    = hal_remote_l64( XPTR( kcm_cxy , &kcm_page->status ));
     608uint32_t count     = hal_remote_l32( XPTR( kcm_cxy , &kcm_page->count ));
     609#endif
     610
     611
     612#if DEBUG_KCM
     613if( (DEBUG_KCM_ORDER == order) && (DEBUG_KCM_CXY == local_cxy) && (DEBUG_KCM < cycle) )
     614printk("\n[%s] enter / order %d / kcm[%x,%x] / nb_full %d / nb_active %d\n"
     615"    page %x / status [%x,%x] / count %d\n",
     616__FUNCTION__, order, kcm_cxy, kcm_ptr, nb_full, nb_active,
     617kcm_page, (uint32_t)(status>>32), (uint32_t)(status), kcm_page->count );
     618#endif
     619
    609620        // get a block from selected active page
    610621        block_ptr = kcm_remote_get_block( kcm_cxy , kcm_ptr , kcm_page );
    611622
     623#if DEBUG_KCM
     624if( (DEBUG_KCM_ORDER == order) && (DEBUG_KCM_CXY == local_cxy) && (DEBUG_KCM < cycle) )
     625printk("\n[%s] exit  / order %d / kcm[%x,%x] / nb_full %d / nb_active %d\n"
     626"    page %x / status [%x,%x] / count %d\n",
     627__FUNCTION__, order, kcm_cxy, kcm_ptr, nb_full, nb_active,
     628kcm_page, (uint32_t)(status>>32), (uint32_t)(status), kcm_page->count );
     629#endif
     630
    612631        // release lock
    613632        remote_busylock_release( lock_xp );
    614633
    615 #if DEBUG_KCM_REMOTE
    616 thread_t * this  = CURRENT_THREAD;
    617 uint32_t   cycle = (uint32_t)hal_get_cycles();
    618 if( DEBUG_KCM_REMOTE < cycle )
    619 printk("\n[%s] thread[%x,%x] allocated block %x / order %d / kcm[%x,%x]\n",
    620 __FUNCTION__, this->process->pid, this->trdid, block_ptr, order, kcm_cxy, kcm_ptr );
    621 #endif
    622 
    623634        return block_ptr;
    624635
    625636}  // end kcm_remote_alloc()
    626637
    627 /////////////////////////////////////
    628 void kcm_remote_free( cxy_t  kcm_cxy,
    629                       void * block_ptr )
     638////////////////////////////////////////
     639void kcm_remote_free( cxy_t     kcm_cxy,
     640                      void    * block_ptr,
     641                      uint32_t  order )
    630642{
    631643        kcm_t      * kcm_ptr;
    632644        kcm_page_t * kcm_page;
    633645
    634 // check argument
    635 assert( __FUNCTION__, (block_ptr != NULL) , "block pointer cannot be NULL" );
    636 
    637     // get local pointer on remote KCM page
    638         kcm_page = (kcm_page_t *)((intptr_t)block_ptr & ~CONFIG_PPM_PAGE_MASK);
    639 
    640     // get local pointer on remote KCM
    641         kcm_ptr = hal_remote_lpt( XPTR( kcm_cxy , &kcm_page->kcm ) );
     646// check kcm_cxy argument
     647assert( __FUNCTION__, cluster_is_active( kcm_cxy ),
     648"cluster %x not active", kcm_cxy );
     649
     650// check block_ptr argument
     651assert( __FUNCTION__, (block_ptr != NULL),
     652"block pointer cannot be NULL" );
     653
     654// check order argument
     655assert( __FUNCTION__, (order < CONFIG_PPM_PAGE_ORDER) ,
     656"order argument %d too large", order );
     657
     658    // smallest block size is a cache line
     659    if (order < CONFIG_CACHE_LINE_ORDER) order = CONFIG_CACHE_LINE_ORDER;
     660
     661    // get local pointer on relevant KCM allocator (same in all clusters)
     662    kcm_ptr = &LOCAL_CLUSTER->kcm[order - CONFIG_CACHE_LINE_ORDER];
     663
     664    // get local pointer on KCM page
     665    intptr_t kcm_page_mask = (1 << (order + 6)) - 1;
     666        kcm_page = (kcm_page_t *)((intptr_t)block_ptr & ~kcm_page_mask);
     667
     668#if DEBUG_KCM
     669uint32_t cycle     = (uint32_t)hal_get_cycles();
     670uint32_t nb_full   = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->full_pages_nr ));
     671uint32_t nb_active = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->active_pages_nr ));
     672uint64_t status    = hal_remote_l64( XPTR( kcm_cxy , &kcm_page->status ));
     673uint32_t count     = hal_remote_l32( XPTR( kcm_cxy , &kcm_page->count ));
     674#endif
    642675
    643676    // build extended pointer on remote KCM lock
     
    647680        remote_busylock_acquire( lock_xp );
    648681
    649         // release block
     682#if DEBUG_KCM
     683if( (DEBUG_KCM_ORDER == order) && (DEBUG_KCM_CXY == local_cxy) && (DEBUG_KCM < cycle) )
     684printk("\n[%s] enter / order %d / kcm[%x,%x] / nb_full %d / nb_active %d\n"
     685"    page %x / status [%x,%x] / count %d\n",
     686__FUNCTION__, order, kcm_cxy, kcm_ptr, nb_full, nb_active,
     687kcm_page, (uint32_t)(status>>32), (uint32_t)(status), kcm_page->count );
     688#endif
     689
     690        // release the block to the relevant page
    650691        kcm_remote_put_block( kcm_cxy , kcm_ptr , kcm_page , block_ptr );
     692
     693#if DEBUG_KCM
     694if( (DEBUG_KCM_ORDER == order) && (DEBUG_KCM_CXY == local_cxy) && (DEBUG_KCM < cycle) )
     695printk("\n[%s] exit  / order %d / kcm[%x,%x] / nb_full %d / nb_active %d\n"
     696"    page %x / status [%x,%x] / count %d\n",
     697__FUNCTION__, order, kcm_cxy, kcm_ptr, nb_full, nb_active,
     698kcm_page, (uint32_t)(status>>32), (uint32_t)(status), kcm_page->count );
     699#endif
    651700
    652701        // release lock
    653702        remote_busylock_release( lock_xp );
    654 
    655 #if DEBUG_KCM_REMOTE
    656 thread_t * this  = CURRENT_THREAD;
    657 uint32_t   cycle = (uint32_t)hal_get_cycles();
    658 uint32_t   order = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->order ) );
    659 if( DEBUG_KCM_REMOTE < cycle )
    660 printk("\n[%s] thread[%x,%x] released block %x / order %d / kcm[%x,%x]\n",
    661 __FUNCTION__, this->process->pid, this->trdid, block_ptr, order, kcm_cxy, kcm_ptr );
    662 #endif
    663703
    664704}  // end kcm_remote_free
     
    673713    uint32_t       count;
    674714
     715    // get pointers on TXT0 chdev
     716    xptr_t    txt0_xp  = chdev_dir.txt_tx[0];
     717    cxy_t     txt0_cxy = GET_CXY( txt0_xp );
     718    chdev_t * txt0_ptr = GET_PTR( txt0_xp );
     719
     720    // get extended pointer on remote TXT0 chdev lock
     721    xptr_t    txt0_lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
     722
     723    // get TXT0 lock
     724    remote_busylock_acquire( txt0_lock_xp );
     725
    675726    uint32_t order           = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->order) );
    676727    uint32_t full_pages_nr   = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->full_pages_nr ) );
    677728    uint32_t active_pages_nr = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->active_pages_nr ) );
    678729
    679         printk("*** KCM : cxy %x / order %d / full_pages_nr %d / active_pages_nr %d\n",
     730        nolock_printk("*** KCM : cxy %x / order %d / full_pages_nr %d / active_pages_nr %d\n",
    680731        kcm_cxy, order, full_pages_nr, active_pages_nr );
    681732
     
    688739            count    = hal_remote_l32( XPTR( kcm_cxy , &kcm_page->count ) );
    689740
    690             printk("- active page %x / status (%x,%x) / count %d\n",
    691             kcm_page, GET_CXY( status ), GET_PTR( status ), count );
     741            nolock_printk("- active page %x / status (%x,%x) / count %d\n",
     742            kcm_page, (uint32_t)( status<< 32 ), (uint32_t)( status ), count );
    692743        }
    693744    }
     
    701752            count    = hal_remote_l32( XPTR( kcm_cxy , &kcm_page->count ) );
    702753
    703             printk("- full page %x / status (%x,%x) / count %d\n",
    704             kcm_page, GET_CXY( status ), GET_PTR( status ), count );
     754            nolock_printk("- full page %x / status (%x,%x) / count %d\n",
     755            kcm_page, (uint32_t)( status<< 32 ), (uint32_t)( status ), count );
    705756        }
    706757    }
     758
     759    // release TXT0 lock
     760    remote_busylock_release( txt0_lock_xp );
     761
    707762}  // end kcm remote_display()
Note: See TracChangeset for help on using the changeset viewer.