[lc-checkins] CVS: linux/mm/comp_cache aux.c,1.39,1.40 free.c,1.38,1.39 main.c,1.56,1.57 swapin.c,1.
Status: Beta
Brought to you by:
nitin_sf
From: Rodrigo S. de C. <rc...@us...> - 2002-07-17 20:44:40
|
Update of /cvsroot/linuxcompressed/linux/mm/comp_cache In directory usw-pr-cvs1:/tmp/cvs-serv16293/mm/comp_cache Modified Files: aux.c free.c main.c swapin.c swapout.c vswap.c Log Message: Features o First implementation of support for SMP systems. There are only two spinlocks used for that, but the goal at the moment is stability, not performance. With our first tests, it is working without corruption on a system with preempt patch, but only swap cache support (and without resizing compressed cache). Let the first races show up :-) As soon as the whole code is working somewhat well, those global locks will be divided into many other to improve concurrency. Bug fixes o fixed compilation error when compressed cache is disabled Cleanups o removed virtual_swap_count() since it wasn't used (swap_count() isn't used either). Index: aux.c =================================================================== RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/aux.c,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -r1.39 -r1.40 *** aux.c 16 Jul 2002 21:58:08 -0000 1.39 --- aux.c 17 Jul 2002 20:44:36 -0000 1.40 *************** *** 2,6 **** * linux/mm/comp_cache/aux.c * ! * Time-stamp: <2002-07-16 16:33:09 rcastro> * * Linux Virtual Memory Compressed Cache --- 2,6 ---- * linux/mm/comp_cache/aux.c * ! * Time-stamp: <2002-07-17 16:06:21 rcastro> * * Linux Virtual Memory Compressed Cache *************** *** 108,113 **** while (pte_list != failed_pte_list) { mm = ptep_to_mm(pte_list->ptep); ! address = ptep_to_address(pte_list->ptep); ! vma = find_vma(mm, address); --- 108,114 ---- while (pte_list != failed_pte_list) { mm = ptep_to_mm(pte_list->ptep); ! spin_lock(&mm->page_table_lock); ! ! address = ptep_to_address(pte_list->ptep); vma = find_vma(mm, address); *************** *** 121,124 **** --- 122,126 ---- set_pte(pte_list->ptep, swp_entry_to_pte(old_entry)); + spin_unlock(&mm->page_table_lock); pte_list = pte_list->next; } *************** *** 135,144 **** pte_list = start_pte_list; ! while (pte_list) { ptep = pte_list->ptep; mm = ptep_to_mm(ptep); address = ptep_to_address(ptep); - vma = find_vma(mm, address); --- 137,147 ---- pte_list = start_pte_list; ! while (pte_list) { ptep = pte_list->ptep; mm = ptep_to_mm(ptep); + spin_lock(&mm->page_table_lock); + address = ptep_to_address(ptep); vma = find_vma(mm, address); *************** *** 151,155 **** set_pte(ptep, swp_entry_to_pte(entry)); ! pte_list = pte_list->next; } --- 154,159 ---- set_pte(ptep, swp_entry_to_pte(entry)); ! ! spin_unlock(&mm->page_table_lock); pte_list = pte_list->next; } *************** *** 158,161 **** --- 162,166 ---- error: + spin_unlock(&mm->page_table_lock); backout_pte_changes(start_pte_list, pte_list, old_entry); return 0; Index: free.c =================================================================== RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/free.c,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -r1.38 -r1.39 *** free.c 17 Jul 2002 13:00:58 -0000 1.38 --- free.c 17 Jul 2002 20:44:36 -0000 1.39 *************** *** 2,6 **** * linux/mm/comp_cache/free.c * ! * Time-stamp: <2002-07-17 08:49:59 rcastro> * * Linux Virtual Memory Compressed Cache --- 2,6 ---- * linux/mm/comp_cache/free.c * ! * Time-stamp: <2002-07-17 16:06:56 rcastro> * * Linux Virtual Memory Compressed Cache *************** *** 256,264 **** struct list_head * vswap_lh; swp_entry_t old_entry; ! int num_freed_ptes; /* no virtual swap entry with a compressed page */ if (list_empty(&vswap_address_used_head)) ! return 0; vswap_lh = &vswap_address_used_head; --- 256,266 ---- struct list_head * vswap_lh; swp_entry_t old_entry; ! int num_freed_ptes, ret = 0; + spin_lock(&virtual_swap_list); + /* no virtual swap entry with a compressed page */ if (list_empty(&vswap_address_used_head)) ! goto out_unlock; vswap_lh = &vswap_address_used_head; *************** *** 294,303 **** /* no page could be locked for changes */ if (vswap_lh == &vswap_address_used_head) ! return 0; fragment = vswap->fragment; /* set old virtual addressed ptes to the real swap entry */ ! if (!set_pte_list_to_entry(vswap->pte_list, old_entry, entry)) goto backout; --- 296,307 ---- /* no page could be locked for changes */ if (vswap_lh == &vswap_address_used_head) ! goto out_unlock; fragment = vswap->fragment; /* 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; *************** *** 339,343 **** add_fragment_to_hash_table(fragment); UnlockPage(fragment->comp_page->page); ! return 1; backout: --- 343,349 ---- add_fragment_to_hash_table(fragment); UnlockPage(fragment->comp_page->page); ! out_unlock: ! spin_unlock(&virtual_swap_list); ! return ret; backout: Index: main.c =================================================================== RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/main.c,v retrieving revision 1.56 retrieving revision 1.57 diff -C2 -r1.56 -r1.57 *** main.c 16 Jul 2002 21:58:08 -0000 1.56 --- main.c 17 Jul 2002 20:44:36 -0000 1.57 *************** *** 2,6 **** * linux/mm/comp_cache/main.c * ! * Time-stamp: <2002-07-16 16:35:35 rcastro> * * Linux Virtual Memory Compressed Cache --- 2,6 ---- * linux/mm/comp_cache/main.c * ! * Time-stamp: <2002-07-17 15:14:43 rcastro> * * Linux Virtual Memory Compressed Cache *************** *** 46,56 **** extern unsigned long num_physpages; - extern struct comp_cache_page * get_comp_cache_page(struct page *, unsigned short, struct comp_cache_fragment **, unsigned int, int); inline void compress_dirty_page(struct page * page, int (*writepage)(struct page *), unsigned int gfp_mask, int priority) { ! int write; write = !!page->buffers; --- 46,58 ---- extern unsigned long num_physpages; extern struct comp_cache_page * get_comp_cache_page(struct page *, unsigned short, struct comp_cache_fragment **, unsigned int, int); + /* ugly global comp_cache_lock (only to start make it SMP-safe) */ + spinlock_t comp_cache_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED; + inline void compress_dirty_page(struct page * page, int (*writepage)(struct page *), unsigned int gfp_mask, int priority) { ! int write, ret; write = !!page->buffers; *************** *** 73,80 **** if (page->buffers) BUG(); ! ! /* in the case we fail to compress the page, set the bits back ! * since that's a dirty page */ ! if (compress_page(page, 1, gfp_mask, priority)) return; set_bits_back: --- 75,85 ---- if (page->buffers) BUG(); ! ! spin_lock(&comp_cache_lock); ! ret = compress_page(page, 1, gfp_mask, priority); ! spin_unlock(&comp_cache_lock); ! ! /* failed to compress the dirty page? set the bits back */ ! if (ret) return; set_bits_back: *************** *** 86,89 **** --- 91,96 ---- compress_clean_page(struct page * page, unsigned int gfp_mask, int priority) { + int ret; + if (page->buffers) BUG(); *************** *** 93,97 **** return 1; #endif ! return compress_page(page, 0, gfp_mask, priority); } --- 100,106 ---- return 1; #endif ! spin_lock(&comp_cache_lock); ! ret = compress_page(page, 0, gfp_mask, priority); ! spin_unlock(&comp_cache_lock); } Index: swapin.c =================================================================== RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/swapin.c,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -r1.45 -r1.46 *** swapin.c 16 Jul 2002 18:41:55 -0000 1.45 --- swapin.c 17 Jul 2002 20:44:36 -0000 1.46 *************** *** 2,6 **** * linux/mm/comp_cache/swapin.c * ! * Time-stamp: <2002-07-16 14:55:53 rcastro> * * Linux Virtual Memory Compressed Cache --- 2,6 ---- * linux/mm/comp_cache/swapin.c * ! * Time-stamp: <2002-07-17 13:58:48 rcastro> * * Linux Virtual Memory Compressed Cache *************** *** 92,95 **** --- 92,96 ---- int err; + spin_lock(&comp_cache_lock); err = find_comp_page(mapping, offset, &fragment); *************** *** 97,101 **** * had a real address assigned */ if (err) ! goto out; if (!PageLocked(page)) --- 98,102 ---- * had a real address assigned */ if (err) ! goto out_unlock; if (!PageLocked(page)) *************** *** 126,130 **** UnlockPage(page); ! out: return err; } --- 127,132 ---- UnlockPage(page); ! out_unlock: ! spin_unlock(&comp_cache_lock); return err; } Index: swapout.c =================================================================== RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/swapout.c,v retrieving revision 1.62 retrieving revision 1.63 diff -C2 -r1.62 -r1.63 *** swapout.c 17 Jul 2002 13:00:58 -0000 1.62 --- swapout.c 17 Jul 2002 20:44:36 -0000 1.63 *************** *** 2,6 **** * /mm/comp_cache/swapout.c * ! * Time-stamp: <2002-07-17 09:42:34 rcastro> * * Linux Virtual Memory Compressed Cache --- 2,6 ---- * /mm/comp_cache/swapout.c * ! * Time-stamp: <2002-07-17 12:34:20 rcastro> * * Linux Virtual Memory Compressed Cache *************** *** 232,237 **** --- 232,239 ---- while (!list_empty(&lru_queue) && maxscan--) { if (unlikely(current->need_resched)) { + spin_unlock(&comp_cache_lock); __set_current_state(TASK_RUNNING); schedule(); + spin_lock(&comp_cache_lock); } *************** *** 304,308 **** if (swap_cache_page && !swap_duplicate(entry)) BUG(); ! swp_buffer = decompress_to_swp_buffer(fragment, gfp_mask); --- 306,311 ---- if (swap_cache_page && !swap_duplicate(entry)) BUG(); ! ! spin_unlock(&comp_cache_lock); swp_buffer = decompress_to_swp_buffer(fragment, gfp_mask); *************** *** 326,329 **** --- 329,334 ---- swap_free(entry); + spin_lock(&comp_cache_lock); + if (!swp_buffer || --nrpages) continue; *************** *** 452,457 **** --- 457,464 ---- if (unlikely(current->need_resched)) { + spin_unlock(&comp_cache_lock); __set_current_state(TASK_RUNNING); schedule(); + spin_lock(&comp_cache_lock); } *************** *** 488,492 **** --- 495,501 ---- BUG(); + spin_unlock(&comp_cache_lock); new_page = alloc_page(gfp_mask); + spin_lock(&comp_cache_lock); if (!new_page) Index: vswap.c =================================================================== RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/vswap.c,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -r1.41 -r1.42 *** vswap.c 17 Jul 2002 13:00:58 -0000 1.41 --- vswap.c 17 Jul 2002 20:44:36 -0000 1.42 *************** *** 2,6 **** * linux/mm/comp_cache/vswap.c * ! * Time-stamp: <2002-07-17 08:52:56 rcastro> * * Linux Virtual Memory Compressed Cache --- 2,6 ---- * linux/mm/comp_cache/vswap.c * ! * Time-stamp: <2002-07-17 16:48:47 rcastro> * * Linux Virtual Memory Compressed Cache *************** *** 61,64 **** --- 61,67 ---- unsigned long nr_free_vswap = 0, nr_used_vswap = 0; + spinlock_t virtual_swap_list __cacheline_aligned = SPIN_LOCK_UNLOCKED; + + /* the caller must hold the virtual_swap_list lock */ static int comp_cache_vswap_alloc(void) *************** *** 107,112 **** * comp_cache_available_vswap - this function returns 1 if we have any * available vswap entry and also if we can assign any vswap entry. */ ! int comp_cache_available_vswap(void) { unsigned short available_mean_size; --- 110,117 ---- * comp_cache_available_vswap - this function returns 1 if we have any * available vswap entry and also if we can assign any vswap entry. + * + * the caller must hold virtual_swap_list lock */ ! static int comp_cache_available_vswap(void) { unsigned short available_mean_size; *************** *** 131,138 **** if (!vswap_alloc_and_init(vswap_address, last_vswap_allocated + 1)) return 0; ! for (i = last_vswap_allocated + 1; i < vswap_current_num_entries && vswap_address[i]; i++); last_vswap_allocated = i - 1; ! return 1; } --- 136,145 ---- if (!vswap_alloc_and_init(vswap_address, last_vswap_allocated + 1)) return 0; ! ! /* update the last_vswap_allocated variable to the ! * actual last vswap allocated entry */ for (i = last_vswap_allocated + 1; i < vswap_current_num_entries && vswap_address[i]; i++); last_vswap_allocated = i - 1; ! return 1; } *************** *** 160,173 **** * if we have virtual swap entries to be compressed. */ ! inline int comp_cache_available_space(void) { if (comp_cache_available_vswap()) ! return 1; /* can we still compress all these entries? */ if (vswap_num_reserved_entries > 0) ! return 1; ! return 0; } --- 167,187 ---- * if we have virtual swap entries to be compressed. */ ! int comp_cache_available_space(void) { + int ret = 1; + + spin_lock(&virtual_swap_list); + if (comp_cache_available_vswap()) ! goto out_unlock; /* can we still compress all these entries? */ if (vswap_num_reserved_entries > 0) ! goto out_unlock; ! ret = 0; ! out_unlock: ! spin_unlock(&virtual_swap_list); ! return ret; } *************** *** 192,201 **** entry.val = 0; if (!vswap_address && !comp_cache_vswap_alloc()) ! return entry; if (!comp_cache_available_vswap()) ! return entry; vswap = list_entry(vswap_address_free_head.next, struct vswap_address, list); --- 206,216 ---- entry.val = 0; + spin_lock(&virtual_swap_list); if (!vswap_address && !comp_cache_vswap_alloc()) ! goto out_unlock; if (!comp_cache_available_vswap()) ! goto out_unlock; vswap = list_entry(vswap_address_free_head.next, struct vswap_address, list); *************** *** 228,237 **** BUG(); return entry; } /** ! * comp_cache_swp_duplicate - swap_duplicate for virtual swap ! * addresses. * @entry: the virtual swap entry which will have its count * incremented --- 243,254 ---- BUG(); + out_unlock: + spin_unlock(&virtual_swap_list); return entry; } /** ! * virtual_swap_duplicate - swap_duplicate for virtual swap addresses. ! * * @entry: the virtual swap entry which will have its count * incremented *************** *** 249,269 **** 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 ! * had a real swap address assigned, we will call swap_free() for it, ! * since we hold a reference to the real address for every pending ! * pte. If we get to count == 0, the entry will have its struct ! * initalized and be added to the free list. In the case we have a ! * fragment (recall that fragments don't hold references on swap ! * addresses), we will free it too. */ int --- 266,289 ---- return 0; if (offset >= vswap_current_num_entries) ! return 0; ! spin_lock(&virtual_swap_list); vswap_address[offset]->swap_count++; + spin_unlock(&virtual_swap_list); 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 get to ! * swap_count == 0, the entry will have its struct initalized and be ! * added to the free list. In the case we have a fragment (recall that ! * fragments don't hold references on swap addresses), we will free it ! * too. ! * ! * the caller must hold virtual_swap_list lock */ int *************** *** 332,354 **** comp_cache_freeable_space += fragment->compressed_size; comp_cache_free(fragment); return 0; } - /** - * virtual_swap_count - swap_count for virtual swap addresses. - * @entry: virtual swap entry that will be returned its counter. - * - * This function returns the counter for the vswap entry parameter. - */ - 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); - } - /*** * remove_fragment_vswap - this function tells the vswap entry that it --- 352,361 ---- comp_cache_freeable_space += fragment->compressed_size; + /* whops, it will DEADLOCK when shrinking the vswap table + * since we hold virtual_swap_list */ comp_cache_free(fragment); return 0; } /*** * remove_fragment_vswap - this function tells the vswap entry that it *************** *** 379,386 **** return; offset = SWP_OFFSET(entry); - if (!vswap_address[offset]->swap_count) ! return; if (reserved(offset) || !vswap_address[offset]->fragment) --- 386,394 ---- return; + spin_lock(&virtual_swap_list); + offset = SWP_OFFSET(entry); if (!vswap_address[offset]->swap_count) ! goto out_unlock; if (reserved(offset) || !vswap_address[offset]->fragment) *************** *** 397,400 **** --- 405,410 ---- comp_cache_freeable_space += fragment->compressed_size; vswap_num_reserved_entries++; + out_unlock: + spin_unlock(&virtual_swap_list); } *************** *** 423,426 **** --- 433,438 ---- if (!vswap_address(entry)) return; + + spin_lock(&virtual_swap_list); offset = SWP_OFFSET(entry); *************** *** 441,444 **** --- 453,458 ---- comp_cache_freeable_space -= fragment->compressed_size; vswap_num_reserved_entries--; + + spin_unlock(&virtual_swap_list); } *************** *** 452,456 **** * may be on and adds the pte_list to the free list. May also be * called for new pte_list structures which aren't on any list yet. ! * Caller needs to hold the pagemap_lru_list. * * (adapted from Rik van Riel's rmap patch) --- 466,471 ---- * may be on and adds the pte_list to the free list. May also be * called for new pte_list structures which aren't on any list yet. ! * ! * caller needs to hold the pagemap_lru_list. * * (adapted from Rik van Riel's rmap patch) *************** *** 499,503 **** * Returns a pointer to a fresh pte_list structure. Allocates new * pte_list structures as required. ! * Caller needs to hold the pagemap_lru_lock. * * (adapted from Rik van Riel's rmap patch) --- 514,519 ---- * Returns a pointer to a fresh pte_list structure. Allocates new * pte_list structures as required. ! * ! * caller needs to hold the pagemap_lru_lock. * * (adapted from Rik van Riel's rmap patch) *************** *** 551,554 **** --- 567,572 ---- * adressed ptes. * + * caller must hold the mm->page_table_lock. + * * (adapted from Rik van Riel's rmap patch) */ *************** *** 599,602 **** --- 617,622 ---- * entries. * + * caller must hold the mm->page_table_lock. + * * (adapted from Rik van Riel's rmap patch) */ *************** *** 639,642 **** --- 659,664 ---- return; + spin_lock(&virtual_swap_list); + offset = SWP_OFFSET(entry); *************** *** 647,650 **** --- 669,674 ---- vswap_address[offset]->swap_cache_page = page; vswap_num_swap_cache++; + + spin_unlock(&virtual_swap_list); } *************** *** 672,675 **** --- 696,701 ---- return; + spin_lock(&virtual_swap_list); + offset = SWP_OFFSET(entry); *************** *** 679,682 **** --- 705,710 ---- vswap_address[offset]->swap_cache_page = NULL; vswap_num_swap_cache--; + + spin_unlock(&virtual_swap_list); } *************** *** 691,694 **** --- 719,723 ---- * its struct, adding it to the list of free vswap entries. * + * the caller must hold virtual_swap_list lock */ int |