Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2c05114d authored by Konrad Rzeszutek Wilk's avatar Konrad Rzeszutek Wilk Committed by Dave Airlie
Browse files

drm/ttm/dma: Fix accounting error when calling ttm_mem_global_free_page and...


drm/ttm/dma: Fix accounting error when calling ttm_mem_global_free_page and don't try to free freed pages.

The code to figure out how many pages to shrink the pool
ends up capping the 'count' at _manager->options.max_size - which is OK.
Except that the 'count' is also used when accounting for how many pages
are recycled - which we end up with the invalid values. This fixes
it by using a different value for the amount of pages to shrink.

On top of that we would free the cached page pool - which is nonsense
as they are deleted from the pool - so there are no free pages in that
pool..

Also we also missed the opportunity to batch the amount of pages
to free (similar to how ttm_page_alloc.c does it). This reintroduces
the code that was lost during rebasing.

Reviewed-by: default avatarJerome Glisse <jglisse@redhat.com>
Signed-off-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 36d7c537
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -949,7 +949,7 @@ void ttm_dma_unpopulate(struct ttm_dma_tt *ttm_dma, struct device *dev)
	struct dma_page *d_page, *next;
	enum pool_type type;
	bool is_cached = false;
	unsigned count = 0, i;
	unsigned count = 0, i, npages = 0;
	unsigned long irq_flags;

	type = ttm_to_type(ttm->page_flags, ttm->caching_state);
@@ -974,8 +974,13 @@ void ttm_dma_unpopulate(struct ttm_dma_tt *ttm_dma, struct device *dev)
	} else {
		pool->npages_free += count;
		list_splice(&ttm_dma->pages_list, &pool->free_list);
		npages = count;
		if (pool->npages_free > _manager->options.max_size) {
			count = pool->npages_free - _manager->options.max_size;
			npages = pool->npages_free - _manager->options.max_size;
			/* free at least NUM_PAGES_TO_ALLOC number of pages
			 * to reduce calls to set_memory_wb */
			if (npages < NUM_PAGES_TO_ALLOC)
				npages = NUM_PAGES_TO_ALLOC;
		}
	}
	spin_unlock_irqrestore(&pool->lock, irq_flags);
@@ -999,9 +1004,9 @@ void ttm_dma_unpopulate(struct ttm_dma_tt *ttm_dma, struct device *dev)
		ttm_dma->dma_address[i] = 0;
	}

	/* shrink pool if necessary */
	if (count)
		ttm_dma_page_pool_free(pool, count);
	/* shrink pool if necessary (only on !is_cached pools)*/
	if (npages)
		ttm_dma_page_pool_free(pool, npages);
	ttm->state = tt_unpopulated;
}
EXPORT_SYMBOL_GPL(ttm_dma_unpopulate);