@@ -176,18 +176,15 @@ static void add_umem_to_per_mm(struct ib_umem_odp *umem_odp)
176
176
struct ib_ucontext_per_mm * per_mm = umem_odp -> per_mm ;
177
177
178
178
down_write (& per_mm -> umem_rwsem );
179
- if (likely (ib_umem_start (umem_odp ) != ib_umem_end (umem_odp ))) {
180
- /*
181
- * Note that the representation of the intervals in the
182
- * interval tree considers the ending point as contained in
183
- * the interval, while the function ib_umem_end returns the
184
- * first address which is not contained in the umem.
185
- */
186
- umem_odp -> interval_tree .start = ib_umem_start (umem_odp );
187
- umem_odp -> interval_tree .last = ib_umem_end (umem_odp ) - 1 ;
188
- interval_tree_insert (& umem_odp -> interval_tree ,
189
- & per_mm -> umem_tree );
190
- }
179
+ /*
180
+ * Note that the representation of the intervals in the interval tree
181
+ * considers the ending point as contained in the interval, while the
182
+ * function ib_umem_end returns the first address which is not
183
+ * contained in the umem.
184
+ */
185
+ umem_odp -> interval_tree .start = ib_umem_start (umem_odp );
186
+ umem_odp -> interval_tree .last = ib_umem_end (umem_odp ) - 1 ;
187
+ interval_tree_insert (& umem_odp -> interval_tree , & per_mm -> umem_tree );
191
188
up_write (& per_mm -> umem_rwsem );
192
189
}
193
190
@@ -196,11 +193,8 @@ static void remove_umem_from_per_mm(struct ib_umem_odp *umem_odp)
196
193
struct ib_ucontext_per_mm * per_mm = umem_odp -> per_mm ;
197
194
198
195
down_write (& per_mm -> umem_rwsem );
199
- if (likely (ib_umem_start (umem_odp ) != ib_umem_end (umem_odp )))
200
- interval_tree_remove (& umem_odp -> interval_tree ,
201
- & per_mm -> umem_tree );
196
+ interval_tree_remove (& umem_odp -> interval_tree , & per_mm -> umem_tree );
202
197
complete_all (& umem_odp -> notifier_completion );
203
-
204
198
up_write (& per_mm -> umem_rwsem );
205
199
}
206
200
@@ -320,6 +314,9 @@ struct ib_umem_odp *ib_alloc_odp_umem(struct ib_umem_odp *root,
320
314
int pages = size >> PAGE_SHIFT ;
321
315
int ret ;
322
316
317
+ if (!size )
318
+ return ERR_PTR (- EINVAL );
319
+
323
320
odp_data = kzalloc (sizeof (* odp_data ), GFP_KERNEL );
324
321
if (!odp_data )
325
322
return ERR_PTR (- ENOMEM );
@@ -381,6 +378,9 @@ int ib_umem_odp_get(struct ib_umem_odp *umem_odp, int access)
381
378
struct mm_struct * mm = umem -> owning_mm ;
382
379
int ret_val ;
383
380
381
+ if (umem_odp -> umem .address == 0 && umem_odp -> umem .length == 0 )
382
+ umem_odp -> is_implicit_odp = 1 ;
383
+
384
384
umem_odp -> page_shift = PAGE_SHIFT ;
385
385
if (access & IB_ACCESS_HUGETLB ) {
386
386
struct vm_area_struct * vma ;
@@ -401,7 +401,10 @@ int ib_umem_odp_get(struct ib_umem_odp *umem_odp, int access)
401
401
402
402
init_completion (& umem_odp -> notifier_completion );
403
403
404
- if (ib_umem_odp_num_pages (umem_odp )) {
404
+ if (!umem_odp -> is_implicit_odp ) {
405
+ if (!ib_umem_odp_num_pages (umem_odp ))
406
+ return - EINVAL ;
407
+
405
408
umem_odp -> page_list =
406
409
vzalloc (array_size (sizeof (* umem_odp -> page_list ),
407
410
ib_umem_odp_num_pages (umem_odp )));
@@ -420,7 +423,9 @@ int ib_umem_odp_get(struct ib_umem_odp *umem_odp, int access)
420
423
ret_val = get_per_mm (umem_odp );
421
424
if (ret_val )
422
425
goto out_dma_list ;
423
- add_umem_to_per_mm (umem_odp );
426
+
427
+ if (!umem_odp -> is_implicit_odp )
428
+ add_umem_to_per_mm (umem_odp );
424
429
425
430
return 0 ;
426
431
@@ -439,13 +444,14 @@ void ib_umem_odp_release(struct ib_umem_odp *umem_odp)
439
444
* It is the driver's responsibility to ensure, before calling us,
440
445
* that the hardware will not attempt to access the MR any more.
441
446
*/
442
- ib_umem_odp_unmap_dma_pages (umem_odp , ib_umem_start (umem_odp ),
443
- ib_umem_end (umem_odp ));
444
-
445
- remove_umem_from_per_mm (umem_odp );
447
+ if (!umem_odp -> is_implicit_odp ) {
448
+ ib_umem_odp_unmap_dma_pages (umem_odp , ib_umem_start (umem_odp ),
449
+ ib_umem_end (umem_odp ));
450
+ remove_umem_from_per_mm (umem_odp );
451
+ vfree (umem_odp -> dma_list );
452
+ vfree (umem_odp -> page_list );
453
+ }
446
454
put_per_mm (umem_odp );
447
- vfree (umem_odp -> dma_list );
448
- vfree (umem_odp -> page_list );
449
455
}
450
456
451
457
/*
0 commit comments