[lc-checkins] CVS: linux/include/linux comp_cache.h,1.104,1.105
Status: Beta
Brought to you by:
nitin_sf
From: Rodrigo S. de C. <rc...@us...> - 2002-12-06 19:29:56
|
Update of /cvsroot/linuxcompressed/linux/include/linux In directory sc8-pr-cvs1:/tmp/cvs-serv8451/include/linux Modified Files: comp_cache.h Log Message: Some races still to be fixed, but we have fixed a bunch of them in this set of changes, including one that would corrupt FSs when used with preempt patch. Bug fixes o Fixed bug that might compress a page for the second time if it were swapped in while being written using swap buffers. In this case, a new swap cache page could be compressed and we are not sure the fragment being written out had actually been freed. The fix is to make the swap buffer get a reference on this swap cache page, releasing when the swap buffer is freed. o Fixed bug that could submit a read to the disk while the same block is being written by a swap buffer. When writing out the swap buffer, we get a reference on the fragment in order to avoid it to be released, even if swapped in in the meanwhile. o Removed extra spin_lock()/spin_unlock() on comp_cache_lock in grow_comp_cache() o Fixed race in compact_comp_cace() that we were triggering which would corrupt fs or return wrong process data, likely to segfault. It happened usually with preempt patch. When a fragment is relocated to another comp page, we could preempt the process after the fragment is removed from the previous comp page, but before being added to the next comp page. If this happens, a read operation is submitted to the disk, likely to read bogus data or, if vswap is used, to reach a kernel BUG. In order to solve, we add the new fragment to the hash table before the old one is removed. So, if the process is preempted before removing the old fragment, we have a fragment with its data. This fragment is locked until get to a sane state, but it surely avoids a read operation to be done. We think it's SMP-safe too, since if a reference to the old fragment is get after the new fragment is added to the hash table, the old fragment isn't freed and we remove the new fragment from the hash table. If the new fragment is referenced, it's the same behaviour that happens when the process is preempted. o Added spin_lock/spin_unlock to clean page adaptability to provide concurrency control. o Fixed bug that would allow to set more than 50% of the memory size as the maximum size of compressed cache. For example, booting with "mem=16M compsize=12M" would work. Simple fix. o Fixed bug that would duplicate a real swap entry (for compressed swap) even if the swap entry failed to duplicate. o Although unlikely, nothing prevents a swap entry to be freed while being written out by a swap buffer. Now we, besides the reference on the fragment, we hold a reference on the swap entry when writing out a page. Index: comp_cache.h =================================================================== RCS file: /cvsroot/linuxcompressed/linux/include/linux/comp_cache.h,v retrieving revision 1.104 retrieving revision 1.105 diff -C2 -r1.104 -r1.105 *** comp_cache.h 26 Nov 2002 21:42:32 -0000 1.104 --- comp_cache.h 6 Dec 2002 19:29:21 -0000 1.105 *************** *** 2,6 **** * linux/mm/comp_cache.h * ! * Time-stamp: <2002-11-26 19:35:01 rcastro> * * Linux Virtual Memory Compressed Cache --- 2,6 ---- * linux/mm/comp_cache.h * ! * Time-stamp: <2002-12-05 10:11:02 rcastro> * * Linux Virtual Memory Compressed Cache *************** *** 175,178 **** --- 175,185 ---- int writeout_fragments(unsigned int, int, int); + #ifdef CONFIG_COMP_CACHE + void sync_all_swp_buffers(void); + #else + static inline void sync_all_swp_buffers() { }; + #endif + + /* -- Fragment Flags */ *************** *** 232,235 **** --- 239,243 ---- struct page * page; /* page for IO */ struct comp_cache_fragment * fragment; /* pointer to the fragment we are doing IO */ + struct page * swap_cache_page; }; |