Changeset 619 for trunk/kernel/mm
- Timestamp:
- Feb 12, 2019, 1:15:47 PM (6 years ago)
- Location:
- trunk/kernel/mm
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/mm/kcm.c
r567 r619 3 3 * 4 4 * Author Ghassan Almaless (2008,2009,2010,2011,2012) 5 * Alain Greiner (2016,2017,2018 )5 * Alain Greiner (2016,2017,2018,2019) 6 6 * 7 7 * Copyright (c) UPMC Sorbonne Universites … … 51 51 52 52 #if DEBUG_KCM 53 thread_t * this = CURRENT_THREAD; 53 54 uint32_t cycle = (uint32_t)hal_get_cycles(); 54 55 if( DEBUG_KCM < cycle ) 55 printk("\n[ DBG] %s : thread %xenters for %s / page %x / count %d / active %d\n",56 __FUNCTION__ , CURRENT_THREAD , kmem_type_str( kcm->type ),56 printk("\n[%s] thread[%x,%x] enters for %s / page %x / count %d / active %d\n", 57 __FUNCTION__, this->process->pid, this->trdid, kmem_type_str(kcm->type), 57 58 (intptr_t)kcm_page , kcm_page->count , kcm_page->active ); 58 59 #endif 59 60 60 61 assert( kcm_page->active , "kcm_page should be active" ); 61 62 62 63 // get first block available 63 64 int32_t index = bitmap_ffs( kcm_page->bitmap , kcm->blocks_nr ); 64 65 65 66 assert( (index != -1) , "kcm_page should not be full" ); 66 67 67 68 // allocate block … … 90 91 cycle = (uint32_t)hal_get_cycles(); 91 92 if( DEBUG_KCM < cycle ) 92 printk("\n[ DBG] %s : thread %x exit / type%s / ptr %x / page %x / count %d\n",93 __FUNCTION__ , CURRENT_THREAD , kmem_type_str( kcm->type ) , (intptr_t)ptr,94 (intptr_t) kcm_page, kcm_page->count );93 printk("\n[%s] thread[%x,%x] exit for %s / ptr %x / page %x / count %d\n", 94 __FUNCTION__, this->process->pid, this->trdid, kmem_type_str(kcm->type), 95 (intptr_t)ptr, (intptr_t)kcm_page, kcm_page->count ); 95 96 #endif 96 97 … … 115 116 index = ((uint8_t *)ptr - (uint8_t *)kcm_page - CONFIG_KCM_SLOT_SIZE) / kcm->block_size; 116 117 117 assert( !bitmap_state( kcm_page->bitmap , index ) , "page already freed" ); 118 assert( (kcm_page->count > 0) , "count already zero" ); 118 assert( !bitmap_state( kcm_page->bitmap , index ) , "page already freed" ); 119 120 assert( (kcm_page->count > 0) , "count already zero" ); 119 121 120 122 bitmap_set( kcm_page->bitmap , index ); … … 163 165 if( page == NULL ) 164 166 { 165 printk("\n[ERROR] in %s : failed to allocate page in cluster % d\n",166 167 printk("\n[ERROR] in %s : failed to allocate page in cluster %x\n", 168 __FUNCTION__ , local_cxy ); 167 169 return ENOMEM; 168 170 } … … 216 218 uint32_t type ) 217 219 { 218 // the kcm_page descriptor mut fit in the KCM slot 219 assert( (sizeof(kcm_page_t) <= CONFIG_KCM_SLOT_SIZE) , 220 "KCM slot too small\n" ); 220 221 // the kcm_page descriptor must fit in the KCM slot 222 assert( (sizeof(kcm_page_t) <= CONFIG_KCM_SLOT_SIZE) , "KCM slot too small\n" ); 223 224 // the allocated object must fit in one single page 225 assert( (kmem_type_size(type) <= (CONFIG_PPM_PAGE_SIZE - CONFIG_KCM_SLOT_SIZE)), 226 "allocated object requires more than one single page\n" ); 221 227 222 228 // initialize lock … … 241 247 uint32_t blocks_nr = (CONFIG_PPM_PAGE_SIZE - CONFIG_KCM_SLOT_SIZE) / block_size; 242 248 kcm->blocks_nr = blocks_nr; 249 250 #if DEBUG_KCM 251 thread_t * this = CURRENT_THREAD; 252 uint32_t cycle = (uint32_t)hal_get_cycles(); 253 if( DEBUG_KCM < cycle ) 254 printk("\n[%s] thread[%x,%x] initialised KCM %s : block_size %d / blocks_nr %d\n", 255 __FUNCTION__, this->process->pid, this->trdid, 256 kmem_type_str( kcm->type ), block_size, blocks_nr ); 257 #endif 258 243 259 } 244 260 … … 331 347 kcm_t * kcm; 332 348 333 assert( (ptr != NULL) , "pointer cannot be NULL" ); 349 // check argument 350 assert( (ptr != NULL) , "pointer cannot be NULL" ); 334 351 335 352 kcm_page = (kcm_page_t *)((intptr_t)ptr & ~CONFIG_PPM_PAGE_MASK); -
trunk/kernel/mm/kcm.h
r567 r619 37 37 * for fixed size objects. It exists a specific KCM allocator for each object type. 38 38 * The actual allocated block size is the smallest multiple of the KCM slot, that 39 * contain one single object. The KCM slot is typically 64 bytes, as it must be large40 * enoughto store the kcm_page descriptor, defined below.39 * contain one single object. The KCM slot is 64 bytes, as it must be large enough 40 * to store the kcm_page descriptor, defined below. 41 41 * The various KCM allocators themselves are not statically allocated in the cluster 42 42 * manager, but are dynamically allocated when required, using the embedded KCM -
trunk/kernel/mm/khm.h
r567 r619 3 3 * 4 4 * Authors Ghassan Almaless (2008,2009,2010,2011,2012) 5 * Alain Greiner (2016,2017,2018 )5 * Alain Greiner (2016,2017,2018,2019) 6 6 * 7 7 * Copyright (c) UPMC Sorbonne Universites … … 32 32 /******************************************************************************************* 33 33 * This structure defines a Kernel Heap Manager (KHM) in a given cluster. 34 * It is used to allocate memory objects, that are not enough replicated to justify35 * a dedicated KCM allocator.34 * It is used to allocate memory objects, that too large, or not enough replicated 35 * to use a dedicated KCM allocator. 36 36 ******************************************************************************************/ 37 37 -
trunk/kernel/mm/kmem.c
r612 r619 90 90 else if( type == KMEM_CPU_CTX ) return CONFIG_CPU_CTX_SIZE; 91 91 else if( type == KMEM_FPU_CTX ) return CONFIG_FPU_CTX_SIZE; 92 else if( type == KMEM_BARRIER ) return sizeof( remote_barrier_t ); 93 92 else if( type == KMEM_GEN_BARRIER ) return sizeof( generic_barrier_t ); 93 94 else if( type == KMEM_SMP_BARRIER ) return sizeof( simple_barrier_t ); 94 95 else if( type == KMEM_DEVFS_CTX ) return sizeof( fatfs_ctx_t ); 95 96 else if( type == KMEM_FATFS_CTX ) return sizeof( fatfs_ctx_t ); … … 101 102 else if( type == KMEM_CONDVAR ) return sizeof( remote_condvar_t ); 102 103 else if( type == KMEM_MUTEX ) return sizeof( remote_mutex_t ); 104 103 105 else if( type == KMEM_DIR ) return sizeof( user_dir_t ); 104 105 106 else if( type == KMEM_512_BYTES ) return 512; 106 107 … … 120 121 else if( type == KMEM_CPU_CTX ) return "KMEM_CPU_CTX"; 121 122 else if( type == KMEM_FPU_CTX ) return "KMEM_FPU_CTX"; 122 else if( type == KMEM_BARRIER ) return "KMEM_BARRIER"; 123 123 else if( type == KMEM_GEN_BARRIER ) return "KMEM_GEN_BARRIER"; 124 125 else if( type == KMEM_SMP_BARRIER ) return "KMEM_SMP_BARRIER"; 124 126 else if( type == KMEM_DEVFS_CTX ) return "KMEM_DEVFS_CTX"; 125 127 else if( type == KMEM_FATFS_CTX ) return "KMEM_FATFS_CTX"; … … 131 133 else if( type == KMEM_CONDVAR ) return "KMEM_CONDVAR"; 132 134 else if( type == KMEM_MUTEX ) return "KMEM_MUTEX"; 135 133 136 else if( type == KMEM_DIR ) return "KMEM_DIR"; 134 135 137 else if( type == KMEM_512_BYTES ) return "KMEM_512_BYTES"; 136 138 -
trunk/kernel/mm/kmem.h
r611 r619 45 45 KMEM_CPU_CTX = 7, /*! hal_cpu_context_t */ 46 46 KMEM_FPU_CTX = 8, /*! hal_fpu_context_t */ 47 KMEM_ BARRIER = 9, /*! remote_barrier_t*/47 KMEM_GEN_BARRIER = 9, /*! generi_cbarrier_t */ 48 48 49 KMEM_ DEVFS_CTX = 10, /*! fatfs_inode_t*/50 KMEM_ FATFS_CTX = 11, /*! fatfs_ctx_t*/51 KMEM_ VFS_CTX = 12, /*! vfs_context_t*/52 KMEM_VFS_ INODE = 13, /*! vfs_inode_t*/53 KMEM_VFS_ DENTRY = 14, /*! vfs_dentry_t*/54 KMEM_VFS_ FILE = 15, /*! vfs_file_t*/55 KMEM_ SEM = 16, /*! remote_sem_t*/56 KMEM_ CONDVAR = 17, /*! remote_condvar_t*/57 KMEM_ MUTEX = 18, /*! remote_mutex_t*/58 KMEM_ DIR = 19, /*! remote_dir_t*/49 KMEM_SMP_BARRIER = 10, /*! simple_barrier_t */ 50 KMEM_DEVFS_CTX = 11, /*! fatfs_inode_t */ 51 KMEM_FATFS_CTX = 12, /*! fatfs_ctx_t */ 52 KMEM_VFS_CTX = 13, /*! vfs_context_t */ 53 KMEM_VFS_INODE = 14, /*! vfs_inode_t */ 54 KMEM_VFS_DENTRY = 15, /*! vfs_dentry_t */ 55 KMEM_VFS_FILE = 16, /*! vfs_file_t */ 56 KMEM_SEM = 17, /*! remote_sem_t */ 57 KMEM_CONDVAR = 18, /*! remote_condvar_t */ 58 KMEM_MUTEX = 19, /*! remote_mutex_t */ 59 59 60 KMEM_512_BYTES = 20, /*! 512 bytes aligned */ 60 KMEM_DIR = 20, /*! remote_dir_t */ 61 KMEM_512_BYTES = 21, /*! 512 bytes aligned */ 61 62 62 KMEM_TYPES_NR = 2 1,63 KMEM_TYPES_NR = 22, 63 64 }; 64 65 … … 97 98 ************************************************************************************* 98 99 * @ req : local pointer to allocation request. 99 * @ return a local pointer on page descriptor if PPM (i.e. type KMEM_PAGE).100 * @ return a local pointer on page descriptor if KMEM_PAGE. 100 101 * return a local pointer to allocated buffer if KCM or KHM. 101 102 * return NULL if no physical memory available. -
trunk/kernel/mm/vmm.c
r617 r619 800 800 // scan the VSL to delete all registered vsegs 801 801 // (don't use a FOREACH for item deletion in xlist) 802 while( !xlist_is_empty( root_xp ) ) 802 803 uint32_t count = 0; 804 805 while( !xlist_is_empty( root_xp ) && (count < 10 ) ) 803 806 { 804 807 // get pointer on first vseg in VSL … … 814 817 __FUNCTION__ , vseg_type_str( vseg->type ), vseg->vpn_base, vseg->vpn_size ); 815 818 #endif 819 820 count++; 816 821 817 822 } … … 1463 1468 1464 1469 #if DEBUG_VMM_ALLOCATE_PAGE 1465 uint32_t cycle = (uint32_t)hal_get_cycles(); 1466 thread_t * this = CURRENT_THREAD; 1470 uint32_t cycle = (uint32_t)hal_get_cycles(); 1471 thread_t * this = CURRENT_THREAD; 1472 xptr_t this_xp = XPTR( local_cxy , this ); 1467 1473 if( DEBUG_VMM_ALLOCATE_PAGE < (uint32_t)hal_get_cycles() ) 1468 1474 printk("\n[%s] thread[%x,%x] enter for vpn %x / cycle %d\n", … … 1950 1956 1951 1957 #if DEBUG_VMM_HANDLE_COW 1952 uint32_t cycle = (uint32_t)hal_get_cycles(); 1953 thread_t * this = CURRENT_THREAD; 1958 uint32_t cycle = (uint32_t)hal_get_cycles(); 1959 thread_t * this = CURRENT_THREAD; 1960 xptr_t this_xp = XPTR( local_cxy , this ); 1954 1961 if( DEBUG_VMM_HANDLE_COW < cycle ) 1955 1962 printk("\n[%s] thread[%x,%x] enter for vpn %x / core[%x,%d] / cycle %d\n", 1956 __FUNCTION__, process->pid, this->trdid, vpn, local_cxy, this->core->lid, cycle );1963 __FUNCTION__, this->process->pid, this->trdid, vpn, local_cxy, this->core->lid, cycle ); 1957 1964 #endif 1958 1965 … … 1974 1981 } 1975 1982 1983 #if( DEBUG_VMM_HANDLE_COW & 1) 1984 if( DEBUG_VMM_HANDLE_COW < cycle ) 1985 printk("\n[%s] thread[%x,%x] get vseg for vpn %x\n", 1986 __FUNCTION__, this->process->pid, this->trdid, vpn ); 1987 #endif 1988 1976 1989 // get reference GPT cluster and local pointer 1977 1990 ref_cxy = GET_CXY( process->ref_xp ); … … 2001 2014 &old_ppn ); 2002 2015 2016 #if( DEBUG_VMM_HANDLE_COW & 1) 2017 if( DEBUG_VMM_HANDLE_COW < cycle ) 2018 printk("\n[%s] thread[%x,%x] get pte for vpn %x : ppn %x / attr %x\n", 2019 __FUNCTION__, this->process->pid, this->trdid, vpn, old_ppn, old_attr ); 2020 #endif 2021 2003 2022 // the PTE must be mapped for a COW 2004 2023 if( (old_attr & GPT_MAPPED) == 0 ) … … 2008 2027 2009 2028 // release GPT lock in write mode 2010 remote_rwlock_wr_ acquire( gpt_lock_xp );2029 remote_rwlock_wr_release( gpt_lock_xp ); 2011 2030 2012 2031 return EXCP_KERNEL_PANIC; 2013 2032 } 2014 2033 2015 // get extended pointer, cluster and local pointeron physical page descriptor2034 // get pointers on physical page descriptor 2016 2035 xptr_t page_xp = ppm_ppn2page( old_ppn ); 2017 2036 cxy_t page_cxy = GET_CXY( page_xp ); … … 2028 2047 uint32_t forks = hal_remote_l32( forks_xp ); 2029 2048 2049 #if( DEBUG_VMM_HANDLE_COW & 1) 2050 if( DEBUG_VMM_HANDLE_COW < cycle ) 2051 printk("\n[%s] thread[%x,%x] get forks = %d for vpn %x\n", 2052 __FUNCTION__, this->process->pid, this->trdid, forks, vpn ); 2053 #endif 2054 2030 2055 if( forks ) // pending fork => allocate a new page, and copy old to new 2031 2056 { 2032 // allocate a new physical page 2057 // decrement pending forks counter in page descriptor 2058 hal_remote_atomic_add( forks_xp , -1 ); 2059 2060 // release lock protecting "forks" counter 2061 remote_busylock_release( forks_lock_xp ); 2062 2063 // allocate a new page 2033 2064 page_xp = vmm_page_allocate( vseg , vpn ); 2065 2034 2066 if( page_xp == XPTR_NULL ) 2035 2067 { … … 2040 2072 remote_rwlock_wr_acquire( gpt_lock_xp ); 2041 2073 2042 // release lock protecting "forks" counter2043 remote_busylock_release( forks_lock_xp );2044 2045 2074 return EXCP_KERNEL_PANIC; 2046 2075 } … … 2049 2078 new_ppn = ppm_page2ppn( page_xp ); 2050 2079 2080 #if( DEBUG_VMM_HANDLE_COW & 1) 2081 if( DEBUG_VMM_HANDLE_COW < cycle ) 2082 printk("\n[%s] thread[%x,%x] get new ppn %x for vpn %x\n", 2083 __FUNCTION__, this->process->pid, this->trdid, new_ppn, vpn ); 2084 #endif 2085 2051 2086 // copy old page content to new page 2052 xptr_t old_base_xp = ppm_ppn2base( old_ppn ); 2053 xptr_t new_base_xp = ppm_ppn2base( new_ppn ); 2054 memcpy( GET_PTR( new_base_xp ), 2055 GET_PTR( old_base_xp ), 2056 CONFIG_PPM_PAGE_SIZE ); 2057 2058 // decrement pending forks counter in page descriptor 2059 hal_remote_atomic_add( forks_xp , -1 ); 2087 hal_remote_memcpy( ppm_ppn2base( new_ppn ), 2088 ppm_ppn2base( old_ppn ), 2089 CONFIG_PPM_PAGE_SIZE ); 2060 2090 2061 2091 #if(DEBUG_VMM_HANDLE_COW & 1) 2062 2092 if( DEBUG_VMM_HANDLE_COW < cycle ) 2063 printk("\n[%s] thread[%x,%x] : pending forks => allocate a new PPN %x\n",2064 __FUNCTION__, process->pid, this->trdid, new_ppn);2093 printk("\n[%s] thread[%x,%x] copied old page to new page\n", 2094 __FUNCTION__, this->process->pid, this->trdid ); 2065 2095 #endif 2066 2096 … … 2068 2098 else // no pending fork => keep the existing page 2069 2099 { 2100 // release lock protecting "forks" counter 2101 remote_busylock_release( forks_lock_xp ); 2070 2102 2071 2103 #if(DEBUG_VMM_HANDLE_COW & 1) 2072 2104 if( DEBUG_VMM_HANDLE_COW < cycle ) 2073 printk("\n[%s] thread[%x,%x] no pending forks =>keep existing PPN %x\n",2074 __FUNCTION__, process->pid, this->trdid, new_ppn );2105 printk("\n[%s] thread[%x,%x] no pending forks / keep existing PPN %x\n", 2106 __FUNCTION__, this->process->pid, this->trdid, old_ppn ); 2075 2107 #endif 2076 2108 new_ppn = old_ppn; 2077 2109 } 2078 2079 // release lock protecting "forks" counter2080 remote_busylock_release( forks_lock_xp );2081 2110 2082 2111 // build new_attr : reset COW and set WRITABLE, 2083 2112 new_attr = (old_attr | GPT_WRITABLE) & (~GPT_COW); 2084 2113 2085 // update the relevan GPT2114 // update the relevant GPT 2086 2115 // - private vseg => update local GPT 2087 2116 // - public vseg => update all GPT copies … … 2119 2148 if( DEBUG_VMM_HANDLE_COW < cycle ) 2120 2149 printk("\n[%s] thread[%x,%x] exit for vpn %x / core[%x,%d] / cycle %d\n", 2121 __FUNCTION__, process->pid, this->trdid, vpn, local_cxy, this->core->lid, cycle );2150 __FUNCTION__, this->process->pid, this->trdid, vpn, local_cxy, this->core->lid, cycle ); 2122 2151 #endif 2123 2152
Note: See TracChangeset
for help on using the changeset viewer.