Commit 22a160fb authored by Linus Torvalds's avatar Linus Torvalds

v2.4.13.4 -> v2.4.13.5

  - Andrew Morton: remove stale UnlockPage
  - me: swap cache page locking update
parent f97f22cb
......@@ -466,20 +466,7 @@ static inline int is_page_cache_freeable(struct page * page)
return page_count(page) - !!page->buffers == 1;
}
/*
* Work out if there are any other processes sharing this
* swap cache page. Never mind the buffers.
*/
static inline int exclusive_swap_page(struct page *page)
{
if (!PageLocked(page))
BUG();
if (!PageSwapCache(page))
return 0;
if (page_count(page) - !!page->buffers != 2) /* 2: us + cache */
return 0;
return swap_count(page) == 1; /* 1: just cache */
}
extern int remove_exclusive_swap_page(struct page *);
extern void __free_pte(pte_t);
......
......@@ -29,7 +29,7 @@
#define PAGE_CACHE_ALIGN(addr) (((addr)+PAGE_CACHE_SIZE-1)&PAGE_CACHE_MASK)
#define page_cache_get(x) get_page(x)
#define page_cache_release(x) __free_page(x)
#define page_cache_release(x) free_lru_page(x)
static inline struct page *page_cache_alloc(struct address_space *x)
{
......
......@@ -939,9 +939,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma,
if (TryLockPage(old_page))
break;
/* Recheck swapcachedness once the page is locked */
can_reuse = exclusive_swap_page(old_page);
if (can_reuse)
delete_from_swap_cache(old_page);
can_reuse = remove_exclusive_swap_page(old_page);
UnlockPage(old_page);
if (!can_reuse)
break;
......@@ -965,7 +963,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma,
if (!new_page)
goto no_mem;
copy_cow_page(old_page,new_page,address);
free_lru_page(old_page);
page_cache_release(old_page);
/*
* Re-check the pte - we dropped the lock
......@@ -981,7 +979,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma,
new_page = old_page;
}
spin_unlock(&mm->page_table_lock);
free_lru_page(new_page);
page_cache_release(new_page);
return 1; /* Minor fault */
bad_wp_page:
......@@ -989,7 +987,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma,
printk("do_wp_page: bogus page at address %08lx (page 0x%lx)\n",address,(unsigned long)old_page);
return -1;
no_mem:
free_lru_page(old_page);
page_cache_release(old_page);
return -1;
}
......@@ -1150,7 +1148,6 @@ static int do_swap_page(struct mm_struct * mm,
*/
spin_lock(&mm->page_table_lock);
if (!pte_same(*page_table, orig_pte)) {
UnlockPage(page);
page_cache_release(page);
spin_unlock(&mm->page_table_lock);
return 1;
......@@ -1283,7 +1280,7 @@ static int do_no_page(struct mm_struct * mm, struct vm_area_struct * vma,
set_pte(page_table, entry);
} else {
/* One of our sibling threads was faster, back out. */
free_lru_page(new_page);
page_cache_release(new_page);
spin_unlock(&mm->page_table_lock);
return 1;
}
......
......@@ -137,11 +137,10 @@ void free_page_and_swap_cache(struct page *page)
* - Marcelo
*/
if (PageSwapCache(page) && !TryLockPage(page)) {
if (exclusive_swap_page(page))
delete_from_swap_cache(page);
remove_exclusive_swap_page(page);
UnlockPage(page);
}
free_lru_page(page);
page_cache_release(page);
}
/*
......
......@@ -223,6 +223,50 @@ void swap_free(swp_entry_t entry)
}
}
/*
* Work out if there are any other processes sharing this
* swap cache page. Free it if you can. Return success.
*/
int remove_exclusive_swap_page(struct page *page)
{
int retval;
struct swap_info_struct * p;
swp_entry_t entry;
if (!PageLocked(page))
BUG();
if (!PageSwapCache(page))
return 0;
if (page_count(page) - !!page->buffers != 2) /* 2: us + cache */
return 0;
entry.val = page->index;
p = swap_info_get(entry);
if (!p)
return 0;
/* Is the only swap cache user the cache itself? */
retval = 0;
if (p->swap_map[SWP_OFFSET(entry)] == 1) {
/* Recheck the page count with the pagecache lock held.. */
spin_lock(&pagecache_lock);
if (page_count(page) - !!page->buffers == 2) {
__delete_from_swap_cache(page);
retval = 1;
}
spin_unlock(&pagecache_lock);
}
swap_info_put(p);
if (retval) {
block_flushpage(page, 0);
swap_free(entry);
page_cache_release(page);
}
return retval;
}
/*
* Free the swap entry like above, but also try to
* free the page cache entry if it is the last user.
......@@ -242,7 +286,7 @@ void free_swap_and_cache(swp_entry_t entry)
page_cache_get(page);
delete_from_swap_cache(page);
UnlockPage(page);
free_lru_page(page);
page_cache_release(page);
}
}
......@@ -582,7 +626,7 @@ static int try_to_unuse(unsigned int type)
*/
SetPageDirty(page);
UnlockPage(page);
free_lru_page(page);
page_cache_release(page);
/*
* Make sure that we aren't completely killing
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment