mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-23 09:57:08 +03:00
gpu: nvgpu: avoid using priv data for non-compressed buffer
Instead of allocating priv data for all external buffers, allocate only on a demand basis for when compression is requested either in CDE or via libnvrm_gpu. This will allow allocators like nvidia-drm to use non-compressed buffers without needing to avoid the core drm checks. e.g. drm_gem_prime_import_dev that checks for if (dma_buf->ops == &drm_gem_prime_dmabuf_ops)" This patch also gets rid of optimization of dma_buf's attach/detach calls. Now, nvgpu instead needs to call attach/detach for everytime the dmabuf fd is imported. Change-Id: Idefd269b32974106e85ff09e17ebc752b92f830c Signed-off-by: Debarshi Dutta <ddutta@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2372213 Tested-by: Yogish Kulkarni <yogishk@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: automaticguardword <automaticguardword@nvidia.com> Reviewed-by: Sagar Kamble <skamble@nvidia.com> Reviewed-by: Alex Waterman <alexw@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
Alex Waterman
parent
58ce9156a8
commit
08ec6e874d
@@ -1140,10 +1140,10 @@ __releases(&l->cde_app->mutex)
|
|||||||
|
|
||||||
nvgpu_log(g, gpu_dbg_cde, "surface=0x%p scatterBuffer=0x%p",
|
nvgpu_log(g, gpu_dbg_cde, "surface=0x%p scatterBuffer=0x%p",
|
||||||
surface, scatter_buffer);
|
surface, scatter_buffer);
|
||||||
sgt = nvgpu_mm_pin_privdata(dev_from_gk20a(g), compbits_scatter_buf,
|
sgt = nvgpu_mm_pin(dev_from_gk20a(g), compbits_scatter_buf,
|
||||||
&attachment);
|
&attachment);
|
||||||
if (IS_ERR(sgt)) {
|
if (IS_ERR(sgt)) {
|
||||||
nvgpu_warn(g,
|
nvgpu_err(g,
|
||||||
"mm_pin failed");
|
"mm_pin failed");
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto exit_unmap_surface;
|
goto exit_unmap_surface;
|
||||||
@@ -1156,7 +1156,7 @@ __releases(&l->cde_app->mutex)
|
|||||||
#endif
|
#endif
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
nvgpu_warn(g, "buffer access setup failed");
|
nvgpu_warn(g, "buffer access setup failed");
|
||||||
nvgpu_mm_unpin_privdata(dev_from_gk20a(g), compbits_scatter_buf,
|
nvgpu_mm_unpin(dev_from_gk20a(g), compbits_scatter_buf,
|
||||||
attachment, sgt);
|
attachment, sgt);
|
||||||
goto exit_unmap_surface;
|
goto exit_unmap_surface;
|
||||||
}
|
}
|
||||||
@@ -1172,7 +1172,7 @@ __releases(&l->cde_app->mutex)
|
|||||||
#endif
|
#endif
|
||||||
WARN_ON(err);
|
WARN_ON(err);
|
||||||
|
|
||||||
nvgpu_mm_unpin_privdata(dev_from_gk20a(g), compbits_scatter_buf,
|
nvgpu_mm_unpin(dev_from_gk20a(g), compbits_scatter_buf,
|
||||||
attachment, sgt);
|
attachment, sgt);
|
||||||
if (err)
|
if (err)
|
||||||
goto exit_unmap_surface;
|
goto exit_unmap_surface;
|
||||||
|
|||||||
@@ -47,13 +47,21 @@ int gk20a_alloc_or_get_comptags(struct gk20a *g,
|
|||||||
struct gk20a_comptag_allocator *allocator,
|
struct gk20a_comptag_allocator *allocator,
|
||||||
struct gk20a_comptags *comptags)
|
struct gk20a_comptags *comptags)
|
||||||
{
|
{
|
||||||
struct gk20a_dmabuf_priv *priv = gk20a_dma_buf_get_drvdata(
|
int ret = 0;
|
||||||
buf->dmabuf, buf->dev);
|
|
||||||
|
struct gk20a_dmabuf_priv *priv = NULL;
|
||||||
u32 offset;
|
u32 offset;
|
||||||
int err;
|
int err;
|
||||||
u64 ctag_granularity;
|
u64 ctag_granularity;
|
||||||
u32 lines;
|
u32 lines;
|
||||||
|
|
||||||
|
ret = gk20a_dmabuf_alloc_drvdata(buf->dmabuf, buf->dev);
|
||||||
|
if (ret) {
|
||||||
|
nvgpu_err(g, "error allocating comptags priv data");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv = gk20a_dma_buf_get_drvdata(buf->dmabuf, buf->dev);
|
||||||
if (!priv)
|
if (!priv)
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ static void nvgpu_dma_buf_release(struct dma_buf *dmabuf)
|
|||||||
dmabuf->ops->release(dmabuf);
|
dmabuf->ops->release(dmabuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
int gk20a_dma_buf_set_drvdata(struct dma_buf *dmabuf, struct device *device,
|
static int gk20a_dma_buf_set_drvdata(struct dma_buf *dmabuf, struct device *device,
|
||||||
struct gk20a_dmabuf_priv *priv)
|
struct gk20a_dmabuf_priv *priv)
|
||||||
{
|
{
|
||||||
nvgpu_mutex_acquire(&priv->lock);
|
nvgpu_mutex_acquire(&priv->lock);
|
||||||
@@ -134,69 +134,40 @@ struct gk20a_dmabuf_priv *gk20a_dma_buf_get_drvdata(
|
|||||||
return priv;
|
return priv;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sg_table *nvgpu_mm_pin_privdata(struct device *dev,
|
struct sg_table *nvgpu_mm_pin(struct device *dev,
|
||||||
struct dma_buf *dmabuf, struct dma_buf_attachment **attachment)
|
struct dma_buf *dmabuf, struct dma_buf_attachment **attachment)
|
||||||
{
|
{
|
||||||
struct gk20a *g = get_gk20a(dev);
|
struct gk20a *g = get_gk20a(dev);
|
||||||
struct gk20a_dmabuf_priv *priv = NULL;
|
struct dma_buf_attachment *attach = NULL;
|
||||||
|
struct sg_table *sgt = NULL;
|
||||||
|
|
||||||
priv = gk20a_dma_buf_get_drvdata(dmabuf, dev);
|
attach = dma_buf_attach(dmabuf, dev);
|
||||||
if (!priv) {
|
if (IS_ERR(attach)) {
|
||||||
nvgpu_do_assert();
|
|
||||||
return ERR_PTR(-EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
nvgpu_mutex_acquire(&priv->lock);
|
|
||||||
|
|
||||||
if (priv->pin_count == 0) {
|
|
||||||
priv->attach = dma_buf_attach(dmabuf, dev);
|
|
||||||
if (IS_ERR(priv->attach)) {
|
|
||||||
nvgpu_mutex_release(&priv->lock);
|
|
||||||
nvgpu_err(g, "Failed to attach dma_buf (err = %ld)!",
|
nvgpu_err(g, "Failed to attach dma_buf (err = %ld)!",
|
||||||
PTR_ERR(priv->attach));
|
PTR_ERR(attach));
|
||||||
return ERR_CAST(priv->attach);
|
return ERR_CAST(attach);
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->sgt = dma_buf_map_attachment(priv->attach,
|
sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
|
||||||
DMA_BIDIRECTIONAL);
|
if (IS_ERR(sgt)) {
|
||||||
if (IS_ERR(priv->sgt)) {
|
dma_buf_detach(dmabuf, attach);
|
||||||
dma_buf_detach(dmabuf, priv->attach);
|
|
||||||
nvgpu_mutex_release(&priv->lock);
|
|
||||||
nvgpu_err(g, "Failed to map attachment (err = %ld)!",
|
nvgpu_err(g, "Failed to map attachment (err = %ld)!",
|
||||||
PTR_ERR(priv->sgt));
|
PTR_ERR(sgt));
|
||||||
return ERR_CAST(priv->sgt);
|
return ERR_CAST(sgt);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->pin_count++;
|
*attachment = attach;
|
||||||
nvgpu_mutex_release(&priv->lock);
|
|
||||||
*attachment = priv->attach;
|
return sgt;
|
||||||
return priv->sgt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nvgpu_mm_unpin_privdata(struct device *dev,
|
void nvgpu_mm_unpin(struct device *dev,
|
||||||
struct dma_buf *dmabuf,
|
struct dma_buf *dmabuf,
|
||||||
struct dma_buf_attachment *attachment,
|
struct dma_buf_attachment *attachment,
|
||||||
struct sg_table *sgt)
|
struct sg_table *sgt)
|
||||||
{
|
{
|
||||||
struct gk20a_dmabuf_priv *priv = gk20a_dma_buf_get_drvdata(dmabuf, dev);
|
dma_buf_unmap_attachment(attachment, sgt, DMA_BIDIRECTIONAL);
|
||||||
dma_addr_t dma_addr;
|
dma_buf_detach(dmabuf, attachment);
|
||||||
|
|
||||||
if (IS_ERR(priv) || !priv)
|
|
||||||
return;
|
|
||||||
|
|
||||||
nvgpu_mutex_acquire(&priv->lock);
|
|
||||||
nvgpu_assert(priv->sgt == sgt);
|
|
||||||
nvgpu_assert(priv->attach == attachment);
|
|
||||||
priv->pin_count--;
|
|
||||||
nvgpu_assert(priv->pin_count >= 0);
|
|
||||||
dma_addr = sg_dma_address(priv->sgt->sgl);
|
|
||||||
if (priv->pin_count == 0) {
|
|
||||||
dma_buf_unmap_attachment(priv->attach, priv->sgt,
|
|
||||||
DMA_BIDIRECTIONAL);
|
|
||||||
dma_buf_detach(dmabuf, priv->attach);
|
|
||||||
}
|
|
||||||
nvgpu_mutex_release(&priv->lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function must be called after acquiring the global level
|
/* This function must be called after acquiring the global level
|
||||||
|
|||||||
@@ -74,11 +74,6 @@ struct gk20a_dmabuf_priv {
|
|||||||
struct gk20a_comptag_allocator *comptag_allocator;
|
struct gk20a_comptag_allocator *comptag_allocator;
|
||||||
struct gk20a_comptags comptags;
|
struct gk20a_comptags comptags;
|
||||||
|
|
||||||
struct dma_buf_attachment *attach;
|
|
||||||
struct sg_table *sgt;
|
|
||||||
|
|
||||||
int pin_count;
|
|
||||||
|
|
||||||
struct nvgpu_list_node states;
|
struct nvgpu_list_node states;
|
||||||
|
|
||||||
u64 buffer_id;
|
u64 buffer_id;
|
||||||
@@ -102,11 +97,11 @@ struct gk20a_dmabuf_priv {
|
|||||||
struct nvgpu_list_node list;
|
struct nvgpu_list_node list;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sg_table *nvgpu_mm_pin_privdata(struct device *dev,
|
struct sg_table *nvgpu_mm_pin(struct device *dev,
|
||||||
struct dma_buf *dmabuf,
|
struct dma_buf *dmabuf,
|
||||||
struct dma_buf_attachment **attachment);
|
struct dma_buf_attachment **attachment);
|
||||||
|
|
||||||
void nvgpu_mm_unpin_privdata(struct device *dev,
|
void nvgpu_mm_unpin(struct device *dev,
|
||||||
struct dma_buf *dmabuf,
|
struct dma_buf *dmabuf,
|
||||||
struct dma_buf_attachment *attachment,
|
struct dma_buf_attachment *attachment,
|
||||||
struct sg_table *sgt);
|
struct sg_table *sgt);
|
||||||
@@ -118,8 +113,6 @@ int gk20a_dmabuf_alloc_drvdata(struct dma_buf *dmabuf, struct device *dev);
|
|||||||
int gk20a_dmabuf_get_state(struct dma_buf *dmabuf, struct gk20a *g,
|
int gk20a_dmabuf_get_state(struct dma_buf *dmabuf, struct gk20a *g,
|
||||||
u64 offset, struct gk20a_buffer_state **state);
|
u64 offset, struct gk20a_buffer_state **state);
|
||||||
|
|
||||||
int gk20a_dma_buf_set_drvdata(struct dma_buf *dmabuf, struct device *device,
|
|
||||||
struct gk20a_dmabuf_priv *priv);
|
|
||||||
void gk20a_dma_buf_priv_list_clear(struct nvgpu_os_linux *l);
|
void gk20a_dma_buf_priv_list_clear(struct nvgpu_os_linux *l);
|
||||||
struct gk20a_dmabuf_priv *gk20a_dma_buf_get_drvdata(
|
struct gk20a_dmabuf_priv *gk20a_dma_buf_get_drvdata(
|
||||||
struct dma_buf *dmabuf, struct device *device);
|
struct dma_buf *dmabuf, struct device *device);
|
||||||
|
|||||||
@@ -433,14 +433,9 @@ int nvgpu_usermode_buf_from_dmabuf(struct gk20a *g, int dmabuf_fd,
|
|||||||
goto put_dmabuf;
|
goto put_dmabuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = gk20a_dmabuf_alloc_drvdata(dmabuf, dev);
|
sgt = nvgpu_mm_pin(dev, dmabuf, &attachment);
|
||||||
if (err != 0) {
|
|
||||||
goto put_dmabuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
sgt = nvgpu_mm_pin_privdata(dev, dmabuf, &attachment);
|
|
||||||
if (IS_ERR(sgt)) {
|
if (IS_ERR(sgt)) {
|
||||||
nvgpu_warn(g, "Failed to pin dma_buf!");
|
nvgpu_err(g, "Failed to pin dma_buf!");
|
||||||
err = PTR_ERR(sgt);
|
err = PTR_ERR(sgt);
|
||||||
goto put_dmabuf;
|
goto put_dmabuf;
|
||||||
}
|
}
|
||||||
@@ -476,7 +471,7 @@ void nvgpu_os_channel_free_usermode_buffers(struct nvgpu_channel *c)
|
|||||||
struct device *dev = dev_from_gk20a(g);
|
struct device *dev = dev_from_gk20a(g);
|
||||||
|
|
||||||
if (priv->usermode.gpfifo.dmabuf != NULL) {
|
if (priv->usermode.gpfifo.dmabuf != NULL) {
|
||||||
nvgpu_mm_unpin_privdata(dev, priv->usermode.gpfifo.dmabuf,
|
nvgpu_mm_unpin(dev, priv->usermode.gpfifo.dmabuf,
|
||||||
priv->usermode.gpfifo.attachment,
|
priv->usermode.gpfifo.attachment,
|
||||||
priv->usermode.gpfifo.sgt);
|
priv->usermode.gpfifo.sgt);
|
||||||
dma_buf_put(priv->usermode.gpfifo.dmabuf);
|
dma_buf_put(priv->usermode.gpfifo.dmabuf);
|
||||||
@@ -484,7 +479,7 @@ void nvgpu_os_channel_free_usermode_buffers(struct nvgpu_channel *c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (priv->usermode.userd.dmabuf != NULL) {
|
if (priv->usermode.userd.dmabuf != NULL) {
|
||||||
nvgpu_mm_unpin_privdata(dev, priv->usermode.userd.dmabuf,
|
nvgpu_mm_unpin(dev, priv->usermode.userd.dmabuf,
|
||||||
priv->usermode.userd.attachment,
|
priv->usermode.userd.attachment,
|
||||||
priv->usermode.userd.sgt);
|
priv->usermode.userd.sgt);
|
||||||
dma_buf_put(priv->usermode.userd.dmabuf);
|
dma_buf_put(priv->usermode.userd.dmabuf);
|
||||||
@@ -547,7 +542,7 @@ static int nvgpu_channel_alloc_usermode_buffers(struct nvgpu_channel *c,
|
|||||||
unmap_free_gpfifo:
|
unmap_free_gpfifo:
|
||||||
nvgpu_dma_unmap_free(c->vm, &c->usermode_gpfifo);
|
nvgpu_dma_unmap_free(c->vm, &c->usermode_gpfifo);
|
||||||
free_gpfifo:
|
free_gpfifo:
|
||||||
nvgpu_mm_unpin_privdata(dev, priv->usermode.gpfifo.dmabuf,
|
nvgpu_mm_unpin(dev, priv->usermode.gpfifo.dmabuf,
|
||||||
priv->usermode.gpfifo.attachment,
|
priv->usermode.gpfifo.attachment,
|
||||||
priv->usermode.gpfifo.sgt);
|
priv->usermode.gpfifo.sgt);
|
||||||
dma_buf_put(priv->usermode.gpfifo.dmabuf);
|
dma_buf_put(priv->usermode.gpfifo.dmabuf);
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ struct nvgpu_mapped_buf *nvgpu_vm_find_mapping(struct vm_gk20a *vm,
|
|||||||
* the dmabuf doesn't support drvdata, prior SGT is unpinned as the
|
* the dmabuf doesn't support drvdata, prior SGT is unpinned as the
|
||||||
* new SGT was pinned at the beginning of the current map call.
|
* new SGT was pinned at the beginning of the current map call.
|
||||||
*/
|
*/
|
||||||
nvgpu_mm_unpin_privdata(os_buf->dev, os_buf->dmabuf,
|
nvgpu_mm_unpin(os_buf->dev, os_buf->dmabuf,
|
||||||
mapped_buffer->os_priv.attachment,
|
mapped_buffer->os_priv.attachment,
|
||||||
mapped_buffer->os_priv.sgt);
|
mapped_buffer->os_priv.sgt);
|
||||||
dma_buf_put(os_buf->dmabuf);
|
dma_buf_put(os_buf->dmabuf);
|
||||||
@@ -205,7 +205,7 @@ int nvgpu_vm_map_linux(struct vm_gk20a *vm,
|
|||||||
struct dma_buf_attachment *attachment;
|
struct dma_buf_attachment *attachment;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
sgt = nvgpu_mm_pin_privdata(dev, dmabuf, &attachment);
|
sgt = nvgpu_mm_pin(dev, dmabuf, &attachment);
|
||||||
if (IS_ERR(sgt)) {
|
if (IS_ERR(sgt)) {
|
||||||
nvgpu_warn(g, "Failed to pin dma_buf!");
|
nvgpu_warn(g, "Failed to pin dma_buf!");
|
||||||
return PTR_ERR(sgt);
|
return PTR_ERR(sgt);
|
||||||
@@ -257,7 +257,7 @@ int nvgpu_vm_map_linux(struct vm_gk20a *vm,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
clean_up:
|
clean_up:
|
||||||
nvgpu_mm_unpin_privdata(dev, dmabuf, attachment, sgt);
|
nvgpu_mm_unpin(dev, dmabuf, attachment, sgt);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -324,12 +324,6 @@ int nvgpu_vm_map_buffer(struct vm_gk20a *vm,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = gk20a_dmabuf_alloc_drvdata(dmabuf, dev_from_vm(vm));
|
|
||||||
if (err) {
|
|
||||||
dma_buf_put(dmabuf);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = nvgpu_vm_map_linux(vm, dmabuf, *map_addr,
|
err = nvgpu_vm_map_linux(vm, dmabuf, *map_addr,
|
||||||
nvgpu_vm_translate_linux_flags(g, flags),
|
nvgpu_vm_translate_linux_flags(g, flags),
|
||||||
page_size,
|
page_size,
|
||||||
@@ -358,7 +352,7 @@ void nvgpu_vm_unmap_system(struct nvgpu_mapped_buf *mapped_buffer)
|
|||||||
{
|
{
|
||||||
struct vm_gk20a *vm = mapped_buffer->vm;
|
struct vm_gk20a *vm = mapped_buffer->vm;
|
||||||
|
|
||||||
nvgpu_mm_unpin_privdata(dev_from_vm(vm), mapped_buffer->os_priv.dmabuf,
|
nvgpu_mm_unpin(dev_from_vm(vm), mapped_buffer->os_priv.dmabuf,
|
||||||
mapped_buffer->os_priv.attachment,
|
mapped_buffer->os_priv.attachment,
|
||||||
mapped_buffer->os_priv.sgt);
|
mapped_buffer->os_priv.sgt);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user