[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v2 1/9] mm: Separate free page chunk merging into its own routine



>>> On 04.04.17 at 15:48, <boris.ostrovsky@xxxxxxxxxx> wrote:
> On 04/04/2017 07:16 AM, Jan Beulich wrote:
>>>>> On 03.04.17 at 18:50, <boris.ostrovsky@xxxxxxxxxx> wrote:
>>> --- a/xen/common/page_alloc.c
>>> +++ b/xen/common/page_alloc.c
>>> @@ -924,11 +924,64 @@ static int reserve_offlined_page(struct page_info 
>>> *head)
>>>      return count;
>>>  }
>>>  
>>> +static bool_t can_merge(struct page_info *buddy, unsigned int node,
>> Plain bool please, and const for the pointer.
> 
> Wei asked for that too but it wasn't clear to me what the hypervisor
> preference is. We currently have much higher use of bool_t than bool
> (1015 vs 321, according to cscope). page_alloc.c uses only the former.

That's because in this release cycle we've only started the transition.

>>> +{
>>> +    if ( !mfn_valid(_mfn(page_to_mfn(buddy))) ||
>>> +         !page_state_is(buddy, free) ||
>> As a helper of freeing, this is fine, but then the name of both
>> functions is too generic: Fundamentally certain other page types
>> might be mergeable too.
> 
> merge_free_chunks()/can_merge_free() ?

Fine with me.

>>> +         (PFN_ORDER(buddy) != order) ||
>>> +         (phys_to_nid(page_to_maddr(buddy)) != node) )
>>> +        return false;
>>> +
>>> +    return true;
>> Is there any reason not to make this a single return statement? I
>> don't think it would be any worse to read.
> 
> See patches 2 and 7, where more checks are added. While those two might
> be merged (they both deal with scrubbing) , combining all 3 of them into
> a single statement would make it a bit difficult to read IMO.

Okay, likely makes sense (didn't get that far yet).

>>> +static struct page_info *merge_chunks(struct page_info *pg, unsigned int 
>>> node,
>>> +                                      unsigned int zone, unsigned int 
>>> order)
>>> +{
>>> +    ASSERT(spin_is_locked(&heap_lock));
>>> +
>>> +    /* Merge chunks as far as possible. */
>>> +    while ( order < MAX_ORDER )
>>> +    {
>>> +        unsigned long mask = 1UL << order;
>>> +        struct page_info *buddy;
>>> +
>>> +        if ( (page_to_mfn(pg) & mask) )
>>> +        {
>>> +            /* Merge with predecessor block? */
>>> +            buddy = pg - mask;
>>> +            if ( !can_merge(buddy, node, order) )
>>> +                break;
>>> +
>>> +            pg = buddy;
>>> +            page_list_del(pg, &heap(node, zone, order));
>>> +        }
>>> +        else
>>> +        {
>>> +            /* Merge with successor block? */
>>> +            buddy = pg + mask;
>>> +            if ( !can_merge(buddy, node, order) )
>>> +                break;
>>> +
>>> +            page_list_del(buddy, &heap(node, zone, order));
>> This and its companion in the if() branch are now the same (taking
>> into account the assignment ahead of the former) - please move
>> them past the if/else.
>>
>>> +        }
>>> +
>>> +        order++;
>>> +    }
>>> +
>>> +    PFN_ORDER(pg) = order;
>>> +    page_list_add_tail(pg, &heap(node, zone, order));
>> I don't think this strictly is part of the merge anymore, so judging
>> by the name of the function this last line would rather belong into
>> the caller.
> 
> All users of merge_chunks() want to place the new chunk back into the
> heap and I don't think I see why anyone would want to just get the new
> buddy without putting it there.

I understand that, yet the name of the function says otherwise.
At the very least I'd expect a comment right ahead of the function
to state this. Or maybe, as a slight variation of the new name you
suggest above, free_merged_chunks() (merge_chunk_sand_free()
or some such would look ugly to me)?

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.