Changeset 23 for trunk/kernel/mm/mapper.c
- Timestamp:
- Jun 18, 2017, 10:06:41 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/mm/mapper.c
r18 r23 26 26 #include <hal_types.h> 27 27 #include <hal_special.h> 28 #include <hal_uspace.h> 28 29 #include <grdxt.h> 29 30 #include <rwlock.h> … … 108 109 { 109 110 // remove page from mapper and release to PPM 110 error = mapper_release_page( mapper , found_index ,page );111 error = mapper_release_page( mapper , page ); 111 112 112 113 if ( error ) return error; … … 148 149 149 150 // test if page available in mapper 150 if( ( page == NULL) || page_is_flag( page , PG_INLOAD ) ) // page not available /151 if( ( page == NULL) || page_is_flag( page , PG_INLOAD ) ) // page not available 151 152 { 152 153 // release the lock in READ_MODE and take it in WRITE_MODE … … 194 195 printk("\n[ERROR] in %s : thread %x cannot insert page in mapper\n", 195 196 __FUNCTION__ , this->trdid ); 196 mapper_release_page( mapper , index ,page );197 mapper_release_page( mapper , page ); 197 198 page_clear_flag( page , PG_ALL ); 198 199 req.ptr = page; … … 203 204 204 205 // launch I/O operation to load page from file system 205 error = mapper_updt_page( mapper , index ,page );206 error = vfs_move_page_to_mapper( page ); 206 207 207 208 if( error ) … … 209 210 printk("\n[ERROR] in %s : thread %x cannot load page from device\n", 210 211 __FUNCTION__ , this->trdid ); 211 mapper_release_page( mapper , index ,page );212 mapper_release_page( mapper , page ); 212 213 page_clear_flag( page , PG_ALL ); 213 214 req.ptr = page; … … 255 256 /////////////////////////////////////////////// 256 257 error_t mapper_release_page( mapper_t * mapper, 257 uint32_t index,258 258 page_t * page ) 259 259 { … … 261 261 262 262 // lauch IO operation to update page to file system 263 error = mapper_sync_page( mapper , index ,page );263 error = vfs_move_page_from_mapper( page ); 264 264 265 265 if( error ) … … 288 288 } // end mapper_release_page() 289 289 290 //////////////////////////////////////////// 291 error_t mapper_updt_page( mapper_t * mapper, 292 uint32_t index, 293 page_t * page ) 294 { 295 uint32_t type; 296 vfs_inode_t * inode; 297 error_t error = 0; 298 299 if( page == NULL ) 300 { 301 printk("\n[PANIC] in %s : page pointer is NULL\n", __FUNCTION__ ); 302 hal_core_sleep(); 303 } 304 305 if( mapper == NULL ) 306 { 307 printk("\n[PANIC] in %s : no mapper for this page\n", __FUNCTION__ ); 308 hal_core_sleep(); 309 } 310 311 // get file system type and inode pointer 312 inode = mapper->inode; 313 type = inode->ctx->type; 314 315 // get page lock 316 page_lock( page ); 317 318 // get mapper lock in WRITE_MODE 319 rwlock_wr_lock( &mapper->lock ); 320 321 // call proper I/O operation to update file system 322 if ( type == FS_TYPE_FATFS ) error = fatfs_read_page( page ); 323 else if( type == FS_TYPE_RAMFS ) error = ramfs_read_page( page ); 324 else 325 { 326 printk("\n[PANIC] in %s : undefined file system type\n", __FUNCTION__ ); 327 hal_core_sleep(); 328 } 329 330 // release mapper lock from WRITE_MODE 331 rwlock_wr_unlock( &mapper->lock ); 332 333 // release page lock 334 page_unlock( page ); 335 336 if( error ) 337 { 338 printk("\n[PANIC] in %s : cannot access file system\n", __FUNCTION__ ); 339 return EIO; 340 } 341 342 return 0; 343 } // end mapper_updt_page 344 345 //////////////////////////////////////////// 346 error_t mapper_sync_page( mapper_t * mapper, 347 uint32_t index, 348 page_t * page ) 349 { 350 uint32_t type; 351 vfs_inode_t * inode; 352 error_t error = 0; 353 354 if( page == NULL ) 355 { 356 printk("\n[PANIC] in %s : page pointer is NULL\n", __FUNCTION__ ); 357 hal_core_sleep(); 358 } 359 360 if( mapper == NULL ) 361 { 362 printk("\n[PANIC] in %s : no mapper for this page\n", __FUNCTION__ ); 363 hal_core_sleep(); 364 } 365 366 if( page_is_flag( page , PG_DIRTY ) ) 367 { 368 // get file system type and inode pointer 369 inode = mapper->inode; 370 type = inode->ctx->type; 371 372 // get page lock 373 page_lock( page ); 374 375 // get mapper lock in READ_MODE 376 rwlock_rd_lock( &mapper->lock ); 377 378 // call proper I/O operation to update file system 379 if ( type == FS_TYPE_FATFS ) error = fatfs_write_page( page ); 380 else if( type == FS_TYPE_RAMFS ) error = ramfs_write_page( page ); 381 else 382 { 383 printk("\n[PANIC] in %s : undefined file system type\n", __FUNCTION__ ); 384 hal_core_sleep(); 385 } 386 387 // release mapper lock from READ_MODE 388 rwlock_rd_unlock( &mapper->lock ); 389 390 // release page lock 391 page_unlock( page ); 392 393 if( error ) 394 { 395 printk("\n[PANIC] in %s : cannot update file system\n", __FUNCTION__ ); 396 return EIO; 397 } 398 399 // clear dirty bit 400 page_undo_dirty( page ); 401 } 402 403 return 0; 404 405 } // end mapper_sync_page() 406 407 /////////////////////////////////////////////////////////////////////////////////////// 408 // This static function is called by the mapper_move fragments() function. 409 // It moves one fragment between an user buffer and the kernel mapper. 410 // Implementation Note: It can require access to one or two pages in mapper: 411 // [max_page_index == min_page_index] <=> fragment fit in one mapper page 412 // [max_page index == min_page_index + 1] <=> fragment spread on two mapper pages 413 /////////////////////////////////////////////////////////////////////////////////////// 414 static error_t mapper_move_one_fragment( mapper_t * mapper, 415 bool_t to_buffer, 416 fragment_t * fragment ) 417 { 418 uint32_t size; // number of bytes in fragment 419 cxy_t buf_cxy; // cluster identifier for user buffer 420 uint8_t * buf_ptr; // local pointer on first byte in user buffer 421 422 xptr_t xp_buf; // extended pointer on byte in user buffer 423 xptr_t xp_map; // extended pointer on byte in kernel mapper 424 425 uint32_t min_file_offset; // offset of first byte in file 426 uint32_t max_file_offset; // offset of last byte in file 427 428 uint32_t first_page_index; // index of first page in mapper 429 uint32_t first_page_offset; // offset of first byte in first page in mapper 430 uint32_t first_page_size; // offset of first byte in first page in mapper 431 432 uint32_t second_page_index; // index of last page in mapper 433 uint32_t second_page_offset; // offset of last byte in last page in mapper 434 uint32_t second_page_size; // offset of last byte in last page in mapper 435 436 page_t * page; // pointer on one page descriptor in mapper 437 uint8_t * map_ptr; // local pointer on first byte in mapper 438 439 // get fragment attributes in user buffer 440 buf_cxy = fragment->buf_cxy; 441 buf_ptr = fragment->buf_ptr; 442 size = fragment->size; 443 444 if( size > CONFIG_PPM_PAGE_SIZE ) 445 { 446 printk("\n[PANIC] in %s : illegal fragment size = %d\n", 447 __FUNCTION__ , size ); 448 return EINVAL; 449 } 290 ///////////////////////////////////////// 291 error_t mapper_move( mapper_t * mapper, 292 bool_t to_buffer, 293 uint32_t file_offset, 294 void * buffer, 295 uint32_t size ) 296 { 297 uint32_t page_offset; // first byte to move to/from a mapper page 298 uint32_t page_count; // number of bytes to move to/from a mapper page 299 uint32_t index; // current mapper page index 300 uint32_t done; // number of moved bytes 301 page_t * page; // current mapper page descriptor 302 uint8_t * map_ptr; // current mapper address 303 uint8_t * buf_ptr; // current buffer address 450 304 451 305 // compute offsets of first and last bytes in file 452 min_file_offset = fragment->file_offset;453 max_file_offset = min_file_offset + size;306 uint32_t min_byte = file_offset; 307 uint32_t max_byte = file_offset + size -1; 454 308 455 309 // compute indexes of pages for first and last byte in mapper 456 first_page_index = min_file_offset >> CONFIG_PPM_PAGE_SHIFT; 457 second_page_index = max_file_offset >> CONFIG_PPM_PAGE_SHIFT; 458 459 if ( first_page_index == second_page_index ) // only one page in mapper 460 { 461 // compute offset and size for page in mapper 462 first_page_offset = min_file_offset & (1<<CONFIG_PPM_PAGE_SHIFT); 463 first_page_size = size; 464 465 // get pointer on first page in mapper 466 page = mapper_get_page( mapper , first_page_index ); 310 uint32_t first = min_byte >> CONFIG_PPM_PAGE_SHIFT; 311 uint32_t last = max_byte >> CONFIG_PPM_PAGE_SHIFT; 312 313 done = 0; 314 315 // loop on pages in mapper 316 for( index = first ; index <= last ; index++ ) 317 { 318 // compute page_offset 319 if( index == first ) page_offset = min_byte & CONFIG_PPM_PAGE_MASK; 320 else page_offset = 0; 321 322 // compute page_count 323 if ( first == last ) page_count = size; 324 else if ( index == first ) page_count = CONFIG_PPM_PAGE_SIZE - page_offset; 325 else if ( index == last ) page_count = (max_byte & CONFIG_PPM_PAGE_MASK) + 1; 326 else page_count = CONFIG_PPM_PAGE_SIZE; 327 328 // get page descriptor 329 page = mapper_get_page( mapper , index ); 467 330 468 331 if ( page == NULL ) return EINVAL; 469 332 470 // compute pointer on fragment first byte in mapper 471 map_ptr = (uint8_t *)ppm_page2base( page ) + first_page_offset; 472 473 // compute extended pointers in mapper and in buffer 474 xp_map = XPTR( local_cxy , map_ptr ); 475 xp_buf = XPTR( buf_cxy , buf_ptr ); 333 // compute pointer in mapper 334 map_ptr = (uint8_t *)ppm_page2base( page ) + page_offset; 335 336 // compute pointer in buffer 337 buf_ptr = (uint8_t *)buffer + done; 476 338 477 339 // move fragment 478 340 if( to_buffer ) 479 341 { 480 hal_ remote_memcpy( xp_buf , xp_map , first_page_size);342 hal_copy_to_uspace( buf_ptr , map_ptr , page_count ); 481 343 } 482 344 else 483 345 { 484 346 page_do_dirty( page ); 485 hal_remote_memcpy( xp_map , xp_buf , first_page_size ); 486 } 487 } 488 else // two pages in mapper 489 { 490 // compute offset and size for first page in mapper 491 first_page_offset = min_file_offset & (1<<CONFIG_PPM_PAGE_SHIFT); 492 first_page_size = CONFIG_PPM_PAGE_SIZE - first_page_offset; 493 494 // get pointer on first page descriptor in mapper 495 page = mapper_get_page( mapper , first_page_index ); 496 497 if ( page == NULL ) return EINVAL; 498 499 // compute local pointer on first byte in first page in mapper 500 map_ptr = (uint8_t *)ppm_page2base(page) + first_page_offset; 501 502 // compute extended pointers 503 xp_map = XPTR( local_cxy , map_ptr ); 504 xp_buf = XPTR( buf_cxy , buf_ptr ); 505 506 // move fragment to/from first page 507 if( to_buffer ) 508 { 509 hal_remote_memcpy( xp_buf , xp_map , first_page_size ); 510 } 511 else 512 { 513 page_do_dirty( page ); 514 hal_remote_memcpy( xp_map , xp_buf , first_page_size ); 515 } 516 517 // compute offset and size for second page in mapper 518 second_page_offset = 0; 519 second_page_size = size - first_page_size; 520 521 // get pointer on second page in mapper 522 page = mapper_get_page( mapper , second_page_index ); 523 524 if ( page == NULL ) return EINVAL; 525 526 // compute local pointer on first byte in second page in mapper 527 map_ptr = (uint8_t *)ppm_page2base( page ) + second_page_offset; 528 529 // compute extended pointers 530 xp_map = XPTR( local_cxy , map_ptr ); 531 xp_buf = XPTR( buf_cxy , buf_ptr + first_page_offset ); 532 533 // move fragment to/from second page 534 if( to_buffer ) 535 { 536 hal_remote_memcpy( xp_buf , xp_map , second_page_size ); 537 } 538 else 539 { 540 page_do_dirty( page ); 541 hal_remote_memcpy( xp_map , xp_buf , second_page_size ); 542 } 347 hal_copy_from_uspace( map_ptr , buf_ptr , page_count ); 348 } 349 350 done += page_count; 543 351 } 544 352 545 353 return 0; 546 } // end mapper_move_one_fragment() 547 548 ///////////////////////////////////////////////// 549 error_t mapper_move_fragments( mapper_t * mapper, 550 bool_t read, 551 uint32_t nb_frags, 552 xptr_t xp_frags ) 553 { 554 uint32_t index; 555 error_t error; 556 fragment_t local_frags[CONFIG_MAPPER_MAX_FRAGMENTS]; // local copy of fragments array 557 fragment_t * frags_array; // pointer on fragments array 558 559 // check nb_frags 560 if( nb_frags > CONFIG_MAPPER_MAX_FRAGMENTS ) 561 { 562 printk("\n[PANIC] in %s : number of fragments cannot be larger than %d\n", 563 __FUNCTION__ , CONFIG_MAPPER_MAX_FRAGMENTS ); 564 return EINVAL; 565 } 566 567 // get client cluster and local pointer on fragments array 568 cxy_t client_cxy = GET_CXY( xp_frags ); 569 fragment_t * client_frags = (fragment_t *)GET_PTR( xp_frags ); 570 571 if ( local_cxy == client_cxy ) // use the local fragments array if possible 572 { 573 frags_array = client_frags; 574 } 575 else // make a local copy of fragments array 576 { 577 hal_remote_memcpy( XPTR( local_cxy , local_frags ) , xp_frags , 578 sizeof(fragment_t) * nb_frags ); 579 frags_array = local_frags; 580 } 581 582 // loop on fragments 583 for( index = 0 ; index < nb_frags ; index ++ ) 584 { 585 error = mapper_move_one_fragment( mapper , read , &frags_array[index] ); 586 if ( error ) return error; 587 } 588 589 return 0; 590 591 } // end mapper_move_fragments() 592 593 354 355 } // end mapper_move() 356 357 358
Note: See TracChangeset
for help on using the changeset viewer.