Subversion Repositories Kolibri OS

Rev

Rev 4075 | Rev 4569 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4075 Rev 4112
Line 381... Line 381...
381
out:
381
out:
382
	kfree(pages_to_free);
382
	kfree(pages_to_free);
383
	return nr_free;
383
	return nr_free;
384
}
384
}
Line 385... Line -...
385
 
-
 
386
/* Get good estimation how many pages are free in pools */
-
 
387
static int ttm_pool_get_num_unused_pages(void)
-
 
388
{
-
 
389
	unsigned i;
-
 
390
	int total = 0;
-
 
391
	for (i = 0; i < NUM_POOLS; ++i)
-
 
392
		total += _manager->pools[i].npages;
-
 
393
 
-
 
394
	return total;
-
 
395
}
-
 
396
 
385
 
397
/**
386
/**
-
 
387
 * Callback for mm to request pool to reduce number of page held.
-
 
388
 *
-
 
389
 * XXX: (dchinner) Deadlock warning!
-
 
390
 *
-
 
391
 * ttm_page_pool_free() does memory allocation using GFP_KERNEL.  that means
-
 
392
 * this can deadlock when called a sc->gfp_mask that is not equal to
-
 
393
 * GFP_KERNEL.
-
 
394
 *
398
 * Callback for mm to request pool to reduce number of page held.
395
 * This code is crying out for a shrinker per pool....
399
 */
396
 */
400
static int ttm_pool_mm_shrink(struct shrinker *shrink,
397
static unsigned long
401
			      struct shrink_control *sc)
398
ttm_pool_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
402
{
399
{
403
	static atomic_t start_pool = ATOMIC_INIT(0);
400
	static atomic_t start_pool = ATOMIC_INIT(0);
404
	unsigned i;
401
	unsigned i;
405
	unsigned pool_offset = atomic_add_return(1, &start_pool);
402
	unsigned pool_offset = atomic_add_return(1, &start_pool);
406
	struct ttm_page_pool *pool;
403
	struct ttm_page_pool *pool;
-
 
404
	int shrink_pages = sc->nr_to_scan;
Line 407... Line 405...
407
	int shrink_pages = sc->nr_to_scan;
405
	unsigned long freed = 0;
408
 
406
 
409
	pool_offset = pool_offset % NUM_POOLS;
407
	pool_offset = pool_offset % NUM_POOLS;
410
	/* select start pool in round robin fashion */
408
	/* select start pool in round robin fashion */
411
	for (i = 0; i < NUM_POOLS; ++i) {
409
	for (i = 0; i < NUM_POOLS; ++i) {
412
		unsigned nr_free = shrink_pages;
410
		unsigned nr_free = shrink_pages;
413
		if (shrink_pages == 0)
411
		if (shrink_pages == 0)
414
			break;
412
			break;
-
 
413
		pool = &_manager->pools[(i + pool_offset)%NUM_POOLS];
-
 
414
		shrink_pages = ttm_page_pool_free(pool, nr_free);
-
 
415
		freed += nr_free - shrink_pages;
415
		pool = &_manager->pools[(i + pool_offset)%NUM_POOLS];
416
	}
-
 
417
	return freed;
-
 
418
}
-
 
419
 
416
		shrink_pages = ttm_page_pool_free(pool, nr_free);
420
 
-
 
421
static unsigned long
-
 
422
ttm_pool_shrink_count(struct shrinker *shrink, struct shrink_control *sc)
-
 
423
{
-
 
424
	unsigned i;
-
 
425
	unsigned long count = 0;
417
	}
426
 
-
 
427
	for (i = 0; i < NUM_POOLS; ++i)
-
 
428
		count += _manager->pools[i].npages;
418
	/* return estimated number of unused pages in pool */
429
 
Line 419... Line 430...
419
	return ttm_pool_get_num_unused_pages();
430
	return count;
420
}
431
}
-
 
432
 
421
 
433
static void ttm_pool_mm_shrink_init(struct ttm_pool_manager *manager)
422
static void ttm_pool_mm_shrink_init(struct ttm_pool_manager *manager)
434
{
423
{
435
	manager->mm_shrink.count_objects = ttm_pool_shrink_count;
424
	manager->mm_shrink.shrink = &ttm_pool_mm_shrink;
436
	manager->mm_shrink.scan_objects = ttm_pool_shrink_scan;
Line 425... Line 437...
425
	manager->mm_shrink.seeks = 1;
437
	manager->mm_shrink.seeks = 1;