Commit 8d69aaee80c123b460918816cbfa2e83224c3646

Authored by Hugh Dickins
Committed by Linus Torvalds
1 parent 253d553ba7

swap_info: swap_map of chars not shorts

Halve the vmalloc'ed swap_map array from unsigned shorts to unsigned
chars: it's still very unusual to reach a swap count of 126, and the
next patch allows it to be extended indefinitely.

Signed-off-by: Hugh Dickins <hugh.dickins@tiscali.co.uk>
Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Rik van Riel <riel@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 2 changed files with 27 additions and 21 deletions Side-by-side Diff

include/linux/swap.h
... ... @@ -151,9 +151,9 @@
151 151  
152 152 #define SWAP_CLUSTER_MAX 32
153 153  
154   -#define SWAP_MAP_MAX 0x7ffe
155   -#define SWAP_MAP_BAD 0x7fff
156   -#define SWAP_HAS_CACHE 0x8000 /* There is a swap cache of entry. */
  154 +#define SWAP_MAP_MAX 0x7e
  155 +#define SWAP_MAP_BAD 0x7f
  156 +#define SWAP_HAS_CACHE 0x80 /* There is a swap cache of entry. */
157 157  
158 158 /*
159 159 * The in-memory structure used to track swap areas.
... ... @@ -167,7 +167,7 @@
167 167 struct block_device *bdev;
168 168 struct swap_extent first_swap_extent;
169 169 struct swap_extent *curr_swap_extent;
170   - unsigned short *swap_map;
  170 + unsigned char *swap_map;
171 171 unsigned int lowest_bit;
172 172 unsigned int highest_bit;
173 173 unsigned int lowest_alloc; /* while preparing discard cluster */
... ... @@ -53,7 +53,7 @@
53 53  
54 54 static DEFINE_MUTEX(swapon_mutex);
55 55  
56   -static inline int swap_count(unsigned short ent)
  56 +static inline unsigned char swap_count(unsigned char ent)
57 57 {
58 58 return ent & ~SWAP_HAS_CACHE;
59 59 }
... ... @@ -203,7 +203,7 @@
203 203 #define LATENCY_LIMIT 256
204 204  
205 205 static inline unsigned long scan_swap_map(struct swap_info_struct *si,
206   - unsigned short usage)
  206 + unsigned char usage)
207 207 {
208 208 unsigned long offset;
209 209 unsigned long scan_base;
210 210  
... ... @@ -531,12 +531,12 @@
531 531 return NULL;
532 532 }
533 533  
534   -static unsigned short swap_entry_free(struct swap_info_struct *p,
535   - swp_entry_t entry, unsigned short usage)
  534 +static unsigned char swap_entry_free(struct swap_info_struct *p,
  535 + swp_entry_t entry, unsigned char usage)
536 536 {
537 537 unsigned long offset = swp_offset(entry);
538   - unsigned short count;
539   - unsigned short has_cache;
  538 + unsigned char count;
  539 + unsigned char has_cache;
540 540  
541 541 count = p->swap_map[offset];
542 542 has_cache = count & SWAP_HAS_CACHE;
... ... @@ -591,7 +591,7 @@
591 591 void swapcache_free(swp_entry_t entry, struct page *page)
592 592 {
593 593 struct swap_info_struct *p;
594   - unsigned short count;
  594 + unsigned char count;
595 595  
596 596 p = swap_info_get(entry);
597 597 if (p) {
... ... @@ -975,7 +975,7 @@
975 975 {
976 976 unsigned int max = si->max;
977 977 unsigned int i = prev;
978   - int count;
  978 + unsigned char count;
979 979  
980 980 /*
981 981 * No need for swap_lock here: we're just looking
... ... @@ -1013,8 +1013,8 @@
1013 1013 {
1014 1014 struct swap_info_struct *si = swap_info[type];
1015 1015 struct mm_struct *start_mm;
1016   - unsigned short *swap_map;
1017   - unsigned short swcount;
  1016 + unsigned char *swap_map;
  1017 + unsigned char swcount;
1018 1018 struct page *page;
1019 1019 swp_entry_t entry;
1020 1020 unsigned int i = 0;
... ... @@ -1174,6 +1174,12 @@
1174 1174 * If that's wrong, then we should worry more about
1175 1175 * exit_mmap() and do_munmap() cases described above:
1176 1176 * we might be resetting SWAP_MAP_MAX too early here.
  1177 + *
  1178 + * Yes, that's wrong: though very unlikely, swap count 0x7ffe
  1179 + * could surely occur if pid_max raised from PID_MAX_DEFAULT;
  1180 + * and we are now lowering SWAP_MAP_MAX to 0x7e, making it
  1181 + * much easier to reach. But the next patch will fix that.
  1182 + *
1177 1183 * We know "Undead"s can happen, they're okay, so don't
1178 1184 * report them; but do report if we reset SWAP_MAP_MAX.
1179 1185 */
... ... @@ -1492,7 +1498,7 @@
1492 1498 SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
1493 1499 {
1494 1500 struct swap_info_struct *p = NULL;
1495   - unsigned short *swap_map;
  1501 + unsigned char *swap_map;
1496 1502 struct file *swap_file, *victim;
1497 1503 struct address_space *mapping;
1498 1504 struct inode *inode;
... ... @@ -1762,7 +1768,7 @@
1762 1768 sector_t span;
1763 1769 unsigned long maxpages = 1;
1764 1770 unsigned long swapfilepages;
1765   - unsigned short *swap_map = NULL;
  1771 + unsigned char *swap_map = NULL;
1766 1772 struct page *page = NULL;
1767 1773 struct inode *inode = NULL;
1768 1774 int did_down = 0;
1769 1775  
... ... @@ -1938,13 +1944,13 @@
1938 1944 goto bad_swap;
1939 1945  
1940 1946 /* OK, set up the swap map and apply the bad block list */
1941   - swap_map = vmalloc(maxpages * sizeof(short));
  1947 + swap_map = vmalloc(maxpages);
1942 1948 if (!swap_map) {
1943 1949 error = -ENOMEM;
1944 1950 goto bad_swap;
1945 1951 }
1946 1952  
1947   - memset(swap_map, 0, maxpages * sizeof(short));
  1953 + memset(swap_map, 0, maxpages);
1948 1954 for (i = 0; i < swap_header->info.nr_badpages; i++) {
1949 1955 int page_nr = swap_header->info.badpages[i];
1950 1956 if (page_nr <= 0 || page_nr >= swap_header->info.last_page) {
1951 1957  
... ... @@ -2082,12 +2088,12 @@
2082 2088 * - swap-cache reference is requested but there is already one. -> EEXIST
2083 2089 * - swap-cache reference is requested but the entry is not used. -> ENOENT
2084 2090 */
2085   -static int __swap_duplicate(swp_entry_t entry, unsigned short usage)
  2091 +static int __swap_duplicate(swp_entry_t entry, unsigned char usage)
2086 2092 {
2087 2093 struct swap_info_struct *p;
2088 2094 unsigned long offset, type;
2089   - unsigned short count;
2090   - unsigned short has_cache;
  2095 + unsigned char count;
  2096 + unsigned char has_cache;
2091 2097 int err = -EINVAL;
2092 2098  
2093 2099 if (non_swap_entry(entry))