Skip to content

Commit

Permalink
drm: etnaviv: Unmap gems on gem_close
Browse files Browse the repository at this point in the history
So far the unmap from gpu address space only happened when dropping the
last ref in gem_free_object_unlocked, however that is skipped if there's
still multiple handles to the same GEM object.

Since userspace (here mesa) in the case of softpin hands back the memory
region to the pool of available GPU virtual memory closing the handle
via DRM_IOCTL_GEM_CLOSE this can lead to etnaviv_iommu_insert_exact
failing later since userspace thinks the vaddr is available while the
kernel thinks it isn't making the submit fail like

  [E] submit failed: -14 (No space left on device) (etna_cmd_stream_flush:244)

Fix this by unmapping the memory via the .gem_close_object callback.

Signed-off-by: Guido Günther <agx@sigxcpu.org>
  • Loading branch information
agx authored and merge committed Apr 12, 2022
1 parent d23c023 commit fed82cb
Showing 1 changed file with 33 additions and 0 deletions.
33 changes: 33 additions & 0 deletions drivers/gpu/drm/etnaviv/etnaviv_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,38 @@ static const struct etnaviv_gem_ops etnaviv_gem_shmem_ops = {
.mmap = etnaviv_gem_mmap_obj,
};

void etnaviv_gem_close_object(struct drm_gem_object *obj, struct drm_file *unused)
{
struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
struct etnaviv_vram_mapping *mapping, *tmp;

/* Handle this via etnaviv_gem_free_object */
if (obj->handle_count == 1)
return;

WARN_ON(is_active(etnaviv_obj));

/*
* userspace wants to release the handle so we need to remove
* the mapping from the gpu's virtual address space to stay
* in sync.
*/
list_for_each_entry_safe(mapping, tmp, &etnaviv_obj->vram_list,
obj_node) {
struct etnaviv_iommu_context *context = mapping->context;

WARN_ON(mapping->use);

if (context) {
etnaviv_iommu_unmap_gem(context, mapping);
etnaviv_iommu_context_put(context);
}

list_del(&mapping->obj_node);
kfree(mapping);
}
}

void etnaviv_gem_free_object(struct drm_gem_object *obj)
{
struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
Expand Down Expand Up @@ -538,6 +570,7 @@ static const struct drm_gem_object_funcs etnaviv_gem_object_funcs = {
.vmap = etnaviv_gem_prime_vmap,
.mmap = etnaviv_gem_mmap,
.vm_ops = &vm_ops,
.close = etnaviv_gem_close_object,
};

static int etnaviv_gem_new_impl(struct drm_device *dev, u32 size, u32 flags,
Expand Down

0 comments on commit fed82cb

Please sign in to comment.