Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dma-buf: cleanup dma_buf_export() to make it easily extensible

At present, dma_buf_export() takes a series of parameters, which
makes it difficult to add any new parameters for exporters, if required.

Make it simpler by moving all these parameters into a struct, and pass
the struct * as parameter to dma_buf_export().

While at it, unite dma_buf_export_named() with dma_buf_export(), and
change all callers accordingly.

Reviewed-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Reviewed-by: Daniel Thompson <daniel.thompson@linaro.org>
Acked-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Acked-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>

+152 -63
+12 -11
Documentation/dma-buf-sharing.txt
··· 49 49 The buffer exporter announces its wish to export a buffer. In this, it 50 50 connects its own private buffer data, provides implementation for operations 51 51 that can be performed on the exported dma_buf, and flags for the file 52 - associated with this buffer. 52 + associated with this buffer. All these fields are filled in struct 53 + dma_buf_export_info, defined via the DEFINE_DMA_BUF_EXPORT_INFO macro. 53 54 54 55 Interface: 55 - struct dma_buf *dma_buf_export_named(void *priv, struct dma_buf_ops *ops, 56 - size_t size, int flags, 57 - const char *exp_name) 56 + DEFINE_DMA_BUF_EXPORT_INFO(exp_info) 57 + struct dma_buf *dma_buf_export(struct dma_buf_export_info *exp_info) 58 58 59 - If this succeeds, dma_buf_export_named allocates a dma_buf structure, and 59 + If this succeeds, dma_buf_export allocates a dma_buf structure, and 60 60 returns a pointer to the same. It also associates an anonymous file with this 61 61 buffer, so it can be exported. On failure to allocate the dma_buf object, 62 62 it returns NULL. 63 63 64 - 'exp_name' is the name of exporter - to facilitate information while 65 - debugging. 64 + 'exp_name' in struct dma_buf_export_info is the name of exporter - to 65 + facilitate information while debugging. It is set to KBUILD_MODNAME by 66 + default, so exporters don't have to provide a specific name, if they don't 67 + wish to. 66 68 67 - Exporting modules which do not wish to provide any specific name may use the 68 - helper define 'dma_buf_export()', with the same arguments as above, but 69 - without the last argument; a KBUILD_MODNAME pre-processor directive will be 70 - inserted in place of 'exp_name' instead. 69 + DEFINE_DMA_BUF_EXPORT_INFO macro defines the struct dma_buf_export_info, 70 + zeroes it out and pre-populates exp_name in it. 71 + 71 72 72 73 2. Userspace gets a handle to pass around to potential buffer-users 73 74
+22 -25
drivers/dma-buf/dma-buf.c
··· 265 265 } 266 266 267 267 /** 268 - * dma_buf_export_named - Creates a new dma_buf, and associates an anon file 268 + * dma_buf_export - Creates a new dma_buf, and associates an anon file 269 269 * with this buffer, so it can be exported. 270 270 * Also connect the allocator specific data and ops to the buffer. 271 271 * Additionally, provide a name string for exporter; useful in debugging. 272 272 * 273 - * @priv: [in] Attach private data of allocator to this buffer 274 - * @ops: [in] Attach allocator-defined dma buf ops to the new buffer. 275 - * @size: [in] Size of the buffer 276 - * @flags: [in] mode flags for the file. 277 - * @exp_name: [in] name of the exporting module - useful for debugging. 278 - * @resv: [in] reservation-object, NULL to allocate default one. 273 + * @exp_info: [in] holds all the export related information provided 274 + * by the exporter. see struct dma_buf_export_info 275 + * for further details. 279 276 * 280 277 * Returns, on success, a newly created dma_buf object, which wraps the 281 278 * supplied private data and operations for dma_buf_ops. On either missing 282 279 * ops, or error in allocating struct dma_buf, will return negative error. 283 280 * 284 281 */ 285 - struct dma_buf *dma_buf_export_named(void *priv, const struct dma_buf_ops *ops, 286 - size_t size, int flags, const char *exp_name, 287 - struct reservation_object *resv) 282 + struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info) 288 283 { 289 284 struct dma_buf *dmabuf; 285 + struct reservation_object *resv = exp_info->resv; 290 286 struct file *file; 291 287 size_t alloc_size = sizeof(struct dma_buf); 292 - if (!resv) 288 + if (!exp_info->resv) 293 289 alloc_size += sizeof(struct reservation_object); 294 290 else 295 291 /* prevent &dma_buf[1] == dma_buf->resv */ 296 292 alloc_size += 1; 297 293 298 - if (WARN_ON(!priv || !ops 299 - || !ops->map_dma_buf 300 - || !ops->unmap_dma_buf 301 - || !ops->release 302 - || !ops->kmap_atomic 303 - || !ops->kmap 304 - || !ops->mmap)) { 294 + if (WARN_ON(!exp_info->priv 295 + || !exp_info->ops 296 + || !exp_info->ops->map_dma_buf 297 + || !exp_info->ops->unmap_dma_buf 298 + || !exp_info->ops->release 299 + || !exp_info->ops->kmap_atomic 300 + || !exp_info->ops->kmap 301 + || !exp_info->ops->mmap)) { 305 302 return ERR_PTR(-EINVAL); 306 303 } 307 304 ··· 306 309 if (dmabuf == NULL) 307 310 return ERR_PTR(-ENOMEM); 308 311 309 - dmabuf->priv = priv; 310 - dmabuf->ops = ops; 311 - dmabuf->size = size; 312 - dmabuf->exp_name = exp_name; 312 + dmabuf->priv = exp_info->priv; 313 + dmabuf->ops = exp_info->ops; 314 + dmabuf->size = exp_info->size; 315 + dmabuf->exp_name = exp_info->exp_name; 313 316 init_waitqueue_head(&dmabuf->poll); 314 317 dmabuf->cb_excl.poll = dmabuf->cb_shared.poll = &dmabuf->poll; 315 318 dmabuf->cb_excl.active = dmabuf->cb_shared.active = 0; ··· 320 323 } 321 324 dmabuf->resv = resv; 322 325 323 - file = anon_inode_getfile("dmabuf", &dma_buf_fops, dmabuf, flags); 326 + file = anon_inode_getfile("dmabuf", &dma_buf_fops, dmabuf, 327 + exp_info->flags); 324 328 if (IS_ERR(file)) { 325 329 kfree(dmabuf); 326 330 return ERR_CAST(file); ··· 339 341 340 342 return dmabuf; 341 343 } 342 - EXPORT_SYMBOL_GPL(dma_buf_export_named); 343 - 344 + EXPORT_SYMBOL_GPL(dma_buf_export); 344 345 345 346 /** 346 347 * dma_buf_fd - returns a file descriptor for the given dma_buf
+8 -2
drivers/gpu/drm/armada/armada_gem.c
··· 538 538 armada_gem_prime_export(struct drm_device *dev, struct drm_gem_object *obj, 539 539 int flags) 540 540 { 541 - return dma_buf_export(obj, &armada_gem_prime_dmabuf_ops, obj->size, 542 - O_RDWR, NULL); 541 + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); 542 + 543 + exp_info.ops = &armada_gem_prime_dmabuf_ops; 544 + exp_info.size = obj->size; 545 + exp_info.flags = O_RDWR; 546 + exp_info.priv = obj; 547 + 548 + return dma_buf_export(&exp_info); 543 549 } 544 550 545 551 struct drm_gem_object *
+8 -4
drivers/gpu/drm/drm_prime.c
··· 339 339 struct dma_buf *drm_gem_prime_export(struct drm_device *dev, 340 340 struct drm_gem_object *obj, int flags) 341 341 { 342 - struct reservation_object *robj = NULL; 342 + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); 343 + 344 + exp_info.ops = &drm_gem_prime_dmabuf_ops; 345 + exp_info.size = obj->size; 346 + exp_info.flags = flags; 347 + exp_info.priv = obj; 343 348 344 349 if (dev->driver->gem_prime_res_obj) 345 - robj = dev->driver->gem_prime_res_obj(obj); 350 + exp_info.resv = dev->driver->gem_prime_res_obj(obj); 346 351 347 - return dma_buf_export(obj, &drm_gem_prime_dmabuf_ops, obj->size, 348 - flags, robj); 352 + return dma_buf_export(&exp_info); 349 353 } 350 354 EXPORT_SYMBOL(drm_gem_prime_export); 351 355
+7 -2
drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
··· 185 185 struct drm_gem_object *obj, int flags) 186 186 { 187 187 struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); 188 + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); 188 189 189 - return dma_buf_export(obj, &exynos_dmabuf_ops, 190 - exynos_gem_obj->base.size, flags, NULL); 190 + exp_info.ops = &exynos_dmabuf_ops; 191 + exp_info.size = exynos_gem_obj->base.size; 192 + exp_info.flags = flags; 193 + exp_info.priv = obj; 194 + 195 + return dma_buf_export(&exp_info); 191 196 } 192 197 193 198 struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev,
+8 -2
drivers/gpu/drm/i915/i915_gem_dmabuf.c
··· 230 230 struct drm_gem_object *gem_obj, int flags) 231 231 { 232 232 struct drm_i915_gem_object *obj = to_intel_bo(gem_obj); 233 + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); 234 + 235 + exp_info.ops = &i915_dmabuf_ops; 236 + exp_info.size = gem_obj->size; 237 + exp_info.flags = flags; 238 + exp_info.priv = gem_obj; 239 + 233 240 234 241 if (obj->ops->dmabuf_export) { 235 242 int ret = obj->ops->dmabuf_export(obj); ··· 244 237 return ERR_PTR(ret); 245 238 } 246 239 247 - return dma_buf_export(gem_obj, &i915_dmabuf_ops, gem_obj->size, flags, 248 - NULL); 240 + return dma_buf_export(&exp_info); 249 241 } 250 242 251 243 static int i915_gem_object_get_pages_dmabuf(struct drm_i915_gem_object *obj)
+8 -1
drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
··· 171 171 struct dma_buf *omap_gem_prime_export(struct drm_device *dev, 172 172 struct drm_gem_object *obj, int flags) 173 173 { 174 - return dma_buf_export(obj, &omap_dmabuf_ops, obj->size, flags, NULL); 174 + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); 175 + 176 + exp_info.ops = &omap_dmabuf_ops; 177 + exp_info.size = obj->size; 178 + exp_info.flags = flags; 179 + exp_info.priv = obj; 180 + 181 + return dma_buf_export(&exp_info); 175 182 } 176 183 177 184 struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev,
+8 -2
drivers/gpu/drm/tegra/gem.c
··· 627 627 struct drm_gem_object *gem, 628 628 int flags) 629 629 { 630 - return dma_buf_export(gem, &tegra_gem_prime_dmabuf_ops, gem->size, 631 - flags, NULL); 630 + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); 631 + 632 + exp_info.ops = &tegra_gem_prime_dmabuf_ops; 633 + exp_info.size = gem->size; 634 + exp_info.flags = flags; 635 + exp_info.priv = gem; 636 + 637 + return dma_buf_export(&exp_info); 632 638 } 633 639 634 640 struct drm_gem_object *tegra_gem_prime_import(struct drm_device *drm,
+7 -2
drivers/gpu/drm/ttm/ttm_object.c
··· 683 683 684 684 dma_buf = prime->dma_buf; 685 685 if (!dma_buf || !get_dma_buf_unless_doomed(dma_buf)) { 686 + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); 687 + 688 + exp_info.ops = &tdev->ops; 689 + exp_info.size = prime->size; 690 + exp_info.flags = flags; 691 + exp_info.priv = prime; 686 692 687 693 /* 688 694 * Need to create a new dma_buf, with memory accounting. ··· 700 694 goto out_unref; 701 695 } 702 696 703 - dma_buf = dma_buf_export(prime, &tdev->ops, 704 - prime->size, flags, NULL); 697 + dma_buf = dma_buf_export(&exp_info); 705 698 if (IS_ERR(dma_buf)) { 706 699 ret = PTR_ERR(dma_buf); 707 700 ttm_mem_global_free(tdev->mem_glob,
+8 -1
drivers/gpu/drm/udl/udl_dmabuf.c
··· 202 202 struct dma_buf *udl_gem_prime_export(struct drm_device *dev, 203 203 struct drm_gem_object *obj, int flags) 204 204 { 205 - return dma_buf_export(obj, &udl_dmabuf_ops, obj->size, flags, NULL); 205 + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); 206 + 207 + exp_info.ops = &udl_dmabuf_ops; 208 + exp_info.size = obj->size; 209 + exp_info.flags = flags; 210 + exp_info.priv = obj; 211 + 212 + return dma_buf_export(&exp_info); 206 213 } 207 214 208 215 static int udl_prime_create(struct drm_device *dev,
+7 -1
drivers/media/v4l2-core/videobuf2-dma-contig.c
··· 402 402 { 403 403 struct vb2_dc_buf *buf = buf_priv; 404 404 struct dma_buf *dbuf; 405 + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); 406 + 407 + exp_info.ops = &vb2_dc_dmabuf_ops; 408 + exp_info.size = buf->size; 409 + exp_info.flags = flags; 410 + exp_info.priv = buf; 405 411 406 412 if (!buf->sgt_base) 407 413 buf->sgt_base = vb2_dc_get_base_sgt(buf); ··· 415 409 if (WARN_ON(!buf->sgt_base)) 416 410 return NULL; 417 411 418 - dbuf = dma_buf_export(buf, &vb2_dc_dmabuf_ops, buf->size, flags, NULL); 412 + dbuf = dma_buf_export(&exp_info); 419 413 if (IS_ERR(dbuf)) 420 414 return NULL; 421 415
+7 -1
drivers/media/v4l2-core/videobuf2-dma-sg.c
··· 583 583 { 584 584 struct vb2_dma_sg_buf *buf = buf_priv; 585 585 struct dma_buf *dbuf; 586 + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); 587 + 588 + exp_info.ops = &vb2_dma_sg_dmabuf_ops; 589 + exp_info.size = buf->size; 590 + exp_info.flags = flags; 591 + exp_info.priv = buf; 586 592 587 593 if (WARN_ON(!buf->dma_sgt)) 588 594 return NULL; 589 595 590 - dbuf = dma_buf_export(buf, &vb2_dma_sg_dmabuf_ops, buf->size, flags, NULL); 596 + dbuf = dma_buf_export(&exp_info); 591 597 if (IS_ERR(dbuf)) 592 598 return NULL; 593 599
+7 -1
drivers/media/v4l2-core/videobuf2-vmalloc.c
··· 368 368 { 369 369 struct vb2_vmalloc_buf *buf = buf_priv; 370 370 struct dma_buf *dbuf; 371 + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); 372 + 373 + exp_info.ops = &vb2_vmalloc_dmabuf_ops; 374 + exp_info.size = buf->size; 375 + exp_info.flags = flags; 376 + exp_info.priv = buf; 371 377 372 378 if (WARN_ON(!buf->vaddr)) 373 379 return NULL; 374 380 375 - dbuf = dma_buf_export(buf, &vb2_vmalloc_dmabuf_ops, buf->size, flags, NULL); 381 + dbuf = dma_buf_export(&exp_info); 376 382 if (IS_ERR(dbuf)) 377 383 return NULL; 378 384
+7 -2
drivers/staging/android/ion/ion.c
··· 1106 1106 struct ion_buffer *buffer; 1107 1107 struct dma_buf *dmabuf; 1108 1108 bool valid_handle; 1109 + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); 1110 + 1111 + exp_info.ops = &dma_buf_ops; 1112 + exp_info.size = buffer->size; 1113 + exp_info.flags = O_RDWR; 1114 + exp_info.priv = buffer; 1109 1115 1110 1116 mutex_lock(&client->lock); 1111 1117 valid_handle = ion_handle_validate(client, handle); ··· 1124 1118 ion_buffer_get(buffer); 1125 1119 mutex_unlock(&client->lock); 1126 1120 1127 - dmabuf = dma_buf_export(buffer, &dma_buf_ops, buffer->size, O_RDWR, 1128 - NULL); 1121 + dmabuf = dma_buf_export(&exp_info); 1129 1122 if (IS_ERR(dmabuf)) { 1130 1123 ion_buffer_put(buffer); 1131 1124 return dmabuf;
+28 -6
include/linux/dma-buf.h
··· 163 163 }; 164 164 165 165 /** 166 + * struct dma_buf_export_info - holds information needed to export a dma_buf 167 + * @exp_name: name of the exporting module - useful for debugging. 168 + * @ops: Attach allocator-defined dma buf ops to the new buffer 169 + * @size: Size of the buffer 170 + * @flags: mode flags for the file 171 + * @resv: reservation-object, NULL to allocate default one 172 + * @priv: Attach private data of allocator to this buffer 173 + * 174 + * This structure holds the information required to export the buffer. Used 175 + * with dma_buf_export() only. 176 + */ 177 + struct dma_buf_export_info { 178 + const char *exp_name; 179 + const struct dma_buf_ops *ops; 180 + size_t size; 181 + int flags; 182 + struct reservation_object *resv; 183 + void *priv; 184 + }; 185 + 186 + /** 187 + * helper macro for exporters; zeros and fills in most common values 188 + */ 189 + #define DEFINE_DMA_BUF_EXPORT_INFO(a) \ 190 + struct dma_buf_export_info a = { .exp_name = KBUILD_MODNAME } 191 + 192 + /** 166 193 * get_dma_buf - convenience wrapper for get_file. 167 194 * @dmabuf: [in] pointer to dma_buf 168 195 * ··· 208 181 void dma_buf_detach(struct dma_buf *dmabuf, 209 182 struct dma_buf_attachment *dmabuf_attach); 210 183 211 - struct dma_buf *dma_buf_export_named(void *priv, const struct dma_buf_ops *ops, 212 - size_t size, int flags, const char *, 213 - struct reservation_object *); 214 - 215 - #define dma_buf_export(priv, ops, size, flags, resv) \ 216 - dma_buf_export_named(priv, ops, size, flags, KBUILD_MODNAME, resv) 184 + struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info); 217 185 218 186 int dma_buf_fd(struct dma_buf *dmabuf, int flags); 219 187 struct dma_buf *dma_buf_get(int fd);