Skip to content

Commit 253d553

Browse files
Hugh Dickinstorvalds
authored andcommitted
swap_info: SWAP_HAS_CACHE cleanups
Though swap_count() is useful, I'm finding that swap_has_cache() and encode_swapmap() obscure what happens in the swap_map entry, just at those points where I need to understand it. Remove them, and pass more usable "usage" values to scan_swap_map(), swap_entry_free() and __swap_duplicate(), instead of the SWAP_MAP and SWAP_CACHE enum. Signed-off-by: Hugh Dickins <[email protected]> Reviewed-by: KAMEZAWA Hiroyuki <[email protected]> Cc: Rik van Riel <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 73c34b6 commit 253d553

File tree

2 files changed

+65
-92
lines changed

2 files changed

+65
-92
lines changed

include/linux/swap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ enum {
154154
#define SWAP_MAP_MAX 0x7ffe
155155
#define SWAP_MAP_BAD 0x7fff
156156
#define SWAP_HAS_CACHE 0x8000 /* There is a swap cache of entry. */
157-
#define SWAP_COUNT_MASK (~SWAP_HAS_CACHE)
157+
158158
/*
159159
* The in-memory structure used to track swap areas.
160160
*/

mm/swapfile.c

Lines changed: 64 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -53,30 +53,9 @@ static struct swap_info_struct *swap_info[MAX_SWAPFILES];
5353

5454
static 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-
6356
static 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

226205
static 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)
614591
void 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+
21652137
unlock_out:
21662138
spin_unlock(&swap_lock);
21672139
out:
2168-
return result;
2140+
return err;
21692141

21702142
bad_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
*/
21772150
void 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
*/
21902163
int 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

Comments
 (0)