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


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

    r672 r683  
    11/*
    2  * vmm.c - virtual memory manager related operations definition.
     2 * vmm.c - virtual memory manager related operations implementation.
    33 *
    44 * Authors   Ghassan Almaless (2008,2009,2010,2011,2012)
     
    8989
    9090// check ltid argument
    91 assert( __FUNCTION__, (ltid <= ((CONFIG_VMM_VSPACE_SIZE - CONFIG_VMM_STACK_BASE) / CONFIG_VMM_STACK_SIZE)),
     91assert( __FUNCTION__,
     92(ltid <= ((CONFIG_VMM_VSPACE_SIZE - CONFIG_VMM_STACK_BASE) / CONFIG_VMM_STACK_SIZE)),
    9293"slot index %d too large for an user stack vseg", ltid );
    9394
     
    107108    if( vseg == NULL )
    108109        {
    109         // release lock protecting free lists
     110 
     111#if DEBUG_VMM_ERROR
     112printk("\n[ERROR] %s cannot allocate memory for vseg in cluster %x\n",
     113__FUNCTION__ , local_cxy );
     114#endif
    110115        busylock_release( &mgr->lock );
    111 
    112         printk("\n[ERROR] %s cannot allocate memory for vseg in cluster %x\n",
    113         __FUNCTION__ , local_cxy );
    114 
    115116        return NULL;
    116117    }
     
    346347    if( current_vseg == NULL )  // return failure
    347348    {
    348         // release lock protecting free lists
     349
     350#if DEBUG_VMM_ERROR
     351printk("\n[ERROR] %s cannot allocate ) %d page(s) in cluster %x\n",
     352__FUNCTION__, npages , local_cxy );
     353#endif
    349354        busylock_release( &mgr->lock );
    350 
    351         printk("\n[ERROR] %s cannot allocate ) %d page(s) in cluster %x\n",
    352         __FUNCTION__, npages , local_cxy );
    353 
    354355        return NULL;
    355356    }
     
    368369            if( new_vseg == NULL )
    369370        {
    370                 // release lock protecting free lists
     371
     372#if DEBUG_VMM_ERROR
     373printk("\n[ERROR] %s cannot allocate memory for vseg in cluster %x\n",
     374__FUNCTION__ , local_cxy );
     375#endif
    371376            busylock_release( &mgr->lock );
    372 
    373             printk("\n[ERROR] %s cannot allocate memory for vseg in cluster %x\n",
    374             __FUNCTION__ , local_cxy );
    375 
    376377            return NULL;
    377378            }
     
    517518                    XPTR( local_cxy , &vseg->xlist ) );
    518519
    519 }  // end vmm_attach_vseg_from_vsl()
     520}  // end vmm_attach_vseg_to_vsl()
    520521
    521522////////////////////////////////////////////////////////////////////////////////////////////
     
    537538    xlist_unlink( XPTR( local_cxy , &vseg->xlist ) );
    538539
    539 }  // end vmm_detach_from_vsl()
     540}  // end vmm_detach_vseg_from_vsl()
    540541
    541542////////////////////////////////////////////
     
    12901291            if( child_vseg == NULL )   // release all allocated vsegs
    12911292            {
     1293
     1294#if DEBUG_VMM_ERROR
     1295printk("\n[ERROR] in %s : cannot create vseg for child in cluster %x\n",
     1296__FUNCTION__, local_cxy );
     1297#endif
    12921298                vmm_destroy( child_process );
    1293                 printk("\n[ERROR] in %s : cannot create vseg for child\n", __FUNCTION__ );
    12941299                return -1;
    12951300            }
     
    13381343                    if( error )
    13391344                    {
     1345
     1346#if DEBUG_VMM_ERROR
     1347printk("\n[ERROR] in %s : cannot copy GPT\n",
     1348__FUNCTION__ );
     1349#endif
    13401350                        vmm_destroy( child_process );
    1341                         printk("\n[ERROR] in %s : cannot copy GPT\n", __FUNCTION__ );
    13421351                        return -1;
    13431352                    }
     
    13571366    remote_queuelock_release( parent_lock_xp );
    13581367
    1359 /* deprecated [AG] : this is already done by the vmm_user_init() funcfion
    1360 
    1361     // initialize the child VMM STACK allocator
    1362     vmm_stack_init( child_vmm );
    1363 
    1364     // initialize the child VMM MMAP allocator
    1365     vmm_mmap_init( child_vmm );
    1366 
    1367     // initialize instrumentation counters
    1368         child_vmm->false_pgfault_nr    = 0;
    1369         child_vmm->local_pgfault_nr    = 0;
    1370         child_vmm->global_pgfault_nr   = 0;
    1371         child_vmm->false_pgfault_cost  = 0;
    1372         child_vmm->local_pgfault_cost  = 0;
    1373         child_vmm->global_pgfault_cost = 0;
    1374 */
    13751368    // copy base addresses from parent VMM to child VMM
    13761369    child_vmm->args_vpn_base = (vpn_t)hal_remote_lpt(XPTR(parent_cxy, &parent_vmm->args_vpn_base));
     
    15641557        if( vseg == NULL )
    15651558        {
    1566             printk("\n[ERROR] %s cannot create %s vseg for process %x in cluster %x\n",
    1567             __FUNCTION__ , vseg_type_str( type ) , process->pid , local_cxy );
     1559
     1560#if DEBUG_VMM_ERROR
     1561printk("\n[ERROR] %s cannot create %s vseg for process %x in cluster %x\n",
     1562__FUNCTION__ , vseg_type_str( type ) , process->pid , local_cxy );
     1563#endif
    15681564            return NULL;
    15691565        }
     
    15721568        vseg->type = type;
    15731569        vseg->vmm  = vmm;
    1574         vseg->min  = vseg->vpn_base << CONFIG_PPM_PAGE_SHIFT;
    1575         vseg->max  = vseg->min + (vseg->vpn_size << CONFIG_PPM_PAGE_SHIFT);
     1570        vseg->min  = vseg->vpn_base << CONFIG_PPM_PAGE_ORDER;
     1571        vseg->max  = vseg->min + (vseg->vpn_size << CONFIG_PPM_PAGE_ORDER);
    15761572        vseg->cxy  = cxy;
    15771573
     
    15821578    {
    15831579        // compute page index (in mapper) for first and last byte
    1584         vpn_t    vpn_min    = file_offset >> CONFIG_PPM_PAGE_SHIFT;
    1585         vpn_t    vpn_max    = (file_offset + size - 1) >> CONFIG_PPM_PAGE_SHIFT;
     1580        vpn_t    vpn_min    = file_offset >> CONFIG_PPM_PAGE_ORDER;
     1581        vpn_t    vpn_max    = (file_offset + size - 1) >> CONFIG_PPM_PAGE_ORDER;
    15861582
    15871583        // compute offset in first page and number of pages
     
    15941590        if( vseg == NULL )
    15951591        {
    1596             printk("\n[ERROR] %s cannot create %s vseg for process %x in cluster %x\n",
    1597             __FUNCTION__ , vseg_type_str( type ) , process->pid , local_cxy );
     1592
     1593#if DEBUG_VMM_ERROR
     1594printk("\n[ERROR] %s cannot create %s vseg for process %x in cluster %x\n",
     1595__FUNCTION__ , vseg_type_str( type ) , process->pid , local_cxy );
     1596#endif
    15981597            return NULL;
    15991598        }
     
    16021601        vseg->type        = type;
    16031602        vseg->vmm         = vmm;
    1604         vseg->min         = (vseg->vpn_base << CONFIG_PPM_PAGE_SHIFT) + offset;
     1603        vseg->min         = (vseg->vpn_base << CONFIG_PPM_PAGE_ORDER) + offset;
    16051604        vseg->max         = vseg->min + size;
    16061605        vseg->file_offset = file_offset;
     
    16151614    {
    16161615        // compute number of required pages in virtual space
    1617         vpn_t npages = size >> CONFIG_PPM_PAGE_SHIFT;
     1616        vpn_t npages = size >> CONFIG_PPM_PAGE_ORDER;
    16181617        if( size & CONFIG_PPM_PAGE_MASK) npages++;
    16191618       
     
    16231622        if( vseg == NULL )
    16241623        {
    1625             printk("\n[ERROR] %s cannot create %s vseg for process %x in cluster %x\n",
    1626             __FUNCTION__ , vseg_type_str( type ) , process->pid , local_cxy );
     1624
     1625#if DEBUG_VMM_ERROR
     1626printk("\n[ERROR] %s cannot create %s vseg for process %x in cluster %x\n",
     1627__FUNCTION__ , vseg_type_str( type ) , process->pid , local_cxy );
     1628#endif
    16271629            return NULL;
    16281630        }
     
    16311633        vseg->type = type;
    16321634        vseg->vmm  = vmm;
    1633         vseg->min  = vseg->vpn_base << CONFIG_PPM_PAGE_SHIFT;
    1634         vseg->max  = vseg->min + (vseg->vpn_size << CONFIG_PPM_PAGE_SHIFT);
     1635        vseg->min  = vseg->vpn_base << CONFIG_PPM_PAGE_ORDER;
     1636        vseg->max  = vseg->min + (vseg->vpn_size << CONFIG_PPM_PAGE_ORDER);
    16351637        vseg->cxy  = cxy;
    16361638
     
    16401642    else    // VSEG_TYPE_DATA, VSEG_TYPE_CODE or KERNEL vseg
    16411643    {
    1642         uint32_t vpn_min = base >> CONFIG_PPM_PAGE_SHIFT;
    1643         uint32_t vpn_max = (base + size - 1) >> CONFIG_PPM_PAGE_SHIFT;
     1644        uint32_t vpn_min = base >> CONFIG_PPM_PAGE_ORDER;
     1645        uint32_t vpn_max = (base + size - 1) >> CONFIG_PPM_PAGE_ORDER;
    16441646
    16451647        // allocate vseg descriptor
     
    16481650            if( vseg == NULL )
    16491651            {
    1650             printk("\n[ERROR] %s cannot create %s vseg for process %x in cluster %x\n",
    1651             __FUNCTION__ , vseg_type_str( type ) , process->pid , local_cxy );
     1652
     1653#if DEBUG_VMM_ERROR
     1654printk("\n[ERROR] %s cannot create %s vseg for process %x in cluster %x\n",
     1655__FUNCTION__ , vseg_type_str( type ) , process->pid , local_cxy );
     1656#endif
    16521657            return NULL;
    16531658            }
     1659
    16541660        // initialize vseg
    16551661        vseg->type        = type;
     
    16571663        vseg->min         = base;
    16581664        vseg->max         = base + size;
    1659         vseg->vpn_base    = base >> CONFIG_PPM_PAGE_SHIFT;
     1665        vseg->vpn_base    = base >> CONFIG_PPM_PAGE_ORDER;
    16601666        vseg->vpn_size    = vpn_max - vpn_min + 1;
    16611667        vseg->file_offset = file_offset;
     
    16721678    if( existing_vseg != NULL )
    16731679    {
    1674         printk("\n[ERROR] in %s for process %x : new vseg %s [vpn_base %x / vpn_size %x]\n"
    1675                "        overlap existing vseg %s [vpn_base %x / vpn_size %x]\n",
    1676         __FUNCTION__ , process->pid, vseg_type_str(vseg->type), vseg->vpn_base, vseg->vpn_size,
    1677         vseg_type_str(existing_vseg->type), existing_vseg->vpn_base, existing_vseg->vpn_size );
     1680
     1681#if DEBUG_VMM_ERROR
     1682printk("\n[ERROR] in %s for process %x : new vseg %s [vpn_base %x / vpn_size %x]\n"
     1683       "        overlap existing vseg %s [vpn_base %x / vpn_size %x]\n",
     1684__FUNCTION__ , process->pid, vseg_type_str(vseg->type), vseg->vpn_base, vseg->vpn_size,
     1685vseg_type_str(existing_vseg->type), existing_vseg->vpn_base, existing_vseg->vpn_size );
     1686#endif
    16781687        vseg_free( vseg );
    16791688        return NULL;
     
    18011810    if( do_kmem_release )
    18021811    {
    1803         kmem_req_t req;
    1804         req.type = KMEM_PPM;
    1805         req.ptr  = GET_PTR( ppm_ppn2base( ppn ) );
    1806 
    1807         kmem_remote_free( page_cxy , &req );
     1812        // get physical page order
     1813        uint32_t order = CONFIG_PPM_PAGE_ORDER +
     1814                         hal_remote_l32( XPTR( page_cxy , &page_ptr->order ));
     1815
     1816        // get physical page base
     1817        void * base = GET_PTR( ppm_ppn2base( ppn ) );
     1818
     1819        // release physical page
     1820        kmem_remote_free( page_cxy , base , order );
    18081821
    18091822#if DEBUG_VMM_PPN_RELEASE
     
    18551868#endif
    18561869
    1857     // loop on PTEs in GPT to unmap all mapped PTE
    1858         for( vpn = vpn_min ; vpn < vpn_max ; vpn++ )
     1870    // the loop on PTEs in GPT to unmap all mapped PTEs
     1871    for( vpn = vpn_min ; vpn < vpn_max ; vpn++ )
    18591872    {
    18601873        // get ppn and attr
     
    19421955    intptr_t min          = new_base;
    19431956    intptr_t max          = new_base + new_size;
    1944     vpn_t    new_vpn_min  = min >> CONFIG_PPM_PAGE_SHIFT;
    1945     vpn_t    new_vpn_max  = (max - 1) >> CONFIG_PPM_PAGE_SHIFT;
     1957    vpn_t    new_vpn_min  = min >> CONFIG_PPM_PAGE_ORDER;
     1958    vpn_t    new_vpn_max  = (max - 1) >> CONFIG_PPM_PAGE_ORDER;
    19461959
    19471960    // build extended pointer on GPT
     
    20822095        if( ref_cxy == local_cxy )    // local is ref => return error
    20832096        {
    2084             printk("\n[ERROR] in %s : vaddr %x in process %x out of segment\n",
    2085             __FUNCTION__, vaddr, process->pid );
    2086 
    2087             // release local VSL lock
     2097
     2098#if DEBUG_VMM_ERROR
     2099printk("\n[ERROR] in %s : vaddr %x in process %x out of segment\n",
     2100__FUNCTION__, vaddr, process->pid );
     2101#endif
    20882102            remote_queuelock_release( loc_lock_xp );
    2089 
    20902103            return -1;
    20912104        }
     
    21032116            if( ref_vseg == NULL )  // vseg not found => return error
    21042117            {
    2105                 // release both VSL locks
     2118
     2119#if DEBUG_VMM_ERROR
     2120printk("\n[ERROR] in %s : vaddr %x in process %x out of segment\n",
     2121__FUNCTION__, vaddr, process->pid );
     2122#endif
    21062123                remote_queuelock_release( loc_lock_xp );
    21072124                remote_queuelock_release( ref_lock_xp );
    2108 
    2109                 printk("\n[ERROR] in %s : vaddr %x in process %x out of segment\n",
    2110                 __FUNCTION__, vaddr, process->pid );
    2111 
    21122125                return -1;
    21132126            }
     
    21192132                if( loc_vseg == NULL )   // no memory => return error
    21202133                {
    2121                     printk("\n[ERROR] in %s : vaddr %x in process %x / no memory\n",
    2122                     __FUNCTION__, vaddr, process->pid );
    2123 
    2124                     // release both VSL locks
     2134
     2135#if DEBUG_VMM_ERROR
     2136printk("\n[ERROR] in %s : vaddr %x in process %x / no memory\n",
     2137__FUNCTION__, vaddr, process->pid );
     2138#endif
    21252139                    remote_queuelock_release( ref_lock_xp );
    21262140                    remote_queuelock_release( loc_lock_xp );
    2127 
    21282141                    return -1;
    21292142                }
     
    21582171//////////////////////////////////////////////////////////////////////////////////////
    21592172// This static function compute the target cluster to allocate a physical page
    2160 // for a given <vpn> in a given <vseg>, allocates the page and returns an extended
    2161 // pointer on the allocated page descriptor.
     2173// for a given <vpn> in a given <vseg>, allocates the physical page from a local
     2174// or remote cluster (depending on the vseg type), and returns an extended pointer
     2175// on the allocated page descriptor.
    21622176// The vseg cannot have the FILE type.
    21632177//////////////////////////////////////////////////////////////////////////////////////
    21642178// @ vseg   : local pointer on vseg.
    21652179// @ vpn    : unmapped vpn.
    2166 // @ return an extended pointer on the allocated page descriptor.
     2180// @ return xptr on page descriptor if success / return XPTR_NULL if failure
    21672181//////////////////////////////////////////////////////////////////////////////////////
    21682182static xptr_t vmm_page_allocate( vseg_t * vseg,
     
    22072221    }
    22082222
    2209     // allocate one small physical page from target cluster
    2210     kmem_req_t req;
    2211     req.type  = KMEM_PPM;
    2212     req.order = 0;
    2213     req.flags = AF_ZERO;
    2214 
    22152223    // get local pointer on page base
    2216     void * ptr = kmem_remote_alloc( page_cxy , &req );
    2217 
     2224    void * ptr = kmem_remote_alloc( page_cxy , CONFIG_PPM_PAGE_ORDER , AF_ZERO );
     2225
     2226    if( ptr == NULL )
     2227    {
     2228
     2229#if DEBUG_VMM_ERROR
     2230printk("\n[ERROR] in %s : cannot allocate memory from cluster %x\n",
     2231__FUNCTION__, page_cxy );
     2232#endif
     2233        return XPTR_NULL;
     2234    }     
    22182235    // get extended pointer on page descriptor
    22192236    page_xp = ppm_base2page( XPTR( page_cxy , ptr ) );
     
    22912308       
    22922309            // compute missing page offset in vseg
    2293             uint32_t offset = page_id << CONFIG_PPM_PAGE_SHIFT;
     2310            uint32_t offset = page_id << CONFIG_PPM_PAGE_ORDER;
    22942311
    22952312            // compute missing page offset in .elf file
     
    24272444    // get local vseg (access to reference VSL can be required)
    24282445    error = vmm_get_vseg( process,
    2429                           (intptr_t)vpn<<CONFIG_PPM_PAGE_SHIFT,
     2446                          (intptr_t)vpn<<CONFIG_PPM_PAGE_ORDER,
    24302447                          &vseg );
    24312448    if( error )
     
    27522769    // get local vseg
    27532770    error = vmm_get_vseg( process,
    2754                           (intptr_t)vpn<<CONFIG_PPM_PAGE_SHIFT,
     2771                          (intptr_t)vpn<<CONFIG_PPM_PAGE_ORDER,
    27552772                          &vseg );
    27562773    if( error )
Note: See TracChangeset for help on using the changeset viewer.