kernel/mm/buddy.c
void __free_pages(struct page *pbpage, unsigned int bplevel) {
    /* page_idx -> the current page
     * buddy_group_idx -> the buddy group that current page is in
     */
    unsigned int page_idx, buddy_group_idx;
    unsigned int combined_idx, tmp;
    struct page *buddy_group_page;
    unsigned int test = 0;
    //kernel_printf("buddy_free.\n");
    // dec_ref(pbpage, 1);
    // if(pbpage->reference)
    //	return;
    if(!(has_flag(pbpage,_PAGE_ALLOCED) || has_flag(pbpage, _PAGE_SLAB))){
    //if(!(has_flag(pbpage, _PAGE_ALLOCED))){
        //original bug!!
        kernel_printf("kfree_again. \n");
        return;
    }else if(has_flag(pbpage, _PAGE_SLAB)){
        // kernel_printf("kfree slab page. \n");
        // test = 1;
        // kernel_printf("page number is: %x", pbpage);
    }
    // if(pbpage->bplevel != -1){
    //     kernel_printf("kfree_again.\n");
    //     return;    
    // }
    //kernel_printf("free_bplevel is: %x", pbpage->bplevel);
    lockup(&buddy.lock);
    set_flag(pbpage,_PAGE_RESERVED);
    page_idx = pbpage - buddy.start_page; 
    // complier do the sizeof(struct) operation, and now page_idx is the index
    while (bplevel < MAX_BUDDY_ORDER) {
        buddy_group_idx = page_idx ^ (1 << bplevel);
        buddy_group_page = pbpage + (buddy_group_idx - page_idx);
        // kernel_printf("group%x %x\n", (page_idx), buddy_group_idx);
        if (!_is_same_bplevel(buddy_group_page, bplevel)) {
            // kernel_printf("%x %x\n", buddy_group_page->bplevel, bplevel);

            break;
        }
        // original bug!!
        if(buddy_group_page->flag == _PAGE_ALLOCED){
            // another memory has been allocated.
            kernel_printf("the buddy memory has been allocated\n");
            break;
        }
        list_del_init(&buddy_group_page->list);
        --buddy.freelist[bplevel].nr_free;
        set_bplevel(buddy_group_page, -1);
        combined_idx = buddy_group_idx & page_idx;
        pbpage += (combined_idx - page_idx);
        page_idx = combined_idx;
        ++bplevel;
    }
    // if(test){
    //     kernel_printf("slab page free nearly finished!\n");
    // }
    set_bplevel(pbpage, bplevel);
//    list_add(&(pbpage->list), &(buddy.freelist[bplevel].free_head));
    //kernel_printf("final free_bplevel is: %x", bplevel)
    buddy_list_add(&(pbpage->list), &(buddy.freelist[bplevel].free_head), bplevel);
    // if(test){
    //     kernel_printf("slab page free nearly finished!\n");
    // }
    ++buddy.freelist[bplevel].nr_free;
    // if(test){
    //     kernel_printf("slab page free finished!\n");
    // }
    // kernel_printf("v%x__addto__%x\n", &(pbpage->list),
    // &(buddy.freelist[bplevel].free_head));
    unlock(&buddy.lock);
}
/* This function is to free the pages
 * @pbpage: the first page's pointer which will be freed 
 * @bplevle: the order of the page block(represent size).
 */
This function is to free the pages
@pbpage: the first page's pointer which will be freed
@bplevle: the order of the page block(represent size).
This function is to free the pages @pbpage : the first page ' s pointer which will be freed @bplevle : the order of the page block ( represent size ) .
void __free_pages(struct page *pbpage, unsigned int bplevel) {
    unsigned int page_idx, buddy_group_idx;
    unsigned int combined_idx, tmp;
    struct page *buddy_group_page;
    unsigned int test = 0;
    if(!(has_flag(pbpage,_PAGE_ALLOCED) || has_flag(pbpage, _PAGE_SLAB))){
        kernel_printf("kfree_again. \n");
        return;
    }else if(has_flag(pbpage, _PAGE_SLAB)){
    }
    lockup(&buddy.lock);
    set_flag(pbpage,_PAGE_RESERVED);
    page_idx = pbpage - buddy.start_page; 
    while (bplevel < MAX_BUDDY_ORDER) {
        buddy_group_idx = page_idx ^ (1 << bplevel);
        buddy_group_page = pbpage + (buddy_group_idx - page_idx);
        if (!_is_same_bplevel(buddy_group_page, bplevel)) {
            break;
        }
        if(buddy_group_page->flag == _PAGE_ALLOCED){
            kernel_printf("the buddy memory has been allocated\n");
            break;
        }
        list_del_init(&buddy_group_page->list);
        --buddy.freelist[bplevel].nr_free;
        set_bplevel(buddy_group_page, -1);
        combined_idx = buddy_group_idx & page_idx;
        pbpage += (combined_idx - page_idx);
        page_idx = combined_idx;
        ++bplevel;
    }
    set_bplevel(pbpage, bplevel);
    buddy_list_add(&(pbpage->list), &(buddy.freelist[bplevel].free_head), bplevel);
    ++buddy.freelist[bplevel].nr_free;
    unlock(&buddy.lock);
}
void __free_pages ( struct page * pbpage , unsigned int bplevel ) { unsigned int page_idx , buddy_group_idx ; unsigned int combined_idx , tmp ; struct page * buddy_group_page ; unsigned int test = 0 ; if ( ! ( has_flag ( pbpage , _PAGE_ALLOCED ) || has_flag ( pbpage , _PAGE_SLAB ) ) ) { kernel_printf ( " \n " ) ; return ; } else if ( has_flag ( pbpage , _PAGE_SLAB ) ) { } lockup ( & buddy . lock ) ; set_flag ( pbpage , _PAGE_RESERVED ) ; page_idx = pbpage - buddy . start_page ; while ( bplevel < MAX_BUDDY_ORDER ) { buddy_group_idx = page_idx ^ ( 1 << bplevel ) ; buddy_group_page = pbpage + ( buddy_group_idx - page_idx ) ; if ( ! _is_same_bplevel ( buddy_group_page , bplevel ) ) { break ; } if ( buddy_group_page -> flag == _PAGE_ALLOCED ) { kernel_printf ( " \n " ) ; break ; } list_del_init ( & buddy_group_page -> list ) ; -- buddy . freelist [ bplevel ] . nr_free ; set_bplevel ( buddy_group_page , -1 ) ; combined_idx = buddy_group_idx & page_idx ; pbpage += ( combined_idx - page_idx ) ; page_idx = combined_idx ; ++ bplevel ; } set_bplevel ( pbpage , bplevel ) ; buddy_list_add ( & ( pbpage -> list ) , & ( buddy . freelist [ bplevel ] . free_head ) , bplevel ) ; ++ buddy . freelist [ bplevel ] . nr_free ; unlock ( & buddy . lock ) ; }
This function is to free the pages
 @pbpage: the first page's pointer which will be freed
 @bplevle: the order of the page block(represent size).
This function is to free the pages @pbpage : the first page ' s pointer which will be freed @bplevle : the order of the page block ( represent size ) .
/* page_idx -> the current page
     * buddy_group_idx -> the buddy group that current page is in
     */ //kernel_printf("buddy_free.\n"); // dec_ref(pbpage, 1); // if(pbpage->reference) //	return; //if(!(has_flag(pbpage, _PAGE_ALLOCED))){ //original bug!! // kernel_printf("kfree slab page. \n"); // test = 1; // kernel_printf("page number is: %x", pbpage); // if(pbpage->bplevel != -1){ //     kernel_printf("kfree_again.\n"); //     return;     // } //kernel_printf("free_bplevel is: %x", pbpage->bplevel); // complier do the sizeof(struct) operation, and now page_idx is the index // kernel_printf("group%x %x\n", (page_idx), buddy_group_idx); // kernel_printf("%x %x\n", buddy_group_page->bplevel, bplevel); // original bug!! // another memory has been allocated. // if(test){ //     kernel_printf("slab page free nearly finished!\n"); // } //    list_add(&(pbpage->list), &(buddy.freelist[bplevel].free_head)); //kernel_printf("final free_bplevel is: %x", bplevel) // if(test){ //     kernel_printf("slab page free nearly finished!\n"); // } // if(test){ //     kernel_printf("slab page free finished!\n"); // } // kernel_printf("v%x__addto__%x\n", &(pbpage->list), // &(buddy.freelist[bplevel].free_head));