[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