Changeset 632 for trunk/kernel/mm/ppm.c
- Timestamp:
- May 28, 2019, 2:56:04 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/mm/ppm.c
r625 r632 3 3 * 4 4 * Authors Ghassan Almaless (2008,2009,2010,2011,2012) 5 * Alain Greiner (2016,2017,2018 )5 * Alain Greiner (2016,2017,2018,2019) 6 6 * 7 7 * Copyright (c) UPMC Sorbonne Universites … … 45 45 //////////////////////////////////////////////////////////////////////////////////////// 46 46 47 ////////////////////////////////////////////////48 inline bool_t ppm_page_is_valid( page_t * page )49 {50 ppm_t * ppm = &LOCAL_CLUSTER->ppm;51 uint32_t pgnr = (uint32_t)( page - ppm->pages_tbl );52 return (pgnr <= ppm->pages_nr);53 }54 47 55 48 ///////////////////////////////////////////// … … 151 144 void ppm_free_pages_nolock( page_t * page ) 152 145 { 153 page_t * buddy; // searched buddy page descriptor154 uint32_t buddy_index; // buddy page index155 page_t * current; // current (merged) page descriptor156 uint32_t current_index; // current (merged) page index157 uint32_t current_order; // current (merged) pageorder146 page_t * buddy; // searched buddy block page descriptor 147 uint32_t buddy_index; // buddy bloc index in page_tbl[] 148 page_t * current; // current (merged) block page descriptor 149 uint32_t current_index; // current (merged) block index in page_tbl[] 150 uint32_t current_order; // current (merged) block order 158 151 159 152 ppm_t * ppm = &LOCAL_CLUSTER->ppm; 160 153 page_t * pages_tbl = ppm->pages_tbl; 161 154 162 163 164 165 166 155 assert( !page_is_flag( page , PG_FREE ) , 156 "page already released : ppn = %x\n" , ppm_page2ppn(XPTR(local_cxy,page)) ); 157 158 assert( !page_is_flag( page , PG_RESERVED ) , 159 "reserved page : ppn = %x\n" , ppm_page2ppn(XPTR(local_cxy,page)) ); 167 160 168 161 // update released page descriptor flags … … 172 165 // - merge with current page descriptor if found 173 166 // - exit to release the current page descriptor if not found 174 current = page ,167 current = page; 175 168 current_index = (uint32_t)(page - ppm->pages_tbl); 176 169 for( current_order = page->order ; … … 181 174 buddy = pages_tbl + buddy_index; 182 175 183 if( !page_is_flag( buddy , PG_FREE ) || (buddy->order != current_order) ) break; 184 185 // remove buddy from free list 176 // exit this loop if buddy block not found 177 if( !page_is_flag( buddy , PG_FREE ) || 178 (buddy->order != current_order) ) break; 179 180 // remove buddy block from free_list 186 181 list_unlink( &buddy->list ); 187 182 ppm->free_pages_nr[current_order] --; 188 183 189 // merge buddy with current 184 // reset order field in buddy block page descriptor 190 185 buddy->order = 0; 186 187 // compute merged block index in page_tbl[] 191 188 current_index &= buddy_index; 192 189 } 193 190 194 // update merged page descriptor order191 // update pointer and order field for merged block page descriptor 195 192 current = pages_tbl + current_index; 196 193 current->order = current_order; 197 194 198 // insert currentin free list195 // insert merged block in free list 199 196 list_add_first( &ppm->free_pages_root[current_order] , ¤t->list ); 200 197 ppm->free_pages_nr[current_order] ++; … … 205 202 page_t * ppm_alloc_pages( uint32_t order ) 206 203 { 204 page_t * current_block; 207 205 uint32_t current_order; 208 page_t * remaining_block;209 206 uint32_t current_size; 207 page_t * found_block; 210 208 211 209 #if DEBUG_PPM_ALLOC_PAGES … … 213 211 uint32_t cycle = (uint32_t)hal_get_cycles(); 214 212 if( DEBUG_PPM_ALLOC_PAGES < 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, c ycle );213 printk("\n[%s] thread[%x,%x] enter for %d page(s) in cluster %x / cycle %d\n", 214 __FUNCTION__, this->process->pid, this->trdid, 1<<order, cxy, cycle ); 217 215 #endif 218 216 219 217 #if(DEBUG_PPM_ALLOC_PAGES & 0x1) 220 218 if( DEBUG_PPM_ALLOC_PAGES < cycle ) 221 ppm_ print("enter ppm_alloc_pages");219 ppm_remote_display( local_cxy ); 222 220 #endif 223 221 … … 227 225 assert( (order < CONFIG_PPM_MAX_ORDER) , "illegal order argument = %d\n" , order ); 228 226 229 page_t * block = NULL; 227 //build extended pointer on lock protecting remote PPM 228 xptr_t lock_xp = XPTR( local_cxy , &ppm->free_lock ); 230 229 231 230 // take lock protecting free lists 232 busylock_acquire( &ppm->free_lock ); 231 remote_busylock_acquire( lock_xp ); 232 233 current_block = NULL; 233 234 234 235 // find a free block equal or larger to requested size … … 237 238 if( !list_is_empty( &ppm->free_pages_root[current_order] ) ) 238 239 { 239 block = LIST_FIRST( &ppm->free_pages_root[current_order] , page_t , list ); 240 list_unlink( &block->list ); 241 break; 240 // get first free block in this free_list 241 current_block = LIST_FIRST( &ppm->free_pages_root[current_order] , page_t , list ); 242 243 // remove this block from this free_list 244 list_unlink( ¤t_block->list ); 245 246 // register pointer on found block 247 found_block = current_block; 248 249 // update this free-list number of blocks 250 ppm->free_pages_nr[current_order] --; 251 252 // compute found block size 253 current_size = (1 << current_order); 254 255 break; 242 256 } 243 257 } 244 258 245 if( block == NULL ) // return failure259 if( current_block == NULL ) // return failure if no free block found 246 260 { 247 261 // release lock protecting free lists 248 busylock_release( &ppm->free_lock);262 remote_busylock_release( lock_xp ); 249 263 250 264 #if DEBUG_PPM_ALLOC_PAGES 251 265 cycle = (uint32_t)hal_get_cycles(); 252 266 if( DEBUG_PPM_ALLOC_PAGES < 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, c ycle );267 printk("\n[%s] thread[%x,%x] cannot allocate %d page(s) in cluster %x / cycle %d\n", 268 __FUNCTION__, this->process->pid, this->trdid, 1<<order, cxy, cycle ); 255 269 #endif 256 270 … … 258 272 } 259 273 260 // update free-lists after removing a block 261 ppm->free_pages_nr[current_order] --; 262 current_size = (1 << current_order); 263 264 // split the removed block in smaller sub-blocks if required 274 275 // split the found block in smaller sub-blocks if required 265 276 // and update the free-lists accordingly 266 277 while( current_order > order ) 267 278 { 268 279 current_order --; 280 281 // update pointer, size, and order fiels for new free block 269 282 current_size >>= 1; 270 271 remaining_block = block + current_size; 272 remaining_block->order = current_order; 273 274 list_add_first( &ppm->free_pages_root[current_order] , &remaining_block->list ); 283 current_block = found_block + current_size; 284 current_block->order = current_order; 285 286 // insert new free block in relevant free_list 287 list_add_first( &ppm->free_pages_root[current_order] , ¤t_block->list ); 288 289 // update number of blocks in free list 275 290 ppm->free_pages_nr[current_order] ++; 276 291 } 277 292 278 // update page descriptor279 page_clear_flag( block , PG_FREE );280 page_refcount_up( block );281 block->order = order;293 // update found block page descriptor 294 page_clear_flag( found_block , PG_FREE ); 295 page_refcount_up( found_block ); 296 found_block->order = order; 282 297 283 298 // release lock protecting free lists 284 busylock_release( &ppm->free_lock);299 remote_busylock_release( lock_xp ); 285 300 286 301 // update DQDT 287 dqdt_increment_pages( order );302 dqdt_increment_pages( local_cxy , order ); 288 303 289 304 #if DEBUG_PPM_ALLOC_PAGES 290 305 cycle = (uint32_t)hal_get_cycles(); 291 306 if( DEBUG_PPM_ALLOC_PAGES < cycle ) 292 printk("\n[%s] thread[%x,%x] exit for %d page(s) / ppn = %x / cycle %d\n",307 printk("\n[%s] thread[%x,%x] exit for %d page(s) in cluster %x / ppn = %x / cycle %d\n", 293 308 __FUNCTION__, this->process->pid, this->trdid, 294 1<<order, ppm_page2ppn(XPTR( local_cxy , block )), cycle );309 1<<order, ppm_page2ppn(XPTR( local_cxy , found_block )), cxy, cycle ); 295 310 #endif 296 311 297 312 #if(DEBUG_PPM_ALLOC_PAGES & 0x1) 298 313 if( DEBUG_PPM_ALLOC_PAGES < cycle ) 299 ppm_ print("exit ppm_alloc_pages");300 #endif 301 302 return block;314 ppm_remote_display( local_cxy ); 315 #endif 316 317 return found_block; 303 318 304 319 } // end ppm_alloc_pages() … … 311 326 312 327 #if DEBUG_PPM_FREE_PAGES 313 uint32_t cycle = (uint32_t)hal_get_cycles(); 328 thread_t * this = CURRENT_THREAD; 329 uint32_t cycle = (uint32_t)hal_get_cycles(); 314 330 if( DEBUG_PPM_FREE_PAGES < cycle ) 315 printk("\n[%s] thread[%x,%x] enter for %d page(s) / ppn %x / cycle %d\n",331 printk("\n[%s] thread[%x,%x] enter for %d page(s) in cluster %x / ppn %x / cycle %d\n", 316 332 __FUNCTION__, this->process->pid, this->trdid, 317 1<<page->order, ppm_page2ppn(XPTR(local_cxy , page)), cycle );333 1<<page->order, local_cxy, ppm_page2ppn(XPTR(local_cxy , page)), cycle ); 318 334 #endif 319 335 320 336 #if(DEBUG_PPM_FREE_PAGES & 0x1) 321 337 if( DEBUG_PPM_FREE_PAGES < cycle ) 322 ppm_print("enter ppm_free_pages"); 323 #endif 338 ppm_remote_display( local_cxy ); 339 #endif 340 341 //build extended pointer on lock protecting free_lists 342 xptr_t lock_xp = XPTR( local_cxy , &ppm->free_lock ); 324 343 325 344 // get lock protecting free_pages[] array 326 busylock_acquire( &ppm->free_lock);345 remote_busylock_acquire( lock_xp ); 327 346 328 347 ppm_free_pages_nolock( page ); 329 348 330 // release lock protecting free_ pages[] array331 busylock_release( &ppm->free_lock);349 // release lock protecting free_lists 350 remote_busylock_release( lock_xp ); 332 351 333 352 // update DQDT 334 dqdt_decrement_pages( page->order );353 dqdt_decrement_pages( local_cxy , page->order ); 335 354 336 355 #if DEBUG_PPM_FREE_PAGES 337 356 cycle = (uint32_t)hal_get_cycles(); 338 357 if( DEBUG_PPM_FREE_PAGES < cycle ) 339 printk("\n[%s] thread[%x,%x] exit for %d page(s) / ppn %x / cycle %d\n",358 printk("\n[%s] thread[%x,%x] exit for %d page(s) in cluster %x / ppn %x / cycle %d\n", 340 359 __FUNCTION__, this->process->pid, this->trdid, 341 1<<page->order, ppm_page2ppn(XPTR(local_cxy , page)), cycle );360 1<<page->order, local_cxy, ppm_page2ppn(XPTR(local_cxy , page)) , cycle ); 342 361 #endif 343 362 344 363 #if(DEBUG_PPM_FREE_PAGES & 0x1) 345 364 if( DEBUG_PPM_FREE_PAGES < cycle ) 346 ppm_ print("exit ppm_free_pages");365 ppm_remote_display( local_cxy ); 347 366 #endif 348 367 349 368 } // end ppm_free_pages() 350 369 351 //////////////////////// 352 void ppm_display( void ) 370 ///////////////////////////////////////////// 371 xptr_t ppm_remote_alloc_pages( cxy_t cxy, 372 uint32_t order ) 373 { 374 uint32_t current_order; 375 uint32_t current_size; 376 page_t * current_block; 377 page_t * found_block; 378 379 #if DEBUG_PPM_ALLOC_PAGES 380 thread_t * this = CURRENT_THREAD; 381 uint32_t cycle = (uint32_t)hal_get_cycles(); 382 if( DEBUG_PPM_ALLOC_PAGES < cycle ) 383 printk("\n[%s] thread[%x,%x] enter for %d small page(s) in cluster %x / cycle %d\n", 384 __FUNCTION__, this->process->pid, this->trdid, 1<<order, cxy, cycle ); 385 #endif 386 387 #if(DEBUG_PPM_ALLOC_PAGES & 0x1) 388 if( DEBUG_PPM_ALLOC_PAGES < cycle ) 389 ppm_remote_display( cxy ); 390 #endif 391 392 // check order 393 assert( (order < CONFIG_PPM_MAX_ORDER) , "illegal order argument = %d\n" , order ); 394 395 // get local pointer on PPM (same in all clusters) 396 ppm_t * ppm = &LOCAL_CLUSTER->ppm; 397 398 //build extended pointer on lock protecting remote PPM 399 xptr_t lock_xp = XPTR( cxy , &ppm->free_lock ); 400 401 // take lock protecting free lists in remote cluster 402 remote_busylock_acquire( lock_xp ); 403 404 current_block = NULL; 405 406 // find in remote cluster a free block equal or larger to requested size 407 for( current_order = order ; current_order < CONFIG_PPM_MAX_ORDER ; current_order ++ ) 408 { 409 // get local pointer on the root of relevant free_list in remote cluster 410 list_entry_t * root = &ppm->free_pages_root[current_order]; 411 412 if( !list_remote_is_empty( cxy , root ) ) 413 { 414 // get local pointer on first free page descriptor in remote cluster 415 current_block = LIST_REMOTE_FIRST( cxy, root , page_t , list ); 416 417 // remove first free page from the free-list in remote cluster 418 list_remote_unlink( cxy , ¤t_block->list ); 419 420 // register found block 421 found_block = current_block; 422 423 // decrement relevant free-list number of items in remote cluster 424 hal_remote_atomic_add( XPTR( cxy , &ppm->free_pages_nr[current_order] ), -1 ); 425 426 // compute found block size 427 current_size = (1 << current_order); 428 429 break; 430 } 431 } 432 433 if( current_block == NULL ) // return failure 434 { 435 // release lock protecting free lists 436 remote_busylock_release( lock_xp ); 437 438 #if DEBUG_PPM_ALLOC_PAGES 439 cycle = (uint32_t)hal_get_cycles(); 440 if( DEBUG_PPM_ALLOC_PAGES < cycle ) 441 printk("\n[%s] thread[%x,%x] cannot allocate %d page(s) in cluster %x / cycle %d\n", 442 __FUNCTION__, this->process->pid, this->trdid, 1<<order, cxy, cycle ); 443 #endif 444 445 return XPTR_NULL; 446 } 447 448 // split the found block in smaller sub-blocks if required 449 // and update the free-lists accordingly in remote cluster 450 while( current_order > order ) 451 { 452 // update order, size, and local pointer for new free block 453 current_order --; 454 current_size >>= 1; 455 current_block = found_block + current_size; 456 457 // update new free block order field in remote cluster 458 hal_remote_s32( XPTR( cxy , ¤t_block->order ) , current_order ); 459 460 // get local pointer on the root of the relevant free_list in remote cluster 461 list_entry_t * root = &ppm->free_pages_root[current_order]; 462 463 // insert new free block in this free_list 464 list_remote_add_first( cxy , root, ¤t_block->list ); 465 466 // update free-list number of items in remote cluster 467 hal_remote_atomic_add( XPTR(cxy , &ppm->free_pages_nr[current_order]), 1 ); 468 } 469 470 // update refcount, flags and order fields in found block remote page descriptor 471 page_remote_clear_flag( XPTR( cxy , found_block ), PG_FREE ); 472 page_remote_refcount_up( XPTR( cxy , found_block ) ); 473 hal_remote_s32( XPTR( cxy , &found_block->order ) , order ); 474 475 // release lock protecting free lists in remote cluster 476 remote_busylock_release( lock_xp ); 477 478 // update DQDT page counter in remote cluster 479 dqdt_increment_pages( cxy , order ); 480 481 #if DEBUG_PPM_ALLOC_PAGES 482 cycle = (uint32_t)hal_get_cycles(); 483 if( DEBUG_PPM_ALLOC_PAGES < cycle ) 484 printk("\n[%s] thread[%x,%x] exit for %d page(s) / ppn = %x in cluster %x / cycle %d\n", 485 __FUNCTION__, this->process->pid, this->trdid, 486 1<<order, ppm_page2ppn(XPTR( local_cxy , found_block )), cxy, cycle ); 487 #endif 488 489 #if(DEBUG_PPM_ALLOC_PAGES & 0x1) 490 if( DEBUG_PPM_ALLOC_PAGES < cycle ) 491 ppm_remote_display( cxy ); 492 #endif 493 494 return XPTR( cxy , found_block ); 495 496 } // end ppm_remote_alloc_pages() 497 498 ////////////////////////////////////////// 499 void ppm_remote_free_pages( cxy_t cxy, 500 page_t * page ) 501 { 502 xptr_t page_xp; // extended pointer on released page descriptor 503 uint32_t order; // released block order 504 page_t * buddy_ptr; // searched buddy block page descriptor 505 uint32_t buddy_order; // searched buddy block order 506 uint32_t buddy_index; // buddy block index in page_tbl[] 507 page_t * current_ptr; // current (merged) block page descriptor 508 uint32_t current_index; // current (merged) block index in page_tbl[] 509 uint32_t current_order; // current (merged) block order 510 511 #if DEBUG_PPM_FREE_PAGES 512 thread_t * this = CURRENT_THREAD; 513 uint32_t cycle = (uint32_t)hal_get_cycles(); 514 if( DEBUG_PPM_FREE_PAGES < cycle ) 515 printk("\n[%s] thread[%x,%x] enter for %d page(s) in cluster %x / ppn %x / cycle %d\n", 516 __FUNCTION__, this->process->pid, this->trdid, 517 1<<page->order, cxy, ppm_page2ppn(XPTR(cxy , page)), cycle ); 518 #endif 519 520 #if(DEBUG_PPM_FREE_PAGES & 0x1) 521 if( DEBUG_PPM_FREE_PAGES < cycle ) 522 ppm_remote_display( cxy ); 523 #endif 524 525 // build extended pointer on released page descriptor 526 page_xp = XPTR( cxy , page ); 527 528 // get released page order 529 order = hal_remote_l32( XPTR( cxy , &page->order ) ); 530 531 // get local pointer on PPM (same in all clusters) 532 ppm_t * ppm = &LOCAL_CLUSTER->ppm; 533 534 // build extended pointer on lock protecting remote PPM 535 xptr_t lock_xp = XPTR( cxy , &ppm->free_lock ); 536 537 // get local pointer on remote PPM page_tbl[] array 538 page_t * pages_tbl = hal_remote_lpt( XPTR( cxy , &ppm->pages_tbl ) ); 539 540 // get lock protecting free_pages in remote cluster 541 remote_busylock_acquire( lock_xp ); 542 543 assert( !page_remote_is_flag( page_xp , PG_FREE ) , 544 "page already released : ppn = %x\n" , ppm_page2ppn(XPTR(local_cxy,page)) ); 545 546 assert( !page_remote_is_flag( page_xp , PG_RESERVED ) , 547 "reserved page : ppn = %x\n" , ppm_page2ppn(XPTR(local_cxy,page)) ); 548 549 // update released page descriptor flags 550 page_remote_set_flag( page_xp , PG_FREE ); 551 552 // search the buddy page descriptor 553 // - merge with current page descriptor if found 554 // - exit to release the current page descriptor if not found 555 current_ptr = page; 556 current_index = (uint32_t)(page - ppm->pages_tbl); 557 for( current_order = order ; 558 current_order < CONFIG_PPM_MAX_ORDER ; 559 current_order++ ) 560 { 561 buddy_index = current_index ^ (1 << current_order); 562 buddy_ptr = pages_tbl + buddy_index; 563 564 // get buddy block order 565 buddy_order = hal_remote_l32( XPTR( cxy , &buddy_ptr->order ) ); 566 567 // exit loop if buddy block not found 568 if( !page_remote_is_flag( XPTR( cxy , buddy_ptr ) , PG_FREE ) || 569 (buddy_order != current_order) ) break; 570 571 // remove buddy from free list in remote cluster 572 list_remote_unlink( cxy , &buddy_ptr->list ); 573 hal_remote_atomic_add( XPTR( cxy , &ppm->free_pages_nr[current_order] ) , -1 ); 574 575 // reset order field in buddy block page descriptor 576 hal_remote_s32( XPTR( cxy , &buddy_ptr->order ) , 0 ); 577 578 // compute merged block index in page_tbl[] array 579 current_index &= buddy_index; 580 } 581 582 // update merged page descriptor order field 583 current_ptr = pages_tbl + current_index; 584 hal_remote_s32( XPTR( cxy , ¤t_ptr->order ) , current_order ); 585 586 // insert merged block into relevant free list in remote cluster 587 list_remote_add_first( cxy , &ppm->free_pages_root[current_order] , ¤t_ptr->list ); 588 hal_remote_atomic_add( XPTR( cxy , &ppm->free_pages_nr[current_order] ) , 1 ); 589 590 // release lock protecting free_pages[] array 591 remote_busylock_release( lock_xp ); 592 593 // update DQDT 594 dqdt_decrement_pages( cxy , page->order ); 595 596 #if DEBUG_PPM_FREE_PAGES 597 cycle = (uint32_t)hal_get_cycles(); 598 if( DEBUG_PPM_FREE_PAGES < cycle ) 599 printk("\n[%s] thread[%x,%x] exit for %d page(s) in cluster %x / ppn %x / cycle %d\n", 600 __FUNCTION__, this->process->pid, this->trdid, 601 1<<page->order, cxy, ppm_page2ppn(XPTR(cxy , page)), cycle ); 602 #endif 603 604 #if(DEBUG_PPM_FREE_PAGES & 0x1) 605 if( DEBUG_PPM_FREE_PAGES < cycle ) 606 ppm_remote_display( cxy ); 607 #endif 608 609 } // end ppm_remote_free_pages() 610 611 //////////////////////////////////// 612 void ppm_remote_display( cxy_t cxy ) 353 613 { 354 614 uint32_t order; … … 358 618 ppm_t * ppm = &LOCAL_CLUSTER->ppm; 359 619 360 // get lock protecting free lists 361 busylock_acquire( &ppm->free_lock ); 620 // build extended pointer on lock protecting remote PPM 621 xptr_t lock_xp = XPTR( cxy , &ppm->free_lock ); 622 623 // get lock protecting free lists in remote cluster 624 remote_busylock_acquire( lock_xp ); 362 625 363 626 printk("\n***** PPM in cluster %x / %d pages\n", local_cxy , ppm->pages_nr ); … … 365 628 for( order = 0 ; order < CONFIG_PPM_MAX_ORDER ; order++ ) 366 629 { 367 printk("- order = %d / free_pages = %d\t: ", 368 order , ppm->free_pages_nr[order] ); 369 370 LIST_FOREACH( &ppm->free_pages_root[order] , iter ) 630 // get number of free pages for free_list[order] in remote cluster 631 uint32_t n = hal_remote_l32( XPTR( cxy , &ppm->free_pages_nr[order] ) ); 632 printk("- order = %d / free_pages = %d\t: ", order , n ); 633 634 LIST_REMOTE_FOREACH( cxy , &ppm->free_pages_root[order] , iter ) 371 635 { 372 636 page = LIST_ELEMENT( iter , page_t , list ); … … 377 641 } 378 642 379 // release lock protecting free lists 380 busylock_release( &ppm->free_lock);643 // release lock protecting free lists in remote cluster 644 remote_busylock_release( lock_xp ); 381 645 } 382 646 383 //////////////////////////////// ///////384 error_t ppm_assert_order( ppm_t * ppm)647 //////////////////////////////// 648 error_t ppm_assert_order( void ) 385 649 { 386 650 uint32_t order; 387 651 list_entry_t * iter; 388 652 page_t * page; 653 654 ppm_t * ppm = &LOCAL_CLUSTER->ppm; 389 655 390 656 for( order=0 ; order < CONFIG_PPM_MAX_ORDER ; order++ ) … … 438 704 hal_remote_s32( page_flags_xp , flags | PG_DIRTY ); 439 705 440 // The PPM dirty list is a LOCAL list !!! 441 // We must update 4 pointers to insert a new page in this list. 442 // We can use the standard LIST API when the page is local, 443 // but we cannot use the standard API if the page is remote... 444 445 if( page_cxy == local_cxy ) // locally update the PPM dirty list 446 { 447 list_add_first( &ppm->dirty_root , &page_ptr->list ); 448 } 449 else // remotely update the PPM dirty list 450 { 451 // get local and remote pointers on "root" list entry 452 list_entry_t * root = &ppm->dirty_root; 453 xptr_t root_xp = XPTR( page_cxy , root ); 454 455 // get local and remote pointers on "page" list entry 456 list_entry_t * list = &page_ptr->list; 457 xptr_t list_xp = XPTR( page_cxy , list ); 458 459 // get local and remote pointers on first dirty page 460 list_entry_t * dirt = hal_remote_lpt( XPTR( page_cxy, &root->next ) ); 461 xptr_t dirt_xp = XPTR( page_cxy , dirt ); 462 463 // set root.next, list.next, list pred, curr.pred in remote cluster 464 hal_remote_spt( root_xp , list ); 465 hal_remote_spt( list_xp , dirt ); 466 hal_remote_spt( list_xp + sizeof(intptr_t) , root ); 467 hal_remote_spt( dirt_xp + sizeof(intptr_t) , list ); 468 } 706 // insert the page in the remote dirty list 707 list_remote_add_first( page_cxy , &ppm->dirty_root , &page_ptr->list ); 469 708 470 709 done = true; … … 512 751 hal_remote_s32( page_flags_xp , flags & (~PG_DIRTY) ); 513 752 514 // The PPM dirty list is a LOCAL list !!! 515 // We must update 4 pointers to remove a page from this list. 516 // we can use the standard LIST API when the page is local, 517 // but we cannot use the standard API if the page is remote... 518 519 if( page_cxy == local_cxy ) // locally update the PPM dirty list 520 { 521 list_unlink( &page_ptr->list ); 522 } 523 else // remotely update the PPM dirty list 524 { 525 // get local and remote pointers on "page" list entry 526 list_entry_t * list = &page_ptr->list; 527 xptr_t list_xp = XPTR( page_cxy , list ); 528 529 // get local and remote pointers on "next" page list entry 530 list_entry_t * next = hal_remote_lpt( list_xp ); 531 xptr_t next_xp = XPTR( page_cxy , next ); 532 533 // get local and remote pointers on "pred" page list entry 534 list_entry_t * pred = hal_remote_lpt( list_xp + sizeof(intptr_t) ); 535 xptr_t pred_xp = XPTR( page_cxy , pred ); 536 537 // set root.next, list.next, list pred, curr.pred in remote cluster 538 hal_remote_spt( pred_xp , next ); 539 hal_remote_spt( list_xp , NULL ); 540 hal_remote_spt( list_xp + sizeof(intptr_t) , NULL ); 541 hal_remote_spt( next_xp + sizeof(intptr_t) , pred ); 542 } 753 // remove the page from remote dirty list 754 list_remote_unlink( page_cxy , &page_ptr->list ); 543 755 544 756 done = true;
Note: See TracChangeset
for help on using the changeset viewer.