All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/5] drm/ttm: add max_swap_mem in ttm_mem_global
@ 2018-02-02  7:22 Roger He
  2018-02-02  7:22 ` [PATCH 2/5] drm/ttm: add swap_glob_mem " Roger He
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Roger He @ 2018-02-02  7:22 UTC (permalink / raw)
  To: dri-devel; +Cc: Roger He, Christian.Koenig

set its initial value as 1/2 * free swap cache size when module initial.
and adjust this value when allocate TTM memory

Signed-off-by: Roger He <Hongbo.He@amd.com>
---
 drivers/gpu/drm/ttm/ttm_memory.c | 10 ++++++++--
 include/drm/ttm/ttm_memory.h     |  2 ++
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c
index aa0c381..b48931d 100644
--- a/drivers/gpu/drm/ttm/ttm_memory.c
+++ b/drivers/gpu/drm/ttm/ttm_memory.c
@@ -36,6 +36,7 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/swap.h>
 
 #define TTM_MEMORY_ALLOC_RETRIES 4
 
@@ -372,9 +373,9 @@ int ttm_mem_global_init(struct ttm_mem_global *glob)
 		kobject_put(&glob->kobj);
 		return ret;
 	}
-
+	/* set it as 1/2 * swap free space we can get at that time */
+	glob->max_swap_mem = get_nr_swap_pages() << (PAGE_SHIFT - 1);
 	si_meminfo(&si);
-
 	ret = ttm_mem_init_kernel_zone(glob, &si);
 	if (unlikely(ret != 0))
 		goto out_no_zone;
@@ -473,12 +474,17 @@ static int ttm_mem_global_reserve(struct ttm_mem_global *glob,
 				  struct ttm_mem_zone *single_zone,
 				  uint64_t amount, bool reserve)
 {
+	uint64_t free_swap_mem = get_nr_swap_pages() << (PAGE_SHIFT - 1);
 	uint64_t limit;
 	int ret = -ENOMEM;
 	unsigned int i;
 	struct ttm_mem_zone *zone;
 
 	spin_lock(&glob->lock);
+	/* adjust the max_swap_mem to cover the new inserted swap space */
+	if (glob->max_swap_mem < free_swap_mem)
+		glob->max_swap_mem = free_swap_mem;
+
 	for (i = 0; i < glob->num_zones; ++i) {
 		zone = glob->zones[i];
 		if (single_zone && zone != single_zone)
diff --git a/include/drm/ttm/ttm_memory.h b/include/drm/ttm/ttm_memory.h
index 8936285..ad5a557 100644
--- a/include/drm/ttm/ttm_memory.h
+++ b/include/drm/ttm/ttm_memory.h
@@ -49,6 +49,7 @@
  * @work: The workqueue callback for the shrink queue.
  * @lock: Lock to protect the @shrink - and the memory accounting members,
  * that is, essentially the whole structure with some exceptions.
+ * @max_swap_mem: upper limit of swap space TTM can use
  * @zones: Array of pointers to accounting zones.
  * @num_zones: Number of populated entries in the @zones array.
  * @zone_kernel: Pointer to the kernel zone.
@@ -67,6 +68,7 @@ struct ttm_mem_global {
 	struct workqueue_struct *swap_queue;
 	struct work_struct work;
 	spinlock_t lock;
+	uint64_t max_swap_mem;
 	struct ttm_mem_zone *zones[TTM_MEM_MAX_ZONES];
 	unsigned int num_zones;
 	struct ttm_mem_zone *zone_kernel;
-- 
2.7.4

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/5] drm/ttm: add swap_glob_mem in ttm_mem_global
  2018-02-02  7:22 [PATCH 1/5] drm/ttm: add max_swap_mem in ttm_mem_global Roger He
@ 2018-02-02  7:22 ` Roger He
  2018-02-02  7:22 ` [PATCH 3/5] drm/ttm: add ttm page_flags TTM_PAGE_FLAG_PAGEFAULT Roger He
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Roger He @ 2018-02-02  7:22 UTC (permalink / raw)
  To: dri-devel; +Cc: Roger He, Christian.Koenig

separate swapped memory account from zone->used_mem because swapped
ttm pages can be flushed into SWAP disk/file under high memory pressure.

add check conditon in ttm_mem_global_reserve to prevent triggering OOM.
because if swap space is full, all swapped ttm pages would stay in
system memory which can't be flushed into swap space.

Signed-off-by: Roger He <Hongbo.He@amd.com>
---
 drivers/gpu/drm/ttm/ttm_memory.c | 12 ++++++++----
 drivers/gpu/drm/ttm/ttm_tt.c     | 13 +++++++++++--
 include/drm/ttm/ttm_memory.h     |  2 ++
 3 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c
index b48931d..598b14b 100644
--- a/drivers/gpu/drm/ttm/ttm_memory.c
+++ b/drivers/gpu/drm/ttm/ttm_memory.c
@@ -197,7 +197,6 @@ static bool ttm_zones_above_swap_target(struct ttm_mem_global *glob,
 			target = zone->max_mem;
 
 		target = (extra > target) ? 0ULL : target;
-
 		if (zone->used_mem > target)
 			return true;
 	}
@@ -375,6 +374,7 @@ int ttm_mem_global_init(struct ttm_mem_global *glob)
 	}
 	/* set it as 1/2 * swap free space we can get at that time */
 	glob->max_swap_mem = get_nr_swap_pages() << (PAGE_SHIFT - 1);
+	atomic64_set(&glob->swap_glob_mem, 0);
 	si_meminfo(&si);
 	ret = ttm_mem_init_kernel_zone(glob, &si);
 	if (unlikely(ret != 0))
@@ -475,10 +475,12 @@ static int ttm_mem_global_reserve(struct ttm_mem_global *glob,
 				  uint64_t amount, bool reserve)
 {
 	uint64_t free_swap_mem = get_nr_swap_pages() << (PAGE_SHIFT - 1);
-	uint64_t limit;
+	uint64_t swap_glob_mem, limit, total_used_mem;
+	struct ttm_mem_zone *zone;
 	int ret = -ENOMEM;
 	unsigned int i;
-	struct ttm_mem_zone *zone;
+
+	swap_glob_mem = atomic64_read(&glob->swap_glob_mem);
 
 	spin_lock(&glob->lock);
 	/* adjust the max_swap_mem to cover the new inserted swap space */
@@ -493,7 +495,9 @@ static int ttm_mem_global_reserve(struct ttm_mem_global *glob,
 		limit = (capable(CAP_SYS_ADMIN)) ?
 			zone->emer_mem : zone->max_mem;
 
-		if (zone->used_mem > limit)
+		total_used_mem = zone->used_mem + swap_glob_mem;
+		limit += glob->max_swap_mem;
+		if (total_used_mem > limit)
 			goto out_unlock;
 	}
 
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index 95a77da..5d441e0 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -183,8 +183,11 @@ void ttm_tt_destroy(struct ttm_tt *ttm)
 		ttm_tt_unpopulate(ttm);
 
 	if (!(ttm->page_flags & TTM_PAGE_FLAG_PERSISTENT_SWAP) &&
-	    ttm->swap_storage)
+	    ttm->swap_storage) {
 		fput(ttm->swap_storage);
+		atomic64_sub_return(ttm->num_pages << PAGE_SHIFT,
+				    &ttm->glob->mem_glob->swap_glob_mem);
+	}
 
 	ttm->swap_storage = NULL;
 	ttm->func->destroy(ttm);
@@ -322,8 +325,11 @@ int ttm_tt_swapin(struct ttm_tt *ttm)
 		put_page(from_page);
 	}
 
-	if (!(ttm->page_flags & TTM_PAGE_FLAG_PERSISTENT_SWAP))
+	if (!(ttm->page_flags & TTM_PAGE_FLAG_PERSISTENT_SWAP)) {
 		fput(swap_storage);
+		atomic64_sub_return(ttm->num_pages << PAGE_SHIFT,
+				    &ttm->glob->mem_glob->swap_glob_mem);
+	}
 	ttm->swap_storage = NULL;
 	ttm->page_flags &= ~TTM_PAGE_FLAG_SWAPPED;
 
@@ -383,6 +389,9 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage)
 	ttm->page_flags |= TTM_PAGE_FLAG_SWAPPED;
 	if (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);
 
 	return 0;
 out_err:
diff --git a/include/drm/ttm/ttm_memory.h b/include/drm/ttm/ttm_memory.h
index ad5a557..6282b50 100644
--- a/include/drm/ttm/ttm_memory.h
+++ b/include/drm/ttm/ttm_memory.h
@@ -50,6 +50,7 @@
  * @lock: Lock to protect the @shrink - and the memory accounting members,
  * that is, essentially the whole structure with some exceptions.
  * @max_swap_mem: upper limit of swap space TTM can use
+ * @swap_glob_mem: total size of ttm pages which have been swapped out
  * @zones: Array of pointers to accounting zones.
  * @num_zones: Number of populated entries in the @zones array.
  * @zone_kernel: Pointer to the kernel zone.
@@ -69,6 +70,7 @@ struct ttm_mem_global {
 	struct work_struct work;
 	spinlock_t lock;
 	uint64_t max_swap_mem;
+	atomic64_t swap_glob_mem;
 	struct ttm_mem_zone *zones[TTM_MEM_MAX_ZONES];
 	unsigned int num_zones;
 	struct ttm_mem_zone *zone_kernel;
-- 
2.7.4

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/5] drm/ttm: add ttm page_flags TTM_PAGE_FLAG_PAGEFAULT
  2018-02-02  7:22 [PATCH 1/5] drm/ttm: add max_swap_mem in ttm_mem_global Roger He
  2018-02-02  7:22 ` [PATCH 2/5] drm/ttm: add swap_glob_mem " Roger He
@ 2018-02-02  7:22 ` Roger He
  2018-02-02  7:42   ` Christian König
  2018-02-02  7:22 ` [PATCH 4/5] drm/ttm: if need_dma32 is not set, actually no need dma32 zone at all Roger He
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Roger He @ 2018-02-02  7:22 UTC (permalink / raw)
  To: dri-devel; +Cc: Roger He, Christian.Koenig

to indicate whether we are servicing for page fault routine 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: fix minor typo
v3: keep original behavior except ttm page with flag NO_RETRY

Signed-off-by: Roger He <Hongbo.He@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, 38 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c
index 716e724..f03dd94 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_vm.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c
@@ -233,8 +233,12 @@ static int ttm_bo_vm_fault(struct vm_fault *vmf)
 		cvma.vm_page_prot = ttm_io_prot(bo->mem.placement,
 						cvma.vm_page_prot);
 
+		if (ttm->page_flags & TTM_PAGE_FLAG_NO_RETRY)
+			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) {
 			ret = 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 598b14b..f5227a5 100644
--- a/drivers/gpu/drm/ttm/ttm_memory.c
+++ b/drivers/gpu/drm/ttm/ttm_memory.c
@@ -472,7 +472,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 free_swap_mem = get_nr_swap_pages() << (PAGE_SHIFT - 1);
 	uint64_t swap_glob_mem, limit, total_used_mem;
@@ -483,6 +484,13 @@ static int ttm_mem_global_reserve(struct ttm_mem_global *glob,
 	swap_glob_mem = atomic64_read(&glob->swap_glob_mem);
 
 	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;
+
 	/* adjust the max_swap_mem to cover the new inserted swap space */
 	if (glob->max_swap_mem < free_swap_mem)
 		glob->max_swap_mem = free_swap_mem;
@@ -501,6 +509,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];
@@ -522,13 +531,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;
@@ -548,13 +557,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;
 
@@ -570,7 +580,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..15bf691 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;
 	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 b122f6e..b8adf37 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
@@ -934,6 +934,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;
 
@@ -943,8 +944,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;
 	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;
@@ -966,7 +967,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;
@@ -1003,7 +1005,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 5d441e0..a730cd6 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -391,7 +391,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 6282b50..6c29b5c 100644
--- a/include/drm/ttm/ttm_memory.h
+++ b/include/drm/ttm/ttm_memory.h
@@ -89,7 +89,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);
-- 
2.7.4

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/5] drm/ttm: if need_dma32 is not set, actually no need dma32 zone at all.
  2018-02-02  7:22 [PATCH 1/5] drm/ttm: add max_swap_mem in ttm_mem_global Roger He
  2018-02-02  7:22 ` [PATCH 2/5] drm/ttm: add swap_glob_mem " Roger He
  2018-02-02  7:22 ` [PATCH 3/5] drm/ttm: add ttm page_flags TTM_PAGE_FLAG_PAGEFAULT Roger He
@ 2018-02-02  7:22 ` Roger He
  2018-02-02  7:39   ` Christian König
  2018-02-02  7:22 ` [PATCH 5/5] drm/ttm: keep original behavior except bo device with flag no_retry Roger He
  2018-02-02  7:34 ` [PATCH 1/5] drm/ttm: add max_swap_mem in ttm_mem_global Chunming Zhou
  4 siblings, 1 reply; 10+ messages in thread
From: Roger He @ 2018-02-02  7:22 UTC (permalink / raw)
  To: dri-devel; +Cc: Roger He, Christian.Koenig

because this zone has only 4GB, it is easy to became bottleneck for
huge normal zone.

Signed-off-by: Roger He <Hongbo.He@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c |  3 +++
 drivers/gpu/drm/ttm/ttm_memory.c        | 10 ++++++++--
 include/drm/ttm/ttm_memory.h            |  1 +
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index 95f9901..9f90022 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -75,6 +75,7 @@ static void amdgpu_ttm_mem_global_release(struct drm_global_reference *ref)
 static int amdgpu_ttm_global_init(struct amdgpu_device *adev)
 {
 	struct drm_global_reference *global_ref;
+	struct ttm_mem_global *mem_glob;
 	struct amdgpu_ring *ring;
 	struct drm_sched_rq *rq;
 	int r;
@@ -91,6 +92,8 @@ static int amdgpu_ttm_global_init(struct amdgpu_device *adev)
 			  "subsystem.\n");
 		goto error_mem;
 	}
+	mem_glob = (struct ttm_mem_global *)global_ref->object;
+	mem_glob->bdev = &adev->mman.bdev;
 
 	adev->mman.bo_global_ref.mem_glob =
 		adev->mman.mem_global_ref.object;
diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c
index f5227a5..875e5b8 100644
--- a/drivers/gpu/drm/ttm/ttm_memory.c
+++ b/drivers/gpu/drm/ttm/ttm_memory.c
@@ -567,6 +567,7 @@ int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,
 			      bool in_pagefault)
 {
 	struct ttm_mem_zone *zone = NULL;
+	struct ttm_bo_device *bdev = glob->bdev;
 
 	/**
 	 * Page allocations may be registed in a single zone
@@ -577,7 +578,9 @@ int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,
 	if (PageHighMem(page) && glob->zone_highmem != NULL)
 		zone = glob->zone_highmem;
 #else
-	if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL)
+	if (bdev && !bdev->need_dma32)
+		zone = glob->zone_kernel;
+	else if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL)
 		zone = glob->zone_kernel;
 #endif
 	return ttm_mem_global_alloc_zone(glob, zone, size,
@@ -588,12 +591,15 @@ void ttm_mem_global_free_page(struct ttm_mem_global *glob, struct page *page,
 			      uint64_t size)
 {
 	struct ttm_mem_zone *zone = NULL;
+	struct ttm_bo_device *bdev = glob->bdev;
 
 #ifdef CONFIG_HIGHMEM
 	if (PageHighMem(page) && glob->zone_highmem != NULL)
 		zone = glob->zone_highmem;
 #else
-	if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL)
+	if (bdev && !bdev->need_dma32)
+		zone = glob->zone_kernel;
+	else if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL)
 		zone = glob->zone_kernel;
 #endif
 	ttm_mem_global_free_zone(glob, zone, size);
diff --git a/include/drm/ttm/ttm_memory.h b/include/drm/ttm/ttm_memory.h
index 6c29b5c..0577475 100644
--- a/include/drm/ttm/ttm_memory.h
+++ b/include/drm/ttm/ttm_memory.h
@@ -79,6 +79,7 @@ struct ttm_mem_global {
 #else
 	struct ttm_mem_zone *zone_dma32;
 #endif
+	struct ttm_bo_device *bdev;
 };
 
 extern int ttm_mem_global_init(struct ttm_mem_global *glob);
-- 
2.7.4

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/5] drm/ttm: keep original behavior except bo device with flag no_retry
  2018-02-02  7:22 [PATCH 1/5] drm/ttm: add max_swap_mem in ttm_mem_global Roger He
                   ` (2 preceding siblings ...)
  2018-02-02  7:22 ` [PATCH 4/5] drm/ttm: if need_dma32 is not set, actually no need dma32 zone at all Roger He
@ 2018-02-02  7:22 ` Roger He
  2018-02-02  7:34 ` [PATCH 1/5] drm/ttm: add max_swap_mem in ttm_mem_global Chunming Zhou
  4 siblings, 0 replies; 10+ messages in thread
From: Roger He @ 2018-02-02  7:22 UTC (permalink / raw)
  To: dri-devel; +Cc: Roger He, Christian.Koenig

Signed-off-by: Roger He <Hongbo.He@amd.com>
---
 drivers/gpu/drm/ttm/ttm_memory.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c
index 875e5b8..25e1ce0 100644
--- a/drivers/gpu/drm/ttm/ttm_memory.c
+++ b/drivers/gpu/drm/ttm/ttm_memory.c
@@ -503,8 +503,11 @@ static int ttm_mem_global_reserve(struct ttm_mem_global *glob,
 		limit = (capable(CAP_SYS_ADMIN)) ?
 			zone->emer_mem : zone->max_mem;
 
-		total_used_mem = zone->used_mem + swap_glob_mem;
-		limit += glob->max_swap_mem;
+		total_used_mem = zone->used_mem;
+		if (glob->bdev && glob->bdev->no_retry) {
+			total_used_mem += swap_glob_mem;
+			limit += glob->max_swap_mem;
+		}
 		if (total_used_mem > limit)
 			goto out_unlock;
 	}
-- 
2.7.4

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/5] drm/ttm: add max_swap_mem in ttm_mem_global
  2018-02-02  7:22 [PATCH 1/5] drm/ttm: add max_swap_mem in ttm_mem_global Roger He
                   ` (3 preceding siblings ...)
  2018-02-02  7:22 ` [PATCH 5/5] drm/ttm: keep original behavior except bo device with flag no_retry Roger He
@ 2018-02-02  7:34 ` Chunming Zhou
  2018-02-02  7:38   ` Chunming Zhou
  4 siblings, 1 reply; 10+ messages in thread
From: Chunming Zhou @ 2018-02-02  7:34 UTC (permalink / raw)
  To: Roger He, dri-devel; +Cc: Christian.Koenig



On 2018年02月02日 15:22, Roger He wrote:
> set its initial value as 1/2 * free swap cache size when module initial.
> and adjust this value when allocate TTM memory
>
> Signed-off-by: Roger He <Hongbo.He@amd.com>
> ---
>   drivers/gpu/drm/ttm/ttm_memory.c | 10 ++++++++--
>   include/drm/ttm/ttm_memory.h     |  2 ++
>   2 files changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c
> index aa0c381..b48931d 100644
> --- a/drivers/gpu/drm/ttm/ttm_memory.c
> +++ b/drivers/gpu/drm/ttm/ttm_memory.c
> @@ -36,6 +36,7 @@
>   #include <linux/mm.h>
>   #include <linux/module.h>
>   #include <linux/slab.h>
> +#include <linux/swap.h>
>   
>   #define TTM_MEMORY_ALLOC_RETRIES 4
>   
> @@ -372,9 +373,9 @@ int ttm_mem_global_init(struct ttm_mem_global *glob)
>   		kobject_put(&glob->kobj);
>   		return ret;
>   	}
> -
> +	/* set it as 1/2 * swap free space we can get at that time */
> +	glob->max_swap_mem = get_nr_swap_pages() << (PAGE_SHIFT - 1);
>   	si_meminfo(&si);
> -
>   	ret = ttm_mem_init_kernel_zone(glob, &si);
>   	if (unlikely(ret != 0))
>   		goto out_no_zone;
> @@ -473,12 +474,17 @@ static int ttm_mem_global_reserve(struct ttm_mem_global *glob,
>   				  struct ttm_mem_zone *single_zone,
>   				  uint64_t amount, bool reserve)
>   {
> +	uint64_t free_swap_mem = get_nr_swap_pages() << (PAGE_SHIFT - 1);
>   	uint64_t limit;
>   	int ret = -ENOMEM;
>   	unsigned int i;
>   	struct ttm_mem_zone *zone;
>   
>   	spin_lock(&glob->lock);
> +	/* adjust the max_swap_mem to cover the new inserted swap space */
> +	if (glob->max_swap_mem < free_swap_mem)
> +		glob->max_swap_mem = free_swap_mem;
Seems using max() for exchange is more obvious, otherwise looks ok to me.

Regards,
David Zhou
> +
>   	for (i = 0; i < glob->num_zones; ++i) {
>   		zone = glob->zones[i];
>   		if (single_zone && zone != single_zone)
> diff --git a/include/drm/ttm/ttm_memory.h b/include/drm/ttm/ttm_memory.h
> index 8936285..ad5a557 100644
> --- a/include/drm/ttm/ttm_memory.h
> +++ b/include/drm/ttm/ttm_memory.h
> @@ -49,6 +49,7 @@
>    * @work: The workqueue callback for the shrink queue.
>    * @lock: Lock to protect the @shrink - and the memory accounting members,
>    * that is, essentially the whole structure with some exceptions.
> + * @max_swap_mem: upper limit of swap space TTM can use
>    * @zones: Array of pointers to accounting zones.
>    * @num_zones: Number of populated entries in the @zones array.
>    * @zone_kernel: Pointer to the kernel zone.
> @@ -67,6 +68,7 @@ struct ttm_mem_global {
>   	struct workqueue_struct *swap_queue;
>   	struct work_struct work;
>   	spinlock_t lock;
> +	uint64_t max_swap_mem;
>   	struct ttm_mem_zone *zones[TTM_MEM_MAX_ZONES];
>   	unsigned int num_zones;
>   	struct ttm_mem_zone *zone_kernel;

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/5] drm/ttm: add max_swap_mem in ttm_mem_global
  2018-02-02  7:34 ` [PATCH 1/5] drm/ttm: add max_swap_mem in ttm_mem_global Chunming Zhou
@ 2018-02-02  7:38   ` Chunming Zhou
  2018-02-02  8:04     ` He, Roger
  0 siblings, 1 reply; 10+ messages in thread
From: Chunming Zhou @ 2018-02-02  7:38 UTC (permalink / raw)
  To: Roger He, dri-devel; +Cc: Christian.Koenig


[-- Attachment #1.1: Type: text/plain, Size: 4271 bytes --]



On 2018年02月02日 15:34, Chunming Zhou wrote:
>
>
> On 2018年02月02日 15:22, Roger He wrote:
>> set its initial value as 1/2 * free swap cache size when module initial.
>> and adjust this value when allocate TTM memory
>>
>> Signed-off-by: Roger He <Hongbo.He@amd.com>
>> ---
>>   drivers/gpu/drm/ttm/ttm_memory.c | 10 ++++++++--
>>   include/drm/ttm/ttm_memory.h     |  2 ++
>>   2 files changed, 10 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/ttm/ttm_memory.c 
>> b/drivers/gpu/drm/ttm/ttm_memory.c
>> index aa0c381..b48931d 100644
>> --- a/drivers/gpu/drm/ttm/ttm_memory.c
>> +++ b/drivers/gpu/drm/ttm/ttm_memory.c
>> @@ -36,6 +36,7 @@
>>   #include <linux/mm.h>
>>   #include <linux/module.h>
>>   #include <linux/slab.h>
>> +#include <linux/swap.h>
>>     #define TTM_MEMORY_ALLOC_RETRIES 4
>>   @@ -372,9 +373,9 @@ int ttm_mem_global_init(struct ttm_mem_global 
>> *glob)
>>           kobject_put(&glob->kobj);
>>           return ret;
>>       }
>> -
>> +    /* set it as 1/2 * swap free space we can get at that time */
>> +    glob->max_swap_mem = get_nr_swap_pages() << (PAGE_SHIFT - 1);
>>       si_meminfo(&si);
Hi Roger,

I just find si_meminfo can get total swap size, see struct sysinfo 
definition:
  struct sysinfo {
         __kernel_long_t uptime;         /* Seconds since boot */
         __kernel_ulong_t loads[3];      /* 1, 5, and 15 minute load 
averages */
         __kernel_ulong_t totalram;      /* Total usable main memory size */
         __kernel_ulong_t freeram;       /* Available memory size */
         __kernel_ulong_t sharedram;     /* Amount of shared memory */
         __kernel_ulong_t bufferram;     /* Memory used by buffers */
         __kernel_ulong_t totalswap;     /* Total swap space size */
         __kernel_ulong_t freeswap;      /* swap space still available */
         __u16 procs;                    /* Number of current processes */
...

can sysinfo.totalswap be used for your change?

Regards,
David Zhou
>> -
>>       ret = ttm_mem_init_kernel_zone(glob, &si);
>>       if (unlikely(ret != 0))
>>           goto out_no_zone;
>> @@ -473,12 +474,17 @@ static int ttm_mem_global_reserve(struct 
>> ttm_mem_global *glob,
>>                     struct ttm_mem_zone *single_zone,
>>                     uint64_t amount, bool reserve)
>>   {
>> +    uint64_t free_swap_mem = get_nr_swap_pages() << (PAGE_SHIFT - 1);
>>       uint64_t limit;
>>       int ret = -ENOMEM;
>>       unsigned int i;
>>       struct ttm_mem_zone *zone;
>>         spin_lock(&glob->lock);
>> +    /* adjust the max_swap_mem to cover the new inserted swap space */
>> +    if (glob->max_swap_mem < free_swap_mem)
>> +        glob->max_swap_mem = free_swap_mem;
> Seems using max() for exchange is more obvious, otherwise looks ok to me.
>
> Regards,
> David Zhou
>> +
>>       for (i = 0; i < glob->num_zones; ++i) {
>>           zone = glob->zones[i];
>>           if (single_zone && zone != single_zone)
>> diff --git a/include/drm/ttm/ttm_memory.h b/include/drm/ttm/ttm_memory.h
>> index 8936285..ad5a557 100644
>> --- a/include/drm/ttm/ttm_memory.h
>> +++ b/include/drm/ttm/ttm_memory.h
>> @@ -49,6 +49,7 @@
>>    * @work: The workqueue callback for the shrink queue.
>>    * @lock: Lock to protect the @shrink - and the memory accounting 
>> members,
>>    * that is, essentially the whole structure with some exceptions.
>> + * @max_swap_mem: upper limit of swap space TTM can use
>>    * @zones: Array of pointers to accounting zones.
>>    * @num_zones: Number of populated entries in the @zones array.
>>    * @zone_kernel: Pointer to the kernel zone.
>> @@ -67,6 +68,7 @@ struct ttm_mem_global {
>>       struct workqueue_struct *swap_queue;
>>       struct work_struct work;
>>       spinlock_t lock;
>> +    uint64_t max_swap_mem;
>>       struct ttm_mem_zone *zones[TTM_MEM_MAX_ZONES];
>>       unsigned int num_zones;
>>       struct ttm_mem_zone *zone_kernel;
>


[-- Attachment #1.2: Type: text/html, Size: 6618 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/5] drm/ttm: if need_dma32 is not set, actually no need dma32 zone at all.
  2018-02-02  7:22 ` [PATCH 4/5] drm/ttm: if need_dma32 is not set, actually no need dma32 zone at all Roger He
@ 2018-02-02  7:39   ` Christian König
  0 siblings, 0 replies; 10+ messages in thread
From: Christian König @ 2018-02-02  7:39 UTC (permalink / raw)
  To: Roger He, dri-devel

NAK, that the gfx driver doesn't need DMA32 doesn't mean that we can use 
it all up with BO allocations.

It is still quite likely that other drivers in the system might need it.

Christian.

Am 02.02.2018 um 08:22 schrieb Roger He:
> because this zone has only 4GB, it is easy to became bottleneck for
> huge normal zone.
>
> Signed-off-by: Roger He <Hongbo.He@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c |  3 +++
>   drivers/gpu/drm/ttm/ttm_memory.c        | 10 ++++++++--
>   include/drm/ttm/ttm_memory.h            |  1 +
>   3 files changed, 12 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index 95f9901..9f90022 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -75,6 +75,7 @@ static void amdgpu_ttm_mem_global_release(struct drm_global_reference *ref)
>   static int amdgpu_ttm_global_init(struct amdgpu_device *adev)
>   {
>   	struct drm_global_reference *global_ref;
> +	struct ttm_mem_global *mem_glob;
>   	struct amdgpu_ring *ring;
>   	struct drm_sched_rq *rq;
>   	int r;
> @@ -91,6 +92,8 @@ static int amdgpu_ttm_global_init(struct amdgpu_device *adev)
>   			  "subsystem.\n");
>   		goto error_mem;
>   	}
> +	mem_glob = (struct ttm_mem_global *)global_ref->object;
> +	mem_glob->bdev = &adev->mman.bdev;
>   
>   	adev->mman.bo_global_ref.mem_glob =
>   		adev->mman.mem_global_ref.object;
> diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c
> index f5227a5..875e5b8 100644
> --- a/drivers/gpu/drm/ttm/ttm_memory.c
> +++ b/drivers/gpu/drm/ttm/ttm_memory.c
> @@ -567,6 +567,7 @@ int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,
>   			      bool in_pagefault)
>   {
>   	struct ttm_mem_zone *zone = NULL;
> +	struct ttm_bo_device *bdev = glob->bdev;
>   
>   	/**
>   	 * Page allocations may be registed in a single zone
> @@ -577,7 +578,9 @@ int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,
>   	if (PageHighMem(page) && glob->zone_highmem != NULL)
>   		zone = glob->zone_highmem;
>   #else
> -	if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL)
> +	if (bdev && !bdev->need_dma32)
> +		zone = glob->zone_kernel;
> +	else if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL)
>   		zone = glob->zone_kernel;
>   #endif
>   	return ttm_mem_global_alloc_zone(glob, zone, size,
> @@ -588,12 +591,15 @@ void ttm_mem_global_free_page(struct ttm_mem_global *glob, struct page *page,
>   			      uint64_t size)
>   {
>   	struct ttm_mem_zone *zone = NULL;
> +	struct ttm_bo_device *bdev = glob->bdev;
>   
>   #ifdef CONFIG_HIGHMEM
>   	if (PageHighMem(page) && glob->zone_highmem != NULL)
>   		zone = glob->zone_highmem;
>   #else
> -	if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL)
> +	if (bdev && !bdev->need_dma32)
> +		zone = glob->zone_kernel;
> +	else if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL)
>   		zone = glob->zone_kernel;
>   #endif
>   	ttm_mem_global_free_zone(glob, zone, size);
> diff --git a/include/drm/ttm/ttm_memory.h b/include/drm/ttm/ttm_memory.h
> index 6c29b5c..0577475 100644
> --- a/include/drm/ttm/ttm_memory.h
> +++ b/include/drm/ttm/ttm_memory.h
> @@ -79,6 +79,7 @@ struct ttm_mem_global {
>   #else
>   	struct ttm_mem_zone *zone_dma32;
>   #endif
> +	struct ttm_bo_device *bdev;
>   };
>   
>   extern int ttm_mem_global_init(struct ttm_mem_global *glob);

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/5] drm/ttm: add ttm page_flags TTM_PAGE_FLAG_PAGEFAULT
  2018-02-02  7:22 ` [PATCH 3/5] drm/ttm: add ttm page_flags TTM_PAGE_FLAG_PAGEFAULT Roger He
@ 2018-02-02  7:42   ` Christian König
  0 siblings, 0 replies; 10+ messages in thread
From: Christian König @ 2018-02-02  7:42 UTC (permalink / raw)
  To: Roger He, dri-devel

Am 02.02.2018 um 08:22 schrieb Roger He:
> to indicate whether we are servicing for page fault routine 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: fix minor typo
> v3: keep original behavior except ttm page with flag NO_RETRY

We need to extend this to the suspend/resume case as well.

Saying so would it be possible to make that behavior depend on the ctx 
instead of the page flags?

Thanks,
Christian.

>
> Signed-off-by: Roger He <Hongbo.He@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, 38 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c
> index 716e724..f03dd94 100644
> --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c
> +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c
> @@ -233,8 +233,12 @@ static int ttm_bo_vm_fault(struct vm_fault *vmf)
>   		cvma.vm_page_prot = ttm_io_prot(bo->mem.placement,
>   						cvma.vm_page_prot);
>   
> +		if (ttm->page_flags & TTM_PAGE_FLAG_NO_RETRY)
> +			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) {
>   			ret = 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 598b14b..f5227a5 100644
> --- a/drivers/gpu/drm/ttm/ttm_memory.c
> +++ b/drivers/gpu/drm/ttm/ttm_memory.c
> @@ -472,7 +472,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 free_swap_mem = get_nr_swap_pages() << (PAGE_SHIFT - 1);
>   	uint64_t swap_glob_mem, limit, total_used_mem;
> @@ -483,6 +484,13 @@ static int ttm_mem_global_reserve(struct ttm_mem_global *glob,
>   	swap_glob_mem = atomic64_read(&glob->swap_glob_mem);
>   
>   	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;
> +
>   	/* adjust the max_swap_mem to cover the new inserted swap space */
>   	if (glob->max_swap_mem < free_swap_mem)
>   		glob->max_swap_mem = free_swap_mem;
> @@ -501,6 +509,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];
> @@ -522,13 +531,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;
> @@ -548,13 +557,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;
>   
> @@ -570,7 +580,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..15bf691 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;
>   	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 b122f6e..b8adf37 100644
> --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
> +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
> @@ -934,6 +934,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;
>   
> @@ -943,8 +944,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;
>   	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;
> @@ -966,7 +967,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;
> @@ -1003,7 +1005,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 5d441e0..a730cd6 100644
> --- a/drivers/gpu/drm/ttm/ttm_tt.c
> +++ b/drivers/gpu/drm/ttm/ttm_tt.c
> @@ -391,7 +391,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 6282b50..6c29b5c 100644
> --- a/include/drm/ttm/ttm_memory.h
> +++ b/include/drm/ttm/ttm_memory.h
> @@ -89,7 +89,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);

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH 1/5] drm/ttm: add max_swap_mem in ttm_mem_global
  2018-02-02  7:38   ` Chunming Zhou
@ 2018-02-02  8:04     ` He, Roger
  0 siblings, 0 replies; 10+ messages in thread
From: He, Roger @ 2018-02-02  8:04 UTC (permalink / raw)
  To: Zhou, David(ChunMing), dri-devel; +Cc: Koenig, Christian


[-- Attachment #1.1: Type: text/plain, Size: 4306 bytes --]

Need call si_swapinfo to fill those valules .
void si_swapinfo(struct sysinfo *val)

But that function is not exported as well.

Thanks
Roger(Hongbo.He)
From: dri-devel [mailto:dri-devel-bounces@lists.freedesktop.org] On Behalf Of Chunming Zhou
Sent: Friday, February 02, 2018 3:38 PM
To: He, Roger <Hongbo.He@amd.com>; dri-devel@lists.freedesktop.org
Cc: Koenig, Christian <Christian.Koenig@amd.com>
Subject: Re: [PATCH 1/5] drm/ttm: add max_swap_mem in ttm_mem_global




On 2018年02月02日 15:34, Chunming Zhou wrote:


On 2018年02月02日 15:22, Roger He wrote:

set its initial value as 1/2 * free swap cache size when module initial.
and adjust this value when allocate TTM memory

Signed-off-by: Roger He <Hongbo.He@amd.com><mailto:Hongbo.He@amd.com>
---
  drivers/gpu/drm/ttm/ttm_memory.c | 10 ++++++++--
  include/drm/ttm/ttm_memory.h     |  2 ++
  2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/ttm/ttm_memory.c b/drivers/gpu/drm/ttm/ttm_memory.c
index aa0c381..b48931d 100644
--- a/drivers/gpu/drm/ttm/ttm_memory.c
+++ b/drivers/gpu/drm/ttm/ttm_memory.c
@@ -36,6 +36,7 @@
  #include <linux/mm.h>
  #include <linux/module.h>
  #include <linux/slab.h>
+#include <linux/swap.h>
    #define TTM_MEMORY_ALLOC_RETRIES 4
  @@ -372,9 +373,9 @@ int ttm_mem_global_init(struct ttm_mem_global *glob)
          kobject_put(&glob->kobj);
          return ret;
      }
-
+    /* set it as 1/2 * swap free space we can get at that time */
+    glob->max_swap_mem = get_nr_swap_pages() << (PAGE_SHIFT - 1);
      si_meminfo(&si);
Hi Roger,

I just find si_meminfo can get total swap size, see struct sysinfo definition:
 struct sysinfo {
        __kernel_long_t uptime;         /* Seconds since boot */
        __kernel_ulong_t loads[3];      /* 1, 5, and 15 minute load averages */
        __kernel_ulong_t totalram;      /* Total usable main memory size */
        __kernel_ulong_t freeram;       /* Available memory size */
        __kernel_ulong_t sharedram;     /* Amount of shared memory */
        __kernel_ulong_t bufferram;     /* Memory used by buffers */
        __kernel_ulong_t totalswap;     /* Total swap space size */
        __kernel_ulong_t freeswap;      /* swap space still available */
        __u16 procs;                    /* Number of current processes */
...

can sysinfo.totalswap be used for your change?

Regards,
David Zhou

-
      ret = ttm_mem_init_kernel_zone(glob, &si);
      if (unlikely(ret != 0))
          goto out_no_zone;
@@ -473,12 +474,17 @@ static int ttm_mem_global_reserve(struct ttm_mem_global *glob,
                    struct ttm_mem_zone *single_zone,
                    uint64_t amount, bool reserve)
  {
+    uint64_t free_swap_mem = get_nr_swap_pages() << (PAGE_SHIFT - 1);
      uint64_t limit;
      int ret = -ENOMEM;
      unsigned int i;
      struct ttm_mem_zone *zone;
        spin_lock(&glob->lock);
+    /* adjust the max_swap_mem to cover the new inserted swap space */
+    if (glob->max_swap_mem < free_swap_mem)
+        glob->max_swap_mem = free_swap_mem;
Seems using max() for exchange is more obvious, otherwise looks ok to me.

Regards,
David Zhou

+
      for (i = 0; i < glob->num_zones; ++i) {
          zone = glob->zones[i];
          if (single_zone && zone != single_zone)
diff --git a/include/drm/ttm/ttm_memory.h b/include/drm/ttm/ttm_memory.h
index 8936285..ad5a557 100644
--- a/include/drm/ttm/ttm_memory.h
+++ b/include/drm/ttm/ttm_memory.h
@@ -49,6 +49,7 @@
   * @work: The workqueue callback for the shrink queue.
   * @lock: Lock to protect the @shrink - and the memory accounting members,
   * that is, essentially the whole structure with some exceptions.
+ * @max_swap_mem: upper limit of swap space TTM can use
   * @zones: Array of pointers to accounting zones.
   * @num_zones: Number of populated entries in the @zones array.
   * @zone_kernel: Pointer to the kernel zone.
@@ -67,6 +68,7 @@ struct ttm_mem_global {
      struct workqueue_struct *swap_queue;
      struct work_struct work;
      spinlock_t lock;
+    uint64_t max_swap_mem;
      struct ttm_mem_zone *zones[TTM_MEM_MAX_ZONES];
      unsigned int num_zones;
      struct ttm_mem_zone *zone_kernel;



[-- Attachment #1.2: Type: text/html, Size: 11407 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2018-02-02  8:04 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-02  7:22 [PATCH 1/5] drm/ttm: add max_swap_mem in ttm_mem_global Roger He
2018-02-02  7:22 ` [PATCH 2/5] drm/ttm: add swap_glob_mem " Roger He
2018-02-02  7:22 ` [PATCH 3/5] drm/ttm: add ttm page_flags TTM_PAGE_FLAG_PAGEFAULT Roger He
2018-02-02  7:42   ` Christian König
2018-02-02  7:22 ` [PATCH 4/5] drm/ttm: if need_dma32 is not set, actually no need dma32 zone at all Roger He
2018-02-02  7:39   ` Christian König
2018-02-02  7:22 ` [PATCH 5/5] drm/ttm: keep original behavior except bo device with flag no_retry Roger He
2018-02-02  7:34 ` [PATCH 1/5] drm/ttm: add max_swap_mem in ttm_mem_global Chunming Zhou
2018-02-02  7:38   ` Chunming Zhou
2018-02-02  8:04     ` He, Roger

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.