Ignore:
Timestamp:
Jun 26, 2019, 11:42:37 AM (5 years ago)
Author:
alain
Message:

This version is a major evolution: The physical memory allocators,
defined in the kmem.c, ppm.c, and kcm.c files have been modified
to support remote accesses. The RPCs that were previously user
to allocate physical memory in a remote cluster have been removed.
This has been done to cure a dead-lock in case of concurrent page-faults.

This version 2.2 has been tested on a (4 clusters / 2 cores per cluster)
TSAR architecture, for both the "sort" and the "fft" applications.

File:
1 edited

Legend:

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

    r628 r635  
    5252    error_t    error;
    5353
    54     // allocate memory for mapper
    55     req.type  = KMEM_MAPPER;
    56     req.size  = sizeof(mapper_t);
     54    // allocate memory for mapper descriptor
     55    req.type  = KMEM_KCM;
     56    req.order = bits_log2( sizeof(mapper_t) );
    5757    req.flags = AF_KERNEL | AF_ZERO;
    58     mapper    = (mapper_t *)kmem_alloc( &req );
     58    mapper    = kmem_alloc( &req );
    5959
    6060    if( mapper == NULL )
     
    7373                        CONFIG_MAPPER_GRDXT_W2,
    7474                        CONFIG_MAPPER_GRDXT_W3 );
    75 
    7675    if( error )
    7776    {
    7877        printk("\n[ERROR] in %s : cannot initialize radix tree\n", __FUNCTION__ );
    79         req.type  = KMEM_MAPPER;
     78        req.type  = KMEM_KCM;
    8079        req.ptr   = mapper;
    8180        kmem_free( &req );
     
    117116        {
    118117            // remove page from mapper and release to PPM
    119             mapper_release_page( mapper , page );
     118            mapper_remote_release_page( XPTR( local_cxy , mapper ) , page );
    120119
    121120            // update start_key value for next page
     
    129128
    130129    // release memory for mapper descriptor
    131     req.type = KMEM_MAPPER;
     130    req.type = KMEM_KCM;
    132131    req.ptr  = mapper;
    133132    kmem_free( &req );
    134133
    135134}  // end mapper_destroy()
     135
     136////////////////////////////////////////////////////////
     137error_t mapper_remote_handle_miss( xptr_t     mapper_xp,
     138                                   uint32_t   page_id,
     139                                   xptr_t   * page_xp_ptr )
     140{
     141    error_t    error;
     142
     143    thread_t * this = CURRENT_THREAD;
     144
     145    // get target mapper cluster and local pointer
     146    cxy_t      mapper_cxy = GET_CXY( mapper_xp );
     147    mapper_t * mapper_ptr = GET_PTR( mapper_xp );
     148
     149#if DEBUG_MAPPER_HANDLE_MISS
     150uint32_t      cycle = (uint32_t)hal_get_cycles();
     151char          name[CONFIG_VFS_MAX_NAME_LENGTH];
     152vfs_inode_t * inode = mapper->inode;
     153if( (DEBUG_MAPPER_HANDLE_MISS < cycle) && (inode != NULL) )
     154{
     155    vfs_inode_get_name( XPTR( local_cxy , inode ) , name );
     156    printk("\n[%s] thread[%x,%x] enter for page %d in <%s> / cluster %x / cycle %d",
     157    __FUNCTION__, this->process->pid, this->trdid, page_id, name, mapper_cxy, cycle );
     158    if( DEBUG_MAPPER_HANDLE_MISS & 1 ) grdxt_display( XPTR(local_cxy,&mapper->rt), name );
     159}
     160if( (DEBUG_MAPPER_HANDLE_MISS < cycle) && (inode == NULL) )
     161{
     162    printk("\n[%s] thread[%x,%x] enter for page %d in FAT / cluster %x / cycle %d",
     163    __FUNCTION__, this->process->pid, this->trdid, page_id, mapper_cxy, cycle );
     164    if( DEBUG_MAPPER_HANDLE_MISS & 1 ) grdxt_display( XPTR(local_cxy,&mapper->rt), "FAT" );
     165}
     166#endif
     167
     168    // allocate one 4 Kbytes page from the remote mapper cluster
     169    page_t * page_ptr = ppm_remote_alloc_pages( mapper_cxy , 0 );
     170                           
     171    if( page_ptr == NULL )
     172    {
     173        printk("\n[ERROR] in %s : thread [%x,%x] cannot allocate page in cluster %x\n",
     174        __FUNCTION__ , this->process->pid, this->trdid , mapper_cxy );
     175        return -1;
     176    }
     177
     178    // build extended pointer on new page descriptor
     179    xptr_t page_xp = XPTR( mapper_cxy , page_ptr );
     180
     181    // initialize the page descriptor
     182    page_remote_init( page_xp );
     183
     184    hal_remote_s32( XPTR( mapper_cxy , &page_ptr->refcount ) , 1          );
     185    hal_remote_s32( XPTR( mapper_cxy , &page_ptr->index )    , page_id    );
     186    hal_remote_spt( XPTR( mapper_cxy , &page_ptr->mapper )   , mapper_ptr );
     187    hal_remote_s32( XPTR( mapper_cxy , &page_ptr->flags )    , PG_INIT    );
     188
     189    // insert page in mapper radix tree
     190    error = grdxt_remote_insert( XPTR( mapper_cxy , &mapper_ptr->rt),
     191                                 page_id,
     192                                 page_ptr );
     193
     194    if( error )
     195    {
     196        printk("\n[ERROR] in %s : thread[%x,%x] cannot insert page in mapper\n",
     197        __FUNCTION__ , this->process->pid, this->trdid );
     198        ppm_remote_free_pages( mapper_cxy , page_ptr );
     199        return -1;
     200    }
     201
     202    // launch I/O operation to load page from IOC device to mapper
     203    error = vfs_fs_move_page( page_xp , IOC_SYNC_READ );
     204
     205    if( error )
     206    {
     207        printk("\n[ERROR] in %s : thread[%x,%x] cannot load page from device\n",
     208        __FUNCTION__ , this->process->pid, this->trdid );
     209        mapper_remote_release_page( mapper_xp , page_ptr );
     210        return -1;
     211    }
     212
     213    // return extended pointer on allocated page
     214    *page_xp_ptr = page_xp;
     215
     216#if DEBUG_MAPPER_HANDLE_MISS
     217cycle = (uint32_t)hal_get_cycles();
     218if( (DEBUG_MAPPER_HANDLE_MISS < cycle) && (inode != NULL) )
     219{
     220    printk("\n[%s] thread[%x,%x] exit for page %d in <%s> / ppn %x / cycle %d",
     221    __FUNCTION__, this->process->pid, this->trdid,
     222    page_id, name, ppm_page2ppn( page_xp ), cycle );
     223    if( DEBUG_MAPPER_HANDLE_MISS & 1 ) grdxt_display( XPTR(local_cxy,&mapper->rt) , name );
     224}
     225if( (DEBUG_MAPPER_HANDLE_MISS < cycle) && (inode == NULL) )
     226{
     227    printk("\n[%s] thread[%x,%x] exit for page %d in FAT / ppn %x / cycle %d",
     228    __FUNCTION__, this->process->pid, this->trdid,
     229    page_id, ppm_page2ppn( page_xp ), cycle );
     230    if( DEBUG_MAPPER_HANDLE_MISS & 1 ) grdxt_display( XPTR(local_cxy,&mapper->rt ), "FAT" );
     231}
     232#endif
     233
     234    return 0;
     235
     236}  // end mapper_remote_handle_miss()
    136237
    137238////////////////////////////////////////////////////
     
    183284
    184285    // test mapper miss
    185     if( page_xp == XPTR_NULL )                  // miss => try to handle it
     286    if( page_xp == XPTR_NULL )                  // miss => handle it
    186287    {
    187288        // release the lock in READ_MODE and take it in WRITE_MODE
     
    196297        if ( page_xp == XPTR_NULL )  // miss confirmed => handle it
    197298        {
    198 
    199             if( mapper_cxy == local_cxy )   // mapper is local
    200             {
    201 
    202 #if (DEBUG_MAPPER_GET_PAGE & 1)
    203 if( DEBUG_MAPPER_GET_PAGE < cycle )
    204 printk("\n[%s] missing page => load it from FS / local access \n", __FUNCTION__ );
    205 #endif
    206                  error = mapper_handle_miss( mapper_ptr,
    207                                              page_id,
    208                                              &page_xp );
    209             }
    210             else
    211             {
    212 
    213 #if (DEBUG_MAPPER_GET_PAGE & 1)
    214 if( DEBUG_MAPPER_GET_PAGE < cycle )
    215 printk("\n[%s] missing page => load it from FS / RPC access \n", __FUNCTION__ );
    216 #endif
    217                  rpc_mapper_handle_miss_client( mapper_cxy,
    218                                                 mapper_ptr,
    219                                                 page_id,
    220                                                 &page_xp,
    221                                                 &error );
    222             }
    223 
    224             if ( error )
     299            error = mapper_remote_handle_miss( mapper_xp,
     300                                               page_id,
     301                                               &page_xp );
     302            if( error )
    225303            {
    226304                printk("\n[ERROR] in %s : thread[%x,%x] cannot handle mapper miss\n",
     
    230308            }
    231309        }
     310
     311#if (DEBUG_MAPPER_GET_PAGE & 1)
     312if( DEBUG_MAPPER_GET_PAGE < cycle )
     313printk("\n[%s] thread[%x,%x] load missing page from FS : ppn %x\n",
     314__FUNCTION__, this->process->pid, this->trdid, ppm_page2ppn(page_xp) );
     315#endif
    232316       
    233317        // release mapper lock from WRITE_MODE
     
    260344}  // end mapper_remote_get_page()
    261345
    262 //////////////////////////////////////////////
    263 error_t mapper_handle_miss( mapper_t * mapper,
    264                             uint32_t   page_id,
    265                             xptr_t   * page_xp )
    266 {
    267     kmem_req_t   req;
    268     page_t     * page;
    269     error_t      error;
    270 
    271     thread_t * this = CURRENT_THREAD;
    272 
    273 #if DEBUG_MAPPER_HANDLE_MISS
    274 uint32_t      cycle = (uint32_t)hal_get_cycles();
    275 char          name[CONFIG_VFS_MAX_NAME_LENGTH];
    276 vfs_inode_t * inode = mapper->inode;
    277 if( (DEBUG_MAPPER_HANDLE_MISS < cycle) && (inode != NULL) )
    278 {
    279     vfs_inode_get_name( XPTR( local_cxy , inode ) , name );
    280     printk("\n[%s] thread[%x,%x] enter for page %d in <%s> / cycle %d",
    281     __FUNCTION__, this->process->pid, this->trdid, page_id, name, cycle );
    282     if( DEBUG_MAPPER_HANDLE_MISS & 1 ) grdxt_display( XPTR(local_cxy,&mapper->rt), name );
    283 }
    284 if( (DEBUG_MAPPER_HANDLE_MISS < cycle) && (inode == NULL) )
    285 {
    286     printk("\n[%s] thread[%x,%x] enter for page %d in FAT / cycle %d",
    287     __FUNCTION__, this->process->pid, this->trdid, page_id, cycle );
    288     if( DEBUG_MAPPER_HANDLE_MISS & 1 ) grdxt_display( XPTR(local_cxy,&mapper->rt), "FAT" );
    289 }
    290 #endif
    291 
    292     // allocate one page from the local cluster
    293     req.type  = KMEM_PAGE;
    294     req.size  = 0;
    295     req.flags = AF_NONE;
    296     page = kmem_alloc( &req );
    297 
    298     if( page == NULL )
    299     {
    300         printk("\n[ERROR] in %s : thread [%x,%x] cannot allocate page in cluster %x\n",
    301         __FUNCTION__ , this->process->pid, this->trdid , local_cxy );
    302         return -1;
    303     }
    304 
    305     // initialize the page descriptor
    306     page_init( page );
    307     page_set_flag( page , PG_INIT );
    308     page_refcount_up( page );
    309     page->mapper = mapper;
    310     page->index  = page_id;
    311 
    312     // insert page in mapper radix tree
    313     error = grdxt_insert( &mapper->rt , page_id , page );
    314 
    315     if( error )
    316     {
    317         printk("\n[ERROR] in %s : thread[%x,%x] cannot insert page in mapper\n",
    318         __FUNCTION__ , this->process->pid, this->trdid );
    319         mapper_release_page( mapper , page );
    320         req.ptr  = page;
    321         req.type = KMEM_PAGE;
    322         kmem_free(&req);
    323         return -1;
    324     }
    325 
    326     // launch I/O operation to load page from IOC device to mapper
    327     error = vfs_fs_move_page( XPTR( local_cxy , page ) , IOC_SYNC_READ );
    328 
    329     if( error )
    330     {
    331         printk("\n[ERROR] in %s : thread[%x,%x] cannot load page from device\n",
    332         __FUNCTION__ , this->process->pid, this->trdid );
    333         mapper_release_page( mapper , page );
    334         req.ptr  = page;
    335         req.type = KMEM_PAGE;
    336         kmem_free( &req );
    337         return -1;
    338     }
    339 
    340     // set extended pointer on allocated page
    341     *page_xp = XPTR( local_cxy , page );
    342 
    343 #if DEBUG_MAPPER_HANDLE_MISS
    344 cycle = (uint32_t)hal_get_cycles();
    345 if( (DEBUG_MAPPER_HANDLE_MISS < cycle) && (inode != NULL) )
    346 {
    347     printk("\n[%s] thread[%x,%x] exit for page %d in <%s> / ppn %x / cycle %d",
    348     __FUNCTION__, this->process->pid, this->trdid,
    349     page_id, name, ppm_page2ppn( *page_xp ), cycle );
    350     if( DEBUG_MAPPER_HANDLE_MISS & 1 ) grdxt_display( XPTR(local_cxy,&mapper->rt) , name );
    351 }
    352 if( (DEBUG_MAPPER_HANDLE_MISS < cycle) && (inode == NULL) )
    353 {
    354     printk("\n[%s] thread[%x,%x] exit for page %d in FAT / ppn %x / cycle %d",
    355     __FUNCTION__, this->process->pid, this->trdid,
    356     page_id, ppm_page2ppn( *page_xp ), cycle );
    357     if( DEBUG_MAPPER_HANDLE_MISS & 1 ) grdxt_display( XPTR(local_cxy,&mapper->rt ), "FAT" );
    358 }
    359 #endif
    360 
    361     return 0;
    362 
    363 }  // end mapper_handle_miss()
    364 
    365 ////////////////////////////////////////////
    366 void mapper_release_page( mapper_t * mapper,
    367                           page_t   * page )
    368 {
     346////////////////////////////////////////////////////
     347void mapper_remote_release_page( xptr_t   mapper_xp,
     348                                 page_t * page )
     349{
     350    // get mapper cluster an local pointer
     351    cxy_t      mapper_cxy = GET_CXY( mapper_xp );
     352    mapper_t * mapper_ptr = GET_PTR( mapper_xp );
     353
    369354    // build extended pointer on mapper lock
    370     xptr_t mapper_lock_xp = XPTR( local_cxy , &mapper->lock );
     355    xptr_t lock_xp = XPTR( mapper_cxy , &mapper_ptr->lock );
    371356
    372357    // take mapper lock in WRITE_MODE
    373     remote_rwlock_wr_acquire( mapper_lock_xp );
     358    remote_rwlock_wr_acquire( lock_xp );
    374359
    375360    // remove physical page from radix tree
    376     grdxt_remove( &mapper->rt , page->index );
     361    grdxt_remote_remove( XPTR( mapper_cxy , &mapper_ptr->rt ) , page->index );
    377362
    378363    // release mapper lock from WRITE_MODE
    379     remote_rwlock_wr_release( mapper_lock_xp );
     364    remote_rwlock_wr_release( lock_xp );
    380365
    381366    // release page to PPM
    382     kmem_req_t   req;
    383     req.type  = KMEM_PAGE;
    384     req.ptr   = page;
    385     kmem_free( &req );
    386 
     367    ppm_remote_free_pages( mapper_cxy , page );
     368                           
    387369}  // end mapper_release_page()
    388370
Note: See TracChangeset for help on using the changeset viewer.