Skip to content

Commit

Permalink
msm: kgsl: Use lock-less list for page pools
Browse files Browse the repository at this point in the history
Page pool additions and removals are very hot during GPU workloads, so
they should be optimized accordingly. We can use a lock-less list for
storing the free pages in order to speed things up. The lock-less list
allows for one llist_del_first() user and unlimited llist_add() users to
run concurrently, so only a spin lock around the llist_del_first() is
needed; everything else is lock-free. The per-pool page count is now an
atomic to make it lock-free as well.

Signed-off-by: Sultan Alsawaf <[email protected]>
[jjpprrrr: adapted _kgsl_pool_get_page() because k4.9 does not update
vmstat counter for memory held in pools]
Signed-off-by: Chenyang Zhong <[email protected]>
  • Loading branch information
kerneltoast authored and zeelog committed Aug 25, 2022
1 parent bcd8421 commit 61264c3
Showing 1 changed file with 13 additions and 20 deletions.
33 changes: 13 additions & 20 deletions drivers/gpu/msm/kgsl_pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@
*/
struct kgsl_page_pool {
unsigned int pool_order;
int page_count;
atomic_t page_count;
unsigned int reserved_pages;
bool allocation_allowed;
spinlock_t list_lock;
struct list_head page_list;
struct llist_head page_list;
};

static struct kgsl_page_pool kgsl_pools[KGSL_MAX_POOLS];
Expand Down Expand Up @@ -85,40 +85,33 @@ _kgsl_pool_add_page(struct kgsl_page_pool *pool, struct page *p)
{
_kgsl_pool_zero_page(p, pool->pool_order);

spin_lock(&pool->list_lock);
list_add_tail(&p->lru, &pool->page_list);
pool->page_count++;
spin_unlock(&pool->list_lock);
llist_add((struct llist_node *)&p->lru, &pool->page_list);
atomic_inc(&pool->page_count);
}

/* Returns a page from specified pool */
static struct page *
_kgsl_pool_get_page(struct kgsl_page_pool *pool)
{
struct llist_node *node;
struct page *p = NULL;

spin_lock(&pool->list_lock);
if (pool->page_count) {
p = list_first_entry(&pool->page_list, struct page, lru);
pool->page_count--;
list_del(&p->lru);
}
node = llist_del_first(&pool->page_list);
spin_unlock(&pool->list_lock);

if (node) {
atomic_dec(&pool->page_count);
p = container_of((struct list_head *)node, typeof(*p), lru);
}
return p;
}

/* Returns the number of pages in specified pool */
static int
kgsl_pool_size(struct kgsl_page_pool *kgsl_pool)
kgsl_pool_size(struct kgsl_page_pool *pool)
{
int size;

spin_lock(&kgsl_pool->list_lock);
size = kgsl_pool->page_count * (1 << kgsl_pool->pool_order);
spin_unlock(&kgsl_pool->list_lock);

return size;
return atomic_read(&pool->page_count) * (1 << pool->pool_order);
}

/* Returns the number of pages in all kgsl page pools */
Expand Down Expand Up @@ -508,7 +501,7 @@ static void kgsl_pool_config(unsigned int order, unsigned int reserved_pages,
kgsl_pools[kgsl_num_pools].reserved_pages = reserved_pages;
kgsl_pools[kgsl_num_pools].allocation_allowed = allocation_allowed;
spin_lock_init(&kgsl_pools[kgsl_num_pools].list_lock);
INIT_LIST_HEAD(&kgsl_pools[kgsl_num_pools].page_list);
init_llist_head(&kgsl_pools[kgsl_num_pools].page_list);
kgsl_num_pools++;
}

Expand Down

0 comments on commit 61264c3

Please sign in to comment.