Update of /cvsroot/linuxcompressed/linux/mm/comp_cache
In directory usw-pr-cvs1:/tmp/cvs-serv19795/mm/comp_cache
Modified Files:
free.c vswap.c
Log Message:
Bug fixes
o Fixed race between comp_cache_use_address() and do_swap_page(). A pte
could be unsafely changed during a page fault service.
Index: free.c
===================================================================
RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/free.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -C2 -r1.41 -r1.42
*** free.c 18 Jul 2002 11:54:48 -0000 1.41
--- free.c 18 Jul 2002 13:32:50 -0000 1.42
***************
*** 2,6 ****
* linux/mm/comp_cache/free.c
*
! * Time-stamp: <2002-07-18 08:40:22 rcastro>
*
* Linux Virtual Memory Compressed Cache
--- 2,6 ----
* linux/mm/comp_cache/free.c
*
! * Time-stamp: <2002-07-18 10:04:09 rcastro>
*
* Linux Virtual Memory Compressed Cache
***************
*** 279,282 ****
--- 279,285 ----
old_entry = SWP_ENTRY(COMP_CACHE_SWP_TYPE, vswap->offset);
+ if (vswap->fault_count)
+ continue;
+
if (TryLockPage(vswap->fragment->comp_page->page))
continue;
***************
*** 301,307 ****
/* set old virtual addressed ptes to the real swap entry */
ret = set_pte_list_to_entry(vswap->pte_list, old_entry, entry);
! if (!ret)
goto backout;
--- 304,315 ----
/* set old virtual addressed ptes to the real swap entry */
+ spin_unlock(&virtual_swap_list);
ret = set_pte_list_to_entry(vswap->pte_list, old_entry, entry);
+ spin_lock(&virtual_swap_list);
! /* if we set all the pte list, but while setting to the new
! * entry, a pte has faulted in, back out the changes so
! * hopefully the page fault can be serviced */
! if (!ret || vswap->fault_count)
goto backout;
***************
*** 318,330 ****
}
- if (vswap->swap_cache_page) {
- if (vswap->swap_count != 1)
- BUG();
- }
- else {
- if (vswap->swap_count)
- BUG();
- }
-
/* let's fix swap cache page address (if any) */
if (vswap->swap_cache_page) {
--- 326,329 ----
***************
*** 347,351 ****
}
! if (vswap->swap_count)
BUG();
--- 346,354 ----
}
! /* Even if the swap cache page has been removed but the
! * swap_count not yet decremented, the maximum value of
! * swap_count is 1. This vswap entry will be added to free
! * list as soon as swap_count gets to zero. */
! if (vswap->swap_count > 1)
BUG();
Index: vswap.c
===================================================================
RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/vswap.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -C2 -r1.42 -r1.43
*** vswap.c 17 Jul 2002 20:44:36 -0000 1.42
--- vswap.c 18 Jul 2002 13:32:51 -0000 1.43
***************
*** 2,6 ****
* linux/mm/comp_cache/vswap.c
*
! * Time-stamp: <2002-07-17 16:48:47 rcastro>
*
* Linux Virtual Memory Compressed Cache
--- 2,6 ----
* linux/mm/comp_cache/vswap.c
*
! * Time-stamp: <2002-07-18 10:01:50 rcastro>
*
* Linux Virtual Memory Compressed Cache
***************
*** 708,711 ****
--- 708,730 ----
spin_unlock(&virtual_swap_list);
}
+
+ void FASTCALL(get_vswap(swp_entry_t));
+ void get_vswap(swp_entry_t entry) {
+ if (!vswap_address(entry))
+ return;
+ spin_lock(&virtual_swap_list);
+ vswap_address[SWP_OFFSET(entry)]->fault_count++;
+ spin_unlock(&virtual_swap_list);
+ }
+
+ void FASTCALL(put_vswap(swp_entry_t));
+ void put_vswap(swp_entry_t entry) {
+ if (!vswap_address(entry))
+ return;
+ spin_lock(&virtual_swap_list);
+ vswap_address[SWP_OFFSET(entry)]->fault_count--;
+ spin_unlock(&virtual_swap_list);
+ }
+
/**
|