Changeset 656 for trunk/kernel/mm/vmm.c
- Timestamp:
- Dec 6, 2019, 12:07:51 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/mm/vmm.c
r651 r656 1745 1745 1746 1746 //////////////////////////////////////////////////////////////////////////////////////////// 1747 // This static function is called by the vmm_remove_vseg() and vmm_resize_vseg() functions. 1748 // Depending on the vseg <type>, it decrements the physical page refcount, and 1749 // conditionnally release to the relevant kmem the physical page identified by <ppn>. 1747 // This static function is called by the vmm_remove_vseg() and vmm_resize_vseg() functions 1748 // to update the physical page descriptor identified by the <ppn> argument. 1749 // It decrements the refcount, set the dirty bit when required, and releases the physical 1750 // page to kmem depending on the vseg type. 1751 // - KERNEL : refcount decremented / not released to kmem / dirty bit not set 1752 // - FILE : refcount decremented / not released to kmem / dirty bit set when required. 1753 // - CODE : refcount decremented / released to kmem / dirty bit not set. 1754 // - STAK : refcount decremented / released to kmem / dirty bit not set. 1755 // - DATA : refcount decremented / released to kmem if ref / dirty bit not set. 1756 // - MMAP : refcount decremented / released to kmem if ref / dirty bit not set. 1750 1757 //////////////////////////////////////////////////////////////////////////////////////////// 1751 1758 // @ process : local pointer on process. 1752 1759 // @ vseg : local pointer on vseg. 1753 1760 // @ ppn : released pysical page index. 1761 // @ dirty : set the dirty bit in page descriptor when non zero. 1754 1762 //////////////////////////////////////////////////////////////////////////////////////////// 1755 1763 static void vmm_ppn_release( process_t * process, 1756 1764 vseg_t * vseg, 1757 ppn_t ppn ) 1765 ppn_t ppn, 1766 uint32_t dirty ) 1758 1767 { 1759 bool_t do_ release;1768 bool_t do_kmem_release; 1760 1769 1761 1770 // get vseg type 1762 1771 vseg_type_t type = vseg->type; 1763 1772 1764 // compute is_ref 1773 // compute is_ref <=> this vseg is the reference vseg 1765 1774 bool_t is_ref = (GET_CXY( process->ref_xp ) == local_cxy); 1766 1775 … … 1774 1783 hal_remote_atomic_add( count_xp , -1 ); 1775 1784 1776 // compute the do_release condition depending on vseg type 1777 if( (type == VSEG_TYPE_FILE) || 1778 (type == VSEG_TYPE_KCODE) || 1785 // compute the do_kmem_release condition depending on vseg type 1786 if( (type == VSEG_TYPE_KCODE) || 1779 1787 (type == VSEG_TYPE_KDATA) || 1780 1788 (type == VSEG_TYPE_KDEV) ) 1781 1789 { 1782 // no physical page release for FILE and KERNEL 1783 do_release = false; 1784 } 1790 // no physical page release for KERNEL 1791 do_kmem_release = false; 1792 } 1793 else if( type == VSEG_TYPE_FILE ) 1794 { 1795 // no physical page release for KERNEL 1796 do_kmem_release = false; 1797 1798 // set dirty bit if required 1799 if( dirty ) ppm_page_do_dirty( page_xp ); 1800 } 1785 1801 else if( (type == VSEG_TYPE_CODE) || 1786 1802 (type == VSEG_TYPE_STACK) ) 1787 1803 { 1788 1804 // always release physical page for private vsegs 1789 do_ release = true;1805 do_kmem_release = true; 1790 1806 } 1791 1807 else if( (type == VSEG_TYPE_ANON) || … … 1793 1809 { 1794 1810 // release physical page if reference cluster 1795 do_ release = is_ref;1811 do_kmem_release = is_ref; 1796 1812 } 1797 1813 else if( is_ref ) // vseg_type == DATA in reference cluster … … 1814 1830 1815 1831 // release physical page if forks == 0 1816 do_ release = (forks == 0);1832 do_kmem_release = (forks == 0); 1817 1833 } 1818 1834 else // vseg_type == DATA not in reference cluster 1819 1835 { 1820 1836 // no physical page release if not in reference cluster 1821 do_ release = false;1837 do_kmem_release = false; 1822 1838 } 1823 1839 1824 1840 // release physical page to relevant kmem when required 1825 if( do_release ) 1826 { 1827 ppm_remote_free_pages( page_cxy , page_ptr ); 1841 if( do_kmem_release ) 1842 { 1843 kmem_req_t req; 1844 req.type = KMEM_PPM; 1845 req.ptr = GET_PTR( ppm_ppn2base( ppn ) ); 1846 1847 kmem_remote_free( page_cxy , &req ); 1828 1848 1829 1849 #if DEBUG_VMM_PPN_RELEASE … … 1892 1912 hal_gpt_reset_pte( gpt_xp , vpn ); 1893 1913 1894 // release physical page when required1895 vmm_ppn_release( process , vseg , ppn );1914 // release physical page depending on vseg type 1915 vmm_ppn_release( process , vseg , ppn , attr & GPT_DIRTY ); 1896 1916 } 1897 1917 } … … 1986 2006 1987 2007 // release physical page when required 1988 vmm_ppn_release( process , vseg , ppn );2008 vmm_ppn_release( process , vseg , ppn , attr & GPT_DIRTY ); 1989 2009 } 1990 2010 } … … 2008 2028 2009 2029 // release physical page when required 2010 vmm_ppn_release( process , vseg , ppn );2030 vmm_ppn_release( process , vseg , ppn , attr & GPT_DIRTY ); 2011 2031 } 2012 2032 } … … 2170 2190 // @ vseg : local pointer on vseg. 2171 2191 // @ vpn : unmapped vpn. 2172 // @ return an extended pointer on the allocated page 2192 // @ return an extended pointer on the allocated page descriptor. 2173 2193 ////////////////////////////////////////////////////////////////////////////////////// 2174 2194 static xptr_t vmm_page_allocate( vseg_t * vseg, … … 2186 2206 xptr_t page_xp; 2187 2207 cxy_t page_cxy; 2188 page_t * page_ptr;2189 2208 uint32_t index; 2190 2209 … … 2197 2216 assert( ( type != VSEG_TYPE_FILE ) , "illegal vseg type\n" ); 2198 2217 2218 // compute target cluster identifier 2199 2219 if( flags & VSEG_DISTRIB ) // distributed => cxy depends on vpn LSB 2200 2220 { … … 2214 2234 2215 2235 // allocate one small physical page from target cluster 2216 page_ptr = ppm_remote_alloc_pages( page_cxy , 0 ); 2217 2218 page_xp = XPTR( page_cxy , page_ptr ); 2236 kmem_req_t req; 2237 req.type = KMEM_PPM; 2238 req.order = 0; 2239 req.flags = AF_ZERO; 2240 2241 // get local pointer on page base 2242 void * ptr = kmem_remote_alloc( page_cxy , &req ); 2243 2244 // get extended pointer on page descriptor 2245 page_xp = ppm_base2page( XPTR( page_cxy , ptr ) ); 2219 2246 2220 2247 #if DEBUG_VMM_PAGE_ALLOCATE … … 2245 2272 uint32_t cycle = (uint32_t)hal_get_cycles(); 2246 2273 thread_t * this = CURRENT_THREAD; 2247 if( (DEBUG_VMM_GET_ONE_PPN < cycle) && (vpn == 0x40b))2248 printk("\n[%s] thread[%x,%x] enter for vpn %x / type%s / page_id %d / cycle %d\n",2274 if( DEBUG_VMM_GET_ONE_PPN < cycle ) 2275 printk("\n[%s] thread[%x,%x] enter for vpn %x / vseg %s / page_id %d / cycle %d\n", 2249 2276 __FUNCTION__, this->process->pid, this->trdid, vpn, vseg_type_str(type), page_id, cycle ); 2277 #endif 2278 2279 #if (DEBUG_VMM_GET_ONE_PPN & 2) 2280 if( DEBUG_VMM_GET_ONE_PPN < cycle ) 2281 hal_vmm_display( XPTR( local_cxy , this->process ) , true ); 2250 2282 #endif 2251 2283 … … 2291 2323 2292 2324 #if (DEBUG_VMM_GET_ONE_PPN & 0x1) 2293 if( (DEBUG_VMM_GET_ONE_PPN < cycle) && (vpn == 0x40b))2325 if( DEBUG_VMM_GET_ONE_PPN < cycle ) 2294 2326 printk("\n[%s] thread[%x,%x] for vpn = %x / elf_offset = %x\n", 2295 2327 __FUNCTION__, this->process->pid, this->trdid, vpn, elf_offset ); … … 2305 2337 2306 2338 #if (DEBUG_VMM_GET_ONE_PPN & 0x1) 2307 if( (DEBUG_VMM_GET_ONE_PPN < cycle) && (vpn == 0x40b))2339 if( DEBUG_VMM_GET_ONE_PPN < cycle ) 2308 2340 printk("\n[%s] thread[%x,%x] for vpn %x / fully in BSS\n", 2309 2341 __FUNCTION__, this->process->pid, this->trdid, vpn ); … … 2322 2354 2323 2355 #if (DEBUG_VMM_GET_ONE_PPN & 0x1) 2324 if( (DEBUG_VMM_GET_ONE_PPN < cycle) && (vpn == 0x40b))2356 if( DEBUG_VMM_GET_ONE_PPN < cycle ) 2325 2357 printk("\n[%s] thread[%x,%x] for vpn %x / fully in mapper\n", 2326 2358 __FUNCTION__, this->process->pid, this->trdid, vpn ); … … 2339 2371 2340 2372 #if (DEBUG_VMM_GET_ONE_PPN & 0x1) 2341 if( (DEBUG_VMM_GET_ONE_PPN < cycle) && (vpn == 0x40b))2373 if( DEBUG_VMM_GET_ONE_PPN < cycle ) 2342 2374 printk("\n[%s] thread[%x,%x] for vpn %x / both mapper & BSS\n" 2343 2375 " %d bytes from mapper / %d bytes from BSS\n", … … 2365 2397 } 2366 2398 } 2367 } // end initialisation for CODE or DATA types 2399 2400 } // end if CODE or DATA types 2368 2401 } 2369 2402 … … 2372 2405 2373 2406 #if DEBUG_VMM_GET_ONE_PPN 2374 cycle = (uint32_t)hal_get_cycles(); 2375 if( (DEBUG_VMM_GET_ONE_PPN < cycle) && (vpn == 0x40b) ) 2407 if( DEBUG_VMM_GET_ONE_PPN < cycle ) 2376 2408 printk("\n[%s] thread[%x,%x] exit for vpn %x / ppn %x / cycle %d\n", 2377 2409 __FUNCTION__ , this->process->pid, this->trdid , vpn , *ppn, cycle ); 2410 #endif 2411 2412 #if (DEBUG_VMM_GET_ONE_PPN & 2) 2413 if( DEBUG_VMM_GET_ONE_PPN < cycle ) 2414 hal_vmm_display( XPTR( local_cxy , this->process ) , true ); 2378 2415 #endif 2379 2416 … … 2404 2441 2405 2442 #if DEBUG_VMM_HANDLE_PAGE_FAULT 2406 if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) & &(vpn > 0) )2443 if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) & (vpn > 0) ) 2407 2444 printk("\n[%s] thread[%x,%x] enter for vpn %x / cycle %d\n", 2408 2445 __FUNCTION__, this->process->pid, this->trdid, vpn, start_cycle ); 2409 2446 #endif 2410 2447 2411 #if (DEBUG_VMM_HANDLE_PAGE_FAULT & 1)2448 #if (DEBUG_VMM_HANDLE_PAGE_FAULT & 2) 2412 2449 if( (start_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) ) 2413 hal_vmm_display( this->process, true );2450 hal_vmm_display( XPTR( local_cxy , this->process ) , true ); 2414 2451 #endif 2415 2452 … … 2504 2541 #if (CONFIG_INSTRUMENTATION_PGFAULTS || DEBUG_VMM_HANDLE_PAGE_FAULT) 2505 2542 uint32_t end_cycle = (uint32_t)hal_get_cycles(); 2506 uint32_t cost = end_cycle - start_cycle;2507 2543 #endif 2508 2544 … … 2513 2549 #endif 2514 2550 2551 #if (DEBUG_VMM_HANDLE_PAGE_FAULT & 2) 2552 if( (end_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) ) 2553 hal_vmm_display( XPTR( local_cxy , this->process ) , true ); 2554 #endif 2555 2515 2556 #if CONFIG_INSTRUMENTATION_PGFAULTS 2557 uint32_t cost = end_cycle - start_cycle; 2516 2558 this->info.local_pgfault_nr++; 2517 2559 this->info.local_pgfault_cost += cost; … … 2584 2626 #if (CONFIG_INSTRUMENTATION_PGFAULTS || DEBUG_VMM_HANDLE_PAGE_FAULT) 2585 2627 uint32_t end_cycle = (uint32_t)hal_get_cycles(); 2586 uint32_t cost = end_cycle - start_cycle;2587 2628 #endif 2588 2629 … … 2593 2634 #endif 2594 2635 2636 #if (DEBUG_VMM_HANDLE_PAGE_FAULT & 2) 2637 if( (end_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) ) 2638 hal_vmm_display( XPTR( local_cxy , this->process ) , true ); 2639 #endif 2640 2595 2641 #if CONFIG_INSTRUMENTATION_PGFAULTS 2642 uint32_t cost = end_cycle - start_cycle; 2596 2643 this->info.false_pgfault_nr++; 2597 2644 this->info.false_pgfault_cost += cost; … … 2651 2698 #if (CONFIG_INSTRUMENTATION_PGFAULTS || DEBUG_VMM_HANDLE_PAGE_FAULT) 2652 2699 uint32_t end_cycle = (uint32_t)hal_get_cycles(); 2653 uint32_t cost = end_cycle - start_cycle;2654 2700 #endif 2655 2701 … … 2660 2706 #endif 2661 2707 2708 #if (DEBUG_VMM_HANDLE_PAGE_FAULT & 2) 2709 if( (end_cycle > DEBUG_VMM_HANDLE_PAGE_FAULT) && (vpn > 0) ) 2710 hal_vmm_display( XPTR( local_cxy , this->process ) , true ); 2711 #endif 2712 2662 2713 #if CONFIG_INSTRUMENTATION_PGFAULTS 2714 uint32_t cost = end_cycle - start_cycle; 2663 2715 this->info.global_pgfault_nr++; 2664 2716 this->info.global_pgfault_cost += cost; … … 2676 2728 #if (CONFIG_INSTRUMENTATION_PGFAULTS || DEBUG_VMM_HANDLE_PAGE_FAULT) 2677 2729 uint32_t end_cycle = (uint32_t)hal_get_cycles(); 2678 uint32_t cost = end_cycle - start_cycle;2679 2730 #endif 2680 2731 … … 2686 2737 2687 2738 #if CONFIG_INSTRUMENTATION_PGFAULTS 2739 uint32_t cost = end_cycle - start_cycle; 2688 2740 this->info.false_pgfault_nr++; 2689 2741 this->info.false_pgfault_cost += cost; … … 2720 2772 #endif 2721 2773 2722 #if ( (DEBUG_VMM_HANDLE_COW & 3) == 3)2774 #if (DEBUG_VMM_HANDLE_COW & 2) 2723 2775 hal_vmm_display( XPTR( local_cxy , process ) , true ); 2724 2776 #endif … … 2902 2954 #endif 2903 2955 2904 #if ( (DEBUG_VMM_HANDLE_COW & 3) == 3)2956 #if (DEBUG_VMM_HANDLE_COW & 2) 2905 2957 hal_vmm_display( XPTR( local_cxy , process ) , true ); 2906 2958 #endif
Note: See TracChangeset
for help on using the changeset viewer.