Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions drivers/accel/amdxdna/aie2_ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -939,13 +939,16 @@ static int aie2_hwctx_cu_config(struct amdxdna_hwctx *hwctx, void *buf, u32 size
static void aie2_cmd_wait(struct amdxdna_hwctx *hwctx, u64 seq)
{
struct dma_fence *out_fence = aie2_cmd_get_out_fence(hwctx, seq);
struct amdxdna_dev *xdna = hwctx->client->xdna;

if (!out_fence) {
XDNA_ERR(hwctx->client->xdna, "Failed to get fence");
XDNA_ERR(xdna, "Failed to get fence");
return;
}

mutex_unlock(&xdna->dev_lock);
dma_fence_wait_timeout(out_fence, false, MAX_SCHEDULE_TIMEOUT);
mutex_lock(&xdna->dev_lock);
dma_fence_put(out_fence);
}

Expand Down Expand Up @@ -1078,7 +1081,7 @@ static int aie2_populate_range(struct amdxdna_gem_obj *abo)
found = false;
down_write(&xdna->notifier_lock);
list_for_each_entry(mapp, &abo->mem.umap_list, node) {
if (mapp->invalid) {
if (mapp->invalid && kref_get_unless_zero(&mapp->refcnt)) {
found = true;
break;
}
Expand All @@ -1089,11 +1092,9 @@ static int aie2_populate_range(struct amdxdna_gem_obj *abo)
up_write(&xdna->notifier_lock);
return 0;
}
kref_get(&mapp->refcnt);

up_write(&xdna->notifier_lock);

XDNA_DBG(xdna, "populate memory range %lx %lx",
mapp->vma->vm_start, mapp->vma->vm_end);
mm = mapp->notifier.mm;
if (!mmget_not_zero(mm)) {
amdxdna_umap_put(mapp);
Expand Down
6 changes: 6 additions & 0 deletions drivers/accel/amdxdna/amdxdna_ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ int amdxdna_drm_destroy_hwctx_ioctl(struct drm_device *dev, void *data, struct d
if (!drm_dev_enter(dev, &idx))
return -ENODEV;

mutex_lock(&xdna->client_lock);
mutex_lock(&xdna->dev_lock);
hwctx = xa_erase(&client->hwctx_xa, args->handle);
if (!hwctx) {
Expand All @@ -345,6 +346,7 @@ int amdxdna_drm_destroy_hwctx_ioctl(struct drm_device *dev, void *data, struct d
XDNA_DBG(xdna, "PID %d destroyed HW context %d", client->pid, args->handle);
out:
mutex_unlock(&xdna->dev_lock);
mutex_unlock(&xdna->client_lock);
drm_dev_exit(idx);
return ret;
}
Expand Down Expand Up @@ -405,6 +407,7 @@ int amdxdna_drm_config_hwctx_ioctl(struct drm_device *dev, void *data, struct dr
goto free_buf;
}

mutex_lock(&xdna->client_lock);
mutex_lock(&xdna->dev_lock);
hwctx = xa_load(&client->hwctx_xa, args->handle);
if (!hwctx) {
Expand All @@ -417,6 +420,7 @@ int amdxdna_drm_config_hwctx_ioctl(struct drm_device *dev, void *data, struct dr

unlock:
mutex_unlock(&xdna->dev_lock);
mutex_unlock(&xdna->client_lock);
amdxdna_pm_suspend_put(xdna);
free_buf:
kfree(buf);
Expand Down Expand Up @@ -445,6 +449,7 @@ int amdxdna_hwctx_sync_debug_bo(struct amdxdna_client *client, u32 debug_bo_hdl)
}

abo = to_xdna_obj(gobj);
mutex_lock(&xdna->client_lock);
mutex_lock(&xdna->dev_lock);
hwctx = xa_load(&client->hwctx_xa, abo->assigned_hwctx);
if (!hwctx) {
Expand All @@ -456,6 +461,7 @@ int amdxdna_hwctx_sync_debug_bo(struct amdxdna_client *client, u32 debug_bo_hdl)

unlock:
mutex_unlock(&xdna->dev_lock);
mutex_unlock(&xdna->client_lock);
amdxdna_pm_suspend_put(xdna);
put_obj:
drm_gem_object_put(gobj);
Expand Down
36 changes: 25 additions & 11 deletions drivers/accel/amdxdna/amdxdna_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ static bool amdxdna_hmm_invalidate(struct mmu_interval_notifier *mni,

xdna = to_xdna_dev(to_gobj(abo)->dev);
XDNA_DBG(xdna, "Invalidating range 0x%lx, 0x%lx, type %d",
mapp->vma->vm_start, mapp->vma->vm_end, abo->type);
mapp->range.start, mapp->range.end, abo->type);

if (!mmu_notifier_range_blockable(range))
return false;
Expand Down Expand Up @@ -301,15 +301,23 @@ static const struct mmu_interval_notifier_ops amdxdna_hmm_ops = {
.invalidate = amdxdna_hmm_invalidate,
};

static inline bool compare_range(struct amdxdna_umap *mapp,
struct mm_struct *mm,
unsigned long start, unsigned long end)
{
return (!mapp->unmapped && mapp->notifier.mm == mm &&
mapp->range.start == start && mapp->range.end == end);
}

static void amdxdna_hmm_unregister(struct amdxdna_gem_obj *abo,
struct vm_area_struct *vma)
{
struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(abo)->dev);
struct amdxdna_umap *mapp;

down_read(&xdna->notifier_lock);
down_write(&xdna->notifier_lock);
list_for_each_entry(mapp, &abo->mem.umap_list, node) {
if (!vma || mapp->vma == vma) {
if (!vma || compare_range(mapp, vma->vm_mm, vma->vm_start, vma->vm_end)) {
if (!mapp->unmapped) {
queue_work(xdna->notifier_wq, &mapp->hmm_unreg_work);
mapp->unmapped = true;
Expand All @@ -318,19 +326,16 @@ static void amdxdna_hmm_unregister(struct amdxdna_gem_obj *abo,
break;
}
}
up_read(&xdna->notifier_lock);
up_write(&xdna->notifier_lock);
}

static void amdxdna_umap_release(struct kref *ref)
{
struct amdxdna_umap *mapp = container_of(ref, struct amdxdna_umap, refcnt);
struct amdxdna_gem_obj *abo = mapp->abo;
struct vm_area_struct *vma = mapp->vma;
struct amdxdna_dev *xdna;

mmu_interval_notifier_remove(&mapp->notifier);
if (is_import_bo(abo) && vma->vm_file && vma->vm_file->f_mapping)
mapping_clear_unevictable(vma->vm_file->f_mapping);

xdna = to_xdna_dev(to_gobj(mapp->abo)->dev);
down_write(&xdna->notifier_lock);
Expand Down Expand Up @@ -369,6 +374,15 @@ static int amdxdna_hmm_register(struct amdxdna_gem_obj *abo,
if (!amdxdna_pasid_on(abo->client))
return 0;

down_read(&xdna->notifier_lock);
list_for_each_entry(mapp, &abo->mem.umap_list, node) {
if (compare_range(mapp, current->mm, addr, addr + len)) {
up_read(&xdna->notifier_lock);
return 0;
}
}
up_read(&xdna->notifier_lock);

mapp = kzalloc_obj(*mapp);
if (!mapp)
return -ENOMEM;
Expand All @@ -394,13 +408,10 @@ static int amdxdna_hmm_register(struct amdxdna_gem_obj *abo,
mapp->range.start = vma->vm_start;
mapp->range.end = vma->vm_end;
mapp->range.default_flags = HMM_PFN_REQ_FAULT;
mapp->vma = vma;
mapp->abo = abo;
kref_init(&mapp->refcnt);

INIT_WORK(&mapp->hmm_unreg_work, amdxdna_hmm_unreg_work);
if (is_import_bo(abo) && vma->vm_file && vma->vm_file->f_mapping)
mapping_set_unevictable(vma->vm_file->f_mapping);

down_write(&xdna->notifier_lock);
if (list_empty(&abo->mem.umap_list))
Expand Down Expand Up @@ -671,8 +682,11 @@ static int amdxdna_gem_obj_open(struct drm_gem_object *gobj, struct drm_file *fi
/* No need to set up dma addr mapping in PASID mode. */
if (!amdxdna_pasid_on(abo->client)) {
ret = amdxdna_dma_map_bo(xdna, abo);
if (ret)
if (ret) {
abo->open_ref--;
abo->client = NULL;
return ret;
}
}

amdxdna_gem_add_bo_usage(abo);
Expand Down
1 change: 0 additions & 1 deletion drivers/accel/amdxdna/amdxdna_gem.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include "amdxdna_pci_drv.h"

struct amdxdna_umap {
struct vm_area_struct *vma;
struct mmu_interval_notifier notifier;
struct hmm_range range;
struct work_struct hmm_unreg_work;
Expand Down