Changeset 683 for trunk/kernel/mm/kcm.c
- Timestamp:
- Jan 13, 2021, 12:36:17 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/mm/kcm.c
r672 r683 36 36 #include <kcm.h> 37 37 38 /////////////////////////////////////////////////////////////////////////////////////////// 39 // global variables 40 /////////////////////////////////////////////////////////////////////////////////////////// 41 42 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c 43 38 44 39 45 ///////////////////////////////////////////////////////////////////////////////////// … … 42 48 43 49 ////////////////////////////////////////////////////////////////////////////////////// 44 // This static function must be called by a local thread.50 // This static function is called by the kcm_alloc() function. 45 51 // It returns a pointer on a block allocated from an active kcm_page. 46 52 // It makes a panic if no block is available in the selected page. … … 55 61 { 56 62 // initialise variables 57 uint32_t size = 1 << kcm->order; 58 uint32_t max = kcm->max_blocks; 63 uint32_t order = kcm->order; 59 64 uint32_t count = kcm_page->count; 60 65 uint64_t status = kcm_page->status; 61 66 62 assert( __FUNCTION__, (count < max) , "kcm_page should not be full" ); 67 // check kcm page not full 68 assert( __FUNCTION__, (count < 63) , 69 "kcm_page should not be full / cxy %x / order %d / count %d", local_cxy, order, count ); 63 70 64 71 uint32_t index = 1; … … 67 74 // allocate first free block in kcm_page, update status, 68 75 // and count , compute index of allocated block in kcm_page 69 while( index <= max)76 while( index <= 63 ) 70 77 { 71 78 if( (status & mask) == 0 ) // block found … … 81 88 } 82 89 83 // change the page list if found block is the last84 if( count == max-1)90 // switch page to full if last block 91 if( (count + 1) == 63 ) 85 92 { 86 93 list_unlink( &kcm_page->list); … … 92 99 93 100 // compute return pointer 94 void * ptr = (void *)((intptr_t)kcm_page + (index * size) ); 95 96 #if DEBUG_KCM 97 thread_t * this = CURRENT_THREAD; 98 uint32_t cycle = (uint32_t)hal_get_cycles(); 99 if( DEBUG_KCM < cycle ) 100 printk("\n[%s] thread[%x,%x] allocated block %x in page %x / size %d / count %d / cycle %d\n", 101 __FUNCTION__, this->process->pid, this->trdid, ptr, kcm_page, size, count + 1, cycle ); 102 #endif 101 void * ptr = (void *)((intptr_t)kcm_page + (index << order)); 103 102 104 103 return ptr; … … 107 106 108 107 ///////////////////////////////////////////////////////////////////////////////////// 109 // This private static function must be called by a local thread.108 // This static function is called by the kcm_free() function. 110 109 // It releases a previously allocated block to the relevant kcm_page. 111 110 // It makes a panic if the released block is not allocated in this page. … … 121 120 { 122 121 // initialise variables 123 uint32_t max = kcm->max_blocks; 124 uint32_t size = 1 << kcm->order; 122 uint32_t order = kcm->order; 125 123 uint32_t count = kcm_page->count; 126 124 uint64_t status = kcm_page->status; 127 125 128 // compute block index from block pointer 129 uint32_t index = ((intptr_t)block_ptr - (intptr_t)kcm_page) / size;126 // compute block index from block pointer and kcm_page pointer 127 uint32_t index = ((intptr_t)block_ptr - (intptr_t)kcm_page) >> order; 130 128 131 129 // compute mask in bit vector … … 136 134 printk("\n[WARNING] in %s : block[%x,%x] not allocated / kcm %x / kcm_page %x\n", 137 135 __FUNCTION__, local_cxy, block_ptr, kcm, kcm_page ); 138 printk(" status %L / mask %L / sts & msk %L\n", status, mask, (status & mask) );139 136 kcm_remote_display( local_cxy , kcm ); 140 137 return; … … 145 142 kcm_page->count = count - 1; 146 143 147 // change the page mode if pagewas full148 if( count == max)144 // switch page to active if it was full 145 if( count == 63 ) 149 146 { 150 147 list_unlink( &kcm_page->list ); … … 155 152 } 156 153 157 #if DEBUG_KCM158 thread_t * this = CURRENT_THREAD;159 uint32_t cycle = (uint32_t)hal_get_cycles();160 if( DEBUG_KCM < cycle )161 printk("\n[%s] thread[%x,%x] block %x / page %x / size %d / count %d / cycle %d\n",162 __FUNCTION__, this->process->pid, this->trdid, block_ptr, kcm_page, size, count - 1, cycle );163 #endif164 165 154 } // kcm_put_block() 166 155 167 156 ///////////////////////////////////////////////////////////////////////////////////// 168 // This static function must be called by a local thread. 169 // It returns one non-full kcm_page with the following policy : 157 // This static function returns one non-full kcm_page with the following policy : 170 158 // - if the "active_list" is non empty, it returns the first "active" page, 171 159 // without modifying the KCM state. … … 188 176 else // allocate a new page from PPM 189 177 { 190 // get one 4 Kbytes page from local PPM 191 page_t * page = ppm_alloc_pages( 0 ); 178 // get KCM order 179 uint32_t order = kcm->order; 180 181 // get one kcm_page from PPM 182 page_t * page = ppm_alloc_pages( order + 6 - CONFIG_PPM_PAGE_ORDER ); 192 183 193 184 if( page == NULL ) 194 185 { 195 printk("\n[ERROR] in %s : failed to allocate page in cluster %x\n", 196 __FUNCTION__ , local_cxy ); 197 186 187 #if DEBUG_KCM_ERROR 188 printk("\n[ERROR] in %s : failed to allocate page in cluster %x\n", 189 __FUNCTION__ , local_cxy ); 190 #endif 198 191 return NULL; 199 192 } … … 202 195 xptr_t base_xp = ppm_page2base( XPTR( local_cxy , page ) ); 203 196 204 // get local pointer on kcm_page 197 // get local pointer on kcm_page 205 198 kcm_page = GET_PTR( base_xp ); 206 199 … … 225 218 { 226 219 227 assert( __FUNCTION__, ((order > 5) && (order < 12)) , "order must be in [6,11]" ); 228 229 assert( __FUNCTION__, (CONFIG_PPM_PAGE_SHIFT == 12) , "check status bit_vector width" ); 220 // check argument 221 assert( __FUNCTION__, (order < CONFIG_PPM_PAGE_ORDER), 222 "order argument %d too large", order ); 223 224 assert( __FUNCTION__, (order >= CONFIG_CACHE_LINE_ORDER), 225 "order argument %d too small", order ); 230 226 231 227 // initialize lock … … 238 234 list_root_init( &kcm->active_root ); 239 235 240 // initialize order and max_blocks 241 kcm->order = order; 242 kcm->max_blocks = ( CONFIG_PPM_PAGE_SIZE >> order ) - 1; 236 // initialize order 237 kcm->order = order; 243 238 244 239 #if DEBUG_KCM 245 thread_t * this = CURRENT_THREAD; 246 uint32_t cycle = (uint32_t)hal_get_cycles(); 247 if( DEBUG_KCM < cycle ) 248 printk("\n[%s] thread[%x,%x] initialised KCM / order %d / max_blocks %d\n", 249 __FUNCTION__, this->process->pid, this->trdid, order, kcm->max_blocks ); 240 if( (DEBUG_KCM_ORDER == order) && (DEBUG_KCM_CXY == local_cxy) ) 241 printk("\n[%s] cxy %x / order %d\n", 242 __FUNCTION__, local_cxy, order ); 250 243 #endif 251 244 … … 287 280 void * kcm_alloc( uint32_t order ) 288 281 { 289 kcm_t * kcm _ptr;282 kcm_t * kcm; 290 283 kcm_page_t * kcm_page; 291 void * block_ptr; 292 293 // min block size is 64 bytes 294 if( order < 6 ) order = 6; 295 296 assert( __FUNCTION__, (order < 12) , "order = %d / must be less than 12" , order ); 284 void * block; 285 286 // check argument 287 assert( __FUNCTION__, (order < CONFIG_PPM_PAGE_ORDER), 288 "order argument %d too large", order ); 289 290 #if DEBUG_KCM 291 uint32_t cycle = (uint32_t)hal_get_cycles(); 292 #endif 293 294 // smallest block size is a cache line 295 if (order < CONFIG_CACHE_LINE_ORDER) order = CONFIG_CACHE_LINE_ORDER; 297 296 298 297 // get local pointer on relevant KCM allocator 299 kcm _ptr = &LOCAL_CLUSTER->kcm[order - 6];298 kcm = &LOCAL_CLUSTER->kcm[order - CONFIG_CACHE_LINE_ORDER]; 300 299 301 300 // build extended pointer on local KCM lock 302 xptr_t lock_xp = XPTR( local_cxy , &kcm _ptr->lock );301 xptr_t lock_xp = XPTR( local_cxy , &kcm->lock ); 303 302 304 303 // get KCM lock … … 306 305 307 306 // get a non-full kcm_page 308 kcm_page = kcm_get_page( kcm_ptr ); 309 310 #if DEBUG_KCM 311 thread_t * this = CURRENT_THREAD; 312 uint32_t cycle = (uint32_t)hal_get_cycles(); 313 if( DEBUG_KCM < cycle ) 314 { 315 printk("\n[%s] thread[%x,%x] enters / order %d / page %x / kcm %x / page_status (%x|%x)\n", 316 __FUNCTION__, this->process->pid, this->trdid, order, kcm_page, kcm_ptr, 317 GET_CXY( kcm_page->status ), GET_PTR( kcm_page->status ) ); 318 kcm_remote_display( local_cxy , kcm_ptr ); 319 } 320 #endif 307 kcm_page = kcm_get_page( kcm ); 321 308 322 309 if( kcm_page == NULL ) … … 326 313 } 327 314 328 // get a block from selected active page 329 block_ptr = kcm_get_block( kcm_ptr , kcm_page ); 315 #if DEBUG_KCM 316 if( (DEBUG_KCM_ORDER == order) && (DEBUG_KCM_CXY == local_cxy) && (DEBUG_KCM < cycle) ) 317 printk("\n[%s] enter / order %d / kcm[%x,%x] / nb_full %d / nb_active %d\n" 318 " page %x / status [%x,%x] / count %d\n", 319 __FUNCTION__, order, local_cxy, kcm, kcm->full_pages_nr, kcm->active_pages_nr, 320 kcm_page, (uint32_t)(kcm_page->status>>32), (uint32_t)(kcm_page->status), kcm_page->count ); 321 #endif 322 323 // allocate a block from selected active page 324 block = kcm_get_block( kcm , kcm_page ); 325 326 #if DEBUG_KCM 327 if( (DEBUG_KCM_ORDER == order) && (DEBUG_KCM_CXY == local_cxy) && (DEBUG_KCM < cycle) ) 328 printk("\n[%s] exit / order %d / kcm[%x,%x] / nb_full %d / nb_active %d\n" 329 " page %x / status [%x,%x] / count %d\n", 330 __FUNCTION__, order, local_cxy, kcm, kcm->full_pages_nr, kcm->active_pages_nr, 331 kcm_page, (uint32_t)(kcm_page->status>>32), (uint32_t)(kcm_page->status), kcm_page->count ); 332 #endif 330 333 331 334 // release lock 332 335 remote_busylock_release( lock_xp ); 333 336 334 #if DEBUG_KCM 335 if( DEBUG_KCM < cycle ) 336 printk("\n[%s] thread[%x,%x] exit / order %d / block %x / kcm %x / page_status (%x|%x)\n", 337 __FUNCTION__, this->process->pid, this->trdid, order, block_ptr, kcm_ptr, 338 GET_CXY( kcm_page->status ), GET_PTR( kcm_page->status ) ); 339 #endif 340 341 return block_ptr; 337 return block; 342 338 343 339 } // end kcm_alloc() 344 340 345 ///////////////////////////////// 346 void kcm_free( void * block_ptr ) 347 { 348 kcm_t * kcm_ptr; 341 /////////////////////////////// 342 void kcm_free( void * block, 343 uint32_t order ) 344 { 345 kcm_t * kcm; 349 346 kcm_page_t * kcm_page; 350 347 351 348 // check argument 352 assert( __FUNCTION__, (block_ptr != NULL) , "block pointer cannot be NULL" ); 349 assert( __FUNCTION__, (block != NULL), 350 "block pointer cannot be NULL" ); 351 352 #if DEBUG_KCM 353 uint32_t cycle = (uint32_t)hal_get_cycles(); 354 #endif 355 356 // smallest block size is a cache line 357 if (order < CONFIG_CACHE_LINE_ORDER) order = CONFIG_CACHE_LINE_ORDER; 358 359 // get local pointer on relevant KCM allocator 360 kcm = &LOCAL_CLUSTER->kcm[order - CONFIG_CACHE_LINE_ORDER]; 353 361 354 362 // get local pointer on KCM page 355 kcm_page = (kcm_page_t *)((intptr_t)block_ptr & ~CONFIG_PPM_PAGE_MASK); 356 357 // get local pointer on KCM descriptor 358 kcm_ptr = kcm_page->kcm; 359 360 #if DEBUG_KCM 361 thread_t * this = CURRENT_THREAD; 362 uint32_t cycle = (uint32_t)hal_get_cycles(); 363 if( (DEBUG_KCM < cycle) && (local_cxy == 1) ) 364 { 365 printk("\n[%s] thread[%x,%x] enters / order %d / block %x / page %x / kcm %x / status [%x,%x]\n", 366 __FUNCTION__, this->process->pid, this->trdid, kcm_ptr->order, block_ptr, kcm_page, kcm_ptr, 367 GET_CXY(kcm_page->status), GET_PTR(kcm_page->status) ); 368 kcm_remote_display( local_cxy , kcm_ptr ); 369 } 370 #endif 363 intptr_t kcm_page_mask = (1 << (order + 6)) - 1; 364 kcm_page = (kcm_page_t *)((intptr_t)block & ~kcm_page_mask); 371 365 372 366 // build extended pointer on local KCM lock 373 xptr_t lock_xp = XPTR( local_cxy , &kcm _ptr->lock );367 xptr_t lock_xp = XPTR( local_cxy , &kcm->lock ); 374 368 375 369 // get lock 376 370 remote_busylock_acquire( lock_xp ); 377 371 378 // release block 379 kcm_put_block( kcm_ptr , kcm_page , block_ptr ); 372 #if DEBUG_KCM 373 if( (DEBUG_KCM_ORDER == order) && (DEBUG_KCM_CXY == local_cxy) && (DEBUG_KCM < cycle) ) 374 printk("\n[%s] exit / order %d / kcm[%x,%x] / nb_full %d / nb_active %d\n" 375 " page %x / status [%x,%x] / count %d\n", 376 __FUNCTION__, order, local_cxy, kcm, kcm->full_pages_nr, kcm->active_pages_nr, 377 kcm_page, (uint32_t)(kcm_page->status>>32), (uint32_t)(kcm_page->status), kcm_page->count ); 378 #endif 379 380 // release the block to the relevant page 381 kcm_put_block( kcm , kcm_page , block ); 382 383 #if DEBUG_KCM 384 if( (DEBUG_KCM_ORDER == order) && (DEBUG_KCM_CXY == local_cxy) && (DEBUG_KCM < cycle) ) 385 printk("\n[%s] exit / order %d / kcm[%x,%x] / nb_full %d / nb_active %d\n" 386 " page %x / status [%x,%x] / count %d\n", 387 __FUNCTION__, order, local_cxy, kcm, kcm->full_pages_nr, kcm->active_pages_nr, 388 kcm_page, (uint32_t)(kcm_page->status>>32), (uint32_t)(kcm_page->status), kcm_page->count ); 389 #endif 380 390 381 391 // release lock 382 392 remote_busylock_release( lock_xp ); 383 393 384 #if DEBUG_KCM385 if( (DEBUG_KCM < cycle) && (local_cxy == 1) )386 {387 printk("\n[%s] thread[%x,%x] exit / order %d / page %x / status [%x,%x]\n",388 __FUNCTION__, this->process->pid, this->trdid, kcm_ptr->order, kcm_ptr,389 GET_CXY(kcm_page->status), GET_PTR(kcm_page->status) );390 kcm_remote_display( local_cxy , kcm_ptr );391 }392 #endif393 394 394 } // end kcm_free() 395 395 … … 400 400 401 401 ///////////////////////////////////////////////////////////////////////////////////// 402 // This static function can be called by any thread running in any cluster. 402 // This static function is called by the kcm_remote_alloc() function. 403 // It can be called by any thread running in any cluster. 403 404 // It returns a local pointer on a block allocated from an active kcm_page. 404 405 // It makes a panic if no block available in the selected kcm_page. … … 415 416 { 416 417 uint32_t order = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->order ) ); 417 uint32_t max = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->max_blocks ) );418 418 uint32_t count = hal_remote_l32( XPTR( kcm_cxy , &kcm_page->count ) ); 419 419 uint64_t status = hal_remote_l64( XPTR( kcm_cxy , &kcm_page->status ) ); 420 uint32_t size = 1 << order; 421 422 assert( __FUNCTION__, (count < max) , "kcm_page should not be full" ); 420 421 // check kcm_page not full 422 assert( __FUNCTION__, (count < 63) , 423 "kcm_page should not be full / cxy %x / order %d / count %d", kcm_cxy, order, count ); 423 424 424 425 uint32_t index = 1; … … 427 428 // allocate first free block in kcm_page, update status, 428 429 // and count , compute index of allocated block in kcm_page 429 while( index <= max)430 while( index <= 63 ) 430 431 { 431 432 if( (status & mask) == 0 ) // block found … … 440 441 } 441 442 442 // change the page list if found block is the last443 if( count == max-1)443 // swich the page to full if last block 444 if( (count + 1) == 63 ) 444 445 { 445 446 list_remote_unlink( kcm_cxy , &kcm_page->list ); … … 451 452 452 453 // compute return pointer 453 void * ptr = (void *)((intptr_t)kcm_page + (index * size) ); 454 455 #if DEBUG_KCM_REMOTE 456 thread_t * this = CURRENT_THREAD; 457 uint32_t cycle = (uint32_t)hal_get_cycles(); 458 if( DEBUG_KCM_REMOTE < cycle ) 459 printk("\n[%s] thread[%x,%x] get block %x in page %x / cluster %x / size %x / count %d\n", 460 __FUNCTION__, this->process->pid, this->trdid, 461 ptr, kcm_page, kcm_cxy, size, count + 1 ); 462 #endif 454 void * ptr = (void *)((intptr_t)kcm_page + (index << order)); 463 455 464 456 return ptr; … … 467 459 468 460 ///////////////////////////////////////////////////////////////////////////////////// 469 // This private static function can be called by any thread running in any cluster. 461 // This static function is called by the kcm_remote_free() function. 462 // It can be called by any thread running in any cluster. 470 463 // It releases a previously allocated block to the relevant kcm_page. 471 464 // It changes the kcm_page status as required. … … 481 474 void * block_ptr ) 482 475 { 483 uint32_t max = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->max_blocks ) );484 476 uint32_t order = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->order ) ); 485 477 uint32_t count = hal_remote_l32( XPTR( kcm_cxy , &kcm_page->count ) ); 486 478 uint64_t status = hal_remote_l64( XPTR( kcm_cxy , &kcm_page->status ) ); 487 uint32_t size = 1 << order;488 479 489 // compute block index from block pointer 490 uint32_t index = ((intptr_t)block_ptr - (intptr_t)kcm_page) / size;480 // compute block index from block pointer and kcm_page pointer 481 uint32_t index = ((intptr_t)block_ptr - (intptr_t)kcm_page) >> order; 491 482 492 483 // compute mask in bit vector … … 497 488 printk("\n[WARNING] in %s : block[%x,%x] not allocated / kcm %x / kcm_page %x\n", 498 489 __FUNCTION__, kcm_cxy, block_ptr, kcm_ptr, kcm_page ); 499 printk(" status %L / mask %L / sts & msk %L\n", status, mask, (status & mask) );500 490 kcm_remote_display( kcm_cxy , kcm_ptr ); 501 491 return; … … 506 496 hal_remote_s32( XPTR( kcm_cxy , &kcm_page->count ) , count - 1 ); 507 497 508 // change the page listif page was full509 if( count == max)498 // switch the page to active if page was full 499 if( count == 63 ) 510 500 { 511 501 list_remote_unlink( kcm_cxy , &kcm_page->list ); … … 516 506 } 517 507 518 #if (DEBUG_KCM_REMOTE & 1)519 thread_t * this = CURRENT_THREAD;520 uint32_t cycle = (uint32_t)hal_get_cycles();521 if( DEBUG_KCM_REMOTE < cycle )522 printk("\n[%s] thread[%x,%x] block %x / page %x / cluster %x / size %x / count %d\n",523 __FUNCTION__, this->process->pid, this->trdid, block_ptr, kcm_page, size, count - 1 )524 #endif525 526 508 } // end kcm_remote_put_block() 527 509 528 510 ///////////////////////////////////////////////////////////////////////////////////// 529 // This privatestatic function can be called by any thread running in any cluster.511 // This static function can be called by any thread running in any cluster. 530 512 // It gets one non-full KCM page from the remote KCM. 531 513 // It allocates a page from remote PPM to populate the freelist, and initialises … … 545 527 else // allocate a new page from PPM 546 528 { 547 // get one 4 Kbytes page from remote PPM 548 xptr_t page_xp = ppm_remote_alloc_pages( kcm_cxy , 0 ); 549 529 // get KCM order 530 uint32_t order = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->order )); 531 532 // get one kcm_page from PPM 533 xptr_t page_xp = ppm_remote_alloc_pages( kcm_cxy, 534 order + 6 - CONFIG_PPM_PAGE_ORDER ); 550 535 if( page_xp == XPTR_NULL ) 551 536 { 552 printk("\n[ERROR] in %s : failed to allocate page in cluster %x\n", 553 __FUNCTION__ , kcm_cxy ); 554 537 538 #if DEBUG_KCM_ERROR 539 printk("\n[ERROR] in %s : failed to allocate page in cluster %x\n", 540 __FUNCTION__ , kcm_cxy ); 541 #endif 555 542 return NULL; 556 543 } … … 585 572 void * block_ptr; 586 573 587 if( order < 6 ) order = 6; 588 589 assert( __FUNCTION__, (order < 12) , "order = %d / must be less than 12" , order ); 590 591 // get local pointer on relevant KCM allocator 574 // check kcm_cxy argument 575 assert( __FUNCTION__, cluster_is_active( kcm_cxy ), 576 "cluster %x not active", kcm_cxy ); 577 578 // check order argument 579 assert( __FUNCTION__, (order < CONFIG_PPM_PAGE_ORDER) , 580 "order argument %d too large", order ); 581 582 // smallest size is a cache line 583 if( order < CONFIG_CACHE_LINE_ORDER ) order = CONFIG_CACHE_LINE_ORDER; 584 585 // get local pointer on relevant KCM allocator (same in all clusters) 592 586 kcm_ptr = &LOCAL_CLUSTER->kcm[order - 6]; 593 587 … … 607 601 } 608 602 603 #if DEBUG_KCM 604 uint32_t cycle = (uint32_t)hal_get_cycles(); 605 uint32_t nb_full = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->full_pages_nr )); 606 uint32_t nb_active = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->active_pages_nr )); 607 uint64_t status = hal_remote_l64( XPTR( kcm_cxy , &kcm_page->status )); 608 uint32_t count = hal_remote_l32( XPTR( kcm_cxy , &kcm_page->count )); 609 #endif 610 611 612 #if DEBUG_KCM 613 if( (DEBUG_KCM_ORDER == order) && (DEBUG_KCM_CXY == local_cxy) && (DEBUG_KCM < cycle) ) 614 printk("\n[%s] enter / order %d / kcm[%x,%x] / nb_full %d / nb_active %d\n" 615 " page %x / status [%x,%x] / count %d\n", 616 __FUNCTION__, order, kcm_cxy, kcm_ptr, nb_full, nb_active, 617 kcm_page, (uint32_t)(status>>32), (uint32_t)(status), kcm_page->count ); 618 #endif 619 609 620 // get a block from selected active page 610 621 block_ptr = kcm_remote_get_block( kcm_cxy , kcm_ptr , kcm_page ); 611 622 623 #if DEBUG_KCM 624 if( (DEBUG_KCM_ORDER == order) && (DEBUG_KCM_CXY == local_cxy) && (DEBUG_KCM < cycle) ) 625 printk("\n[%s] exit / order %d / kcm[%x,%x] / nb_full %d / nb_active %d\n" 626 " page %x / status [%x,%x] / count %d\n", 627 __FUNCTION__, order, kcm_cxy, kcm_ptr, nb_full, nb_active, 628 kcm_page, (uint32_t)(status>>32), (uint32_t)(status), kcm_page->count ); 629 #endif 630 612 631 // release lock 613 632 remote_busylock_release( lock_xp ); 614 633 615 #if DEBUG_KCM_REMOTE616 thread_t * this = CURRENT_THREAD;617 uint32_t cycle = (uint32_t)hal_get_cycles();618 if( DEBUG_KCM_REMOTE < cycle )619 printk("\n[%s] thread[%x,%x] allocated block %x / order %d / kcm[%x,%x]\n",620 __FUNCTION__, this->process->pid, this->trdid, block_ptr, order, kcm_cxy, kcm_ptr );621 #endif622 623 634 return block_ptr; 624 635 625 636 } // end kcm_remote_alloc() 626 637 627 ///////////////////////////////////// 628 void kcm_remote_free( cxy_t kcm_cxy, 629 void * block_ptr ) 638 //////////////////////////////////////// 639 void kcm_remote_free( cxy_t kcm_cxy, 640 void * block_ptr, 641 uint32_t order ) 630 642 { 631 643 kcm_t * kcm_ptr; 632 644 kcm_page_t * kcm_page; 633 645 634 // check argument 635 assert( __FUNCTION__, (block_ptr != NULL) , "block pointer cannot be NULL" ); 636 637 // get local pointer on remote KCM page 638 kcm_page = (kcm_page_t *)((intptr_t)block_ptr & ~CONFIG_PPM_PAGE_MASK); 639 640 // get local pointer on remote KCM 641 kcm_ptr = hal_remote_lpt( XPTR( kcm_cxy , &kcm_page->kcm ) ); 646 // check kcm_cxy argument 647 assert( __FUNCTION__, cluster_is_active( kcm_cxy ), 648 "cluster %x not active", kcm_cxy ); 649 650 // check block_ptr argument 651 assert( __FUNCTION__, (block_ptr != NULL), 652 "block pointer cannot be NULL" ); 653 654 // check order argument 655 assert( __FUNCTION__, (order < CONFIG_PPM_PAGE_ORDER) , 656 "order argument %d too large", order ); 657 658 // smallest block size is a cache line 659 if (order < CONFIG_CACHE_LINE_ORDER) order = CONFIG_CACHE_LINE_ORDER; 660 661 // get local pointer on relevant KCM allocator (same in all clusters) 662 kcm_ptr = &LOCAL_CLUSTER->kcm[order - CONFIG_CACHE_LINE_ORDER]; 663 664 // get local pointer on KCM page 665 intptr_t kcm_page_mask = (1 << (order + 6)) - 1; 666 kcm_page = (kcm_page_t *)((intptr_t)block_ptr & ~kcm_page_mask); 667 668 #if DEBUG_KCM 669 uint32_t cycle = (uint32_t)hal_get_cycles(); 670 uint32_t nb_full = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->full_pages_nr )); 671 uint32_t nb_active = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->active_pages_nr )); 672 uint64_t status = hal_remote_l64( XPTR( kcm_cxy , &kcm_page->status )); 673 uint32_t count = hal_remote_l32( XPTR( kcm_cxy , &kcm_page->count )); 674 #endif 642 675 643 676 // build extended pointer on remote KCM lock … … 647 680 remote_busylock_acquire( lock_xp ); 648 681 649 // release block 682 #if DEBUG_KCM 683 if( (DEBUG_KCM_ORDER == order) && (DEBUG_KCM_CXY == local_cxy) && (DEBUG_KCM < cycle) ) 684 printk("\n[%s] enter / order %d / kcm[%x,%x] / nb_full %d / nb_active %d\n" 685 " page %x / status [%x,%x] / count %d\n", 686 __FUNCTION__, order, kcm_cxy, kcm_ptr, nb_full, nb_active, 687 kcm_page, (uint32_t)(status>>32), (uint32_t)(status), kcm_page->count ); 688 #endif 689 690 // release the block to the relevant page 650 691 kcm_remote_put_block( kcm_cxy , kcm_ptr , kcm_page , block_ptr ); 692 693 #if DEBUG_KCM 694 if( (DEBUG_KCM_ORDER == order) && (DEBUG_KCM_CXY == local_cxy) && (DEBUG_KCM < cycle) ) 695 printk("\n[%s] exit / order %d / kcm[%x,%x] / nb_full %d / nb_active %d\n" 696 " page %x / status [%x,%x] / count %d\n", 697 __FUNCTION__, order, kcm_cxy, kcm_ptr, nb_full, nb_active, 698 kcm_page, (uint32_t)(status>>32), (uint32_t)(status), kcm_page->count ); 699 #endif 651 700 652 701 // release lock 653 702 remote_busylock_release( lock_xp ); 654 655 #if DEBUG_KCM_REMOTE656 thread_t * this = CURRENT_THREAD;657 uint32_t cycle = (uint32_t)hal_get_cycles();658 uint32_t order = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->order ) );659 if( DEBUG_KCM_REMOTE < cycle )660 printk("\n[%s] thread[%x,%x] released block %x / order %d / kcm[%x,%x]\n",661 __FUNCTION__, this->process->pid, this->trdid, block_ptr, order, kcm_cxy, kcm_ptr );662 #endif663 703 664 704 } // end kcm_remote_free … … 673 713 uint32_t count; 674 714 715 // get pointers on TXT0 chdev 716 xptr_t txt0_xp = chdev_dir.txt_tx[0]; 717 cxy_t txt0_cxy = GET_CXY( txt0_xp ); 718 chdev_t * txt0_ptr = GET_PTR( txt0_xp ); 719 720 // get extended pointer on remote TXT0 chdev lock 721 xptr_t txt0_lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock ); 722 723 // get TXT0 lock 724 remote_busylock_acquire( txt0_lock_xp ); 725 675 726 uint32_t order = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->order) ); 676 727 uint32_t full_pages_nr = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->full_pages_nr ) ); 677 728 uint32_t active_pages_nr = hal_remote_l32( XPTR( kcm_cxy , &kcm_ptr->active_pages_nr ) ); 678 729 679 printk("*** KCM : cxy %x / order %d / full_pages_nr %d / active_pages_nr %d\n",730 nolock_printk("*** KCM : cxy %x / order %d / full_pages_nr %d / active_pages_nr %d\n", 680 731 kcm_cxy, order, full_pages_nr, active_pages_nr ); 681 732 … … 688 739 count = hal_remote_l32( XPTR( kcm_cxy , &kcm_page->count ) ); 689 740 690 printk("- active page %x / status (%x,%x) / count %d\n",691 kcm_page, GET_CXY( status ), GET_PTR( status ), count );741 nolock_printk("- active page %x / status (%x,%x) / count %d\n", 742 kcm_page, (uint32_t)( status<< 32 ), (uint32_t)( status ), count ); 692 743 } 693 744 } … … 701 752 count = hal_remote_l32( XPTR( kcm_cxy , &kcm_page->count ) ); 702 753 703 printk("- full page %x / status (%x,%x) / count %d\n",704 kcm_page, GET_CXY( status ), GET_PTR( status ), count );754 nolock_printk("- full page %x / status (%x,%x) / count %d\n", 755 kcm_page, (uint32_t)( status<< 32 ), (uint32_t)( status ), count ); 705 756 } 706 757 } 758 759 // release TXT0 lock 760 remote_busylock_release( txt0_lock_xp ); 761 707 762 } // end kcm remote_display()
Note: See TracChangeset
for help on using the changeset viewer.