Changeset 611 for trunk/kernel/mm
- Timestamp:
- Jan 9, 2019, 3:02:51 PM (6 years ago)
- Location:
- trunk/kernel/mm
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/mm/kmem.c
r577 r611 40 40 #include <fatfs.h> 41 41 #include <ramfs.h> 42 #include <remote_dir.h> 42 43 #include <remote_sem.h> 43 44 #include <remote_barrier.h> … … 100 101 else if( type == KMEM_CONDVAR ) return sizeof( remote_condvar_t ); 101 102 else if( type == KMEM_MUTEX ) return sizeof( remote_mutex_t ); 103 else if( type == KMEM_DIR ) return sizeof( remote_dir_t ); 104 102 105 else if( type == KMEM_512_BYTES ) return 512; 103 106 … … 128 131 else if( type == KMEM_CONDVAR ) return "KMEM_CONDVAR"; 129 132 else if( type == KMEM_MUTEX ) return "KMEM_MUTEX"; 133 else if( type == KMEM_DIR ) return "KMEM_DIR"; 134 130 135 else if( type == KMEM_512_BYTES ) return "KMEM_512_BYTES"; 131 136 … … 144 149 145 150 #if DEBUG_KMEM 151 thread_t * this = CURRENT_THREAD; 146 152 uint32_t cycle = (uint32_t)hal_get_cycles(); 147 153 if( DEBUG_KMEM < cycle ) 148 printk("\n[ DBG] %s : thread %xenter / KCM type %s missing in cluster %x / cycle %d\n",149 __FUNCTION__, CURRENT_THREAD, kmem_type_str( type ), local_cxy, cycle );154 printk("\n[%s] thread[%x,%x] enter / KCM type %s missing in cluster %x / cycle %d\n", 155 __FUNCTION__, this->process->pid, this->trdid, kmem_type_str( type ), local_cxy, cycle ); 150 156 #endif 151 157 … … 174 180 cycle = (uint32_t)hal_get_cycles(); 175 181 if( DEBUG_KMEM < cycle ) 176 printk("\n[ DBG] %s : thread %xexit / cycle %d\n",177 __FUNCTION__, CURRENT_THREAD, cycle );182 printk("\n[%s] thread[%x,%x] exit / cycle %d\n", 183 __FUNCTION__, this->process->pid, this->trdid, cycle ); 178 184 #endif 179 185 … … 198 204 199 205 #if DEBUG_KMEM 206 thread_t * this = CURRENT_THREAD; 200 207 uint32_t cycle = (uint32_t)hal_get_cycles(); 201 208 if( DEBUG_KMEM < cycle ) 202 printk("\n[DBG] %s : thread %x enter / type %s / cluster %x / cycle %d\n", 203 __FUNCTION__, CURRENT_THREAD, kmem_type_str( type ), local_cxy, cycle ); 209 printk("\n[%s] thread [%x,%x] enter / %s / size %d / cluster %x / cycle %d\n", 210 __FUNCTION__, this->process->pid, this->trdid, 211 kmem_type_str( type ), size, local_cxy, cycle ); 204 212 #endif 205 213 … … 222 230 cycle = (uint32_t)hal_get_cycles(); 223 231 if( DEBUG_KMEM < cycle ) 224 printk("\n[DBG] %s : thread %x exit / %d page(s) allocated / ppn %x / cycle %d\n", 225 __FUNCTION__, CURRENT_THREAD, 1<<size, ppm_page2ppn(XPTR(local_cxy,ptr)), cycle ); 232 printk("\n[%s] thread[%x,%x] exit / %d page(s) allocated / ppn %x / cycle %d\n", 233 __FUNCTION__, this->process->pid, this->trdid, 234 1<<size, ppm_page2ppn(XPTR(local_cxy,ptr)), cycle ); 226 235 #endif 227 236 … … 244 253 cycle = (uint32_t)hal_get_cycles(); 245 254 if( DEBUG_KMEM < cycle ) 246 printk("\n[DBG] %s : thread %x exit / type %s allocated / base %x / size %d / cycle %d\n", 247 __FUNCTION__, CURRENT_THREAD, kmem_type_str( type ), (intptr_t)ptr, size, cycle ); 255 printk("\n[%s] thread[%x,%x] exit / type %s allocated / base %x / size %d / cycle %d\n", 256 __FUNCTION__, this->process->pid, this->trdid, 257 kmem_type_str( type ), (intptr_t)ptr, size, cycle ); 248 258 #endif 249 259 … … 286 296 cycle = (uint32_t)hal_get_cycles(); 287 297 if( DEBUG_KMEM < cycle ) 288 printk("\n[ DBG] %s : thread %xexit / type %s allocated / base %x / size %d / cycle %d\n",289 __FUNCTION__, CURRENT_THREAD, kmem_type_str(type), (intptr_t)ptr,298 printk("\n[%s] thread [%x,%x] exit / type %s allocated / base %x / size %d / cycle %d\n", 299 __FUNCTION__, this->process->pid, this->trdid, kmem_type_str(type), (intptr_t)ptr, 290 300 kmem_type_size(type), cycle ); 291 301 #endif -
trunk/kernel/mm/kmem.h
r567 r611 36 36 enum 37 37 { 38 KMEM_PAGE = 0, /*! reserved for PPM allocator*/39 KMEM_GENERIC = 1, /*! reserved for KHM allocator*/40 KMEM_KCM = 2, /*! kcm_t*/41 KMEM_VSEG = 3, /*! vseg_t*/42 KMEM_DEVICE = 4, /*! device_t*/43 KMEM_MAPPER = 5, /*! mapper_t*/44 KMEM_PROCESS = 6, /*! process_t*/45 KMEM_CPU_CTX = 7, /*! hal_cpu_context_t*/46 KMEM_FPU_CTX = 8, /*! hal_fpu_context_t*/47 KMEM_BARRIER = 9, /*! remote_barrier_t*/38 KMEM_PAGE = 0, /*! reserved for PPM allocator */ 39 KMEM_GENERIC = 1, /*! reserved for KHM allocator */ 40 KMEM_KCM = 2, /*! kcm_t */ 41 KMEM_VSEG = 3, /*! vseg_t */ 42 KMEM_DEVICE = 4, /*! device_t */ 43 KMEM_MAPPER = 5, /*! mapper_t */ 44 KMEM_PROCESS = 6, /*! process_t */ 45 KMEM_CPU_CTX = 7, /*! hal_cpu_context_t */ 46 KMEM_FPU_CTX = 8, /*! hal_fpu_context_t */ 47 KMEM_BARRIER = 9, /*! remote_barrier_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_512_BYTES = 19, /*! 512 bytes aligned*/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 */ 59 59 60 KMEM_TYPES_NR = 21, 60 KMEM_512_BYTES = 20, /*! 512 bytes aligned */ 61 62 KMEM_TYPES_NR = 21, 61 63 }; 62 64 -
trunk/kernel/mm/mapper.c
r610 r611 644 644 } // end mapper_remote_set_32() 645 645 646 646 ////////////////////////////////////////////////// 647 error_t mapper_display_page( xptr_t mapper_xp, 648 uint32_t page_id, 649 uint32_t nbytes, 650 char * string ) 651 { 652 xptr_t page_xp; // extended pointer on page descriptor 653 xptr_t base_xp; // extended pointer on page base 654 char buffer[4096]; // local buffer 655 uint32_t * tab; // pointer on uint32_t to scan the buffer 656 uint32_t line; // line index 657 uint32_t word; // word index 658 659 if( nbytes > 4096) 660 { 661 printk("\n[ERROR] in %s : nbytes (%d) cannot be larger than 4096\n", 662 __FUNCTION__, nbytes ); 663 return -1; 664 } 665 666 // get extended pointer on page descriptor 667 page_xp = mapper_remote_get_page( mapper_xp , page_id ); 668 669 if( page_xp == XPTR_NULL) 670 { 671 printk("\n[ERROR] in %s : cannot access page %d in mapper\n", 672 __FUNCTION__, page_id ); 673 return -1; 674 } 675 676 // get extended pointer on page base 677 base_xp = ppm_page2base( page_xp ); 678 679 // copy remote page to local buffer 680 hal_remote_memcpy( XPTR( local_cxy , buffer ) , base_xp , nbytes ); 681 682 // display 8 words per line 683 tab = (uint32_t *)buffer; 684 printk("\n***** %s : first %d bytes of page %d *****\n", string, nbytes, page_id ); 685 for( line = 0 ; line < (nbytes >> 5) ; line++ ) 686 { 687 printk("%X : ", line ); 688 for( word = 0 ; word < 8 ; word++ ) printk("%X ", tab[(line<<3) + word] ); 689 printk("\n"); 690 } 691 692 return 0; 693 694 } // end mapper_display_page 695 696 -
trunk/kernel/mm/mapper.h
r610 r611 1 1 /* 2 * mapper.h - Kernel cache for FS files ordirectories definition.2 * mapper.h - Kernel cache for VFS files/directories definition. 3 3 * 4 4 * Authors Mohamed Lamine Karaoui (2015) … … 195 195 196 196 /******************************************************************************************* 197 * This function returns an extended pointer on a mapper page, identified by <page_id>, 198 * index in the file. The - possibly remote - mapper is identified by the <mapper_xp> 199 * argument. It can be executed by a thread running in any cluster, as it uses remote 197 * This function returns an extended pointer on a page descriptor. 198 * The - possibly remote - mapper is identified by the <mapper_xp> argument. 199 * The page is identified by <page_id> argument (page index in the file). 200 * It can be executed by a thread running in any cluster, as it uses remote 200 201 * access primitives to scan the mapper. 201 202 * In case of miss, this function takes the mapper lock in WRITE_MODE, and call the … … 205 206 * @ mapper_xp : extended pointer on the mapper. 206 207 * @ page_id : page index in file 207 * @ returns extended pointer on page baseif success / return XPTR_NULL if error.208 * @ returns extended pointer on page descriptor if success / return XPTR_NULL if error. 208 209 ******************************************************************************************/ 209 210 xptr_t mapper_remote_get_page( xptr_t mapper_xp, … … 212 213 /******************************************************************************************* 213 214 * This function allows to read a single word in a mapper seen as and array of uint32_t. 214 * It has bee designed to support remote access t ho the FAT mapper of the FATFS.215 * It has bee designed to support remote access to the FAT mapper of the FATFS. 215 216 * It can be called by any thread running in any cluster. 216 217 * In case of miss, it takes the mapper lock in WRITE_MODE, load the missing … … 218 219 ******************************************************************************************* 219 220 * @ mapper_xp : [in] extended pointer on the mapper. 220 * @ index: [in] 32 bits word index in file.221 * @ word_id : [in] 32 bits word index in file. 221 222 * @ p_value : [out] local pointer on destination buffer. 222 223 * @ returns 0 if success / return -1 if error. … … 234 235 ******************************************************************************************* 235 236 * @ mapper_xp : [in] extended pointer on the mapper. 236 * @ index: [in] 32 bits word index in file.237 * @ p_value: [in] value to be written.237 * @ word_id : [in] 32 bits word index in file. 238 * @ value : [in] value to be written. 238 239 * @ returns 0 if success / return -1 if error. 239 240 ******************************************************************************************/ … … 242 243 uint32_t value ); 243 244 245 /******************************************************************************************* 246 * This debug function displays the content of a given page of a given mapper. 247 * - the mapper is identified by the <mapper_xp> argument. 248 * - the page is identified by the <page_id> argument. 249 * - the number of bytes to display in page is defined by the <nbytes> argument. 250 * The format is eigth (32 bits) words per line in hexadecimal. 251 * It can be called by any thread running in any cluster. 252 * In case of miss in mapper, it load the missing page from device to mapper. 253 ******************************************************************************************* 254 * @ mapper_xp : [in] extended pointer on the mapper. 255 * @ page_id : [in] page index in file. 256 * @ nbytes : [in] value to be written. 257 * @ string : [in] string printed in header. 258 * @ returns 0 if success / return -1 if error. 259 ******************************************************************************************/ 260 error_t mapper_display_page( xptr_t mapper_xp, 261 uint32_t page_id, 262 uint32_t nbytes, 263 char * string ); 264 265 244 266 #endif /* _MAPPER_H_ */ -
trunk/kernel/mm/ppm.c
r610 r611 210 210 211 211 #if DEBUG_PPM_ALLOC_PAGES 212 thread_t * this = CURRENT_THREAD; 212 213 uint32_t cycle = (uint32_t)hal_get_cycles(); 213 214 if( DEBUG_PPM_ALLOC_PAGES < cycle ) 214 printk("\n[ DBG] in %s : thread %x in process %xenter for %d page(s) / cycle %d\n",215 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, 1<<order, cycle );215 printk("\n[%s] thread[%x,%x] enter for %d page(s) / cycle %d\n", 216 __FUNCTION__, this->process->pid, this->trdid, 1<<order, cycle ); 216 217 #endif 217 218 218 219 #if(DEBUG_PPM_ALLOC_PAGES & 0x1) 219 220 if( DEBUG_PPM_ALLOC_PAGES < cycle ) 220 ppm_print( );221 ppm_print("enter ppm_alloc_pages"); 221 222 #endif 222 223 223 224 ppm_t * ppm = &LOCAL_CLUSTER->ppm; 224 225 225 assert( (order < CONFIG_PPM_MAX_ORDER) , 226 "illegal order argument = %x\n" , order );226 // check order 227 assert( (order < CONFIG_PPM_MAX_ORDER) , "illegal order argument = %d\n" , order ); 227 228 228 229 page_t * block = NULL; … … 250 251 cycle = (uint32_t)hal_get_cycles(); 251 252 if( DEBUG_PPM_ALLOC_PAGES < cycle ) 252 printk("\n[ DBG] in %s : thread %x in process %xcannot allocate %d page(s) / cycle %d\n",253 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid, 1<<order, cycle );253 printk("\n[%s] thread[%x,%x] cannot allocate %d page(s) / cycle %d\n", 254 __FUNCTION__, this->process->pid, this->trdid, 1<<order, cycle ); 254 255 #endif 255 256 … … 289 290 cycle = (uint32_t)hal_get_cycles(); 290 291 if( DEBUG_PPM_ALLOC_PAGES < cycle ) 291 printk("\n[ DBG] in %s : thread %x in process %xexit for %d page(s) / ppn = %x / cycle %d\n",292 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid,292 printk("\n[%s] thread[%x,%x] exit for %d page(s) / ppn = %x / cycle %d\n", 293 __FUNCTION__, this->process->pid, this->trdid, 293 294 1<<order, ppm_page2ppn(XPTR( local_cxy , block )), cycle ); 295 #endif 296 297 #if(DEBUG_PPM_ALLOC_PAGES & 0x1) 298 if( DEBUG_PPM_ALLOC_PAGES < cycle ) 299 ppm_print("exit ppm_alloc_pages"); 294 300 #endif 295 301 … … 307 313 uint32_t cycle = (uint32_t)hal_get_cycles(); 308 314 if( DEBUG_PPM_FREE_PAGES < cycle ) 309 printk("\n[ DBG] in %s : thread %x in process %xenter for %d page(s) / ppn %x / cycle %d\n",310 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid,315 printk("\n[%s] thread[%x,%x] enter for %d page(s) / ppn %x / cycle %d\n", 316 __FUNCTION__, this->process->pid, this->trdid, 311 317 1<<page->order, ppm_page2ppn(XPTR(local_cxy , page)), cycle ); 312 318 #endif … … 314 320 #if(DEBUG_PPM_FREE_PAGES & 0x1) 315 321 if( DEBUG_PPM_FREE_PAGES < cycle ) 316 ppm_print( );322 ppm_print("enter ppm_free_pages"); 317 323 #endif 318 324 … … 331 337 cycle = (uint32_t)hal_get_cycles(); 332 338 if( DEBUG_PPM_FREE_PAGES < cycle ) 333 printk("\n[ DBG] in %s : thread %x in process %xexit for %d page(s) / ppn %x / cycle %d\n",334 __FUNCTION__, CURRENT_THREAD->trdid, CURRENT_THREAD->process->pid,339 printk("\n[%s] thread[%x,%x] exit for %d page(s) / ppn %x / cycle %d\n", 340 __FUNCTION__, this->process->pid, this->trdid, 335 341 1<<page->order, ppm_page2ppn(XPTR(local_cxy , page)), cycle ); 336 342 #endif 337 343 344 #if(DEBUG_PPM_FREE_PAGES & 0x1) 345 if( DEBUG_PPM_FREE_PAGES < cycle ) 346 ppm_print("exit ppm_free_pages"); 347 #endif 348 338 349 } // end ppm_free_pages() 339 350 340 ////////////////////// 341 void ppm_print( void)351 /////////////////////////////// 352 void ppm_print( char * string ) 342 353 { 343 354 uint32_t order; … … 350 361 busylock_acquire( &ppm->free_lock ); 351 362 352 printk("\n*** PPM in cluster %x : %d pages ***\n", local_cxy , ppm->pages_nr ); 363 printk("\n*** PPM in cluster %x / %s / %d pages ***\n", 364 local_cxy , string, ppm->pages_nr ); 353 365 354 366 for( order = 0 ; order < CONFIG_PPM_MAX_ORDER ; order++ ) … … 413 425 xptr_t dirty_lock_xp = XPTR( page_cxy , &ppm->dirty_lock ); 414 426 415 // printk("\n@@@ %s : before dirty_list lock aquire\n", __FUNCTION__ );416 417 427 // lock the remote PPM dirty_list 418 428 remote_queuelock_acquire( dirty_lock_xp ); 419 429 420 // printk("\n@@@ %s : after dirty_list lock aquire\n", __FUNCTION__ );421 422 430 // lock the remote page 423 431 remote_busylock_acquire( page_lock_xp ); 424 425 // printk("\n@@@ %s : after page lock aquire\n", __FUNCTION__ );426 432 427 433 // get remote page flags … … 466 472 } 467 473 468 // printk("\n@@@ %s : before page lock release\n", __FUNCTION__ );469 470 474 // unlock the remote page 471 475 remote_busylock_release( page_lock_xp ); 472 476 473 // printk("\n@@@ %s : after page lock release\n", __FUNCTION__ );474 475 477 // unlock the remote PPM dirty_list 476 478 remote_queuelock_release( dirty_lock_xp ); 477 478 // printk("\n@@@ %s : after page lock aquire\n", __FUNCTION__ );479 479 480 480 return done; -
trunk/kernel/mm/ppm.h
r610 r611 83 83 * This is the low-level physical pages allocation function. 84 84 * It allocates N contiguous physical pages. N is a power of 2. 85 * In normal use, you don't need to call itdirectly, as the recommended way to get85 * In normal use, it should not be called directly, as the recommended way to get 86 86 * physical pages is to call the generic allocator defined in kmem.h. 87 87 ***************************************************************************************** 88 88 * @ order : ln2( number of 4 Kbytes pages) 89 89 * @ returns a pointer on the page descriptor if success / NULL otherwise 90 ************************************************************************************** à))**/90 ****************************************************************************************/ 91 91 page_t * ppm_alloc_pages( uint32_t order ); 92 92 … … 174 174 /***************************************************************************************** 175 175 * This function prints the PPM allocator status in the calling thread cluster. 176 ****************************************************************************************/ 177 void ppm_print( void ); 176 ***************************************************************************************** 177 * string : character string printed in header 178 ****************************************************************************************/ 179 void ppm_print( char * string ); 178 180 179 181 /***************************************************************************************** -
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 -
trunk/kernel/mm/vmm.h
r610 r611 38 38 39 39 struct process_s; 40 struct vseg_s; 40 41 41 42 /********************************************************************************************* 42 43 * This structure defines the STACK allocator used by the VMM to dynamically handle 43 * a STACK vseg requested or released by an user process.44 * This allocator handles a fixed size array of fixed size slots in the STACK zone.44 * vseg allocation or release requests for an user thread. 45 * This allocator handles a fixed size array of fixed size slots in STACK zone of user space. 45 46 * The stack size and the number of slots are defined by the CONFIG_VMM_STACK_SIZE, and 46 47 * CONFIG_VMM_STACK_BASE parameters. 47 * Each slot can contain one user stack vseg. The first page in the slot is not allocated48 * to detect stack overflow.48 * Each slot can contain one user stack vseg. The first 4 Kbytes page in the slot is not 49 * mapped to detect stack overflow. 49 50 * The slot index can be computed form the slot base address, and reversely. 50 51 * All allocation / release operations are registered in the stack_bitmap, that completely 51 * define the STACK zone stat e.52 * define the STACK zone status. 52 53 ********************************************************************************************/ 53 54 … … 159 160 160 161 /********************************************************************************************* 161 * This function adds a vseg descriptor in the VSL of a given VMM,162 * and updates the vmm field in the vseg descriptor.163 * It takes the lock protecting VSL.164 *********************************************************************************************165 * @ vmm : pointer on the VMM166 * @ vseg : pointer on the vseg descriptor167 ********************************************************************************************/168 void vmm_vseg_attach( struct vmm_s * vmm,169 vseg_t * vseg );170 171 /*********************************************************************************************172 * This function removes a vseg descriptor from the set of vsegs controlled by a given VMM,173 * and updates the vmm field in the vseg descriptor. No memory is released.174 * It takes the lock protecting VSL.175 *********************************************************************************************176 * @ vmm : pointer on the VMM177 * @ vseg : pointer on the vseg descriptor178 ********************************************************************************************/179 void vmm_vseg_detach( struct vmm_s * vmm,180 vseg_t * vseg );181 182 /*********************************************************************************************183 162 * This function is called by the process_make_fork() function. It partially copies 184 163 * the content of a remote parent process VMM to the local child process VMM: … … 235 214 236 215 /********************************************************************************************* 237 * This function unmaps from the local GPT all mapped PTEs of a vseg identified by the238 * <process> and <vseg> arguments. It can be used for any type of vseg.239 * If this function is executed in the reference cluster, it handles for each referenced240 * physical pages the pending forks counter :241 * - if counter is non-zero, it decrements it.242 * - if counter is zero, it releases the physical page to local kmem allocator.243 *********************************************************************************************244 * @ process : pointer on process descriptor.245 * @ vseg : pointer on the vseg to be unmapped.246 ********************************************************************************************/247 void vmm_unmap_vseg( struct process_s * process,248 vseg_t * vseg );249 250 /*********************************************************************************************251 216 * This function deletes, in the local cluster, all vsegs registered in the VSL 252 217 * of the process identified by the <process> argument. For each vseg: … … 254 219 * - it removes the vseg from the local VSL. 255 220 * - it releases the memory allocated to the local vseg descriptors. 256 * Finally,it releases the memory allocated to the GPT itself.221 * - it releases the memory allocated to the GPT itself. 257 222 ********************************************************************************************* 258 223 * @ process : pointer on process descriptor. … … 304 269 305 270 /********************************************************************************************* 306 * This function removes a vseg identified by it's pointer from the VMM of the calling process. 307 * - If the vseg has not the STACK or MMAP type, it is removed from the vsegs list, 308 * and the physical memory allocated to vseg descriptor is released to KMEM. 309 * - If the vseg has the STACK type, it is removed from the vsegs list, the physical memory 310 * allocated to vseg descriptor is released to KMEM, and the stack slot is returned to the 311 * VMM STACK allocator. 312 * - If the vseg has the MMAP type, it is removed from the vsegs list and is registered 313 * in the zombi_list of the VMM MMAP allocator for future reuse. The physical memory 314 * allocated to vseg descriptor is NOT released to KMEM. 315 ********************************************************************************************* 316 * @ vseg : pointer on vseg to be removed. 317 ********************************************************************************************/ 318 void vmm_remove_vseg( vseg_t * vseg ); 271 * This function removes from the local VMM of a process descriptor identified by the <pid> 272 * argument a local vseg identified by its base address <vaddr> in user space. 273 * It can be used for any type of vseg, but must be called by a local thread. 274 * Use the RPC_VMM_DELETE_VSEG if the client thread is not local. 275 * It does nothing if the process is not registered in the local cluster. 276 * It does nothing if the vseg is not registered in the local process VSL. 277 * - It removes from the local GPT all registered PTEs. If it is executed in the reference 278 * cluster, it releases the referenced physical pages, to the relevant kmem allocator, 279 * depending on vseg type and the pending forks counter. 280 * - It removes the vseg from the local VSL, and release the vseg descriptor if not MMAP. 281 ********************************************************************************************* 282 * @ process : process identifier. 283 * @ vaddr : vseg base address in user space. 284 ********************************************************************************************/ 285 void vmm_delete_vseg( pid_t pid, 286 intptr_t vaddr ); 287 288 /********************************************************************************************* 289 * This function insert a new <vseg> descriptor in the VSL identifed by the <vmm> argument. 290 * and updates the vmm field in the vseg descriptor. 291 * It takes the lock protecting VSL. 292 ********************************************************************************************* 293 * @ vmm : local pointer on local VMM. 294 * @ vseg : local pointer on local vseg descriptor. 295 ********************************************************************************************/ 296 void vmm_attach_vseg_to_vsl( vmm_t * vmm, 297 vseg_t * vseg ); 298 299 /********************************************************************************************* 300 * This function removes a vseg identified by the <vseg> argument from the local VSL 301 * identified by the <vmm> argument and release the memory allocated to vseg descriptor, 302 * for all vseg types, BUT the MMAP type (i.e. ANON or REMOTE). 303 * - If the vseg has not the STACK or MMAP type, it is simply removed from the VSL, 304 * and vseg descriptor is released. 305 * - If the vseg has the STACK type, it is removed from VSL, vseg descriptor is released, 306 * and the stack slot is returned to the local VMM_STACK allocator. 307 * - If the vseg has the MMAP type, it is removed from VSL and is registered in zombi_list 308 * of the VMM_MMAP allocator for future reuse. The vseg descriptor is NOT released. 309 ********************************************************************************************* 310 * @ vmm : local pointer on local VMM. 311 * @ vseg : local pointer on local vseg to be removed. 312 ********************************************************************************************/ 313 void vmm_detach_vseg_from_vsl( vmm_t * vmm, 314 vseg_t * vseg ); 319 315 320 316 /********************************************************************************************* … … 338 334 339 335 /********************************************************************************************* 336 * This low-level function scan the local VSL in <vmm> to find the unique vseg containing 337 * a given virtual address <vaddr>. 338 * It is called by the vmm_get_vseg(), vmm_get_pte(), and vmm_resize_vseg() functions. 339 ********************************************************************************************* 340 * @ vmm : pointer on the process VMM. 341 * @ vaddr : virtual address. 342 * @ return vseg pointer if success / return NULL if not found. 343 ********************************************************************************************/ 344 struct vseg_s * vmm_vseg_from_vaddr( vmm_t * vmm, 345 intptr_t vaddr ); 346 347 /********************************************************************************************* 340 348 * This function checks that a given virtual address is contained in a registered vseg. 341 349 * It can be called by any thread running in any cluster: … … 344 352 * register it in local VMM and returns the local vseg pointer, if success. 345 353 * - it returns an user error if the vseg is missing in the reference VMM, or if there is 346 * not enough memory for a new vseg descriptor in cluster containing the calling thread.354 * not enough memory for a new vseg descriptor in the calling thread cluster. 347 355 ********************************************************************************************* 348 356 * @ process : [in] pointer on process descriptor … … 350 358 * @ vseg : [out] local pointer on local vseg 351 359 * @ returns 0 if success / returns -1 if user error (out of segment). 352 ******************************************************************************************** */360 ********************************************************************************************/ 353 361 error_t vmm_get_vseg( struct process_s * process, 354 362 intptr_t vaddr, -
trunk/kernel/mm/vseg.h
r595 r611 71 71 typedef struct vseg_s 72 72 { 73 xlist_entry_t xlist; /*! all vsegs in same VSL (or same zombi list)*/73 xlist_entry_t xlist; /*! all vsegs in same VSL */ 74 74 list_entry_t zlist; /*! all vsegs in same zombi list */ 75 75 struct vmm_s * vmm; /*! pointer on associated VM manager */
Note: See TracChangeset
for help on using the changeset viewer.