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

Configure Feed

Select the types of activity you want to include in your feed.

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

+170 -15
+33 -5
Documentation/DocBook/device-drivers.tmpl
··· 128 128 !Edrivers/base/platform.c 129 129 !Edrivers/base/bus.c 130 130 </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> 132 151 !Edrivers/dma-buf/dma-buf.c 133 - !Edrivers/dma-buf/fence.c 134 - !Edrivers/dma-buf/seqno-fence.c 135 - !Iinclude/linux/fence.h 136 - !Iinclude/linux/seqno-fence.h 152 + !Iinclude/linux/dma-buf.h 153 + </sect2> 154 + <sect2><title>reservation</title> 155 + !Pdrivers/dma-buf/reservation.c Reservation Object Overview 137 156 !Edrivers/dma-buf/reservation.c 138 157 !Iinclude/linux/reservation.h 158 + </sect2> 159 + <sect2><title>fence</title> 160 + !Edrivers/dma-buf/fence.c 161 + !Iinclude/linux/fence.h 162 + !Edrivers/dma-buf/seqno-fence.c 163 + !Iinclude/linux/seqno-fence.h 139 164 !Edrivers/dma-buf/sync_file.c 140 165 !Iinclude/linux/sync_file.h 166 + </sect2> 167 + </sect1> 168 + <sect1><title>Device Drivers DMA Management</title> 141 169 !Edrivers/base/dma-coherent.c 142 170 !Edrivers/base/dma-mapping.c 143 171 </sect1>
+4 -3
drivers/dma-buf/dma-buf.c
··· 33 33 #include <linux/seq_file.h> 34 34 #include <linux/poll.h> 35 35 #include <linux/reservation.h> 36 + #include <linux/mm.h> 36 37 37 38 #include <uapi/linux/dma-buf.h> 38 39 ··· 91 90 dmabuf = file->private_data; 92 91 93 92 /* check for overflowing the buffer's size */ 94 - if (vma->vm_pgoff + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) > 93 + if (vma->vm_pgoff + vma_pages(vma) > 95 94 dmabuf->size >> PAGE_SHIFT) 96 95 return -EINVAL; 97 96 ··· 724 723 return -EINVAL; 725 724 726 725 /* check for offset overflow */ 727 - if (pgoff + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) < pgoff) 726 + if (pgoff + vma_pages(vma) < pgoff) 728 727 return -EOVERFLOW; 729 728 730 729 /* check for overflowing the buffer's size */ 731 - if (pgoff + ((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) > 730 + if (pgoff + vma_pages(vma) > 732 731 dmabuf->size >> PAGE_SHIFT) 733 732 return -EINVAL; 734 733
+68 -4
drivers/dma-buf/reservation.c
··· 35 35 #include <linux/reservation.h> 36 36 #include <linux/export.h> 37 37 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 + 38 49 DEFINE_WW_CLASS(reservation_ww_class); 39 50 EXPORT_SYMBOL(reservation_ww_class); 40 51 ··· 54 43 55 44 const char reservation_seqcount_string[] = "reservation_seqcount"; 56 45 EXPORT_SYMBOL(reservation_seqcount_string); 57 - /* 58 - * Reserve space to add a shared fence to a reservation_object, 59 - * must be called with obj->lock held. 46 + 47 + /** 48 + * reservation_object_reserve_shared - Reserve space to add a shared 49 + * fence to a reservation_object. 50 + * @obj: reservation object 51 + * 52 + * Should be called before reservation_object_add_shared_fence(). Must 53 + * be called with obj->lock held. 54 + * 55 + * RETURNS 56 + * Zero for success, or -errno 60 57 */ 61 58 int reservation_object_reserve_shared(struct reservation_object *obj) 62 59 { ··· 199 180 fence_put(old_fence); 200 181 } 201 182 202 - /* 183 + /** 184 + * reservation_object_add_shared_fence - Add a fence to a shared slot 185 + * @obj: the reservation object 186 + * @fence: the shared fence to add 187 + * 203 188 * Add a fence to a shared slot, obj->lock must be held, and 204 189 * reservation_object_reserve_shared_fence has been called. 205 190 */ ··· 223 200 } 224 201 EXPORT_SYMBOL(reservation_object_add_shared_fence); 225 202 203 + /** 204 + * reservation_object_add_excl_fence - Add an exclusive fence. 205 + * @obj: the reservation object 206 + * @fence: the shared fence to add 207 + * 208 + * Add a fence to the exclusive slot. The obj->lock must be held. 209 + */ 226 210 void reservation_object_add_excl_fence(struct reservation_object *obj, 227 211 struct fence *fence) 228 212 { ··· 263 233 } 264 234 EXPORT_SYMBOL(reservation_object_add_excl_fence); 265 235 236 + /** 237 + * reservation_object_get_fences_rcu - Get an object's shared and exclusive 238 + * fences without update side lock held 239 + * @obj: the reservation object 240 + * @pfence_excl: the returned exclusive fence (or NULL) 241 + * @pshared_count: the number of shared fences returned 242 + * @pshared: the array of shared fence ptrs returned (array is krealloc'd to 243 + * the required size, and must be freed by caller) 244 + * 245 + * RETURNS 246 + * Zero or -errno 247 + */ 266 248 int reservation_object_get_fences_rcu(struct reservation_object *obj, 267 249 struct fence **pfence_excl, 268 250 unsigned *pshared_count, ··· 361 319 } 362 320 EXPORT_SYMBOL_GPL(reservation_object_get_fences_rcu); 363 321 322 + /** 323 + * reservation_object_wait_timeout_rcu - Wait on reservation's objects 324 + * shared and/or exclusive fences. 325 + * @obj: the reservation object 326 + * @wait_all: if true, wait on all fences, else wait on just exclusive fence 327 + * @intr: if true, do interruptible wait 328 + * @timeout: timeout value in jiffies or zero to return immediately 329 + * 330 + * RETURNS 331 + * Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or 332 + * greater than zer on success. 333 + */ 364 334 long reservation_object_wait_timeout_rcu(struct reservation_object *obj, 365 335 bool wait_all, bool intr, 366 336 unsigned long timeout) ··· 470 416 return ret; 471 417 } 472 418 419 + /** 420 + * reservation_object_test_signaled_rcu - Test if a reservation object's 421 + * fences have been signaled. 422 + * @obj: the reservation object 423 + * @test_all: if true, test all fences, otherwise only test the exclusive 424 + * fence 425 + * 426 + * RETURNS 427 + * true if all fences signaled, else false 428 + */ 473 429 bool reservation_object_test_signaled_rcu(struct reservation_object *obj, 474 430 bool test_all) 475 431 {
+10 -3
include/linux/dma-buf.h
··· 112 112 * @file: file pointer used for sharing buffers across, and for refcounting. 113 113 * @attachments: list of dma_buf_attachment that denotes all devices attached. 114 114 * @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 115 118 * @exp_name: name of the exporter; useful for debugging. 116 119 * @owner: pointer to exporter module; used for refcounting when exporter is a 117 120 * kernel module. 118 121 * @list_node: node for dma_buf accounting and debugging. 119 122 * @priv: exporter specific private data for this buffer object. 120 123 * @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 121 127 */ 122 128 struct dma_buf { 123 129 size_t size; 124 130 struct file *file; 125 131 struct list_head attachments; 126 132 const struct dma_buf_ops *ops; 127 - /* mutex to serialize list manipulation, attach/detach and vmap/unmap */ 128 133 struct mutex lock; 129 134 unsigned vmapping_counter; 130 135 void *vmap_ptr; ··· 193 188 194 189 /** 195 190 * helper macro for exporters; zeros and fills in most common values 191 + * 192 + * @name: export-info name 196 193 */ 197 - #define DEFINE_DMA_BUF_EXPORT_INFO(a) \ 198 - struct dma_buf_export_info a = { .exp_name = KBUILD_MODNAME, \ 194 + #define DEFINE_DMA_BUF_EXPORT_INFO(name) \ 195 + struct dma_buf_export_info name = { .exp_name = KBUILD_MODNAME, \ 199 196 .owner = THIS_MODULE } 200 197 201 198 /**
+2
include/linux/fence.h
··· 49 49 * @timestamp: Timestamp when the fence was signaled. 50 50 * @status: Optional, only valid if < 0, must be set before calling 51 51 * 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 52 54 * 53 55 * the flags member must be manipulated and read using the appropriate 54 56 * atomic ops (bit_*), so taking the spinlock will not be needed most
+53
include/linux/reservation.h
··· 49 49 extern struct lock_class_key reservation_seqcount_class; 50 50 extern const char reservation_seqcount_string[]; 51 51 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 + */ 52 59 struct reservation_object_list { 53 60 struct rcu_head rcu; 54 61 u32 shared_count, shared_max; 55 62 struct fence __rcu *shared[]; 56 63 }; 57 64 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 + */ 58 73 struct reservation_object { 59 74 struct ww_mutex lock; 60 75 seqcount_t seq; ··· 83 68 #define reservation_object_assert_held(obj) \ 84 69 lockdep_assert_held(&(obj)->lock.base) 85 70 71 + /** 72 + * reservation_object_init - initialize a reservation object 73 + * @obj: the reservation object 74 + */ 86 75 static inline void 87 76 reservation_object_init(struct reservation_object *obj) 88 77 { ··· 98 79 obj->staged = NULL; 99 80 } 100 81 82 + /** 83 + * reservation_object_fini - destroys a reservation object 84 + * @obj: the reservation object 85 + */ 101 86 static inline void 102 87 reservation_object_fini(struct reservation_object *obj) 103 88 { ··· 129 106 ww_mutex_destroy(&obj->lock); 130 107 } 131 108 109 + /** 110 + * reservation_object_get_list - get the reservation object's 111 + * shared fence list, with update-side lock held 112 + * @obj: the reservation object 113 + * 114 + * Returns the shared fence list. Does NOT take references to 115 + * the fence. The obj->lock must be held. 116 + */ 132 117 static inline struct reservation_object_list * 133 118 reservation_object_get_list(struct reservation_object *obj) 134 119 { ··· 144 113 reservation_object_held(obj)); 145 114 } 146 115 116 + /** 117 + * reservation_object_get_excl - get the reservation object's 118 + * exclusive fence, with update-side lock held 119 + * @obj: the reservation object 120 + * 121 + * Returns the exclusive fence (if any). Does NOT take a 122 + * reference. The obj->lock must be held. 123 + * 124 + * RETURNS 125 + * The exclusive fence or NULL 126 + */ 147 127 static inline struct fence * 148 128 reservation_object_get_excl(struct reservation_object *obj) 149 129 { ··· 162 120 reservation_object_held(obj)); 163 121 } 164 122 123 + /** 124 + * reservation_object_get_excl_rcu - get the reservation object's 125 + * exclusive fence, without lock held. 126 + * @obj: the reservation object 127 + * 128 + * If there is an exclusive fence, this atomically increments it's 129 + * reference count and returns it. 130 + * 131 + * RETURNS 132 + * The exclusive fence or NULL if none 133 + */ 165 134 static inline struct fence * 166 135 reservation_object_get_excl_rcu(struct reservation_object *obj) 167 136 {