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) ...@@ -466,20 +466,7 @@ static inline int is_page_cache_freeable(struct page * page)
return page_count(page) - !!page->buffers == 1; return page_count(page) - !!page->buffers == 1;
} }
/* extern int remove_exclusive_swap_page(struct page *);
* 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 void __free_pte(pte_t); extern void __free_pte(pte_t);
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#define PAGE_CACHE_ALIGN(addr) (((addr)+PAGE_CACHE_SIZE-1)&PAGE_CACHE_MASK) #define PAGE_CACHE_ALIGN(addr) (((addr)+PAGE_CACHE_SIZE-1)&PAGE_CACHE_MASK)
#define page_cache_get(x) get_page(x) #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) 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, ...@@ -939,9 +939,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma,
if (TryLockPage(old_page)) if (TryLockPage(old_page))
break; break;
/* Recheck swapcachedness once the page is locked */ /* Recheck swapcachedness once the page is locked */
can_reuse = exclusive_swap_page(old_page); can_reuse = remove_exclusive_swap_page(old_page);
if (can_reuse)
delete_from_swap_cache(old_page);
UnlockPage(old_page); UnlockPage(old_page);
if (!can_reuse) if (!can_reuse)
break; break;
...@@ -965,7 +963,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma, ...@@ -965,7 +963,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma,
if (!new_page) if (!new_page)
goto no_mem; goto no_mem;
copy_cow_page(old_page,new_page,address); 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 * 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, ...@@ -981,7 +979,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma,
new_page = old_page; new_page = old_page;
} }
spin_unlock(&mm->page_table_lock); spin_unlock(&mm->page_table_lock);
free_lru_page(new_page); page_cache_release(new_page);
return 1; /* Minor fault */ return 1; /* Minor fault */
bad_wp_page: bad_wp_page:
...@@ -989,7 +987,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma, ...@@ -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); printk("do_wp_page: bogus page at address %08lx (page 0x%lx)\n",address,(unsigned long)old_page);
return -1; return -1;
no_mem: no_mem:
free_lru_page(old_page); page_cache_release(old_page);
return -1; return -1;
} }
...@@ -1150,7 +1148,6 @@ static int do_swap_page(struct mm_struct * mm, ...@@ -1150,7 +1148,6 @@ static int do_swap_page(struct mm_struct * mm,
*/ */
spin_lock(&mm->page_table_lock); spin_lock(&mm->page_table_lock);
if (!pte_same(*page_table, orig_pte)) { if (!pte_same(*page_table, orig_pte)) {
UnlockPage(page);
page_cache_release(page); page_cache_release(page);
spin_unlock(&mm->page_table_lock); spin_unlock(&mm->page_table_lock);
return 1; return 1;
...@@ -1283,7 +1280,7 @@ static int do_no_page(struct mm_struct * mm, struct vm_area_struct * vma, ...@@ -1283,7 +1280,7 @@ static int do_no_page(struct mm_struct * mm, struct vm_area_struct * vma,
set_pte(page_table, entry); set_pte(page_table, entry);
} else { } else {
/* One of our sibling threads was faster, back out. */ /* 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); spin_unlock(&mm->page_table_lock);
return 1; return 1;
} }
......
...@@ -137,11 +137,10 @@ void free_page_and_swap_cache(struct page *page) ...@@ -137,11 +137,10 @@ void free_page_and_swap_cache(struct page *page)
* - Marcelo * - Marcelo
*/ */
if (PageSwapCache(page) && !TryLockPage(page)) { if (PageSwapCache(page) && !TryLockPage(page)) {
if (exclusive_swap_page(page)) remove_exclusive_swap_page(page);
delete_from_swap_cache(page);
UnlockPage(page); UnlockPage(page);
} }
free_lru_page(page); page_cache_release(page);
} }
/* /*
......
...@@ -223,6 +223,50 @@ void swap_free(swp_entry_t entry) ...@@ -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 swap entry like above, but also try to
* free the page cache entry if it is the last user. * free the page cache entry if it is the last user.
...@@ -242,7 +286,7 @@ void free_swap_and_cache(swp_entry_t entry) ...@@ -242,7 +286,7 @@ void free_swap_and_cache(swp_entry_t entry)
page_cache_get(page); page_cache_get(page);
delete_from_swap_cache(page); delete_from_swap_cache(page);
UnlockPage(page); UnlockPage(page);
free_lru_page(page); page_cache_release(page);
} }
} }
...@@ -582,7 +626,7 @@ static int try_to_unuse(unsigned int type) ...@@ -582,7 +626,7 @@ static int try_to_unuse(unsigned int type)
*/ */
SetPageDirty(page); SetPageDirty(page);
UnlockPage(page); UnlockPage(page);
free_lru_page(page); page_cache_release(page);
/* /*
* Make sure that we aren't completely killing * 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