[lc-checkins] CVS: linux/mm/comp_cache main.c,1.41,1.42 swapin.c,1.36,1.37 swapout.c,1.46,1.47
Status: Beta
Brought to you by:
nitin_sf
|
From: Rodrigo S. de C. <rc...@us...> - 2002-05-31 16:48:58
|
Update of /cvsroot/linuxcompressed/linux/mm/comp_cache
In directory usw-pr-cvs1:/tmp/cvs-serv26610/mm/comp_cache
Modified Files:
main.c swapin.c swapout.c
Log Message:
- Back out fixes for FS corruption under UML
- Swap buffer management was partially rewritten to fix another potential
bug which could hang the machine. Besides, get_comp_cache_page() now first
tries to free pages that have already been written by the swap buffers. Only
if it really can't make it, it writes out more fragments.
Index: main.c
===================================================================
RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/main.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -C2 -r1.41 -r1.42
*** main.c 28 May 2002 19:16:15 -0000 1.41
--- main.c 31 May 2002 16:48:53 -0000 1.42
***************
*** 2,6 ****
* linux/mm/comp_cache/main.c
*
! * Time-stamp: <2002-05-28 14:42:21 rcastro>
*
* Linux Virtual Memory Compressed Cache
--- 2,6 ----
* linux/mm/comp_cache/main.c
*
! * Time-stamp: <2002-05-31 13:12:36 rcastro>
*
* Linux Virtual Memory Compressed Cache
***************
*** 15,21 ****
#include <linux/init.h>
#include <linux/pagemap.h>
#include <asm/page.h>
- #include <net/checksum.h>
/* compressed cache control variables */
--- 15,21 ----
#include <linux/init.h>
#include <linux/pagemap.h>
+ #include <linux/slab.h>
#include <asm/page.h>
/* compressed cache control variables */
***************
*** 131,135 ****
} else
memcpy(page_address(comp_page->page), page_address(page), PAGE_SIZE);
-
if (PageTestandSetCompCache(page))
--- 131,134 ----
Index: swapin.c
===================================================================
RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/swapin.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -C2 -r1.36 -r1.37
*** swapin.c 28 May 2002 19:16:15 -0000 1.36
--- swapin.c 31 May 2002 16:48:53 -0000 1.37
***************
*** 2,6 ****
* linux/mm/comp_cache/swapin.c
*
! * Time-stamp: <2002-05-28 14:27:51 rcastro>
*
* Linux Virtual Memory Compressed Cache
--- 2,6 ----
* linux/mm/comp_cache/swapin.c
*
! * Time-stamp: <2002-05-31 13:04:02 rcastro>
*
* Linux Virtual Memory Compressed Cache
***************
*** 17,21 ****
#include <asm/uaccess.h>
- #include <net/checksum.h>
int
--- 17,20 ----
***************
*** 84,88 ****
memcpy(page_address(page), page_address(comp_page->page), PAGE_SIZE);
! PageSetCompCache(page);
}
--- 83,88 ----
memcpy(page_address(page), page_address(comp_page->page), PAGE_SIZE);
! PageSetCompCache(page);
! SetPageUptodate(page);
}
***************
*** 114,118 ****
decompress_fragment(fragment, page);
!
/* update fault in stats */
comp_cache_update_faultin_stats(fragment);
--- 114,118 ----
decompress_fragment(fragment, page);
!
/* update fault in stats */
comp_cache_update_faultin_stats(fragment);
Index: swapout.c
===================================================================
RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/swapout.c,v
retrieving revision 1.46
retrieving revision 1.47
diff -C2 -r1.46 -r1.47
*** swapout.c 28 May 2002 19:16:15 -0000 1.46
--- swapout.c 31 May 2002 16:48:53 -0000 1.47
***************
*** 2,6 ****
* /mm/comp_cache/swapout.c
*
! * Time-stamp: <2002-05-28 14:51:56 rcastro>
*
* Linux Virtual Memory Compressed Cache
--- 2,6 ----
* /mm/comp_cache/swapout.c
*
! * Time-stamp: <2002-05-31 13:32:50 rcastro>
*
* Linux Virtual Memory Compressed Cache
***************
*** 23,61 ****
struct list_head swp_free_buffer_head, swp_used_buffer_head;
! /**
! * find_free_swp_buffer - gets a swap buffer page
! * @fragment: the fragment which will be decompressed to this buffer
! * page.
! *
! * If there's a free buffer page, it will lock the page and
! * return. Otherwise we may sleep to get the lock.
! *
! */
! static struct swp_buffer *
! find_free_swp_buffer(comp_cache_fragment_t * fragment, unsigned int gfp_mask)
{
struct page * buffer_page;
- struct list_head * swp_buffer_lh, * tmp_lh;
struct swp_buffer * swp_buffer;
! comp_cache_fragment_t * old_fragment;
! int wait, maxscan = NUM_SWP_BUFFERS >> 2;
!
! if (!fragment)
! BUG();
!
! CompFragmentSetIO(fragment);
! if (!list_empty(&swp_free_buffer_head))
! goto get_a_page;
- wait = 0;
try_again:
! list_for_each_safe(swp_buffer_lh, tmp_lh, &swp_used_buffer_head) {
swp_buffer = list_entry(swp_buffer_lh, struct swp_buffer, list);
buffer_page = swp_buffer->page;
! old_fragment = swp_buffer->fragment;
! if (!maxscan--)
! break;
if (TryLockPage(buffer_page)) {
--- 23,48 ----
struct list_head swp_free_buffer_head, swp_used_buffer_head;
! static int
! refill_swp_buffer(unsigned int gfp_mask, int num_pages)
{
+ struct list_head * swp_buffer_lh;
struct page * buffer_page;
struct swp_buffer * swp_buffer;
! comp_cache_fragment_t * fragment;
! unsigned int gfp_mask_buffer;
! int wait, maxscan;
! gfp_mask_buffer = gfp_mask & ~__GFP_IO;
! maxscan = max(NUM_SWP_BUFFERS >> 2, (int) (num_pages * 1.5));
! wait = 0;
try_again:
! while(--maxscan >= 0 && (swp_buffer_lh = swp_used_buffer_head.prev) != &swp_used_buffer_head) {
swp_buffer = list_entry(swp_buffer_lh, struct swp_buffer, list);
buffer_page = swp_buffer->page;
! fragment = swp_buffer->fragment;
! list_del(swp_buffer_lh);
! list_add(swp_buffer_lh, &swp_used_buffer_head);
if (TryLockPage(buffer_page)) {
***************
*** 65,89 ****
lock_page(buffer_page);
}
!
/* its fragment was added to locked_pages list below,
* right before being returned to the caller, so let's
* remove it now from any mapping->*_pages list */
list_del(&buffer_page->list);
!
if (buffer_page->buffers) {
- unsigned int gfp_mask_buffer = gfp_mask;
-
- /***
- * we would like to try freeing the buffers
- * without syncing them to disk at this first
- * try, so let's get rid of __GFP_IO flag
- */
- if (!wait)
- gfp_mask_buffer &= ~__GFP_IO;
list_del_init(swp_buffer_lh);
if (!try_to_free_buffers(buffer_page, gfp_mask_buffer)) {
! list_add_tail(swp_buffer_lh, &swp_used_buffer_head);
! list_add(&buffer_page->list, &old_fragment->mapping->locked_comp_pages);
UnlockPage(buffer_page);
continue;
--- 52,67 ----
lock_page(buffer_page);
}
!
/* its fragment was added to locked_pages list below,
* right before being returned to the caller, so let's
* remove it now from any mapping->*_pages list */
list_del(&buffer_page->list);
!
if (buffer_page->buffers) {
list_del_init(swp_buffer_lh);
if (!try_to_free_buffers(buffer_page, gfp_mask_buffer)) {
! list_add(swp_buffer_lh, &swp_used_buffer_head);
! list_add(&buffer_page->list, &fragment->mapping->locked_comp_pages);
UnlockPage(buffer_page);
continue;
***************
*** 91,98 ****
}
! /* has the fragment we are swapping out been swapped
! * in? so let's free only the fragment struct */
! if (!CompFragmentIO(old_fragment)) {
! kmem_cache_free(fragment_cachep, (old_fragment));
goto out;
}
--- 69,78 ----
}
! /* has the fragment we are swapping out been already
! * freed? Given that we were on IO process,
! * comp_cache_free() didn't free the fragment struct,
! * so let's do it now */
! if (!CompFragmentIO(fragment)) {
! kmem_cache_free(fragment_cachep, (fragment));
goto out;
}
***************
*** 100,111 ****
/* in the case it is waiting for merge in
* comp_cache_free(), we can't free it */
! if (!old_fragment->mapping) {
! CompFragmentClearIO(old_fragment);
goto out;
}
/* it's not swapped out, so let' free it */
! CompFragmentClearIO(old_fragment);
! comp_cache_free(old_fragment);
out:
--- 80,91 ----
/* in the case it is waiting for merge in
* comp_cache_free(), we can't free it */
! if (!fragment->mapping) {
! CompFragmentClearIO(fragment);
goto out;
}
/* it's not swapped out, so let' free it */
! CompFragmentClearIO(fragment);
! comp_cache_free(fragment);
out:
***************
*** 115,144 ****
list_add_tail(swp_buffer_lh, &swp_free_buffer_head);
- /* has the fragment been totally (!IO) or partially
- * freed (Freed)? no need to swap it out any longer */
- if (!CompFragmentIO(fragment) || CompFragmentFreed(fragment)) {
- CompFragmentClearIO(fragment);
- UnlockPage(buffer_page);
- return NULL;
- }
-
UnlockPage(buffer_page);
!
! if (wait)
! goto get_a_page;
}
! /* couldn't free any swap buffer? so let's IO to finish */
! if (list_empty(&swp_free_buffer_head)) {
! maxscan = wait = 1;
! if (unlikely(current->need_resched)) {
! __set_current_state(TASK_RUNNING);
! schedule();
! }
goto try_again;
}
get_a_page:
! swp_buffer = list_entry(swp_buffer_lh = swp_free_buffer_head.next, struct swp_buffer, list);
buffer_page = swp_buffer->page;
--- 95,152 ----
list_add_tail(swp_buffer_lh, &swp_free_buffer_head);
UnlockPage(buffer_page);
! --num_pages;
}
! /* couldn't free any swap buffer? so let's perform IO, if
! * gfp_mask allows, to free the page buffers */
! if (!wait && num_pages > 0) {
! wait = 1;
! maxscan = max(NUM_SWP_BUFFERS >> 4, (int) (num_pages * 1.5));
! gfp_mask_buffer = gfp_mask;
! run_task_queue(&tq_disk);
goto try_again;
}
+
+ return (num_pages > 0?0:1);
+ }
+
+
+ /**
+ * find_free_swp_buffer - gets a swap buffer page
+ * @fragment: the fragment which will be decompressed to this buffer
+ * page.
+ *
+ * If there's a free buffer page, it will lock the page and
+ * return. Otherwise we may sleep to get the lock.
+ *
+ */
+ static struct swp_buffer *
+ find_free_swp_buffer(comp_cache_fragment_t * fragment, unsigned int gfp_mask)
+ {
+ struct page * buffer_page;
+ struct list_head * swp_buffer_lh;
+ struct swp_buffer * swp_buffer;
+
+ if (!fragment)
+ BUG();
+
+ CompFragmentSetIO(fragment);
+
+ if (!list_empty(&swp_free_buffer_head))
+ goto get_a_page;
+
+ if (!refill_swp_buffer(gfp_mask, 1))
+ panic("couldn't free a swap buffer\n");
+
+ /* has the fragment been totally (!IO) or partially
+ * freed (Freed)? no need to swap it out any longer */
+ if (!CompFragmentIO(fragment) || CompFragmentFreed(fragment)) {
+ CompFragmentClearIO(fragment);
+ return NULL;
+ }
get_a_page:
! swp_buffer = list_entry(swp_buffer_lh = swp_free_buffer_head.prev, struct swp_buffer, list);
buffer_page = swp_buffer->page;
***************
*** 148,152 ****
list_del(swp_buffer_lh);
! list_add_tail(swp_buffer_lh, &swp_used_buffer_head);
swp_buffer->fragment = fragment;
--- 156,160 ----
list_del(swp_buffer_lh);
! list_add(swp_buffer_lh, &swp_used_buffer_head);
swp_buffer->fragment = fragment;
***************
*** 365,370 ****
UnlockPage(page);
!
! writeout_fragments(gfp_mask);
if (TryLockPage(page)) {
--- 373,379 ----
UnlockPage(page);
!
! if (!refill_swp_buffer(gfp_mask, SWAP_CLUSTER_MAX >> 2))
! writeout_fragments(gfp_mask);
if (TryLockPage(page)) {
|