All of lore.kernel.org
 help / color / mirror / Atom feed
From: Brian Welty <brian.welty@intel.com>
To: "Brian Welty" <brian.welty@intel.com>,
	cgroups@vger.kernel.org, "Tejun Heo" <tj@kernel.org>,
	dri-devel@lists.freedesktop.org,
	"David Airlie" <airlied@linux.ie>,
	"Daniel Vetter" <daniel@ffwll.ch>,
	"Christian König" <christian.koenig@amd.com>,
	"Kenny Ho" <Kenny.Ho@amd.com>,
	amd-gfx@lists.freedesktop.org,
	"Chris Wilson" <chris@chris-wilson.co.uk>,
	"Tvrtko Ursulin" <tvrtko.ursulin@linux.intel.com>,
	intel-gfx@lists.freedesktop.org,
	"Joonas Lahtinen" <joonas.lahtinen@linux.intel.com>,
	"Eero Tamminen" <eero.t.tamminen@intel.com>
Subject: [RFC PATCH 9/9] drm/i915: Use memory cgroup for enforcing device memory limit
Date: Tue, 26 Jan 2021 13:46:26 -0800	[thread overview]
Message-ID: <20210126214626.16260-10-brian.welty@intel.com> (raw)
In-Reply-To: <20210126214626.16260-1-brian.welty@intel.com>

To charge device memory allocations, we need to (1) identify appropriate
cgroup to charge (currently decided at object creation time), and (2)
make the charging call at the time that memory pages are being allocated.

For (1), see prior DRM patch which associates current task's cgroup with
GEM objects as they are created.  That cgroup will be charged/uncharged
for all paging activity against the GEM object.

For (2), we call drm_get_object_charge_mem() in .get_pages callback
for the GEM object type.  Uncharging is done in .put_pages when the
memory is marked such that it can be evicted.  The try_charge() call will
fail with -ENOMEM if the current memory allocation will exceed the cgroup
device memory maximum, and allow for driver to perform memory reclaim.

We also set the total device memory reported by DRM cgroup by storing
in drm_device.drmcg_props after initializing LMEM memory regions.

FIXME: to release drm cgroup reference requires this additional patch:
  https://patchwork.freedesktop.org/patch/349029

Signed-off-by: Brian Welty <brian.welty@intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c   |  1 +
 drivers/gpu/drm/i915/gem/i915_gem_region.c | 23 ++++++++++++++++++----
 drivers/gpu/drm/i915/intel_memory_region.c | 13 ++++++++++--
 drivers/gpu/drm/i915/intel_memory_region.h |  2 +-
 4 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index ec28a6cde49b..9fbe91d4d2f1 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -16,6 +16,7 @@
 #include "i915_gem_gtt.h"
 #include "i915_gem_ioctls.h"
 #include "i915_gem_object.h"
+#include "i915_gem_lmem.h"
 #include "i915_gem_mman.h"
 #include "i915_trace.h"
 #include "i915_user_extensions.h"
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c b/drivers/gpu/drm/i915/gem/i915_gem_region.c
index 3e3dad22a683..690b36b25984 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_region.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c
@@ -12,11 +12,14 @@ void
 i915_gem_object_put_pages_buddy(struct drm_i915_gem_object *obj,
 				struct sg_table *pages)
 {
-	__intel_memory_region_put_pages_buddy(obj->mm.region, &obj->mm.blocks);
+	u64 freed;
 
+	freed = __intel_memory_region_put_pages_buddy(obj->mm.region,
+						      &obj->mm.blocks);
 	obj->mm.dirty = false;
 	sg_free_table(pages);
 	kfree(pages);
+	drm_gem_object_uncharge_mem(&obj->base, freed);
 }
 
 int
@@ -25,7 +28,7 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj)
 	const u64 max_segment = i915_sg_segment_size();
 	struct intel_memory_region *mem = obj->mm.region;
 	struct list_head *blocks = &obj->mm.blocks;
-	resource_size_t size = obj->base.size;
+	resource_size_t charged, size = obj->base.size;
 	resource_size_t prev_end;
 	struct i915_buddy_block *block;
 	unsigned int flags;
@@ -44,12 +47,22 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj)
 	}
 
 	flags = I915_ALLOC_MIN_PAGE_SIZE;
-	if (obj->flags & I915_BO_ALLOC_CONTIGUOUS)
+	if (obj->flags & I915_BO_ALLOC_CONTIGUOUS) {
 		flags |= I915_ALLOC_CONTIGUOUS;
+		charged = roundup_pow_of_two(size);
+	} else {
+		charged = size;
+	}
+
+	ret = drm_gem_object_charge_mem(&obj->base, charged);
+	if (ret) {
+		DRM_DEBUG("DRMCG: charge_mem failed for %lld\n", charged);
+		goto err_free_sg;
+	}
 
 	ret = __intel_memory_region_get_pages_buddy(mem, size, flags, blocks);
 	if (ret)
-		goto err_free_sg;
+		goto err_uncharge;
 
 	GEM_BUG_ON(list_empty(blocks));
 
@@ -99,6 +112,8 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj)
 
 	return 0;
 
+err_uncharge:
+	drm_gem_object_uncharge_mem(&obj->base, charged);
 err_free_sg:
 	sg_free_table(st);
 	kfree(st);
diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c
index 1bfcdd89b241..9b1edbf4361c 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/intel_memory_region.c
@@ -46,13 +46,18 @@ intel_memory_region_free_pages(struct intel_memory_region *mem,
 	return size;
 }
 
-void
+u64
 __intel_memory_region_put_pages_buddy(struct intel_memory_region *mem,
 				      struct list_head *blocks)
 {
+	u64 freed;
+
 	mutex_lock(&mem->mm_lock);
-	mem->avail += intel_memory_region_free_pages(mem, blocks);
+	freed = intel_memory_region_free_pages(mem, blocks);
+	mem->avail += freed;
 	mutex_unlock(&mem->mm_lock);
+
+	return freed;
 }
 
 void
@@ -241,6 +246,7 @@ void intel_memory_region_put(struct intel_memory_region *mem)
 
 int intel_memory_regions_hw_probe(struct drm_i915_private *i915)
 {
+	u64 lmem_total = 0;
 	int err, i;
 
 	for (i = 0; i < ARRAY_SIZE(i915->mm.regions); i++) {
@@ -260,6 +266,7 @@ int intel_memory_regions_hw_probe(struct drm_i915_private *i915)
 			break;
 		case INTEL_MEMORY_LOCAL:
 			mem = intel_setup_fake_lmem(i915);
+			lmem_total += mem->total;
 			break;
 		}
 
@@ -278,6 +285,8 @@ int intel_memory_regions_hw_probe(struct drm_i915_private *i915)
 		i915->mm.regions[i] = mem;
 	}
 
+	i915->drm.drmcg_props.memory_total = lmem_total;
+
 	return 0;
 
 out_cleanup:
diff --git a/drivers/gpu/drm/i915/intel_memory_region.h b/drivers/gpu/drm/i915/intel_memory_region.h
index 6ffc0673f005..c9fca951a372 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.h
+++ b/drivers/gpu/drm/i915/intel_memory_region.h
@@ -109,7 +109,7 @@ struct i915_buddy_block *
 __intel_memory_region_get_block_buddy(struct intel_memory_region *mem,
 				      resource_size_t size,
 				      unsigned int flags);
-void __intel_memory_region_put_pages_buddy(struct intel_memory_region *mem,
+u64 __intel_memory_region_put_pages_buddy(struct intel_memory_region *mem,
 					   struct list_head *blocks);
 void __intel_memory_region_put_block_buddy(struct i915_buddy_block *block);
 
-- 
2.20.1

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

WARNING: multiple messages have this Message-ID (diff)
From: Brian Welty <brian.welty@intel.com>
To: "Brian Welty" <brian.welty@intel.com>,
	cgroups@vger.kernel.org, "Tejun Heo" <tj@kernel.org>,
	dri-devel@lists.freedesktop.org,
	"David Airlie" <airlied@linux.ie>,
	"Daniel Vetter" <daniel@ffwll.ch>,
	"Christian König" <christian.koenig@amd.com>,
	"Kenny Ho" <Kenny.Ho@amd.com>,
	amd-gfx@lists.freedesktop.org,
	"Chris Wilson" <chris@chris-wilson.co.uk>,
	"Tvrtko Ursulin" <tvrtko.ursulin@linux.intel.com>,
	intel-gfx@lists.freedesktop.org,
	"Joonas Lahtinen" <joonas.lahtinen@linux.intel.com>,
	"Eero Tamminen" <eero.t.tamminen@intel.com>
Subject: [Intel-gfx] [RFC PATCH 9/9] drm/i915: Use memory cgroup for enforcing device memory limit
Date: Tue, 26 Jan 2021 13:46:26 -0800	[thread overview]
Message-ID: <20210126214626.16260-10-brian.welty@intel.com> (raw)
In-Reply-To: <20210126214626.16260-1-brian.welty@intel.com>

To charge device memory allocations, we need to (1) identify appropriate
cgroup to charge (currently decided at object creation time), and (2)
make the charging call at the time that memory pages are being allocated.

For (1), see prior DRM patch which associates current task's cgroup with
GEM objects as they are created.  That cgroup will be charged/uncharged
for all paging activity against the GEM object.

For (2), we call drm_get_object_charge_mem() in .get_pages callback
for the GEM object type.  Uncharging is done in .put_pages when the
memory is marked such that it can be evicted.  The try_charge() call will
fail with -ENOMEM if the current memory allocation will exceed the cgroup
device memory maximum, and allow for driver to perform memory reclaim.

We also set the total device memory reported by DRM cgroup by storing
in drm_device.drmcg_props after initializing LMEM memory regions.

FIXME: to release drm cgroup reference requires this additional patch:
  https://patchwork.freedesktop.org/patch/349029

Signed-off-by: Brian Welty <brian.welty@intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c   |  1 +
 drivers/gpu/drm/i915/gem/i915_gem_region.c | 23 ++++++++++++++++++----
 drivers/gpu/drm/i915/intel_memory_region.c | 13 ++++++++++--
 drivers/gpu/drm/i915/intel_memory_region.h |  2 +-
 4 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index ec28a6cde49b..9fbe91d4d2f1 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -16,6 +16,7 @@
 #include "i915_gem_gtt.h"
 #include "i915_gem_ioctls.h"
 #include "i915_gem_object.h"
+#include "i915_gem_lmem.h"
 #include "i915_gem_mman.h"
 #include "i915_trace.h"
 #include "i915_user_extensions.h"
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c b/drivers/gpu/drm/i915/gem/i915_gem_region.c
index 3e3dad22a683..690b36b25984 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_region.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c
@@ -12,11 +12,14 @@ void
 i915_gem_object_put_pages_buddy(struct drm_i915_gem_object *obj,
 				struct sg_table *pages)
 {
-	__intel_memory_region_put_pages_buddy(obj->mm.region, &obj->mm.blocks);
+	u64 freed;
 
+	freed = __intel_memory_region_put_pages_buddy(obj->mm.region,
+						      &obj->mm.blocks);
 	obj->mm.dirty = false;
 	sg_free_table(pages);
 	kfree(pages);
+	drm_gem_object_uncharge_mem(&obj->base, freed);
 }
 
 int
@@ -25,7 +28,7 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj)
 	const u64 max_segment = i915_sg_segment_size();
 	struct intel_memory_region *mem = obj->mm.region;
 	struct list_head *blocks = &obj->mm.blocks;
-	resource_size_t size = obj->base.size;
+	resource_size_t charged, size = obj->base.size;
 	resource_size_t prev_end;
 	struct i915_buddy_block *block;
 	unsigned int flags;
@@ -44,12 +47,22 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj)
 	}
 
 	flags = I915_ALLOC_MIN_PAGE_SIZE;
-	if (obj->flags & I915_BO_ALLOC_CONTIGUOUS)
+	if (obj->flags & I915_BO_ALLOC_CONTIGUOUS) {
 		flags |= I915_ALLOC_CONTIGUOUS;
+		charged = roundup_pow_of_two(size);
+	} else {
+		charged = size;
+	}
+
+	ret = drm_gem_object_charge_mem(&obj->base, charged);
+	if (ret) {
+		DRM_DEBUG("DRMCG: charge_mem failed for %lld\n", charged);
+		goto err_free_sg;
+	}
 
 	ret = __intel_memory_region_get_pages_buddy(mem, size, flags, blocks);
 	if (ret)
-		goto err_free_sg;
+		goto err_uncharge;
 
 	GEM_BUG_ON(list_empty(blocks));
 
@@ -99,6 +112,8 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj)
 
 	return 0;
 
+err_uncharge:
+	drm_gem_object_uncharge_mem(&obj->base, charged);
 err_free_sg:
 	sg_free_table(st);
 	kfree(st);
diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c
index 1bfcdd89b241..9b1edbf4361c 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/intel_memory_region.c
@@ -46,13 +46,18 @@ intel_memory_region_free_pages(struct intel_memory_region *mem,
 	return size;
 }
 
-void
+u64
 __intel_memory_region_put_pages_buddy(struct intel_memory_region *mem,
 				      struct list_head *blocks)
 {
+	u64 freed;
+
 	mutex_lock(&mem->mm_lock);
-	mem->avail += intel_memory_region_free_pages(mem, blocks);
+	freed = intel_memory_region_free_pages(mem, blocks);
+	mem->avail += freed;
 	mutex_unlock(&mem->mm_lock);
+
+	return freed;
 }
 
 void
@@ -241,6 +246,7 @@ void intel_memory_region_put(struct intel_memory_region *mem)
 
 int intel_memory_regions_hw_probe(struct drm_i915_private *i915)
 {
+	u64 lmem_total = 0;
 	int err, i;
 
 	for (i = 0; i < ARRAY_SIZE(i915->mm.regions); i++) {
@@ -260,6 +266,7 @@ int intel_memory_regions_hw_probe(struct drm_i915_private *i915)
 			break;
 		case INTEL_MEMORY_LOCAL:
 			mem = intel_setup_fake_lmem(i915);
+			lmem_total += mem->total;
 			break;
 		}
 
@@ -278,6 +285,8 @@ int intel_memory_regions_hw_probe(struct drm_i915_private *i915)
 		i915->mm.regions[i] = mem;
 	}
 
+	i915->drm.drmcg_props.memory_total = lmem_total;
+
 	return 0;
 
 out_cleanup:
diff --git a/drivers/gpu/drm/i915/intel_memory_region.h b/drivers/gpu/drm/i915/intel_memory_region.h
index 6ffc0673f005..c9fca951a372 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.h
+++ b/drivers/gpu/drm/i915/intel_memory_region.h
@@ -109,7 +109,7 @@ struct i915_buddy_block *
 __intel_memory_region_get_block_buddy(struct intel_memory_region *mem,
 				      resource_size_t size,
 				      unsigned int flags);
-void __intel_memory_region_put_pages_buddy(struct intel_memory_region *mem,
+u64 __intel_memory_region_put_pages_buddy(struct intel_memory_region *mem,
 					   struct list_head *blocks);
 void __intel_memory_region_put_block_buddy(struct i915_buddy_block *block);
 
-- 
2.20.1

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

WARNING: multiple messages have this Message-ID (diff)
From: Brian Welty <brian.welty@intel.com>
To: "Brian Welty" <brian.welty@intel.com>,
	cgroups@vger.kernel.org, "Tejun Heo" <tj@kernel.org>,
	dri-devel@lists.freedesktop.org,
	"David Airlie" <airlied@linux.ie>,
	"Daniel Vetter" <daniel@ffwll.ch>,
	"Christian König" <christian.koenig@amd.com>,
	"Kenny Ho" <Kenny.Ho@amd.com>,
	amd-gfx@lists.freedesktop.org,
	"Chris Wilson" <chris@chris-wilson.co.uk>,
	"Tvrtko Ursulin" <tvrtko.ursulin@linux.intel.com>,
	intel-gfx@lists.freedesktop.org,
	"Joonas Lahtinen" <joonas.lahtinen@linux.intel.com>,
	"Eero Tamminen" <eero.t.tamminen@intel.com>
Subject: [RFC PATCH 9/9] drm/i915: Use memory cgroup for enforcing device memory limit
Date: Tue, 26 Jan 2021 13:46:26 -0800	[thread overview]
Message-ID: <20210126214626.16260-10-brian.welty@intel.com> (raw)
In-Reply-To: <20210126214626.16260-1-brian.welty@intel.com>

To charge device memory allocations, we need to (1) identify appropriate
cgroup to charge (currently decided at object creation time), and (2)
make the charging call at the time that memory pages are being allocated.

For (1), see prior DRM patch which associates current task's cgroup with
GEM objects as they are created.  That cgroup will be charged/uncharged
for all paging activity against the GEM object.

For (2), we call drm_get_object_charge_mem() in .get_pages callback
for the GEM object type.  Uncharging is done in .put_pages when the
memory is marked such that it can be evicted.  The try_charge() call will
fail with -ENOMEM if the current memory allocation will exceed the cgroup
device memory maximum, and allow for driver to perform memory reclaim.

We also set the total device memory reported by DRM cgroup by storing
in drm_device.drmcg_props after initializing LMEM memory regions.

FIXME: to release drm cgroup reference requires this additional patch:
  https://patchwork.freedesktop.org/patch/349029

Signed-off-by: Brian Welty <brian.welty@intel.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c   |  1 +
 drivers/gpu/drm/i915/gem/i915_gem_region.c | 23 ++++++++++++++++++----
 drivers/gpu/drm/i915/intel_memory_region.c | 13 ++++++++++--
 drivers/gpu/drm/i915/intel_memory_region.h |  2 +-
 4 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index ec28a6cde49b..9fbe91d4d2f1 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -16,6 +16,7 @@
 #include "i915_gem_gtt.h"
 #include "i915_gem_ioctls.h"
 #include "i915_gem_object.h"
+#include "i915_gem_lmem.h"
 #include "i915_gem_mman.h"
 #include "i915_trace.h"
 #include "i915_user_extensions.h"
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c b/drivers/gpu/drm/i915/gem/i915_gem_region.c
index 3e3dad22a683..690b36b25984 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_region.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c
@@ -12,11 +12,14 @@ void
 i915_gem_object_put_pages_buddy(struct drm_i915_gem_object *obj,
 				struct sg_table *pages)
 {
-	__intel_memory_region_put_pages_buddy(obj->mm.region, &obj->mm.blocks);
+	u64 freed;
 
+	freed = __intel_memory_region_put_pages_buddy(obj->mm.region,
+						      &obj->mm.blocks);
 	obj->mm.dirty = false;
 	sg_free_table(pages);
 	kfree(pages);
+	drm_gem_object_uncharge_mem(&obj->base, freed);
 }
 
 int
@@ -25,7 +28,7 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj)
 	const u64 max_segment = i915_sg_segment_size();
 	struct intel_memory_region *mem = obj->mm.region;
 	struct list_head *blocks = &obj->mm.blocks;
-	resource_size_t size = obj->base.size;
+	resource_size_t charged, size = obj->base.size;
 	resource_size_t prev_end;
 	struct i915_buddy_block *block;
 	unsigned int flags;
@@ -44,12 +47,22 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj)
 	}
 
 	flags = I915_ALLOC_MIN_PAGE_SIZE;
-	if (obj->flags & I915_BO_ALLOC_CONTIGUOUS)
+	if (obj->flags & I915_BO_ALLOC_CONTIGUOUS) {
 		flags |= I915_ALLOC_CONTIGUOUS;
+		charged = roundup_pow_of_two(size);
+	} else {
+		charged = size;
+	}
+
+	ret = drm_gem_object_charge_mem(&obj->base, charged);
+	if (ret) {
+		DRM_DEBUG("DRMCG: charge_mem failed for %lld\n", charged);
+		goto err_free_sg;
+	}
 
 	ret = __intel_memory_region_get_pages_buddy(mem, size, flags, blocks);
 	if (ret)
-		goto err_free_sg;
+		goto err_uncharge;
 
 	GEM_BUG_ON(list_empty(blocks));
 
@@ -99,6 +112,8 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj)
 
 	return 0;
 
+err_uncharge:
+	drm_gem_object_uncharge_mem(&obj->base, charged);
 err_free_sg:
 	sg_free_table(st);
 	kfree(st);
diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c
index 1bfcdd89b241..9b1edbf4361c 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/intel_memory_region.c
@@ -46,13 +46,18 @@ intel_memory_region_free_pages(struct intel_memory_region *mem,
 	return size;
 }
 
-void
+u64
 __intel_memory_region_put_pages_buddy(struct intel_memory_region *mem,
 				      struct list_head *blocks)
 {
+	u64 freed;
+
 	mutex_lock(&mem->mm_lock);
-	mem->avail += intel_memory_region_free_pages(mem, blocks);
+	freed = intel_memory_region_free_pages(mem, blocks);
+	mem->avail += freed;
 	mutex_unlock(&mem->mm_lock);
+
+	return freed;
 }
 
 void
@@ -241,6 +246,7 @@ void intel_memory_region_put(struct intel_memory_region *mem)
 
 int intel_memory_regions_hw_probe(struct drm_i915_private *i915)
 {
+	u64 lmem_total = 0;
 	int err, i;
 
 	for (i = 0; i < ARRAY_SIZE(i915->mm.regions); i++) {
@@ -260,6 +266,7 @@ int intel_memory_regions_hw_probe(struct drm_i915_private *i915)
 			break;
 		case INTEL_MEMORY_LOCAL:
 			mem = intel_setup_fake_lmem(i915);
+			lmem_total += mem->total;
 			break;
 		}
 
@@ -278,6 +285,8 @@ int intel_memory_regions_hw_probe(struct drm_i915_private *i915)
 		i915->mm.regions[i] = mem;
 	}
 
+	i915->drm.drmcg_props.memory_total = lmem_total;
+
 	return 0;
 
 out_cleanup:
diff --git a/drivers/gpu/drm/i915/intel_memory_region.h b/drivers/gpu/drm/i915/intel_memory_region.h
index 6ffc0673f005..c9fca951a372 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.h
+++ b/drivers/gpu/drm/i915/intel_memory_region.h
@@ -109,7 +109,7 @@ struct i915_buddy_block *
 __intel_memory_region_get_block_buddy(struct intel_memory_region *mem,
 				      resource_size_t size,
 				      unsigned int flags);
-void __intel_memory_region_put_pages_buddy(struct intel_memory_region *mem,
+u64 __intel_memory_region_put_pages_buddy(struct intel_memory_region *mem,
 					   struct list_head *blocks);
 void __intel_memory_region_put_block_buddy(struct i915_buddy_block *block);
 
-- 
2.20.1

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

WARNING: multiple messages have this Message-ID (diff)
From: Brian Welty <brian.welty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
To: "Brian Welty"
	<brian.welty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
	cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	"Tejun Heo" <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
	"David Airlie" <airlied-cv59FeDIM0c@public.gmane.org>,
	"Daniel Vetter" <daniel-/w4YWyX8dFk@public.gmane.org>,
	"Christian König" <christian.koenig-5C7GfCeVMHo@public.gmane.org>,
	"Kenny Ho" <Kenny.Ho-5C7GfCeVMHo@public.gmane.org>,
	amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
	"Chris Wilson"
	<chris-Y6uKTt2uX1cEflXRtASbqLVCufUGDwFn@public.gmane.org>,
	"Tvrtko Ursulin"
	<tvrtko.ursulin-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>,
	intel-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
	"Joonas Lahtinen"
	<joonas.lahtinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>,
	"Eero Tamminen"
	<eero.t.tamminen-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Subject: [RFC PATCH 9/9] drm/i915: Use memory cgroup for enforcing device memory limit
Date: Tue, 26 Jan 2021 13:46:26 -0800	[thread overview]
Message-ID: <20210126214626.16260-10-brian.welty@intel.com> (raw)
In-Reply-To: <20210126214626.16260-1-brian.welty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>

To charge device memory allocations, we need to (1) identify appropriate
cgroup to charge (currently decided at object creation time), and (2)
make the charging call at the time that memory pages are being allocated.

For (1), see prior DRM patch which associates current task's cgroup with
GEM objects as they are created.  That cgroup will be charged/uncharged
for all paging activity against the GEM object.

For (2), we call drm_get_object_charge_mem() in .get_pages callback
for the GEM object type.  Uncharging is done in .put_pages when the
memory is marked such that it can be evicted.  The try_charge() call will
fail with -ENOMEM if the current memory allocation will exceed the cgroup
device memory maximum, and allow for driver to perform memory reclaim.

We also set the total device memory reported by DRM cgroup by storing
in drm_device.drmcg_props after initializing LMEM memory regions.

FIXME: to release drm cgroup reference requires this additional patch:
  https://patchwork.freedesktop.org/patch/349029

Signed-off-by: Brian Welty <brian.welty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
---
 drivers/gpu/drm/i915/gem/i915_gem_mman.c   |  1 +
 drivers/gpu/drm/i915/gem/i915_gem_region.c | 23 ++++++++++++++++++----
 drivers/gpu/drm/i915/intel_memory_region.c | 13 ++++++++++--
 drivers/gpu/drm/i915/intel_memory_region.h |  2 +-
 4 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
index ec28a6cde49b..9fbe91d4d2f1 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -16,6 +16,7 @@
 #include "i915_gem_gtt.h"
 #include "i915_gem_ioctls.h"
 #include "i915_gem_object.h"
+#include "i915_gem_lmem.h"
 #include "i915_gem_mman.h"
 #include "i915_trace.h"
 #include "i915_user_extensions.h"
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c b/drivers/gpu/drm/i915/gem/i915_gem_region.c
index 3e3dad22a683..690b36b25984 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_region.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c
@@ -12,11 +12,14 @@ void
 i915_gem_object_put_pages_buddy(struct drm_i915_gem_object *obj,
 				struct sg_table *pages)
 {
-	__intel_memory_region_put_pages_buddy(obj->mm.region, &obj->mm.blocks);
+	u64 freed;
 
+	freed = __intel_memory_region_put_pages_buddy(obj->mm.region,
+						      &obj->mm.blocks);
 	obj->mm.dirty = false;
 	sg_free_table(pages);
 	kfree(pages);
+	drm_gem_object_uncharge_mem(&obj->base, freed);
 }
 
 int
@@ -25,7 +28,7 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj)
 	const u64 max_segment = i915_sg_segment_size();
 	struct intel_memory_region *mem = obj->mm.region;
 	struct list_head *blocks = &obj->mm.blocks;
-	resource_size_t size = obj->base.size;
+	resource_size_t charged, size = obj->base.size;
 	resource_size_t prev_end;
 	struct i915_buddy_block *block;
 	unsigned int flags;
@@ -44,12 +47,22 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj)
 	}
 
 	flags = I915_ALLOC_MIN_PAGE_SIZE;
-	if (obj->flags & I915_BO_ALLOC_CONTIGUOUS)
+	if (obj->flags & I915_BO_ALLOC_CONTIGUOUS) {
 		flags |= I915_ALLOC_CONTIGUOUS;
+		charged = roundup_pow_of_two(size);
+	} else {
+		charged = size;
+	}
+
+	ret = drm_gem_object_charge_mem(&obj->base, charged);
+	if (ret) {
+		DRM_DEBUG("DRMCG: charge_mem failed for %lld\n", charged);
+		goto err_free_sg;
+	}
 
 	ret = __intel_memory_region_get_pages_buddy(mem, size, flags, blocks);
 	if (ret)
-		goto err_free_sg;
+		goto err_uncharge;
 
 	GEM_BUG_ON(list_empty(blocks));
 
@@ -99,6 +112,8 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj)
 
 	return 0;
 
+err_uncharge:
+	drm_gem_object_uncharge_mem(&obj->base, charged);
 err_free_sg:
 	sg_free_table(st);
 	kfree(st);
diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c
index 1bfcdd89b241..9b1edbf4361c 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.c
+++ b/drivers/gpu/drm/i915/intel_memory_region.c
@@ -46,13 +46,18 @@ intel_memory_region_free_pages(struct intel_memory_region *mem,
 	return size;
 }
 
-void
+u64
 __intel_memory_region_put_pages_buddy(struct intel_memory_region *mem,
 				      struct list_head *blocks)
 {
+	u64 freed;
+
 	mutex_lock(&mem->mm_lock);
-	mem->avail += intel_memory_region_free_pages(mem, blocks);
+	freed = intel_memory_region_free_pages(mem, blocks);
+	mem->avail += freed;
 	mutex_unlock(&mem->mm_lock);
+
+	return freed;
 }
 
 void
@@ -241,6 +246,7 @@ void intel_memory_region_put(struct intel_memory_region *mem)
 
 int intel_memory_regions_hw_probe(struct drm_i915_private *i915)
 {
+	u64 lmem_total = 0;
 	int err, i;
 
 	for (i = 0; i < ARRAY_SIZE(i915->mm.regions); i++) {
@@ -260,6 +266,7 @@ int intel_memory_regions_hw_probe(struct drm_i915_private *i915)
 			break;
 		case INTEL_MEMORY_LOCAL:
 			mem = intel_setup_fake_lmem(i915);
+			lmem_total += mem->total;
 			break;
 		}
 
@@ -278,6 +285,8 @@ int intel_memory_regions_hw_probe(struct drm_i915_private *i915)
 		i915->mm.regions[i] = mem;
 	}
 
+	i915->drm.drmcg_props.memory_total = lmem_total;
+
 	return 0;
 
 out_cleanup:
diff --git a/drivers/gpu/drm/i915/intel_memory_region.h b/drivers/gpu/drm/i915/intel_memory_region.h
index 6ffc0673f005..c9fca951a372 100644
--- a/drivers/gpu/drm/i915/intel_memory_region.h
+++ b/drivers/gpu/drm/i915/intel_memory_region.h
@@ -109,7 +109,7 @@ struct i915_buddy_block *
 __intel_memory_region_get_block_buddy(struct intel_memory_region *mem,
 				      resource_size_t size,
 				      unsigned int flags);
-void __intel_memory_region_put_pages_buddy(struct intel_memory_region *mem,
+u64 __intel_memory_region_put_pages_buddy(struct intel_memory_region *mem,
 					   struct list_head *blocks);
 void __intel_memory_region_put_block_buddy(struct i915_buddy_block *block);
 
-- 
2.20.1

  parent reply	other threads:[~2021-01-26 21:45 UTC|newest]

Thread overview: 110+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-26 21:46 [RFC PATCH 0/9] cgroup support for GPU devices Brian Welty
2021-01-26 21:46 ` Brian Welty
2021-01-26 21:46 ` Brian Welty
2021-01-26 21:46 ` [Intel-gfx] " Brian Welty
2021-01-26 21:46 ` [RFC PATCH 1/9] cgroup: Introduce cgroup for drm subsystem Brian Welty
2021-01-26 21:46   ` Brian Welty
2021-01-26 21:46   ` Brian Welty
2021-01-26 21:46   ` [Intel-gfx] " Brian Welty
2021-01-26 21:46 ` [RFC PATCH 2/9] drm, cgroup: Bind drm and cgroup subsystem Brian Welty
2021-01-26 21:46   ` Brian Welty
2021-01-26 21:46   ` Brian Welty
2021-01-26 21:46   ` [Intel-gfx] " Brian Welty
2021-01-26 21:46 ` [RFC PATCH 3/9] drm, cgroup: Initialize drmcg properties Brian Welty
2021-01-26 21:46   ` Brian Welty
2021-01-26 21:46   ` Brian Welty
2021-01-26 21:46   ` [Intel-gfx] " Brian Welty
2021-01-26 21:46 ` [RFC PATCH 4/9] drmcg: Add skeleton seq_show and write for drmcg files Brian Welty
2021-01-26 21:46   ` Brian Welty
2021-01-26 21:46   ` Brian Welty
2021-01-26 21:46   ` [Intel-gfx] " Brian Welty
2021-01-26 21:46 ` [RFC PATCH 5/9] drmcg: Add support for device memory accounting via page counter Brian Welty
2021-01-26 21:46   ` Brian Welty
2021-01-26 21:46   ` Brian Welty
2021-01-26 21:46   ` [Intel-gfx] " Brian Welty
2021-01-27  9:14   ` kernel test robot
2021-01-26 21:46 ` [RFC PATCH 6/9] drmcg: Add memory.total file Brian Welty
2021-01-26 21:46   ` Brian Welty
2021-01-26 21:46   ` Brian Welty
2021-01-26 21:46   ` [Intel-gfx] " Brian Welty
2021-01-26 21:46 ` [RFC PATCH 7/9] drmcg: Add initial support for tracking gpu time usage Brian Welty
2021-01-26 21:46   ` Brian Welty
2021-01-26 21:46   ` Brian Welty
2021-01-26 21:46   ` [Intel-gfx] " Brian Welty
2021-02-03 13:25   ` Joonas Lahtinen
2021-02-03 13:25     ` Joonas Lahtinen
2021-02-03 13:25     ` [Intel-gfx] " Joonas Lahtinen
2021-02-04  2:23     ` Brian Welty
2021-02-04  2:23       ` Brian Welty
2021-02-04  2:23       ` Brian Welty
2021-02-04  2:23       ` [Intel-gfx] " Brian Welty
2021-01-26 21:46 ` [RFC PATCH 8/9] drm/gem: Associate GEM objects with drm cgroup Brian Welty
2021-01-26 21:46   ` Brian Welty
2021-01-26 21:46   ` Brian Welty
2021-01-26 21:46   ` [Intel-gfx] " Brian Welty
2021-02-09 10:54   ` Daniel Vetter
2021-02-09 10:54     ` Daniel Vetter
2021-02-09 10:54     ` Daniel Vetter
2021-02-09 10:54     ` [Intel-gfx] " Daniel Vetter
2021-02-10  7:52     ` Thomas Zimmermann
2021-02-10  7:52       ` Thomas Zimmermann
2021-02-10  7:52       ` Thomas Zimmermann
2021-02-10  7:52       ` [Intel-gfx] " Thomas Zimmermann
2021-02-10 12:45       ` Daniel Vetter
2021-02-10 12:45         ` Daniel Vetter
2021-02-10 12:45         ` Daniel Vetter
2021-02-10 12:45         ` [Intel-gfx] " Daniel Vetter
2021-02-10 22:00     ` Brian Welty
2021-02-10 22:00       ` Brian Welty
2021-02-10 22:00       ` Brian Welty
2021-02-10 22:00       ` [Intel-gfx] " Brian Welty
2021-02-11 15:34       ` Daniel Vetter
2021-02-11 15:34         ` Daniel Vetter
2021-02-11 15:34         ` Daniel Vetter
2021-02-11 15:34         ` [Intel-gfx] " Daniel Vetter
2021-03-06  0:44         ` Brian Welty
2021-03-06  0:44           ` Brian Welty
2021-03-06  0:44           ` Brian Welty
2021-03-06  0:44           ` [Intel-gfx] " Brian Welty
2021-03-18 10:16           ` Daniel Vetter
2021-03-18 10:16             ` Daniel Vetter
2021-03-18 10:16             ` Daniel Vetter
2021-03-18 10:16             ` [Intel-gfx] " Daniel Vetter
2021-03-18 19:20             ` Brian Welty
2021-03-18 19:20               ` Brian Welty
2021-03-18 19:20               ` Brian Welty
2021-03-18 19:20               ` [Intel-gfx] " Brian Welty
2021-05-10 15:36               ` Daniel Vetter
2021-05-10 15:36                 ` Daniel Vetter
2021-05-10 15:36                 ` Daniel Vetter
2021-05-10 15:36                 ` [Intel-gfx] " Daniel Vetter
2021-05-10 16:06                 ` Tamminen, Eero T
2021-05-10 16:06                   ` Tamminen, Eero T
2021-05-10 16:06                   ` Tamminen, Eero T
2021-05-10 16:06                   ` [Intel-gfx] " Tamminen, Eero T
2021-01-26 21:46 ` Brian Welty [this message]
2021-01-26 21:46   ` [RFC PATCH 9/9] drm/i915: Use memory cgroup for enforcing device memory limit Brian Welty
2021-01-26 21:46   ` Brian Welty
2021-01-26 21:46   ` [Intel-gfx] " Brian Welty
2021-01-27  6:04   ` kernel test robot
2021-01-26 22:37 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for cgroup support for GPU devices (rev3) Patchwork
2021-01-26 22:40 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2021-01-26 23:07 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2021-01-26 23:07 ` [Intel-gfx] ✗ Fi.CI.BUILD: warning " Patchwork
2021-01-27  4:55 ` [Intel-gfx] ✓ Fi.CI.IGT: success " Patchwork
2021-01-29  2:45 ` [RFC PATCH 0/9] cgroup support for GPU devices Xingyou Chen
2021-01-29  2:45   ` Xingyou Chen
2021-01-29  2:45   ` Xingyou Chen
2021-01-29  2:45   ` [Intel-gfx] " Xingyou Chen
2021-01-29  3:00 ` Xingyou Chen
2021-01-29  3:00   ` Xingyou Chen
2021-01-29  3:00   ` Xingyou Chen
2021-01-29  3:00   ` [Intel-gfx] " Xingyou Chen
2021-02-01 23:21   ` Brian Welty
2021-02-01 23:21     ` Brian Welty
2021-02-01 23:21     ` Brian Welty
2021-02-01 23:21     ` [Intel-gfx] " Brian Welty
2021-02-03 10:18     ` Daniel Vetter
2021-02-03 10:18       ` Daniel Vetter
2021-02-03 10:18       ` Daniel Vetter
2021-02-03 10:18       ` [Intel-gfx] " Daniel Vetter

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=20210126214626.16260-10-brian.welty@intel.com \
    --to=brian.welty@intel.com \
    --cc=Kenny.Ho@amd.com \
    --cc=airlied@linux.ie \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=cgroups@vger.kernel.org \
    --cc=chris@chris-wilson.co.uk \
    --cc=christian.koenig@amd.com \
    --cc=daniel@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=eero.t.tamminen@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=joonas.lahtinen@linux.intel.com \
    --cc=tj@kernel.org \
    --cc=tvrtko.ursulin@linux.intel.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 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.