This patch fixes gather's BO refcounting on a pinning error. Gather's BO
won't be leaked now if something goes wrong.

Signed-off-by: Dmitry Osipenko <dig...@gmail.com>
---
 drivers/gpu/host1x/job.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c
index a954bd41aa79..89b6c14b7392 100644
--- a/drivers/gpu/host1x/job.c
+++ b/drivers/gpu/host1x/job.c
@@ -105,6 +105,7 @@ static unsigned int pin_job(struct host1x *host, struct 
host1x_job *job)
 {
        struct host1x_client *client = job->client;
        struct device *dev = client->dev;
+       struct host1x_job_gather *g;
        struct iommu_domain *domain;
        unsigned int i;
        int err;
@@ -194,7 +195,6 @@ static unsigned int pin_job(struct host1x *host, struct 
host1x_job *job)
                return 0;
 
        for (i = 0; i < job->num_gathers; i++) {
-               struct host1x_job_gather *g = &job->gathers[i];
                size_t gather_size = 0;
                struct scatterlist *sg;
                struct sg_table *sgt;
@@ -204,6 +204,7 @@ static unsigned int pin_job(struct host1x *host, struct 
host1x_job *job)
                dma_addr_t *phys;
                unsigned int j;
 
+               g = &job->gathers[i];
                g->bo = host1x_bo_get(g->bo);
                if (!g->bo) {
                        err = -EINVAL;
@@ -223,7 +224,7 @@ static unsigned int pin_job(struct host1x *host, struct 
host1x_job *job)
                sgt = host1x_bo_pin(host->dev, g->bo, phys);
                if (IS_ERR(sgt)) {
                        err = PTR_ERR(sgt);
-                       goto unpin;
+                       goto put;
                }
 
                if (host->domain) {
@@ -236,7 +237,7 @@ static unsigned int pin_job(struct host1x *host, struct 
host1x_job *job)
                                           host->iova_end >> shift, true);
                        if (!alloc) {
                                err = -ENOMEM;
-                               goto unpin;
+                               goto put;
                        }
 
                        err = iommu_map_sg(host->domain,
@@ -245,7 +246,7 @@ static unsigned int pin_job(struct host1x *host, struct 
host1x_job *job)
                        if (err == 0) {
                                __free_iova(&host->iova, alloc);
                                err = -EINVAL;
-                               goto unpin;
+                               goto put;
                        }
 
                        job->unpins[job->num_unpins].size = gather_size;
@@ -255,7 +256,7 @@ static unsigned int pin_job(struct host1x *host, struct 
host1x_job *job)
                                         DMA_TO_DEVICE);
                        if (!err) {
                                err = -ENOMEM;
-                               goto unpin;
+                               goto put;
                        }
 
                        job->unpins[job->num_unpins].dir = DMA_TO_DEVICE;
@@ -273,6 +274,8 @@ static unsigned int pin_job(struct host1x *host, struct 
host1x_job *job)
 
        return 0;
 
+put:
+       host1x_bo_put(g->bo);
 unpin:
        host1x_job_unpin(job);
        return err;
-- 
2.26.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to