Hello,
This patchset adds reference counting for an exporter module to DMABUF
framework. Moreover, it adds setup of an owner field for exporters in DRM
subsystem.
v1: Original
v2:
- split patch into DMABUF and DRM part
- allow owner to be NULL
Regards,
Tomasz Stanislawski
Tomasz Stanislawski (2):
dma-buf: add reference counting for exporter module
drm: set owner field to for all DMABUF exporters
Documentation/dma-buf-sharing.txt | 3 ++-
drivers/base/dma-buf.c | 9 ++++++++-
drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | 1 +
drivers/gpu/drm/i915/i915_gem_dmabuf.c | 1 +
drivers/gpu/drm/nouveau/nouveau_prime.c | 1 +
drivers/gpu/drm/radeon/radeon_prime.c | 1 +
drivers/staging/omapdrm/omap_gem_dmabuf.c | 1 +
include/linux/dma-buf.h | 2 ++
8 files changed, 17 insertions(+), 2 deletions(-)
--
1.7.9.5
This patch adds reference counting on a module that exported dma-buf and
implements its operations. This prevents the module from being unloaded while
DMABUF file is in use.
Signed-off-by: Tomasz Stanislawski <[email protected]>
Acked-by: Sumit Semwal <[email protected]>
Acked-by: Daniel Vetter <[email protected]>
CC: [email protected]
---
Documentation/dma-buf-sharing.txt | 3 ++-
drivers/base/dma-buf.c | 9 ++++++++-
include/linux/dma-buf.h | 2 ++
3 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/Documentation/dma-buf-sharing.txt b/Documentation/dma-buf-sharing.txt
index ad86fb8..2613057 100644
--- a/Documentation/dma-buf-sharing.txt
+++ b/Documentation/dma-buf-sharing.txt
@@ -49,7 +49,8 @@ The dma_buf buffer sharing API usage contains the following steps:
The buffer exporter announces its wish to export a buffer. In this, it
connects its own private buffer data, provides implementation for operations
that can be performed on the exported dma_buf, and flags for the file
- associated with this buffer.
+ associated with this buffer. The operations structure has owner field.
+ You should initialize this to THIS_MODULE in most cases.
Interface:
struct dma_buf *dma_buf_export(void *priv, struct dma_buf_ops *ops,
diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
index c30f3e1..a1d9cab 100644
--- a/drivers/base/dma-buf.c
+++ b/drivers/base/dma-buf.c
@@ -27,6 +27,7 @@
#include <linux/dma-buf.h>
#include <linux/anon_inodes.h>
#include <linux/export.h>
+#include <linux/module.h>
static inline int is_dma_buf_file(struct file *);
@@ -40,6 +41,7 @@ static int dma_buf_release(struct inode *inode, struct file *file)
dmabuf = file->private_data;
dmabuf->ops->release(dmabuf);
+ module_put(dmabuf->ops->owner);
kfree(dmabuf);
return 0;
}
@@ -105,9 +107,14 @@ struct dma_buf *dma_buf_export(void *priv, const struct dma_buf_ops *ops,
return ERR_PTR(-EINVAL);
}
+ if (!try_module_get(ops->owner))
+ return ERR_PTR(-ENOENT);
+
dmabuf = kzalloc(sizeof(struct dma_buf), GFP_KERNEL);
- if (dmabuf == NULL)
+ if (dmabuf == NULL) {
+ module_put(ops->owner);
return ERR_PTR(-ENOMEM);
+ }
dmabuf->priv = priv;
dmabuf->ops = ops;
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index eb48f38..22953de 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -37,6 +37,7 @@ struct dma_buf_attachment;
/**
* struct dma_buf_ops - operations possible on struct dma_buf
+ * @owner: the module that implements dma_buf operations
* @attach: [optional] allows different devices to 'attach' themselves to the
* given buffer. It might return -EBUSY to signal that backing storage
* is already allocated and incompatible with the requirements
@@ -70,6 +71,7 @@ struct dma_buf_attachment;
* @vunmap: [optional] unmaps a vmap from the buffer
*/
struct dma_buf_ops {
+ struct module *owner;
int (*attach)(struct dma_buf *, struct device *,
struct dma_buf_attachment *);
--
1.7.9.5
This patch sets owner field in DMABUF operations for all DMABUF exporters in
DRM subsystem. This prevents an exporting module from being unloaded while
exported DMABUF descriptor is in use.
Signed-off-by: Tomasz Stanislawski <[email protected]>
Acked-by: Sumit Semwal <[email protected]>
Acked-by: Daniel Vetter <[email protected]>
---
drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | 1 +
drivers/gpu/drm/i915/i915_gem_dmabuf.c | 1 +
drivers/gpu/drm/nouveau/nouveau_prime.c | 1 +
drivers/gpu/drm/radeon/radeon_prime.c | 1 +
drivers/staging/omapdrm/omap_gem_dmabuf.c | 1 +
5 files changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
index 613bf8a..cf3bc6d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
@@ -164,6 +164,7 @@ static void exynos_gem_dmabuf_kunmap(struct dma_buf *dma_buf,
}
static struct dma_buf_ops exynos_dmabuf_ops = {
+ .owner = THIS_MODULE,
.map_dma_buf = exynos_gem_map_dma_buf,
.unmap_dma_buf = exynos_gem_unmap_dma_buf,
.kmap = exynos_gem_dmabuf_kmap,
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
index aa308e1..07ff03b 100644
--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
@@ -152,6 +152,7 @@ static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *
}
static const struct dma_buf_ops i915_dmabuf_ops = {
+ .owner = THIS_MODULE,
.map_dma_buf = i915_gem_map_dma_buf,
.unmap_dma_buf = i915_gem_unmap_dma_buf,
.release = i915_gem_dmabuf_release,
diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c
index a25cf2c..8605033 100644
--- a/drivers/gpu/drm/nouveau/nouveau_prime.c
+++ b/drivers/gpu/drm/nouveau/nouveau_prime.c
@@ -127,6 +127,7 @@ static void nouveau_gem_prime_vunmap(struct dma_buf *dma_buf, void *vaddr)
}
static const struct dma_buf_ops nouveau_dmabuf_ops = {
+ .owner = THIS_MODULE,
.map_dma_buf = nouveau_gem_map_dma_buf,
.unmap_dma_buf = nouveau_gem_unmap_dma_buf,
.release = nouveau_gem_dmabuf_release,
diff --git a/drivers/gpu/drm/radeon/radeon_prime.c b/drivers/gpu/drm/radeon/radeon_prime.c
index 6bef46a..4061fd3 100644
--- a/drivers/gpu/drm/radeon/radeon_prime.c
+++ b/drivers/gpu/drm/radeon/radeon_prime.c
@@ -127,6 +127,7 @@ static void radeon_gem_prime_vunmap(struct dma_buf *dma_buf, void *vaddr)
mutex_unlock(&dev->struct_mutex);
}
const static struct dma_buf_ops radeon_dmabuf_ops = {
+ .owner = THIS_MODULE,
.map_dma_buf = radeon_gem_map_dma_buf,
.unmap_dma_buf = radeon_gem_unmap_dma_buf,
.release = radeon_gem_dmabuf_release,
diff --git a/drivers/staging/omapdrm/omap_gem_dmabuf.c b/drivers/staging/omapdrm/omap_gem_dmabuf.c
index 42728e0..6a4dd67 100644
--- a/drivers/staging/omapdrm/omap_gem_dmabuf.c
+++ b/drivers/staging/omapdrm/omap_gem_dmabuf.c
@@ -179,6 +179,7 @@ out_unlock:
}
struct dma_buf_ops omap_dmabuf_ops = {
+ .owner = THIS_MODULE,
.map_dma_buf = omap_gem_map_dma_buf,
.unmap_dma_buf = omap_gem_unmap_dma_buf,
.release = omap_gem_dmabuf_release,
--
1.7.9.5
On Thu, Aug 09, 2012 at 11:36:21AM +0200, Tomasz Stanislawski wrote:
> This patch adds reference counting on a module that exported dma-buf and
> implements its operations. This prevents the module from being unloaded while
> DMABUF file is in use.
Why force all of the modules to be changed "by hand", and not just do
this automatically by changing the register function to include the
THIS_MODULE macro in it? Much like the pci_register_driver() function
is implemented in include/linux/pci.h?
That makes it impossible for driver authors to get it wrong, which is
always a good sign of a correct api.
thanks,
greg k-h
Hi Greg,
On 08/09/2012 04:23 PM, Greg KH wrote:
> On Thu, Aug 09, 2012 at 11:36:21AM +0200, Tomasz Stanislawski wrote:
>> This patch adds reference counting on a module that exported dma-buf and
>> implements its operations. This prevents the module from being unloaded while
>> DMABUF file is in use.
>
> Why force all of the modules to be changed "by hand", and not just do
> this automatically by changing the register function to include the
> THIS_MODULE macro in it? Much like the pci_register_driver() function
> is implemented in include/linux/pci.h?
Thank you for the hint.
The owner field belongs to dma_buf_ops structure that is often a 'const'
entity. Therefore owner field would have to be moved to 'struct dma_buf'
to avoid 'deconstification' issues.
Regards,
Tomasz Stanislawski
>
> That makes it impossible for driver authors to get it wrong, which is
> always a good sign of a correct api.
>
> thanks,
>
> greg k-h
>