@@ -344,6 +344,28 @@ static unsigned int ttm_pool_page_order(struct ttm_pool *pool, struct page *p)
344344 return p -> private ;
345345}
346346
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+
347369/**
348370 * ttm_pool_alloc - Fill a ttm_tt object
349371 *
@@ -385,45 +407,57 @@ int ttm_pool_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
385407 for (order = min_t (unsigned int , MAX_ORDER - 1 , __fls (num_pages ));
386408 num_pages ;
387409 order = min_t (unsigned int , order , __fls (num_pages ))) {
388- bool apply_caching = false;
389410 struct ttm_pool_type * pt ;
390411
391412 pt = ttm_pool_select_type (pool , tt -> caching , order );
392413 p = pt ? ttm_pool_type_take (pt ) : NULL ;
393414 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 ) {
411415 r = ttm_pool_apply_caching (caching , pages ,
412416 tt -> caching );
413417 if (r )
414418 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 ;
416434 }
417435
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 );
420447 if (r )
421448 goto error_free_page ;
449+ if (PageHighMem (p ))
450+ caching = pages ;
422451 }
423452
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+ }
427461 }
428462
429463 r = ttm_pool_apply_caching (caching , pages , tt -> caching );
0 commit comments