From 9e283f9f40be0d357e90a355eae6d3b183073184 Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Thu, 25 Jan 2018 13:35:22 -0800 Subject: gpu: nvgpu: Add tracking of dma_buf_attachment VM and CDE code assumes that dma_buf_attachment is stored as a pointer in the private dma_buf_drvdata, so it is not tracked. In Linux trees without dma_buf_*_drvdata() support this is not true, so change the code to explicitly track dma_buf_attachment. JIRA NVGPU-4 Change-Id: I692f05a19a6469195d5444a7e5ff6e92f77ae272 Signed-off-by: Terje Bergstrom Reviewed-on: https://git-master.nvidia.com/r/1648004 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/linux/cde.c | 9 ++++++--- drivers/gpu/nvgpu/common/linux/dmabuf.c | 6 +++++- drivers/gpu/nvgpu/common/linux/dmabuf.h | 4 +++- drivers/gpu/nvgpu/common/linux/vm.c | 17 ++++++++++++----- drivers/gpu/nvgpu/include/nvgpu/linux/vm.h | 4 +++- 5 files changed, 29 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/nvgpu/common/linux/cde.c b/drivers/gpu/nvgpu/common/linux/cde.c index 040a4e3d..894e776d 100644 --- a/drivers/gpu/nvgpu/common/linux/cde.c +++ b/drivers/gpu/nvgpu/common/linux/cde.c @@ -1,7 +1,7 @@ /* * Color decompression engine support * - * Copyright (c) 2014-2017, NVIDIA Corporation. All rights reserved. + * Copyright (c) 2014-2018, NVIDIA Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -984,6 +984,7 @@ __releases(&l->cde_app->mutex) struct gk20a_comptags comptags; struct nvgpu_os_buffer os_buf = { compbits_scatter_buf, + NULL, dev_from_gk20a(g) }; u64 mapped_compbits_offset = 0; @@ -999,6 +1000,7 @@ __releases(&l->cde_app->mutex) int err, i; const s16 compbits_kind = 0; u32 submit_op; + struct dma_buf_attachment *attachment; gk20a_dbg(gpu_dbg_cde, "compbits_byte_offset=%llu scatterbuffer_byte_offset=%llu", compbits_byte_offset, scatterbuffer_byte_offset); @@ -1093,7 +1095,8 @@ __releases(&l->cde_app->mutex) gk20a_dbg(gpu_dbg_cde, "surface=0x%p scatterBuffer=0x%p", surface, scatter_buffer); - sgt = gk20a_mm_pin(dev_from_gk20a(g), compbits_scatter_buf); + sgt = gk20a_mm_pin(dev_from_gk20a(g), compbits_scatter_buf, + &attachment); if (IS_ERR(sgt)) { nvgpu_warn(g, "mm_pin failed"); @@ -1106,7 +1109,7 @@ __releases(&l->cde_app->mutex) WARN_ON(err); gk20a_mm_unpin(dev_from_gk20a(g), compbits_scatter_buf, - sgt); + attachment, sgt); if (err) goto exit_unmap_surface; } diff --git a/drivers/gpu/nvgpu/common/linux/dmabuf.c b/drivers/gpu/nvgpu/common/linux/dmabuf.c index 580dfcae..129739f0 100644 --- a/drivers/gpu/nvgpu/common/linux/dmabuf.c +++ b/drivers/gpu/nvgpu/common/linux/dmabuf.c @@ -83,7 +83,8 @@ enum nvgpu_aperture gk20a_dmabuf_aperture(struct gk20a *g, } } -struct sg_table *gk20a_mm_pin(struct device *dev, struct dma_buf *dmabuf) +struct sg_table *gk20a_mm_pin(struct device *dev, struct dma_buf *dmabuf, + struct dma_buf_attachment **attachment) { struct gk20a_dmabuf_priv *priv; @@ -111,10 +112,12 @@ struct sg_table *gk20a_mm_pin(struct device *dev, struct dma_buf *dmabuf) priv->pin_count++; nvgpu_mutex_release(&priv->lock); + *attachment = priv->attach; return priv->sgt; } void gk20a_mm_unpin(struct device *dev, struct dma_buf *dmabuf, + struct dma_buf_attachment *attachment, struct sg_table *sgt) { struct gk20a_dmabuf_priv *priv = dma_buf_get_drvdata(dmabuf, dev); @@ -125,6 +128,7 @@ void gk20a_mm_unpin(struct device *dev, struct dma_buf *dmabuf, nvgpu_mutex_acquire(&priv->lock); WARN_ON(priv->sgt != sgt); + WARN_ON(priv->attach != attachment); priv->pin_count--; WARN_ON(priv->pin_count < 0); dma_addr = sg_dma_address(priv->sgt->sgl); diff --git a/drivers/gpu/nvgpu/common/linux/dmabuf.h b/drivers/gpu/nvgpu/common/linux/dmabuf.h index d30ff5a5..8399eaaf 100644 --- a/drivers/gpu/nvgpu/common/linux/dmabuf.h +++ b/drivers/gpu/nvgpu/common/linux/dmabuf.h @@ -48,8 +48,10 @@ struct gk20a_dmabuf_priv { u64 buffer_id; }; -struct sg_table *gk20a_mm_pin(struct device *dev, struct dma_buf *dmabuf); +struct sg_table *gk20a_mm_pin(struct device *dev, struct dma_buf *dmabuf, + struct dma_buf_attachment **attachment); void gk20a_mm_unpin(struct device *dev, struct dma_buf *dmabuf, + struct dma_buf_attachment *attachment, struct sg_table *sgt); int gk20a_dmabuf_alloc_drvdata(struct dma_buf *dmabuf, struct device *dev); diff --git a/drivers/gpu/nvgpu/common/linux/vm.c b/drivers/gpu/nvgpu/common/linux/vm.c index 4529a322..e3ca4eda 100644 --- a/drivers/gpu/nvgpu/common/linux/vm.c +++ b/drivers/gpu/nvgpu/common/linux/vm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -150,7 +150,8 @@ struct nvgpu_mapped_buf *nvgpu_vm_find_mapping(struct vm_gk20a *vm, * If we find the mapping here then that means we have mapped it already * and the prior pin and get must be undone. */ - gk20a_mm_unpin(os_buf->dev, os_buf->dmabuf, mapped_buffer->os_priv.sgt); + gk20a_mm_unpin(os_buf->dev, os_buf->dmabuf, os_buf->attachment, + mapped_buffer->os_priv.sgt); dma_buf_put(os_buf->dmabuf); nvgpu_log(g, gpu_dbg_map, @@ -184,21 +185,25 @@ int nvgpu_vm_map_linux(struct vm_gk20a *vm, { struct gk20a *g = gk20a_from_vm(vm); struct device *dev = dev_from_gk20a(g); - struct nvgpu_os_buffer os_buf = { dmabuf, dev }; + struct nvgpu_os_buffer os_buf; struct sg_table *sgt; struct nvgpu_sgt *nvgpu_sgt = NULL; struct nvgpu_mapped_buf *mapped_buffer = NULL; + struct dma_buf_attachment *attachment; u64 map_addr = 0ULL; int err = 0; if (flags & NVGPU_VM_MAP_FIXED_OFFSET) map_addr = offset_align; - sgt = gk20a_mm_pin(dev, dmabuf); + sgt = gk20a_mm_pin(dev, dmabuf, &attachment); if (IS_ERR(sgt)) { nvgpu_warn(g, "Failed to pin dma_buf!"); return PTR_ERR(sgt); } + os_buf.dmabuf = dmabuf; + os_buf.attachment = attachment; + os_buf.dev = dev; if (gk20a_dmabuf_aperture(g, dmabuf) == APERTURE_INVALID) { err = -EINVAL; @@ -232,13 +237,14 @@ int nvgpu_vm_map_linux(struct vm_gk20a *vm, } mapped_buffer->os_priv.dmabuf = dmabuf; + mapped_buffer->os_priv.attachment = attachment; mapped_buffer->os_priv.sgt = sgt; *gpu_va = mapped_buffer->addr; return 0; clean_up: - gk20a_mm_unpin(dev, dmabuf, sgt); + gk20a_mm_unpin(dev, dmabuf, attachment, sgt); return err; } @@ -316,6 +322,7 @@ void nvgpu_vm_unmap_system(struct nvgpu_mapped_buf *mapped_buffer) struct vm_gk20a *vm = mapped_buffer->vm; gk20a_mm_unpin(dev_from_vm(vm), mapped_buffer->os_priv.dmabuf, + mapped_buffer->os_priv.attachment, mapped_buffer->os_priv.sgt); dma_buf_put(mapped_buffer->os_priv.dmabuf); diff --git a/drivers/gpu/nvgpu/include/nvgpu/linux/vm.h b/drivers/gpu/nvgpu/include/nvgpu/linux/vm.h index d9f082af..97b8334b 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/linux/vm.h +++ b/drivers/gpu/nvgpu/include/nvgpu/linux/vm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, @@ -41,11 +41,13 @@ struct nvgpu_vm_area; struct nvgpu_os_buffer { struct dma_buf *dmabuf; + struct dma_buf_attachment *attachment; struct device *dev; }; struct nvgpu_mapped_buf_priv { struct dma_buf *dmabuf; + struct dma_buf_attachment *attachment; struct sg_table *sgt; }; -- cgit v1.2.2