summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/drm_gpusvm.c26
-rw-r--r--drivers/gpu/drm/xe/xe_svm.c22
2 files changed, 40 insertions, 8 deletions
diff --git a/drivers/gpu/drm/drm_gpusvm.c b/drivers/gpu/drm/drm_gpusvm.c
index 958cb605aedd..abdfdaaf5e23 100644
--- a/drivers/gpu/drm/drm_gpusvm.c
+++ b/drivers/gpu/drm/drm_gpusvm.c
@@ -641,7 +641,7 @@ drm_gpusvm_range_alloc(struct drm_gpusvm *gpusvm,
range->itree.last = ALIGN(fault_addr + 1, chunk_size) - 1;
INIT_LIST_HEAD(&range->entry);
range->pages.notifier_seq = LONG_MAX;
- range->pages.flags.migrate_devmem = migrate_devmem ? 1 : 0;
+ range->flags.migrate_devmem = migrate_devmem ? 1 : 0;
return range;
}
@@ -1784,20 +1784,40 @@ EXPORT_SYMBOL_GPL(drm_gpusvm_has_mapping);
/**
* drm_gpusvm_range_set_unmapped() - Mark a GPU SVM range as unmapped
* @range: Pointer to the GPU SVM range structure.
+ * @pages: Pointer to the GPU SVM pages structure(s).
+ * @pages_count: Number of GPU SVM pages structure(s) passed in.
* @mmu_range: Pointer to the MMU notifier range structure.
*
* This function marks a GPU SVM range as unmapped and sets the partial_unmap flag
* if the range partially falls within the provided MMU notifier range.
*/
void drm_gpusvm_range_set_unmapped(struct drm_gpusvm_range *range,
+ struct drm_gpusvm_pages *pages,
+ unsigned int pages_count,
const struct mmu_notifier_range *mmu_range)
{
+ struct drm_gpusvm_range_flags range_flags = {
+ .__flags = range->flags.__flags,
+ };
+ unsigned int i;
+
lockdep_assert_held_write(&range->gpusvm->notifier_lock);
- range->pages.flags.unmapped = true;
+ range_flags.unmapped = true;
+ for (i = 0; i < pages_count; ++i) {
+ struct drm_gpusvm_pages_flags flags = {
+ .__flags = pages[i].flags.__flags,
+ };
+
+ flags.unmapped = true;
+ /* WRITE_ONCE pairs with READ_ONCE for opportunistic checks */
+ WRITE_ONCE(pages[i].flags.__flags, flags.__flags);
+ }
if (drm_gpusvm_range_start(range) < mmu_range->start ||
drm_gpusvm_range_end(range) > mmu_range->end)
- range->pages.flags.partial_unmap = true;
+ range_flags.partial_unmap = true;
+ /* WRITE_ONCE pairs with READ_ONCE for opportunistic checks */
+ WRITE_ONCE(range->flags.__flags, range_flags.__flags);
}
EXPORT_SYMBOL_GPL(drm_gpusvm_range_set_unmapped);
diff --git a/drivers/gpu/drm/xe/xe_svm.c b/drivers/gpu/drm/xe/xe_svm.c
index e0f0c23d172d..28a5d95945c3 100644
--- a/drivers/gpu/drm/xe/xe_svm.c
+++ b/drivers/gpu/drm/xe/xe_svm.c
@@ -134,7 +134,8 @@ xe_svm_garbage_collector_add_range(struct xe_vm *vm, struct xe_svm_range *range,
range_debug(range, "GARBAGE COLLECTOR ADD");
- drm_gpusvm_range_set_unmapped(&range->base, mmu_range);
+ drm_gpusvm_range_set_unmapped(&range->base, &range->base.pages, 1,
+ mmu_range);
spin_lock(&vm->svm.garbage_collector.lock);
if (list_empty(&range->garbage_collector_link))
@@ -166,7 +167,7 @@ xe_svm_range_notifier_event_begin(struct xe_vm *vm, struct drm_gpusvm_range *r,
range_debug(range, "NOTIFIER");
/* Skip if already unmapped or if no binding exist */
- if (range->base.pages.flags.unmapped || !range->tile_present)
+ if (range->base.flags.unmapped || !range->tile_present)
return 0;
range_debug(range, "NOTIFIER - EXECUTE");
@@ -1135,8 +1136,12 @@ bool xe_svm_range_needs_migrate_to_vram(struct xe_svm_range *range, struct xe_vm
{
struct xe_vm *vm = range_to_vm(&range->base);
u64 range_size = xe_svm_range_size(range);
+ struct drm_gpusvm_range_flags flags = {
+ /* READ_ONCE pairs with WRITE_ONCE in drm_gpusvm_range_set_unmapped() */
+ .__flags = READ_ONCE(range->base.flags.__flags),
+ };
- if (!range->base.pages.flags.migrate_devmem || !dpagemap)
+ if (!flags.migrate_devmem || !dpagemap)
return false;
xe_assert(vm->xe, IS_DGFX(vm->xe));
@@ -1220,6 +1225,7 @@ static int __xe_svm_handle_pagefault(struct xe_vm *vm, struct xe_vma *vma,
struct xe_validation_ctx vctx;
struct drm_exec exec;
struct xe_svm_range *range;
+ struct drm_gpusvm_range_flags range_flags;
struct dma_fence *fence;
struct drm_pagemap *dpagemap;
struct xe_tile *tile = gt_to_tile(gt);
@@ -1248,7 +1254,9 @@ retry:
xe_svm_range_fault_count_stats_incr(gt, range);
- if (ctx.devmem_only && !range->base.pages.flags.migrate_devmem)
+ /* READ_ONCE pairs with WRITE_ONCE in drm_gpusvm_range_set_unmapped() */
+ range_flags.__flags = READ_ONCE(range->base.flags.__flags);
+ if (ctx.devmem_only && !range_flags.migrate_devmem)
return -EACCES;
if (xe_svm_range_is_valid(range, tile, ctx.devmem_only, dpagemap)) {
@@ -1620,8 +1628,12 @@ int xe_svm_alloc_vram(struct xe_svm_range *range, const struct drm_gpusvm_ctx *c
struct xe_device *xe = vm->xe;
int err, retries = 1;
bool write_locked = false;
+ struct drm_gpusvm_range_flags flags = {
+ /* READ_ONCE pairs with WRITE_ONCE in drm_gpusvm_range_set_unmapped() */
+ .__flags = READ_ONCE(range->base.flags.__flags),
+ };
- xe_assert(range_to_vm(&range->base)->xe, range->base.pages.flags.migrate_devmem);
+ xe_assert(range_to_vm(&range->base)->xe, flags.migrate_devmem);
range_debug(range, "ALLOCATE VRAM");
migration_state = drm_gpusvm_scan_mm(&range->base,