[lc-checkins] CVS: linux/mm/comp_cache free.c,1.37,1.38 swapout.c,1.61,1.62 vswap.c,1.40,1.41
Status: Beta
Brought to you by:
nitin_sf
|
From: Rodrigo S. de C. <rc...@us...> - 2002-07-17 13:01:02
|
Update of /cvsroot/linuxcompressed/linux/mm/comp_cache
In directory usw-pr-cvs1:/tmp/cvs-serv577/mm/comp_cache
Modified Files:
free.c swapout.c vswap.c
Log Message:
Bug fixes
o Fixed bug in find_free_swp_buffer() that would leak fragment structs
if the fragment got completely freed while refilling swap buffers.
o Fixed bug in find_free_swp_buffer() that would panic in the case it
couldn't free any swap buffers because of gfp_mask. In this case,
simply return neither decompressing nor writing the dirty fragment.
o Fixed bug in comp_cache_swp_duplicate() (now known as
virtual_swap_duplicate()) that would cause a kernel BUG if duplicating
a freed entry. This scenario may happen in the swapin path code.
Cleanups
o Renamed comp_cache_swp_{duplicate,free,count} -> virtual_swap_*
o Removed useless "nrpages" parameter
Index: free.c
===================================================================
RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/free.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -C2 -r1.37 -r1.38
*** free.c 16 Jul 2002 21:58:08 -0000 1.37
--- free.c 17 Jul 2002 13:00:58 -0000 1.38
***************
*** 2,6 ****
* linux/mm/comp_cache/free.c
*
! * Time-stamp: <2002-07-16 18:35:21 rcastro>
*
* Linux Virtual Memory Compressed Cache
--- 2,6 ----
* linux/mm/comp_cache/free.c
*
! * Time-stamp: <2002-07-17 08:49:59 rcastro>
*
* Linux Virtual Memory Compressed Cache
***************
*** 310,314 ****
/* let's proceed to fix swap counter for either entries */
for(; num_freed_ptes > 0; --num_freed_ptes) {
! comp_cache_swp_free(old_entry);
swap_duplicate(entry);
}
--- 310,314 ----
/* let's proceed to fix swap counter for either entries */
for(; num_freed_ptes > 0; --num_freed_ptes) {
! virtual_swap_free(vswap->offset);
swap_duplicate(entry);
}
Index: swapout.c
===================================================================
RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/swapout.c,v
retrieving revision 1.61
retrieving revision 1.62
diff -C2 -r1.61 -r1.62
*** swapout.c 16 Jul 2002 21:58:08 -0000 1.61
--- swapout.c 17 Jul 2002 13:00:58 -0000 1.62
***************
*** 2,6 ****
* /mm/comp_cache/swapout.c
*
! * Time-stamp: <2002-07-16 16:35:08 rcastro>
*
* Linux Virtual Memory Compressed Cache
--- 2,6 ----
* /mm/comp_cache/swapout.c
*
! * Time-stamp: <2002-07-17 09:42:34 rcastro>
*
* Linux Virtual Memory Compressed Cache
***************
*** 24,28 ****
static int
! refill_swp_buffer(unsigned int gfp_mask, int nrpages, int priority)
{
struct list_head * swp_buffer_lh;
--- 24,28 ----
static int
! refill_swp_buffer(unsigned int gfp_mask, int priority)
{
struct list_head * swp_buffer_lh;
***************
*** 32,40 ****
int wait, maxscan;
! maxscan = max(NUM_SWP_BUFFERS/priority, (int) (nrpages * 1.5));
wait = 0;
try_again:
! while(--maxscan >= 0 && nrpages && (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;
--- 32,40 ----
int wait, maxscan;
! maxscan = NUM_SWP_BUFFERS/priority;
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;
***************
*** 98,109 ****
UnlockPage(buffer_page);
! --nrpages;
}
/* couldn't free any swap buffer? so let's start waiting for
* the lock from the locked pages */
! if (!wait && nrpages > 0) {
wait = 1;
! maxscan = max(NUM_SWP_BUFFERS >> 4, (int) (nrpages * 4));
if (unlikely(current->need_resched)) {
__set_current_state(TASK_RUNNING);
--- 98,109 ----
UnlockPage(buffer_page);
! return 1;
}
/* couldn't free any swap buffer? so let's start waiting for
* the lock from the locked pages */
! if (!wait) {
wait = 1;
! maxscan = NUM_SWP_BUFFERS >> 3;
if (unlikely(current->need_resched)) {
__set_current_state(TASK_RUNNING);
***************
*** 112,117 ****
goto try_again;
}
!
! return (nrpages > 0?0:1);
}
--- 112,116 ----
goto try_again;
}
! return 0;
}
***************
*** 140,159 ****
if (!list_empty(&swp_free_buffer_head))
! goto get_a_page;
while (list_empty(&swp_free_buffer_head) && priority)
! refill_swp_buffer(gfp_mask, 1, priority--);
if (list_empty(&swp_free_buffer_head))
! 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);
--- 139,163 ----
if (!list_empty(&swp_free_buffer_head))
! goto get_free_buffer;
while (list_empty(&swp_free_buffer_head) && priority)
! refill_swp_buffer(gfp_mask, priority--);
+ /* Failed to get a free swap buffer. Probably gfp_mask does
+ * not allow buffer sync in refill_swp_buffer() function. */
if (list_empty(&swp_free_buffer_head))
! goto failed;
! /* Fragment totally freed. Free its struct to avoid leakage. */
! if (!CompFragmentIO(fragment)) {
! kmem_cache_free(fragment_cachep, (fragment));
! goto failed;
}
! /* Fragment partially freed (to be merged). Nothing to do. */
! if (CompFragmentFreed(fragment))
! goto failed;
!
! get_free_buffer:
swp_buffer = list_entry(swp_buffer_lh = swp_free_buffer_head.prev, struct swp_buffer, list);
***************
*** 174,177 ****
--- 178,185 ----
return (swp_buffer);
+
+ failed:
+ CompFragmentClearIO(fragment);
+ return NULL;
}
Index: vswap.c
===================================================================
RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/vswap.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -C2 -r1.40 -r1.41
*** vswap.c 16 Jul 2002 18:41:55 -0000 1.40
--- vswap.c 17 Jul 2002 13:00:58 -0000 1.41
***************
*** 2,6 ****
* linux/mm/comp_cache/vswap.c
*
! * Time-stamp: <2002-07-16 14:57:52 rcastro>
*
* Linux Virtual Memory Compressed Cache
--- 2,6 ----
* linux/mm/comp_cache/vswap.c
*
! * Time-stamp: <2002-07-17 08:52:56 rcastro>
*
* Linux Virtual Memory Compressed Cache
***************
*** 238,245 ****
*/
int
! comp_cache_swp_duplicate(swp_entry_t entry)
{
unsigned long offset = SWP_OFFSET(entry);
- int ret = 0;
if (!vswap_address(entry))
--- 238,244 ----
*/
int
! virtual_swap_duplicate(swp_entry_t entry)
{
unsigned long offset = SWP_OFFSET(entry);
if (!vswap_address(entry))
***************
*** 248,265 ****
BUG();
if (!vswap_address[offset]->swap_count)
! BUG();
if (offset >= vswap_current_num_entries)
! goto out;
!
vswap_address[offset]->swap_count++;
! ret = 1;
! out:
! return ret;
}
/**
! * comp_cache_swp_free - swap_free for virtual swap addresses.
! * @entry: the virtual swap entry which will have its count
! * decremented and possibly the vswap entry freed.
*
* This function will decrement the vswap entry counter. If we have
--- 247,261 ----
BUG();
if (!vswap_address[offset]->swap_count)
! return 0;
if (offset >= vswap_current_num_entries)
! return 0;
vswap_address[offset]->swap_count++;
! return 1;
}
/**
! * virtual_swap_free - swap_free for virtual swap addresses. @entry:
! * the virtual swap entry which will have its count decremented and
! * possibly the vswap entry freed.
*
* This function will decrement the vswap entry counter. If we have
***************
*** 272,285 ****
*/
int
! comp_cache_swp_free(swp_entry_t entry)
{
- unsigned long offset = SWP_OFFSET(entry);
unsigned int swap_count;
struct comp_cache_fragment * fragment;
struct vswap_address * vswap;
- if (!vswap_address(entry))
- BUG();
-
if (offset >= vswap_current_num_entries)
BUG();
--- 268,277 ----
*/
int
! virtual_swap_free(unsigned long offset)
{
unsigned int swap_count;
struct comp_cache_fragment * fragment;
struct vswap_address * vswap;
if (offset >= vswap_current_num_entries)
BUG();
***************
*** 345,349 ****
/**
! * comp_cache_swp_count - swap_count for virtual swap addresses.
* @entry: virtual swap entry that will be returned its counter.
*
--- 337,341 ----
/**
! * virtual_swap_count - swap_count for virtual swap addresses.
* @entry: virtual swap entry that will be returned its counter.
*
***************
*** 351,364 ****
*/
int
! comp_cache_swp_count(swp_entry_t entry)
{
unsigned long offset = SWP_OFFSET(entry);
-
- if (!vswap_address(entry))
- BUG();
-
if (!vswap_address[offset]->swap_count)
BUG();
-
return (vswap_address[offset]->swap_count);
}
--- 343,351 ----
*/
int
! virtual_swap_count(swp_entry_t entry)
{
unsigned long offset = SWP_OFFSET(entry);
if (!vswap_address[offset]->swap_count)
BUG();
return (vswap_address[offset]->swap_count);
}
|