drm/i915/gem: Atomically invalidate userptr on mmu-notifier
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
This commit is contained in:
parent
31accc37ea
commit
86ceaaaec5
@ -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
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
@ -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__ */
|
@ -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;
|
||||
|
@ -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(>->uc);
|
||||
intel_wopcm_init(>->wopcm);
|
||||
|
Loading…
x
Reference in New Issue
Block a user