[lc-checkins] CVS: linux/mm/comp_cache aux.c,1.32,1.33 main.c,1.49,1.50 swapin.c,1.42,1.43 swapout.c
Status: Beta
Brought to you by:
nitin_sf
From: Rodrigo S. de C. <rc...@us...> - 2002-07-01 17:37:33
|
Update of /cvsroot/linuxcompressed/linux/mm/comp_cache In directory usw-pr-cvs1:/tmp/cvs-serv26297/mm/comp_cache Modified Files: aux.c main.c swapin.c swapout.c Log Message: Features o Some compressed cache functions (in particular the swap out ones) have priority parameter now, which will passed from VM main functions. The priority will show how far we should go on scanning lists to free spaces in compressed cache. o Fragments will not be decompressed when they are read from a read ahead (for swap and page cache). In this case, we only check if the fragment is in compressed cache. This police avoids LRU order to be changed. o Fragments will be removed from compressed cache if resize on demand is enabled. o Support for pages with buffers will only happen if resize on demand is disabled. Bug fixes o Fixed potential bug in __find_lock_page() where we would decompress a fragment and add a new page to page cache even if it had been just swapped in. Cleanups o Added #ifdefs in lru queues functions. o Several small cleanups Other o compress_page() only returns the page in locked state if it has been compressed. Otherwise, it will returned always unlocked. o now get_comp_cache_page() doesn't try so hard to get an entry. The maximum number of tries (which includes calls to writeout_fragments()) is 3. Index: aux.c =================================================================== RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/aux.c,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -r1.32 -r1.33 *** aux.c 19 Jun 2002 12:18:44 -0000 1.32 --- aux.c 1 Jul 2002 17:37:29 -0000 1.33 *************** *** 2,6 **** * linux/mm/comp_cache/aux.c * ! * Time-stamp: <2002-06-19 08:45:54 rcastro> * * Linux Virtual Memory Compressed Cache --- 2,6 ---- * linux/mm/comp_cache/aux.c * ! * Time-stamp: <2002-07-01 13:09:27 rcastro> * * Linux Virtual Memory Compressed Cache *************** *** 334,339 **** --- 334,341 ---- BUG(); + #ifdef CONFIG_COMP_PAGE_CACHE if (!PageSwapCache(fragment)) goto add; + #endif entry.val = fragment->index; *************** *** 353,358 **** --- 355,362 ---- BUG(); + #ifdef CONFIG_COMP_PAGE_CACHE if (!PageSwapCache(fragment)) goto remove; + #endif entry.val = fragment->index; *************** *** 367,371 **** /* adapted version of __find_page_nolock:filemap.c */ int FASTCALL(find_comp_page(struct address_space *, unsigned long, struct comp_cache_fragment **)); ! int find_comp_page(struct address_space *mapping, unsigned long offset, struct comp_cache_fragment ** fragment) { struct comp_cache_fragment * fhash; --- 371,375 ---- /* adapted version of __find_page_nolock:filemap.c */ int FASTCALL(find_comp_page(struct address_space *, unsigned long, struct comp_cache_fragment **)); ! int find_comp_page(struct address_space * mapping, unsigned long offset, struct comp_cache_fragment ** fragment) { struct comp_cache_fragment * fhash; *************** *** 398,401 **** --- 402,413 ---- return err; } + + inline int + in_comp_cache(struct address_space * mapping, unsigned long offset) + { + struct comp_cache_fragment * fragment; + return !find_comp_page(mapping, offset, &fragment); + } + inline void Index: main.c =================================================================== RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/main.c,v retrieving revision 1.49 retrieving revision 1.50 diff -C2 -r1.49 -r1.50 *** main.c 27 Jun 2002 13:17:37 -0000 1.49 --- main.c 1 Jul 2002 17:37:29 -0000 1.50 *************** *** 2,6 **** * linux/mm/comp_cache/main.c * ! * Time-stamp: <2002-06-27 09:31:15 rcastro> * * Linux Virtual Memory Compressed Cache --- 2,6 ---- * linux/mm/comp_cache/main.c * ! * Time-stamp: <2002-07-01 13:12:44 rcastro> * * Linux Virtual Memory Compressed Cache *************** *** 41,48 **** extern unsigned long num_physpages; ! extern struct comp_cache_page * get_comp_cache_page(struct page *, unsigned short, struct comp_cache_fragment **, int, int, unsigned int); inline void ! compress_dirty_page(struct page * page, int (*writepage)(struct page *), unsigned int gfp_mask) { int write; --- 41,48 ---- extern unsigned long num_physpages; ! extern struct comp_cache_page * get_comp_cache_page(struct page *, unsigned short, struct comp_cache_fragment **, int, int, unsigned int, int); inline void ! compress_dirty_page(struct page * page, int (*writepage)(struct page *), unsigned int gfp_mask, int priority) { int write; *************** *** 54,59 **** write |= !PageSwapCache(page); #endif ! if (write) ! goto writepage; if (PageMappedCompCache(page)) --- 54,61 ---- write |= !PageSwapCache(page); #endif ! if (write) { ! writepage(page); ! return; ! } if (PageMappedCompCache(page)) *************** *** 63,76 **** BUG(); ! if (!compress_page(page, 1, gfp_mask)) ! UnlockPage(page); ! return; ! ! writepage: ! writepage(page); } inline int ! compress_clean_page(struct page * page, unsigned int gfp_mask) { /* that should not happen */ --- 65,73 ---- BUG(); ! compress_page(page, 1, gfp_mask, priority); } inline int ! compress_clean_page(struct page * page, unsigned int gfp_mask, int priority) { /* that should not happen */ *************** *** 85,93 **** return 1; #endif ! return compress_page(page, 0, gfp_mask); } int ! compress_page(struct page * page, int dirty, unsigned int gfp_mask) { struct comp_cache_page * comp_page; --- 82,90 ---- return 1; #endif ! return compress_page(page, 0, gfp_mask, priority); } int ! compress_page(struct page * page, int dirty, unsigned int gfp_mask, int priority) { struct comp_cache_page * comp_page; *************** *** 112,116 **** comp_size = compress(current_compressed_page = page, buffer_compressed = (unsigned long *) &buffer_compressed1, &algorithm, dirty); ! comp_page = get_comp_cache_page(page, comp_size, &fragment, dirty, 1, gfp_mask); /* if comp_page == NULL, get_comp_cache_page() gave up --- 109,113 ---- comp_size = compress(current_compressed_page = page, buffer_compressed = (unsigned long *) &buffer_compressed1, &algorithm, dirty); ! comp_page = get_comp_cache_page(page, comp_size, &fragment, dirty, 1, gfp_mask, priority); /* if comp_page == NULL, get_comp_cache_page() gave up *************** *** 185,190 **** } int ! comp_cache_try_to_release_page(struct page ** page, int gfp_mask) { struct comp_cache_fragment * fragment; --- 182,188 ---- } + #ifndef CONFIG_COMP_DEMAND_RESIZE int ! comp_cache_try_to_release_page(struct page ** page, int gfp_mask, int priority) { struct comp_cache_fragment * fragment; *************** *** 223,227 **** dirty = 0; ! comp_page = get_comp_cache_page(*page, comp_size, &fragment, dirty, 0, gfp_mask); if (!comp_page) --- 221,225 ---- dirty = 0; ! comp_page = get_comp_cache_page(*page, comp_size, &fragment, dirty, 0, gfp_mask, priority); if (!comp_page) *************** *** 259,262 **** --- 257,261 ---- return ret; } + #endif #endif Index: swapin.c =================================================================== RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/swapin.c,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -r1.42 -r1.43 *** swapin.c 25 Jun 2002 14:34:08 -0000 1.42 --- swapin.c 1 Jul 2002 17:37:30 -0000 1.43 *************** *** 2,6 **** * linux/mm/comp_cache/swapin.c * ! * Time-stamp: <2002-06-22 15:19:52 rcastro> * * Linux Virtual Memory Compressed Cache --- 2,6 ---- * linux/mm/comp_cache/swapin.c * ! * Time-stamp: <2002-07-01 11:28:19 rcastro> * * Linux Virtual Memory Compressed Cache *************** *** 87,91 **** int ! read_comp_cache(struct address_space *mapping, unsigned long offset, struct page * page, int access) { struct comp_cache_fragment * fragment; --- 87,91 ---- int ! read_comp_cache(struct address_space *mapping, unsigned long offset, struct page * page) { struct comp_cache_fragment * fragment; *************** *** 107,118 **** /* move the fragment to the back of the lru list */ ! if (access) { ! remove_fragment_from_lru_queue(fragment); ! add_fragment_to_lru_queue(fragment); ! } decompress_fragment(fragment, page); ! #if 0 PageClearCompCache(page); --- 107,119 ---- /* move the fragment to the back of the lru list */ ! remove_fragment_from_lru_queue(fragment); ! add_fragment_to_lru_queue(fragment); decompress_fragment(fragment, page); ! /* update fault in stats */ ! comp_cache_update_faultin_stats(fragment); ! ! #ifdef CONFIG_COMP_DEMAND_RESIZE PageClearCompCache(page); *************** *** 120,131 **** __set_page_dirty(page); comp_cache_free(fragment); ! #endif ! ! /* update fault in stats */ ! comp_cache_update_faultin_stats(fragment); ! UnlockPage(fragment->comp_page->page); ! UnlockPage(page); out: return err; --- 121,131 ---- __set_page_dirty(page); + UnlockPage(fragment->comp_page->page); comp_cache_free(fragment); ! #else UnlockPage(fragment->comp_page->page); ! #endif ! ! UnlockPage(page); out: return err; Index: swapout.c =================================================================== RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/swapout.c,v retrieving revision 1.53 retrieving revision 1.54 diff -C2 -r1.53 -r1.54 *** swapout.c 25 Jun 2002 14:34:08 -0000 1.53 --- swapout.c 1 Jul 2002 17:37:30 -0000 1.54 *************** *** 2,6 **** * /mm/comp_cache/swapout.c * ! * Time-stamp: <2002-06-22 14:55:33 rcastro> * * Linux Virtual Memory Compressed Cache --- 2,6 ---- * /mm/comp_cache/swapout.c * ! * Time-stamp: <2002-07-01 14:22:54 rcastro> * * Linux Virtual Memory Compressed Cache *************** *** 24,28 **** static int ! refill_swp_buffer(unsigned int gfp_mask, int num_pages, int priority) { struct list_head * swp_buffer_lh; --- 24,28 ---- static int ! refill_swp_buffer(unsigned int gfp_mask, int nrpages, int priority) { struct list_head * swp_buffer_lh; *************** *** 34,42 **** gfp_mask_buffer = gfp_mask & ~__GFP_IO; ! maxscan = max(NUM_SWP_BUFFERS/priority, (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; --- 34,42 ---- gfp_mask_buffer = gfp_mask & ~__GFP_IO; ! 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; *************** *** 73,90 **** * 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; } ! /* 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); --- 73,92 ---- * comp_cache_free() didn't free the fragment struct, * so let's do it now */ ! if (!CompFragmentTestandClearIO(fragment)) { kmem_cache_free(fragment_cachep, (fragment)); goto out; } ! /*** ! * In the case it is waiting for merge in ! * comp_cache_free(), we don't have to free it. To be ! * clearer, it has been freed, except its data ! * structure, what will be freed when merged in ! * comp_cache_free() ! */ ! if (!fragment->mapping) //!CompFragmentFreed(fragment)) goto out; /* it's not swapped out, so let' free it */ comp_cache_free(fragment); *************** *** 95,113 **** 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 * 4)); gfp_mask_buffer = gfp_mask; ! run_task_queue(&tq_disk); goto try_again; } ! return (num_pages > 0?0:1); } --- 97,118 ---- list_add_tail(swp_buffer_lh, &swp_free_buffer_head); ! UnlockPage(buffer_page); ! --nrpages; } /* couldn't free any swap buffer? so let's perform IO, if * gfp_mask allows, to free the page buffers */ ! if (!wait && nrpages > 0) { wait = 1; ! maxscan = max(NUM_SWP_BUFFERS >> 4, (int) (nrpages * 4)); gfp_mask_buffer = gfp_mask; ! if (unlikely(current->need_resched)) { ! __set_current_state(TASK_RUNNING); ! schedule(); ! } goto try_again; } ! return (nrpages > 0?0:1); } *************** *** 205,209 **** /* writeout_fragments() - write out some pages in the lru order until * we have a comp_page where we can store the new page */ ! static void writeout_fragments(unsigned int gfp_mask, int priority) { int (*writepage)(struct page *); --- 210,214 ---- /* writeout_fragments() - write out some pages in the lru order until * we have a comp_page where we can store the new page */ ! static int writeout_fragments(unsigned int gfp_mask, int priority) { int (*writepage)(struct page *); *************** *** 215,220 **** swp_entry_t entry; - maxscan = num_fragments/priority; nrpages = SWAP_CLUSTER_MAX; while (!list_empty(&lru_queue) && maxscan--) { --- 220,225 ---- swp_entry_t entry; nrpages = SWAP_CLUSTER_MAX; + maxscan = max((int) (num_fragments/priority), (int) (nrpages * 1.5)); while (!list_empty(&lru_queue) && maxscan--) { *************** *** 233,239 **** /* page locked */ ! if (TryLockPage(page)) { continue; - } /* page which has/had buffer? */ --- 238,243 ---- /* page locked */ ! if (TryLockPage(page)) continue; /* page which has/had buffer? */ *************** *** 291,297 **** } ! swap_cache_page = 0; ! if (PageSwapCache(fragment)) { ! swap_cache_page = 1; entry.val = fragment->index; if (vswap_address(entry)) --- 295,299 ---- } ! if ((swap_cache_page = PageSwapCache(fragment))) { entry.val = fragment->index; if (vswap_address(entry)) *************** *** 354,357 **** --- 356,361 ---- break; } + + return (!nrpages); } *************** *** 382,386 **** * @gfp_mask: we need to know if we can perform IO */ struct comp_cache_page * ! get_comp_cache_page(struct page * page, unsigned short compressed_size, struct comp_cache_fragment ** fragment_out, int dirty, int alloc, unsigned int gfp_mask) { struct comp_cache_page * comp_page = NULL; --- 386,390 ---- * @gfp_mask: we need to know if we can perform IO */ struct comp_cache_page * ! get_comp_cache_page(struct page * page, unsigned short compressed_size, struct comp_cache_fragment ** fragment_out, int dirty, int alloc, unsigned int gfp_mask, int priority) { struct comp_cache_page * comp_page = NULL; *************** *** 389,393 **** struct page * new_page; unsigned short aux_comp_size; ! int maxscan, maxtry, priority = 6; if (!page) --- 393,397 ---- struct page * new_page; unsigned short aux_comp_size; ! int maxscan, maxtry; if (!page) *************** *** 398,408 **** BUG(); - maxtry = num_comp_pages >> 1; - page_cache_get(page); ! while (maxtry-- && priority) { aux_comp_size = compressed_size; ! maxscan = num_comp_pages >> 3; while (maxscan--) { --- 402,411 ---- BUG(); page_cache_get(page); + maxtry = 3; ! while (maxtry--) { aux_comp_size = compressed_size; ! maxscan = 3; while (maxscan--) { *************** *** 456,485 **** UnlockPage(page); ! /*** ! * We didn't grow the compressed cache, thus it's time ! * to check if we able to free any fragment which was ! * waiting for IO completion. If we can't free any ! * fragment, it's time to write out some fragments. ! */ ! if (!refill_swp_buffer(gfp_mask, 1, priority)) ! writeout_fragments(gfp_mask, priority--); ! if (TryLockPage(page)) { ! if (!dirty) ! goto out_release; ! lock_page(page); ! goto set_bits_back; } ! if (page_count(page) - !!page->buffers != 3) ! break; } if (!dirty) goto out_release; - - set_bits_back: __set_page_dirty(page); ! ClearPageLaunder(page); out_release: page_cache_release(page); --- 459,485 ---- UnlockPage(page); ! if (!writeout_fragments(gfp_mask, priority)) ! goto give_up; ! if (unlikely(current->need_resched)) { ! __set_current_state(TASK_RUNNING); ! schedule(); } ! if (TryLockPage(page)) ! goto give_up; ! ! if (page_count(page) - !!page->buffers == 3) ! continue; ! ! break; } + UnlockPage(page); + give_up: if (!dirty) goto out_release; __set_page_dirty(page); ! ClearPageLaunder(page); out_release: page_cache_release(page); *************** *** 493,496 **** --- 493,498 ---- BUG(); } + if (!comp_page && PageLocked(page)) + BUG(); return comp_page; *************** *** 532,546 **** fragment->flags = 0; fragment->comp_page = comp_page; - - #if 0 - { - struct comp_cache_fragment * fout; - - if (!find_comp_page(page->mapping, page->index, &fout)) { - printk("found %p (index %08lx dirty %d sc %d) new %p (index %08lx dirty %d sc %d)\n", fout, fout->index, CompFragmentDirty(fout)?1:0, PageSwapCache(fragment)?1:0, fragment, fragment->index, dirty?1:0, PageSwapCache(fragment)?1:0); - BUG(); - } - } - #endif /* let's update some important fields */ --- 534,537 ---- *************** *** 629,636 **** UnlockPage(comp_page->page); comp_page = NULL; ! ! if (!dirty) ! goto out_release; ! goto set_bits_back; } --- 620,625 ---- UnlockPage(comp_page->page); comp_page = NULL; ! UnlockPage(page); ! goto give_up; } |