In case that etnaviv_gem_get_pages is unable to get the required pages the object mutex needs to be unlocked. Also return NULL in this case instead of propagating the error, as callers of this function might not be prepared to handle a pointer error, but expect this call to follow the semantics of a plain vmap to return NULL in case of an error.
Signed-off-by: Lucas Stach l.stach@pengutronix.de --- drivers/gpu/drm/etnaviv/etnaviv_dump.c | 2 +- drivers/gpu/drm/etnaviv/etnaviv_gem.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_dump.c b/drivers/gpu/drm/etnaviv/etnaviv_dump.c index fd7d3e989e79..09a759e69dd2 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_dump.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_dump.c @@ -216,7 +216,7 @@ void etnaviv_core_dump(struct etnaviv_gpu *gpu) iter.hdr->iova = cpu_to_le64(vram->iova);
vaddr = etnaviv_gem_vaddr(&obj->base); - if (vaddr && !IS_ERR(vaddr)) + if (vaddr) memcpy(iter.data, vaddr, obj->base.size);
etnaviv_core_dump_header(&iter, ETDUMP_BUF_BO, iter.data + diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c index 9f77c3b94cc6..b22712fdd31e 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c @@ -361,8 +361,10 @@ void *etnaviv_gem_vaddr(struct drm_gem_object *obj) if (!etnaviv_obj->vaddr) { struct page **pages = etnaviv_gem_get_pages(etnaviv_obj);
- if (IS_ERR(pages)) - return ERR_CAST(pages); + if (IS_ERR(pages)) { + mutex_unlock(&etnaviv_obj->lock); + return NULL; + }
etnaviv_obj->vaddr = vmap(pages, obj->size >> PAGE_SHIFT, VM_MAP, pgprot_writecombine(PAGE_KERNEL));
When trying to get the vmap address of an imported buffer, we must call into the appropriate helper function, to allow the exporter to establish the vmap, instead of trying to vmap the buffer on our own.
Signed-off-by: Lucas Stach l.stach@pengutronix.de --- drivers/gpu/drm/etnaviv/etnaviv_gem.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c index b22712fdd31e..ce458d8473fe 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c @@ -14,6 +14,7 @@ * this program. If not, see http://www.gnu.org/licenses/. */
+#include <linux/dma-buf.h> #include <linux/spinlock.h> #include <linux/shmem_fs.h>
@@ -357,8 +358,14 @@ void *etnaviv_gem_vaddr(struct drm_gem_object *obj) { struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
+ if (etnaviv_obj->vaddr) + return etnaviv_obj->vaddr; + mutex_lock(&etnaviv_obj->lock); - if (!etnaviv_obj->vaddr) { + if (etnaviv_obj->base.import_attach) { + etnaviv_obj->vaddr = + dma_buf_vmap(etnaviv_obj->base.import_attach->dmabuf); + } else { struct page **pages = etnaviv_gem_get_pages(etnaviv_obj);
if (IS_ERR(pages)) {
On Tue, Jan 26, 2016 at 04:45:26PM +0100, Lucas Stach wrote:
When trying to get the vmap address of an imported buffer, we must call into the appropriate helper function, to allow the exporter to establish the vmap, instead of trying to vmap the buffer on our own.
Rather than this way, please add a vmap() method to struct etnaviv_gem_ops and indirect through that.
On Tue, Jan 26, 2016 at 04:45:25PM +0100, Lucas Stach wrote:
In case that etnaviv_gem_get_pages is unable to get the required pages the object mutex needs to be unlocked. Also return NULL in this case instead of propagating the error, as callers of this function might not be prepared to handle a pointer error, but expect this call to follow the semantics of a plain vmap to return NULL in case of an error.
If we're giving it vmap() semantics, then let's add another patch which calls this function etnaviv_gem_vmap()...
dri-devel@lists.freedesktop.org