diff options
| author | Dave Airlie <airlied@redhat.com> | 2026-09-22 15:52:47 +1000 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2026-09-22 15:52:48 +1000 |
| commit | 014ee7742bed896f1aee13ecdee5fe8c7826c0a1 (patch) | |
| tree | 7d4bc9a5544918906ed3efdb44c9e5fb67305658 /include | |
| parent | f2a214c0aaae52967e4fb1cfc0a8dc43b5d8a688 (diff) | |
| parent | 320662381ca243a3364663e917a7447afaf618fa (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.h | 71 | ||||
| -rw-r--r-- | include/uapi/drm/xe_drm.h | 22 |
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 */ |
