Rev 479 | Rev 487 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 479 | Rev 480 | ||
---|---|---|---|
Line 505... | Line 505... | ||
505 | 505 | ||
506 | spinlock_unlock(&zone_head_lock); |
506 | spinlock_unlock(&zone_head_lock); |
507 | interrupts_restore(ipl); |
507 | interrupts_restore(ipl); |
508 | } |
508 | } |
509 | 509 | ||
- | 510 | /** Guess zone by frame instance address |
|
- | 511 | * |
|
- | 512 | * @param frame Frame |
|
- | 513 | * |
|
- | 514 | * @return Zone of given frame |
|
- | 515 | */ |
|
- | 516 | zone_t * get_zone_by_frame(frame_t * frame) { |
|
- | 517 | link_t * cur; |
|
- | 518 | zone_t * zone, *z; |
|
- | 519 | ||
- | 520 | ASSERT(frame); |
|
- | 521 | /* |
|
- | 522 | * First, find host frame zone for addr. |
|
- | 523 | */ |
|
- | 524 | for (cur = zone_head.next; cur != &zone_head; cur = cur->next) { |
|
- | 525 | z = list_get_instance(cur, zone_t, link); |
|
- | 526 | ||
- | 527 | spinlock_lock(&z->lock); |
|
- | 528 | ||
- | 529 | /* |
|
- | 530 | * Check if frame address belongs to z. |
|
- | 531 | */ |
|
- | 532 | if ((frame >= z->frames) && (frame <= z->frames + (z->free_count + z->busy_count))) { |
|
- | 533 | zone = z; |
|
- | 534 | break; |
|
- | 535 | } |
|
- | 536 | spinlock_unlock(&z->lock); |
|
- | 537 | } |
|
- | 538 | ASSERT(zone); |
|
- | 539 | ||
- | 540 | return zone; |
|
- | 541 | ||
- | 542 | ||
- | 543 | } |
|
510 | 544 | ||
511 | /** Buddy system find_buddy implementation |
545 | /** Buddy system find_buddy implementation |
- | 546 | * @param block Block for which buddy should be found |
|
512 | * |
547 | * |
- | 548 | * @return Buddy for given block if found |
|
- | 549 | */ |
|
- | 550 | link_t * zone_buddy_find_buddy(link_t * block) { |
|
- | 551 | frame_t * frame, * f; |
|
- | 552 | zone_t * zone; |
|
- | 553 | link_t * cur; |
|
- | 554 | bool is_left, is_right; |
|
- | 555 | ||
- | 556 | frame = list_get_instance(block, frame_t, buddy_link); |
|
- | 557 | zone = get_zone_by_frame(frame); |
|
- | 558 | ||
- | 559 | ||
- | 560 | /* |
|
- | 561 | * (FRAME_INDEX % 2^(ORDER+1)) == 0 ===> LEFT BUDDY |
|
- | 562 | * (FRAME_INDEX % 2^(ORDER+1)) == 2^(ORDER) ===> RIGHT BUDDY |
|
- | 563 | */ |
|
- | 564 | ||
- | 565 | is_left = IS_BUDDY_LEFT_BLOCK(zone, frame); |
|
- | 566 | is_right = IS_BUDDY_RIGHT_BLOCK(zone, frame); |
|
- | 567 | ||
- | 568 | ASSERT((is_left || is_right) && (!is_left || !is_right)); |
|
- | 569 | ||
- | 570 | for (cur = &zone->buddy_system->order[frame->buddy_order]; cur; cur = cur->next) { |
|
- | 571 | f = list_get_instance(cur, frame_t, buddy_link); |
|
- | 572 | ||
- | 573 | ASSERT(f->buddy_order == frame->buddy_order); |
|
- | 574 | ||
- | 575 | /* |
|
- | 576 | * if found frame is coherent with our frame from the left |
|
513 | */ |
577 | */ |
- | 578 | if ((FRAME_INDEX(zone, f) + 1 >> frame->buddy_order == FRAME_INDEX(zone, frame)) && is_right) { |
|
- | 579 | return cur; |
|
- | 580 | } |
|
- | 581 | ||
- | 582 | /* |
|
514 | link_t * zone_buddy_find_buddy(link_t * buddy) { |
583 | * if found frame is coherent with our frame from the right |
- | 584 | */ |
|
- | 585 | if ((FRAME_INDEX(zone,f) - 1 >> frame->buddy_order == FRAME_INDEX(zone, frame)) && is_left) { |
|
- | 586 | return cur; |
|
- | 587 | } |
|
- | 588 | ||
- | 589 | } |
|
- | 590 | ||
- | 591 | return NULL; |
|
- | 592 | ||
515 | 593 | ||
516 | } |
594 | } |
517 | 595 | ||
518 | /** Buddy system bisect implementation |
596 | /** Buddy system bisect implementation |
519 | * |
597 | * |
- | 598 | * @param block Block to bisect |
|
- | 599 | * |
|
- | 600 | * @return right block |
|
520 | */ |
601 | */ |
521 | link_t * zone_buddy_bisect(link_t * block) { |
602 | link_t * zone_buddy_bisect(link_t * block) { |
- | 603 | frame_t * frame_l, * frame_r; |
|
- | 604 | zone_t * zone; |
|
- | 605 | ||
- | 606 | frame_l = list_get_instance(block, frame_t, buddy_link); |
|
- | 607 | ||
- | 608 | zone = get_zone_by_frame(frame_l); |
|
- | 609 | ||
- | 610 | frame_r = &zone->frames[FRAME_INDEX(zone, frame_l) + 1>>(frame_l->buddy_order-1)]; |
|
- | 611 | ||
- | 612 | ||
- | 613 | return &frame_r->buddy_link; |
|
522 | 614 | ||
523 | } |
615 | } |
524 | 616 | ||
525 | /** Buddy system coalesce implementation |
617 | /** Buddy system coalesce implementation |
526 | * |
618 | * |
- | 619 | * @param block_1 First block |
|
- | 620 | * @param block_2 First block's buddy |
|
- | 621 | * |
|
- | 622 | * @return Coalesced block (actually block that represents lower address) |
|
527 | */ |
623 | */ |
528 | link_t * zone_buddy_coalesce(link_t * buddy_l, link_t * buddy_r) { |
624 | link_t * zone_buddy_coalesce(link_t * block_1, link_t * block_2) { |
- | 625 | frame_t * frame1, * frame2; |
|
- | 626 | zone_t * zone; |
|
- | 627 | ||
- | 628 | frame1 = list_get_instance(block_1, frame_t, buddy_link); |
|
- | 629 | frame2 = list_get_instance(block_2, frame_t, buddy_link); |
|
- | 630 | ||
- | 631 | zone = get_zone_by_frame(frame1); |
|
- | 632 | ||
- | 633 | return FRAME_INDEX(zone, frame1) < FRAME_INDEX(zone, frame2) ? block_1 : block_2; |
|
529 | 634 | ||
530 | } |
635 | } |
531 | 636 | ||
532 | /** Buddy system set_order implementation |
637 | /** Buddy system set_order implementation |
- | 638 | * @param block Buddy system block |
|
533 | * |
639 | * @param order Order to set |
534 | */ |
640 | */ |
535 | void zone_buddy_set_order(link_t * block, __u8 order) { |
641 | void zone_buddy_set_order(link_t * block, __u8 order) { |
536 | - | ||
- | 642 | frame_t * frame; |
|
- | 643 | frame = list_get_instance(block, frame_t, buddy_link); |
|
- | 644 | frame->buddy_order = order; |
|
537 | } |
645 | } |
538 | 646 | ||
539 | /** Buddy system get_order implementation |
647 | /** Buddy system get_order implementation |
- | 648 | * @param block Buddy system block |
|
540 | * |
649 | * |
- | 650 | * @return Order of block |
|
541 | */ |
651 | */ |
542 | __u8 zone_buddy_get_order(link_t * block) { |
652 | __u8 zone_buddy_get_order(link_t * block) { |
543 | - | ||
544 | - | ||
- | 653 | frame_t * frame; |
|
- | 654 | frame = list_get_instance(block, frame_t, buddy_link); |
|
- | 655 | return frame->buddy_order; |
|
545 | } |
656 | } |