History

dma-buf: change DMA-buf locking convention v3

This patch is a stripped down version of the locking changes necessary to support dynamic DMA-buf handling. It adds a dynamic flag for both importers as well as exporters so that drivers can choose if they want the reservation object locked or unlocked during mapping of attachments. For compatibility between drivers we cache the DMA-buf mapping during attaching an importer as soon as exporter/importer disagree on the dynamic handling. Issues and solutions we considered: - We can't change all existing drivers, and existing improters have strong opinions about which locks they're holding while calling dma_buf_attachment_map/unmap. Exporters also have strong opinions about which locks they can acquire in their ->map/unmap callbacks, levaing no room for change. The solution to avoid this was to move the actual map/unmap out from this call, into the attach/detach callbacks, and cache the mapping. This works because drivers don't call attach/detach from deep within their code callchains (like deep in memory management code called from cs/execbuf ioctl), but directly from the fd2handle implementation. - The caching has some troubles on some soc drivers, which set other modes than DMA_BIDIRECTIONAL. We can't have 2 incompatible mappings, and we can't re-create the mapping at _map time due to the above locking fun. We very carefuly step around that by only caching at attach time if the dynamic mode between importer/expoert mismatches. - There's been quite some discussion on dma-buf mappings which need active cache management, which would all break down when caching, plus we don't have explicit flush operations on the attachment side. The solution to this was to shrug and keep the current discrepancy between what the dma-buf docs claim and what implementations do, with the hope that the begin/end_cpu_access hooks are good enough and that all necessary flushing to keep device mappings consistent will be done there. v2: cleanup set_name merge, improve kerneldoc v3: update commit message, kerneldoc and cleanup _debug_show()

Christian König committed 8 years ago

Commit 15fd5521 parent 9a42c7c2 files · +158 −23Browse files

Showing the changes to include/linux (1 of 2 files). Show all

Unified · Split

include/linux/dma-buf.h+57−6
@@ -42,6 +42,18 @@ struct dma_buf_ops { · 41 unmodified lines
42 */42 */
43 bool cache_sgt_mapping;43 bool cache_sgt_mapping;
44 44
45 /**
46 * @dynamic_mapping:
47 *
48 * If true the framework makes sure that the map/unmap_dma_buf
49 * callbacks are always called with the dma_resv object locked.
50 *
51 * If false the framework makes sure that the map/unmap_dma_buf
52 * callbacks are always called without the dma_resv object locked.
53 * Mutual exclusive with @cache_sgt_mapping.
54 */
55 bool dynamic_mapping;
56
45 /**57 /**
46 * @attach:58 * @attach:
47 *59 *
@@ -109,6 +121,9 @@ struct dma_buf_ops { · 61 unmodified lines
109 * any other kind of sharing that the exporter might wish to make121 * any other kind of sharing that the exporter might wish to make
110 * available to buffer-users.122 * available to buffer-users.
111 *123 *
124 * This is always called with the dmabuf->resv object locked when
125 * the dynamic_mapping flag is true.
126 *
112 * Returns:127 * Returns:
113 *128 *
114 * A &sg_table scatter list of or the backing storage of the DMA buffer,129 * A &sg_table scatter list of or the backing storage of the DMA buffer,
@@ -267,14 +282,16 @@ struct dma_buf_ops { · 152 unmodified lines
267 * struct dma_buf - shared buffer object282 * struct dma_buf - shared buffer object
268 * @size: size of the buffer283 * @size: size of the buffer
269 * @file: file pointer used for sharing buffers across, and for refcounting.284 * @file: file pointer used for sharing buffers across, and for refcounting.
270 * @attachments: list of dma_buf_attachment that denotes all devices attached.285 * @attachments: list of dma_buf_attachment that denotes all devices attached,
286 * protected by dma_resv lock.
271 * @ops: dma_buf_ops associated with this buffer object.287 * @ops: dma_buf_ops associated with this buffer object.
272 * @lock: used internally to serialize list manipulation, attach/detach and288 * @lock: used internally to serialize list manipulation, attach/detach and
273 * vmap/unmap, and accesses to name289 * vmap/unmap
274 * @vmapping_counter: used internally to refcnt the vmaps290 * @vmapping_counter: used internally to refcnt the vmaps
275 * @vmap_ptr: the current vmap ptr if vmapping_counter > 0291 * @vmap_ptr: the current vmap ptr if vmapping_counter > 0
276 * @exp_name: name of the exporter; useful for debugging.292 * @exp_name: name of the exporter; useful for debugging.
277 * @name: userspace-provided name; useful for accounting and debugging.293 * @name: userspace-provided name; useful for accounting and debugging,
294 * protected by @resv.
278 * @owner: pointer to exporter module; used for refcounting when exporter is a295 * @owner: pointer to exporter module; used for refcounting when exporter is a
279 * kernel module.296 * kernel module.
280 * @list_node: node for dma_buf accounting and debugging.297 * @list_node: node for dma_buf accounting and debugging.
@@ -323,10 +340,12 @@ struct dma_buf { · 42 unmodified lines
323 * struct dma_buf_attachment - holds device-buffer attachment data340 * struct dma_buf_attachment - holds device-buffer attachment data
324 * @dmabuf: buffer for this attachment.341 * @dmabuf: buffer for this attachment.
325 * @dev: device attached to the buffer.342 * @dev: device attached to the buffer.
326 * @node: list of dma_buf_attachment.343 * @node: list of dma_buf_attachment, protected by dma_resv lock of the dmabuf.
327 * @sgt: cached mapping.344 * @sgt: cached mapping.
328 * @dir: direction of cached mapping.345 * @dir: direction of cached mapping.
329 * @priv: exporter specific attachment data.346 * @priv: exporter specific attachment data.
347 * @dynamic_mapping: true if dma_buf_map/unmap_attachment() is called with the
348 * dma_resv lock held.
330 *349 *
331 * This structure holds the attachment information between the dma_buf buffer350 * This structure holds the attachment information between the dma_buf buffer
332 * and its user device(s). The list contains one attachment struct per device351 * and its user device(s). The list contains one attachment struct per device
@@ -343,6 +362,7 @@ struct dma_buf_attachment { · 10 unmodified lines
343 struct list_head node;362 struct list_head node;
344 struct sg_table *sgt;363 struct sg_table *sgt;
345 enum dma_data_direction dir;364 enum dma_data_direction dir;
365 bool dynamic_mapping;
346 void *priv;366 void *priv;
347};367};
348 368
@@ -394,10 +414,40 @@ static inline void get_dma_buf(struct dma_buf *dmabuf) · 45 unmodified lines
394 get_file(dmabuf->file);414 get_file(dmabuf->file);
395}415}
396 416
417/**
418 * dma_buf_is_dynamic - check if a DMA-buf uses dynamic mappings.
419 * @dmabuf: the DMA-buf to check
420 *
421 * Returns true if a DMA-buf exporter wants to be called with the dma_resv
422 * locked for the map/unmap callbacks, false if it doesn't wants to be called
423 * with the lock held.
424 */
425static inline bool dma_buf_is_dynamic(struct dma_buf *dmabuf)
426{
427 return dmabuf->ops->dynamic_mapping;
428}
429
430/**
431 * dma_buf_attachment_is_dynamic - check if a DMA-buf attachment uses dynamic
432 * mappinsg
433 * @attach: the DMA-buf attachment to check
434 *
435 * Returns true if a DMA-buf importer wants to call the map/unmap functions with
436 * the dma_resv lock held.
437 */
438static inline bool
439dma_buf_attachment_is_dynamic(struct dma_buf_attachment *attach)
440{
441 return attach->dynamic_mapping;
442}
443
397struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,444struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf,
398 struct device *dev);445 struct device *dev);
446struct dma_buf_attachment *
447dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
448 bool dynamic_mapping);
399void dma_buf_detach(struct dma_buf *dmabuf,449void dma_buf_detach(struct dma_buf *dmabuf,
400 struct dma_buf_attachment *dmabuf_attach);450 struct dma_buf_attachment *attach);
401 451
402struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info);452struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info);
403 453
@@ -409,6 +459,7 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *, · 5 unmodified lines
409 enum dma_data_direction);459 enum dma_data_direction);
410void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *,460void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *,
411 enum dma_data_direction);461 enum dma_data_direction);
462void dma_buf_move_notify(struct dma_buf *dma_buf);
412int dma_buf_begin_cpu_access(struct dma_buf *dma_buf,463int dma_buf_begin_cpu_access(struct dma_buf *dma_buf,
413 enum dma_data_direction dir);464 enum dma_data_direction dir);
414int dma_buf_end_cpu_access(struct dma_buf *dma_buf,465int dma_buf_end_cpu_access(struct dma_buf *dma_buf,

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t