aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-03-14 18:10:10 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-03-14 18:10:10 -0400
commitf261c4e529dac5608a604d3dd3ae1cd2adf23c89 (patch)
tree5e73077db2d1bd0011531941c2cb4cd65aeab78a
parent3b319ee220a8795406852a897299dbdfc1b09911 (diff)
parenta4046c06be50a4f01d435aa7fe57514818e6cc82 (diff)
Merge branch 'akpm' (patches from Andrew)
Merge misc patches from Andrew Morton: - a little bit more MM - a few fixups [ The "little bit more MM" is actually just one of the three patches Andrew sent for mm/filemap.c, I'm still mulling over two more of them from Josef Bacik - Linus ] * emailed patches from Andrew Morton <akpm@linux-foundation.org>: include/linux/swap.h: use offsetof() instead of custom __swapoffset macro tools/testing/selftests/proc/proc-pid-vm.c: test with vsyscall in mind zram: default to lzo-rle instead of lzo filemap: pass vm_fault to the mmap ra helpers
-rw-r--r--drivers/block/zram/zram_drv.c2
-rw-r--r--include/linux/swap.h4
-rw-r--r--mm/filemap.c28
-rw-r--r--tools/testing/selftests/proc/proc-pid-vm.c49
4 files changed, 63 insertions, 20 deletions
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 04ca65912638..e7a5f1d1c314 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -41,7 +41,7 @@ static DEFINE_IDR(zram_index_idr);
41static DEFINE_MUTEX(zram_index_mutex); 41static DEFINE_MUTEX(zram_index_mutex);
42 42
43static int zram_major; 43static int zram_major;
44static const char *default_compressor = "lzo"; 44static const char *default_compressor = "lzo-rle";
45 45
46/* Module params (documentation at end) */ 46/* Module params (documentation at end) */
47static unsigned int num_devices = 1; 47static unsigned int num_devices = 1;
diff --git a/include/linux/swap.h b/include/linux/swap.h
index fc50e21b3b88..4bfb5c4ac108 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -157,9 +157,9 @@ struct swap_extent {
157/* 157/*
158 * Max bad pages in the new format.. 158 * Max bad pages in the new format..
159 */ 159 */
160#define __swapoffset(x) ((unsigned long)&((union swap_header *)0)->x)
161#define MAX_SWAP_BADPAGES \ 160#define MAX_SWAP_BADPAGES \
162 ((__swapoffset(magic.magic) - __swapoffset(info.badpages)) / sizeof(int)) 161 ((offsetof(union swap_header, magic.magic) - \
162 offsetof(union swap_header, info.badpages)) / sizeof(int))
163 163
164enum { 164enum {
165 SWP_USED = (1 << 0), /* is slot in swap_info[] used? */ 165 SWP_USED = (1 << 0), /* is slot in swap_info[] used? */
diff --git a/mm/filemap.c b/mm/filemap.c
index a3b4021c448f..ec6566ffbd90 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2420,20 +2420,20 @@ static int page_cache_read(struct file *file, pgoff_t offset, gfp_t gfp_mask)
2420 * Synchronous readahead happens when we don't even find 2420 * Synchronous readahead happens when we don't even find
2421 * a page in the page cache at all. 2421 * a page in the page cache at all.
2422 */ 2422 */
2423static void do_sync_mmap_readahead(struct vm_area_struct *vma, 2423static void do_sync_mmap_readahead(struct vm_fault *vmf)
2424 struct file_ra_state *ra,
2425 struct file *file,
2426 pgoff_t offset)
2427{ 2424{
2425 struct file *file = vmf->vma->vm_file;
2426 struct file_ra_state *ra = &file->f_ra;
2428 struct address_space *mapping = file->f_mapping; 2427 struct address_space *mapping = file->f_mapping;
2428 pgoff_t offset = vmf->pgoff;
2429 2429
2430 /* If we don't want any read-ahead, don't bother */ 2430 /* If we don't want any read-ahead, don't bother */
2431 if (vma->vm_flags & VM_RAND_READ) 2431 if (vmf->vma->vm_flags & VM_RAND_READ)
2432 return; 2432 return;
2433 if (!ra->ra_pages) 2433 if (!ra->ra_pages)
2434 return; 2434 return;
2435 2435
2436 if (vma->vm_flags & VM_SEQ_READ) { 2436 if (vmf->vma->vm_flags & VM_SEQ_READ) {
2437 page_cache_sync_readahead(mapping, ra, file, offset, 2437 page_cache_sync_readahead(mapping, ra, file, offset,
2438 ra->ra_pages); 2438 ra->ra_pages);
2439 return; 2439 return;
@@ -2463,16 +2463,16 @@ static void do_sync_mmap_readahead(struct vm_area_struct *vma,
2463 * Asynchronous readahead happens when we find the page and PG_readahead, 2463 * Asynchronous readahead happens when we find the page and PG_readahead,
2464 * so we want to possibly extend the readahead further.. 2464 * so we want to possibly extend the readahead further..
2465 */ 2465 */
2466static void do_async_mmap_readahead(struct vm_area_struct *vma, 2466static void do_async_mmap_readahead(struct vm_fault *vmf,
2467 struct file_ra_state *ra, 2467 struct page *page)
2468 struct file *file,
2469 struct page *page,
2470 pgoff_t offset)
2471{ 2468{
2469 struct file *file = vmf->vma->vm_file;
2470 struct file_ra_state *ra = &file->f_ra;
2472 struct address_space *mapping = file->f_mapping; 2471 struct address_space *mapping = file->f_mapping;
2472 pgoff_t offset = vmf->pgoff;
2473 2473
2474 /* If we don't want any read-ahead, don't bother */ 2474 /* If we don't want any read-ahead, don't bother */
2475 if (vma->vm_flags & VM_RAND_READ) 2475 if (vmf->vma->vm_flags & VM_RAND_READ)
2476 return; 2476 return;
2477 if (ra->mmap_miss > 0) 2477 if (ra->mmap_miss > 0)
2478 ra->mmap_miss--; 2478 ra->mmap_miss--;
@@ -2531,10 +2531,10 @@ vm_fault_t filemap_fault(struct vm_fault *vmf)
2531 * We found the page, so try async readahead before 2531 * We found the page, so try async readahead before
2532 * waiting for the lock. 2532 * waiting for the lock.
2533 */ 2533 */
2534 do_async_mmap_readahead(vmf->vma, ra, file, page, offset); 2534 do_async_mmap_readahead(vmf, page);
2535 } else if (!page) { 2535 } else if (!page) {
2536 /* No page in the page cache at all */ 2536 /* No page in the page cache at all */
2537 do_sync_mmap_readahead(vmf->vma, ra, file, offset); 2537 do_sync_mmap_readahead(vmf);
2538 count_vm_event(PGMAJFAULT); 2538 count_vm_event(PGMAJFAULT);
2539 count_memcg_event_mm(vmf->vma->vm_mm, PGMAJFAULT); 2539 count_memcg_event_mm(vmf->vma->vm_mm, PGMAJFAULT);
2540 ret = VM_FAULT_MAJOR; 2540 ret = VM_FAULT_MAJOR;
diff --git a/tools/testing/selftests/proc/proc-pid-vm.c b/tools/testing/selftests/proc/proc-pid-vm.c
index bbe8150d18aa..7202bbac976e 100644
--- a/tools/testing/selftests/proc/proc-pid-vm.c
+++ b/tools/testing/selftests/proc/proc-pid-vm.c
@@ -29,6 +29,7 @@
29#include <errno.h> 29#include <errno.h>
30#include <sched.h> 30#include <sched.h>
31#include <signal.h> 31#include <signal.h>
32#include <stdbool.h>
32#include <stdint.h> 33#include <stdint.h>
33#include <stdio.h> 34#include <stdio.h>
34#include <string.h> 35#include <string.h>
@@ -36,11 +37,14 @@
36#include <sys/mount.h> 37#include <sys/mount.h>
37#include <sys/types.h> 38#include <sys/types.h>
38#include <sys/stat.h> 39#include <sys/stat.h>
40#include <sys/wait.h>
39#include <fcntl.h> 41#include <fcntl.h>
40#include <unistd.h> 42#include <unistd.h>
41#include <sys/syscall.h> 43#include <sys/syscall.h>
42#include <sys/uio.h> 44#include <sys/uio.h>
43#include <linux/kdev_t.h> 45#include <linux/kdev_t.h>
46#include <sys/time.h>
47#include <sys/resource.h>
44 48
45static inline long sys_execveat(int dirfd, const char *pathname, char **argv, char **envp, int flags) 49static inline long sys_execveat(int dirfd, const char *pathname, char **argv, char **envp, int flags)
46{ 50{
@@ -205,12 +209,44 @@ static int make_exe(const uint8_t *payload, size_t len)
205} 209}
206#endif 210#endif
207 211
212static bool g_vsyscall = false;
213
214static const char str_vsyscall[] =
215"ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]\n";
216
208#ifdef __x86_64__ 217#ifdef __x86_64__
218/*
219 * vsyscall page can't be unmapped, probe it with memory load.
220 */
221static void vsyscall(void)
222{
223 pid_t pid;
224 int wstatus;
225
226 pid = fork();
227 if (pid < 0) {
228 fprintf(stderr, "fork, errno %d\n", errno);
229 exit(1);
230 }
231 if (pid == 0) {
232 struct rlimit rlim = {0, 0};
233 (void)setrlimit(RLIMIT_CORE, &rlim);
234 *(volatile int *)0xffffffffff600000UL;
235 exit(0);
236 }
237 wait(&wstatus);
238 if (WIFEXITED(wstatus)) {
239 g_vsyscall = true;
240 }
241}
242
209int main(void) 243int main(void)
210{ 244{
211 int pipefd[2]; 245 int pipefd[2];
212 int exec_fd; 246 int exec_fd;
213 247
248 vsyscall();
249
214 atexit(ate); 250 atexit(ate);
215 251
216 make_private_tmp(); 252 make_private_tmp();
@@ -261,9 +297,9 @@ int main(void)
261 snprintf(buf0 + MAPS_OFFSET, sizeof(buf0) - MAPS_OFFSET, 297 snprintf(buf0 + MAPS_OFFSET, sizeof(buf0) - MAPS_OFFSET,
262 "/tmp/#%llu (deleted)\n", (unsigned long long)st.st_ino); 298 "/tmp/#%llu (deleted)\n", (unsigned long long)st.st_ino);
263 299
264
265 /* Test /proc/$PID/maps */ 300 /* Test /proc/$PID/maps */
266 { 301 {
302 const size_t len = strlen(buf0) + (g_vsyscall ? strlen(str_vsyscall) : 0);
267 char buf[256]; 303 char buf[256];
268 ssize_t rv; 304 ssize_t rv;
269 int fd; 305 int fd;
@@ -274,13 +310,16 @@ int main(void)
274 return 1; 310 return 1;
275 } 311 }
276 rv = read(fd, buf, sizeof(buf)); 312 rv = read(fd, buf, sizeof(buf));
277 assert(rv == strlen(buf0)); 313 assert(rv == len);
278 assert(memcmp(buf, buf0, strlen(buf0)) == 0); 314 assert(memcmp(buf, buf0, strlen(buf0)) == 0);
315 if (g_vsyscall) {
316 assert(memcmp(buf + strlen(buf0), str_vsyscall, strlen(str_vsyscall)) == 0);
317 }
279 } 318 }
280 319
281 /* Test /proc/$PID/smaps */ 320 /* Test /proc/$PID/smaps */
282 { 321 {
283 char buf[1024]; 322 char buf[4096];
284 ssize_t rv; 323 ssize_t rv;
285 int fd; 324 int fd;
286 325
@@ -319,6 +358,10 @@ int main(void)
319 for (i = 0; i < sizeof(S)/sizeof(S[0]); i++) { 358 for (i = 0; i < sizeof(S)/sizeof(S[0]); i++) {
320 assert(memmem(buf, rv, S[i], strlen(S[i]))); 359 assert(memmem(buf, rv, S[i], strlen(S[i])));
321 } 360 }
361
362 if (g_vsyscall) {
363 assert(memmem(buf, rv, str_vsyscall, strlen(str_vsyscall)));
364 }
322 } 365 }
323 366
324 /* Test /proc/$PID/smaps_rollup */ 367 /* Test /proc/$PID/smaps_rollup */