[lc-checkins] CVS: linux/mm memory.c,1.17,1.18 swapfile.c,1.22,1.23
Status: Beta
Brought to you by:
nitin_sf
From: Rodrigo S. de C. <rc...@us...> - 2002-01-24 22:05:07
|
Update of /cvsroot/linuxcompressed/linux/mm In directory usw-pr-cvs1:/tmp/cvs-serv7824/mm Modified Files: memory.c swapfile.c Log Message: This patch include changes regarding the tlb and cache flushing when setting pte. It also fixes a stupid bug in vswap. - comp_cache_release() split into comp_cache_release() and comp_cache_use_address(). - comp_cache_use_address() now searches for the vma for the pte we are going to change. If found, we flush the cache and tlb for this pte before setting it. If not found, we count this reference for the swap count and when this pte faults in or gets freed, we fix the counters. - so we have to handle the cases in lookup_comp_cache() in which the pte gets changed when we sleep to get a new page. In this case, we check to see if the pte has changed. If it has, wow, it's time to return and waits it to fault in again, now with the real address. - to flush, some code was copied from rmap patch by Rik van Riel. He has the same problem and devised a nice way to decrease complexity when looking for the mm struct. - real_entry field was added back to vswap_address struct - fix a _stupid_ bug in vswap. The estimated_pages is a variable that avoids that we assign a huge number of vswaps which are reserved (vswap which is used but does not have a fragment, so we don't know how bit the fragment will be). This variable was supposed to have negative values, _but_ it was declared as unsigned long. :-( - (in this meanwhile I tried to add a referente to the swap count for our compressed fragment, but it turned out to perform not as well as the old code. I intended to remove that find_comp_page() and comp_cache_free() from comp_cache_release(), but that take less time to execute than some general idea, so I reverted the changes). Index: memory.c =================================================================== RCS file: /cvsroot/linuxcompressed/linux/mm/memory.c,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -r1.17 -r1.18 *** memory.c 2002/01/14 12:05:08 1.17 --- memory.c 2002/01/24 22:05:03 1.18 *************** *** 103,106 **** --- 103,107 ---- pte = pte_offset(dir, 0); pmd_clear(dir); + pgtable_remove_rmap(pte); pte_free(pte); } *************** *** 1103,1109 **** --- 1104,1138 ---- int ret = 1; + if (vswap_address(entry)) { + unsigned long offset = SWP_OFFSET(entry); + + if (vswap_address[offset]->real_entry.val) { + swp_entry_t old_entry; + + remove_pte_vswap(page_table); + + pte = ptep_get_and_clear(page_table); + flush_tlb_page(vma, address); + flush_cache_page(vma, address); + + swap_duplicate(vswap_address[offset]->real_entry); + set_pte(page_table, swp_entry_to_pte(vswap_address[offset]->real_entry)); + + old_entry.val = entry.val; + entry.val = vswap_address[offset]->real_entry.val; + + comp_cache_swp_free_generic(old_entry, 0); + } + } + + spin_unlock(&mm->page_table_lock); page = lookup_comp_cache(entry); + /* we may sleep in the above function and a vswap addressed + * pte can have a real address assigned in the meanwhile */ + if (!page && !pte_same(*page_table, orig_pte)) + return 1; + if (!page) { swapin_readahead(entry); *************** *** 1436,1439 **** --- 1465,1469 ---- } } + pgtable_add_rmap(new, mm, address); pmd_populate(mm, pmd, new); } Index: swapfile.c =================================================================== RCS file: /cvsroot/linuxcompressed/linux/mm/swapfile.c,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -r1.22 -r1.23 *** swapfile.c 2001/12/21 18:33:11 1.22 --- swapfile.c 2002/01/24 22:05:03 1.23 *************** *** 199,202 **** --- 199,203 ---- { int count; + swp_entry_t entry; if (vswap_info_struct(p)) *************** *** 206,219 **** if (count < SWAP_MAP_MAX) { count--; - p->swap_map[offset] = count; if (!count) { #ifdef CONFIG_COMP_SWAP p->swap_comp[offset] = 0; #endif ! /* let's keep the swap_map[offset] used for ! * the case the comp_cache_release() calls ! * swap_dup() */ ! p->swap_map[offset]++; ! if (!comp_cache_release(SWP_ENTRY(p - swap_info, offset))) { if (offset < p->lowest_bit) p->lowest_bit = offset; --- 207,217 ---- if (count < SWAP_MAP_MAX) { count--; if (!count) { #ifdef CONFIG_COMP_SWAP p->swap_comp[offset] = 0; #endif ! entry = SWP_ENTRY(p - swap_info, offset); ! comp_cache_release(entry); ! if (!comp_cache_use_address(entry)) { if (offset < p->lowest_bit) p->lowest_bit = offset; *************** *** 222,227 **** nr_swap_pages++; } ! p->swap_map[offset]--; } } return count; --- 220,227 ---- nr_swap_pages++; } ! count = p->swap_map[offset]; ! count--; } + p->swap_map[offset] = count; } return count; |