Difference in PG_buddy page type assignment between kernel version 5.15 and 6.6

  Kiến thức lập trình

I have been working on porting a kernel patch from 5.15 to 6.6. The patch in question is Palloc (link here). It extends the base buddy allocator to allow for (in my use case) cache coloring. Based on my testing, I have successfully ported the patch and all is well. However, I don’t entirely understand why one specific change I made was required and was hoping to get some insight.

A majority of the changes happen in page_alloc.c. Going from 5.15 to 6.6 I had to edit the way the code handled MAX_ORDER, as the range became inclusive, and had to account for the page struct addition of buddy_list, instead of using the lru list (just a cosmetic change). The other edit (the one I don’t understand) is that in the below code I had to wrap a call to __ClearPageBuddy in a check to make sure the passed page had the PG_buddy flag bits set. I did this because I was getting a kernel bug output that came from line 974 in page-flags.h (macro expansion that includes __ClearPageBuddy).

static inline void rmv_page_order(struct page *page)
{
    if (PageBuddy(page))
        __ClearPageBuddy(page);
    set_page_private(page, 0);
}

/* Move a page (size = 1 << order) into order-0 colored cache */
static void palloc_insert(struct zone *zone, struct page *page, int order)
{
    int i, color;

    /* 1 page (2^order) -> 2^order x pages of colored cache.
       Remove from zone->free_area[order].free_list[mt] */
    list_del(&page->buddy_list);
    zone->free_area[order].nr_free--;

    /* Insert pages to zone->color_list[] (all order-0) */
    for (i = 0; i < (1 << order); i++) {
        color = page_to_color(&page[i]);

        /* Add to zone->color_list[color] */
        memdbg(5, "- Add pfn %ld (0x%08llx) to color_list[%d]n", page_to_pfn(&page[i]), (u64)page_to_phys(&page[i]), color);

        INIT_LIST_HEAD(&page[i].buddy_list);
        list_add_tail(&page[i].buddy_list, &zone->color_list[color]);
        bitmap_set(zone->color_bitmap, color, 1);
        zone->free_area[0].nr_free++;
        rmv_page_order(&page[i]);
    }

    memdbg(4, "Add order=%d zone=%sn", order, zone->name);

    return;
}

At a high level, the code snippet, palloc_insert function, takes in a page block of some order and then splits it into order zero pages. Along the way assigning a color to the page and adding it to the color list. It seems to me that some change in the kernel between 5.15 and 6.6 made it so that the pages included in some higher order page block don’t necessarily have the buddy flag bit set. I can’t find any evidence of this. I would like to fully understand why this edit was needed. Does anyone have any insight into what changed? I am new to kernel programming so if there are any resources for tracking down my question feel free to point me to them.

New contributor

csullivan is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

LEAVE A COMMENT