[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); } |