Commit 0839c537 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'akpm' (patches from Andrew)

Merge misc fixes from Andrew Morton:
 "15 fixes"

* emailed patches from Andrew Morton <akpm@linux-foundation.org>:
  linux/kernel.h: fix overflow for DIV_ROUND_UP_ULL
  mm, swap: fix THP swap out
  fork,memcg: alloc_thread_stack_node needs to set tsk->stack
  MAINTAINERS: add CLANG/LLVM BUILD SUPPORT info
  mm/vmalloc.c: avoid bogus -Wmaybe-uninitialized warning
  mm/page_idle.c: fix oops because end_pfn is larger than max_pfn
  initramfs: fix populate_initrd_image() section mismatch
  mm/oom_kill.c: fix uninitialized oc->constraint
  mm: hugetlb: soft-offline: dissolve_free_huge_page() return zero on !PageHuge
  mm: soft-offline: return -EBUSY if set_hwpoison_free_buddy_page() fails
  signal: remove the wrong signal_pending() check in restore_user_sigmask()
  fs/binfmt_flat.c: make load_flat_shared_library() work
  mm/mempolicy.c: fix an incorrect rebind node in mpol_rebind_nodemask
  fs/proc/array.c: allow reporting eip/esp for all coredumping threads
  mm/dev_pfn: exclude MEMORY_DEVICE_PRIVATE while computing virtual address
parents f8b5c722 8f9fab48
...@@ -3942,6 +3942,14 @@ M: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com> ...@@ -3942,6 +3942,14 @@ M: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>
S: Maintained S: Maintained
F: .clang-format F: .clang-format
CLANG/LLVM BUILD SUPPORT
L: clang-built-linux@googlegroups.com
W: https://clangbuiltlinux.github.io/
B: https://github.com/ClangBuiltLinux/linux/issues
C: irc://chat.freenode.net/clangbuiltlinux
S: Supported
K: \b(?i:clang|llvm)\b
CLEANCACHE API CLEANCACHE API
M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
L: linux-kernel@vger.kernel.org L: linux-kernel@vger.kernel.org
......
...@@ -2095,6 +2095,7 @@ SYSCALL_DEFINE6(io_pgetevents, ...@@ -2095,6 +2095,7 @@ SYSCALL_DEFINE6(io_pgetevents,
struct __aio_sigset ksig = { NULL, }; struct __aio_sigset ksig = { NULL, };
sigset_t ksigmask, sigsaved; sigset_t ksigmask, sigsaved;
struct timespec64 ts; struct timespec64 ts;
bool interrupted;
int ret; int ret;
if (timeout && unlikely(get_timespec64(&ts, timeout))) if (timeout && unlikely(get_timespec64(&ts, timeout)))
...@@ -2108,8 +2109,10 @@ SYSCALL_DEFINE6(io_pgetevents, ...@@ -2108,8 +2109,10 @@ SYSCALL_DEFINE6(io_pgetevents,
return ret; return ret;
ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL); ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL);
restore_user_sigmask(ksig.sigmask, &sigsaved);
if (signal_pending(current) && !ret) interrupted = signal_pending(current);
restore_user_sigmask(ksig.sigmask, &sigsaved, interrupted);
if (interrupted && !ret)
ret = -ERESTARTNOHAND; ret = -ERESTARTNOHAND;
return ret; return ret;
...@@ -2128,6 +2131,7 @@ SYSCALL_DEFINE6(io_pgetevents_time32, ...@@ -2128,6 +2131,7 @@ SYSCALL_DEFINE6(io_pgetevents_time32,
struct __aio_sigset ksig = { NULL, }; struct __aio_sigset ksig = { NULL, };
sigset_t ksigmask, sigsaved; sigset_t ksigmask, sigsaved;
struct timespec64 ts; struct timespec64 ts;
bool interrupted;
int ret; int ret;
if (timeout && unlikely(get_old_timespec32(&ts, timeout))) if (timeout && unlikely(get_old_timespec32(&ts, timeout)))
...@@ -2142,8 +2146,10 @@ SYSCALL_DEFINE6(io_pgetevents_time32, ...@@ -2142,8 +2146,10 @@ SYSCALL_DEFINE6(io_pgetevents_time32,
return ret; return ret;
ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL); ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL);
restore_user_sigmask(ksig.sigmask, &sigsaved);
if (signal_pending(current) && !ret) interrupted = signal_pending(current);
restore_user_sigmask(ksig.sigmask, &sigsaved, interrupted);
if (interrupted && !ret)
ret = -ERESTARTNOHAND; ret = -ERESTARTNOHAND;
return ret; return ret;
...@@ -2193,6 +2199,7 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents, ...@@ -2193,6 +2199,7 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents,
struct __compat_aio_sigset ksig = { NULL, }; struct __compat_aio_sigset ksig = { NULL, };
sigset_t ksigmask, sigsaved; sigset_t ksigmask, sigsaved;
struct timespec64 t; struct timespec64 t;
bool interrupted;
int ret; int ret;
if (timeout && get_old_timespec32(&t, timeout)) if (timeout && get_old_timespec32(&t, timeout))
...@@ -2206,8 +2213,10 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents, ...@@ -2206,8 +2213,10 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents,
return ret; return ret;
ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL); ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL);
restore_user_sigmask(ksig.sigmask, &sigsaved);
if (signal_pending(current) && !ret) interrupted = signal_pending(current);
restore_user_sigmask(ksig.sigmask, &sigsaved, interrupted);
if (interrupted && !ret)
ret = -ERESTARTNOHAND; ret = -ERESTARTNOHAND;
return ret; return ret;
...@@ -2226,6 +2235,7 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64, ...@@ -2226,6 +2235,7 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64,
struct __compat_aio_sigset ksig = { NULL, }; struct __compat_aio_sigset ksig = { NULL, };
sigset_t ksigmask, sigsaved; sigset_t ksigmask, sigsaved;
struct timespec64 t; struct timespec64 t;
bool interrupted;
int ret; int ret;
if (timeout && get_timespec64(&t, timeout)) if (timeout && get_timespec64(&t, timeout))
...@@ -2239,8 +2249,10 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64, ...@@ -2239,8 +2249,10 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64,
return ret; return ret;
ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL); ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL);
restore_user_sigmask(ksig.sigmask, &sigsaved);
if (signal_pending(current) && !ret) interrupted = signal_pending(current);
restore_user_sigmask(ksig.sigmask, &sigsaved, interrupted);
if (interrupted && !ret)
ret = -ERESTARTNOHAND; ret = -ERESTARTNOHAND;
return ret; return ret;
......
...@@ -856,9 +856,14 @@ static int load_flat_file(struct linux_binprm *bprm, ...@@ -856,9 +856,14 @@ static int load_flat_file(struct linux_binprm *bprm,
static int load_flat_shared_library(int id, struct lib_info *libs) static int load_flat_shared_library(int id, struct lib_info *libs)
{ {
/*
* This is a fake bprm struct; only the members "buf", "file" and
* "filename" are actually used.
*/
struct linux_binprm bprm; struct linux_binprm bprm;
int res; int res;
char buf[16]; char buf[16];
loff_t pos = 0;
memset(&bprm, 0, sizeof(bprm)); memset(&bprm, 0, sizeof(bprm));
...@@ -872,25 +877,11 @@ static int load_flat_shared_library(int id, struct lib_info *libs) ...@@ -872,25 +877,11 @@ static int load_flat_shared_library(int id, struct lib_info *libs)
if (IS_ERR(bprm.file)) if (IS_ERR(bprm.file))
return res; return res;
bprm.cred = prepare_exec_creds(); res = kernel_read(bprm.file, bprm.buf, BINPRM_BUF_SIZE, &pos);
res = -ENOMEM;
if (!bprm.cred)
goto out;
/* We don't really care about recalculating credentials at this point
* as we're past the point of no return and are dealing with shared
* libraries.
*/
bprm.called_set_creds = 1;
res = prepare_binprm(&bprm); if (res >= 0)
if (!res)
res = load_flat_file(&bprm, libs, id, NULL); res = load_flat_file(&bprm, libs, id, NULL);
abort_creds(bprm.cred);
out:
allow_write_access(bprm.file); allow_write_access(bprm.file);
fput(bprm.file); fput(bprm.file);
......
...@@ -2325,7 +2325,7 @@ SYSCALL_DEFINE6(epoll_pwait, int, epfd, struct epoll_event __user *, events, ...@@ -2325,7 +2325,7 @@ SYSCALL_DEFINE6(epoll_pwait, int, epfd, struct epoll_event __user *, events,
error = do_epoll_wait(epfd, events, maxevents, timeout); error = do_epoll_wait(epfd, events, maxevents, timeout);
restore_user_sigmask(sigmask, &sigsaved); restore_user_sigmask(sigmask, &sigsaved, error == -EINTR);
return error; return error;
} }
...@@ -2350,7 +2350,7 @@ COMPAT_SYSCALL_DEFINE6(epoll_pwait, int, epfd, ...@@ -2350,7 +2350,7 @@ COMPAT_SYSCALL_DEFINE6(epoll_pwait, int, epfd,
err = do_epoll_wait(epfd, events, maxevents, timeout); err = do_epoll_wait(epfd, events, maxevents, timeout);
restore_user_sigmask(sigmask, &sigsaved); restore_user_sigmask(sigmask, &sigsaved, err == -EINTR);
return err; return err;
} }
......
...@@ -2200,11 +2200,12 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, ...@@ -2200,11 +2200,12 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events,
} }
ret = wait_event_interruptible(ctx->wait, io_cqring_events(ring) >= min_events); ret = wait_event_interruptible(ctx->wait, io_cqring_events(ring) >= min_events);
if (ret == -ERESTARTSYS)
ret = -EINTR;
if (sig) if (sig)
restore_user_sigmask(sig, &sigsaved); restore_user_sigmask(sig, &sigsaved, ret == -ERESTARTSYS);
if (ret == -ERESTARTSYS)
ret = -EINTR;
return READ_ONCE(ring->r.head) == READ_ONCE(ring->r.tail) ? ret : 0; return READ_ONCE(ring->r.head) == READ_ONCE(ring->r.tail) ? ret : 0;
} }
......
...@@ -462,7 +462,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns, ...@@ -462,7 +462,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
* a program is not able to use ptrace(2) in that case. It is * a program is not able to use ptrace(2) in that case. It is
* safe because the task has stopped executing permanently. * safe because the task has stopped executing permanently.
*/ */
if (permitted && (task->flags & PF_DUMPCORE)) { if (permitted && (task->flags & (PF_EXITING|PF_DUMPCORE))) {
if (try_get_task_stack(task)) { if (try_get_task_stack(task)) {
eip = KSTK_EIP(task); eip = KSTK_EIP(task);
esp = KSTK_ESP(task); esp = KSTK_ESP(task);
......
...@@ -758,10 +758,9 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp, ...@@ -758,10 +758,9 @@ static long do_pselect(int n, fd_set __user *inp, fd_set __user *outp,
return ret; return ret;
ret = core_sys_select(n, inp, outp, exp, to); ret = core_sys_select(n, inp, outp, exp, to);
restore_user_sigmask(sigmask, &sigsaved, ret == -ERESTARTNOHAND);
ret = poll_select_copy_remaining(&end_time, tsp, type, ret); ret = poll_select_copy_remaining(&end_time, tsp, type, ret);
restore_user_sigmask(sigmask, &sigsaved);
return ret; return ret;
} }
...@@ -1106,8 +1105,7 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds, ...@@ -1106,8 +1105,7 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds,
ret = do_sys_poll(ufds, nfds, to); ret = do_sys_poll(ufds, nfds, to);
restore_user_sigmask(sigmask, &sigsaved); restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR);
/* We can restart this syscall, usually */ /* We can restart this syscall, usually */
if (ret == -EINTR) if (ret == -EINTR)
ret = -ERESTARTNOHAND; ret = -ERESTARTNOHAND;
...@@ -1142,8 +1140,7 @@ SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds, unsigned int, nfds, ...@@ -1142,8 +1140,7 @@ SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds, unsigned int, nfds,
ret = do_sys_poll(ufds, nfds, to); ret = do_sys_poll(ufds, nfds, to);
restore_user_sigmask(sigmask, &sigsaved); restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR);
/* We can restart this syscall, usually */ /* We can restart this syscall, usually */
if (ret == -EINTR) if (ret == -EINTR)
ret = -ERESTARTNOHAND; ret = -ERESTARTNOHAND;
...@@ -1350,10 +1347,9 @@ static long do_compat_pselect(int n, compat_ulong_t __user *inp, ...@@ -1350,10 +1347,9 @@ static long do_compat_pselect(int n, compat_ulong_t __user *inp,
return ret; return ret;
ret = compat_core_sys_select(n, inp, outp, exp, to); ret = compat_core_sys_select(n, inp, outp, exp, to);
restore_user_sigmask(sigmask, &sigsaved, ret == -ERESTARTNOHAND);
ret = poll_select_copy_remaining(&end_time, tsp, type, ret); ret = poll_select_copy_remaining(&end_time, tsp, type, ret);
restore_user_sigmask(sigmask, &sigsaved);
return ret; return ret;
} }
...@@ -1425,8 +1421,7 @@ COMPAT_SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds, ...@@ -1425,8 +1421,7 @@ COMPAT_SYSCALL_DEFINE5(ppoll_time32, struct pollfd __user *, ufds,
ret = do_sys_poll(ufds, nfds, to); ret = do_sys_poll(ufds, nfds, to);
restore_user_sigmask(sigmask, &sigsaved); restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR);
/* We can restart this syscall, usually */ /* We can restart this syscall, usually */
if (ret == -EINTR) if (ret == -EINTR)
ret = -ERESTARTNOHAND; ret = -ERESTARTNOHAND;
...@@ -1461,8 +1456,7 @@ COMPAT_SYSCALL_DEFINE5(ppoll_time64, struct pollfd __user *, ufds, ...@@ -1461,8 +1456,7 @@ COMPAT_SYSCALL_DEFINE5(ppoll_time64, struct pollfd __user *, ufds,
ret = do_sys_poll(ufds, nfds, to); ret = do_sys_poll(ufds, nfds, to);
restore_user_sigmask(sigmask, &sigsaved); restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR);
/* We can restart this syscall, usually */ /* We can restart this syscall, usually */
if (ret == -EINTR) if (ret == -EINTR)
ret = -ERESTARTNOHAND; ret = -ERESTARTNOHAND;
......
...@@ -93,7 +93,8 @@ ...@@ -93,7 +93,8 @@
#define DIV_ROUND_DOWN_ULL(ll, d) \ #define DIV_ROUND_DOWN_ULL(ll, d) \
({ unsigned long long _tmp = (ll); do_div(_tmp, d); _tmp; }) ({ unsigned long long _tmp = (ll); do_div(_tmp, d); _tmp; })
#define DIV_ROUND_UP_ULL(ll, d) DIV_ROUND_DOWN_ULL((ll) + (d) - 1, (d)) #define DIV_ROUND_UP_ULL(ll, d) \
DIV_ROUND_DOWN_ULL((unsigned long long)(ll) + (d) - 1, (d))
#if BITS_PER_LONG == 32 #if BITS_PER_LONG == 32
# define DIV_ROUND_UP_SECTOR_T(ll,d) DIV_ROUND_UP_ULL(ll, d) # define DIV_ROUND_UP_SECTOR_T(ll,d) DIV_ROUND_UP_ULL(ll, d)
......
...@@ -68,7 +68,7 @@ static inline phys_addr_t pfn_t_to_phys(pfn_t pfn) ...@@ -68,7 +68,7 @@ static inline phys_addr_t pfn_t_to_phys(pfn_t pfn)
static inline void *pfn_t_to_virt(pfn_t pfn) static inline void *pfn_t_to_virt(pfn_t pfn)
{ {
if (pfn_t_has_page(pfn)) if (pfn_t_has_page(pfn) && !is_device_private_page(pfn_t_to_page(pfn)))
return __va(pfn_t_to_phys(pfn)); return __va(pfn_t_to_phys(pfn));
return NULL; return NULL;
} }
......
...@@ -276,7 +276,7 @@ extern int sigprocmask(int, sigset_t *, sigset_t *); ...@@ -276,7 +276,7 @@ extern int sigprocmask(int, sigset_t *, sigset_t *);
extern int set_user_sigmask(const sigset_t __user *usigmask, sigset_t *set, extern int set_user_sigmask(const sigset_t __user *usigmask, sigset_t *set,
sigset_t *oldset, size_t sigsetsize); sigset_t *oldset, size_t sigsetsize);
extern void restore_user_sigmask(const void __user *usigmask, extern void restore_user_sigmask(const void __user *usigmask,
sigset_t *sigsaved); sigset_t *sigsaved, bool interrupted);
extern void set_current_blocked(sigset_t *); extern void set_current_blocked(sigset_t *);
extern void __set_current_blocked(const sigset_t *); extern void __set_current_blocked(const sigset_t *);
extern int show_unhandled_signals; extern int show_unhandled_signals;
......
...@@ -617,7 +617,7 @@ static inline void clean_rootfs(void) ...@@ -617,7 +617,7 @@ static inline void clean_rootfs(void)
#endif /* CONFIG_BLK_DEV_RAM */ #endif /* CONFIG_BLK_DEV_RAM */
#ifdef CONFIG_BLK_DEV_RAM #ifdef CONFIG_BLK_DEV_RAM
static void populate_initrd_image(char *err) static void __init populate_initrd_image(char *err)
{ {
ssize_t written; ssize_t written;
int fd; int fd;
...@@ -637,7 +637,7 @@ static void populate_initrd_image(char *err) ...@@ -637,7 +637,7 @@ static void populate_initrd_image(char *err)
ksys_close(fd); ksys_close(fd);
} }
#else #else
static void populate_initrd_image(char *err) static void __init populate_initrd_image(char *err)
{ {
printk(KERN_EMERG "Initramfs unpacking failed: %s\n", err); printk(KERN_EMERG "Initramfs unpacking failed: %s\n", err);
} }
......
...@@ -248,7 +248,11 @@ static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, int node) ...@@ -248,7 +248,11 @@ static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, int node)
struct page *page = alloc_pages_node(node, THREADINFO_GFP, struct page *page = alloc_pages_node(node, THREADINFO_GFP,
THREAD_SIZE_ORDER); THREAD_SIZE_ORDER);
return page ? page_address(page) : NULL; if (likely(page)) {
tsk->stack = page_address(page);
return tsk->stack;
}
return NULL;
#endif #endif
} }
......
...@@ -2912,7 +2912,8 @@ EXPORT_SYMBOL(set_compat_user_sigmask); ...@@ -2912,7 +2912,8 @@ EXPORT_SYMBOL(set_compat_user_sigmask);
* This is useful for syscalls such as ppoll, pselect, io_pgetevents and * This is useful for syscalls such as ppoll, pselect, io_pgetevents and
* epoll_pwait where a new sigmask is passed in from userland for the syscalls. * epoll_pwait where a new sigmask is passed in from userland for the syscalls.
*/ */
void restore_user_sigmask(const void __user *usigmask, sigset_t *sigsaved) void restore_user_sigmask(const void __user *usigmask, sigset_t *sigsaved,
bool interrupted)
{ {
if (!usigmask) if (!usigmask)
...@@ -2922,7 +2923,7 @@ void restore_user_sigmask(const void __user *usigmask, sigset_t *sigsaved) ...@@ -2922,7 +2923,7 @@ void restore_user_sigmask(const void __user *usigmask, sigset_t *sigsaved)
* Restoring sigmask here can lead to delivering signals that the above * Restoring sigmask here can lead to delivering signals that the above
* syscalls are intended to block because of the sigmask passed in. * syscalls are intended to block because of the sigmask passed in.
*/ */
if (signal_pending(current)) { if (interrupted) {
current->saved_sigmask = *sigsaved; current->saved_sigmask = *sigsaved;
set_restore_sigmask(); set_restore_sigmask();
return; return;
......
...@@ -1510,16 +1510,29 @@ static int free_pool_huge_page(struct hstate *h, nodemask_t *nodes_allowed, ...@@ -1510,16 +1510,29 @@ static int free_pool_huge_page(struct hstate *h, nodemask_t *nodes_allowed,
/* /*
* Dissolve a given free hugepage into free buddy pages. This function does * Dissolve a given free hugepage into free buddy pages. This function does
* nothing for in-use (including surplus) hugepages. Returns -EBUSY if the * nothing for in-use hugepages and non-hugepages.
* dissolution fails because a give page is not a free hugepage, or because * This function returns values like below:
* free hugepages are fully reserved. *
* -EBUSY: failed to dissolved free hugepages or the hugepage is in-use
* (allocated or reserved.)
* 0: successfully dissolved free hugepages or the page is not a
* hugepage (considered as already dissolved)
*/ */
int dissolve_free_huge_page(struct page *page) int dissolve_free_huge_page(struct page *page)
{ {
int rc = -EBUSY; int rc = -EBUSY;
/* Not to disrupt normal path by vainly holding hugetlb_lock */
if (!PageHuge(page))
return 0;
spin_lock(&hugetlb_lock); spin_lock(&hugetlb_lock);
if (PageHuge(page) && !page_count(page)) { if (!PageHuge(page)) {
rc = 0;
goto out;
}
if (!page_count(page)) {
struct page *head = compound_head(page); struct page *head = compound_head(page);
struct hstate *h = page_hstate(head); struct hstate *h = page_hstate(head);
int nid = page_to_nid(head); int nid = page_to_nid(head);
...@@ -1564,12 +1577,10 @@ int dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn) ...@@ -1564,12 +1577,10 @@ int dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn)
for (pfn = start_pfn; pfn < end_pfn; pfn += 1 << minimum_order) { for (pfn = start_pfn; pfn < end_pfn; pfn += 1 << minimum_order) {
page = pfn_to_page(pfn); page = pfn_to_page(pfn);
if (PageHuge(page) && !page_count(page)) {
rc = dissolve_free_huge_page(page); rc = dissolve_free_huge_page(page);
if (rc) if (rc)
break; break;
} }
}
return rc; return rc;
} }
......
...@@ -1730,6 +1730,8 @@ static int soft_offline_huge_page(struct page *page, int flags) ...@@ -1730,6 +1730,8 @@ static int soft_offline_huge_page(struct page *page, int flags)
if (!ret) { if (!ret) {
if (set_hwpoison_free_buddy_page(page)) if (set_hwpoison_free_buddy_page(page))
num_poisoned_pages_inc(); num_poisoned_pages_inc();
else
ret = -EBUSY;
} }
} }
return ret; return ret;
...@@ -1854,11 +1856,8 @@ static int soft_offline_in_use_page(struct page *page, int flags) ...@@ -1854,11 +1856,8 @@ static int soft_offline_in_use_page(struct page *page, int flags)
static int soft_offline_free_page(struct page *page) static int soft_offline_free_page(struct page *page)
{ {
int rc = 0; int rc = dissolve_free_huge_page(page);
struct page *head = compound_head(page);
if (PageHuge(head))
rc = dissolve_free_huge_page(page);
if (!rc) { if (!rc) {
if (set_hwpoison_free_buddy_page(page)) if (set_hwpoison_free_buddy_page(page))
num_poisoned_pages_inc(); num_poisoned_pages_inc();
......
...@@ -306,7 +306,7 @@ static void mpol_rebind_nodemask(struct mempolicy *pol, const nodemask_t *nodes) ...@@ -306,7 +306,7 @@ static void mpol_rebind_nodemask(struct mempolicy *pol, const nodemask_t *nodes)
else { else {
nodes_remap(tmp, pol->v.nodes,pol->w.cpuset_mems_allowed, nodes_remap(tmp, pol->v.nodes,pol->w.cpuset_mems_allowed,
*nodes); *nodes);
pol->w.cpuset_mems_allowed = tmp; pol->w.cpuset_mems_allowed = *nodes;
} }
if (nodes_empty(tmp)) if (nodes_empty(tmp))
......
...@@ -987,8 +987,7 @@ static void oom_kill_process(struct oom_control *oc, const char *message) ...@@ -987,8 +987,7 @@ static void oom_kill_process(struct oom_control *oc, const char *message)
/* /*
* Determines whether the kernel must panic because of the panic_on_oom sysctl. * Determines whether the kernel must panic because of the panic_on_oom sysctl.
*/ */
static void check_panic_on_oom(struct oom_control *oc, static void check_panic_on_oom(struct oom_control *oc)
enum oom_constraint constraint)
{ {
if (likely(!sysctl_panic_on_oom)) if (likely(!sysctl_panic_on_oom))
return; return;
...@@ -998,7 +997,7 @@ static void check_panic_on_oom(struct oom_control *oc, ...@@ -998,7 +997,7 @@ static void check_panic_on_oom(struct oom_control *oc,
* does not panic for cpuset, mempolicy, or memcg allocation * does not panic for cpuset, mempolicy, or memcg allocation
* failures. * failures.
*/ */
if (constraint != CONSTRAINT_NONE) if (oc->constraint != CONSTRAINT_NONE)
return; return;
} }
/* Do not panic for oom kills triggered by sysrq */ /* Do not panic for oom kills triggered by sysrq */
...@@ -1035,7 +1034,6 @@ EXPORT_SYMBOL_GPL(unregister_oom_notifier); ...@@ -1035,7 +1034,6 @@ EXPORT_SYMBOL_GPL(unregister_oom_notifier);
bool out_of_memory(struct oom_control *oc) bool out_of_memory(struct oom_control *oc)
{ {
unsigned long freed = 0; unsigned long freed = 0;
enum oom_constraint constraint = CONSTRAINT_NONE;
if (oom_killer_disabled) if (oom_killer_disabled)
return false; return false;
...@@ -1071,10 +1069,10 @@ bool out_of_memory(struct oom_control *oc) ...@@ -1071,10 +1069,10 @@ bool out_of_memory(struct oom_control *oc)
* Check if there were limitations on the allocation (only relevant for * Check if there were limitations on the allocation (only relevant for
* NUMA and memcg) that may require different handling. * NUMA and memcg) that may require different handling.
*/ */
constraint = constrained_alloc(oc); oc->constraint = constrained_alloc(oc);
if (constraint != CONSTRAINT_MEMORY_POLICY) if (oc->constraint != CONSTRAINT_MEMORY_POLICY)
oc->nodemask = NULL; oc->nodemask = NULL;
check_panic_on_oom(oc, constraint); check_panic_on_oom(oc);
if (!is_memcg_oom(oc) && sysctl_oom_kill_allocating_task && if (!is_memcg_oom(oc) && sysctl_oom_kill_allocating_task &&
current->mm && !oom_unkillable_task(current, NULL, oc->nodemask) && current->mm && !oom_unkillable_task(current, NULL, oc->nodemask) &&
......
...@@ -136,7 +136,7 @@ static ssize_t page_idle_bitmap_read(struct file *file, struct kobject *kobj, ...@@ -136,7 +136,7 @@ static ssize_t page_idle_bitmap_read(struct file *file, struct kobject *kobj,
end_pfn = pfn + count * BITS_PER_BYTE; end_pfn = pfn + count * BITS_PER_BYTE;
if (end_pfn > max_pfn) if (end_pfn > max_pfn)
end_pfn = ALIGN(max_pfn, BITMAP_CHUNK_BITS); end_pfn = max_pfn;
for (; pfn < end_pfn; pfn++) { for (; pfn < end_pfn; pfn++) {
bit = pfn % BITMAP_CHUNK_BITS; bit = pfn % BITMAP_CHUNK_BITS;
...@@ -181,7 +181,7 @@ static ssize_t page_idle_bitmap_write(struct file *file, struct kobject *kobj, ...@@ -181,7 +181,7 @@ static ssize_t page_idle_bitmap_write(struct file *file, struct kobject *kobj,
end_pfn = pfn + count * BITS_PER_BYTE; end_pfn = pfn + count * BITS_PER_BYTE;
if (end_pfn > max_pfn) if (end_pfn > max_pfn)
end_pfn = ALIGN(max_pfn, BITMAP_CHUNK_BITS); end_pfn = max_pfn;
for (; pfn < end_pfn; pfn++) { for (; pfn < end_pfn; pfn++) {
bit = pfn % BITMAP_CHUNK_BITS; bit = pfn % BITMAP_CHUNK_BITS;
......
...@@ -29,10 +29,9 @@ ...@@ -29,10 +29,9 @@
static struct bio *get_swap_bio(gfp_t gfp_flags, static struct bio *get_swap_bio(gfp_t gfp_flags,
struct page *page, bio_end_io_t end_io) struct page *page, bio_end_io_t end_io)
{ {
int i, nr = hpage_nr_pages(page);
struct bio *bio; struct bio *bio;
bio = bio_alloc(gfp_flags, nr); bio = bio_alloc(gfp_flags, 1);
if (bio) { if (bio) {
struct block_device *bdev; struct block_device *bdev;
...@@ -41,9 +40,7 @@ static struct bio *get_swap_bio(gfp_t gfp_flags, ...@@ -41,9 +40,7 @@ static struct bio *get_swap_bio(gfp_t gfp_flags,
bio->bi_iter.bi_sector <<= PAGE_SHIFT - 9; bio->bi_iter.bi_sector <<= PAGE_SHIFT - 9;
bio->bi_end_io = end_io; bio->bi_end_io = end_io;
for (i = 0; i < nr; i++) bio_add_page(bio, page, PAGE_SIZE * hpage_nr_pages(page), 0);
bio_add_page(bio, page + i, PAGE_SIZE, 0);
VM_BUG_ON(bio->bi_iter.bi_size != PAGE_SIZE * nr);
} }
return bio; return bio;
} }
......
...@@ -913,7 +913,7 @@ adjust_va_to_fit_type(struct vmap_area *va, ...@@ -913,7 +913,7 @@ adjust_va_to_fit_type(struct vmap_area *va,
unsigned long nva_start_addr, unsigned long size, unsigned long nva_start_addr, unsigned long size,
enum fit_type type) enum fit_type type)
{ {
struct vmap_area *lva; struct vmap_area *lva = NULL;
if (type == FL_FIT_TYPE) { if (type == FL_FIT_TYPE) {
/* /*
...@@ -972,7 +972,7 @@ adjust_va_to_fit_type(struct vmap_area *va, ...@@ -972,7 +972,7 @@ adjust_va_to_fit_type(struct vmap_area *va,
if (type != FL_FIT_TYPE) { if (type != FL_FIT_TYPE) {
augment_tree_propagate_from(va); augment_tree_propagate_from(va);
if (type == NE_FIT_TYPE) if (lva) /* type == NE_FIT_TYPE */
insert_vmap_area_augment(lva, &va->rb_node, insert_vmap_area_augment(lva, &va->rb_node,
&free_vmap_area_root, &free_vmap_area_list); &free_vmap_area_root, &free_vmap_area_list);
} }
......
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