|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3 2/9] mm: Place unscrubbed pages at the end of pagelist
>>> On 14.04.17 at 17:37, <boris.ostrovsky@xxxxxxxxxx> wrote:
> @@ -678,6 +680,20 @@ static void check_low_mem_virq(void)
> }
> }
>
> +/* Pages that need scrub are added to tail, otherwise to head. */
> +static void page_list_add_scrub(struct page_info *pg, unsigned int node,
> + unsigned int zone, unsigned int order,
> + bool need_scrub)
> +{
> + PFN_ORDER(pg) = order;
> + pg->u.free.dirty_head = need_scrub;
> +
> + if ( need_scrub )
> + page_list_add_tail(pg, &heap(node, zone, order));
> + else
> + page_list_add(pg, &heap(node, zone, order));
> +}
> +
> /* Allocate 2^@order contiguous pages. */
> static struct page_info *alloc_heap_pages(
> unsigned int zone_lo, unsigned int zone_hi,
> @@ -802,7 +818,7 @@ static struct page_info *alloc_heap_pages(
> while ( j != order )
> {
> PFN_ORDER(pg) = --j;
> - page_list_add_tail(pg, &heap(node, zone, j));
> + page_list_add(pg, &heap(node, zone, j));
Don't you need to replicate pg->u.free.dirty_head (and hence use
page_list_add_scrub()) here too?
> @@ -851,11 +867,14 @@ static int reserve_offlined_page(struct page_info *head)
> int zone = page_to_zone(head), i, head_order = PFN_ORDER(head), count =
> 0;
> struct page_info *cur_head;
> int cur_order;
> + bool need_scrub;
Please put this in the most narrow scope it's needed in.
> ASSERT(spin_is_locked(&heap_lock));
>
> cur_head = head;
>
> + head->u.free.dirty_head = false;
> +
> page_list_del(head, &heap(node, zone, head_order));
>
> while ( cur_head < (head + (1 << head_order)) )
> @@ -892,8 +911,16 @@ static int reserve_offlined_page(struct page_info *head)
> {
> merge:
> /* We don't consider merging outside the head_order. */
> - page_list_add_tail(cur_head, &heap(node, zone, cur_order));
> - PFN_ORDER(cur_head) = cur_order;
> +
> + /* See if any of the pages need scrubbing. */
> + need_scrub = false;
> + for ( i = 0; i < (1 << cur_order); i++ )
> + if ( test_bit(_PGC_need_scrub, &cur_head[i].count_info) )
> + {
> + need_scrub = true;
> + break;
> + }
Can't you skip this loop when the incoming chunk has
->u.free.dirty_head clear?
> +static void scrub_free_pages(unsigned int node)
> +{
> + struct page_info *pg;
> + unsigned int zone, order;
> + unsigned long i;
Here I would similarly appreciate if the local variables were moved
into the scopes they're actually needed in.
> + ASSERT(spin_is_locked(&heap_lock));
> +
> + if ( !node_need_scrub[node] )
> + return;
> +
> + for ( zone = 0; zone < NR_ZONES; zone++ )
> + {
> + order = MAX_ORDER;
> + do {
> + while ( !page_list_empty(&heap(node, zone, order)) )
> + {
> + /* Unscrubbed pages are always at the end of the list. */
> + pg = page_list_last(&heap(node, zone, order));
> + if ( !pg->u.free.dirty_head )
> + break;
> +
> + for ( i = 0; i < (1UL << order); i++)
> + {
> + if ( test_bit(_PGC_need_scrub, &pg[i].count_info) )
> + {
> + scrub_one_page(&pg[i]);
> + pg[i].count_info &= ~PGC_need_scrub;
> + node_need_scrub[node]--;
> + }
> + }
> +
> + page_list_del(pg, &heap(node, zone, order));
> + merge_and_free_buddy(pg, node, zone, order, false);
Is there actually any merging involved here, i.e. can't you
simply put back the buddy at the list head?
> --- a/xen/include/asm-arm/mm.h
> +++ b/xen/include/asm-arm/mm.h
> @@ -45,6 +45,8 @@ struct page_info
> struct {
> /* Do TLBs need flushing for safety before next page use? */
> bool_t need_tlbflush;
> + /* Set on a buddy head if the buddy has unscrubbed pages. */
> + bool dirty_head;
> } free;
>
> } u;
> @@ -115,6 +117,10 @@ struct page_info
> #define PGC_count_width PG_shift(9)
> #define PGC_count_mask ((1UL<<PGC_count_width)-1)
>
> +/* Page needs to be scrubbed */
> +#define _PGC_need_scrub PG_shift(10)
> +#define PGC_need_scrub PG_mask(1, 10)
This is at least dangerous: You're borrowing a bit from
PGC_count_mask. That's presumably okay because you only
ever set the bit on free pages (and it is being zapped by
alloc_heap_pages() setting ->count_info to PGC_state_inuse),
but I think it would be more explicit that you borrow another bit
if you re-used one of the existing ones (like PGC_allocated), and
then did so by using a straight #define to that other value.
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |