linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Nathan Fontenot <nfont@linux.vnet.ibm.com>
To: Li Zhong <zhong@linux.vnet.ibm.com>, linuxppc-dev@lists.ozlabs.org
Cc: paulus@samba.org
Subject: Re: [PATCH 1/4] powerpc: implement vmemmap_list_free()
Date: Thu, 24 Jul 2014 10:11:43 -0500	[thread overview]
Message-ID: <53D1222F.7010900@linux.vnet.ibm.com> (raw)
In-Reply-To: <1402475019-19699-1-git-send-email-zhong@linux.vnet.ibm.com>

On 06/11/2014 03:23 AM, Li Zhong wrote:
> This patch implements vmemmap_list_free() for vmemmap_free().
> 
> The freed entries will be removed from vmemmap_list, and form a freed list,
> with next as the header. The next position in the last allocated page is kept
> at the list tail.
> 
> When allocation, if there are freed entries left, get it from the freed list;
> if no freed entries left, get it like before from the last allocated pages.
> 
> With this change, realmode_pfn_to_page() also needs to be changed to walk
> all the entries in the vmemmap_list, as the virt_addr of the entries might not
> be stored in order anymore.
> 
> It helps to reuse the memory when continuous doing memory hot-plug/remove
> operations, but didn't reclaim the pages already allocated, so the memory usage
> will only increase, but won't exceed the value for the largest memory
> configuration.
> 
> Signed-off-by: Li Zhong <zhong@linux.vnet.ibm.com>
> Cc: Nathan Fontenot <nfont@linux.vnet.ibm.com>

Acked-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>

> ---
>  arch/powerpc/mm/init_64.c |   62 +++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 52 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
> index e3734ed..fa5d28b 100644
> --- a/arch/powerpc/mm/init_64.c
> +++ b/arch/powerpc/mm/init_64.c
> @@ -226,14 +226,24 @@ static void __meminit vmemmap_create_mapping(unsigned long start,
>  #endif /* CONFIG_PPC_BOOK3E */
>  
>  struct vmemmap_backing *vmemmap_list;
> +static struct vmemmap_backing *next;
> +static int num_left;
> +static int num_freed;
>  
>  static __meminit struct vmemmap_backing * vmemmap_list_alloc(int node)
>  {
> -	static struct vmemmap_backing *next;
> -	static int num_left;
> +	struct vmemmap_backing *vmem_back;
> +	/* get from freed entries first */
> +	if (num_freed) {
> +		num_freed--;
> +		vmem_back = next;
> +		next = next->list;
> +
> +		return vmem_back;
> +	}
>  
>  	/* allocate a page when required and hand out chunks */
> -	if (!next || !num_left) {
> +	if (!num_left) {
>  		next = vmemmap_alloc_block(PAGE_SIZE, node);
>  		if (unlikely(!next)) {
>  			WARN_ON(1);
> @@ -266,6 +276,38 @@ static __meminit void vmemmap_list_populate(unsigned long phys,
>  	vmemmap_list = vmem_back;
>  }
>  
> +static unsigned long vmemmap_list_free(unsigned long start)
> +{
> +	struct vmemmap_backing *vmem_back, *vmem_back_prev;
> +
> +	vmem_back_prev = vmem_back = vmemmap_list;
> +
> +	/* look for it with prev pointer recorded */
> +	for (; vmem_back; vmem_back = vmem_back->list) {
> +		if (vmem_back->virt_addr == start)
> +			break;
> +		vmem_back_prev = vmem_back;
> +	}
> +
> +	if (unlikely(!vmem_back)) {
> +		WARN_ON(1);
> +		return 0;
> +	}
> +
> +	/* remove it from vmemmap_list */
> +	if (vmem_back == vmemmap_list) /* remove head */
> +		vmemmap_list = vmem_back->list;
> +	else
> +		vmem_back_prev->list = vmem_back->list;
> +
> +	/* next point to this freed entry */
> +	vmem_back->list = next;
> +	next = vmem_back;
> +	num_freed++;
> +
> +	return vmem_back->phys;
> +}
> +
>  int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
>  {
>  	unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift;
> @@ -331,16 +373,16 @@ struct page *realmode_pfn_to_page(unsigned long pfn)
>  		if (pg_va < vmem_back->virt_addr)
>  			continue;
>  
> -		/* Check that page struct is not split between real pages */
> -		if ((pg_va + sizeof(struct page)) >
> -				(vmem_back->virt_addr + page_size))
> -			return NULL;
> -
> -		page = (struct page *) (vmem_back->phys + pg_va -
> +		/* After vmemmap_list entry free is possible, need check all */
> +		if ((pg_va + sizeof(struct page)) <=
> +				(vmem_back->virt_addr + page_size)) {
> +			page = (struct page *) (vmem_back->phys + pg_va -
>  				vmem_back->virt_addr);
> -		return page;
> +			return page;
> +		}
>  	}
>  
> +	/* Probably that page struct is split between real pages */
>  	return NULL;
>  }
>  EXPORT_SYMBOL_GPL(realmode_pfn_to_page);
> 

      parent reply	other threads:[~2014-07-24 15:11 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-11  8:23 [PATCH 1/4] powerpc: implement vmemmap_list_free() Li Zhong
2014-06-11  8:23 ` [PATCH 2/4] powerpc: implement vmemmap_remove_mapping() for BOOK3S Li Zhong
2014-07-24 15:12   ` Nathan Fontenot
2014-06-11  8:23 ` [PATCH 3/4] powerpc: implement vmemmap_free() Li Zhong
2014-07-24 15:12   ` Nathan Fontenot
2014-06-11  8:23 ` [PATCH 4/4] powerpc: start loop at section start of start in vmemmap_populated() Li Zhong
2014-07-24 15:13   ` Nathan Fontenot
2014-07-24 15:11 ` Nathan Fontenot [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=53D1222F.7010900@linux.vnet.ibm.com \
    --to=nfont@linux.vnet.ibm.com \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=paulus@samba.org \
    --cc=zhong@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).