@@ -70,7 +70,7 @@ static void dma_fence_array_cb_func(struct dma_fence *f,
7070static bool dma_fence_array_enable_signaling (struct dma_fence * fence )
7171{
7272 struct dma_fence_array * array = to_dma_fence_array (fence );
73- struct dma_fence_array_cb * cb = ( void * )( & array [ 1 ]) ;
73+ struct dma_fence_array_cb * cb = array -> callbacks ;
7474 unsigned i ;
7575
7676 for (i = 0 ; i < array -> num_fences ; ++ i ) {
@@ -144,46 +144,45 @@ const struct dma_fence_ops dma_fence_array_ops = {
144144EXPORT_SYMBOL (dma_fence_array_ops );
145145
146146/**
147- * dma_fence_array_create - Create a custom fence array
147+ * dma_fence_array_alloc - Allocate a custom fence array
148+ * @num_fences: [in] number of fences to add in the array
149+ *
150+ * Return dma fence array on success, NULL on failure
151+ */
152+ struct dma_fence_array * dma_fence_array_alloc (int num_fences )
153+ {
154+ struct dma_fence_array * array ;
155+
156+ return kzalloc (struct_size (array , callbacks , num_fences ), GFP_KERNEL );
157+ }
158+ EXPORT_SYMBOL (dma_fence_array_alloc );
159+
160+ /**
161+ * dma_fence_array_init - Init a custom fence array
162+ * @array: [in] dma fence array to arm
148163 * @num_fences: [in] number of fences to add in the array
149164 * @fences: [in] array containing the fences
150165 * @context: [in] fence context to use
151166 * @seqno: [in] sequence number to use
152167 * @signal_on_any: [in] signal on any fence in the array
153168 *
154- * Allocate a dma_fence_array object and initialize the base fence with
155- * dma_fence_init().
156- * In case of error it returns NULL.
157- *
158- * The caller should allocate the fences array with num_fences size
159- * and fill it with the fences it wants to add to the object. Ownership of this
160- * array is taken and dma_fence_put() is used on each fence on release.
161- *
162- * If @signal_on_any is true the fence array signals if any fence in the array
163- * signals, otherwise it signals when all fences in the array signal.
169+ * Implementation of @dma_fence_array_create without allocation. Useful to init
170+ * a preallocated dma fence array in the path of reclaim or dma fence signaling.
164171 */
165- struct dma_fence_array * dma_fence_array_create ( int num_fences ,
166- struct dma_fence * * fences ,
167- u64 context , unsigned seqno ,
168- bool signal_on_any )
172+ void dma_fence_array_init ( struct dma_fence_array * array ,
173+ int num_fences , struct dma_fence * * fences ,
174+ u64 context , unsigned seqno ,
175+ bool signal_on_any )
169176{
170- struct dma_fence_array * array ;
171- size_t size = sizeof (* array );
172-
173177 WARN_ON (!num_fences || !fences );
174178
175- /* Allocate the callback structures behind the array. */
176- size += num_fences * sizeof (struct dma_fence_array_cb );
177- array = kzalloc (size , GFP_KERNEL );
178- if (!array )
179- return NULL ;
179+ array -> num_fences = num_fences ;
180180
181181 spin_lock_init (& array -> lock );
182182 dma_fence_init (& array -> base , & dma_fence_array_ops , & array -> lock ,
183183 context , seqno );
184184 init_irq_work (& array -> work , irq_dma_fence_array_work );
185185
186- array -> num_fences = num_fences ;
187186 atomic_set (& array -> num_pending , signal_on_any ? 1 : num_fences );
188187 array -> fences = fences ;
189188
@@ -202,6 +201,41 @@ struct dma_fence_array *dma_fence_array_create(int num_fences,
202201 */
203202 while (num_fences -- )
204203 WARN_ON (dma_fence_is_container (fences [num_fences ]));
204+ }
205+ EXPORT_SYMBOL (dma_fence_array_init );
206+
207+ /**
208+ * dma_fence_array_create - Create a custom fence array
209+ * @num_fences: [in] number of fences to add in the array
210+ * @fences: [in] array containing the fences
211+ * @context: [in] fence context to use
212+ * @seqno: [in] sequence number to use
213+ * @signal_on_any: [in] signal on any fence in the array
214+ *
215+ * Allocate a dma_fence_array object and initialize the base fence with
216+ * dma_fence_init().
217+ * In case of error it returns NULL.
218+ *
219+ * The caller should allocate the fences array with num_fences size
220+ * and fill it with the fences it wants to add to the object. Ownership of this
221+ * array is taken and dma_fence_put() is used on each fence on release.
222+ *
223+ * If @signal_on_any is true the fence array signals if any fence in the array
224+ * signals, otherwise it signals when all fences in the array signal.
225+ */
226+ struct dma_fence_array * dma_fence_array_create (int num_fences ,
227+ struct dma_fence * * fences ,
228+ u64 context , unsigned seqno ,
229+ bool signal_on_any )
230+ {
231+ struct dma_fence_array * array ;
232+
233+ array = dma_fence_array_alloc (num_fences );
234+ if (!array )
235+ return NULL ;
236+
237+ dma_fence_array_init (array , num_fences , fences ,
238+ context , seqno , signal_on_any );
205239
206240 return array ;
207241}
0 commit comments