Thread: [lc-checkins] CVS: linux/mm/comp_cache adaptivity.c,1.21,1.22 aux.c,1.28,1.29 free.c,1.29,1.30 main.
Status: Beta
Brought to you by:
nitin_sf
|
From: Rodrigo S. de C. <rc...@us...> - 2002-06-11 13:21:01
|
Update of /cvsroot/linuxcompressed/linux/mm/comp_cache
In directory usw-pr-cvs1:/tmp/cvs-serv3905/mm/comp_cache
Modified Files:
adaptivity.c aux.c free.c main.c proc.c swapin.c swapout.c
Log Message:
- Now compress_*_page() and shrink_cache() take into account the
return value of compress_page() and don't loop in shrink_cache() if
not needed.
- Support for storing page with buffers in compressed cache. These
pages are not compressed, only referenced by a compressed cache entry
in order to make the space reserved for compressed cache useful for
these kind of pages. The main consequence is that we avoid syncing
those buffers to disk in case of memory pressure on the uncompressed
cache.
- For this buffer support, there's a new page flag used by our
code. It's called PG_mapped_comp_cache, which means that a certain
page is part of page cache, but is also mapped by compressed
cache. The old PG_comp_cache flag means that the page has a fragment
in compressed cache. The difference is subtle.
- The buffer support is based on two main functions. The first one,
comp_cache_try_to_release(), is a wrapper for try_to_release()
function. In some cases, we won't call the try_to_release() and will
store the page in compressed cache, returning the page reserved for
compressed cache (if any) to the caller (shrink_cache()) to be freed.
- The second fundamental function is steal_page_from_comp_cache(),
which will remove a PageMappedCompCache from compressed cache,
ocasionally replacing this page (which was used by compressed cache)
with a new one. That sort of thing is needed when mapping this page
back to a pte or for any reference that is made to this particular
page. Actually, all reference to a PageMappedCompCache page will
remove it from compressed cache (will "steal" it).
- Another way out for this kind of page will be writeout_fragments(),
which will sync the page buffers, removing from page cache (or swap
cache), and keep using this page just freed for the compressed cache.
- New info in /proc/comp_cache_hist. Now /proc/comp_cache_hist shows
data about how many compressed cache entries whose pages have buffers
and also compressed cache entries without a reserved page (which will
happen often with buffer support, since the buffer support may "steal"
the page from compressed cache).
Index: adaptivity.c
===================================================================
RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/adaptivity.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -C2 -r1.21 -r1.22
*** adaptivity.c 30 May 2002 13:56:09 -0000 1.21
--- adaptivity.c 11 Jun 2002 13:20:49 -0000 1.22
***************
*** 2,6 ****
* linux/mm/comp_cache/adaptivity.c
*
! * Time-stamp: <2002-05-30 10:50:05 rcastro>
*
* Linux Virtual Memory Compressed Cache
--- 2,6 ----
* linux/mm/comp_cache/adaptivity.c
*
! * Time-stamp: <2002-06-10 13:32:33 rcastro>
*
* Linux Virtual Memory Compressed Cache
***************
*** 570,578 ****
UnlockPage(empty_comp_page->page);
page_cache_release(empty_comp_page->page);
kmem_cache_free(comp_cachep, (empty_comp_page));
-
- comp_cache_freeable_space -= PAGE_SIZE;
- comp_cache_free_space -= PAGE_SIZE;
num_comp_pages--;
#if 0
--- 570,577 ----
UnlockPage(empty_comp_page->page);
+ set_comp_page(empty_comp_page, NULL);
+
page_cache_release(empty_comp_page->page);
kmem_cache_free(comp_cachep, (empty_comp_page));
num_comp_pages--;
#if 0
Index: aux.c
===================================================================
RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/aux.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -C2 -r1.28 -r1.29
*** aux.c 29 May 2002 21:28:54 -0000 1.28
--- aux.c 11 Jun 2002 13:20:49 -0000 1.29
***************
*** 2,6 ****
* linux/mm/comp_cache/aux.c
*
! * Time-stamp: <2002-05-29 17:13:08 rcastro>
*
* Linux Virtual Memory Compressed Cache
--- 2,6 ----
* linux/mm/comp_cache/aux.c
*
! * Time-stamp: <2002-06-10 15:04:55 rcastro>
*
* Linux Virtual Memory Compressed Cache
***************
*** 68,71 ****
--- 68,93 ----
}
+ inline void
+ set_comp_page(comp_cache_t * comp_page, struct page * page)
+ {
+ if (!comp_page)
+ BUG();
+ if (comp_page->page) {
+ if (page)
+ goto out;
+ comp_cache_freeable_space -= PAGE_SIZE;
+ comp_cache_free_space -= PAGE_SIZE;
+ goto out;
+ }
+
+ if (!page)
+ BUG();
+
+ comp_cache_freeable_space += PAGE_SIZE;
+ comp_cache_free_space += PAGE_SIZE;
+
+ out:
+ comp_page->page = page;
+ }
static void
***************
*** 169,173 ****
unsigned long total, total_fragments;
struct list_head * fragment_lh;
!
if (index < 0)
BUG();
--- 191,195 ----
unsigned long total, total_fragments;
struct list_head * fragment_lh;
!
if (index < 0)
BUG();
***************
*** 182,189 ****
total_fragments++;
! if (total_fragments > 3)
! num_fragments[3]++;
! else
! num_fragments[total_fragments]++;
}
--- 204,248 ----
total_fragments++;
! #if 0
! if (comp_page->page) {
! if (comp_page->page->buffers) {
! if (index != 0 && index != free_space_hash_size - 1)
! BUG();
! if (!comp_page->page->mapping)
! BUG();
! if (page_count(comp_page->page) != 2)
! BUG();
! }
! if (!comp_page->page->buffers && page_count(comp_page->page) != 1)
! BUG();
! if (PageDirty(comp_page->page))
! BUG();
! }
! else {
! if (index != free_space_hash_size - 1)
! BUG();
! if (comp_page->free_space != PAGE_SIZE)
! BUG();
! }
! #endif
!
! switch(total_fragments)
! {
! case 0:
! if (!comp_page->page)
! num_fragments[6]++;
! break;
! case 1:
! if (comp_page->page && comp_page->page->buffers)
! num_fragments[5]++;
! num_fragments[1]++;
! break;
! default:
! if (total_fragments > 3)
! num_fragments[4]++;
! else
! num_fragments[total_fragments]++;
! break;
! }
}
Index: free.c
===================================================================
RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/free.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -C2 -r1.29 -r1.30
*** free.c 15 May 2002 18:05:36 -0000 1.29
--- free.c 11 Jun 2002 13:20:49 -0000 1.30
***************
*** 2,6 ****
* linux/mm/comp_cache/free.c
*
! * Time-stamp: <2002-05-15 10:05:47 rcastro>
*
* Linux Virtual Memory Compressed Cache
--- 2,6 ----
* linux/mm/comp_cache/free.c
*
! * Time-stamp: <2002-06-10 13:42:06 rcastro>
*
* Linux Virtual Memory Compressed Cache
***************
*** 87,92 ****
if (!comp_page)
BUG();
- if (!comp_page->page)
- BUG();
if (not_compressed(fragment) && comp_page->free_space)
BUG();
--- 87,90 ----
***************
*** 94,98 ****
/* remove from the free space hash table to update it */
remove_comp_page_from_hash_table(comp_page);
!
/* fragment is added in the correct location to the comp_page
* list (see get_comp_cache_page():swapout.c) */
--- 92,96 ----
/* remove from the free space hash table to update it */
remove_comp_page_from_hash_table(comp_page);
!
/* fragment is added in the correct location to the comp_page
* list (see get_comp_cache_page():swapout.c) */
***************
*** 167,170 ****
--- 165,169 ----
comp_cache_free(comp_cache_fragment_t * fragment) {
comp_cache_t * comp_page;
+ int locked;
if (!fragment)
***************
*** 172,182 ****
comp_page = fragment->comp_page;
! if (TryLockPage(comp_page->page))
! BUG();
!
! comp_cache_free_locked(fragment);
! /* steal the page if we need to shrink the comp cache */
! shrink_comp_cache(comp_page);
}
--- 171,183 ----
comp_page = fragment->comp_page;
! locked = !TryLockPage(comp_page->page);
! comp_cache_free_locked(fragment);
!
! /* steal the page if we need to shrink the cache. The
! * page will be unlocked in shrink_comp_cache()
! * function */
! if (locked)
! shrink_comp_cache(comp_page);
}
Index: main.c
===================================================================
RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/main.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -C2 -r1.42 -r1.43
*** main.c 31 May 2002 16:48:53 -0000 1.42
--- main.c 11 Jun 2002 13:20:50 -0000 1.43
***************
*** 2,6 ****
* linux/mm/comp_cache/main.c
*
! * Time-stamp: <2002-05-31 13:12:36 rcastro>
*
* Linux Virtual Memory Compressed Cache
--- 2,6 ----
* linux/mm/comp_cache/main.c
*
! * Time-stamp: <2002-06-10 15:15:24 rcastro>
*
* Linux Virtual Memory Compressed Cache
***************
*** 43,62 ****
extern unsigned long num_physpages;
! extern comp_cache_t * get_comp_cache_page(struct page *, unsigned short, comp_cache_fragment_t **, int, unsigned int);
! inline int
compress_dirty_page(struct page * page, int (*writepage)(struct page *), unsigned int gfp_mask)
{
! int ret;
!
#ifdef CONFIG_COMP_PAGE_CACHE
! if (!shmem_page(page))
#else
! if (PageSwapCache(page))
#endif
! ret = compress_page(page, 1, gfp_mask);
! else
! ret = writepage(page);
! return ret;
}
--- 43,74 ----
extern unsigned long num_physpages;
! extern comp_cache_t * get_comp_cache_page(struct page *, unsigned short, comp_cache_fragment_t **, int, int, unsigned int);
! inline void
compress_dirty_page(struct page * page, int (*writepage)(struct page *), unsigned int gfp_mask)
{
! int write;
!
! write = !!page->buffers;
#ifdef CONFIG_COMP_PAGE_CACHE
! write |= shmem_page(page);
#else
! write |= !PageSwapCache(page);
#endif
! if (write)
! goto writepage;
!
! if (PageMappedCompCache(page))
! BUG();
!
! if (page->buffers)
! BUG();
!
! if (!compress_page(page, 1, gfp_mask))
! UnlockPage(page);
! return;
!
! writepage:
! writepage(page);
}
***************
*** 64,83 ****
compress_clean_page(struct page * page, unsigned int gfp_mask)
{
! if (PageCompCache(page))
! return 0;
#ifndef CONFIG_COMP_PAGE_CACHE
if (!PageSwapCache(page))
! return 0;
#endif
!
! page_cache_get(page);
! spin_unlock(&pagecache_lock);
!
! compress_page(page, 0, gfp_mask);
! page_cache_release(page);
!
! spin_lock(&pagemap_lru_lock);
! return 1;
}
--- 76,91 ----
compress_clean_page(struct page * page, unsigned int gfp_mask)
{
! /* that should not happen */
! if (PageMappedCompCache(page))
! BUG();
!
! if (page->buffers)
! BUG();
#ifndef CONFIG_COMP_PAGE_CACHE
if (!PageSwapCache(page))
! return 1;
#endif
! return compress_page(page, 0, gfp_mask);
}
***************
*** 110,114 ****
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, gfp_mask);
/* if comp_page == NULL, get_comp_cache_page() gave up
--- 118,122 ----
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
***************
*** 135,140 ****
BUG();
UnlockPage(comp_page->page);
- UnlockPage(page);
return 1;
}
--- 143,256 ----
BUG();
UnlockPage(comp_page->page);
return 1;
+ }
+
+ void
+ steal_page_from_comp_cache(struct page * page, struct page * new_page)
+ {
+ comp_cache_fragment_t * fragment;
+ comp_cache_t * comp_page;
+ struct page * old_page;
+ int locked;
+
+ if (!PageMappedCompCache(page))
+ return;
+
+ if (find_comp_page(page->mapping, page->index, &fragment))
+ BUG();
+
+ if (CompFragmentIO(fragment))
+ BUG();
+ comp_page = fragment->comp_page;
+ old_page = comp_page->page;
+
+ if (old_page != page)
+ BUG();
+ locked = !TryLockPage(old_page);
+
+ set_comp_page(comp_page, new_page);
+
+ if (new_page) {
+ /* the reference got in the caller will be drop */
+ page_cache_get(new_page);
+ if (page_count(new_page) != 3)
+ BUG();
+ }
+
+ comp_cache_free_locked(fragment);
+ PageClearMappedCompCache(old_page);
+
+ if (locked)
+ UnlockPage(old_page);
+ }
+
+ int
+ comp_cache_try_to_release_page(struct page ** page, int gfp_mask)
+ {
+ comp_cache_fragment_t * fragment;
+ comp_cache_t * comp_page;
+ unsigned short comp_size, dirty;
+ struct page * old_page;
+ int ret = 0;
+
+ if (PageCompCache(*page))
+ BUG();
+
+ if (PageMappedCompCache(*page))
+ return 0;
+
+ if (page_count(*page) != 3)
+ return try_to_release_page(*page, gfp_mask);
+
+ if (PageSwapCache(*page)) {
+ swp_entry_t entry = (swp_entry_t) { (*page)->index };
+
+ if (vswap_address(entry))
+ BUG();
+ }
+
+ /* could we free the buffer without IO, so why store in
+ * compressed cache with the buffers? it can be ocasionally
+ * stored later as a clean page */
+ if (try_to_release_page(*page, 0))
+ return 1;
+
+ /* it's not mapped by any process, therefore we can trade this
+ * page with a page reserved for compressed cache use */
+ comp_size = PAGE_SIZE;
+ dirty = 0;
+
+ comp_page = get_comp_cache_page(*page, comp_size, &fragment, dirty, 0, gfp_mask);
+
+ if (!comp_page)
+ return ret;
+
+ /* let's swap the pages */
+ old_page = comp_page->page;
+ set_comp_page(comp_page, (*page));
+
+ PageSetMappedCompCache(comp_page->page);
+
+ /* whoops, no page to set to (*page), so it's time to leave */
+ if (!old_page)
+ goto out;
+
+ /* no need to call page_cache_get() since we have an extra
+ * reference got in shrink_cache() that won't be released
+ * (recall that we are setting *page to a new page) */
+ *page = old_page;
+ if (page_count(old_page) != 1)
+ BUG();
+ if (old_page->mapping)
+ BUG();
+ if (!PageLocked(old_page))
+ BUG();
+
+ UnlockPage(comp_page->page);
+ page_cache_release(comp_page->page);
+ ret = 1;
+ out:
+ comp_cache_update_page_stats(comp_page->page, 0);
+ return ret;
}
Index: proc.c
===================================================================
RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/proc.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -C2 -r1.13 -r1.14
*** proc.c 30 May 2002 16:33:18 -0000 1.13
--- proc.c 11 Jun 2002 13:20:50 -0000 1.14
***************
*** 2,6 ****
* linux/mm/comp_cache/proc.c
*
! * Time-stamp: <2002-05-30 13:21:25 rcastro>
*
* Linux Virtual Memory Compressed Cache
--- 2,6 ----
* linux/mm/comp_cache/proc.c
*
! * Time-stamp: <2002-06-10 14:46:20 rcastro>
*
* Linux Virtual Memory Compressed Cache
***************
*** 65,68 ****
--- 65,83 ----
};
+ inline void
+ comp_cache_update_page_stats(struct page * page, int dirty)
+ {
+ #ifdef CONFIG_COMP_PAGE_CACHE
+ if (!PageSwapCache(page))
+ compression_algorithms[current_algorithm].stats.comp_page++;
+ else
+ #endif
+ compression_algorithms[current_algorithm].stats.comp_swap++;
+ if (dirty)
+ compression_algorithms[current_algorithm].stats.comp_dirty++;
+ else
+ compression_algorithms[current_algorithm].stats.comp_clean++;
+ }
+
static void
comp_cache_update_comp_stats(stats_page_t * comp_page_stats, struct page * page, int dirty)
***************
*** 92,105 ****
stats->comp_cycles_sum += comp_page_stats->comp_cycles;
! #ifdef CONFIG_COMP_PAGE_CACHE
! if (!PageSwapCache(page))
! compression_algorithms[current_algorithm].stats.comp_page++;
! else
! #endif
! compression_algorithms[current_algorithm].stats.comp_swap++;
! if (dirty)
! compression_algorithms[current_algorithm].stats.comp_dirty++;
! else
! compression_algorithms[current_algorithm].stats.comp_clean++;
}
--- 107,111 ----
stats->comp_cycles_sum += comp_page_stats->comp_cycles;
! comp_cache_update_page_stats(page, dirty);
}
***************
*** 374,379 ****
}
! #define FRAGMENTS_PRINTK num_fragments[0], num_fragments[1], num_fragments[2], num_fragments[3], num_fragments[4]
! #define FRAGMENTS_COUNT 5
int
--- 380,387 ----
}
! #define FRAGMENTS_PRINTK \
! num_fragments[0], num_fragments[1], num_fragments[2], num_fragments[3], \
! num_fragments[4], num_fragments[5], num_fragments[6]
! #define FRAGMENTS_COUNT 7
int
***************
*** 396,401 ****
total1 = free_space_count(0, num_fragments);
length += sprintf(page + length,
! " total 0f 1f 2f 3f more\n"
! " %4d: %8lu %5lu %5lu %5lu %5lu %5lu\n",
0,
total1,
--- 404,409 ----
total1 = free_space_count(0, num_fragments);
length += sprintf(page + length,
! " total 0f 1f 2f 3f more buffers nopg\n"
! " %4d: %7lu %5lu %5lu %5lu %5lu %5lu %5lu %5lu\n",
0,
total1,
***************
*** 408,412 ****
length += sprintf(page + length,
! "%4d - %4d: %8lu %5lu %5lu %5lu %5lu %5lu\n",
(i+1)*100-200?:1, (i+1)*100, total1 + total2,
FRAGMENTS_PRINTK);
--- 416,420 ----
length += sprintf(page + length,
! "%4d - %4d: %7lu %5lu %5lu %5lu %5lu %5lu %5lu %5lu\n",
(i+1)*100-200?:1, (i+1)*100, total1 + total2,
FRAGMENTS_PRINTK);
***************
*** 417,421 ****
total1 = free_space_count(free_space_hash_size - 1, num_fragments);
length += sprintf(page + length,
! "%4d - %4d: %8lu %5lu %5lu %5lu %5lu %5lu\n",
(free_space_hash_size - 2) * 100 + 1, (int) PAGE_SIZE,
total1,
--- 425,429 ----
total1 = free_space_count(free_space_hash_size - 1, num_fragments);
length += sprintf(page + length,
! "%4d - %4d: %7lu %5lu %5lu %5lu %5lu %5lu %5lu %5lu\n",
(free_space_hash_size - 2) * 100 + 1, (int) PAGE_SIZE,
total1,
Index: swapin.c
===================================================================
RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/swapin.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -C2 -r1.37 -r1.38
*** swapin.c 31 May 2002 16:48:53 -0000 1.37
--- swapin.c 11 Jun 2002 13:20:50 -0000 1.38
***************
*** 2,6 ****
* linux/mm/comp_cache/swapin.c
*
! * Time-stamp: <2002-05-31 13:04:02 rcastro>
*
* Linux Virtual Memory Compressed Cache
--- 2,6 ----
* linux/mm/comp_cache/swapin.c
*
! * Time-stamp: <2002-06-10 18:05:50 rcastro>
*
* Linux Virtual Memory Compressed Cache
***************
*** 37,41 ****
comp_cache_fragment_t * fragment;
int err = -ENOENT;
!
if (likely(!PageTestandClearCompCache(page)))
goto out;
--- 37,41 ----
comp_cache_fragment_t * fragment;
int err = -ENOENT;
!
if (likely(!PageTestandClearCompCache(page)))
goto out;
***************
*** 57,61 ****
__set_page_dirty(page);
}
-
comp_cache_free(fragment);
out:
--- 57,60 ----
***************
*** 108,111 ****
--- 107,112 ----
if (TryLockPage(fragment->comp_page->page))
BUG();
+ if (PageMappedCompCache(fragment->comp_page->page))
+ BUG();
/* move the fragment to the back of the lru list */
***************
*** 135,142 ****
fragment = list_entry(fragment_lh, comp_cache_fragment_t, mapping_list);
! if ((fragment->index < start) && (partial && (fragment->index + 1) != start))
! continue;
!
! comp_cache_free(fragment);
}
}
--- 136,152 ----
fragment = list_entry(fragment_lh, comp_cache_fragment_t, mapping_list);
! if ((fragment->index >= start) || (partial && (fragment->index + 1) == start)) {
! /***
! * Only valid if we are invalidating entries
! * in compressed cache. We could invalidate in
! * invalidate_inode_pages() each page, but
! * that would make us search comp cache for
! * every page, which is not wanted
! */
! if (PageMappedCompCache(fragment->comp_page->page))
! steal_page_from_comp_cache(fragment->comp_page->page, NULL);
! else
! comp_cache_free(fragment);
! }
}
}
***************
*** 190,193 ****
--- 200,205 ----
hash = page_hash(mapping, fragment->index);
+ if (PageMappedCompCache(fragment->comp_page->page))
+ BUG();
if (!CompFragmentTestandClearDirty(fragment))
BUG();
Index: swapout.c
===================================================================
RCS file: /cvsroot/linuxcompressed/linux/mm/comp_cache/swapout.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -C2 -r1.47 -r1.48
*** swapout.c 31 May 2002 16:48:53 -0000 1.47
--- swapout.c 11 Jun 2002 13:20:50 -0000 1.48
***************
*** 2,6 ****
* /mm/comp_cache/swapout.c
*
! * Time-stamp: <2002-05-31 13:32:50 rcastro>
*
* Linux Virtual Memory Compressed Cache
--- 2,6 ----
* /mm/comp_cache/swapout.c
*
! * Time-stamp: <2002-06-10 15:27:56 rcastro>
*
* Linux Virtual Memory Compressed Cache
***************
*** 175,178 ****
--- 175,180 ----
struct swp_buffer * swp_buffer;
+ if (fragment->comp_page->page->buffers)
+ BUG();
swp_buffer = find_free_swp_buffer(fragment, gfp_mask);
***************
*** 233,236 ****
--- 235,271 ----
continue;
+ /* page which has/had buffer? */
+ if (PageMappedCompCache(page)) {
+ page_cache_get(page);
+ CompFragmentSetIO(fragment);
+ if (page->buffers && !try_to_release_page(page, gfp_mask)) {
+ UnlockPage(page);
+ page_cache_release(page);
+ CompFragmentClearIO(fragment);
+ continue;
+ }
+
+ if (PageSwapCache(page))
+ delete_from_swap_cache(page);
+ else {
+ __remove_inode_page(page);
+ page_cache_release(page);
+ }
+ PageClearMappedCompCache(page);
+ page->flags &= ~((1 << PG_uptodate) | (1 << PG_referenced));
+
+ if (CompFragmentTestandClearIO(fragment))
+ comp_cache_free_locked(fragment);
+ else
+ kmem_cache_free(fragment_cachep, (fragment));
+ UnlockPage(page);
+
+ if (page_count(page) != 1)
+ BUG();
+ if (PageDirty(page))
+ BUG();
+ continue;
+ }
+
/* clean page, let's free it */
if (!CompFragmentDirty(fragment)) {
***************
*** 308,311 ****
--- 343,350 ----
* @dirty: are we going to compress a dirty page?
*
+ * @alloc: do we allocate in case the comp_page->page == NULL? Usually
+ * yes, but in case we are going to store a page from page cache with
+ * buffers, that's not needed.
+ *
* @fragment: variable that will store the fragment to store the
* compressed data
***************
*** 313,321 ****
* @gfp_mask: we need to know if we can perform IO */
comp_cache_t *
! get_comp_cache_page(struct page * page, unsigned short compressed_size, comp_cache_fragment_t ** fragment_out, int dirty, unsigned int gfp_mask)
{
comp_cache_t * comp_page = NULL;
comp_cache_fragment_t * fragment = NULL, * previous_fragment = NULL;
struct list_head * fragment_lh;
unsigned short aux_comp_size;
int maxscan, maxtry;
--- 352,361 ----
* @gfp_mask: we need to know if we can perform IO */
comp_cache_t *
! get_comp_cache_page(struct page * page, unsigned short compressed_size, comp_cache_fragment_t ** fragment_out, int dirty, int alloc, unsigned int gfp_mask)
{
comp_cache_t * comp_page = NULL;
comp_cache_fragment_t * fragment = NULL, * previous_fragment = NULL;
struct list_head * fragment_lh;
+ struct page * new_page;
unsigned short aux_comp_size;
int maxscan, maxtry;
***************
*** 346,350 ****
if (comp_page->free_space != PAGE_SIZE)
BUG();
! goto new_page;
}
--- 386,394 ----
if (comp_page->free_space != PAGE_SIZE)
BUG();
! if (alloc)
! goto alloc_new_page;
!
! remove_comp_page_from_hash_table(comp_page);
! goto check_references;
}
***************
*** 389,404 ****
if (!dirty)
! goto out_unlock;
set_bits_back:
__set_page_dirty(page);
ClearPageLaunder(page);
- out_unlock:
- UnlockPage(page);
out_release:
page_cache_release(page);
return comp_page;
! new_page:
/* remove from free space hash table before update */
remove_comp_page_from_hash_table(comp_page);
--- 433,455 ----
if (!dirty)
! goto out_release;
set_bits_back:
__set_page_dirty(page);
ClearPageLaunder(page);
out_release:
page_cache_release(page);
+ /* debug */
+ if (comp_page && comp_page->page) {
+ if (comp_page->page->mapping)
+ BUG();
+ if (comp_page->page->buffers)
+ BUG();
+ if (page_count(comp_page->page) != 1)
+ BUG();
+ }
return comp_page;
! alloc_new_page:
/* remove from free space hash table before update */
remove_comp_page_from_hash_table(comp_page);
***************
*** 406,415 ****
if (comp_page->page)
BUG();
!
! comp_page->page = alloc_page(GFP_KERNEL);
! if (!comp_page->page)
! panic("get_comp_cache_page(): cannot allocate page");
if (TryLockPage(comp_page->page))
BUG();
--- 457,468 ----
if (comp_page->page)
BUG();
!
! new_page = alloc_page(gfp_mask);
! if (!new_page)
! goto failed;
+ set_comp_page(comp_page, new_page);
+
if (TryLockPage(comp_page->page))
BUG();
***************
*** 523,531 ****
failed:
add_comp_page_to_hash_table(comp_page);
! UnlockPage(comp_page->page);
comp_page = NULL;
if (!dirty)
! goto out_unlock;
goto set_bits_back;
}
--- 576,585 ----
failed:
add_comp_page_to_hash_table(comp_page);
! if (comp_page->page)
! UnlockPage(comp_page->page);
comp_page = NULL;
if (!dirty)
! goto out_release;
goto set_bits_back;
}
|