From: Thomas Hellstrom <thellstrom@vmware.com>
To: j.glisse@gmail.com
Cc: Jerome Glisse <jglisse@redhat.com>, dri-devel@lists.freedesktop.org
Subject: Re: [PATCH 07/13] drm/ttm: page allocation use page array instead of list
Date: Fri, 11 Nov 2011 09:02:51 +0100 [thread overview]
Message-ID: <4EBCD6AB.4010806@vmware.com> (raw)
In-Reply-To: <1320975417-13871-8-git-send-email-j.glisse@gmail.com>
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
On 11/11/2011 02:36 AM, j.glisse@gmail.com wrote:
> From: Jerome Glisse<jglisse@redhat.com>
>
> Use the ttm_tt pages array for pages allocations, move the list
> unwinding into the page allocation functions.
>
> Signed-off-by: Jerome Glisse<jglisse@redhat.com>
> ---
> drivers/gpu/drm/ttm/ttm_page_alloc.c | 85 +++++++++++++++++++++-------------
> drivers/gpu/drm/ttm/ttm_tt.c | 36 +++------------
> include/drm/ttm/ttm_page_alloc.h | 8 ++--
> 3 files changed, 63 insertions(+), 66 deletions(-)
>
> diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c
> index 727e93d..0f3e6d2 100644
> --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c
> +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c
> @@ -619,8 +619,10 @@ static void ttm_page_pool_fill_locked(struct ttm_page_pool *pool,
> * @return count of pages still required to fulfill the request.
> */
> static unsigned ttm_page_pool_get_pages(struct ttm_page_pool *pool,
> - struct list_head *pages, int ttm_flags,
> - enum ttm_caching_state cstate, unsigned count)
> + struct list_head *pages,
> + int ttm_flags,
> + enum ttm_caching_state cstate,
> + unsigned count)
> {
> unsigned long irq_flags;
> struct list_head *p;
> @@ -664,13 +666,15 @@ out:
> * On success pages list will hold count number of correctly
> * cached pages.
> */
> -int ttm_get_pages(struct list_head *pages, int flags,
> - enum ttm_caching_state cstate, unsigned count,
> +int ttm_get_pages(struct page **pages, int flags,
> + enum ttm_caching_state cstate, unsigned npages,
> dma_addr_t *dma_address)
> {
> struct ttm_page_pool *pool = ttm_get_pool(flags, cstate);
> + struct list_head plist;
> struct page *p = NULL;
> gfp_t gfp_flags = GFP_USER;
> + unsigned count;
> int r;
>
> /* set zero flag for page allocation if required */
> @@ -684,7 +688,7 @@ int ttm_get_pages(struct list_head *pages, int flags,
> else
> gfp_flags |= GFP_HIGHUSER;
>
> - for (r = 0; r< count; ++r) {
> + for (r = 0; r< npages; ++r) {
> p = alloc_page(gfp_flags);
> if (!p) {
>
> @@ -693,85 +697,100 @@ int ttm_get_pages(struct list_head *pages, int flags,
> return -ENOMEM;
> }
>
> - list_add(&p->lru, pages);
> + pages[r] = p;
> }
> return 0;
> }
>
> -
> /* combine zero flag to pool flags */
> gfp_flags |= pool->gfp_flags;
>
> /* First we take pages from the pool */
> - count = ttm_page_pool_get_pages(pool, pages, flags, cstate, count);
> + INIT_LIST_HEAD(&plist);
> + npages = ttm_page_pool_get_pages(pool,&plist, flags, cstate, npages);
> + count = 0;
> + list_for_each_entry(p,&plist, lru) {
> + pages[count++] = p;
> + }
>
> /* clear the pages coming from the pool if requested */
> if (flags& TTM_PAGE_FLAG_ZERO_ALLOC) {
> - list_for_each_entry(p, pages, lru) {
> + list_for_each_entry(p,&plist, lru) {
> clear_page(page_address(p));
> }
> }
>
> /* If pool didn't have enough pages allocate new one. */
> - if (count> 0) {
> + if (npages> 0) {
> /* ttm_alloc_new_pages doesn't reference pool so we can run
> * multiple requests in parallel.
> **/
> - r = ttm_alloc_new_pages(pages, gfp_flags, flags, cstate, count);
> + INIT_LIST_HEAD(&plist);
> + r = ttm_alloc_new_pages(&plist, gfp_flags, flags, cstate, npages);
> + list_for_each_entry(p,&plist, lru) {
> + pages[count++] = p;
> + }
> if (r) {
> /* If there is any pages in the list put them back to
> * the pool. */
> printk(KERN_ERR TTM_PFX
> "Failed to allocate extra pages "
> "for large request.");
> - ttm_put_pages(pages, 0, flags, cstate, NULL);
> + ttm_put_pages(pages, count, flags, cstate, NULL);
> return r;
> }
> }
>
> -
> return 0;
> }
>
> /* Put all pages in pages list to correct pool to wait for reuse */
> -void ttm_put_pages(struct list_head *pages, unsigned page_count, int flags,
> +void ttm_put_pages(struct page **pages, unsigned npages, int flags,
> enum ttm_caching_state cstate, dma_addr_t *dma_address)
> {
> unsigned long irq_flags;
> struct ttm_page_pool *pool = ttm_get_pool(flags, cstate);
> - struct page *p, *tmp;
> + unsigned i;
>
> if (pool == NULL) {
> /* No pool for this memory type so free the pages */
> -
> - list_for_each_entry_safe(p, tmp, pages, lru) {
> - __free_page(p);
> + for (i = 0; i< npages; i++) {
> + if (pages[i]) {
> + if (page_count(pages[i]) != 1)
> + printk(KERN_ERR TTM_PFX
> + "Erroneous page count. "
> + "Leaking pages.\n");
> + __free_page(pages[i]);
> + pages[i] = NULL;
> + }
> }
> - /* Make the pages list empty */
> - INIT_LIST_HEAD(pages);
> return;
> }
> - if (page_count == 0) {
> - list_for_each_entry_safe(p, tmp, pages, lru) {
> - ++page_count;
> - }
> - }
>
> spin_lock_irqsave(&pool->lock, irq_flags);
> - list_splice_init(pages,&pool->list);
> - pool->npages += page_count;
> + for (i = 0; i< npages; i++) {
> + if (pages[i]) {
> + if (page_count(pages[i]) != 1)
> + printk(KERN_ERR TTM_PFX
> + "Erroneous page count. "
> + "Leaking pages.\n");
> + list_add_tail(&pages[i]->lru,&pool->list);
> + pages[i] = NULL;
> + pool->npages++;
> + }
> + }
> /* Check that we don't go over the pool limit */
> - page_count = 0;
> + npages = 0;
> if (pool->npages> _manager->options.max_size) {
> - page_count = pool->npages - _manager->options.max_size;
> + npages = pool->npages - _manager->options.max_size;
> /* free at least NUM_PAGES_TO_ALLOC number of pages
> * to reduce calls to set_memory_wb */
> - if (page_count< NUM_PAGES_TO_ALLOC)
> - page_count = NUM_PAGES_TO_ALLOC;
> + if (npages< NUM_PAGES_TO_ALLOC)
> + npages = NUM_PAGES_TO_ALLOC;
> }
> spin_unlock_irqrestore(&pool->lock, irq_flags);
> - if (page_count)
> - ttm_page_pool_free(pool, page_count);
> + if (npages)
> + ttm_page_pool_free(pool, npages);
> }
>
> static void ttm_page_pool_init_locked(struct ttm_page_pool *pool, int flags,
> diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
> index aceecb5..0454f42 100644
> --- a/drivers/gpu/drm/ttm/ttm_tt.c
> +++ b/drivers/gpu/drm/ttm/ttm_tt.c
> @@ -65,22 +65,16 @@ static void ttm_tt_free_page_directory(struct ttm_tt *ttm)
> static struct page *__ttm_tt_get_page(struct ttm_tt *ttm, int index)
> {
> struct page *p;
> - struct list_head h;
> struct ttm_mem_global *mem_glob = ttm->glob->mem_glob;
> int ret;
>
> if (NULL == (p = ttm->pages[index])) {
>
> - INIT_LIST_HEAD(&h);
> -
> - ret = ttm_get_pages(&h, ttm->page_flags, ttm->caching_state, 1,
> + ret = ttm_get_pages(&p, ttm->page_flags, ttm->caching_state, 1,
> &ttm->dma_address[index]);
> -
> if (ret != 0)
> return NULL;
>
> - p = list_first_entry(&h, struct page, lru);
> -
> ret = ttm_mem_global_alloc_page(mem_glob, p, false, false);
> if (unlikely(ret != 0))
> goto out_err;
> @@ -89,9 +83,7 @@ static struct page *__ttm_tt_get_page(struct ttm_tt *ttm, int index)
> }
> return p;
> out_err:
> - INIT_LIST_HEAD(&h);
> - list_add(&p->lru,&h);
> - ttm_put_pages(&h, 1, ttm->page_flags,
> + ttm_put_pages(&p, 1, ttm->page_flags,
> ttm->caching_state,&ttm->dma_address[index]);
> return NULL;
> }
> @@ -242,33 +234,19 @@ EXPORT_SYMBOL(ttm_tt_set_placement_caching);
>
> static void ttm_tt_free_alloced_pages(struct ttm_tt *ttm)
> {
> - int i;
> - unsigned count = 0;
> - struct list_head h;
> - struct page *cur_page;
> struct ttm_backend *be = ttm->be;
> -
> - INIT_LIST_HEAD(&h);
> + unsigned i;
>
> if (be)
> be->func->clear(be);
> for (i = 0; i< ttm->num_pages; ++i) {
> -
> - cur_page = ttm->pages[i];
> - ttm->pages[i] = NULL;
> - if (cur_page) {
> - if (page_count(cur_page) != 1)
> - printk(KERN_ERR TTM_PFX
> - "Erroneous page count. "
> - "Leaking pages.\n");
> + if (ttm->pages[i]) {
> ttm_mem_global_free_page(ttm->glob->mem_glob,
> - cur_page);
> - list_add(&cur_page->lru,&h);
> - count++;
> + ttm->pages[i]);
> + ttm_put_pages(&ttm->pages[i], 1, ttm->page_flags,
> + ttm->caching_state,&ttm->dma_address[i]);
> }
> }
> - ttm_put_pages(&h, count, ttm->page_flags, ttm->caching_state,
> - ttm->dma_address);
> ttm->state = tt_unpopulated;
> }
>
> diff --git a/include/drm/ttm/ttm_page_alloc.h b/include/drm/ttm/ttm_page_alloc.h
> index 129de12..fe61c8d 100644
> --- a/include/drm/ttm/ttm_page_alloc.h
> +++ b/include/drm/ttm/ttm_page_alloc.h
> @@ -38,10 +38,10 @@
> * @count: number of pages to allocate.
> * @dma_address: The DMA (bus) address of pages (if TTM_PAGE_FLAG_DMA32 set).
> */
> -int ttm_get_pages(struct list_head *pages,
> +int ttm_get_pages(struct page **pages,
> int flags,
> enum ttm_caching_state cstate,
> - unsigned count,
> + unsigned npages,
> dma_addr_t *dma_address);
> /**
> * Put linked list of pages to pool.
> @@ -53,8 +53,8 @@ int ttm_get_pages(struct list_head *pages,
> * @cstate: ttm caching state.
> * @dma_address: The DMA (bus) address of pages (if TTM_PAGE_FLAG_DMA32 set).
> */
> -void ttm_put_pages(struct list_head *pages,
> - unsigned page_count,
> +void ttm_put_pages(struct page **pages,
> + unsigned npages,
> int flags,
> enum ttm_caching_state cstate,
> dma_addr_t *dma_address);
>
next prev parent reply other threads:[~2011-11-11 8:05 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-11-11 1:36 ttm: merge ttm_backend & ttm_tt, introduce ttm dma allocator V4 j.glisse
2011-11-11 1:36 ` [PATCH 01/13] swiotlb: Expose swiotlb_nr_tlb function to modules j.glisse
2011-11-11 1:36 ` [PATCH 02/13] drm/ttm: remove userspace backed ttm object support j.glisse
2011-11-11 1:36 ` [PATCH 03/13] drm/ttm: remove split btw highmen and lowmem page j.glisse
2011-11-11 1:36 ` [PATCH 04/13] drm/ttm: remove unused backend flags field j.glisse
2011-11-11 1:36 ` [PATCH 05/13] drm/ttm: use ttm put pages function to properly restore cache attribute j.glisse
2011-11-11 1:36 ` [PATCH 06/13] drm/ttm: test for dma_address array allocation failure j.glisse
2011-11-11 1:36 ` [PATCH 07/13] drm/ttm: page allocation use page array instead of list j.glisse
2011-11-11 8:02 ` Thomas Hellstrom [this message]
2011-11-11 1:36 ` [PATCH 08/13] drm/ttm: merge ttm_backend and ttm_tt V4 j.glisse
2011-11-11 8:03 ` Thomas Hellstrom
2011-11-11 1:36 ` [PATCH 09/13] drm/ttm: introduce callback for ttm_tt populate & unpopulate V4 j.glisse
2011-11-11 1:36 ` [PATCH 10/13] drm/ttm: provide dma aware ttm page pool code V7 j.glisse
2011-11-11 8:06 ` Thomas Hellstrom
2011-11-11 1:36 ` [PATCH 11/13] drm/radeon/kms: enable the ttm dma pool if swiotlb is on V3 j.glisse
2011-11-11 1:36 ` [PATCH 12/13] drm/nouveau: enable the ttm dma pool when swiotlb is active V3 j.glisse
2011-11-11 1:36 ` [PATCH 13/13] drm/ttm: isolate dma data from ttm_tt V2 j.glisse
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4EBCD6AB.4010806@vmware.com \
--to=thellstrom@vmware.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=j.glisse@gmail.com \
--cc=jglisse@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.