Changeset 683 for trunk/kernel/mm/vmm.c
- Timestamp:
- Jan 13, 2021, 12:36:17 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/mm/vmm.c
r672 r683 1 1 /* 2 * vmm.c - virtual memory manager related operations definition.2 * vmm.c - virtual memory manager related operations implementation. 3 3 * 4 4 * Authors Ghassan Almaless (2008,2009,2010,2011,2012) … … 89 89 90 90 // check ltid argument 91 assert( __FUNCTION__, (ltid <= ((CONFIG_VMM_VSPACE_SIZE - CONFIG_VMM_STACK_BASE) / CONFIG_VMM_STACK_SIZE)), 91 assert( __FUNCTION__, 92 (ltid <= ((CONFIG_VMM_VSPACE_SIZE - CONFIG_VMM_STACK_BASE) / CONFIG_VMM_STACK_SIZE)), 92 93 "slot index %d too large for an user stack vseg", ltid ); 93 94 … … 107 108 if( vseg == NULL ) 108 109 { 109 // release lock protecting free lists 110 111 #if DEBUG_VMM_ERROR 112 printk("\n[ERROR] %s cannot allocate memory for vseg in cluster %x\n", 113 __FUNCTION__ , local_cxy ); 114 #endif 110 115 busylock_release( &mgr->lock ); 111 112 printk("\n[ERROR] %s cannot allocate memory for vseg in cluster %x\n",113 __FUNCTION__ , local_cxy );114 115 116 return NULL; 116 117 } … … 346 347 if( current_vseg == NULL ) // return failure 347 348 { 348 // release lock protecting free lists 349 350 #if DEBUG_VMM_ERROR 351 printk("\n[ERROR] %s cannot allocate ) %d page(s) in cluster %x\n", 352 __FUNCTION__, npages , local_cxy ); 353 #endif 349 354 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 354 355 return NULL; 355 356 } … … 368 369 if( new_vseg == NULL ) 369 370 { 370 // release lock protecting free lists 371 372 #if DEBUG_VMM_ERROR 373 printk("\n[ERROR] %s cannot allocate memory for vseg in cluster %x\n", 374 __FUNCTION__ , local_cxy ); 375 #endif 371 376 busylock_release( &mgr->lock ); 372 373 printk("\n[ERROR] %s cannot allocate memory for vseg in cluster %x\n",374 __FUNCTION__ , local_cxy );375 376 377 return NULL; 377 378 } … … 517 518 XPTR( local_cxy , &vseg->xlist ) ); 518 519 519 } // end vmm_attach_vseg_ from_vsl()520 } // end vmm_attach_vseg_to_vsl() 520 521 521 522 //////////////////////////////////////////////////////////////////////////////////////////// … … 537 538 xlist_unlink( XPTR( local_cxy , &vseg->xlist ) ); 538 539 539 } // end vmm_detach_ from_vsl()540 } // end vmm_detach_vseg_from_vsl() 540 541 541 542 //////////////////////////////////////////// … … 1290 1291 if( child_vseg == NULL ) // release all allocated vsegs 1291 1292 { 1293 1294 #if DEBUG_VMM_ERROR 1295 printk("\n[ERROR] in %s : cannot create vseg for child in cluster %x\n", 1296 __FUNCTION__, local_cxy ); 1297 #endif 1292 1298 vmm_destroy( child_process ); 1293 printk("\n[ERROR] in %s : cannot create vseg for child\n", __FUNCTION__ );1294 1299 return -1; 1295 1300 } … … 1338 1343 if( error ) 1339 1344 { 1345 1346 #if DEBUG_VMM_ERROR 1347 printk("\n[ERROR] in %s : cannot copy GPT\n", 1348 __FUNCTION__ ); 1349 #endif 1340 1350 vmm_destroy( child_process ); 1341 printk("\n[ERROR] in %s : cannot copy GPT\n", __FUNCTION__ );1342 1351 return -1; 1343 1352 } … … 1357 1366 remote_queuelock_release( parent_lock_xp ); 1358 1367 1359 /* deprecated [AG] : this is already done by the vmm_user_init() funcfion1360 1361 // initialize the child VMM STACK allocator1362 vmm_stack_init( child_vmm );1363 1364 // initialize the child VMM MMAP allocator1365 vmm_mmap_init( child_vmm );1366 1367 // initialize instrumentation counters1368 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 */1375 1368 // copy base addresses from parent VMM to child VMM 1376 1369 child_vmm->args_vpn_base = (vpn_t)hal_remote_lpt(XPTR(parent_cxy, &parent_vmm->args_vpn_base)); … … 1564 1557 if( vseg == NULL ) 1565 1558 { 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 1561 printk("\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 1568 1564 return NULL; 1569 1565 } … … 1572 1568 vseg->type = type; 1573 1569 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); 1576 1572 vseg->cxy = cxy; 1577 1573 … … 1582 1578 { 1583 1579 // 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; 1586 1582 1587 1583 // compute offset in first page and number of pages … … 1594 1590 if( vseg == NULL ) 1595 1591 { 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 1594 printk("\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 1598 1597 return NULL; 1599 1598 } … … 1602 1601 vseg->type = type; 1603 1602 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; 1605 1604 vseg->max = vseg->min + size; 1606 1605 vseg->file_offset = file_offset; … … 1615 1614 { 1616 1615 // 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; 1618 1617 if( size & CONFIG_PPM_PAGE_MASK) npages++; 1619 1618 … … 1623 1622 if( vseg == NULL ) 1624 1623 { 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 1626 printk("\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 1627 1629 return NULL; 1628 1630 } … … 1631 1633 vseg->type = type; 1632 1634 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); 1635 1637 vseg->cxy = cxy; 1636 1638 … … 1640 1642 else // VSEG_TYPE_DATA, VSEG_TYPE_CODE or KERNEL vseg 1641 1643 { 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; 1644 1646 1645 1647 // allocate vseg descriptor … … 1648 1650 if( vseg == NULL ) 1649 1651 { 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 1654 printk("\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 1652 1657 return NULL; 1653 1658 } 1659 1654 1660 // initialize vseg 1655 1661 vseg->type = type; … … 1657 1663 vseg->min = base; 1658 1664 vseg->max = base + size; 1659 vseg->vpn_base = base >> CONFIG_PPM_PAGE_ SHIFT;1665 vseg->vpn_base = base >> CONFIG_PPM_PAGE_ORDER; 1660 1666 vseg->vpn_size = vpn_max - vpn_min + 1; 1661 1667 vseg->file_offset = file_offset; … … 1672 1678 if( existing_vseg != NULL ) 1673 1679 { 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 1682 printk("\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, 1685 vseg_type_str(existing_vseg->type), existing_vseg->vpn_base, existing_vseg->vpn_size ); 1686 #endif 1678 1687 vseg_free( vseg ); 1679 1688 return NULL; … … 1801 1810 if( do_kmem_release ) 1802 1811 { 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 ); 1808 1821 1809 1822 #if DEBUG_VMM_PPN_RELEASE … … 1855 1868 #endif 1856 1869 1857 // loop on PTEs in GPT to unmap all mapped PTE1858 1870 // the loop on PTEs in GPT to unmap all mapped PTEs 1871 for( vpn = vpn_min ; vpn < vpn_max ; vpn++ ) 1859 1872 { 1860 1873 // get ppn and attr … … 1942 1955 intptr_t min = new_base; 1943 1956 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; 1946 1959 1947 1960 // build extended pointer on GPT … … 2082 2095 if( ref_cxy == local_cxy ) // local is ref => return error 2083 2096 { 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 2099 printk("\n[ERROR] in %s : vaddr %x in process %x out of segment\n", 2100 __FUNCTION__, vaddr, process->pid ); 2101 #endif 2088 2102 remote_queuelock_release( loc_lock_xp ); 2089 2090 2103 return -1; 2091 2104 } … … 2103 2116 if( ref_vseg == NULL ) // vseg not found => return error 2104 2117 { 2105 // release both VSL locks 2118 2119 #if DEBUG_VMM_ERROR 2120 printk("\n[ERROR] in %s : vaddr %x in process %x out of segment\n", 2121 __FUNCTION__, vaddr, process->pid ); 2122 #endif 2106 2123 remote_queuelock_release( loc_lock_xp ); 2107 2124 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 2112 2125 return -1; 2113 2126 } … … 2119 2132 if( loc_vseg == NULL ) // no memory => return error 2120 2133 { 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 2136 printk("\n[ERROR] in %s : vaddr %x in process %x / no memory\n", 2137 __FUNCTION__, vaddr, process->pid ); 2138 #endif 2125 2139 remote_queuelock_release( ref_lock_xp ); 2126 2140 remote_queuelock_release( loc_lock_xp ); 2127 2128 2141 return -1; 2129 2142 } … … 2158 2171 ////////////////////////////////////////////////////////////////////////////////////// 2159 2172 // 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. 2162 2176 // The vseg cannot have the FILE type. 2163 2177 ////////////////////////////////////////////////////////////////////////////////////// 2164 2178 // @ vseg : local pointer on vseg. 2165 2179 // @ 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 2167 2181 ////////////////////////////////////////////////////////////////////////////////////// 2168 2182 static xptr_t vmm_page_allocate( vseg_t * vseg, … … 2207 2221 } 2208 2222 2209 // allocate one small physical page from target cluster2210 kmem_req_t req;2211 req.type = KMEM_PPM;2212 req.order = 0;2213 req.flags = AF_ZERO;2214 2215 2223 // 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 2230 printk("\n[ERROR] in %s : cannot allocate memory from cluster %x\n", 2231 __FUNCTION__, page_cxy ); 2232 #endif 2233 return XPTR_NULL; 2234 } 2218 2235 // get extended pointer on page descriptor 2219 2236 page_xp = ppm_base2page( XPTR( page_cxy , ptr ) ); … … 2291 2308 2292 2309 // 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; 2294 2311 2295 2312 // compute missing page offset in .elf file … … 2427 2444 // get local vseg (access to reference VSL can be required) 2428 2445 error = vmm_get_vseg( process, 2429 (intptr_t)vpn<<CONFIG_PPM_PAGE_ SHIFT,2446 (intptr_t)vpn<<CONFIG_PPM_PAGE_ORDER, 2430 2447 &vseg ); 2431 2448 if( error ) … … 2752 2769 // get local vseg 2753 2770 error = vmm_get_vseg( process, 2754 (intptr_t)vpn<<CONFIG_PPM_PAGE_ SHIFT,2771 (intptr_t)vpn<<CONFIG_PPM_PAGE_ORDER, 2755 2772 &vseg ); 2756 2773 if( error )
Note: See TracChangeset
for help on using the changeset viewer.