[PATCH 2/2] drm/ttm: add ttm page_flags TTM_PAGE_FLAG_PAGEFAULT

Chunming Zhou zhoucm1 at amd.com
Wed Jan 31 07:53:33 UTC 2018



On 2018年01月29日 16:31, Roger He wrote:
> to indicate whether we are serving for page fault routine when in
> ttm_mem_global_reserve.
>
> for ttm_mem_global_reserve if in page fault routine, allow success
> always. because page fault routing already grabbed system memory
> successfully and allow this exception is harmless.
> Otherwise, it will trigger OOM killer.
>
> v2: add new page flag TTM_PAGE_FLAG_PAGEFAULT rather than using
> struct ttm_operation_ctx
>
> Signed-off-by: Roger He <Hongbo.He at amd.com>
> ---
>   drivers/gpu/drm/ttm/ttm_bo_vm.c          |  6 ++++--
>   drivers/gpu/drm/ttm/ttm_memory.c         | 27 +++++++++++++++++++--------
>   drivers/gpu/drm/ttm/ttm_page_alloc.c     |  5 ++++-
>   drivers/gpu/drm/ttm/ttm_page_alloc_dma.c |  9 ++++++---
>   drivers/gpu/drm/ttm/ttm_tt.c             |  2 +-
>   include/drm/ttm/ttm_bo_driver.h          |  1 +
>   include/drm/ttm/ttm_memory.h             |  3 ++-
>   7 files changed, 37 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c
> index 08a3c32..1aee124 100644
> --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c
> +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c
> @@ -235,9 +235,11 @@ static int ttm_bo_vm_fault(struct vm_fault *vmf)
>   		ttm = bo->ttm;
>   		cvma.vm_page_prot = ttm_io_prot(bo->mem.placement,
>   						cvma.vm_page_prot);
> -
> +		ttm->page_flags |= TTM_PAGE_FLAG_PAGEFAULT;
>   		/* Allocate all page at once, most common usage */
> -		if (ttm->bdev->driver->ttm_tt_populate(ttm, &ctx)) {
> +		ret = ttm->bdev->driver->ttm_tt_populate(ttm, &ctx);
> +		ttm->page_flags &= ~TTM_PAGE_FLAG_PAGEFAULT;
> +		if (ret) {
>   			retval = VM_FAULT_OOM;
>   			goto out_io_unlock;
>   		}
> diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c
> index 06024ba..d0312a7 100644
> --- a/drivers/gpu/drm/ttm/ttm_memory.c
> +++ b/drivers/gpu/drm/ttm/ttm_memory.c
> @@ -473,7 +473,8 @@ EXPORT_SYMBOL(ttm_mem_global_free);
>   
>   static int ttm_mem_global_reserve(struct ttm_mem_global *glob,
>   				  struct ttm_mem_zone *single_zone,
> -				  uint64_t amount, bool reserve)
> +				  uint64_t amount, bool reserve,
> +				  bool in_pagefault)
>   {
>   	uint64_t swap_glob_mem, max_swap_cache;
>   	uint64_t limit, total_used_mem;
> @@ -485,6 +486,13 @@ static int ttm_mem_global_reserve(struct ttm_mem_global *glob,
>   	max_swap_cache = (get_total_swap_pages() >> 1) << PAGE_SHIFT;
>   
>   	spin_lock(&glob->lock);
> +	/*
> +	 * if in page_fault allow reserve successfully anyway since it
> +	 * already allocated system pages. Otherwise it will trigger OOM
> +	 */
> +	if (in_pagefault)
> +		goto reserve_direct;
> +
>   	for (i = 0; i < glob->num_zones; ++i) {
>   		zone = glob->zones[i];
>   		if (single_zone && zone != single_zone)
> @@ -499,6 +507,7 @@ static int ttm_mem_global_reserve(struct ttm_mem_global *glob,
>   			goto out_unlock;
>   	}
>   
> +reserve_direct:
>   	if (reserve) {
>   		for (i = 0; i < glob->num_zones; ++i) {
>   			zone = glob->zones[i];
> @@ -520,13 +529,13 @@ static int ttm_mem_global_reserve(struct ttm_mem_global *glob,
>   static int ttm_mem_global_alloc_zone(struct ttm_mem_global *glob,
>   				     struct ttm_mem_zone *single_zone,
>   				     uint64_t memory,
> -				     struct ttm_operation_ctx *ctx)
> +				     struct ttm_operation_ctx *ctx,
> +				     bool in_pagefault)
>   {
>   	int count = TTM_MEMORY_ALLOC_RETRIES;
>   
> -	while (unlikely(ttm_mem_global_reserve(glob,
> -					       single_zone,
> -					       memory, true)
> +	while (unlikely(ttm_mem_global_reserve(glob, single_zone, memory,
> +					       true, in_pagefault)
>   			!= 0)) {
>   		if (ctx->no_wait_gpu)
>   			return -ENOMEM;
> @@ -546,13 +555,14 @@ int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory,
>   	 * all zones.
>   	 */
>   
> -	return ttm_mem_global_alloc_zone(glob, NULL, memory, ctx);
> +	return ttm_mem_global_alloc_zone(glob, NULL, memory, ctx, false);
>   }
>   EXPORT_SYMBOL(ttm_mem_global_alloc);
>   
>   int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,
>   			      struct page *page, uint64_t size,
> -			      struct ttm_operation_ctx *ctx)
> +			      struct ttm_operation_ctx *ctx,
> +			      bool in_pagefault)
>   {
>   	struct ttm_mem_zone *zone = NULL;
>   
> @@ -568,7 +578,8 @@ int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,
>   	if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL)
>   		zone = glob->zone_kernel;
>   #endif
> -	return ttm_mem_global_alloc_zone(glob, zone, size, ctx);
> +	return ttm_mem_global_alloc_zone(glob, zone, size,
> +					 ctx, in_pagefault);
>   }
>   
>   void ttm_mem_global_free_page(struct ttm_mem_global *glob, struct page *page,
> diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c
> index 5edcd89..39b184f 100644
> --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c
> +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c
> @@ -1094,6 +1094,7 @@ ttm_pool_unpopulate_helper(struct ttm_tt *ttm, unsigned mem_count_update)
>   int ttm_pool_populate(struct ttm_tt *ttm, struct ttm_operation_ctx *ctx)
>   {
>   	struct ttm_mem_global *mem_glob = ttm->glob->mem_glob;
> +	bool in_pagefault;
>   	unsigned i;
>   	int ret;
>   
> @@ -1107,9 +1108,11 @@ int ttm_pool_populate(struct ttm_tt *ttm, struct ttm_operation_ctx *ctx)
>   		return ret;
>   	}
>   
> +	in_pagefault = ttm->page_flags | TTM_PAGE_FLAG_PAGEFAULT;
I guess you want to write as "in_pagefault = ttm->page_flags & 
TTM_PAGE_FLAG_PAGEFAULT; ".

>   	for (i = 0; i < ttm->num_pages; ++i) {
>   		ret = ttm_mem_global_alloc_page(mem_glob, ttm->pages[i],
> -						PAGE_SIZE, ctx);
> +						PAGE_SIZE, ctx,
> +						in_pagefault);
>   		if (unlikely(ret != 0)) {
>   			ttm_pool_unpopulate_helper(ttm, i);
>   			return -ENOMEM;
> diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
> index 9e90d0e..77dd167 100644
> --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
> +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
> @@ -939,6 +939,7 @@ int ttm_dma_populate(struct ttm_dma_tt *ttm_dma, struct device *dev,
>   	struct dma_pool *pool;
>   	struct dma_page *d_page;
>   	enum pool_type type;
> +	bool in_pagefault;
>   	unsigned i;
>   	int ret;
>   
> @@ -948,8 +949,8 @@ int ttm_dma_populate(struct ttm_dma_tt *ttm_dma, struct device *dev,
>   	INIT_LIST_HEAD(&ttm_dma->pages_list);
>   	i = 0;
>   
> +	in_pagefault = ttm_dma->ttm.page_flags | TTM_PAGE_FLAG_PAGEFAULT;
same above, should be "in_pagefault = ttm->page_flags & 
TTM_PAGE_FLAG_PAGEFAULT; ".

Regards,
David Zhou
>   	type = ttm_to_type(ttm->page_flags, ttm->caching_state);
> -
>   #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>   	if (ttm->page_flags & TTM_PAGE_FLAG_DMA32)
>   		goto skip_huge;
> @@ -971,7 +972,8 @@ int ttm_dma_populate(struct ttm_dma_tt *ttm_dma, struct device *dev,
>   			break;
>   
>   		ret = ttm_mem_global_alloc_page(mem_glob, ttm->pages[i],
> -						pool->size, ctx);
> +						pool->size, ctx,
> +						in_pagefault);
>   		if (unlikely(ret != 0)) {
>   			ttm_dma_unpopulate(ttm_dma, dev);
>   			return -ENOMEM;
> @@ -1008,7 +1010,8 @@ int ttm_dma_populate(struct ttm_dma_tt *ttm_dma, struct device *dev,
>   		}
>   
>   		ret = ttm_mem_global_alloc_page(mem_glob, ttm->pages[i],
> -						pool->size, ctx);
> +						pool->size, ctx,
> +						in_pagefault);
>   		if (unlikely(ret != 0)) {
>   			ttm_dma_unpopulate(ttm_dma, dev);
>   			return -ENOMEM;
> diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
> index 395cac0..c36db66 100644
> --- a/drivers/gpu/drm/ttm/ttm_tt.c
> +++ b/drivers/gpu/drm/ttm/ttm_tt.c
> @@ -386,7 +386,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage)
>   		ttm->page_flags |= TTM_PAGE_FLAG_PERSISTENT_SWAP;
>   	else
>   		atomic64_add_return(ttm->num_pages << PAGE_SHIFT,
> -			    &ttm->glob->mem_glob->swap_glob_mem);
> +				    &ttm->glob->mem_glob->swap_glob_mem);
>   
>   	return 0;
>   out_err:
> diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
> index 9b417eb..8f68781 100644
> --- a/include/drm/ttm/ttm_bo_driver.h
> +++ b/include/drm/ttm/ttm_bo_driver.h
> @@ -87,6 +87,7 @@ struct ttm_backend_func {
>   #define TTM_PAGE_FLAG_DMA32           (1 << 7)
>   #define TTM_PAGE_FLAG_SG              (1 << 8)
>   #define TTM_PAGE_FLAG_NO_RETRY	      (1 << 9)
> +#define TTM_PAGE_FLAG_PAGEFAULT       (1 << 10)
>   
>   enum ttm_caching_state {
>   	tt_uncached,
> diff --git a/include/drm/ttm/ttm_memory.h b/include/drm/ttm/ttm_memory.h
> index a273581..b801010 100644
> --- a/include/drm/ttm/ttm_memory.h
> +++ b/include/drm/ttm/ttm_memory.h
> @@ -87,7 +87,8 @@ extern void ttm_mem_global_free(struct ttm_mem_global *glob,
>   				uint64_t amount);
>   extern int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,
>   				     struct page *page, uint64_t size,
> -				     struct ttm_operation_ctx *ctx);
> +				     struct ttm_operation_ctx *ctx,
> +				     bool in_pagefault);
>   extern void ttm_mem_global_free_page(struct ttm_mem_global *glob,
>   				     struct page *page, uint64_t size);
>   extern size_t ttm_round_pot(size_t size);



More information about the dri-devel mailing list