Changeset 611 for trunk/kernel/mm/vmm.c
- Timestamp:
- Jan 9, 2019, 3:02:51 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/mm/vmm.c
r610 r611 1 1 /* 2 * vmm.c - virtual memory manager related operations interface.2 * vmm.c - virtual memory manager related operations definition. 3 3 * 4 4 * Authors Ghassan Almaless (2008,2009,2010,2011, 2012) … … 254 254 } // vmm_display() 255 255 256 /////////////////////////////////// 257 void vmm_ vseg_attach( vmm_t * vmm,258 vseg_t * vseg )256 ////////////////////////////////////////// 257 void vmm_attach_vseg_to_vsl( vmm_t * vmm, 258 vseg_t * vseg ) 259 259 { 260 260 // build extended pointer on rwlock protecting VSL … … 275 275 } 276 276 277 /////////////////////////////////// 278 void vmm_ vseg_detach( vmm_t * vmm,279 vseg_t * vseg )277 //////////////////////////////////////////// 278 void vmm_detach_vseg_from_vsl( vmm_t * vmm, 279 vseg_t * vseg ) 280 280 { 281 // get vseg type 282 uint32_t type = vseg->type; 283 281 284 // build extended pointer on rwlock protecting VSL 282 285 xptr_t lock_xp = XPTR( local_cxy , &vmm->vsegs_lock ); … … 288 291 vseg->vmm = NULL; 289 292 290 // remove vseg from vmm list293 // remove vseg from VSL 291 294 xlist_unlink( XPTR( local_cxy , &vseg->xlist ) ); 292 295 293 296 // release rwlock in write mode 294 297 remote_rwlock_wr_release( lock_xp ); 295 } 298 299 // release the stack slot to VMM stack allocator if STACK type 300 if( type == VSEG_TYPE_STACK ) 301 { 302 // get pointer on stack allocator 303 stack_mgr_t * mgr = &vmm->stack_mgr; 304 305 // compute slot index 306 uint32_t index = ((vseg->vpn_base - mgr->vpn_base - 1) / CONFIG_VMM_STACK_SIZE); 307 308 // update stacks_bitmap 309 busylock_acquire( &mgr->lock ); 310 bitmap_clear( &mgr->bitmap , index ); 311 busylock_release( &mgr->lock ); 312 } 313 314 // release the vseg to VMM mmap allocator if MMAP type 315 if( (type == VSEG_TYPE_ANON) || (type == VSEG_TYPE_FILE) || (type == VSEG_TYPE_REMOTE) ) 316 { 317 // get pointer on mmap allocator 318 mmap_mgr_t * mgr = &vmm->mmap_mgr; 319 320 // compute zombi_list index 321 uint32_t index = bits_log2( vseg->vpn_size ); 322 323 // update zombi_list 324 busylock_acquire( &mgr->lock ); 325 list_add_first( &mgr->zombi_list[index] , &vseg->zlist ); 326 busylock_release( &mgr->lock ); 327 } 328 329 // release physical memory allocated for vseg descriptor if no MMAP type 330 if( (type != VSEG_TYPE_ANON) && (type != VSEG_TYPE_FILE) && (type != VSEG_TYPE_REMOTE) ) 331 { 332 vseg_free( vseg ); 333 } 334 335 } // end vmm_remove_vseg_from_vsl() 296 336 297 337 //////////////////////////////////////////////// … … 616 656 617 657 // register child vseg in child VSL 618 vmm_ vseg_attach( child_vmm , child_vseg );658 vmm_attach_vseg_to_vsl( child_vmm , child_vseg ); 619 659 620 660 #if DEBUG_VMM_FORK_COPY … … 759 799 xptr_t root_xp = XPTR( local_cxy , &vmm->vsegs_root ); 760 800 761 // remove all user vsegs registered in VSL 801 // scan the VSL to delete all registered vsegs 802 // (don't use a FOREACH for item deletion in xlist) 762 803 while( !xlist_is_empty( root_xp ) ) 763 804 { … … 766 807 vseg = GET_PTR( vseg_xp ); 767 808 768 // unmap and release physical pages 769 vmm_unmap_vseg( process , vseg ); 770 771 // remove vseg from VSL 772 vmm_vseg_detach( vmm , vseg ); 773 774 // release memory allocated to vseg descriptor 775 vseg_free( vseg ); 809 // delete vseg and release physical pages 810 vmm_delete_vseg( process->pid , vseg->min ); 776 811 777 812 #if( DEBUG_VMM_DESTROY & 1 ) 778 813 if( DEBUG_VMM_DESTROY < cycle ) 779 printk("\n[%s] %s vseg released / vpn_base %x / vpn_size %d\n",814 printk("\n[%s] %s vseg deleted / vpn_base %x / vpn_size %d\n", 780 815 __FUNCTION__ , vseg_type_str( vseg->type ), vseg->vpn_base, vseg->vpn_size ); 781 816 #endif … … 796 831 __FUNCTION__ , vseg_type_str( vseg->type ), vseg->vpn_base, vseg->vpn_size ); 797 832 #endif 798 vmm_vseg_detach( vmm , vseg ); 833 // clean vseg descriptor 834 vseg->vmm = NULL; 835 836 // remove vseg from xlist 837 xlist_unlink( XPTR( local_cxy , &vseg->xlist ) ); 838 839 // release vseg descriptor 799 840 vseg_free( vseg ); 800 841 … … 1079 1120 1080 1121 // attach vseg to VSL 1081 vmm_ vseg_attach( vmm , vseg );1122 vmm_attach_vseg_to_vsl( vmm , vseg ); 1082 1123 1083 1124 #if DEBUG_VMM_CREATE_VSEG … … 1092 1133 } // vmm_create_vseg() 1093 1134 1094 ///////////////////////////////////// 1095 void vmm_remove_vseg( vseg_t * vseg ) 1135 /////////////////////////////////// 1136 void vmm_delete_vseg( pid_t pid, 1137 intptr_t vaddr ) 1096 1138 { 1097 // get pointers on calling process and VMM 1098 thread_t * this = CURRENT_THREAD; 1099 vmm_t * vmm = &this->process->vmm; 1100 uint32_t type = vseg->type; 1101 1102 // detach vseg from VSL 1103 vmm_vseg_detach( vmm , vseg ); 1104 1105 // release the stack slot to VMM stack allocator if STACK type 1106 if( type == VSEG_TYPE_STACK ) 1107 { 1108 // get pointer on stack allocator 1109 stack_mgr_t * mgr = &vmm->stack_mgr; 1110 1111 // compute slot index 1112 uint32_t index = ((vseg->vpn_base - mgr->vpn_base - 1) / CONFIG_VMM_STACK_SIZE); 1113 1114 // update stacks_bitmap 1115 busylock_acquire( &mgr->lock ); 1116 bitmap_clear( &mgr->bitmap , index ); 1117 busylock_release( &mgr->lock ); 1118 } 1119 1120 // release the vseg to VMM mmap allocator if MMAP type 1121 if( (type == VSEG_TYPE_ANON) || (type == VSEG_TYPE_FILE) || (type == VSEG_TYPE_REMOTE) ) 1122 { 1123 // get pointer on mmap allocator 1124 mmap_mgr_t * mgr = &vmm->mmap_mgr; 1125 1126 // compute zombi_list index 1127 uint32_t index = bits_log2( vseg->vpn_size ); 1128 1129 // update zombi_list 1130 busylock_acquire( &mgr->lock ); 1131 list_add_first( &mgr->zombi_list[index] , &vseg->zlist ); 1132 busylock_release( &mgr->lock ); 1133 } 1134 1135 // release physical memory allocated for vseg descriptor if no MMAP type 1136 if( (type != VSEG_TYPE_ANON) && (type != VSEG_TYPE_FILE) && (type != VSEG_TYPE_REMOTE) ) 1137 { 1138 vseg_free( vseg ); 1139 } 1140 } // end vmm_remove_vseg() 1141 1142 ///////////////////////////////////////// 1143 void vmm_unmap_vseg( process_t * process, 1144 vseg_t * vseg ) 1145 { 1139 process_t * process; // local pointer on local process 1140 vmm_t * vmm; // local pointer on local process VMM 1141 vseg_t * vseg; // local pointer on local vseg containing vaddr 1142 gpt_t * gpt; // local pointer on local process GPT 1146 1143 vpn_t vpn; // VPN of current PTE 1147 1144 vpn_t vpn_min; // VPN of first PTE … … 1157 1154 uint32_t forks; // actual number of pendinf forks 1158 1155 1159 #if DEBUG_VMM_ UNMAP_VSEG1156 #if DEBUG_VMM_DELETE_VSEG 1160 1157 uint32_t cycle = (uint32_t)hal_get_cycles(); 1161 1158 thread_t * this = CURRENT_THREAD; 1162 if( DEBUG_VMM_UNMAP_VSEG < cycle ) 1163 printk("\n[%s] thread[%x,%x] enter / process %x / vseg %s / base %x / cycle %d\n", 1164 __FUNCTION__, this->process->pid, this->trdid, process->pid, 1165 vseg_type_str( vseg->type ), vseg->vpn_base, cycle ); 1166 #endif 1167 1168 // get pointer on local GPT 1169 gpt_t * gpt = &process->vmm.gpt; 1170 1171 // loop on pages in vseg 1159 if( DEBUG_VMM_DELETE_VSEG < cycle ) 1160 printk("\n[%s] thread[%x,%x] enter / process %x / vaddr %x / cycle %d\n", 1161 __FUNCTION__, this->process->pid, this->trdid, pid, vaddr, cycle ); 1162 #endif 1163 1164 // get local pointer on local process descriptor 1165 process = cluster_get_local_process_from_pid( pid ); 1166 1167 if( process == NULL ) return; 1168 1169 // get pointers on local process VMM an GPT 1170 vmm = &process->vmm; 1171 gpt = &process->vmm.gpt; 1172 1173 // get local pointer on vseg containing vaddr 1174 vseg = vmm_vseg_from_vaddr( vmm , vaddr ); 1175 1176 if( vseg == NULL ) return; 1177 1178 // loop to invalidate all vseg PTEs in GPT 1172 1179 vpn_min = vseg->vpn_base; 1173 1180 vpn_max = vpn_min + vseg->vpn_size; … … 1180 1187 { 1181 1188 1182 #if( DEBUG_VMM_ UNMAP_VSEG & 1 )1183 if( DEBUG_VMM_ UNMAP_VSEG < cycle )1184 printk("- vpn %x / ppn %x\n" , vpn , ppn);1189 #if( DEBUG_VMM_DELETE_VSEG & 1 ) 1190 if( DEBUG_VMM_DELETE_VSEG < cycle ) 1191 printk("- unmap vpn %x / ppn %x / vseg %s \n" , vpn , ppn, vseg_type_str(vseg->type) ); 1185 1192 #endif 1186 1193 … … 1225 1232 rpc_pmem_release_pages_client( page_cxy , page_ptr ); 1226 1233 } 1234 1235 #if( DEBUG_VMM_DELETE_VSEG & 1 ) 1236 if( DEBUG_VMM_DELETE_VSEG < cycle ) 1237 printk("- release ppn %x\n", ppn ); 1238 #endif 1227 1239 } 1228 1240 } … … 1230 1242 } 1231 1243 1232 #if DEBUG_VMM_UNMAP_VSEG 1244 // remove vseg from VSL and release vseg descriptor (if not MMAP) 1245 vmm_detach_vseg_from_vsl( vmm , vseg ); 1246 1247 #if DEBUG_VMM_DELETE_VSEG 1233 1248 cycle = (uint32_t)hal_get_cycles(); 1234 if( DEBUG_VMM_ UNMAP_VSEG < cycle )1249 if( DEBUG_VMM_DELETE_VSEG < cycle ) 1235 1250 printk("\n[%s] thread[%x,%x] exit / process %x / vseg %s / base %x / cycle %d\n", 1236 __FUNCTION__, this->process->pid, this->trdid, process->pid, 1237 vseg_type_str( vseg->type ), vseg->vpn_base, cycle ); 1238 #endif 1239 1240 } // end vmm_unmap_vseg() 1241 1242 ////////////////////////////////////////////////////////////////////////////////////////// 1243 // This low-level static function is called by the vmm_get_vseg(), vmm_get_pte(), 1244 // and vmm_resize_vseg() functions. It scan the local VSL to find the unique vseg 1245 // containing a given virtual address. 1246 ////////////////////////////////////////////////////////////////////////////////////////// 1247 // @ vmm : pointer on the process VMM. 1248 // @ vaddr : virtual address. 1249 // @ return vseg pointer if success / return NULL if not found. 1250 ////////////////////////////////////////////////////////////////////////////////////////// 1251 static vseg_t * vmm_vseg_from_vaddr( vmm_t * vmm, 1252 intptr_t vaddr ) 1251 __FUNCTION__, this->process->pid, this->trdid, pid, vseg_type_str(vseg->type), vaddr, cycle ); 1252 #endif 1253 1254 } // end vmm_delete_vseg() 1255 1256 ///////////////////////////////////////////// 1257 vseg_t * vmm_vseg_from_vaddr( vmm_t * vmm, 1258 intptr_t vaddr ) 1253 1259 { 1254 1260 xptr_t iter_xp; … … 1310 1316 remote_rwlock_wr_acquire( lock_xp ); 1311 1317 1312 if( (vseg->min > addr_min) || (vseg->max < addr_max) ) // regionnot included in vseg1313 { 1314 error = EINVAL;1315 } 1316 else if( (vseg->min == addr_min) && (vseg->max == addr_max) ) // vseg must be removed1317 { 1318 vmm_ remove_vseg( vseg);1318 if( (vseg->min > addr_min) || (vseg->max < addr_max) ) // not included in vseg 1319 { 1320 error = -1; 1321 } 1322 else if( (vseg->min == addr_min) && (vseg->max == addr_max) ) // vseg must be deleted 1323 { 1324 vmm_delete_vseg( process->pid , vseg->min ); 1319 1325 error = 0; 1320 1326 } 1321 else if( vseg->min == addr_min ) // vseg must be resized1327 else if( vseg->min == addr_min ) // vseg must be resized 1322 1328 { 1323 1329 // update vseg base address … … 1331 1337 error = 0; 1332 1338 } 1333 else if( vseg->max == addr_max ) // vseg must be resized1339 else if( vseg->max == addr_max ) // vseg must be resized 1334 1340 { 1335 1341 // update vseg max address … … 1343 1349 error = 0; 1344 1350 } 1345 else // vseg cut in three regions1351 else // vseg cut in three regions 1346 1352 { 1347 1353 // resize existing vseg … … 1415 1421 vseg_init_from_ref( vseg , vseg_xp ); 1416 1422 1417 // register local vseg in local V MM1418 vmm_ vseg_attach( vmm , vseg );1423 // register local vseg in local VSL 1424 vmm_attach_vseg_to_vsl( vmm , vseg ); 1419 1425 } 1420 1426
Note: See TracChangeset
for help on using the changeset viewer.