@ -413,26 +413,28 @@ static int is_last_page(struct page *page)
return PagePrivate2 ( page ) ;
}
static void get_zspage_mapping ( struct page * page , unsigned int * class_idx ,
static void get_zspage_mapping ( struct page * first_page ,
unsigned int * class_idx ,
enum fullness_group * fullness )
{
unsigned long m ;
BUG_ON ( ! is_first_page ( page ) ) ;
BUG_ON ( ! is_first_page ( first_ page) ) ;
m = ( unsigned long ) page - > mapping ;
m = ( unsigned long ) first_ page- > mapping ;
* fullness = m & FULLNESS_MASK ;
* class_idx = ( m > > FULLNESS_BITS ) & CLASS_IDX_MASK ;
}
static void set_zspage_mapping ( struct page * page , unsigned int class_idx ,
static void set_zspage_mapping ( struct page * first_page ,
unsigned int class_idx ,
enum fullness_group fullness )
{
unsigned long m ;
BUG_ON ( ! is_first_page ( page ) ) ;
BUG_ON ( ! is_first_page ( first_ page) ) ;
m = ( ( class_idx & CLASS_IDX_MASK ) < < FULLNESS_BITS ) |
( fullness & FULLNESS_MASK ) ;
page - > mapping = ( struct address_space * ) m ;
first_ page- > mapping = ( struct address_space * ) m ;
}
/*
@ -625,14 +627,14 @@ static inline void zs_pool_stat_destroy(struct zs_pool *pool)
* the pool ( not yet implemented ) . This function returns fullness
* status of the given page .
*/
static enum fullness_group get_fullness_group ( struct page * page )
static enum fullness_group get_fullness_group ( struct page * first_ page)
{
int inuse , max_objects ;
enum fullness_group fg ;
BUG_ON ( ! is_first_page ( page ) ) ;
BUG_ON ( ! is_first_page ( first_ page) ) ;
inuse = page - > inuse ;
max_objects = page - > objects ;
inuse = first_ page- > inuse ;
max_objects = first_ page- > objects ;
if ( inuse = = 0 )
fg = ZS_EMPTY ;
@ -652,12 +654,12 @@ static enum fullness_group get_fullness_group(struct page *page)
* have . This functions inserts the given zspage into the freelist
* identified by < class , fullness_group > .
*/
static void insert_zspage ( struct page * page , struct size_class * class ,
static void insert_zspage ( struct page * first_ page, struct size_class * class ,
enum fullness_group fullness )
{
struct page * * head ;
BUG_ON ( ! is_first_page ( page ) ) ;
BUG_ON ( ! is_first_page ( first_ page) ) ;
if ( fullness > = _ZS_NR_FULLNESS_GROUPS )
return ;
@ -667,7 +669,7 @@ static void insert_zspage(struct page *page, struct size_class *class,
head = & class - > fullness_list [ fullness ] ;
if ( ! * head ) {
* head = page ;
* head = first_ page;
return ;
}
@ -675,21 +677,21 @@ static void insert_zspage(struct page *page, struct size_class *class,
* We want to see more ZS_FULL pages and less almost
* empty / full . Put pages with higher - > inuse first .
*/
list_add_tail ( & page - > lru , & ( * head ) - > lru ) ;
if ( page - > inuse > = ( * head ) - > inuse )
* head = page ;
list_add_tail ( & first_ page- > lru , & ( * head ) - > lru ) ;
if ( first_ page- > inuse > = ( * head ) - > inuse )
* head = first_ page;
}
/*
* This function removes the given zspage from the freelist identified
* by < class , fullness_group > .
*/
static void remove_zspage ( struct page * page , struct size_class * class ,
static void remove_zspage ( struct page * first_ page, struct size_class * class ,
enum fullness_group fullness )
{
struct page * * head ;
BUG_ON ( ! is_first_page ( page ) ) ;
BUG_ON ( ! is_first_page ( first_ page) ) ;
if ( fullness > = _ZS_NR_FULLNESS_GROUPS )
return ;
@ -698,11 +700,11 @@ static void remove_zspage(struct page *page, struct size_class *class,
BUG_ON ( ! * head ) ;
if ( list_empty ( & ( * head ) - > lru ) )
* head = NULL ;
else if ( * head = = page )
else if ( * head = = first_ page)
* head = ( struct page * ) list_entry ( ( * head ) - > lru . next ,
struct page , lru ) ;
list_del_init ( & page - > lru ) ;
list_del_init ( & first_ page- > lru ) ;
zs_stat_dec ( class , fullness = = ZS_ALMOST_EMPTY ?
CLASS_ALMOST_EMPTY : CLASS_ALMOST_FULL , 1 ) ;
}
@ -717,21 +719,21 @@ static void remove_zspage(struct page *page, struct size_class *class,
* fullness group .
*/
static enum fullness_group fix_fullness_group ( struct size_class * class ,
struct page * page )
struct page * first_ page)
{
int class_idx ;
enum fullness_group currfg , newfg ;
BUG_ON ( ! is_first_page ( page ) ) ;
BUG_ON ( ! is_first_page ( first_ page) ) ;
get_zspage_mapping ( page , & class_idx , & currfg ) ;
newfg = get_fullness_group ( page ) ;
get_zspage_mapping ( first_ page, & class_idx , & currfg ) ;
newfg = get_fullness_group ( first_ page) ;
if ( newfg = = currfg )
goto out ;
remove_zspage ( page , class , currfg ) ;
insert_zspage ( page , class , newfg ) ;
set_zspage_mapping ( page , class_idx , newfg ) ;
remove_zspage ( first_ page, class , currfg ) ;
insert_zspage ( first_ page, class , newfg ) ;
set_zspage_mapping ( first_ page, class_idx , newfg ) ;
out :
return newfg ;
@ -1234,11 +1236,11 @@ static bool can_merge(struct size_class *prev, int size, int pages_per_zspage)
return true ;
}
static bool zspage_full ( struct page * page )
static bool zspage_full ( struct page * first_ page)
{
BUG_ON ( ! is_first_page ( page ) ) ;
BUG_ON ( ! is_first_page ( first_ page) ) ;
return page - > inuse = = page - > objects ;
return first_ page- > inuse = = first_ page- > objects ;
}
unsigned long zs_get_total_pages ( struct zs_pool * pool )