All of lore.kernel.org
 help / color / mirror / Atom feed
From: zhoucm1 <david1.zhou-5C7GfCeVMHo@public.gmane.org>
To: "Christian König"
	<deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>,
	amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
Cc: felix.kuehling-5C7GfCeVMHo@public.gmane.org
Subject: Re: [PATCH 2/2] drm/amdgpu: enable huge page handling in the VM v4
Date: Tue, 18 Jul 2017 10:24:16 +0800	[thread overview]
Message-ID: <596D7150.1080203@amd.com> (raw)
In-Reply-To: <1500325342-26253-2-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>

Still holding on? I thought this patch was pushed in earlier with my RB.

Regards,
David Zhou
On 2017年07月18日 05:02, Christian König wrote:
> From: Christian König <christian.koenig@amd.com>
>
> The hardware can use huge pages to map 2MB of address space with only one PDE.
>
> v2: few cleanups and rebased
> v3: skip PT updates if we are using the PDE
> v4: rebased, added support for CPU based updates
>
> Signed-off-by: Christian König <christian.koenig@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 119 +++++++++++++++++++++++++++------
>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h |   4 ++
>   2 files changed, 103 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> index a3dbebe..62d97f5 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
> @@ -351,6 +351,7 @@ static int amdgpu_vm_alloc_levels(struct amdgpu_device *adev,
>   
>   			entry->bo = pt;
>   			entry->addr = 0;
> +			entry->huge_page = false;
>   		}
>   
>   		if (level < adev->vm_manager.num_level) {
> @@ -1116,7 +1117,8 @@ static int amdgpu_vm_update_level(struct amdgpu_device *adev,
>   
>   		pt = amdgpu_bo_gpu_offset(bo);
>   		pt = amdgpu_gart_get_vm_pde(adev, pt);
> -		if (parent->entries[pt_idx].addr == pt)
> +		if (parent->entries[pt_idx].addr == pt ||
> +		    parent->entries[pt_idx].huge_page)
>   			continue;
>   
>   		parent->entries[pt_idx].addr = pt;
> @@ -1257,29 +1259,95 @@ int amdgpu_vm_update_directories(struct amdgpu_device *adev,
>   }
>   
>   /**
> - * amdgpu_vm_find_pt - find the page table for an address
> + * amdgpu_vm_find_entry - find the entry for an address
>    *
>    * @p: see amdgpu_pte_update_params definition
>    * @addr: virtual address in question
> + * @entry: resulting entry or NULL
> + * @parent: parent entry
>    *
> - * Find the page table BO for a virtual address, return NULL when none found.
> + * Find the vm_pt entry and it's parent for the given address.
>    */
> -static struct amdgpu_bo *amdgpu_vm_get_pt(struct amdgpu_pte_update_params *p,
> -					  uint64_t addr)
> +void amdgpu_vm_get_entry(struct amdgpu_pte_update_params *p, uint64_t addr,
> +			 struct amdgpu_vm_pt **entry,
> +			 struct amdgpu_vm_pt **parent)
>   {
> -	struct amdgpu_vm_pt *entry = &p->vm->root;
>   	unsigned idx, level = p->adev->vm_manager.num_level;
>   
> -	while (entry->entries) {
> +	*parent = NULL;
> +	*entry = &p->vm->root;
> +	while ((*entry)->entries) {
>   		idx = addr >> (p->adev->vm_manager.block_size * level--);
> -		idx %= amdgpu_bo_size(entry->bo) / 8;
> -		entry = &entry->entries[idx];
> +		idx %= amdgpu_bo_size((*entry)->bo) / 8;
> +		*parent = *entry;
> +		*entry = &(*entry)->entries[idx];
>   	}
>   
>   	if (level)
> -		return NULL;
> +		*entry = NULL;
> +}
> +
> +/**
> + * amdgpu_vm_handle_huge_pages - handle updating the PD with huge pages
> + *
> + * @p: see amdgpu_pte_update_params definition
> + * @entry: vm_pt entry to check
> + * @parent: parent entry
> + * @nptes: number of PTEs updated with this operation
> + * @dst: destination address where the PTEs should point to
> + * @flags: access flags fro the PTEs
> + *
> + * Check if we can update the PD with a huge page.
> + */
> +static int amdgpu_vm_handle_huge_pages(struct amdgpu_pte_update_params *p,
> +				       struct amdgpu_vm_pt *entry,
> +				       struct amdgpu_vm_pt *parent,
> +				       unsigned nptes, uint64_t dst,
> +				       uint64_t flags)
> +{
> +	bool use_cpu_update = (p->func == amdgpu_vm_cpu_set_ptes);
> +	uint64_t pd_addr, pde;
> +	int r;
>   
> -	return entry->bo;
> +	/* In the case of a mixed PT the PDE must point to it*/
> +	if (p->adev->asic_type < CHIP_VEGA10 ||
> +	    nptes != AMDGPU_VM_PTE_COUNT(p->adev) ||
> +	    p->func != amdgpu_vm_do_set_ptes ||
> +	    !(flags & AMDGPU_PTE_VALID)) {
> +
> +		dst = amdgpu_bo_gpu_offset(entry->bo);
> +		dst = amdgpu_gart_get_vm_pde(p->adev, dst);
> +		flags = AMDGPU_PTE_VALID;
> +	} else {
> +		flags |= AMDGPU_PDE_PTE;
> +	}
> +
> +	if (entry->addr == dst &&
> +	    entry->huge_page == !!(flags & AMDGPU_PDE_PTE))
> +		return 0;
> +
> +	entry->addr = dst;
> +	entry->huge_page = !!(flags & AMDGPU_PDE_PTE);
> +
> +	if (use_cpu_update) {
> +		r = amdgpu_bo_kmap(parent->bo, (void *)&pd_addr);
> +		if (r)
> +			return r;
> +
> +		pde = pd_addr + (entry - parent->entries) * 8;
> +		amdgpu_vm_cpu_set_ptes(p, pde, dst, 1, 0, flags);
> +	} else {
> +		if (parent->bo->shadow) {
> +			pd_addr = amdgpu_bo_gpu_offset(parent->bo->shadow);
> +			pde = pd_addr + (entry - parent->entries) * 8;
> +			amdgpu_vm_do_set_ptes(p, pde, dst, 1, 0, flags);
> +		}
> +		pd_addr = amdgpu_bo_gpu_offset(parent->bo);
> +		pde = pd_addr + (entry - parent->entries) * 8;
> +		amdgpu_vm_do_set_ptes(p, pde, dst, 1, 0, flags);
> +	}
> +
> +	return 0;
>   }
>   
>   /**
> @@ -1306,22 +1374,31 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
>   	struct amdgpu_bo *pt;
>   	unsigned nptes;
>   	bool use_cpu_update = (params->func == amdgpu_vm_cpu_set_ptes);
> -
> +	int r;
>   
>   	/* walk over the address space and update the page tables */
> -	for (addr = start; addr < end; addr += nptes) {
> -		pt = amdgpu_vm_get_pt(params, addr);
> -		if (!pt) {
> -			pr_err("PT not found, aborting update_ptes\n");
> -			return -EINVAL;
> -		}
> +	for (addr = start; addr < end; addr += nptes,
> +	     dst += nptes * AMDGPU_GPU_PAGE_SIZE) {
> +		struct amdgpu_vm_pt *entry, *parent;
> +
> +		amdgpu_vm_get_entry(params, addr, &entry, &parent);
> +		if (!entry)
> +			return -ENOENT;
>   
>   		if ((addr & ~mask) == (end & ~mask))
>   			nptes = end - addr;
>   		else
>   			nptes = AMDGPU_VM_PTE_COUNT(adev) - (addr & mask);
>   
> +		r = amdgpu_vm_handle_huge_pages(params, entry, parent,
> +						nptes, dst, flags);
> +		if (r)
> +			return r;
>   
> +		if (entry->huge_page)
> +			continue;
> +
> +		pt = entry->bo;
>   		if (use_cpu_update) {
>   			pe_start = (unsigned long)pt->kptr;
>   		} else {
> @@ -1337,8 +1414,6 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
>   		pe_start += (addr & mask) * 8;
>   		params->func(params, pe_start, dst, nptes,
>   			     AMDGPU_GPU_PAGE_SIZE, flags);
> -
> -		dst += nptes * AMDGPU_GPU_PAGE_SIZE;
>   	}
>   
>   	return 0;
> @@ -1490,6 +1565,9 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
>   	/* padding, etc. */
>   	ndw = 64;
>   
> +	/* one PDE write for each huge page */
> +	ndw += ((nptes >> adev->vm_manager.block_size) + 1) * 7;
> +
>   	if (src) {
>   		/* only copy commands needed */
>   		ndw += ncmds * 7;
> @@ -1569,6 +1647,7 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
>   
>   error_free:
>   	amdgpu_job_free(job);
> +	amdgpu_vm_invalidate_level(&vm->root);
>   	return r;
>   }
>   
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> index c4f5d1f..34d9174 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
> @@ -70,6 +70,9 @@ struct amdgpu_bo_list_entry;
>   /* TILED for VEGA10, reserved for older ASICs  */
>   #define AMDGPU_PTE_PRT		(1ULL << 51)
>   
> +/* PDE is handled as PTE for VEGA10 */
> +#define AMDGPU_PDE_PTE		(1ULL << 54)
> +
>   /* VEGA10 only */
>   #define AMDGPU_PTE_MTYPE(a)    ((uint64_t)a << 57)
>   #define AMDGPU_PTE_MTYPE_MASK	AMDGPU_PTE_MTYPE(3ULL)
> @@ -100,6 +103,7 @@ struct amdgpu_bo_list_entry;
>   struct amdgpu_vm_pt {
>   	struct amdgpu_bo	*bo;
>   	uint64_t		addr;
> +	bool			huge_page;
>   
>   	/* array of page tables, one for each directory entry */
>   	struct amdgpu_vm_pt	*entries;

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

  parent reply	other threads:[~2017-07-18  2:24 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-17 21:02 [PATCH 1/2] drm/amdgpu: increase fragmentation size for Vega10 v2 Christian König
     [not found] ` <1500325342-26253-1-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
2017-07-17 21:02   ` [PATCH 2/2] drm/amdgpu: enable huge page handling in the VM v4 Christian König
     [not found]     ` <1500325342-26253-2-git-send-email-deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
2017-07-17 21:21       ` StDenis, Tom
     [not found]         ` <BN6PR1201MB0065BFD8FAAAD1EFFD4E23E9F7A00-6iU6OBHu2P9OVrXVbVH+K2rFom/aUZj6nBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2017-07-17 21:27           ` Christian König
2017-07-17 21:30       ` Felix Kuehling
     [not found]         ` <c2b1e857-67c1-fd51-adf4-c4f84ea37368-5C7GfCeVMHo@public.gmane.org>
2017-07-17 21:31           ` Christian König
2017-07-18  2:24       ` zhoucm1 [this message]
     [not found]         ` <596D7150.1080203-5C7GfCeVMHo@public.gmane.org>
2017-07-18 13:54           ` Christian König
     [not found]             ` <d8a5081e-24cb-0751-e4fc-d4a9e09cfa9d-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org>
2017-07-18 18:56               ` Felix Kuehling
     [not found]                 ` <afaf4a12-a3fc-1178-03f6-7faf930874af-5C7GfCeVMHo@public.gmane.org>
2017-07-19 15:28                   ` Christian König

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=596D7150.1080203@amd.com \
    --to=david1.zhou-5c7gfcevmho@public.gmane.org \
    --cc=amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    --cc=deathsimple-ANTagKRnAhcb1SvskN2V4Q@public.gmane.org \
    --cc=felix.kuehling-5C7GfCeVMHo@public.gmane.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.