All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matthew Auld <matthew.auld@intel.com>
To: intel-xe@lists.freedesktop.org
Cc: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
Subject: [PATCH 2/3] drm/xe: Exclude imported dma-buf BOs from the TT budget
Date: Sat,  7 Nov 2026 17:26:51 +0000	[thread overview]
Message-ID: <20261107-oom-fun-v1-2-be9eb05b82ed@intel.com> (raw)
In-Reply-To: <20261107-oom-fun-v1-0-be9eb05b82ed@intel.com>

From: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>

The TT ("system") resource manager budget is sized to total host RAM
and enforced in xe_ttm_sys_mgr_new(). Imported dma-buf BOs
(ttm_bo_type_sg) placed in XE_PL_TT are backed by external pages and
never allocate from this device's TTM pool, so they consume no host
RAM. Charging them against the host-RAM-sized budget can falsely trip
it (e.g. many peer mappings on multi-GPU systems), surfacing as a
spurious -ENOSPC/OOM while memory is actually free.

Track the bytes of ttm_bo_type_sg BOs in a new per-device counter,
mem.sys_mgr_sg_usage, and subtract it from the usage compared against
the budget. The counter is maintained in xe_ttm_sys_mgr_new() and
xe_ttm_sys_mgr_del().

v2 (Matt, Sashiko)
  - Use a separate charged counter instead of subtracting import usage
    from the manager usage, avoiding an unsigned underflow race.
  - Don't dereference the BO in the free path, since the resource may
    have been transferred to a ghost object by then.
  - Make the memory region query report the charged usage.

Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs")
Signed-off-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
---
 drivers/gpu/drm/xe/xe_device_types.h |  6 ++++++
 drivers/gpu/drm/xe/xe_query.c        |  3 ++-
 drivers/gpu/drm/xe/xe_ttm_sys_mgr.c  | 38 ++++++++++++++++++++++++++++++++----
 drivers/gpu/drm/xe/xe_ttm_sys_mgr.h  |  3 +++
 4 files changed, 45 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
index d99881c6e1d5..c70f17ca8bba 100644
--- a/drivers/gpu/drm/xe/xe_device_types.h
+++ b/drivers/gpu/drm/xe/xe_device_types.h
@@ -298,6 +298,12 @@ struct xe_device {
 		struct xe_vram_region *vram;
 		/** @mem.sys_mgr: system TTM manager */
 		struct ttm_resource_manager sys_mgr;
+		/**
+		 * @mem.sys_mgr_charged: bytes charged against the @mem.sys_mgr
+		 * budget. Excludes imported dma-bufs (e.g. peer-GPU VRAM mapped
+		 * for P2P), which consume no local system memory.
+		 */
+		atomic64_t sys_mgr_charged;
 		/** @mem.shrinker: system memory shrinker. */
 		struct xe_shrinker *shrinker;
 		/** @mem.stolen_mgr: stolen memory manager. */
diff --git a/drivers/gpu/drm/xe/xe_query.c b/drivers/gpu/drm/xe/xe_query.c
index dc975f595368..ab3a4ca79e75 100644
--- a/drivers/gpu/drm/xe/xe_query.c
+++ b/drivers/gpu/drm/xe/xe_query.c
@@ -27,6 +27,7 @@
 #include "xe_mmio.h"
 #include "xe_oa.h"
 #include "xe_pxp.h"
+#include "xe_ttm_sys_mgr.h"
 #include "xe_ttm_vram_mgr.h"
 #include "xe_vram_types.h"
 #include "xe_wa.h"
@@ -278,7 +279,7 @@ static int query_mem_regions(struct xe_device *xe,
 	mem_regions->mem_regions[0].instance = 0;
 	mem_regions->mem_regions[0].min_page_size = PAGE_SIZE;
 	mem_regions->mem_regions[0].total_size = man->size << PAGE_SHIFT;
-	mem_regions->mem_regions[0].used = ttm_resource_manager_usage(man);
+	mem_regions->mem_regions[0].used = xe_ttm_sys_mgr_usage(xe);
 	mem_regions->num_mem_regions = 1;
 
 	for (i = XE_PL_VRAM0; i <= XE_PL_VRAM1; ++i) {
diff --git a/drivers/gpu/drm/xe/xe_ttm_sys_mgr.c b/drivers/gpu/drm/xe/xe_ttm_sys_mgr.c
index 9d77ba605aec..24e2c690d992 100644
--- a/drivers/gpu/drm/xe/xe_ttm_sys_mgr.c
+++ b/drivers/gpu/drm/xe/xe_ttm_sys_mgr.c
@@ -16,9 +16,15 @@
 
 struct xe_ttm_sys_node {
 	struct ttm_buffer_object *tbo;
+	bool charged;
 	struct ttm_range_mgr_node base;
 };
 
+static atomic64_t *to_charged_usage(struct ttm_resource_manager *man)
+{
+	return &container_of(man, struct xe_device, mem.sys_mgr)->mem.sys_mgr_charged;
+}
+
 static inline struct xe_ttm_sys_node *
 to_xe_ttm_sys_node(struct ttm_resource *res)
 {
@@ -40,10 +46,21 @@ static int xe_ttm_sys_mgr_new(struct ttm_resource_manager *man,
 	node->tbo = tbo;
 	ttm_resource_init(tbo, place, &node->base.base);
 
-	if (!(place->flags & TTM_PL_FLAG_TEMPORARY) &&
-	    ttm_resource_manager_usage(man) > (man->size << PAGE_SHIFT)) {
-		r = -ENOSPC;
-		goto err_fini;
+	/*
+	 * Imported dma-bufs are backed by the exporter (possibly peer VRAM),
+	 * so don't charge them against the local system memory budget.
+	 */
+	if (tbo->type != ttm_bo_type_sg) {
+		u64 size = node->base.base.size;
+		u64 usage = atomic64_add_return(size, to_charged_usage(man));
+
+		if (!(place->flags & TTM_PL_FLAG_TEMPORARY) &&
+		    usage > (man->size << PAGE_SHIFT)) {
+			atomic64_sub(size, to_charged_usage(man));
+			r = -ENOSPC;
+			goto err_fini;
+		}
+		node->charged = true;
 	}
 
 	node->base.mm_nodes[0].start = 0;
@@ -65,6 +82,8 @@ static void xe_ttm_sys_mgr_del(struct ttm_resource_manager *man,
 {
 	struct xe_ttm_sys_node *node = to_xe_ttm_sys_node(res);
 
+	if (node->charged)
+		atomic64_sub(res->size, to_charged_usage(man));
 	ttm_resource_fini(man, res);
 	kfree(node);
 }
@@ -117,3 +136,14 @@ int xe_ttm_sys_mgr_init(struct xe_device *xe)
 	ttm_resource_manager_set_used(man, true);
 	return drmm_add_action_or_reset(&xe->drm, xe_ttm_sys_mgr_fini, xe);
 }
+
+/**
+ * xe_ttm_sys_mgr_usage() - System memory charged against the TT budget
+ * @xe: The xe device.
+ *
+ * Return: Bytes of system memory in use, excluding imported dma-bufs.
+ */
+u64 xe_ttm_sys_mgr_usage(struct xe_device *xe)
+{
+	return atomic64_read(&xe->mem.sys_mgr_charged);
+}
diff --git a/drivers/gpu/drm/xe/xe_ttm_sys_mgr.h b/drivers/gpu/drm/xe/xe_ttm_sys_mgr.h
index e8f5cd395b28..0b4678a05986 100644
--- a/drivers/gpu/drm/xe/xe_ttm_sys_mgr.h
+++ b/drivers/gpu/drm/xe/xe_ttm_sys_mgr.h
@@ -6,8 +6,11 @@
 #ifndef _XE_TTM_SYS_MGR_H_
 #define _XE_TTM_SYS_MGR_H_
 
+#include <linux/types.h>
+
 struct xe_device;
 
 int xe_ttm_sys_mgr_init(struct xe_device *xe);
+u64 xe_ttm_sys_mgr_usage(struct xe_device *xe);
 
 #endif

-- 
2.56.0

  parent reply	other threads:[~2026-11-07 17:27 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-07 17:26 [PATCH 0/3] Spurious OOM with P2P dma-buf imports on multi-GPU systems Matthew Auld
2026-11-07 17:26 ` [PATCH 1/3] drm/xe: don't allocate fake mmap offsets for imported dma-bufs Matthew Auld
2026-11-07 17:43   ` sashiko-bot
2026-11-07 17:26 ` Matthew Auld [this message]
2026-11-07 17:36   ` [PATCH 2/3] drm/xe: Exclude imported dma-buf BOs from the TT budget sashiko-bot
2026-11-07 17:26 ` [PATCH 3/3] drm/ttm, drm/xe: Drop the ttm_tt on null moves to VRAM Matthew Auld
2026-11-07 17:36 ` ✓ CI.KUnit: success for Spurious OOM with P2P dma-buf imports on multi-GPU systems Patchwork
2026-11-07 18:10 ` ✓ Xe.CI.BAT: " Patchwork
2026-11-08  8:22 ` ✓ Xe.CI.FULL: " Patchwork

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=20261107-oom-fun-v1-2-be9eb05b82ed@intel.com \
    --to=matthew.auld@intel.com \
    --cc=himal.prasad.ghimiray@intel.com \
    --cc=intel-xe@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.