| 585 | } |
| 586 | |
| 587 | static int _pages_free(pgls_agr_t page_list[], struct rt_page *p, |
| 588 | char *frame_va, rt_uint32_t size_bits) |
| 589 | { |
| 590 | rt_uint32_t level = size_bits; |
| 591 | struct rt_page *buddy; |
| 592 | |
| 593 | RT_ASSERT(p >= page_start); |
| 594 | RT_ASSERT((char *)p < (char *)rt_mpr_start + rt_mpr_size); |
| 595 | RT_ASSERT(rt_kmem_v2p(p)); |
| 596 | RT_ASSERT(p->ref_cnt > 0); |
| 597 | RT_ASSERT(p->size_bits == ARCH_ADDRESS_WIDTH_BITS); |
| 598 | RT_ASSERT(size_bits < RT_PAGE_MAX_ORDER); |
| 599 | RT_UNUSED(_pages_are_member); |
| 600 | RT_ASSERT(_pages_are_member((rt_ubase_t)frame_va, size_bits)); |
| 601 | |
| 602 | p->ref_cnt--; |
| 603 | if (p->ref_cnt != 0) |
| 604 | { |
| 605 | return 0; |
| 606 | } |
| 607 | |
| 608 | #ifdef RT_DEBUGGING_PAGE_POISON |
| 609 | _poisoned_pages(frame_va, size_bits); |
| 610 | #endif /* RT_DEBUGGING_PAGE_POISON */ |
| 611 | |
| 612 | while (level < RT_PAGE_MAX_ORDER - 1) |
| 613 | { |
| 614 | buddy = _buddy_get(p, level); |
| 615 | if (buddy && buddy->size_bits == level) |
| 616 | { |
| 617 | _page_remove(_get_pgls_head_by_page(page_list, buddy, level), |
| 618 | buddy, level); |
| 619 | p = (p < buddy) ? p : buddy; |
| 620 | level++; |
| 621 | } |
| 622 | else |
| 623 | { |
| 624 | break; |
| 625 | } |
| 626 | } |
| 627 | |
| 628 | _page_insert(_get_pgls_head_by_page(page_list, p, level), |
| 629 | p, level); |
| 630 | return 1; |
| 631 | } |
| 632 | |
| 633 | static struct rt_page *__pages_alloc( |
| 634 | pgls_agr_t agr_pgls[], rt_uint32_t size_bits, int affid, |
no test coverage detected