drm/tegra: Implement buffer object cache

This cache is used to avoid mapping and unmapping buffer objects
unnecessarily. Mappings are cached per client and stay hot until
the buffer object is destroyed.

Bug 200768479

Signed-off-by: Thierry Reding <treding@nvidia.com>
Change-Id: Ia2efe2b77b5043b665bae403d9eba4698e6a5228
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2596399
(cherry picked from commit d23156d94fa9499256e8082250e3bc02559f9c8d)
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2620152
Tested-by: Jonathan Hunter <jonathanh@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: Jonathan Hunter <jonathanh@nvidia.com>
Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com>
Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
This commit is contained in:
Thierry Reding
2020-02-07 16:50:52 +01:00
committed by Laxman Dewangan
parent 756aa327f1
commit 1da27ee38f
4 changed files with 14 additions and 5 deletions

View File

@@ -60,6 +60,7 @@ static struct host1x_bo_mapping *tegra_bo_pin(struct device *dev, struct host1x_
if (!map)
return ERR_PTR(-ENOMEM);
kref_init(&map->ref);
map->bo = host1x_bo_get(bo);
map->direction = direction;
map->dev = dev;
@@ -150,9 +151,6 @@ free:
static void tegra_bo_unpin(struct host1x_bo_mapping *map)
{
if (!map)
return;
if (map->attach) {
dma_buf_unmap_attachment(map->attach, map->sgt, map->direction);
dma_buf_detach(map->attach->dmabuf, map->attach);
@@ -503,8 +501,18 @@ free:
void tegra_bo_free_object(struct drm_gem_object *gem)
{
struct tegra_drm *tegra = gem->dev->dev_private;
struct host1x_bo_mapping *mapping, *tmp;
struct tegra_bo *bo = to_tegra_bo(gem);
/* remove all mappings of this buffer object from any caches */
list_for_each_entry_safe(mapping, tmp, &bo->base.mappings, list) {
if (mapping->cache)
host1x_bo_unpin(mapping);
else
dev_err(gem->dev->dev, "mapping %p stale for device %s\n", mapping,
dev_name(mapping->dev));
}
if (tegra->domain)
tegra_bo_iommu_unmap(tegra, bo);

View File

@@ -146,7 +146,7 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
struct tegra_bo *bo = tegra_fb_get_plane(state->base.fb, i);
struct host1x_bo_mapping *map;
map = host1x_bo_pin(dc->dev, &bo->base, DMA_TO_DEVICE);
map = host1x_bo_pin(dc->dev, &bo->base, DMA_TO_DEVICE, &dc->client.cache);
if (IS_ERR(map)) {
err = PTR_ERR(map);
goto unpin;

View File

@@ -43,6 +43,7 @@ gather_bo_pin(struct device *dev, struct host1x_bo *bo, enum dma_data_direction
if (!map)
return ERR_PTR(-ENOMEM);
kref_init(&map->ref);
map->bo = host1x_bo_get(bo);
map->direction = direction;
map->dev = dev;

View File

@@ -192,7 +192,7 @@ int tegra_drm_ioctl_channel_map(struct drm_device *drm, void *data,
else
direction = DMA_TO_DEVICE;
mapping->map = host1x_bo_pin(ctx->client->base.dev, mapping->bo, direction);
mapping->map = host1x_bo_pin(ctx->client->base.dev, mapping->bo, direction, NULL);
if (IS_ERR(mapping->map)) {
err = PTR_ERR(mapping->map);
goto put_gem;