Changeset 657 for trunk/kernel/mm/mapper.c
- Timestamp:
- Mar 18, 2020, 11:16:59 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/mm/mapper.c
r656 r657 3 3 * 4 4 * Authors Mohamed Lamine Karaoui (2015) 5 * Alain Greiner (2016,2017,2018,2019 )5 * Alain Greiner (2016,2017,2018,2019,2020) 6 6 * 7 7 * Copyright (c) UPMC Sorbonne Universites … … 46 46 47 47 48 ////////////////////////////////////////////// 49 mapper_t * mapper_create( vfs_fs_type_t type ) 50 { 51 mapper_t * mapper; 48 ///////////////////////////////////// 49 xptr_t mapper_create( cxy_t cxy, 50 uint32_t type ) 51 { 52 mapper_t * mapper_ptr; 52 53 kmem_req_t req; 53 54 error_t error; 54 55 55 56 // allocate memory for mapper descriptor 56 req.type = KMEM_KCM;57 req.order = bits_log2( sizeof(mapper_t) );58 req.flags = AF_KERNEL | AF_ZERO;59 mapper = kmem_alloc(&req );60 61 if( mapper == NULL )57 req.type = KMEM_KCM; 58 req.order = bits_log2( sizeof(mapper_t) ); 59 req.flags = AF_KERNEL | AF_ZERO; 60 mapper_ptr = kmem_remote_alloc( cxy , &req ); 61 62 if( mapper_ptr == NULL ) 62 63 { 63 64 printk("\n[ERROR] in %s : no memory for mapper descriptor\n", __FUNCTION__ ); 64 return NULL;65 } 66 67 // initialize refcount & inode68 mapper->refcount = 0;69 mapper->inode = NULL;65 return XPTR_NULL; 66 } 67 68 // initialize refcount and type 69 hal_remote_s32( XPTR( cxy , &mapper_ptr->refcount ) , 0 ); 70 hal_remote_s32( XPTR( cxy , &mapper_ptr->fs_type ) , type ); 70 71 71 72 // initialize radix tree 72 error = grdxt_ init( &mapper->rt,73 CONFIG_MAPPER_GRDXT_W1,74 CONFIG_MAPPER_GRDXT_W2,75 CONFIG_MAPPER_GRDXT_W3 );73 error = grdxt_remote_init( XPTR( cxy , &mapper_ptr->rt ), 74 CONFIG_MAPPER_GRDXT_W1, 75 CONFIG_MAPPER_GRDXT_W2, 76 CONFIG_MAPPER_GRDXT_W3 ); 76 77 if( error ) 77 78 { 78 79 printk("\n[ERROR] in %s : cannot initialize radix tree\n", __FUNCTION__ ); 79 80 req.type = KMEM_KCM; 80 req.ptr = mapper; 81 kmem_free( &req ); 82 return NULL; 83 } 84 85 // initialize mapper type 86 mapper->type = type; 81 req.ptr = mapper_ptr; 82 kmem_remote_free( cxy , &req ); 83 return XPTR_NULL; 84 } 87 85 88 86 // initialize mapper lock 89 remote_rwlock_init( XPTR( local_cxy , &mapper->lock ) , LOCK_MAPPER_STATE );87 remote_rwlock_init( XPTR( cxy , &mapper_ptr->lock ) , LOCK_MAPPER_STATE ); 90 88 91 89 // initialize waiting threads xlist (empty) 92 xlist_root_init( XPTR( local_cxy , &mapper->wait_root ) );90 xlist_root_init( XPTR( cxy , &mapper_ptr->wait_root ) ); 93 91 94 92 // initialize vsegs xlist (empty) 95 xlist_root_init( XPTR( local_cxy , &mapper->vsegs_root ) );96 97 return mapper;93 xlist_root_init( XPTR( cxy , &mapper_ptr->vsegs_root ) ); 94 95 return XPTR( cxy , mapper_ptr ); 98 96 99 97 } // end mapper_create() 100 98 101 99 //////////////////////////////////////// 102 void mapper_destroy( mapper_t * mapper ) 103 { 100 void mapper_destroy( xptr_t mapper_xp ) 101 { 102 xptr_t page_xp; 104 103 page_t * page; 105 104 uint32_t found_index = 0; … … 107 106 kmem_req_t req; 108 107 108 cxy_t mapper_cxy = GET_CXY( mapper_xp ); 109 mapper_t * mapper_ptr = GET_PTR( mapper_xp ); 110 111 // build extended pointer on radix tree 112 xptr_t rt_xp = XPTR( mapper_cxy , &mapper_ptr->rt ); 113 109 114 // scan radix tree 110 115 do 111 116 { 112 117 // get page from radix tree 113 page = (page_t *)grdxt_get_first( &mapper->rt , start_index , &found_index ); 114 118 page_xp = grdxt_remote_get_first( rt_xp, 119 start_index , 120 &found_index ); 121 page = GET_PTR( page_xp ); 122 115 123 // release registered pages to PPM 116 124 if( page != NULL ) 117 125 { 118 126 // remove page from mapper and release to PPM 119 mapper_remote_release_page( XPTR( local_cxy , mapper ), page );127 mapper_remote_release_page( mapper_xp , page ); 120 128 121 129 // update start_key value for next page … … 126 134 127 135 // release the memory allocated to radix tree itself 128 grdxt_ destroy( &mapper->rt);136 grdxt_remote_destroy( rt_xp ); 129 137 130 138 // release memory for mapper descriptor 131 139 req.type = KMEM_KCM; 132 req.ptr = mapper ;133 kmem_ free(&req );140 req.ptr = mapper_ptr; 141 kmem_remote_free( mapper_cxy , &req ); 134 142 135 143 } // end mapper_destroy() 136 144 137 ///////////////////////////////////////////////// ///////138 error_t mapper_ remote_handle_miss( xptr_t mapper_xp,139 140 145 ///////////////////////////////////////////////// 146 error_t mapper_handle_miss( xptr_t mapper_xp, 147 uint32_t page_id, 148 xptr_t * page_xp_ptr ) 141 149 { 142 150 error_t error; 143 151 144 uint32_t inode_size ;145 uint32_t inode_type ;152 uint32_t inode_size = 0; 153 uint32_t inode_type = 0; 146 154 147 155 thread_t * this = CURRENT_THREAD; … … 159 167 inode_size = hal_remote_l32( XPTR( mapper_cxy , &inode->size ) ); 160 168 inode_type = hal_remote_l32( XPTR( mapper_cxy , &inode->type ) ); 161 }162 else163 {164 inode_size = 0;165 inode_type = 0;166 169 } 167 170 … … 267 270 return 0; 268 271 269 } // end mapper_ remote_handle_miss()270 271 ///////////////////////////////////////////// ///////272 xptr_t mapper_ remote_get_page( xptr_t mapper_xp,273 272 } // end mapper_handle_miss() 273 274 ///////////////////////////////////////////// 275 xptr_t mapper_get_page( xptr_t mapper_xp, 276 uint32_t page_id ) 274 277 { 275 278 error_t error; … … 281 284 cxy_t mapper_cxy = GET_CXY( mapper_xp ); 282 285 286 assert( (hal_remote_lpt( XPTR( mapper_cxy , &mapper_ptr->inode ) ) != NULL ), 287 "should not be used for the FAT mapper"); 288 283 289 #if DEBUG_MAPPER_GET_PAGE 284 vfs_inode_t * inode = hal_remote_lpt( XPTR( mapper_cxy , &mapper_ptr->inode ) );285 290 uint32_t cycle = (uint32_t)hal_get_cycles(); 286 291 char name[CONFIG_VFS_MAX_NAME_LENGTH]; 287 if( (DEBUG_MAPPER_GET_PAGE < cycle) && (inode == NULL) ) // FAT mapper 288 { 289 printk("\n[%s] thread[%x,%x] enter for page %d of FAT mapper / cycle %d\n", 290 __FUNCTION__, this->process->pid, this->trdid, page_id, cycle ); 291 } 292 if( (DEBUG_MAPPER_GET_PAGE < cycle) && (inode != NULL) ) // file mapper 293 { 292 if( DEBUG_MAPPER_GET_PAGE < cycle ) 293 { 294 vfs_inode_t * inode = hal_remote_lpt( XPTR( mapper_cxy , &mapper_ptr->inode ) ); 294 295 vfs_inode_get_name( XPTR( mapper_cxy , inode ) , name ); 295 296 printk("\n[%s] thread[%x,%x] enter for page %d of <%s> mapper / cycle %d\n", … … 330 331 if ( page_xp == XPTR_NULL ) // miss confirmed => handle it 331 332 { 332 error = mapper_ remote_handle_miss( mapper_xp,333 334 333 error = mapper_handle_miss( mapper_xp, 334 page_id, 335 &page_xp ); 335 336 if( error ) 336 337 { … … 343 344 344 345 #if (DEBUG_MAPPER_GET_PAGE & 1) 345 if( (DEBUG_MAPPER_GET_PAGE < cycle) && (inode != NULL) ) 346 { 347 printk("\n[%s] thread[%x,%x] introduced missing page in <%s> mapper / ppn %x\n", 348 __FUNCTION__, this->process->pid, this->trdid, name, ppm_page2ppn(page_xp) ); 349 } 350 if( (DEBUG_MAPPER_GET_PAGE < cycle) && (inode == NULL) ) 351 { 352 printk("\n[%s] thread[%x,%x] introduced missing page in FAT mapper / ppn %x\n", 353 __FUNCTION__, this->process->pid, this->trdid, ppm_page2ppn(page_xp) ); 354 } 346 if( DEBUG_MAPPER_GET_PAGE < cycle ) 347 printk("\n[%s] thread[%x,%x] introduced missing page %d in <%s> mapper / ppn %x\n", 348 __FUNCTION__, this->process->pid, this->trdid, page_id, name, ppm_page2ppn(page_xp) ); 355 349 #endif 356 350 … … 365 359 366 360 #if DEBUG_MAPPER_GET_PAGE 367 cycle = (uint32_t)hal_get_cycles(); 368 if( (DEBUG_MAPPER_GET_PAGE < cycle) && (inode != NULL) ) 369 { 370 printk("\n[%s] thread[%x,%x] exit for page %d of <%s> mapper / ppn %x\n", 371 __FUNCTION__, this->process->pid, this->trdid, page_id, name, ppm_page2ppn(page_xp) ); 372 } 373 if( (DEBUG_MAPPER_GET_PAGE < cycle) && (inode == NULL) ) 374 { 375 printk("\n[%s] thread[%x,%x] exit for page %d of FAT mapper / ppn %x\n", 376 __FUNCTION__, this->process->pid, this->trdid, page_id, ppm_page2ppn(page_xp) ); 377 } 361 if( DEBUG_MAPPER_GET_PAGE < cycle ) 362 printk("\n[%s] thread[%x,%x] exit for page %d of <%s> mapper / ppn %x\n", 363 __FUNCTION__, this->process->pid, this->trdid, page_id, name, ppm_page2ppn(page_xp) ); 378 364 #endif 379 365 … … 385 371 return page_xp; 386 372 387 } // end mapper_remote_get_page() 373 } // end mapper_get_page() 374 375 ///////////////////////////////////////////////// 376 xptr_t mapper_get_fat_page( xptr_t mapper_xp, 377 uint32_t page_id ) 378 { 379 error_t error; 380 381 thread_t * this = CURRENT_THREAD; 382 383 // get mapper cluster and local pointer 384 mapper_t * mapper_ptr = GET_PTR( mapper_xp ); 385 cxy_t mapper_cxy = GET_CXY( mapper_xp ); 386 387 assert( (hal_remote_lpt( XPTR( mapper_cxy , &mapper_ptr->inode ) ) == NULL ), 388 "should be used for the FAT mapper"); 389 390 #if DEBUG_MAPPER_GET_FAT_PAGE 391 uint32_t cycle = (uint32_t)hal_get_cycles(); 392 if( DEBUG_MAPPER_GET_FAT_PAGE < cycle ) 393 printk("\n[%s] thread[%x,%x] enter for page %d of FAT mapper / cycle %d\n", 394 __FUNCTION__, this->process->pid, this->trdid, page_id, cycle ); 395 #endif 396 397 #if( DEBUG_MAPPER_GET_FAT_PAGE & 2 ) 398 if( DEBUG_MAPPER_GET_FAT_PAGE < cycle ) 399 ppm_remote_display( local_cxy ); 400 #endif 401 402 // check thread can yield 403 thread_assert_can_yield( this , __FUNCTION__ ); 404 405 // build extended pointer on mapper lock and mapper rt 406 xptr_t lock_xp = XPTR( mapper_cxy , &mapper_ptr->lock ); 407 xptr_t rt_xp = XPTR( mapper_cxy , &mapper_ptr->rt ); 408 409 // take mapper lock in READ_MODE 410 remote_rwlock_rd_acquire( lock_xp ); 411 412 // search page in radix tree 413 xptr_t page_xp = grdxt_remote_lookup( rt_xp , page_id ); 414 415 // test mapper miss 416 if( page_xp == XPTR_NULL ) // miss => handle it 417 { 418 // release the lock in READ_MODE and take it in WRITE_MODE 419 remote_rwlock_rd_release( lock_xp ); 420 remote_rwlock_wr_acquire( lock_xp ); 421 422 // second test on missing page because the page status can be modified 423 // by another thread, when passing from READ_MODE to WRITE_MODE. 424 // from this point there is no concurrent accesses to mapper. 425 page_xp = grdxt_remote_lookup( rt_xp , page_id ); 426 427 if ( page_xp == XPTR_NULL ) // miss confirmed => handle it 428 { 429 error = mapper_handle_miss( mapper_xp, 430 page_id, 431 &page_xp ); 432 if( error ) 433 { 434 printk("\n[ERROR] in %s : thread[%x,%x] cannot handle mapper miss\n", 435 __FUNCTION__ , this->process->pid, this->trdid ); 436 remote_rwlock_wr_release( lock_xp ); 437 return XPTR_NULL; 438 } 439 } 440 441 #if (DEBUG_MAPPER_GET_FAT_PAGE & 1) 442 if( DEBUG_MAPPER_GET_FAT_PAGE < cycle ) 443 printk("\n[%s] thread[%x,%x] introduced missing page %d in FAT mapper / ppn %x\n", 444 __FUNCTION__, this->process->pid, this->trdid, page_id, ppm_page2ppn(page_xp) ); 445 #endif 446 447 // release mapper lock from WRITE_MODE 448 remote_rwlock_wr_release( lock_xp ); 449 } 450 else // hit 451 { 452 // release mapper lock from READ_MODE 453 remote_rwlock_rd_release( lock_xp ); 454 } 455 456 #if DEBUG_MAPPER_GET_FAT_PAGE 457 if( DEBUG_MAPPER_GET_FAT_PAGE < cycle ) 458 printk("\n[%s] thread[%x,%x] exit for page %d of FAT mapper / ppn %x\n", 459 __FUNCTION__, this->process->pid, this->trdid, page_id, ppm_page2ppn(page_xp) ); 460 #endif 461 462 #if( DEBUG_MAPPER_GET_FAT_PAGE & 2) 463 if( DEBUG_MAPPER_GET_FAT_PAGE < cycle ) 464 ppm_remote_display( local_cxy ); 465 #endif 466 467 return page_xp; 468 469 } // end mapper_get_fat_page() 388 470 389 471 //////////////////////////////////////////////////// … … 481 563 482 564 // get extended pointer on page descriptor in mapper 483 page_xp = mapper_ remote_get_page( mapper_xp , page_id );565 page_xp = mapper_get_page( mapper_xp , page_id ); 484 566 485 567 if ( page_xp == XPTR_NULL ) return -1; … … 519 601 __FUNCTION__, this->process->pid, this->trdid, page_bytes, 520 602 local_cxy, buf_ptr, name, GET_CXY(map_xp), GET_PTR(map_xp) ); 521 mapper_display_page( mapper_xp , page_ xp, 128 );603 mapper_display_page( mapper_xp , page_id , 128 ); 522 604 #endif 523 605 … … 617 699 618 700 // get extended pointer on page descriptor 619 page_xp = mapper_ remote_get_page( mapper_xp , page_id );701 page_xp = mapper_get_page( mapper_xp , page_id ); 620 702 621 703 if ( page_xp == XPTR_NULL ) return -1; … … 678 760 679 761 // get page containing the searched word 680 page_xp = mapper_ remote_get_page( mapper_xp , page_id );762 page_xp = mapper_get_page( mapper_xp , page_id ); 681 763 682 764 if( page_xp == XPTR_NULL ) return -1; … … 702 784 703 785 // get page containing the searched word 704 page_xp = mapper_ remote_get_page( mapper_xp , page_id );786 page_xp = mapper_get_page( mapper_xp , page_id ); 705 787 706 788 if( page_xp == XPTR_NULL ) return -1; … … 719 801 } // end mapper_remote_set_32() 720 802 721 ///////////////////////////////////////// 722 error_t mapper_sync( mapper_t * mapper ) 723 { 724 page_t * page; // local pointer on current page descriptor 725 xptr_t page_xp; // extended pointer on current page descriptor 726 grdxt_t * rt; // pointer on radix_tree descriptor 727 uint32_t start_key; // start page index in mapper 728 uint32_t found_key; // current page index in mapper 803 //////////////////////////////////////// 804 error_t mapper_sync( xptr_t mapper_xp ) 805 { 806 uint32_t found_key; // unused, required by grdxt_remote_get_first() 729 807 error_t error; 808 809 // get mapper cluster and local pointer 810 mapper_t * mapper_ptr = GET_PTR( mapper_xp ); 811 cxy_t mapper_cxy = GET_CXY( mapper_xp ); 730 812 731 813 #if DEBUG_MAPPER_SYNC … … 733 815 uint32_t cycle = (uint32_t)hal_get_cycles(); 734 816 char name[CONFIG_VFS_MAX_NAME_LENGTH]; 735 vfs_inode_get_name( XPTR( local_cxy , mapper->inode ) , name );736 #endif 737 738 // getpointer on radix tree739 rt = &mapper->rt;817 vfs_inode_get_name( XPTR( mapper_cxy , &mapper_ptr->inode ) , name ); 818 #endif 819 820 // build extended pointer on radix tree 821 xptr_t rt_xp = XPTR( mapper_cxy , &mapper_ptr->rt ); 740 822 741 823 // initialise loop variable 742 start_key = 0;824 uint32_t start_key = 0; 743 825 744 826 // scan radix-tree until last page found … … 746 828 { 747 829 // get page descriptor from radix tree 748 page = (page_t *)grdxt_get_first( rt, start_key , &found_key );830 xptr_t page_xp = grdxt_remote_get_first( rt_xp , start_key , &found_key ); 749 831 750 if( page == NULL ) break; 751 752 assert( (page->index == found_key ), "page_index (%d) != key (%d)", page->index, found_key ); 753 assert( (page->order == 0), "page_order (%d] != 0", page->order ); 754 755 // build extended pointer on page descriptor 756 page_xp = XPTR( local_cxy , page ); 832 page_t * page_ptr = GET_PTR( page_xp ); 833 834 // exit loop when last page found 835 if( page_ptr == NULL ) break; 836 837 // get page flags & index fields 838 uint32_t flags = hal_remote_l32( XPTR( mapper_cxy , &page_ptr->flags ) ); 839 uint32_t index = hal_remote_l32( XPTR( mapper_cxy , &page_ptr->index ) ); 757 840 758 841 // synchronize page if dirty 759 if( (page->flags & PG_DIRTY) != 0)842 if( flags & PG_DIRTY ) 760 843 { 761 844 … … 763 846 if( cycle > DEBUG_MAPPER_SYNC ) 764 847 printk("\n[%s] thread[%x,%x] synchonise page %d of <%s> to IOC device\n", 765 __FUNCTION__, this->process->pid, this->trdid, page ->index, name );848 __FUNCTION__, this->process->pid, this->trdid, page_ptr->index, name ); 766 849 #endif 767 850 // copy page to file system … … 771 854 { 772 855 printk("\n[ERROR] in %s : cannot synchonize dirty page %d\n", 773 __FUNCTION__, page ->index );856 __FUNCTION__, page_ptr->index ); 774 857 return -1; 775 858 } … … 784 867 if( cycle > DEBUG_MAPPER_SYNC ) 785 868 printk("\n[%s] thread[%x,%x] skip page %d for <%s>\n", 786 __FUNCTION__, this->process->pid, this->trdid, page ->index, name );869 __FUNCTION__, this->process->pid, this->trdid, page_ptr->index, name ); 787 870 #endif 788 871 } 789 872 790 873 // update loop variable 791 start_key = page->index + 1;874 start_key = index + 1; 792 875 } // end while 793 876 … … 798 881 /////////////////////////////////////////////// 799 882 void mapper_display_page( xptr_t mapper_xp, 800 xptr_t page_xp,883 uint32_t page_id, 801 884 uint32_t nbytes ) 802 885 { … … 809 892 assert( (nbytes <= 4096) , "nbytes cannot be larger than 4096"); 810 893 assert( (mapper_xp != XPTR_NULL) , "mapper_xp argument cannot be null"); 811 assert( (page_xp != XPTR_NULL) , "page_xp argument cannot be null");812 894 813 895 // get mapper cluster and local pointer … … 815 897 mapper_t * mapper_ptr = GET_PTR( mapper_xp ); 816 898 817 // get page cluster an local pointer 899 // get extended pointer on page descriptor 900 xptr_t page_xp = mapper_get_page( mapper_xp , page_id ); 901 902 // get page cluster and local pointer 818 903 cxy_t page_cxy = GET_CXY( page_xp ); 819 904 page_t * page_ptr = GET_PTR( page_xp ); 820 905 821 906 // get page_id and mapper from page descriptor 822 uint32_t page_id= hal_remote_l32( XPTR( page_cxy , &page_ptr->index ) );907 uint32_t index = hal_remote_l32( XPTR( page_cxy , &page_ptr->index ) ); 823 908 mapper_t * mapper = hal_remote_lpt( XPTR( page_cxy , &page_ptr->mapper ) ); 824 909 825 910 assert( (mapper_cxy == page_cxy ) , "mapper and page must be in same cluster"); 826 assert( (mapper_ptr == mapper ) , "unconsistent mapper_xp & page_xp arguments"); 911 assert( (mapper_ptr == mapper ) , "unconsistent mapper field in page descriptor"); 912 assert( (page_id == index ) , "unconsistent index field in page descriptor"); 827 913 828 914 // get inode
Note: See TracChangeset
for help on using the changeset viewer.