On 2018å¹´04æ??26æ?¥ 23:06, Michel Dänzer wrote: > From: Michel Dänzer <michel.daenzer at amd.com> > > When it's set, TTM tries to allocate huge pages if possible. Do you mean original driver doesn't do this? From the code, driver always try huge pages if CONFIG_TRANSPARENT_HUGEPAGE is enabled. Regards, David Zhou > Drivers > which can take advantage of huge pages should set it. > > Drivers not setting this flag no longer incur any overhead related to > allocating or freeing huge pages. > > Cc: stable at vger.kernel.org > Signed-off-by: Michel Dänzer <michel.daenzer at amd.com> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +- > drivers/gpu/drm/ttm/ttm_page_alloc.c | 14 ++++++++++---- > drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | 8 +++++--- > include/drm/ttm/ttm_tt.h | 1 + > 4 files changed, 17 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > index dfd22db13fb1..e03e9e361e2a 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > @@ -988,7 +988,7 @@ static struct ttm_tt *amdgpu_ttm_tt_create(struct ttm_buffer_object *bo, > return NULL; > } > gtt->ttm.ttm.func = &amdgpu_backend_func; > - if (ttm_sg_tt_init(>t->ttm, bo, page_flags)) { > + if (ttm_sg_tt_init(>t->ttm, bo, page_flags | TTM_PAGE_FLAG_TRANSHUGE)) { > kfree(gtt); > return NULL; > } > diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c > index f0481b7b60c5..2ce91272b111 100644 > --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c > +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c > @@ -760,7 +760,7 @@ static void ttm_put_pages(struct page **pages, unsigned npages, int flags, > { > struct ttm_page_pool *pool = ttm_get_pool(flags, false, cstate); > #ifdef CONFIG_TRANSPARENT_HUGEPAGE > - struct ttm_page_pool *huge = ttm_get_pool(flags, true, cstate); > + struct ttm_page_pool *huge = NULL; > #endif > unsigned long irq_flags; > unsigned i; > @@ -780,7 +780,8 @@ static void ttm_put_pages(struct page **pages, unsigned npages, int flags, > } > > #ifdef CONFIG_TRANSPARENT_HUGEPAGE > - if (!(flags & TTM_PAGE_FLAG_DMA32)) { > + if ((flags & (TTM_PAGE_FLAG_DMA32 | TTM_PAGE_FLAG_TRANSHUGE)) == > + TTM_PAGE_FLAG_TRANSHUGE) { > for (j = 0; j < HPAGE_PMD_NR; ++j) > if (p++ != pages[i + j]) > break; > @@ -805,6 +806,8 @@ static void ttm_put_pages(struct page **pages, unsigned npages, int flags, > > i = 0; > #ifdef CONFIG_TRANSPARENT_HUGEPAGE > + if (flags & TTM_PAGE_FLAG_TRANSHUGE) > + huge = ttm_get_pool(flags, true, cstate); > if (huge) { > unsigned max_size, n2free; > > @@ -877,7 +880,7 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags, > { > struct ttm_page_pool *pool = ttm_get_pool(flags, false, cstate); > #ifdef CONFIG_TRANSPARENT_HUGEPAGE > - struct ttm_page_pool *huge = ttm_get_pool(flags, true, cstate); > + struct ttm_page_pool *huge = NULL; > #endif > struct list_head plist; > struct page *p = NULL; > @@ -906,7 +909,8 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags, > > i = 0; > #ifdef CONFIG_TRANSPARENT_HUGEPAGE > - if (!(gfp_flags & GFP_DMA32)) { > + if ((flags & (TTM_PAGE_FLAG_DMA32 | TTM_PAGE_FLAG_TRANSHUGE)) == > + TTM_PAGE_FLAG_TRANSHUGE) { > while (npages >= HPAGE_PMD_NR) { > gfp_t huge_flags = gfp_flags; > > @@ -946,6 +950,8 @@ static int ttm_get_pages(struct page **pages, unsigned npages, int flags, > count = 0; > > #ifdef CONFIG_TRANSPARENT_HUGEPAGE > + if (flags & TTM_PAGE_FLAG_TRANSHUGE) > + huge = ttm_get_pool(flags, true, cstate); > if (huge && npages >= HPAGE_PMD_NR) { > INIT_LIST_HEAD(&plist); > ttm_page_pool_get_pages(huge, &plist, flags, cstate, > diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c > index 8a25d1974385..291b04213ec5 100644 > --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c > +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c > @@ -949,7 +949,8 @@ int ttm_dma_populate(struct ttm_dma_tt *ttm_dma, struct device *dev, > type = ttm_to_type(ttm->page_flags, ttm->caching_state); > > #ifdef CONFIG_TRANSPARENT_HUGEPAGE > - if (ttm->page_flags & TTM_PAGE_FLAG_DMA32) > + if ((ttm->page_flags & (TTM_PAGE_FLAG_DMA32 | TTM_PAGE_FLAG_TRANSHUGE)) > + != TTM_PAGE_FLAG_TRANSHUGE) > goto skip_huge; > > pool = ttm_dma_find_pool(dev, type | IS_HUGE); > @@ -1035,7 +1036,7 @@ void ttm_dma_unpopulate(struct ttm_dma_tt *ttm_dma, struct device *dev) > { > struct ttm_tt *ttm = &ttm_dma->ttm; > struct ttm_mem_global *mem_glob = ttm->bdev->glob->mem_glob; > - struct dma_pool *pool; > + struct dma_pool *pool = NULL; > struct dma_page *d_page, *next; > enum pool_type type; > bool is_cached = false; > @@ -1045,7 +1046,8 @@ void ttm_dma_unpopulate(struct ttm_dma_tt *ttm_dma, struct device *dev) > type = ttm_to_type(ttm->page_flags, ttm->caching_state); > > #ifdef CONFIG_TRANSPARENT_HUGEPAGE > - pool = ttm_dma_find_pool(dev, type | IS_HUGE); > + if (ttm->page_flags & TTM_PAGE_FLAG_TRANSHUGE) > + pool = ttm_dma_find_pool(dev, type | IS_HUGE); > if (pool) { > count = 0; > list_for_each_entry_safe(d_page, next, &ttm_dma->pages_list, > diff --git a/include/drm/ttm/ttm_tt.h b/include/drm/ttm/ttm_tt.h > index c0e928abf592..c7d2120f0362 100644 > --- a/include/drm/ttm/ttm_tt.h > +++ b/include/drm/ttm/ttm_tt.h > @@ -41,6 +41,7 @@ struct ttm_operation_ctx; > #define TTM_PAGE_FLAG_DMA32 (1 << 7) > #define TTM_PAGE_FLAG_SG (1 << 8) > #define TTM_PAGE_FLAG_NO_RETRY (1 << 9) > +#define TTM_PAGE_FLAG_TRANSHUGE (1 << 10) > > enum ttm_caching_state { > tt_uncached,