Skip to content

Commit ebb8cb2

Browse files
committed
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
2 parents 6b15d66 + b02da6f commit ebb8cb2

File tree

6 files changed

+169
-14
lines changed

6 files changed

+169
-14
lines changed

Documentation/DocBook/device-drivers.tmpl

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,16 +128,44 @@ X!Edrivers/base/interface.c
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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
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)
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,
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

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,17 @@
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);
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 @@ reservation_object_add_shared_replace(struct reservation_object *obj,
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,
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,
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 @@ int reservation_object_get_fences_rcu(struct reservation_object *obj,
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)
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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,19 +112,24 @@ struct dma_buf_ops {
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 {
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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ struct fence_cb;
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

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,27 @@ extern struct ww_class reservation_ww_class;
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 {
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)
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,20 +129,50 @@ reservation_object_fini(struct reservation_object *obj)
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
{
112143
return rcu_dereference_protected(obj->fence,
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
{
119161
return rcu_dereference_protected(obj->fence_excl,
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
{

0 commit comments

Comments
 (0)