History

Merge tag 'dma-buf-for-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/sumits/dma-buf

Pull dma-buf updates from Sumit Semwal: - use of vma_pages instead of explicit computation - DocBook and headerdoc updates for dma-buf * tag 'dma-buf-for-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/sumits/dma-buf: dma-buf: use vma_pages() fence: add missing descriptions for fence doc: update/fixup dma-buf related DocBook reservation: add headerdoc comments dma-buf: headerdoc fixes

Linus Torvalds committed 10 years ago

Commit ebb8cb22 parents 6b15d66 b02da6f6 files · +169 −14Browse files

Unified · Split

6 files
  1. Documentation/DocBook/device-drivers.tmpl +32 −4
  2. drivers/dma-buf/dma-buf.c +4 −3
  3. drivers/dma-buf/reservation.c +68 −4
  4. include/linux/dma-buf.h +10 −3
  5. include/linux/fence.h +2 −0
  6. include/linux/reservation.h +53 −0
Documentation/DocBook/device-drivers.tmpl+32−4
@@ -128,16 +128,44 @@ X!Edrivers/base/interface.c · 127 unmodified lines
128128 !Edrivers/base/platform.c
129129 !Edrivers/base/bus.c
130130 </sect1>
131− <sect1><title>Device Drivers DMA Management</title>
131+ <sect1>
132+ <title>Buffer Sharing and Synchronization</title>
133+ <para>
134+ The dma-buf subsystem provides the framework for sharing buffers
135+ for hardware (DMA) access across multiple device drivers and
136+ subsystems, and for synchronizing asynchronous hardware access.
137+ </para>
138+ <para>
139+ This is used, for example, by drm "prime" multi-GPU support, but
140+ is of course not limited to GPU use cases.
141+ </para>
142+ <para>
143+ The three main components of this are: (1) dma-buf, representing
144+ a sg_table and exposed to userspace as a file descriptor to allow
145+ passing between devices, (2) fence, which provides a mechanism
146+ to signal when one device as finished access, and (3) reservation,
147+ which manages the shared or exclusive fence(s) associated with
148+ the buffer.
149+ </para>
150+ <sect2><title>dma-buf</title>
132151 !Edrivers/dma-buf/dma-buf.c
152+!Iinclude/linux/dma-buf.h
153+ </sect2>
154+ <sect2><title>reservation</title>
155+!Pdrivers/dma-buf/reservation.c Reservation Object Overview
156+!Edrivers/dma-buf/reservation.c
157+!Iinclude/linux/reservation.h
158+ </sect2>
159+ <sect2><title>fence</title>
133160 !Edrivers/dma-buf/fence.c
134−!Edrivers/dma-buf/seqno-fence.c
135161 !Iinclude/linux/fence.h
162+!Edrivers/dma-buf/seqno-fence.c
136163 !Iinclude/linux/seqno-fence.h
137−!Edrivers/dma-buf/reservation.c
138−!Iinclude/linux/reservation.h
139164 !Edrivers/dma-buf/sync_file.c
140165 !Iinclude/linux/sync_file.h
166+ </sect2>
167+ </sect1>
168+ <sect1><title>Device Drivers DMA Management</title>
141169 !Edrivers/base/dma-coherent.c
142170 !Edrivers/base/dma-mapping.c
143171 </sect1>
drivers/dma-buf/dma-buf.c+4−3
@@ -33,6 +33,7 @@ · 32 unmodified lines
3333 #include <linux/seq_file.h>
3434 #include <linux/poll.h>
3535 #include <linux/reservation.h>
36+#include <linux/mm.h>
3637
3738 #include <uapi/linux/dma-buf.h>
3839
@@ -90,7 +91,7 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma) · 51 unmodified lines
9091 dmabuf = file->private_data;
9192
9293 /* check for overflowing the buffer's size */
93− if (vma->vm_pgoff + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) >
94+ if (vma->vm_pgoff + vma_pages(vma) >
9495 dmabuf->size >> PAGE_SHIFT)
9596 return -EINVAL;
9697
@@ -723,11 +724,11 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma, · 626 unmodified lines
723724 return -EINVAL;
724725
725726 /* check for offset overflow */
726− if (pgoff + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) < pgoff)
727+ if (pgoff + vma_pages(vma) < pgoff)
727728 return -EOVERFLOW;
728729
729730 /* check for overflowing the buffer's size */
730− if (pgoff + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) >
731+ if (pgoff + vma_pages(vma) >
731732 dmabuf->size >> PAGE_SHIFT)
732733 return -EINVAL;
733734
drivers/dma-buf/reservation.c+68−4
@@ -35,6 +35,17 @@ · 34 unmodified lines
3535 #include <linux/reservation.h>
3636 #include <linux/export.h>
3737
38+/**
39+ * DOC: Reservation Object Overview
40+ *
41+ * The reservation object provides a mechanism to manage shared and
42+ * exclusive fences associated with a buffer. A reservation object
43+ * can have attached one exclusive fence (normally associated with
44+ * write operations) or N shared fences (read operations). The RCU
45+ * mechanism is used to protect read access to fences from locked
46+ * write-side updates.
47+ */
48+
3849 DEFINE_WW_CLASS(reservation_ww_class);
3950 EXPORT_SYMBOL(reservation_ww_class);
4051
@@ -43,9 +54,17 @@ EXPORT_SYMBOL(reservation_seqcount_class); · 2 unmodified lines
4354
4455 const char reservation_seqcount_string[] = "reservation_seqcount";
4556 EXPORT_SYMBOL(reservation_seqcount_string);
46−/*
47− * Reserve space to add a shared fence to a reservation_object,
48− * must be called with obj->lock held.
57+
58+/**
59+ * reservation_object_reserve_shared - Reserve space to add a shared
60+ * fence to a reservation_object.
61+ * @obj: reservation object
62+ *
63+ * Should be called before reservation_object_add_shared_fence(). Must
64+ * be called with obj->lock held.
65+ *
66+ * RETURNS
67+ * Zero for success, or -errno
4968 */
5069 int reservation_object_reserve_shared(struct reservation_object *obj)
5170 {
@@ -180,7 +199,11 @@ done: · 128 unmodified lines
180199 fence_put(old_fence);
181200 }
182201
183−/*
202+/**
203+ * reservation_object_add_shared_fence - Add a fence to a shared slot
204+ * @obj: the reservation object
205+ * @fence: the shared fence to add
206+ *
184207 * Add a fence to a shared slot, obj->lock must be held, and
185208 * reservation_object_reserve_shared_fence has been called.
186209 */
@@ -200,6 +223,13 @@ void reservation_object_add_shared_fence(struct reservation_object *obj, · 13 unmodified lines
200223 }
201224 EXPORT_SYMBOL(reservation_object_add_shared_fence);
202225
226+/**
227+ * reservation_object_add_excl_fence - Add an exclusive fence.
228+ * @obj: the reservation object
229+ * @fence: the shared fence to add
230+ *
231+ * Add a fence to the exclusive slot. The obj->lock must be held.
232+ */
203233 void reservation_object_add_excl_fence(struct reservation_object *obj,
204234 struct fence *fence)
205235 {
@@ -233,6 +263,18 @@ void reservation_object_add_excl_fence(struct reservation_object *obj, · 27 unmodified lines
233263 }
234264 EXPORT_SYMBOL(reservation_object_add_excl_fence);
235265
266+/**
267+ * reservation_object_get_fences_rcu - Get an object's shared and exclusive
268+ * fences without update side lock held
269+ * @obj: the reservation object
270+ * @pfence_excl: the returned exclusive fence (or NULL)
271+ * @pshared_count: the number of shared fences returned
272+ * @pshared: the array of shared fence ptrs returned (array is krealloc'd to
273+ * the required size, and must be freed by caller)
274+ *
275+ * RETURNS
276+ * Zero or -errno
277+ */
236278 int reservation_object_get_fences_rcu(struct reservation_object *obj,
237279 struct fence **pfence_excl,
238280 unsigned *pshared_count,
@@ -319,6 +361,18 @@ unlock: · 80 unmodified lines
319361 }
320362 EXPORT_SYMBOL_GPL(reservation_object_get_fences_rcu);
321363
364+/**
365+ * reservation_object_wait_timeout_rcu - Wait on reservation's objects
366+ * shared and/or exclusive fences.
367+ * @obj: the reservation object
368+ * @wait_all: if true, wait on all fences, else wait on just exclusive fence
369+ * @intr: if true, do interruptible wait
370+ * @timeout: timeout value in jiffies or zero to return immediately
371+ *
372+ * RETURNS
373+ * Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or
374+ * greater than zer on success.
375+ */
322376 long reservation_object_wait_timeout_rcu(struct reservation_object *obj,
323377 bool wait_all, bool intr,
324378 unsigned long timeout)
@@ -416,6 +470,16 @@ reservation_object_test_signaled_single(struct fence *passed_fence) · 91 unmodified lines
416470 return ret;
417471 }
418472
473+/**
474+ * reservation_object_test_signaled_rcu - Test if a reservation object's
475+ * fences have been signaled.
476+ * @obj: the reservation object
477+ * @test_all: if true, test all fences, otherwise only test the exclusive
478+ * fence
479+ *
480+ * RETURNS
481+ * true if all fences signaled, else false
482+ */
419483 bool reservation_object_test_signaled_rcu(struct reservation_object *obj,
420484 bool test_all)
421485 {
include/linux/dma-buf.h+10−3
@@ -112,19 +112,24 @@ struct dma_buf_ops { · 111 unmodified lines
112112 * @file: file pointer used for sharing buffers across, and for refcounting.
113113 * @attachments: list of dma_buf_attachment that denotes all devices attached.
114114 * @ops: dma_buf_ops associated with this buffer object.
115+ * @lock: used internally to serialize list manipulation, attach/detach and vmap/unmap
116+ * @vmapping_counter: used internally to refcnt the vmaps
117+ * @vmap_ptr: the current vmap ptr if vmapping_counter > 0
115118 * @exp_name: name of the exporter; useful for debugging.
116119 * @owner: pointer to exporter module; used for refcounting when exporter is a
117120 * kernel module.
118121 * @list_node: node for dma_buf accounting and debugging.
119122 * @priv: exporter specific private data for this buffer object.
120123 * @resv: reservation object linked to this dma-buf
124+ * @poll: for userspace poll support
125+ * @cb_excl: for userspace poll support
126+ * @cb_shared: for userspace poll support
121127 */
122128 struct dma_buf {
123129 size_t size;
124130 struct file *file;
125131 struct list_head attachments;
126132 const struct dma_buf_ops *ops;
127− /* mutex to serialize list manipulation, attach/detach and vmap/unmap */
128133 struct mutex lock;
129134 unsigned vmapping_counter;
130135 void *vmap_ptr;
@@ -188,9 +193,11 @@ struct dma_buf_export_info { · 57 unmodified lines
188193
189194 /**
190195 * helper macro for exporters; zeros and fills in most common values
196+ *
197+ * @name: export-info name
191198 */
192−#define DEFINE_DMA_BUF_EXPORT_INFO(a) \
193− struct dma_buf_export_info a = { .exp_name = KBUILD_MODNAME, \
199+#define DEFINE_DMA_BUF_EXPORT_INFO(name) \
200+ struct dma_buf_export_info name = { .exp_name = KBUILD_MODNAME, \
194201 .owner = THIS_MODULE }
195202
196203 /**
include/linux/fence.h+2−0
@@ -49,6 +49,8 @@ struct fence_cb; · 48 unmodified lines
4949 * @timestamp: Timestamp when the fence was signaled.
5050 * @status: Optional, only valid if < 0, must be set before calling
5151 * fence_signal, indicates that the fence has completed with an error.
52+ * @child_list: list of children fences
53+ * @active_list: list of active fences
5254 *
5355 * the flags member must be manipulated and read using the appropriate
5456 * atomic ops (bit_*), so taking the spinlock will not be needed most
include/linux/reservation.h+53−0
@@ -49,12 +49,27 @@ extern struct ww_class reservation_ww_class; · 48 unmodified lines
4949 extern struct lock_class_key reservation_seqcount_class;
5050 extern const char reservation_seqcount_string[];
5151
52+/**
53+ * struct reservation_object_list - a list of shared fences
54+ * @rcu: for internal use
55+ * @shared_count: table of shared fences
56+ * @shared_max: for growing shared fence table
57+ * @shared: shared fence table
58+ */
5259 struct reservation_object_list {
5360 struct rcu_head rcu;
5461 u32 shared_count, shared_max;
5562 struct fence __rcu *shared[];
5663 };
5764
65+/**
66+ * struct reservation_object - a reservation object manages fences for a buffer
67+ * @lock: update side lock
68+ * @seq: sequence count for managing RCU read-side synchronization
69+ * @fence_excl: the exclusive fence, if there is one currently
70+ * @fence: list of current shared fences
71+ * @staged: staged copy of shared fences for RCU updates
72+ */
5873 struct reservation_object {
5974 struct ww_mutex lock;
6075 seqcount_t seq;
@@ -68,6 +83,10 @@ struct reservation_object { · 7 unmodified lines
6883 #define reservation_object_assert_held(obj) \
6984 lockdep_assert_held(&(obj)->lock.base)
7085
86+/**
87+ * reservation_object_init - initialize a reservation object
88+ * @obj: the reservation object
89+ */
7190 static inline void
7291 reservation_object_init(struct reservation_object *obj)
7392 {
@@ -79,6 +98,10 @@ reservation_object_init(struct reservation_object *obj) · 5 unmodified lines
7998 obj->staged = NULL;
8099 }
81100
101+/**
102+ * reservation_object_fini - destroys a reservation object
103+ * @obj: the reservation object
104+ */
82105 static inline void
83106 reservation_object_fini(struct reservation_object *obj)
84107 {
@@ -106,6 +129,14 @@ reservation_object_fini(struct reservation_object *obj) · 21 unmodified lines
106129 ww_mutex_destroy(&obj->lock);
107130 }
108131
132+/**
133+ * reservation_object_get_list - get the reservation object's
134+ * shared fence list, with update-side lock held
135+ * @obj: the reservation object
136+ *
137+ * Returns the shared fence list. Does NOT take references to
138+ * the fence. The obj->lock must be held.
139+ */
109140 static inline struct reservation_object_list *
110141 reservation_object_get_list(struct reservation_object *obj)
111142 {
@@ -113,6 +144,17 @@ reservation_object_get_list(struct reservation_object *obj) · 1 unmodified line
113144 reservation_object_held(obj));
114145 }
115146
147+/**
148+ * reservation_object_get_excl - get the reservation object's
149+ * exclusive fence, with update-side lock held
150+ * @obj: the reservation object
151+ *
152+ * Returns the exclusive fence (if any). Does NOT take a
153+ * reference. The obj->lock must be held.
154+ *
155+ * RETURNS
156+ * The exclusive fence or NULL
157+ */
116158 static inline struct fence *
117159 reservation_object_get_excl(struct reservation_object *obj)
118160 {
@@ -120,6 +162,17 @@ reservation_object_get_excl(struct reservation_object *obj) · 1 unmodified line
120162 reservation_object_held(obj));
121163 }
122164
165+/**
166+ * reservation_object_get_excl_rcu - get the reservation object's
167+ * exclusive fence, without lock held.
168+ * @obj: the reservation object
169+ *
170+ * If there is an exclusive fence, this atomically increments it's
171+ * reference count and returns it.
172+ *
173+ * RETURNS
174+ * The exclusive fence or NULL if none
175+ */
123176 static inline struct fence *
124177 reservation_object_get_excl_rcu(struct reservation_object *obj)
125178 {

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