@@ -53,30 +53,9 @@ static struct swap_info_struct *swap_info[MAX_SWAPFILES];
5353
5454static DEFINE_MUTEX (swapon_mutex );
5555
56- /* For reference count accounting in swap_map */
57- /* enum for swap_map[] handling. internal use only */
58- enum {
59- SWAP_MAP = 0 , /* ops for reference from swap users */
60- SWAP_CACHE , /* ops for reference from swap cache */
61- };
62-
6356static inline int swap_count (unsigned short ent )
6457{
65- return ent & SWAP_COUNT_MASK ;
66- }
67-
68- static inline bool swap_has_cache (unsigned short ent )
69- {
70- return !!(ent & SWAP_HAS_CACHE );
71- }
72-
73- static inline unsigned short encode_swapmap (int count , bool has_cache )
74- {
75- unsigned short ret = count ;
76-
77- if (has_cache )
78- return SWAP_HAS_CACHE | ret ;
79- return ret ;
58+ return ent & ~SWAP_HAS_CACHE ;
8059}
8160
8261/* returns 1 if swap entry is freed */
@@ -224,7 +203,7 @@ static int wait_for_discard(void *word)
224203#define LATENCY_LIMIT 256
225204
226205static inline unsigned long scan_swap_map (struct swap_info_struct * si ,
227- int cache )
206+ unsigned short usage )
228207{
229208 unsigned long offset ;
230209 unsigned long scan_base ;
@@ -355,10 +334,7 @@ static inline unsigned long scan_swap_map(struct swap_info_struct *si,
355334 si -> lowest_bit = si -> max ;
356335 si -> highest_bit = 0 ;
357336 }
358- if (cache == SWAP_CACHE ) /* at usual swap-out via vmscan.c */
359- si -> swap_map [offset ] = encode_swapmap (0 , true);
360- else /* at suspend */
361- si -> swap_map [offset ] = encode_swapmap (1 , false);
337+ si -> swap_map [offset ] = usage ;
362338 si -> cluster_next = offset + 1 ;
363339 si -> flags -= SWP_SCANNING ;
364340
@@ -483,7 +459,7 @@ swp_entry_t get_swap_page(void)
483459
484460 swap_list .next = next ;
485461 /* This is called for allocating swap entry for cache */
486- offset = scan_swap_map (si , SWAP_CACHE );
462+ offset = scan_swap_map (si , SWAP_HAS_CACHE );
487463 if (offset ) {
488464 spin_unlock (& swap_lock );
489465 return swp_entry (type , offset );
@@ -508,7 +484,7 @@ swp_entry_t get_swap_page_of_type(int type)
508484 if (si && (si -> flags & SWP_WRITEOK )) {
509485 nr_swap_pages -- ;
510486 /* This is called for allocating swap entry, not cache */
511- offset = scan_swap_map (si , SWAP_MAP );
487+ offset = scan_swap_map (si , 1 );
512488 if (offset ) {
513489 spin_unlock (& swap_lock );
514490 return swp_entry (type , offset );
@@ -555,29 +531,31 @@ static struct swap_info_struct *swap_info_get(swp_entry_t entry)
555531 return NULL ;
556532}
557533
558- static int swap_entry_free (struct swap_info_struct * p ,
559- swp_entry_t ent , int cache )
534+ static unsigned short swap_entry_free (struct swap_info_struct * p ,
535+ swp_entry_t entry , unsigned short usage )
560536{
561- unsigned long offset = swp_offset (ent );
562- int count = swap_count ( p -> swap_map [ offset ]) ;
563- bool has_cache ;
537+ unsigned long offset = swp_offset (entry );
538+ unsigned short count ;
539+ unsigned short has_cache ;
564540
565- has_cache = swap_has_cache (p -> swap_map [offset ]);
541+ count = p -> swap_map [offset ];
542+ has_cache = count & SWAP_HAS_CACHE ;
543+ count &= ~SWAP_HAS_CACHE ;
566544
567- if (cache == SWAP_MAP ) { /* dropping usage count of swap */
568- if (count < SWAP_MAP_MAX ) {
569- count -- ;
570- p -> swap_map [offset ] = encode_swapmap (count , has_cache );
571- }
572- } else { /* dropping swap cache flag */
545+ if (usage == SWAP_HAS_CACHE ) {
573546 VM_BUG_ON (!has_cache );
574- p -> swap_map [offset ] = encode_swapmap (count , false);
547+ has_cache = 0 ;
548+ } else if (count < SWAP_MAP_MAX )
549+ count -- ;
550+
551+ if (!count )
552+ mem_cgroup_uncharge_swap (entry );
553+
554+ usage = count | has_cache ;
555+ p -> swap_map [offset ] = usage ;
575556
576- }
577- /* return code. */
578- count = p -> swap_map [offset ];
579557 /* free if no reference */
580- if (!count ) {
558+ if (!usage ) {
581559 if (offset < p -> lowest_bit )
582560 p -> lowest_bit = offset ;
583561 if (offset > p -> highest_bit )
@@ -588,9 +566,8 @@ static int swap_entry_free(struct swap_info_struct *p,
588566 nr_swap_pages ++ ;
589567 p -> inuse_pages -- ;
590568 }
591- if (!swap_count (count ))
592- mem_cgroup_uncharge_swap (ent );
593- return count ;
569+
570+ return usage ;
594571}
595572
596573/*
@@ -603,7 +580,7 @@ void swap_free(swp_entry_t entry)
603580
604581 p = swap_info_get (entry );
605582 if (p ) {
606- swap_entry_free (p , entry , SWAP_MAP );
583+ swap_entry_free (p , entry , 1 );
607584 spin_unlock (& swap_lock );
608585 }
609586}
@@ -614,19 +591,13 @@ void swap_free(swp_entry_t entry)
614591void swapcache_free (swp_entry_t entry , struct page * page )
615592{
616593 struct swap_info_struct * p ;
617- int ret ;
594+ unsigned short count ;
618595
619596 p = swap_info_get (entry );
620597 if (p ) {
621- ret = swap_entry_free (p , entry , SWAP_CACHE );
622- if (page ) {
623- bool swapout ;
624- if (ret )
625- swapout = true; /* the end of swap out */
626- else
627- swapout = false; /* no more swap users! */
628- mem_cgroup_uncharge_swapcache (page , entry , swapout );
629- }
598+ count = swap_entry_free (p , entry , SWAP_HAS_CACHE );
599+ if (page )
600+ mem_cgroup_uncharge_swapcache (page , entry , count != 0 );
630601 spin_unlock (& swap_lock );
631602 }
632603}
@@ -705,7 +676,7 @@ int free_swap_and_cache(swp_entry_t entry)
705676
706677 p = swap_info_get (entry );
707678 if (p ) {
708- if (swap_entry_free (p , entry , SWAP_MAP ) == SWAP_HAS_CACHE ) {
679+ if (swap_entry_free (p , entry , 1 ) == SWAP_HAS_CACHE ) {
709680 page = find_get_page (& swapper_space , entry .val );
710681 if (page && !trylock_page (page )) {
711682 page_cache_release (page );
@@ -1212,7 +1183,7 @@ static int try_to_unuse(unsigned int type)
12121183
12131184 if (swap_count (* swap_map ) == SWAP_MAP_MAX ) {
12141185 spin_lock (& swap_lock );
1215- * swap_map = encode_swapmap ( 0 , true) ;
1186+ * swap_map = SWAP_HAS_CACHE ;
12161187 spin_unlock (& swap_lock );
12171188 reset_overflow = 1 ;
12181189 }
@@ -2111,16 +2082,16 @@ void si_swapinfo(struct sysinfo *val)
21112082 * - swap-cache reference is requested but there is already one. -> EEXIST
21122083 * - swap-cache reference is requested but the entry is not used. -> ENOENT
21132084 */
2114- static int __swap_duplicate (swp_entry_t entry , bool cache )
2085+ static int __swap_duplicate (swp_entry_t entry , unsigned short usage )
21152086{
21162087 struct swap_info_struct * p ;
21172088 unsigned long offset , type ;
2118- int result = - EINVAL ;
2119- int count ;
2120- bool has_cache ;
2089+ unsigned short count ;
2090+ unsigned short has_cache ;
2091+ int err = - EINVAL ;
21212092
21222093 if (non_swap_entry (entry ))
2123- return - EINVAL ;
2094+ goto out ;
21242095
21252096 type = swp_type (entry );
21262097 if (type >= nr_swapfiles )
@@ -2129,54 +2100,56 @@ static int __swap_duplicate(swp_entry_t entry, bool cache)
21292100 offset = swp_offset (entry );
21302101
21312102 spin_lock (& swap_lock );
2132-
21332103 if (unlikely (offset >= p -> max ))
21342104 goto unlock_out ;
21352105
2136- count = swap_count (p -> swap_map [offset ]);
2137- has_cache = swap_has_cache (p -> swap_map [offset ]);
2106+ count = p -> swap_map [offset ];
2107+ has_cache = count & SWAP_HAS_CACHE ;
2108+ count &= ~SWAP_HAS_CACHE ;
2109+ err = 0 ;
21382110
2139- if (cache == SWAP_CACHE ) { /* called for swapcache/swapin-readahead */
2111+ if (usage == SWAP_HAS_CACHE ) {
21402112
21412113 /* set SWAP_HAS_CACHE if there is no cache and entry is used */
2142- if (!has_cache && count ) {
2143- p -> swap_map [offset ] = encode_swapmap (count , true);
2144- result = 0 ;
2145- } else if (has_cache ) /* someone added cache */
2146- result = - EEXIST ;
2147- else if (!count ) /* no users */
2148- result = - ENOENT ;
2114+ if (!has_cache && count )
2115+ has_cache = SWAP_HAS_CACHE ;
2116+ else if (has_cache ) /* someone else added cache */
2117+ err = - EEXIST ;
2118+ else /* no users remaining */
2119+ err = - ENOENT ;
21492120
21502121 } else if (count || has_cache ) {
2151- if (count < SWAP_MAP_MAX - 1 ) {
2152- p -> swap_map [offset ] = encode_swapmap (count + 1 ,
2153- has_cache );
2154- result = 0 ;
2155- } else if (count <= SWAP_MAP_MAX ) {
2122+
2123+ if (count < SWAP_MAP_MAX - 1 )
2124+ count ++ ;
2125+ else if (count <= SWAP_MAP_MAX ) {
21562126 if (swap_overflow ++ < 5 )
21572127 printk (KERN_WARNING
21582128 "swap_dup: swap entry overflow\n" );
2159- p -> swap_map [offset ] = encode_swapmap (SWAP_MAP_MAX ,
2160- has_cache );
2161- result = 0 ;
2162- }
2129+ count = SWAP_MAP_MAX ;
2130+ } else
2131+ err = - EINVAL ;
21632132 } else
2164- result = - ENOENT ; /* unused swap entry */
2133+ err = - ENOENT ; /* unused swap entry */
2134+
2135+ p -> swap_map [offset ] = count | has_cache ;
2136+
21652137unlock_out :
21662138 spin_unlock (& swap_lock );
21672139out :
2168- return result ;
2140+ return err ;
21692141
21702142bad_file :
21712143 printk (KERN_ERR "swap_dup: %s%08lx\n" , Bad_file , entry .val );
21722144 goto out ;
21732145}
2146+
21742147/*
21752148 * increase reference count of swap entry by 1.
21762149 */
21772150void swap_duplicate (swp_entry_t entry )
21782151{
2179- __swap_duplicate (entry , SWAP_MAP );
2152+ __swap_duplicate (entry , 1 );
21802153}
21812154
21822155/*
@@ -2189,7 +2162,7 @@ void swap_duplicate(swp_entry_t entry)
21892162 */
21902163int swapcache_prepare (swp_entry_t entry )
21912164{
2192- return __swap_duplicate (entry , SWAP_CACHE );
2165+ return __swap_duplicate (entry , SWAP_HAS_CACHE );
21932166}
21942167
21952168/*
0 commit comments