Skip to content

Commit

Permalink
drm/msm: Reference count address spaces
Browse files Browse the repository at this point in the history
There are reasons for a memory object to outlive the file descriptor
that created it and so the address space that a buffer object is
attached to must also outlive the file descriptor. Reference count
the address space so that it can remain viable until all the objects
have released their addresses.

Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@gmail.com>
  • Loading branch information
Jordan Crouse authored and Rob Clark committed Apr 8, 2017
1 parent 9873ef0 commit ee546cd
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 13 deletions.
2 changes: 1 addition & 1 deletion drivers/gpu/drm/msm/adreno/adreno_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,6 @@ void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
if (gpu->aspace) {
gpu->aspace->mmu->funcs->detach(gpu->aspace->mmu,
iommu_ports, ARRAY_SIZE(iommu_ports));
msm_gem_address_space_destroy(gpu->aspace);
msm_gem_address_space_put(gpu->aspace);
}
}
2 changes: 1 addition & 1 deletion drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ static void mdp4_destroy(struct msm_kms *kms)
if (aspace) {
aspace->mmu->funcs->detach(aspace->mmu,
iommu_ports, ARRAY_SIZE(iommu_ports));
msm_gem_address_space_destroy(aspace);
msm_gem_address_space_put(aspace);
}

if (mdp4_kms->rpm_enabled)
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ static void mdp5_kms_destroy(struct msm_kms *kms)
if (aspace) {
aspace->mmu->funcs->detach(aspace->mmu,
iommu_ports, ARRAY_SIZE(iommu_ports));
msm_gem_address_space_destroy(aspace);
msm_gem_address_space_put(aspace);
}
}

Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/msm/msm_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ void msm_gem_unmap_vma(struct msm_gem_address_space *aspace,
int msm_gem_map_vma(struct msm_gem_address_space *aspace,
struct msm_gem_vma *vma, struct sg_table *sgt, int npages);

void msm_gem_address_space_destroy(struct msm_gem_address_space *aspace);
void msm_gem_address_space_put(struct msm_gem_address_space *aspace);

struct msm_gem_address_space *
msm_gem_address_space_create(struct device *dev, struct iommu_domain *domain,
const char *name);
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/msm/msm_gem.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#ifndef __MSM_GEM_H__
#define __MSM_GEM_H__

#include <linux/kref.h>
#include <linux/reservation.h>
#include "msm_drv.h"

Expand All @@ -31,6 +32,7 @@ struct msm_gem_address_space {
*/
struct drm_mm mm;
struct msm_mmu *mmu;
struct kref kref;
};

struct msm_gem_vma {
Expand Down
35 changes: 26 additions & 9 deletions drivers/gpu/drm/msm/msm_gem_vma.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,25 @@
#include "msm_gem.h"
#include "msm_mmu.h"

static void
msm_gem_address_space_destroy(struct kref *kref)
{
struct msm_gem_address_space *aspace = container_of(kref,
struct msm_gem_address_space, kref);

drm_mm_takedown(&aspace->mm);
if (aspace->mmu)
aspace->mmu->funcs->destroy(aspace->mmu);
kfree(aspace);
}


void msm_gem_address_space_put(struct msm_gem_address_space *aspace)
{
if (aspace)
kref_put(&aspace->kref, msm_gem_address_space_destroy);
}

void
msm_gem_unmap_vma(struct msm_gem_address_space *aspace,
struct msm_gem_vma *vma, struct sg_table *sgt)
Expand All @@ -34,6 +53,8 @@ msm_gem_unmap_vma(struct msm_gem_address_space *aspace,
drm_mm_remove_node(&vma->node);

vma->iova = 0;

msm_gem_address_space_put(aspace);
}

int
Expand All @@ -57,16 +78,10 @@ msm_gem_map_vma(struct msm_gem_address_space *aspace,
size, IOMMU_READ | IOMMU_WRITE);
}

return ret;
}
/* Get a reference to the aspace to keep it around */
kref_get(&aspace->kref);

void
msm_gem_address_space_destroy(struct msm_gem_address_space *aspace)
{
drm_mm_takedown(&aspace->mm);
if (aspace->mmu)
aspace->mmu->funcs->destroy(aspace->mmu);
kfree(aspace);
return ret;
}

struct msm_gem_address_space *
Expand All @@ -85,5 +100,7 @@ msm_gem_address_space_create(struct device *dev, struct iommu_domain *domain,
drm_mm_init(&aspace->mm, (domain->geometry.aperture_start >> PAGE_SHIFT),
(domain->geometry.aperture_end >> PAGE_SHIFT) - 1);

kref_init(&aspace->kref);

return aspace;
}

0 comments on commit ee546cd

Please sign in to comment.