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


Ignore:
Timestamp:
May 28, 2019, 2:56:04 PM (5 years ago)
Author:
alain
Message:

This version replace the RPC by direct remote memory access
for physical pages allacation/release.
It is commited before being tested.

File:
1 edited

Legend:

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

    r630 r632  
    12261226    ppn_t       ppn;        // current PTE ppn value
    12271227    uint32_t    attr;       // current PTE attributes
    1228     kmem_req_t  req;        // request to release memory
    12291228    xptr_t      page_xp;    // extended pointer on page descriptor
    12301229    cxy_t       page_cxy;   // page descriptor cluster
     
    13351334
    13361335            // release physical page to relevant kmem when required
    1337             if( ppn_release )
    1338             {
    1339                 if( page_cxy == local_cxy )
    1340                 {
    1341                     req.type = KMEM_PAGE;
    1342                     req.ptr  = page_ptr;
    1343                     kmem_free( &req );
    1344                 }
    1345                 else
    1346                 {
    1347                     rpc_pmem_release_pages_client( page_cxy , page_ptr );
    1348                 }
    1349             }
     1336            if( ppn_release ) ppm_remote_free_pages( page_cxy , page_ptr );
    13501337
    13511338#if( DEBUG_VMM_REMOVE_VSEG & 1 )
     
    16811668//////////////////////////////////////////////////////////////////////////////////////
    16821669// This static function compute the target cluster to allocate a physical page
    1683 // for a given <vpn> in a given <vseg>, allocates the page (with an RPC if required)
    1684 // and returns an extended pointer on the allocated page descriptor.
    1685 // It can be called by a thread running in any cluster.
     1670// for a given <vpn> in a given <vseg>, allocates the page and returns an extended
     1671// pointer on the allocated page descriptor.
    16861672// The vseg cannot have the FILE type.
    16871673//////////////////////////////////////////////////////////////////////////////////////
     
    16901676{
    16911677
    1692 #if DEBUG_VMM_ALLOCATE_PAGE
     1678#if DEBUG_VMM_PAGE_ALLOCATE
    16931679uint32_t   cycle   = (uint32_t)hal_get_cycles();
    16941680thread_t * this    = CURRENT_THREAD;
    1695 if( DEBUG_VMM_ALLOCATE_PAGE < (uint32_t)hal_get_cycles() )
     1681if( DEBUG_VMM_PAGE_ALLOCATE < cycle )
    16961682printk("\n[%s] thread[%x,%x] enter for vpn %x / cycle %d\n",
    16971683__FUNCTION__ , this->process->pid, this->trdid, vpn, cycle );
    16981684#endif
    16991685
    1700     page_t     * page_ptr;
     1686    xptr_t       page_xp;
    17011687    cxy_t        page_cxy;
    1702     kmem_req_t   req;
    17031688    uint32_t     index;
    17041689
     
    17271712    }
    17281713
    1729     // allocate a physical page from target cluster
    1730     if( page_cxy == local_cxy )  // target cluster is the local cluster
    1731     {
    1732         req.type  = KMEM_PAGE;
    1733         req.size  = 0;
    1734         req.flags = AF_NONE;
    1735         page_ptr  = (page_t *)kmem_alloc( &req );
    1736     }
    1737     else                           // target cluster is not the local cluster
    1738     {
    1739         rpc_pmem_get_pages_client( page_cxy , 0 , &page_ptr );
    1740     }
    1741 
    1742 #if DEBUG_VMM_ALLOCATE_PAGE
     1714    // allocate a 4 Kbytes physical page from target cluster
     1715    page_xp = ppm_remote_alloc_pages( page_cxy , 0 );
     1716
     1717#if DEBUG_VMM_PAGE_ALLOCATE
    17431718cycle = (uint32_t)hal_get_cycles();
    1744 if( DEBUG_VMM_ALLOCATE_PAGE < (uint32_t)hal_get_cycles() )
    1745 printk("\n[%s] thread[%x,%x] exit for vpn %x / ppn %x / cycle %d\n",
    1746 __FUNCTION__ , this->process->pid, this->trdid, vpn,
    1747 ppm_page2ppn( XPTR( page_cxy , page_ptr ) , cycle );
    1748 #endif
    1749 
    1750     if( page_ptr == NULL ) return XPTR_NULL;
    1751     else                   return XPTR( page_cxy , page_ptr );
     1719if( DEBUG_VMM_PAGE_ALLOCATE < cycle )
     1720printk("\n[%s] thread[%x,%x] exit for vpn %x / ppn %x / cluster %x / cycle %d\n",
     1721__FUNCTION__ , this->process->pid, this->trdid, vpn, ppm_page2ppn(page_xp), page_cxy, cycle );
     1722#endif
     1723
     1724    return page_xp;
    17521725
    17531726}  // end vmm_page_allocate() 
     
    17691742uint32_t   cycle = (uint32_t)hal_get_cycles();
    17701743thread_t * this  = CURRENT_THREAD;
    1771 if( DEBUG_VMM_GET_ONE_PPN < cycle )
     1744// if( DEBUG_VMM_GET_ONE_PPN < cycle )
     1745if( vpn == 0x40B )
    17721746printk("\n[%s] thread[%x,%x] enter for vpn %x / type %s / page_id  %d / cycle %d\n",
    17731747__FUNCTION__, this->process->pid, this->trdid, vpn, vseg_type_str(type), page_id, cycle );
     
    18151789
    18161790#if (DEBUG_VMM_GET_ONE_PPN & 0x1)
    1817 if( DEBUG_VMM_GET_ONE_PPN < (uint32_t)hal_get_cycles() )
     1791// if( DEBUG_VMM_GET_ONE_PPN < cycle )
     1792if( vpn == 0x40B )
    18181793printk("\n[%s] thread[%x,%x] for vpn = %x / elf_offset = %x\n",
    18191794__FUNCTION__, this->process->pid, this->trdid, vpn, elf_offset );
     
    18291804
    18301805#if (DEBUG_VMM_GET_ONE_PPN & 0x1)
    1831 if( DEBUG_VMM_GET_ONE_PPN < (uint32_t)hal_get_cycles() )
     1806// if( DEBUG_VMM_GET_ONE_PPN < cycle )
     1807if( vpn == 0x40B )
    18321808printk("\n[%s] thread[%x,%x] for vpn  %x / fully in BSS\n",
    18331809__FUNCTION__, this->process->pid, this->trdid, vpn );
     
    18461822
    18471823#if (DEBUG_VMM_GET_ONE_PPN & 0x1)
    1848 if( DEBUG_VMM_GET_ONE_PPN < (uint32_t)hal_get_cycles() )
     1824// if( DEBUG_VMM_GET_ONE_PPN < cycle )
     1825if( vpn == 0x40B )
    18491826printk("\n[%s] thread[%x,%x] for vpn  %x / fully in mapper\n",
    18501827__FUNCTION__, this->process->pid, this->trdid, vpn );
     
    18631840
    18641841#if (DEBUG_VMM_GET_ONE_PPN & 0x1)
    1865 if( DEBUG_VMM_GET_ONE_PPN < (uint32_t)hal_get_cycles() )
     1842// if( DEBUG_VMM_GET_ONE_PPN < cycle )
     1843if( vpn == 0x40B )
    18661844printk("\n[%s] thread[%x,%x] for vpn  %x / both mapper & BSS\n"
    18671845"      %d bytes from mapper / %d bytes from BSS\n",
     
    18971875#if DEBUG_VMM_GET_ONE_PPN
    18981876cycle = (uint32_t)hal_get_cycles();
    1899 if( DEBUG_VMM_GET_ONE_PPN < cycle )
     1877// if( DEBUG_VMM_GET_ONE_PPN < cycle )
     1878if( vpn == 0x40B )
    19001879printk("\n[%s] thread[%x,%x] exit for vpn %x / ppn %x / cycle\n",
    19011880__FUNCTION__ , this->process->pid, this->trdid , vpn , *ppn, cycle );
     
    19281907
    19291908#if DEBUG_VMM_HANDLE_PAGE_FAULT
    1930 if( DEBUG_VMM_HANDLE_PAGE_FAULT < start_cycle )
     1909if( vpn == 0x40b )
    19311910printk("\n[%s] thread[%x,%x] enter for vpn %x / cycle %d\n",
    19321911__FUNCTION__, this->process->pid, this->trdid, vpn, start_cycle );
     
    19501929
    19511930#if DEBUG_VMM_HANDLE_PAGE_FAULT
    1952 if( DEBUG_VMM_HANDLE_PAGE_FAULT < start_cycle )
    1953 printk("\n[%s] thread[%x,%x] found vseg %s\n",
    1954 __FUNCTION__, this->process->pid, this->trdid, vseg_type_str(vseg->type) );
     1931uint32_t cycle = (uint32_t)hal_get_cycles();
     1932if( vpn == 0x40b )
     1933printk("\n[%s] thread[%x,%x] found vseg %s / cycle %d\n",
     1934__FUNCTION__, this->process->pid, this->trdid, vseg_type_str(vseg->type), cycle );
    19551935#endif
    19561936
     
    19581938    local_gpt_xp  = XPTR( local_cxy , &process->vmm.gpt );
    19591939
    1960     // lock target PTE in local GPT and get current PPN and attributes
     1940    // lock PTE in local GPT and get current PPN and attributes
    19611941    error = hal_gpt_lock_pte( local_gpt_xp,
    19621942                              vpn,
     
    19711951    }
    19721952
    1973     // handle page fault only if PTE still unmapped after lock
     1953#if DEBUG_VMM_HANDLE_PAGE_FAULT
     1954cycle = (uint32_t)hal_get_cycles();
     1955if( vpn == 0x40b )
     1956printk("\n[%s] thread[%x,%x] locked vpn %x in cluster %x / cycle %d\n",
     1957__FUNCTION__, this->process->pid, this->trdid, vpn, local_cxy, cycle );
     1958#endif
     1959
     1960    // handle page fault only if local PTE still unmapped after lock
    19741961    if( (attr & GPT_MAPPED) == 0 )
    19751962    {
     
    19841971            (ref_cxy    == local_cxy ) )
    19851972        {
    1986             // allocate and initialise a physical page depending on the vseg type
     1973
     1974#if DEBUG_VMM_HANDLE_PAGE_FAULT
     1975if( vpn == 0x40b )
     1976printk("\n[%s] thread[%x,%x] : access local gpt : local_cxy %x / ref_cxy %x / type %s\n",
     1977__FUNCTION__, this->process->pid, this->trdid, local_cxy, ref_cxy, vseg_type_str(vseg->type) );
     1978#endif
     1979            // allocate and initialise a physical page
    19871980            error = vmm_get_one_ppn( vseg , vpn , &ppn );
    19881981
     
    19991992
    20001993            // define attr from vseg flags
    2001             attr = GPT_MAPPED | GPT_SMALL;
     1994            attr = GPT_MAPPED | GPT_SMALL | GPT_READABLE;
    20021995            if( vseg->flags & VSEG_USER  ) attr |= GPT_USER;
    20031996            if( vseg->flags & VSEG_WRITE ) attr |= GPT_WRITABLE;
     
    20061999
    20072000            // set PTE to local GPT
     2001            // it unlocks this PTE
    20082002            hal_gpt_set_pte( local_gpt_xp,
    20092003                             vpn,
     
    20162010
    20172011#if DEBUG_VMM_HANDLE_PAGE_FAULT
    2018 if( DEBUG_VMM_HANDLE_PAGE_FAULT < end_cycle )
    2019 printk("\n[%s] local page fault handled / vpn %x / ppn %x / attr %x / cycle %d\n",
    2020 __FUNCTION__, vpn, ppn, attr, end_cycle );
     2012if( vpn == 0x40b )
     2013printk("\n[%s] thread[%x,%x] handled local pgfault / ppn %x / attr %x / cycle %d\n",
     2014__FUNCTION__, this->process->pid, this->trdid, ppn, attr, end_cycle );
    20212015#endif
    20222016
     
    20332027        else                               
    20342028        {
     2029
     2030#if DEBUG_VMM_HANDLE_PAGE_FAULT
     2031if( vpn == 0x40b )
     2032printk("\n[%s] thread[%x,%x] access ref gpt : local_cxy %x / ref_cxy %x / type %s\n",
     2033__FUNCTION__, this->process->pid, this->trdid, local_cxy, ref_cxy, vseg_type_str(vseg->type) );
     2034#endif
    20352035            // build extended pointer on reference GPT
    20362036            ref_gpt_xp = XPTR( ref_cxy , &ref_ptr->vmm.gpt );
    20372037
    2038             // get current PPN and attributes from reference GPT
    2039             // without locking the PTE (in case of false page fault)
    2040             hal_gpt_get_pte( ref_gpt_xp,
    2041                              vpn,
    2042                              &ref_attr,
    2043                              &ref_ppn );
    2044 
    2045             if( ref_attr & GPT_MAPPED )        // false page fault => update local GPT
     2038            // lock PTE in reference GPT and get current PPN and attributes
     2039            error = hal_gpt_lock_pte( ref_gpt_xp,
     2040                                      vpn,
     2041                                      &ref_attr,
     2042                                      &ref_ppn );
     2043            if( error )
     2044            {
     2045                printk("\n[PANIC] in %s : cannot lock PTE in ref GPT / vpn %x / process %x\n",
     2046                __FUNCTION__ , vpn , process->pid );
     2047       
     2048                // unlock PTE in local GPT
     2049                hal_gpt_unlock_pte( local_gpt_xp , vpn );
     2050                   
     2051                return EXCP_KERNEL_PANIC;
     2052            }
     2053
     2054#if DEBUG_VMM_HANDLE_PAGE_FAULT
     2055if( vpn == 0x40b )
     2056printk("\n[%s] thread[%x,%x] get pte from ref gpt / attr %x / ppn %x\n",
     2057__FUNCTION__, this->process->pid, this->trdid, ref_attr, ref_ppn );
     2058#endif
     2059
     2060            if( ref_attr & GPT_MAPPED )        // false page fault
    20462061            {
    20472062                // update local GPT from reference GPT values
     2063                // this unlocks the PTE in local GPT
    20482064                hal_gpt_set_pte( local_gpt_xp,
    20492065                                 vpn,
     
    20512067                                 ref_ppn );
    20522068
     2069#if DEBUG_VMM_HANDLE_PAGE_FAULT
     2070if( vpn == 0x40b )
     2071printk("\n[%s] thread[%x,%x] updated local gpt for a false pgfault\n",
     2072__FUNCTION__, this->process->pid, this->trdid );
     2073#endif
     2074
     2075                // unlock the PTE in reference GPT
     2076                hal_gpt_unlock_pte( ref_gpt_xp, vpn );
     2077                             
     2078#if DEBUG_VMM_HANDLE_PAGE_FAULT
     2079if( vpn == 0x40b )
     2080printk("\n[%s] thread[%x,%x] unlock the ref gpt after a false pgfault\n",
     2081__FUNCTION__, this->process->pid, this->trdid );
     2082#endif
     2083
    20532084#if (CONFIG_INSTRUMENTATION_PGFAULTS || DEBUG_VMM_HANDLE_PAGE_FAULT)
    20542085uint32_t end_cycle = (uint32_t)hal_get_cycles();
     
    20562087
    20572088#if DEBUG_VMM_HANDLE_PAGE_FAULT
    2058 if( DEBUG_VMM_HANDLE_PAGE_FAULT < end_cycle )
    2059 printk("\n[%s] false page fault handled / vpn %x / ppn %x / attr %x / cycle %d\n",
    2060 __FUNCTION__, vpn, ref_ppn, ref_attr, end_cycle );
     2089if( vpn == 0x40b )
     2090printk("\n[%s] thread[%x,%x] handled false pgfault / ppn %x / attr %x / cycle %d\n",
     2091__FUNCTION__, this->process->pid, this->trdid, ref_ppn, ref_attr, end_cycle );
    20612092#endif
    20622093
     
    20672098                return EXCP_NON_FATAL;
    20682099            }
    2069             else                            // true page fault => update both GPTs
     2100            else                            // true page fault
    20702101            {
    20712102                // allocate and initialise a physical page depending on the vseg type
     
    20772108                    __FUNCTION__ , process->pid , vpn );
    20782109
    2079                     // unlock PTE in local GPT
     2110                    // unlock PTE in local GPT and in reference GPT
    20802111                    hal_gpt_unlock_pte( local_gpt_xp , vpn );
     2112                    hal_gpt_unlock_pte( ref_gpt_xp   , vpn );
    20812113                   
    20822114                    return EXCP_KERNEL_PANIC;
    20832115                }
    20842116
    2085                 // lock PTE in reference GPT
    2086                 error = hal_gpt_lock_pte( ref_gpt_xp,
    2087                                           vpn,
    2088                                           &ref_attr,
    2089                                           &ref_ppn );
    2090                 if( error )
    2091                 {
    2092                     printk("\n[PANIC] in %s : cannot lock PTE in ref GPT / vpn %x / process %x\n",
    2093                     __FUNCTION__ , vpn , process->pid );
    2094        
    2095                     // unlock PTE in local GPT
    2096                     hal_gpt_unlock_pte( local_gpt_xp , vpn );
    2097                    
    2098                     return EXCP_KERNEL_PANIC;
    2099                 }
    2100 
    21012117                // define attr from vseg flags
    2102                 attr = GPT_MAPPED | GPT_SMALL;
     2118                attr = GPT_MAPPED | GPT_SMALL | GPT_READABLE;
    21032119                if( vseg->flags & VSEG_USER  ) attr |= GPT_USER;
    21042120                if( vseg->flags & VSEG_WRITE ) attr |= GPT_WRITABLE;
     
    21062122                if( vseg->flags & VSEG_CACHE ) attr |= GPT_CACHABLE;
    21072123
     2124#if DEBUG_VMM_HANDLE_PAGE_FAULT
     2125if( vpn == 0x40b )
     2126printk("\n[%s] thread[%x,%x] build a new PTE for a true pgfault\n",
     2127__FUNCTION__, this->process->pid, this->trdid );
     2128#endif
    21082129                // set PTE in reference GPT
     2130                // this unlock the PTE
    21092131                hal_gpt_set_pte( ref_gpt_xp,
    21102132                                 vpn,
     
    21122134                                 ppn );
    21132135
     2136#if DEBUG_VMM_HANDLE_PAGE_FAULT
     2137if( vpn == 0x40b )
     2138printk("\n[%s] thread[%x,%x] set new PTE in ref gpt for a true page fault\n",
     2139__FUNCTION__, this->process->pid, this->trdid );
     2140#endif
     2141
    21142142                // set PTE in local GPT
     2143                // this unlock the PTE
    21152144                hal_gpt_set_pte( local_gpt_xp,
    21162145                                 vpn,
     
    21232152
    21242153#if DEBUG_VMM_HANDLE_PAGE_FAULT
    2125 if( DEBUG_VMM_HANDLE_PAGE_FAULT < end_cycle )
    2126 printk("\n[%s] global page fault handled / vpn %x / ppn %x / attr %x / cycle %d\n",
    2127 __FUNCTION__, vpn, ppn, attr, end_cycle );
     2154if( vpn == 0x40b )
     2155printk("\n[%s] thread[%x,%x] handled global pgfault / ppn %x / attr %x / cycle %d\n",
     2156__FUNCTION__, this->process->pid, this->trdid, ppn, attr, end_cycle );
    21282157#endif
    21292158
     
    21382167    else   // page has been locally mapped by another concurrent thread
    21392168    {
    2140         // unlock PTE in local GPT
     2169        // unlock the PTE in local GPT
    21412170        hal_gpt_unlock_pte( local_gpt_xp , vpn );
    21422171
     2172#if (CONFIG_INSTRUMENTATION_PGFAULTS || DEBUG_VMM_HANDLE_PAGE_FAULT)
     2173uint32_t end_cycle = (uint32_t)hal_get_cycles();
     2174#endif
     2175
     2176#if DEBUG_VMM_HANDLE_PAGE_FAULT
     2177if( vpn == 0x40b )
     2178printk("\n[%s] handled by another thread / vpn %x / ppn %x / attr %x / cycle %d\n",
     2179__FUNCTION__, vpn, ppn, attr, end_cycle );
     2180#endif
     2181
     2182#if CONFIG_INSTRUMENTATION_PGFAULTS
     2183this->info.false_pgfault_nr++;
     2184this->info.false_pgfault_cost += (end_cycle - start_cycle);
     2185#endif
    21432186        return EXCP_NON_FATAL;
    21442187    }
     
    22142257
    22152258    // lock target PTE in relevant GPT (local or reference)
     2259    // and get current PTE value
    22162260    error = hal_gpt_lock_pte( gpt_xp,
    22172261                              vpn,
Note: See TracChangeset for help on using the changeset viewer.