Commit f261c4e5 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 3b319ee2 a4046c06
...@@ -41,7 +41,7 @@ static DEFINE_IDR(zram_index_idr); ...@@ -41,7 +41,7 @@ static DEFINE_IDR(zram_index_idr);
static DEFINE_MUTEX(zram_index_mutex); static DEFINE_MUTEX(zram_index_mutex);
static int zram_major; static int zram_major;
static const char *default_compressor = "lzo"; static const char *default_compressor = "lzo-rle";
/* Module params (documentation at end) */ /* Module params (documentation at end) */
static unsigned int num_devices = 1; static unsigned int num_devices = 1;
......
...@@ -157,9 +157,9 @@ struct swap_extent { ...@@ -157,9 +157,9 @@ struct swap_extent {
/* /*
* Max bad pages in the new format.. * Max bad pages in the new format..
*/ */
#define __swapoffset(x) ((unsigned long)&((union swap_header *)0)->x)
#define MAX_SWAP_BADPAGES \ #define MAX_SWAP_BADPAGES \
((__swapoffset(magic.magic) - __swapoffset(info.badpages)) / sizeof(int)) ((offsetof(union swap_header, magic.magic) - \
offsetof(union swap_header, info.badpages)) / sizeof(int))
enum { enum {
SWP_USED = (1 << 0), /* is slot in swap_info[] used? */ SWP_USED = (1 << 0), /* is slot in swap_info[] used? */
......
...@@ -2420,20 +2420,20 @@ static int page_cache_read(struct file *file, pgoff_t offset, gfp_t gfp_mask) ...@@ -2420,20 +2420,20 @@ static int page_cache_read(struct file *file, pgoff_t offset, gfp_t gfp_mask)
* Synchronous readahead happens when we don't even find * Synchronous readahead happens when we don't even find
* a page in the page cache at all. * a page in the page cache at all.
*/ */
static void do_sync_mmap_readahead(struct vm_area_struct *vma, static void do_sync_mmap_readahead(struct vm_fault *vmf)
struct file_ra_state *ra,
struct file *file,
pgoff_t offset)
{ {
struct file *file = vmf->vma->vm_file;
struct file_ra_state *ra = &file->f_ra;
struct address_space *mapping = file->f_mapping; struct address_space *mapping = file->f_mapping;
pgoff_t offset = vmf->pgoff;
/* If we don't want any read-ahead, don't bother */ /* If we don't want any read-ahead, don't bother */
if (vma->vm_flags & VM_RAND_READ) if (vmf->vma->vm_flags & VM_RAND_READ)
return; return;
if (!ra->ra_pages) if (!ra->ra_pages)
return; return;
if (vma->vm_flags & VM_SEQ_READ) { if (vmf->vma->vm_flags & VM_SEQ_READ) {
page_cache_sync_readahead(mapping, ra, file, offset, page_cache_sync_readahead(mapping, ra, file, offset,
ra->ra_pages); ra->ra_pages);
return; return;
...@@ -2463,16 +2463,16 @@ static void do_sync_mmap_readahead(struct vm_area_struct *vma, ...@@ -2463,16 +2463,16 @@ static void do_sync_mmap_readahead(struct vm_area_struct *vma,
* Asynchronous readahead happens when we find the page and PG_readahead, * Asynchronous readahead happens when we find the page and PG_readahead,
* so we want to possibly extend the readahead further.. * so we want to possibly extend the readahead further..
*/ */
static void do_async_mmap_readahead(struct vm_area_struct *vma, static void do_async_mmap_readahead(struct vm_fault *vmf,
struct file_ra_state *ra, struct page *page)
struct file *file,
struct page *page,
pgoff_t offset)
{ {
struct file *file = vmf->vma->vm_file;
struct file_ra_state *ra = &file->f_ra;
struct address_space *mapping = file->f_mapping; struct address_space *mapping = file->f_mapping;
pgoff_t offset = vmf->pgoff;
/* If we don't want any read-ahead, don't bother */ /* If we don't want any read-ahead, don't bother */
if (vma->vm_flags & VM_RAND_READ) if (vmf->vma->vm_flags & VM_RAND_READ)
return; return;
if (ra->mmap_miss > 0) if (ra->mmap_miss > 0)
ra->mmap_miss--; ra->mmap_miss--;
...@@ -2531,10 +2531,10 @@ vm_fault_t filemap_fault(struct vm_fault *vmf) ...@@ -2531,10 +2531,10 @@ vm_fault_t filemap_fault(struct vm_fault *vmf)
* We found the page, so try async readahead before * We found the page, so try async readahead before
* waiting for the lock. * waiting for the lock.
*/ */
do_async_mmap_readahead(vmf->vma, ra, file, page, offset); do_async_mmap_readahead(vmf, page);
} else if (!page) { } else if (!page) {
/* No page in the page cache at all */ /* No page in the page cache at all */
do_sync_mmap_readahead(vmf->vma, ra, file, offset); do_sync_mmap_readahead(vmf);
count_vm_event(PGMAJFAULT); count_vm_event(PGMAJFAULT);
count_memcg_event_mm(vmf->vma->vm_mm, PGMAJFAULT); count_memcg_event_mm(vmf->vma->vm_mm, PGMAJFAULT);
ret = VM_FAULT_MAJOR; ret = VM_FAULT_MAJOR;
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <errno.h> #include <errno.h>
#include <sched.h> #include <sched.h>
#include <signal.h> #include <signal.h>
#include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
...@@ -36,11 +37,14 @@ ...@@ -36,11 +37,14 @@
#include <sys/mount.h> #include <sys/mount.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <sys/syscall.h> #include <sys/syscall.h>
#include <sys/uio.h> #include <sys/uio.h>
#include <linux/kdev_t.h> #include <linux/kdev_t.h>
#include <sys/time.h>
#include <sys/resource.h>
static inline long sys_execveat(int dirfd, const char *pathname, char **argv, char **envp, int flags) static inline long sys_execveat(int dirfd, const char *pathname, char **argv, char **envp, int flags)
{ {
...@@ -205,12 +209,44 @@ static int make_exe(const uint8_t *payload, size_t len) ...@@ -205,12 +209,44 @@ static int make_exe(const uint8_t *payload, size_t len)
} }
#endif #endif
static bool g_vsyscall = false;
static const char str_vsyscall[] =
"ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]\n";
#ifdef __x86_64__ #ifdef __x86_64__
/*
* vsyscall page can't be unmapped, probe it with memory load.
*/
static void vsyscall(void)
{
pid_t pid;
int wstatus;
pid = fork();
if (pid < 0) {
fprintf(stderr, "fork, errno %d\n", errno);
exit(1);
}
if (pid == 0) {
struct rlimit rlim = {0, 0};
(void)setrlimit(RLIMIT_CORE, &rlim);
*(volatile int *)0xffffffffff600000UL;
exit(0);
}
wait(&wstatus);
if (WIFEXITED(wstatus)) {
g_vsyscall = true;
}
}
int main(void) int main(void)
{ {
int pipefd[2]; int pipefd[2];
int exec_fd; int exec_fd;
vsyscall();
atexit(ate); atexit(ate);
make_private_tmp(); make_private_tmp();
...@@ -261,9 +297,9 @@ int main(void) ...@@ -261,9 +297,9 @@ int main(void)
snprintf(buf0 + MAPS_OFFSET, sizeof(buf0) - MAPS_OFFSET, snprintf(buf0 + MAPS_OFFSET, sizeof(buf0) - MAPS_OFFSET,
"/tmp/#%llu (deleted)\n", (unsigned long long)st.st_ino); "/tmp/#%llu (deleted)\n", (unsigned long long)st.st_ino);
/* Test /proc/$PID/maps */ /* Test /proc/$PID/maps */
{ {
const size_t len = strlen(buf0) + (g_vsyscall ? strlen(str_vsyscall) : 0);
char buf[256]; char buf[256];
ssize_t rv; ssize_t rv;
int fd; int fd;
...@@ -274,13 +310,16 @@ int main(void) ...@@ -274,13 +310,16 @@ int main(void)
return 1; return 1;
} }
rv = read(fd, buf, sizeof(buf)); rv = read(fd, buf, sizeof(buf));
assert(rv == strlen(buf0)); assert(rv == len);
assert(memcmp(buf, buf0, strlen(buf0)) == 0); assert(memcmp(buf, buf0, strlen(buf0)) == 0);
if (g_vsyscall) {
assert(memcmp(buf + strlen(buf0), str_vsyscall, strlen(str_vsyscall)) == 0);
}
} }
/* Test /proc/$PID/smaps */ /* Test /proc/$PID/smaps */
{ {
char buf[1024]; char buf[4096];
ssize_t rv; ssize_t rv;
int fd; int fd;
...@@ -319,6 +358,10 @@ int main(void) ...@@ -319,6 +358,10 @@ int main(void)
for (i = 0; i < sizeof(S)/sizeof(S[0]); i++) { for (i = 0; i < sizeof(S)/sizeof(S[0]); i++) {
assert(memmem(buf, rv, S[i], strlen(S[i]))); assert(memmem(buf, rv, S[i], strlen(S[i])));
} }
if (g_vsyscall) {
assert(memmem(buf, rv, str_vsyscall, strlen(str_vsyscall)));
}
} }
/* Test /proc/$PID/smaps_rollup */ /* Test /proc/$PID/smaps_rollup */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment