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; |