> +int ttm_dma_populate(struct ttm_tt *ttm, struct device *dev)
> +{
.. snip..

> +     for (i = 0; i < ttm->num_pages; ++i) {
> +             ret = ttm_dma_pool_get_pages(pool, ttm, i);
> +             if (ret != 0) {
> +                     ttm_dma_unpopulate(ttm, dev);
> +                     return -ENOMEM;
> +             }
> +
> +             ret = ttm_mem_global_alloc_page(mem_glob, ttm->pages[i],
> +                                             false, false);

Ok, so we increment it here..

.. snip..
> +void ttm_dma_unpopulate(struct ttm_tt *ttm, struct device *dev)
> +{
> +     struct dma_pool *pool;
> +     struct dma_page *d_page;
> +     enum pool_type type;
> +     bool is_cached = false;
> +     unsigned count = 0, i;
> +     unsigned long irq_flags;
> +
> +     type = ttm_to_type(ttm->page_flags, ttm->caching_state);
> +     pool = ttm_dma_find_pool(dev, type);
> +     if (!pool) {
> +             WARN_ON(!pool);
> +             return;
> +     }
> +     is_cached = (ttm_dma_find_pool(pool->dev,
> +                  ttm_to_type(ttm->page_flags, tt_cached)) == pool);
> +
> +     /* make sure pages array match list and count number of pages */
> +     list_for_each_entry(d_page, &ttm->alloc_list, page_list) {
> +             ttm->pages[count] = d_page->p;
> +             count++;
> +     }
> +
> +     spin_lock_irqsave(&pool->lock, irq_flags);
> +     pool->npages_in_use -= count;
> +     if (is_cached) {
> +             pool->nfrees += count;
> +     } else {
> +             pool->npages_free += count;
> +             list_splice(&ttm->alloc_list, &pool->free_list);
> +             if (pool->npages_free > _manager->options.max_size) {
> +                     count = pool->npages_free - _manager->options.max_size;
> +             }
> +     }
> +     spin_unlock_irqrestore(&pool->lock, irq_flags);

But we don't do it here.  I think you need:

        for (i = 0; i < ttm->num_pages; i++) {
                ttm_mem_global_free_page(mem_glob, ttm->pages[i]);

And it has to be done before ttm_dma_pages_put as at that point the
pages are truly gone.

Could actually be done in the '/* make sure pages array match list .."


> +
> +     if (is_cached) {
> +             ttm_dma_pages_put(pool, &ttm->alloc_list,
> +                               ttm->pages, count);
> +     }
> +
> +     INIT_LIST_HEAD(&ttm->alloc_list);
> +     for (i = 0; i < ttm->num_pages; i++) {
> +             ttm->pages[i] = NULL;
> +             ttm->dma_address[i] = 0;
> +     }

Reply via email to