]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/i915/gem: Atomically invalidate userptr on mmu-notifier
authorJonathan Cavitt <jonathan.cavitt@intel.com>
Tue, 28 Nov 2023 16:25:05 +0000 (08:25 -0800)
committerAndi Shyti <andi.shyti@linux.intel.com>
Tue, 19 Dec 2023 15:56:39 +0000 (16:56 +0100)
Never block for outstanding work on userptr object upon receipt of a
mmu-notifier. The reason we originally did so was to immediately unbind
the userptr and unpin its pages, but since that has been dropped in
commit b4b9731b02c3c ("drm/i915: Simplify userptr locking"), we never
return the pages to the system i.e. never drop our page->mapcount and so
do not allow the page and CPU PTE to be revoked. Based on this history,
we know we are safe to drop the wait entirely.

Upon return from mmu-notifier, we will still have the userptr pages
pinned preventing the following PTE operation (such as try_to_unmap)
adjusting the vm_area_struct, so it is safe to keep the pages around for
as long as we still have i/o pending.

We do not have any means currently to asynchronously revalidate the
userptr pages, that is always prior to next use.

Signed-off-by: Chris Wilson <chris.p.wilson@linux.intel.com>
Signed-off-by: Jonathan Cavitt <jonathan.cavitt@intel.com>
Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
Signed-off-by: Andi Shyti <andi.shyti@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231128162505.3493942-1-jonathan.cavitt@intel.com
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
drivers/gpu/drm/i915/gem/i915_gem_userptr.c
drivers/gpu/drm/i915/gem/i915_gem_userptr.h [deleted file]
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c

index 12cb2ef8dbd62eaed6dbc54fc0547551fc0dd74c..8968a09f3e441011956d2f25d38da446ca1ec3df 100644 (file)
@@ -2159,12 +2159,6 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb)
 
 #ifdef CONFIG_MMU_NOTIFIER
        if (!err && (eb->args->flags & __EXEC_USERPTR_USED)) {
-               read_lock(&eb->i915->mm.notifier_lock);
-
-               /*
-                * count is always at least 1, otherwise __EXEC_USERPTR_USED
-                * could not have been set
-                */
                for (i = 0; i < count; i++) {
                        struct eb_vma *ev = &eb->vma[i];
                        struct drm_i915_gem_object *obj = ev->vma->obj;
@@ -2176,8 +2170,6 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb)
                        if (err)
                                break;
                }
-
-               read_unlock(&eb->i915->mm.notifier_lock);
        }
 #endif
 
index 1d3ebdf4069b5d0fea98aefdb2b1609f82b9650e..0e21ce9d3e5ac04377cb385a2f5a1893e8b1b19b 100644 (file)
@@ -42,7 +42,6 @@
 #include "i915_drv.h"
 #include "i915_gem_ioctls.h"
 #include "i915_gem_object.h"
-#include "i915_gem_userptr.h"
 #include "i915_scatterlist.h"
 
 #ifdef CONFIG_MMU_NOTIFIER
@@ -61,36 +60,7 @@ static bool i915_gem_userptr_invalidate(struct mmu_interval_notifier *mni,
                                        const struct mmu_notifier_range *range,
                                        unsigned long cur_seq)
 {
-       struct drm_i915_gem_object *obj = container_of(mni, struct drm_i915_gem_object, userptr.notifier);
-       struct drm_i915_private *i915 = to_i915(obj->base.dev);
-       long r;
-
-       if (!mmu_notifier_range_blockable(range))
-               return false;
-
-       write_lock(&i915->mm.notifier_lock);
-
        mmu_interval_set_seq(mni, cur_seq);
-
-       write_unlock(&i915->mm.notifier_lock);
-
-       /*
-        * We don't wait when the process is exiting. This is valid
-        * because the object will be cleaned up anyway.
-        *
-        * This is also temporarily required as a hack, because we
-        * cannot currently force non-consistent batch buffers to preempt
-        * and reschedule by waiting on it, hanging processes on exit.
-        */
-       if (current->flags & PF_EXITING)
-               return true;
-
-       /* we will unbind on next submission, still have userptr pins */
-       r = dma_resv_wait_timeout(obj->base.resv, DMA_RESV_USAGE_BOOKKEEP, false,
-                                 MAX_SCHEDULE_TIMEOUT);
-       if (r <= 0)
-               drm_err(&i915->drm, "(%ld) failed to wait for idle\n", r);
-
        return true;
 }
 
@@ -580,15 +550,3 @@ i915_gem_userptr_ioctl(struct drm_device *dev,
 #endif
 }
 
-int i915_gem_init_userptr(struct drm_i915_private *dev_priv)
-{
-#ifdef CONFIG_MMU_NOTIFIER
-       rwlock_init(&dev_priv->mm.notifier_lock);
-#endif
-
-       return 0;
-}
-
-void i915_gem_cleanup_userptr(struct drm_i915_private *dev_priv)
-{
-}
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.h b/drivers/gpu/drm/i915/gem/i915_gem_userptr.h
deleted file mode 100644 (file)
index 8dadb2f..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * Copyright © 2021 Intel Corporation
- */
-
-#ifndef __I915_GEM_USERPTR_H__
-#define __I915_GEM_USERPTR_H__
-
-struct drm_i915_private;
-
-int i915_gem_init_userptr(struct drm_i915_private *dev_priv);
-void i915_gem_cleanup_userptr(struct drm_i915_private *dev_priv);
-
-#endif /* __I915_GEM_USERPTR_H__ */
index 6a2a78c61f212c7c8178012ab6676015903e271a..a72cecd2dbc74dbf252a93a91bec3a73d217e93f 100644 (file)
@@ -165,14 +165,6 @@ struct i915_gem_mm {
        struct notifier_block vmap_notifier;
        struct shrinker shrinker;
 
-#ifdef CONFIG_MMU_NOTIFIER
-       /**
-        * notifier_lock for mmu notifiers, memory may not be allocated
-        * while holding this lock.
-        */
-       rwlock_t notifier_lock;
-#endif
-
        /* shrinker accounting, also useful for userland debugging */
        u64 shrink_memory;
        u32 shrink_count;
index c166ad5e187a3716535fd97a67b89e7fe8e5a6a2..02e10451867a56dc96474167db5353375f6f38d9 100644 (file)
@@ -48,7 +48,6 @@
 #include "gem/i915_gem_object_frontbuffer.h"
 #include "gem/i915_gem_pm.h"
 #include "gem/i915_gem_region.h"
-#include "gem/i915_gem_userptr.h"
 #include "gt/intel_engine_user.h"
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_pm.h"
@@ -1165,10 +1164,6 @@ int i915_gem_init(struct drm_i915_private *dev_priv)
        if (intel_vgpu_active(dev_priv) && !intel_vgpu_has_huge_gtt(dev_priv))
                RUNTIME_INFO(dev_priv)->page_sizes = I915_GTT_PAGE_SIZE_4K;
 
-       ret = i915_gem_init_userptr(dev_priv);
-       if (ret)
-               return ret;
-
        for_each_gt(gt, dev_priv, i) {
                intel_uc_fetch_firmwares(&gt->uc);
                intel_wopcm_init(&gt->wopcm);