aboutsummaryrefslogtreecommitdiffstats
path: root/mm/swapfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/swapfile.c')
-rw-r--r--mm/swapfile.c90
1 files changed, 55 insertions, 35 deletions
diff --git a/mm/swapfile.c b/mm/swapfile.c
index bd1bb5920306..90cb67a5417c 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -33,17 +33,18 @@
33#include <asm/tlbflush.h> 33#include <asm/tlbflush.h>
34#include <linux/swapops.h> 34#include <linux/swapops.h>
35 35
36DEFINE_SPINLOCK(swap_lock); 36static DEFINE_SPINLOCK(swap_lock);
37unsigned int nr_swapfiles; 37static unsigned int nr_swapfiles;
38long total_swap_pages; 38long total_swap_pages;
39static int swap_overflow; 39static int swap_overflow;
40static int least_priority;
40 41
41static const char Bad_file[] = "Bad swap file entry "; 42static const char Bad_file[] = "Bad swap file entry ";
42static const char Unused_file[] = "Unused swap file entry "; 43static const char Unused_file[] = "Unused swap file entry ";
43static const char Bad_offset[] = "Bad swap offset entry "; 44static const char Bad_offset[] = "Bad swap offset entry ";
44static const char Unused_offset[] = "Unused swap offset entry "; 45static const char Unused_offset[] = "Unused swap offset entry ";
45 46
46struct swap_list_t swap_list = {-1, -1}; 47static struct swap_list_t swap_list = {-1, -1};
47 48
48static struct swap_info_struct swap_info[MAX_SWAPFILES]; 49static struct swap_info_struct swap_info[MAX_SWAPFILES];
49 50
@@ -343,7 +344,7 @@ int can_share_swap_page(struct page *page)
343 * Work out if there are any other processes sharing this 344 * Work out if there are any other processes sharing this
344 * swap cache page. Free it if you can. Return success. 345 * swap cache page. Free it if you can. Return success.
345 */ 346 */
346int remove_exclusive_swap_page(struct page *page) 347static int remove_exclusive_swap_page_count(struct page *page, int count)
347{ 348{
348 int retval; 349 int retval;
349 struct swap_info_struct * p; 350 struct swap_info_struct * p;
@@ -356,7 +357,7 @@ int remove_exclusive_swap_page(struct page *page)
356 return 0; 357 return 0;
357 if (PageWriteback(page)) 358 if (PageWriteback(page))
358 return 0; 359 return 0;
359 if (page_count(page) != 2) /* 2: us + cache */ 360 if (page_count(page) != count) /* us + cache + ptes */
360 return 0; 361 return 0;
361 362
362 entry.val = page_private(page); 363 entry.val = page_private(page);
@@ -368,13 +369,13 @@ int remove_exclusive_swap_page(struct page *page)
368 retval = 0; 369 retval = 0;
369 if (p->swap_map[swp_offset(entry)] == 1) { 370 if (p->swap_map[swp_offset(entry)] == 1) {
370 /* Recheck the page count with the swapcache lock held.. */ 371 /* Recheck the page count with the swapcache lock held.. */
371 write_lock_irq(&swapper_space.tree_lock); 372 spin_lock_irq(&swapper_space.tree_lock);
372 if ((page_count(page) == 2) && !PageWriteback(page)) { 373 if ((page_count(page) == count) && !PageWriteback(page)) {
373 __delete_from_swap_cache(page); 374 __delete_from_swap_cache(page);
374 SetPageDirty(page); 375 SetPageDirty(page);
375 retval = 1; 376 retval = 1;
376 } 377 }
377 write_unlock_irq(&swapper_space.tree_lock); 378 spin_unlock_irq(&swapper_space.tree_lock);
378 } 379 }
379 spin_unlock(&swap_lock); 380 spin_unlock(&swap_lock);
380 381
@@ -387,6 +388,25 @@ int remove_exclusive_swap_page(struct page *page)
387} 388}
388 389
389/* 390/*
391 * Most of the time the page should have two references: one for the
392 * process and one for the swap cache.
393 */
394int remove_exclusive_swap_page(struct page *page)
395{
396 return remove_exclusive_swap_page_count(page, 2);
397}
398
399/*
400 * The pageout code holds an extra reference to the page. That raises
401 * the reference count to test for to 2 for a page that is only in the
402 * swap cache plus 1 for each process that maps the page.
403 */
404int remove_exclusive_swap_page_ref(struct page *page)
405{
406 return remove_exclusive_swap_page_count(page, 2 + page_mapcount(page));
407}
408
409/*
390 * Free the swap entry like above, but also try to 410 * Free the swap entry like above, but also try to
391 * free the page cache entry if it is the last user. 411 * free the page cache entry if it is the last user.
392 */ 412 */
@@ -402,7 +422,7 @@ void free_swap_and_cache(swp_entry_t entry)
402 if (p) { 422 if (p) {
403 if (swap_entry_free(p, swp_offset(entry)) == 1) { 423 if (swap_entry_free(p, swp_offset(entry)) == 1) {
404 page = find_get_page(&swapper_space, entry.val); 424 page = find_get_page(&swapper_space, entry.val);
405 if (page && unlikely(TestSetPageLocked(page))) { 425 if (page && !trylock_page(page)) {
406 page_cache_release(page); 426 page_cache_release(page);
407 page = NULL; 427 page = NULL;
408 } 428 }
@@ -655,8 +675,8 @@ static int unuse_mm(struct mm_struct *mm,
655 675
656 if (!down_read_trylock(&mm->mmap_sem)) { 676 if (!down_read_trylock(&mm->mmap_sem)) {
657 /* 677 /*
658 * Activate page so shrink_cache is unlikely to unmap its 678 * Activate page so shrink_inactive_list is unlikely to unmap
659 * ptes while lock is dropped, so swapoff can make progress. 679 * its ptes while lock is dropped, so swapoff can make progress.
660 */ 680 */
661 activate_page(page); 681 activate_page(page);
662 unlock_page(page); 682 unlock_page(page);
@@ -1260,6 +1280,11 @@ asmlinkage long sys_swapoff(const char __user * specialfile)
1260 /* just pick something that's safe... */ 1280 /* just pick something that's safe... */
1261 swap_list.next = swap_list.head; 1281 swap_list.next = swap_list.head;
1262 } 1282 }
1283 if (p->prio < 0) {
1284 for (i = p->next; i >= 0; i = swap_info[i].next)
1285 swap_info[i].prio = p->prio--;
1286 least_priority++;
1287 }
1263 nr_swap_pages -= p->pages; 1288 nr_swap_pages -= p->pages;
1264 total_swap_pages -= p->pages; 1289 total_swap_pages -= p->pages;
1265 p->flags &= ~SWP_WRITEOK; 1290 p->flags &= ~SWP_WRITEOK;
@@ -1272,9 +1297,14 @@ asmlinkage long sys_swapoff(const char __user * specialfile)
1272 if (err) { 1297 if (err) {
1273 /* re-insert swap space back into swap_list */ 1298 /* re-insert swap space back into swap_list */
1274 spin_lock(&swap_lock); 1299 spin_lock(&swap_lock);
1275 for (prev = -1, i = swap_list.head; i >= 0; prev = i, i = swap_info[i].next) 1300 if (p->prio < 0)
1301 p->prio = --least_priority;
1302 prev = -1;
1303 for (i = swap_list.head; i >= 0; i = swap_info[i].next) {
1276 if (p->prio >= swap_info[i].prio) 1304 if (p->prio >= swap_info[i].prio)
1277 break; 1305 break;
1306 prev = i;
1307 }
1278 p->next = i; 1308 p->next = i;
1279 if (prev < 0) 1309 if (prev < 0)
1280 swap_list.head = swap_list.next = p - swap_info; 1310 swap_list.head = swap_list.next = p - swap_info;
@@ -1447,7 +1477,6 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags)
1447 unsigned int type; 1477 unsigned int type;
1448 int i, prev; 1478 int i, prev;
1449 int error; 1479 int error;
1450 static int least_priority;
1451 union swap_header *swap_header = NULL; 1480 union swap_header *swap_header = NULL;
1452 int swap_header_version; 1481 int swap_header_version;
1453 unsigned int nr_good_pages = 0; 1482 unsigned int nr_good_pages = 0;
@@ -1455,7 +1484,7 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags)
1455 sector_t span; 1484 sector_t span;
1456 unsigned long maxpages = 1; 1485 unsigned long maxpages = 1;
1457 int swapfilesize; 1486 int swapfilesize;
1458 unsigned short *swap_map; 1487 unsigned short *swap_map = NULL;
1459 struct page *page = NULL; 1488 struct page *page = NULL;
1460 struct inode *inode = NULL; 1489 struct inode *inode = NULL;
1461 int did_down = 0; 1490 int did_down = 0;
@@ -1474,22 +1503,10 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags)
1474 } 1503 }
1475 if (type >= nr_swapfiles) 1504 if (type >= nr_swapfiles)
1476 nr_swapfiles = type+1; 1505 nr_swapfiles = type+1;
1506 memset(p, 0, sizeof(*p));
1477 INIT_LIST_HEAD(&p->extent_list); 1507 INIT_LIST_HEAD(&p->extent_list);
1478 p->flags = SWP_USED; 1508 p->flags = SWP_USED;
1479 p->swap_file = NULL;
1480 p->old_block_size = 0;
1481 p->swap_map = NULL;
1482 p->lowest_bit = 0;
1483 p->highest_bit = 0;
1484 p->cluster_nr = 0;
1485 p->inuse_pages = 0;
1486 p->next = -1; 1509 p->next = -1;
1487 if (swap_flags & SWAP_FLAG_PREFER) {
1488 p->prio =
1489 (swap_flags & SWAP_FLAG_PRIO_MASK)>>SWAP_FLAG_PRIO_SHIFT;
1490 } else {
1491 p->prio = --least_priority;
1492 }
1493 spin_unlock(&swap_lock); 1510 spin_unlock(&swap_lock);
1494 name = getname(specialfile); 1511 name = getname(specialfile);
1495 error = PTR_ERR(name); 1512 error = PTR_ERR(name);
@@ -1632,19 +1649,20 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags)
1632 goto bad_swap; 1649 goto bad_swap;
1633 1650
1634 /* OK, set up the swap map and apply the bad block list */ 1651 /* OK, set up the swap map and apply the bad block list */
1635 if (!(p->swap_map = vmalloc(maxpages * sizeof(short)))) { 1652 swap_map = vmalloc(maxpages * sizeof(short));
1653 if (!swap_map) {
1636 error = -ENOMEM; 1654 error = -ENOMEM;
1637 goto bad_swap; 1655 goto bad_swap;
1638 } 1656 }
1639 1657
1640 error = 0; 1658 error = 0;
1641 memset(p->swap_map, 0, maxpages * sizeof(short)); 1659 memset(swap_map, 0, maxpages * sizeof(short));
1642 for (i = 0; i < swap_header->info.nr_badpages; i++) { 1660 for (i = 0; i < swap_header->info.nr_badpages; i++) {
1643 int page_nr = swap_header->info.badpages[i]; 1661 int page_nr = swap_header->info.badpages[i];
1644 if (page_nr <= 0 || page_nr >= swap_header->info.last_page) 1662 if (page_nr <= 0 || page_nr >= swap_header->info.last_page)
1645 error = -EINVAL; 1663 error = -EINVAL;
1646 else 1664 else
1647 p->swap_map[page_nr] = SWAP_MAP_BAD; 1665 swap_map[page_nr] = SWAP_MAP_BAD;
1648 } 1666 }
1649 nr_good_pages = swap_header->info.last_page - 1667 nr_good_pages = swap_header->info.last_page -
1650 swap_header->info.nr_badpages - 1668 swap_header->info.nr_badpages -
@@ -1654,7 +1672,7 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags)
1654 } 1672 }
1655 1673
1656 if (nr_good_pages) { 1674 if (nr_good_pages) {
1657 p->swap_map[0] = SWAP_MAP_BAD; 1675 swap_map[0] = SWAP_MAP_BAD;
1658 p->max = maxpages; 1676 p->max = maxpages;
1659 p->pages = nr_good_pages; 1677 p->pages = nr_good_pages;
1660 nr_extents = setup_swap_extents(p, &span); 1678 nr_extents = setup_swap_extents(p, &span);
@@ -1672,6 +1690,12 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags)
1672 1690
1673 mutex_lock(&swapon_mutex); 1691 mutex_lock(&swapon_mutex);
1674 spin_lock(&swap_lock); 1692 spin_lock(&swap_lock);
1693 if (swap_flags & SWAP_FLAG_PREFER)
1694 p->prio =
1695 (swap_flags & SWAP_FLAG_PRIO_MASK) >> SWAP_FLAG_PRIO_SHIFT;
1696 else
1697 p->prio = --least_priority;
1698 p->swap_map = swap_map;
1675 p->flags = SWP_ACTIVE; 1699 p->flags = SWP_ACTIVE;
1676 nr_swap_pages += nr_good_pages; 1700 nr_swap_pages += nr_good_pages;
1677 total_swap_pages += nr_good_pages; 1701 total_swap_pages += nr_good_pages;
@@ -1707,12 +1731,8 @@ bad_swap:
1707 destroy_swap_extents(p); 1731 destroy_swap_extents(p);
1708bad_swap_2: 1732bad_swap_2:
1709 spin_lock(&swap_lock); 1733 spin_lock(&swap_lock);
1710 swap_map = p->swap_map;
1711 p->swap_file = NULL; 1734 p->swap_file = NULL;
1712 p->swap_map = NULL;
1713 p->flags = 0; 1735 p->flags = 0;
1714 if (!(swap_flags & SWAP_FLAG_PREFER))
1715 ++least_priority;
1716 spin_unlock(&swap_lock); 1736 spin_unlock(&swap_lock);
1717 vfree(swap_map); 1737 vfree(swap_map);
1718 if (swap_file) 1738 if (swap_file)