Commit 19788a90 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'akpm' (patches from Andrew Morton)

Merge more patches from Andrew Morton:
 "A bunch of fixes.

  Plus Joe's printk move and rework.  It's not a -rc3 thing but now
  would be a nice time to offload it, while things are quiet.  I've been
  sitting on it all for a couple of weeks, no issues"

* emailed patches from Andrew Morton <akpm@linux-foundation.org>:
  vmpressure: make sure there are no events queued after memcg is offlined
  vmpressure: do not check for pending work to prevent from new work
  vmpressure: change vmpressure::sr_lock to spinlock
  printk: rename struct log to struct printk_log
  printk: use pointer for console_cmdline indexing
  printk: move braille console support into separate braille.[ch] files
  printk: add console_cmdline.h
  printk: move to separate directory for easier modification
  drivers/rtc/rtc-twl.c: fix: rtcX/wakealarm attribute isn't created
  mm: zbud: fix condition check on allocation size
  thp, mm: avoid PageUnevictable on active/inactive lru lists
  mm/swap.c: clear PageActive before adding pages onto unevictable list
  arch/x86/platform/ce4100/ce4100.c: include reboot.h
  mm: sched: numa: fix NUMA balancing when !SCHED_DEBUG
  rapidio: fix use after free in rio_unregister_scan()
  .gitignore: ignore *.lz4 files
  MAINTAINERS: dynamic debug: Jason's not there...
  dmi_scan: add comments on dmi_present() and the loop in dmi_scan_machine()
  ocfs2/refcounttree: add the missing NULL check of the return value of find_or_create_page()
  mm: mempolicy: fix mbind_range() && vma_adjust() interaction
parents 06693f30 33cb876e
...@@ -29,6 +29,7 @@ modules.builtin ...@@ -29,6 +29,7 @@ modules.builtin
*.bz2 *.bz2
*.lzma *.lzma
*.xz *.xz
*.lz4
*.lzo *.lzo
*.patch *.patch
*.gcno *.gcno
......
...@@ -84,7 +84,7 @@ X!Iinclude/linux/kobject.h ...@@ -84,7 +84,7 @@ X!Iinclude/linux/kobject.h
<sect1><title>Kernel utility functions</title> <sect1><title>Kernel utility functions</title>
!Iinclude/linux/kernel.h !Iinclude/linux/kernel.h
!Ekernel/printk.c !Ekernel/printk/printk.c
!Ekernel/panic.c !Ekernel/panic.c
!Ekernel/sys.c !Ekernel/sys.c
!Ekernel/rcupdate.c !Ekernel/rcupdate.c
......
...@@ -2871,7 +2871,7 @@ F: drivers/media/usb/dvb-usb-v2/dvb_usb* ...@@ -2871,7 +2871,7 @@ F: drivers/media/usb/dvb-usb-v2/dvb_usb*
F: drivers/media/usb/dvb-usb-v2/usb_urb.c F: drivers/media/usb/dvb-usb-v2/usb_urb.c
DYNAMIC DEBUG DYNAMIC DEBUG
M: Jason Baron <jbaron@redhat.com> M: Jason Baron <jbaron@akamai.com>
S: Maintained S: Maintained
F: lib/dynamic_debug.c F: lib/dynamic_debug.c
F: include/linux/dynamic_debug.h F: include/linux/dynamic_debug.h
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/reboot.h>
#include <linux/serial_reg.h> #include <linux/serial_reg.h>
#include <linux/serial_8250.h> #include <linux/serial_8250.h>
#include <linux/reboot.h> #include <linux/reboot.h>
......
...@@ -359,6 +359,9 @@ int braille_register_console(struct console *console, int index, ...@@ -359,6 +359,9 @@ int braille_register_console(struct console *console, int index,
char *console_options, char *braille_options) char *console_options, char *braille_options)
{ {
int ret; int ret;
if (!(console->flags & CON_BRL))
return 0;
if (!console_options) if (!console_options)
/* Only support VisioBraille for now */ /* Only support VisioBraille for now */
console_options = "57600o8"; console_options = "57600o8";
...@@ -374,15 +377,17 @@ int braille_register_console(struct console *console, int index, ...@@ -374,15 +377,17 @@ int braille_register_console(struct console *console, int index,
braille_co = console; braille_co = console;
register_keyboard_notifier(&keyboard_notifier_block); register_keyboard_notifier(&keyboard_notifier_block);
register_vt_notifier(&vt_notifier_block); register_vt_notifier(&vt_notifier_block);
return 0; return 1;
} }
int braille_unregister_console(struct console *console) int braille_unregister_console(struct console *console)
{ {
if (braille_co != console) if (braille_co != console)
return -EINVAL; return -EINVAL;
if (!(console->flags & CON_BRL))
return 0;
unregister_keyboard_notifier(&keyboard_notifier_block); unregister_keyboard_notifier(&keyboard_notifier_block);
unregister_vt_notifier(&vt_notifier_block); unregister_vt_notifier(&vt_notifier_block);
braille_co = NULL; braille_co = NULL;
return 0; return 1;
} }
...@@ -419,6 +419,13 @@ static void __init dmi_format_ids(char *buf, size_t len) ...@@ -419,6 +419,13 @@ static void __init dmi_format_ids(char *buf, size_t len)
dmi_get_system_info(DMI_BIOS_DATE)); dmi_get_system_info(DMI_BIOS_DATE));
} }
/*
* Check for DMI/SMBIOS headers in the system firmware image. Any
* SMBIOS header must start 16 bytes before the DMI header, so take a
* 32 byte buffer and check for DMI at offset 16 and SMBIOS at offset
* 0. If the DMI header is present, set dmi_ver accordingly (SMBIOS
* takes precedence) and return 0. Otherwise return 1.
*/
static int __init dmi_present(const u8 *buf) static int __init dmi_present(const u8 *buf)
{ {
int smbios_ver; int smbios_ver;
...@@ -506,6 +513,13 @@ void __init dmi_scan_machine(void) ...@@ -506,6 +513,13 @@ void __init dmi_scan_machine(void)
if (p == NULL) if (p == NULL)
goto error; goto error;
/*
* Iterate over all possible DMI header addresses q.
* Maintain the 32 bytes around q in buf. On the
* first iteration, substitute zero for the
* out-of-range bytes so there is no chance of falsely
* detecting an SMBIOS header.
*/
memset(buf, 0, 16); memset(buf, 0, 16);
for (q = p; q < p + 0x10000; q += 16) { for (q = p; q < p + 0x10000; q += 16) {
memcpy_fromio(buf + 16, q, 16); memcpy_fromio(buf + 16, q, 16);
......
...@@ -1715,11 +1715,13 @@ int rio_unregister_scan(int mport_id, struct rio_scan *scan_ops) ...@@ -1715,11 +1715,13 @@ int rio_unregister_scan(int mport_id, struct rio_scan *scan_ops)
(mport_id == RIO_MPORT_ANY && port->nscan == scan_ops)) (mport_id == RIO_MPORT_ANY && port->nscan == scan_ops))
port->nscan = NULL; port->nscan = NULL;
list_for_each_entry(scan, &rio_scans, node) list_for_each_entry(scan, &rio_scans, node) {
if (scan->mport_id == mport_id) { if (scan->mport_id == mport_id) {
list_del(&scan->node); list_del(&scan->node);
kfree(scan); kfree(scan);
break;
} }
}
mutex_unlock(&rio_mport_list_lock); mutex_unlock(&rio_mport_list_lock);
......
...@@ -524,6 +524,8 @@ static int twl_rtc_probe(struct platform_device *pdev) ...@@ -524,6 +524,8 @@ static int twl_rtc_probe(struct platform_device *pdev)
if (ret < 0) if (ret < 0)
goto out1; goto out1;
device_init_wakeup(&pdev->dev, 1);
rtc = rtc_device_register(pdev->name, rtc = rtc_device_register(pdev->name,
&pdev->dev, &twl_rtc_ops, THIS_MODULE); &pdev->dev, &twl_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc)) { if (IS_ERR(rtc)) {
...@@ -542,7 +544,6 @@ static int twl_rtc_probe(struct platform_device *pdev) ...@@ -542,7 +544,6 @@ static int twl_rtc_probe(struct platform_device *pdev)
} }
platform_set_drvdata(pdev, rtc); platform_set_drvdata(pdev, rtc);
device_init_wakeup(&pdev->dev, 1);
return 0; return 0;
out2: out2:
......
...@@ -2965,6 +2965,11 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle, ...@@ -2965,6 +2965,11 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle,
to = map_end & (PAGE_CACHE_SIZE - 1); to = map_end & (PAGE_CACHE_SIZE - 1);
page = find_or_create_page(mapping, page_index, GFP_NOFS); page = find_or_create_page(mapping, page_index, GFP_NOFS);
if (!page) {
ret = -ENOMEM;
mlog_errno(ret);
break;
}
/* /*
* In case PAGE_CACHE_SIZE <= CLUSTER_SIZE, This page * In case PAGE_CACHE_SIZE <= CLUSTER_SIZE, This page
......
...@@ -12,7 +12,7 @@ struct vmpressure { ...@@ -12,7 +12,7 @@ struct vmpressure {
unsigned long scanned; unsigned long scanned;
unsigned long reclaimed; unsigned long reclaimed;
/* The lock is used to keep the scanned/reclaimed above in sync. */ /* The lock is used to keep the scanned/reclaimed above in sync. */
struct mutex sr_lock; struct spinlock sr_lock;
/* The list of vmpressure_event structs. */ /* The list of vmpressure_event structs. */
struct list_head events; struct list_head events;
...@@ -30,6 +30,7 @@ extern void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, ...@@ -30,6 +30,7 @@ extern void vmpressure(gfp_t gfp, struct mem_cgroup *memcg,
extern void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, int prio); extern void vmpressure_prio(gfp_t gfp, struct mem_cgroup *memcg, int prio);
extern void vmpressure_init(struct vmpressure *vmpr); extern void vmpressure_init(struct vmpressure *vmpr);
extern void vmpressure_cleanup(struct vmpressure *vmpr);
extern struct vmpressure *memcg_to_vmpressure(struct mem_cgroup *memcg); extern struct vmpressure *memcg_to_vmpressure(struct mem_cgroup *memcg);
extern struct cgroup_subsys_state *vmpressure_to_css(struct vmpressure *vmpr); extern struct cgroup_subsys_state *vmpressure_to_css(struct vmpressure *vmpr);
extern struct vmpressure *css_to_vmpressure(struct cgroup_subsys_state *css); extern struct vmpressure *css_to_vmpressure(struct cgroup_subsys_state *css);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Makefile for the linux kernel. # Makefile for the linux kernel.
# #
obj-y = fork.o exec_domain.o panic.o printk.o \ obj-y = fork.o exec_domain.o panic.o \
cpu.o exit.o itimer.o time.o softirq.o resource.o \ cpu.o exit.o itimer.o time.o softirq.o resource.o \
sysctl.o sysctl_binary.o capability.o ptrace.o timer.o user.o \ sysctl.o sysctl_binary.o capability.o ptrace.o timer.o user.o \
signal.o sys.o kmod.o workqueue.o pid.o task_work.o \ signal.o sys.o kmod.o workqueue.o pid.o task_work.o \
...@@ -24,6 +24,7 @@ endif ...@@ -24,6 +24,7 @@ endif
obj-y += sched/ obj-y += sched/
obj-y += power/ obj-y += power/
obj-y += printk/
obj-y += cpu/ obj-y += cpu/
obj-$(CONFIG_CHECKPOINT_RESTORE) += kcmp.o obj-$(CONFIG_CHECKPOINT_RESTORE) += kcmp.o
......
obj-y = printk.o
obj-$(CONFIG_A11Y_BRAILLE_CONSOLE) += braille.o
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
#include <linux/console.h>
#include <linux/string.h>
#include "console_cmdline.h"
#include "braille.h"
char *_braille_console_setup(char **str, char **brl_options)
{
if (!memcmp(*str, "brl,", 4)) {
*brl_options = "";
*str += 4;
} else if (!memcmp(str, "brl=", 4)) {
*brl_options = *str + 4;
*str = strchr(*brl_options, ',');
if (!*str)
pr_err("need port name after brl=\n");
else
*((*str)++) = 0;
}
return *str;
}
int
_braille_register_console(struct console *console, struct console_cmdline *c)
{
int rtn = 0;
if (c->brl_options) {
console->flags |= CON_BRL;
rtn = braille_register_console(console, c->index, c->options,
c->brl_options);
}
return rtn;
}
int
_braille_unregister_console(struct console *console)
{
if (console->flags & CON_BRL)
return braille_unregister_console(console);
return 0;
}
#ifndef _PRINTK_BRAILLE_H
#define _PRINTK_BRAILLE_H
#ifdef CONFIG_A11Y_BRAILLE_CONSOLE
static inline void
braille_set_options(struct console_cmdline *c, char *brl_options)
{
c->brl_options = brl_options;
}
char *
_braille_console_setup(char **str, char **brl_options);
int
_braille_register_console(struct console *console, struct console_cmdline *c);
int
_braille_unregister_console(struct console *console);
#else
static inline void
braille_set_options(struct console_cmdline *c, char *brl_options)
{
}
static inline char *
_braille_console_setup(char **str, char **brl_options)
{
return NULL;
}
static inline int
_braille_register_console(struct console *console, struct console_cmdline *c)
{
return 0;
}
static inline int
_braille_unregister_console(struct console *console)
{
return 0;
}
#endif
#endif
#ifndef _CONSOLE_CMDLINE_H
#define _CONSOLE_CMDLINE_H
struct console_cmdline
{
char name[8]; /* Name of the driver */
int index; /* Minor dev. to use */
char *options; /* Options for the driver */
#ifdef CONFIG_A11Y_BRAILLE_CONSOLE
char *brl_options; /* Options for braille driver */
#endif
};
#endif
...@@ -51,6 +51,9 @@ ...@@ -51,6 +51,9 @@
#define CREATE_TRACE_POINTS #define CREATE_TRACE_POINTS
#include <trace/events/printk.h> #include <trace/events/printk.h>
#include "console_cmdline.h"
#include "braille.h"
/* printk's without a loglevel use this.. */ /* printk's without a loglevel use this.. */
#define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL #define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL
...@@ -105,19 +108,11 @@ static struct console *exclusive_console; ...@@ -105,19 +108,11 @@ static struct console *exclusive_console;
/* /*
* Array of consoles built from command line options (console=) * Array of consoles built from command line options (console=)
*/ */
struct console_cmdline
{
char name[8]; /* Name of the driver */
int index; /* Minor dev. to use */
char *options; /* Options for the driver */
#ifdef CONFIG_A11Y_BRAILLE_CONSOLE
char *brl_options; /* Options for braille driver */
#endif
};
#define MAX_CMDLINECONSOLES 8 #define MAX_CMDLINECONSOLES 8
static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES]; static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
static int selected_console = -1; static int selected_console = -1;
static int preferred_console = -1; static int preferred_console = -1;
int console_set_on_cmdline; int console_set_on_cmdline;
...@@ -178,7 +173,7 @@ static int console_may_schedule; ...@@ -178,7 +173,7 @@ static int console_may_schedule;
* 67 "g" * 67 "g"
* 0032 00 00 00 padding to next message header * 0032 00 00 00 padding to next message header
* *
* The 'struct log' buffer header must never be directly exported to * The 'struct printk_log' buffer header must never be directly exported to
* userspace, it is a kernel-private implementation detail that might * userspace, it is a kernel-private implementation detail that might
* need to be changed in the future, when the requirements change. * need to be changed in the future, when the requirements change.
* *
...@@ -200,7 +195,7 @@ enum log_flags { ...@@ -200,7 +195,7 @@ enum log_flags {
LOG_CONT = 8, /* text is a fragment of a continuation line */ LOG_CONT = 8, /* text is a fragment of a continuation line */
}; };
struct log { struct printk_log {
u64 ts_nsec; /* timestamp in nanoseconds */ u64 ts_nsec; /* timestamp in nanoseconds */
u16 len; /* length of entire record */ u16 len; /* length of entire record */
u16 text_len; /* length of text buffer */ u16 text_len; /* length of text buffer */
...@@ -248,7 +243,7 @@ static u32 clear_idx; ...@@ -248,7 +243,7 @@ static u32 clear_idx;
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
#define LOG_ALIGN 4 #define LOG_ALIGN 4
#else #else
#define LOG_ALIGN __alignof__(struct log) #define LOG_ALIGN __alignof__(struct printk_log)
#endif #endif
#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT) #define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN); static char __log_buf[__LOG_BUF_LEN] __aligned(LOG_ALIGN);
...@@ -259,35 +254,35 @@ static u32 log_buf_len = __LOG_BUF_LEN; ...@@ -259,35 +254,35 @@ static u32 log_buf_len = __LOG_BUF_LEN;
static volatile unsigned int logbuf_cpu = UINT_MAX; static volatile unsigned int logbuf_cpu = UINT_MAX;
/* human readable text of the record */ /* human readable text of the record */
static char *log_text(const struct log *msg) static char *log_text(const struct printk_log *msg)
{ {
return (char *)msg + sizeof(struct log); return (char *)msg + sizeof(struct printk_log);
} }
/* optional key/value pair dictionary attached to the record */ /* optional key/value pair dictionary attached to the record */
static char *log_dict(const struct log *msg) static char *log_dict(const struct printk_log *msg)
{ {
return (char *)msg + sizeof(struct log) + msg->text_len; return (char *)msg + sizeof(struct printk_log) + msg->text_len;
} }
/* get record by index; idx must point to valid msg */ /* get record by index; idx must point to valid msg */
static struct log *log_from_idx(u32 idx) static struct printk_log *log_from_idx(u32 idx)
{ {
struct log *msg = (struct log *)(log_buf + idx); struct printk_log *msg = (struct printk_log *)(log_buf + idx);
/* /*
* A length == 0 record is the end of buffer marker. Wrap around and * A length == 0 record is the end of buffer marker. Wrap around and
* read the message at the start of the buffer. * read the message at the start of the buffer.
*/ */
if (!msg->len) if (!msg->len)
return (struct log *)log_buf; return (struct printk_log *)log_buf;
return msg; return msg;
} }
/* get next record; idx must point to valid msg */ /* get next record; idx must point to valid msg */
static u32 log_next(u32 idx) static u32 log_next(u32 idx)
{ {
struct log *msg = (struct log *)(log_buf + idx); struct printk_log *msg = (struct printk_log *)(log_buf + idx);
/* length == 0 indicates the end of the buffer; wrap */ /* length == 0 indicates the end of the buffer; wrap */
/* /*
...@@ -296,7 +291,7 @@ static u32 log_next(u32 idx) ...@@ -296,7 +291,7 @@ static u32 log_next(u32 idx)
* return the one after that. * return the one after that.
*/ */
if (!msg->len) { if (!msg->len) {
msg = (struct log *)log_buf; msg = (struct printk_log *)log_buf;
return msg->len; return msg->len;
} }
return idx + msg->len; return idx + msg->len;
...@@ -308,11 +303,11 @@ static void log_store(int facility, int level, ...@@ -308,11 +303,11 @@ static void log_store(int facility, int level,
const char *dict, u16 dict_len, const char *dict, u16 dict_len,
const char *text, u16 text_len) const char *text, u16 text_len)
{ {
struct log *msg; struct printk_log *msg;
u32 size, pad_len; u32 size, pad_len;
/* number of '\0' padding bytes to next message */ /* number of '\0' padding bytes to next message */
size = sizeof(struct log) + text_len + dict_len; size = sizeof(struct printk_log) + text_len + dict_len;
pad_len = (-size) & (LOG_ALIGN - 1); pad_len = (-size) & (LOG_ALIGN - 1);
size += pad_len; size += pad_len;
...@@ -324,7 +319,7 @@ static void log_store(int facility, int level, ...@@ -324,7 +319,7 @@ static void log_store(int facility, int level,
else else
free = log_first_idx - log_next_idx; free = log_first_idx - log_next_idx;
if (free > size + sizeof(struct log)) if (free > size + sizeof(struct printk_log))
break; break;
/* drop old messages until we have enough contiuous space */ /* drop old messages until we have enough contiuous space */
...@@ -332,18 +327,18 @@ static void log_store(int facility, int level, ...@@ -332,18 +327,18 @@ static void log_store(int facility, int level,
log_first_seq++; log_first_seq++;
} }
if (log_next_idx + size + sizeof(struct log) >= log_buf_len) { if (log_next_idx + size + sizeof(struct printk_log) >= log_buf_len) {
/* /*
* This message + an additional empty header does not fit * This message + an additional empty header does not fit
* at the end of the buffer. Add an empty header with len == 0 * at the end of the buffer. Add an empty header with len == 0
* to signify a wrap around. * to signify a wrap around.
*/ */
memset(log_buf + log_next_idx, 0, sizeof(struct log)); memset(log_buf + log_next_idx, 0, sizeof(struct printk_log));
log_next_idx = 0; log_next_idx = 0;
} }
/* fill message */ /* fill message */
msg = (struct log *)(log_buf + log_next_idx); msg = (struct printk_log *)(log_buf + log_next_idx);
memcpy(log_text(msg), text, text_len); memcpy(log_text(msg), text, text_len);
msg->text_len = text_len; msg->text_len = text_len;
memcpy(log_dict(msg), dict, dict_len); memcpy(log_dict(msg), dict, dict_len);
...@@ -356,7 +351,7 @@ static void log_store(int facility, int level, ...@@ -356,7 +351,7 @@ static void log_store(int facility, int level,
else else
msg->ts_nsec = local_clock(); msg->ts_nsec = local_clock();
memset(log_dict(msg) + dict_len, 0, pad_len); memset(log_dict(msg) + dict_len, 0, pad_len);
msg->len = sizeof(struct log) + text_len + dict_len + pad_len; msg->len = sizeof(struct printk_log) + text_len + dict_len + pad_len;
/* insert message */ /* insert message */
log_next_idx += msg->len; log_next_idx += msg->len;
...@@ -479,7 +474,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf, ...@@ -479,7 +474,7 @@ static ssize_t devkmsg_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct devkmsg_user *user = file->private_data; struct devkmsg_user *user = file->private_data;
struct log *msg; struct printk_log *msg;
u64 ts_usec; u64 ts_usec;
size_t i; size_t i;
char cont = '-'; char cont = '-';
...@@ -724,14 +719,14 @@ void log_buf_kexec_setup(void) ...@@ -724,14 +719,14 @@ void log_buf_kexec_setup(void)
VMCOREINFO_SYMBOL(log_first_idx); VMCOREINFO_SYMBOL(log_first_idx);
VMCOREINFO_SYMBOL(log_next_idx); VMCOREINFO_SYMBOL(log_next_idx);
/* /*
* Export struct log size and field offsets. User space tools can * Export struct printk_log size and field offsets. User space tools can
* parse it and detect any changes to structure down the line. * parse it and detect any changes to structure down the line.
*/ */
VMCOREINFO_STRUCT_SIZE(log); VMCOREINFO_STRUCT_SIZE(printk_log);
VMCOREINFO_OFFSET(log, ts_nsec); VMCOREINFO_OFFSET(printk_log, ts_nsec);
VMCOREINFO_OFFSET(log, len); VMCOREINFO_OFFSET(printk_log, len);
VMCOREINFO_OFFSET(log, text_len); VMCOREINFO_OFFSET(printk_log, text_len);
VMCOREINFO_OFFSET(log, dict_len); VMCOREINFO_OFFSET(printk_log, dict_len);
} }
#endif #endif
...@@ -884,7 +879,7 @@ static size_t print_time(u64 ts, char *buf) ...@@ -884,7 +879,7 @@ static size_t print_time(u64 ts, char *buf)
(unsigned long)ts, rem_nsec / 1000); (unsigned long)ts, rem_nsec / 1000);
} }
static size_t print_prefix(const struct log *msg, bool syslog, char *buf) static size_t print_prefix(const struct printk_log *msg, bool syslog, char *buf)
{ {
size_t len = 0; size_t len = 0;
unsigned int prefix = (msg->facility << 3) | msg->level; unsigned int prefix = (msg->facility << 3) | msg->level;
...@@ -907,7 +902,7 @@ static size_t print_prefix(const struct log *msg, bool syslog, char *buf) ...@@ -907,7 +902,7 @@ static size_t print_prefix(const struct log *msg, bool syslog, char *buf)
return len; return len;
} }
static size_t msg_print_text(const struct log *msg, enum log_flags prev, static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev,
bool syslog, char *buf, size_t size) bool syslog, char *buf, size_t size)
{ {
const char *text = log_text(msg); const char *text = log_text(msg);
...@@ -969,7 +964,7 @@ static size_t msg_print_text(const struct log *msg, enum log_flags prev, ...@@ -969,7 +964,7 @@ static size_t msg_print_text(const struct log *msg, enum log_flags prev,
static int syslog_print(char __user *buf, int size) static int syslog_print(char __user *buf, int size)
{ {
char *text; char *text;
struct log *msg; struct printk_log *msg;
int len = 0; int len = 0;
text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL); text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL);
...@@ -1060,7 +1055,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear) ...@@ -1060,7 +1055,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
idx = clear_idx; idx = clear_idx;
prev = 0; prev = 0;
while (seq < log_next_seq) { while (seq < log_next_seq) {
struct log *msg = log_from_idx(idx); struct printk_log *msg = log_from_idx(idx);
len += msg_print_text(msg, prev, true, NULL, 0); len += msg_print_text(msg, prev, true, NULL, 0);
prev = msg->flags; prev = msg->flags;
...@@ -1073,7 +1068,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear) ...@@ -1073,7 +1068,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
idx = clear_idx; idx = clear_idx;
prev = 0; prev = 0;
while (len > size && seq < log_next_seq) { while (len > size && seq < log_next_seq) {
struct log *msg = log_from_idx(idx); struct printk_log *msg = log_from_idx(idx);
len -= msg_print_text(msg, prev, true, NULL, 0); len -= msg_print_text(msg, prev, true, NULL, 0);
prev = msg->flags; prev = msg->flags;
...@@ -1087,7 +1082,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear) ...@@ -1087,7 +1082,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
len = 0; len = 0;
prev = 0; prev = 0;
while (len >= 0 && seq < next_seq) { while (len >= 0 && seq < next_seq) {
struct log *msg = log_from_idx(idx); struct printk_log *msg = log_from_idx(idx);
int textlen; int textlen;
textlen = msg_print_text(msg, prev, true, text, textlen = msg_print_text(msg, prev, true, text,
...@@ -1233,7 +1228,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file) ...@@ -1233,7 +1228,7 @@ int do_syslog(int type, char __user *buf, int len, bool from_file)
error = 0; error = 0;
while (seq < log_next_seq) { while (seq < log_next_seq) {
struct log *msg = log_from_idx(idx); struct printk_log *msg = log_from_idx(idx);
error += msg_print_text(msg, prev, true, NULL, 0); error += msg_print_text(msg, prev, true, NULL, 0);
idx = log_next(idx); idx = log_next(idx);
...@@ -1719,10 +1714,10 @@ static struct cont { ...@@ -1719,10 +1714,10 @@ static struct cont {
u8 level; u8 level;
bool flushed:1; bool flushed:1;
} cont; } cont;
static struct log *log_from_idx(u32 idx) { return NULL; } static struct printk_log *log_from_idx(u32 idx) { return NULL; }
static u32 log_next(u32 idx) { return 0; } static u32 log_next(u32 idx) { return 0; }
static void call_console_drivers(int level, const char *text, size_t len) {} static void call_console_drivers(int level, const char *text, size_t len) {}
static size_t msg_print_text(const struct log *msg, enum log_flags prev, static size_t msg_print_text(const struct printk_log *msg, enum log_flags prev,
bool syslog, char *buf, size_t size) { return 0; } bool syslog, char *buf, size_t size) { return 0; }
static size_t cont_print_text(char *text, size_t size) { return 0; } static size_t cont_print_text(char *text, size_t size) { return 0; }
...@@ -1761,23 +1756,23 @@ static int __add_preferred_console(char *name, int idx, char *options, ...@@ -1761,23 +1756,23 @@ static int __add_preferred_console(char *name, int idx, char *options,
* See if this tty is not yet registered, and * See if this tty is not yet registered, and
* if we have a slot free. * if we have a slot free.
*/ */
for (i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++) for (i = 0, c = console_cmdline;
if (strcmp(console_cmdline[i].name, name) == 0 && i < MAX_CMDLINECONSOLES && c->name[0];
console_cmdline[i].index == idx) { i++, c++) {
if (!brl_options) if (strcmp(c->name, name) == 0 && c->index == idx) {
selected_console = i; if (!brl_options)
return 0; selected_console = i;
return 0;
} }
}
if (i == MAX_CMDLINECONSOLES) if (i == MAX_CMDLINECONSOLES)
return -E2BIG; return -E2BIG;
if (!brl_options) if (!brl_options)
selected_console = i; selected_console = i;
c = &console_cmdline[i];
strlcpy(c->name, name, sizeof(c->name)); strlcpy(c->name, name, sizeof(c->name));
c->options = options; c->options = options;
#ifdef CONFIG_A11Y_BRAILLE_CONSOLE braille_set_options(c, brl_options);
c->brl_options = brl_options;
#endif
c->index = idx; c->index = idx;
return 0; return 0;
} }
...@@ -1790,20 +1785,8 @@ static int __init console_setup(char *str) ...@@ -1790,20 +1785,8 @@ static int __init console_setup(char *str)
char *s, *options, *brl_options = NULL; char *s, *options, *brl_options = NULL;
int idx; int idx;
#ifdef CONFIG_A11Y_BRAILLE_CONSOLE if (_braille_console_setup(&str, &brl_options))
if (!memcmp(str, "brl,", 4)) { return 1;
brl_options = "";
str += 4;
} else if (!memcmp(str, "brl=", 4)) {
brl_options = str + 4;
str = strchr(brl_options, ',');
if (!str) {
printk(KERN_ERR "need port name after brl=\n");
return 1;
}
*(str++) = 0;
}
#endif
/* /*
* Decode str into name, index, options. * Decode str into name, index, options.
...@@ -1858,15 +1841,15 @@ int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, cha ...@@ -1858,15 +1841,15 @@ int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, cha
struct console_cmdline *c; struct console_cmdline *c;
int i; int i;
for (i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++) for (i = 0, c = console_cmdline;
if (strcmp(console_cmdline[i].name, name) == 0 && i < MAX_CMDLINECONSOLES && c->name[0];
console_cmdline[i].index == idx) { i++, c++)
c = &console_cmdline[i]; if (strcmp(c->name, name) == 0 && c->index == idx) {
strlcpy(c->name, name_new, sizeof(c->name)); strlcpy(c->name, name_new, sizeof(c->name));
c->name[sizeof(c->name) - 1] = 0; c->name[sizeof(c->name) - 1] = 0;
c->options = options; c->options = options;
c->index = idx_new; c->index = idx_new;
return i; return i;
} }
/* not found */ /* not found */
return -1; return -1;
...@@ -2046,7 +2029,7 @@ void console_unlock(void) ...@@ -2046,7 +2029,7 @@ void console_unlock(void)
console_cont_flush(text, sizeof(text)); console_cont_flush(text, sizeof(text));
again: again:
for (;;) { for (;;) {
struct log *msg; struct printk_log *msg;
size_t len; size_t len;
int level; int level;
...@@ -2241,6 +2224,7 @@ void register_console(struct console *newcon) ...@@ -2241,6 +2224,7 @@ void register_console(struct console *newcon)
int i; int i;
unsigned long flags; unsigned long flags;
struct console *bcon = NULL; struct console *bcon = NULL;
struct console_cmdline *c;
/* /*
* before we register a new CON_BOOT console, make sure we don't * before we register a new CON_BOOT console, make sure we don't
...@@ -2288,30 +2272,25 @@ void register_console(struct console *newcon) ...@@ -2288,30 +2272,25 @@ void register_console(struct console *newcon)
* See if this console matches one we selected on * See if this console matches one we selected on
* the command line. * the command line.
*/ */
for (i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; for (i = 0, c = console_cmdline;
i++) { i < MAX_CMDLINECONSOLES && c->name[0];
if (strcmp(console_cmdline[i].name, newcon->name) != 0) i++, c++) {
if (strcmp(c->name, newcon->name) != 0)
continue; continue;
if (newcon->index >= 0 && if (newcon->index >= 0 &&
newcon->index != console_cmdline[i].index) newcon->index != c->index)
continue; continue;
if (newcon->index < 0) if (newcon->index < 0)
newcon->index = console_cmdline[i].index; newcon->index = c->index;
#ifdef CONFIG_A11Y_BRAILLE_CONSOLE
if (console_cmdline[i].brl_options) { if (_braille_register_console(newcon, c))
newcon->flags |= CON_BRL;
braille_register_console(newcon,
console_cmdline[i].index,
console_cmdline[i].options,
console_cmdline[i].brl_options);
return; return;
}
#endif
if (newcon->setup && if (newcon->setup &&
newcon->setup(newcon, console_cmdline[i].options) != 0) newcon->setup(newcon, console_cmdline[i].options) != 0)
break; break;
newcon->flags |= CON_ENABLED; newcon->flags |= CON_ENABLED;
newcon->index = console_cmdline[i].index; newcon->index = c->index;
if (i == selected_console) { if (i == selected_console) {
newcon->flags |= CON_CONSDEV; newcon->flags |= CON_CONSDEV;
preferred_console = selected_console; preferred_console = selected_console;
...@@ -2394,13 +2373,13 @@ EXPORT_SYMBOL(register_console); ...@@ -2394,13 +2373,13 @@ EXPORT_SYMBOL(register_console);
int unregister_console(struct console *console) int unregister_console(struct console *console)
{ {
struct console *a, *b; struct console *a, *b;
int res = 1; int res;
#ifdef CONFIG_A11Y_BRAILLE_CONSOLE res = _braille_unregister_console(console);
if (console->flags & CON_BRL) if (res)
return braille_unregister_console(console); return res;
#endif
res = 1;
console_lock(); console_lock();
if (console_drivers == console) { if (console_drivers == console) {
console_drivers=console->next; console_drivers=console->next;
...@@ -2666,7 +2645,7 @@ void kmsg_dump(enum kmsg_dump_reason reason) ...@@ -2666,7 +2645,7 @@ void kmsg_dump(enum kmsg_dump_reason reason)
bool kmsg_dump_get_line_nolock(struct kmsg_dumper *dumper, bool syslog, bool kmsg_dump_get_line_nolock(struct kmsg_dumper *dumper, bool syslog,
char *line, size_t size, size_t *len) char *line, size_t size, size_t *len)
{ {
struct log *msg; struct printk_log *msg;
size_t l = 0; size_t l = 0;
bool ret = false; bool ret = false;
...@@ -2778,7 +2757,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, ...@@ -2778,7 +2757,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
idx = dumper->cur_idx; idx = dumper->cur_idx;
prev = 0; prev = 0;
while (seq < dumper->next_seq) { while (seq < dumper->next_seq) {
struct log *msg = log_from_idx(idx); struct printk_log *msg = log_from_idx(idx);
l += msg_print_text(msg, prev, true, NULL, 0); l += msg_print_text(msg, prev, true, NULL, 0);
idx = log_next(idx); idx = log_next(idx);
...@@ -2791,7 +2770,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, ...@@ -2791,7 +2770,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
idx = dumper->cur_idx; idx = dumper->cur_idx;
prev = 0; prev = 0;
while (l > size && seq < dumper->next_seq) { while (l > size && seq < dumper->next_seq) {
struct log *msg = log_from_idx(idx); struct printk_log *msg = log_from_idx(idx);
l -= msg_print_text(msg, prev, true, NULL, 0); l -= msg_print_text(msg, prev, true, NULL, 0);
idx = log_next(idx); idx = log_next(idx);
...@@ -2806,7 +2785,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, ...@@ -2806,7 +2785,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog,
l = 0; l = 0;
prev = 0; prev = 0;
while (seq < dumper->next_seq) { while (seq < dumper->next_seq) {
struct log *msg = log_from_idx(idx); struct printk_log *msg = log_from_idx(idx);
l += msg_print_text(msg, prev, syslog, buf + l, size - l); l += msg_print_text(msg, prev, syslog, buf + l, size - l);
idx = log_next(idx); idx = log_next(idx);
......
...@@ -851,7 +851,7 @@ void task_numa_fault(int node, int pages, bool migrated) ...@@ -851,7 +851,7 @@ void task_numa_fault(int node, int pages, bool migrated)
{ {
struct task_struct *p = current; struct task_struct *p = current;
if (!sched_feat_numa(NUMA)) if (!numabalancing_enabled)
return; return;
/* FIXME: Allocate task-specific structure for placement policy here */ /* FIXME: Allocate task-specific structure for placement policy here */
...@@ -5786,7 +5786,7 @@ static void task_tick_fair(struct rq *rq, struct task_struct *curr, int queued) ...@@ -5786,7 +5786,7 @@ static void task_tick_fair(struct rq *rq, struct task_struct *curr, int queued)
entity_tick(cfs_rq, se, queued); entity_tick(cfs_rq, se, queued);
} }
if (sched_feat_numa(NUMA)) if (numabalancing_enabled)
task_tick_numa(rq, curr); task_tick_numa(rq, curr);
update_rq_runnable_avg(rq, 1); update_rq_runnable_avg(rq, 1);
......
...@@ -1620,7 +1620,9 @@ static void __split_huge_page_refcount(struct page *page, ...@@ -1620,7 +1620,9 @@ static void __split_huge_page_refcount(struct page *page,
((1L << PG_referenced) | ((1L << PG_referenced) |
(1L << PG_swapbacked) | (1L << PG_swapbacked) |
(1L << PG_mlocked) | (1L << PG_mlocked) |
(1L << PG_uptodate))); (1L << PG_uptodate) |
(1L << PG_active) |
(1L << PG_unevictable)));
page_tail->flags |= (1L << PG_dirty); page_tail->flags |= (1L << PG_dirty);
/* clear PageTail before overwriting first_page */ /* clear PageTail before overwriting first_page */
......
...@@ -6335,6 +6335,7 @@ static void mem_cgroup_css_offline(struct cgroup *cont) ...@@ -6335,6 +6335,7 @@ static void mem_cgroup_css_offline(struct cgroup *cont)
mem_cgroup_invalidate_reclaim_iterators(memcg); mem_cgroup_invalidate_reclaim_iterators(memcg);
mem_cgroup_reparent_charges(memcg); mem_cgroup_reparent_charges(memcg);
mem_cgroup_destroy_all_caches(memcg); mem_cgroup_destroy_all_caches(memcg);
vmpressure_cleanup(&memcg->vmpressure);
} }
static void mem_cgroup_css_free(struct cgroup *cont) static void mem_cgroup_css_free(struct cgroup *cont)
......
...@@ -732,7 +732,10 @@ static int mbind_range(struct mm_struct *mm, unsigned long start, ...@@ -732,7 +732,10 @@ static int mbind_range(struct mm_struct *mm, unsigned long start,
if (prev) { if (prev) {
vma = prev; vma = prev;
next = vma->vm_next; next = vma->vm_next;
continue; if (mpol_equal(vma_policy(vma), new_pol))
continue;
/* vma_merge() joined vma && vma->next, case 8 */
goto replace;
} }
if (vma->vm_start != vmstart) { if (vma->vm_start != vmstart) {
err = split_vma(vma->vm_mm, vma, vmstart, 1); err = split_vma(vma->vm_mm, vma, vmstart, 1);
...@@ -744,6 +747,7 @@ static int mbind_range(struct mm_struct *mm, unsigned long start, ...@@ -744,6 +747,7 @@ static int mbind_range(struct mm_struct *mm, unsigned long start,
if (err) if (err)
goto out; goto out;
} }
replace:
err = vma_replace_policy(vma, new_pol); err = vma_replace_policy(vma, new_pol);
if (err) if (err)
goto out; goto out;
......
...@@ -865,7 +865,7 @@ again: remove_next = 1 + (end > next->vm_end); ...@@ -865,7 +865,7 @@ again: remove_next = 1 + (end > next->vm_end);
if (next->anon_vma) if (next->anon_vma)
anon_vma_merge(vma, next); anon_vma_merge(vma, next);
mm->map_count--; mm->map_count--;
vma_set_policy(vma, vma_policy(next)); mpol_put(vma_policy(next));
kmem_cache_free(vm_area_cachep, next); kmem_cache_free(vm_area_cachep, next);
/* /*
* In mprotect's case 6 (see comments on vma_merge), * In mprotect's case 6 (see comments on vma_merge),
......
...@@ -512,12 +512,7 @@ EXPORT_SYMBOL(__lru_cache_add); ...@@ -512,12 +512,7 @@ EXPORT_SYMBOL(__lru_cache_add);
*/ */
void lru_cache_add(struct page *page) void lru_cache_add(struct page *page)
{ {
if (PageActive(page)) { VM_BUG_ON(PageActive(page) && PageUnevictable(page));
VM_BUG_ON(PageUnevictable(page));
} else if (PageUnevictable(page)) {
VM_BUG_ON(PageActive(page));
}
VM_BUG_ON(PageLRU(page)); VM_BUG_ON(PageLRU(page));
__lru_cache_add(page); __lru_cache_add(page);
} }
...@@ -539,6 +534,7 @@ void add_page_to_unevictable_list(struct page *page) ...@@ -539,6 +534,7 @@ void add_page_to_unevictable_list(struct page *page)
spin_lock_irq(&zone->lru_lock); spin_lock_irq(&zone->lru_lock);
lruvec = mem_cgroup_page_lruvec(page, zone); lruvec = mem_cgroup_page_lruvec(page, zone);
ClearPageActive(page);
SetPageUnevictable(page); SetPageUnevictable(page);
SetPageLRU(page); SetPageLRU(page);
add_page_to_lru_list(page, lruvec, LRU_UNEVICTABLE); add_page_to_lru_list(page, lruvec, LRU_UNEVICTABLE);
...@@ -774,8 +770,6 @@ EXPORT_SYMBOL(__pagevec_release); ...@@ -774,8 +770,6 @@ EXPORT_SYMBOL(__pagevec_release);
void lru_add_page_tail(struct page *page, struct page *page_tail, void lru_add_page_tail(struct page *page, struct page *page_tail,
struct lruvec *lruvec, struct list_head *list) struct lruvec *lruvec, struct list_head *list)
{ {
int uninitialized_var(active);
enum lru_list lru;
const int file = 0; const int file = 0;
VM_BUG_ON(!PageHead(page)); VM_BUG_ON(!PageHead(page));
...@@ -787,20 +781,6 @@ void lru_add_page_tail(struct page *page, struct page *page_tail, ...@@ -787,20 +781,6 @@ void lru_add_page_tail(struct page *page, struct page *page_tail,
if (!list) if (!list)
SetPageLRU(page_tail); SetPageLRU(page_tail);
if (page_evictable(page_tail)) {
if (PageActive(page)) {
SetPageActive(page_tail);
active = 1;
lru = LRU_ACTIVE_ANON;
} else {
active = 0;
lru = LRU_INACTIVE_ANON;
}
} else {
SetPageUnevictable(page_tail);
lru = LRU_UNEVICTABLE;
}
if (likely(PageLRU(page))) if (likely(PageLRU(page)))
list_add_tail(&page_tail->lru, &page->lru); list_add_tail(&page_tail->lru, &page->lru);
else if (list) { else if (list) {
...@@ -816,13 +796,13 @@ void lru_add_page_tail(struct page *page, struct page *page_tail, ...@@ -816,13 +796,13 @@ void lru_add_page_tail(struct page *page, struct page *page_tail,
* Use the standard add function to put page_tail on the list, * Use the standard add function to put page_tail on the list,
* but then correct its position so they all end up in order. * but then correct its position so they all end up in order.
*/ */
add_page_to_lru_list(page_tail, lruvec, lru); add_page_to_lru_list(page_tail, lruvec, page_lru(page_tail));
list_head = page_tail->lru.prev; list_head = page_tail->lru.prev;
list_move_tail(&page_tail->lru, list_head); list_move_tail(&page_tail->lru, list_head);
} }
if (!PageUnevictable(page)) if (!PageUnevictable(page))
update_page_reclaim_stat(lruvec, file, active); update_page_reclaim_stat(lruvec, file, PageActive(page_tail));
} }
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */ #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
...@@ -833,7 +813,6 @@ static void __pagevec_lru_add_fn(struct page *page, struct lruvec *lruvec, ...@@ -833,7 +813,6 @@ static void __pagevec_lru_add_fn(struct page *page, struct lruvec *lruvec,
int active = PageActive(page); int active = PageActive(page);
enum lru_list lru = page_lru(page); enum lru_list lru = page_lru(page);
VM_BUG_ON(PageUnevictable(page));
VM_BUG_ON(PageLRU(page)); VM_BUG_ON(PageLRU(page));
SetPageLRU(page); SetPageLRU(page);
......
...@@ -180,12 +180,12 @@ static void vmpressure_work_fn(struct work_struct *work) ...@@ -180,12 +180,12 @@ static void vmpressure_work_fn(struct work_struct *work)
if (!vmpr->scanned) if (!vmpr->scanned)
return; return;
mutex_lock(&vmpr->sr_lock); spin_lock(&vmpr->sr_lock);
scanned = vmpr->scanned; scanned = vmpr->scanned;
reclaimed = vmpr->reclaimed; reclaimed = vmpr->reclaimed;
vmpr->scanned = 0; vmpr->scanned = 0;
vmpr->reclaimed = 0; vmpr->reclaimed = 0;
mutex_unlock(&vmpr->sr_lock); spin_unlock(&vmpr->sr_lock);
do { do {
if (vmpressure_event(vmpr, scanned, reclaimed)) if (vmpressure_event(vmpr, scanned, reclaimed))
...@@ -240,13 +240,13 @@ void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, ...@@ -240,13 +240,13 @@ void vmpressure(gfp_t gfp, struct mem_cgroup *memcg,
if (!scanned) if (!scanned)
return; return;
mutex_lock(&vmpr->sr_lock); spin_lock(&vmpr->sr_lock);
vmpr->scanned += scanned; vmpr->scanned += scanned;
vmpr->reclaimed += reclaimed; vmpr->reclaimed += reclaimed;
scanned = vmpr->scanned; scanned = vmpr->scanned;
mutex_unlock(&vmpr->sr_lock); spin_unlock(&vmpr->sr_lock);
if (scanned < vmpressure_win || work_pending(&vmpr->work)) if (scanned < vmpressure_win)
return; return;
schedule_work(&vmpr->work); schedule_work(&vmpr->work);
} }
...@@ -367,8 +367,24 @@ void vmpressure_unregister_event(struct cgroup *cg, struct cftype *cft, ...@@ -367,8 +367,24 @@ void vmpressure_unregister_event(struct cgroup *cg, struct cftype *cft,
*/ */
void vmpressure_init(struct vmpressure *vmpr) void vmpressure_init(struct vmpressure *vmpr)
{ {
mutex_init(&vmpr->sr_lock); spin_lock_init(&vmpr->sr_lock);
mutex_init(&vmpr->events_lock); mutex_init(&vmpr->events_lock);
INIT_LIST_HEAD(&vmpr->events); INIT_LIST_HEAD(&vmpr->events);
INIT_WORK(&vmpr->work, vmpressure_work_fn); INIT_WORK(&vmpr->work, vmpressure_work_fn);
} }
/**
* vmpressure_cleanup() - shuts down vmpressure control structure
* @vmpr: Structure to be cleaned up
*
* This function should be called before the structure in which it is
* embedded is cleaned up.
*/
void vmpressure_cleanup(struct vmpressure *vmpr)
{
/*
* Make sure there is no pending work before eventfd infrastructure
* goes away.
*/
flush_work(&vmpr->work);
}
...@@ -257,7 +257,7 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp, ...@@ -257,7 +257,7 @@ int zbud_alloc(struct zbud_pool *pool, int size, gfp_t gfp,
if (size <= 0 || gfp & __GFP_HIGHMEM) if (size <= 0 || gfp & __GFP_HIGHMEM)
return -EINVAL; return -EINVAL;
if (size > PAGE_SIZE - ZHDR_SIZE_ALIGNED) if (size > PAGE_SIZE - ZHDR_SIZE_ALIGNED - CHUNK_SIZE)
return -ENOSPC; return -ENOSPC;
chunks = size_to_chunks(size); chunks = size_to_chunks(size);
spin_lock(&pool->lock); spin_lock(&pool->lock);
......
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