@@ -344,6 +344,28 @@ static unsigned int ttm_pool_page_order(struct ttm_pool *pool, struct page *p)
344
344
return p -> private ;
345
345
}
346
346
347
+ /* Called when we got a page, either from a pool or newly allocated */
348
+ static int ttm_pool_page_allocated (struct ttm_pool * pool , unsigned int order ,
349
+ struct page * p , dma_addr_t * * dma_addr ,
350
+ unsigned long * num_pages ,
351
+ struct page * * * pages )
352
+ {
353
+ unsigned int i ;
354
+ int r ;
355
+
356
+ if (* dma_addr ) {
357
+ r = ttm_pool_map (pool , order , p , dma_addr );
358
+ if (r )
359
+ return r ;
360
+ }
361
+
362
+ * num_pages -= 1 << order ;
363
+ for (i = 1 << order ; i ; -- i , ++ (* pages ), ++ p )
364
+ * * pages = p ;
365
+
366
+ return 0 ;
367
+ }
368
+
347
369
/**
348
370
* ttm_pool_alloc - Fill a ttm_tt object
349
371
*
@@ -385,45 +407,57 @@ int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
385
407
for (order = min_t (unsigned int , MAX_ORDER - 1 , __fls (num_pages ));
386
408
num_pages ;
387
409
order = min_t (unsigned int , order , __fls (num_pages ))) {
388
- bool apply_caching = false;
389
410
struct ttm_pool_type * pt ;
390
411
391
412
pt = ttm_pool_select_type (pool , tt -> caching , order );
392
413
p = pt ? ttm_pool_type_take (pt ) : NULL ;
393
414
if (p ) {
394
- apply_caching = true;
395
- } else {
396
- p = ttm_pool_alloc_page (pool , gfp_flags , order );
397
- if (p && PageHighMem (p ))
398
- apply_caching = true;
399
- }
400
-
401
- if (!p ) {
402
- if (order ) {
403
- -- order ;
404
- continue ;
405
- }
406
- r = - ENOMEM ;
407
- goto error_free_all ;
408
- }
409
-
410
- if (apply_caching ) {
411
415
r = ttm_pool_apply_caching (caching , pages ,
412
416
tt -> caching );
413
417
if (r )
414
418
goto error_free_page ;
415
- caching = pages + (1 << order );
419
+
420
+ do {
421
+ r = ttm_pool_page_allocated (pool , order , p ,
422
+ & dma_addr ,
423
+ & num_pages ,
424
+ & pages );
425
+ if (r )
426
+ goto error_free_page ;
427
+
428
+ if (num_pages < (1 << order ))
429
+ break ;
430
+
431
+ p = ttm_pool_type_take (pt );
432
+ } while (p );
433
+ caching = pages ;
416
434
}
417
435
418
- if (dma_addr ) {
419
- r = ttm_pool_map (pool , order , p , & dma_addr );
436
+ while (num_pages >= (1 << order ) &&
437
+ (p = ttm_pool_alloc_page (pool , gfp_flags , order ))) {
438
+
439
+ if (PageHighMem (p )) {
440
+ r = ttm_pool_apply_caching (caching , pages ,
441
+ tt -> caching );
442
+ if (r )
443
+ goto error_free_page ;
444
+ }
445
+ r = ttm_pool_page_allocated (pool , order , p , & dma_addr ,
446
+ & num_pages , & pages );
420
447
if (r )
421
448
goto error_free_page ;
449
+ if (PageHighMem (p ))
450
+ caching = pages ;
422
451
}
423
452
424
- num_pages -= 1 << order ;
425
- for (i = 1 << order ; i ; -- i )
426
- * (pages ++ ) = p ++ ;
453
+ if (!p ) {
454
+ if (order ) {
455
+ -- order ;
456
+ continue ;
457
+ }
458
+ r = - ENOMEM ;
459
+ goto error_free_all ;
460
+ }
427
461
}
428
462
429
463
r = ttm_pool_apply_caching (caching , pages , tt -> caching );
0 commit comments