summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2026-09-22 15:52:47 +1000
committerDave Airlie <airlied@redhat.com>2026-09-22 15:52:48 +1000
commit014ee7742bed896f1aee13ecdee5fe8c7826c0a1 (patch)
tree7d4bc9a5544918906ed3efdb44c9e5fb67305658 /include
parentf2a214c0aaae52967e4fb1cfc0a8dc43b5d8a688 (diff)
parent320662381ca243a3364663e917a7447afaf618fa (diff)
Merge tag 'drm-xe-next-2026-09-18' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-next
UAPI Changes: - Add SRCID to pagefault reporting (Jonathan) Cross-subsystem Changes: - gpusvm: share one HMM fault and keep single mappings inline (Honglei) - pagemap: Prevent CPU stalls during unbounded pagemap teardown (Varun) Driver Changes: - VRAM health check + CCS fix (Auld) - Add memory page offlining support (Tejas) - Report GT TDR and VM rebind faults using SIGID (Arvind) - Flush LSC untyped L1 dataport cache after rcs/ccs batches (Thomas) - Add multi_queue_active_lrca debugfs (Varun) - mmio_gem: fix fault handler and destroy path (Auld, Ilia, Shuicheng) - sysctrl: Add helper to query application status (Anoop) - shrinker: Runtime PM reference for non-system memory (Shuicheng) - pcode: Increase default mailbox timeout (Karthik) - Skip clearing purged page-table BOs (Tejas) - tests: Fix subplatform selection (Wajdeczko) - log: Relax location ID recognition (Wajdeczko) - i2c: Disable IRQ on unbind (Raag) - Refactor VF LMEM BAR resize helper function (Wajdeczko) - pf: Add _locked variant of config functions (Wajdeczko) - nvm: add system controller region (Alexander) - guc: Add simple KLV decoder helpers (Wajdeczko) - debugfs: Expose per-engine idle status (Anirban) - gt_throttle: Report power brake as a throttle reason on CRI (Anirban) - tlb_inval: Treat wedged-device invalidations as complete (Shuicheng) - Add mnemonic error reason to page fault diagnostics (Brost) - Keep walking on SVM eviction failure (Brost) - Make p2pdma distance check verbose via dynamic debug (Thomas) - Consolidate semaphore instruction definitions (Roper) - Poll GT for C6 before D3 (Vinay) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Matthew Brost <matthew.brost@intel.com> Link: https://patch.msgid.link/aq2UzTdN95ZpzKGz@gsse-cloud1.jf.intel.com
Diffstat (limited to 'include')
-rw-r--r--include/drm/drm_gpusvm.h71
-rw-r--r--include/uapi/drm/xe_drm.h22
2 files changed, 87 insertions, 6 deletions
diff --git a/include/drm/drm_gpusvm.h b/include/drm/drm_gpusvm.h
index b7d987bf76aa..9e35584812fd 100644
--- a/include/drm/drm_gpusvm.h
+++ b/include/drm/drm_gpusvm.h
@@ -10,6 +10,7 @@
#include <linux/kref.h>
#include <linux/interval_tree.h>
#include <linux/mmu_notifier.h>
+#include <drm/drm_pagemap.h>
struct dev_pagemap_ops;
struct drm_device;
@@ -18,7 +19,6 @@ struct drm_gpusvm_notifier;
struct drm_gpusvm_ops;
struct drm_gpusvm_range;
struct drm_pagemap;
-struct drm_pagemap_addr;
/**
* struct drm_gpusvm_ops - Operations structure for GPU SVM
@@ -112,6 +112,7 @@ struct drm_gpusvm_notifier {
* @unmapped: Flag indicating if the pages has been unmapped
* @has_devmem_pages: Flag indicating if the pages has devmem pages
* @has_dma_mapping: Flag indicating if the pages has a DMA mapping
+ * @inline_dma_mapping: Flag indicating if the pages have an inline DMA mapping
* @__flags: Flags for pages in u16 form (used for READ_ONCE)
*/
struct drm_gpusvm_pages_flags {
@@ -121,6 +122,7 @@ struct drm_gpusvm_pages_flags {
u16 unmapped : 1;
u16 has_devmem_pages : 1;
u16 has_dma_mapping : 1;
+ u16 inline_dma_mapping : 1;
};
u16 __flags;
};
@@ -130,17 +132,27 @@ struct drm_gpusvm_pages_flags {
* struct drm_gpusvm_pages - Structure representing a GPU SVM mapped pages
*
* @drm: The DRM device that owns the dma mappings
- * @dma_addr: Device address array
+ * @dma_addr: Device address array, valid while @flags.inline_dma_mapping is
+ * not set
+ * @inline_addr: Device address inline address, valid while
+ * @flags.inline_dma_mapping is set
* @dpagemap: The struct drm_pagemap of the device pages we're dma-mapping.
* Note this is assuming only one drm_pagemap per range is allowed.
* @state: DMA IOVA state for mapping.
* @state_offset: DMA IOVA offset for mapping.
* @notifier_seq: Notifier sequence number of the range's pages
* @flags: Flags for the range; see &struct drm_gpusvm_pages_flags
+ *
+ * @dma_addr and @inline_addr share storage, discriminated by
+ * @flags.inline_dma_mapping. Driver should use drm_gpusvm_pages_first_dma()
+ * to access the correct DMA address.
*/
struct drm_gpusvm_pages {
struct drm_device *drm;
- struct drm_pagemap_addr *dma_addr;
+ union {
+ struct drm_pagemap_addr *dma_addr;
+ struct drm_pagemap_addr inline_addr;
+ };
struct drm_pagemap *dpagemap;
struct dma_iova_state state;
unsigned long state_offset;
@@ -254,6 +266,14 @@ struct drm_gpusvm {
* @allow_mixed: Allow mixed mappings in get pages. Mixing between system and
* single dpagemap is supported, mixing between multiple dpagemap
* is unsupported.
+ * @no_dma_map: Only fault the CPU pages for the range; skip the device DMA
+ * mapping step. Used by drivers that consume the faulted pages
+ * without needing a DMA mapping. In this mode @drm on the
+ * drm_gpusvm_pages is not required, no mapping state is recorded
+ * and drm_gpusvm_pages_valid() therefore never reports these
+ * pages as valid; the caller revalidates the snapshot itself, see
+ * drm_gpusvm_get_pages(). @devmem_only is rejected and no page
+ * type check is performed, so @allow_mixed has no effect.
*
* Context that is DRM GPUSVM is operating in (i.e. user arguments).
*/
@@ -266,6 +286,7 @@ struct drm_gpusvm_ctx {
unsigned int devmem_possible :1;
unsigned int devmem_only :1;
unsigned int allow_mixed :1;
+ unsigned int no_dma_map :1;
};
int drm_gpusvm_init(struct drm_gpusvm *gpusvm,
@@ -324,6 +345,7 @@ void drm_gpusvm_range_set_unmapped(struct drm_gpusvm_range *range,
int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm,
struct drm_gpusvm_pages *svm_pages,
+ unsigned int num_pages,
struct mm_struct *mm,
struct mmu_interval_notifier *notifier,
unsigned long pages_start, unsigned long pages_end,
@@ -356,6 +378,49 @@ static inline void drm_gpusvm_init_pages(struct drm_gpusvm_pages *svm_pages,
}
/**
+ * drm_gpusvm_pages_first_dma() - Resolve the device address array
+ * @svm_pages: Pointer to the drm_gpusvm_pages.
+ * @contiguous: Where to store whether one entry spans the whole range, or NULL
+ *
+ * drm_gpusvm_pages use unions to optimize the storage of DMA addresses,
+ * this function abstracts the access to the first device address. The driver
+ * should use this helper instead of reading dma_addr directly to prevent
+ * array out of bounds access.
+ *
+ * @contiguous comes from the same read of the flags as the array itself, so a
+ * caller cannot see the two disagree and walk past that single entry into the
+ * fields behind it. When it is set the length comes from the range rather than
+ * from the order. The order still states what one PTE may cover: the range
+ * length for a huge page, PAGE_SIZE for an IOVA mapped range of single pages.
+ *
+ * Only get_pages() and the free path switch between the two union members.
+ * Both hold the notifier lock for read, so taking that lock does not stop
+ * them; callers need the driver lock that does, which every reader of the
+ * addresses holds anyway. The notifier never touches the union, so the
+ * pointer returned here stays good and can then be used under the notifier
+ * lock.
+ *
+ * Return: Pointer to the first device address, NULL if none is populated.
+ */
+static inline const struct drm_pagemap_addr *
+drm_gpusvm_pages_first_dma(const struct drm_gpusvm_pages *svm_pages,
+ bool *contiguous)
+{
+ struct drm_gpusvm_pages_flags flags = {
+ /* READ_ONCE pairs with the WRITE_ONCE of the flag writers */
+ .__flags = READ_ONCE(svm_pages->flags.__flags),
+ };
+
+ if (contiguous)
+ *contiguous = flags.inline_dma_mapping;
+
+ if (flags.inline_dma_mapping)
+ return &svm_pages->inline_addr;
+
+ return READ_ONCE(svm_pages->dma_addr);
+}
+
+/**
* enum drm_gpusvm_scan_result - Scan result from the drm_gpusvm_scan_mm() function.
* @DRM_GPUSVM_SCAN_UNPOPULATED: At least one page was not present or inaccessible.
* @DRM_GPUSVM_SCAN_EQUAL: All pages belong to the struct dev_pagemap indicated as
diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
index 509202a7b13e..578f0c1eb43e 100644
--- a/include/uapi/drm/xe_drm.h
+++ b/include/uapi/drm/xe_drm.h
@@ -1294,8 +1294,8 @@ struct xe_vm_fault {
#define FAULT_LEVEL_PML4 3
#define FAULT_LEVEL_PML5 4
__u8 fault_level;
- /** @pad: MBZ */
- __u8 pad;
+ /** @srcid: ID of the faulting hardware unit */
+ __u8 srcid;
/** @reserved: MBZ */
__u64 reserved[4];
};
@@ -1491,6 +1491,12 @@ struct drm_xe_exec_queue_destroy {
*
* The @property can be:
* - %DRM_XE_EXEC_QUEUE_GET_PROPERTY_BAN
+ *
+ * For %DRM_XE_EXEC_QUEUE_GET_PROPERTY_BAN, @value is a bitmask of ban reasons:
+ * - %DRM_XE_EXEC_QUEUE_BAN_REASON_GPU_HANG - banned due to GPU hang/timeout
+ * - %DRM_XE_EXEC_QUEUE_BAN_REASON_PAGE_OFFLINE - banned due to memory page offline
+ *
+ * A @value of 0 means the exec queue is not banned.
*/
struct drm_xe_exec_queue_get_property {
/** @extensions: Pointer to the first extension struct, if any */
@@ -1503,7 +1509,17 @@ struct drm_xe_exec_queue_get_property {
/** @property: property to get */
__u32 property;
- /** @value: property value */
+ /**
+ * @value: property value
+ *
+ * For %DRM_XE_EXEC_QUEUE_GET_PROPERTY_BAN, this is a bitmask of:
+ * - %DRM_XE_EXEC_QUEUE_BAN_REASON_GPU_HANG - banned due to GPU hang/timeout
+ * - %DRM_XE_EXEC_QUEUE_BAN_REASON_PAGE_OFFLINE - banned due to memory page offline
+ *
+ * Value of 0 means the exec queue is not banned.
+ */
+#define DRM_XE_EXEC_QUEUE_BAN_REASON_GPU_HANG (1 << 0)
+#define DRM_XE_EXEC_QUEUE_BAN_REASON_PAGE_OFFLINE (1 << 1)
__u64 value;
/** @reserved: Reserved */