static int ttm_pool_mm_shrink(struct shrinker *shrink,
struct shrink_control *sc)
{
- static atomic_t start_pool = ATOMIC_INIT(0);
+ static DEFINE_MUTEX(lock);
+ static unsigned start_pool;
unsigned i;
- unsigned pool_offset = atomic_add_return(1, &start_pool);
+ unsigned pool_offset;
struct ttm_page_pool *pool;
int shrink_pages = sc->nr_to_scan;
- pool_offset = pool_offset % NUM_POOLS;
+ if (shrink_pages == 0)
+ goto out;
+ if (!mutex_trylock(&lock))
+ return -1;
+ pool_offset = ++start_pool % NUM_POOLS;
/* select start pool in round robin fashion */
for (i = 0; i < NUM_POOLS; ++i) {
unsigned nr_free = shrink_pages;
pool = &_manager->pools[(i + pool_offset)%NUM_POOLS];
shrink_pages = ttm_page_pool_free(pool, nr_free);
}
+ mutex_unlock(&lock);
+out:
/* return estimated number of unused pages in pool */
return ttm_pool_get_num_unused_pages();
}