Commit bfbaa60d 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>:
  ocfs2/dlm: fix deadlock when dispatch assert master
  membarrier: clean up selftest
  vmscan: fix sane_reclaim helper for legacy memcg
  lib/iommu-common.c: do not try to deref a null iommu->lazy_flush() pointer when n < pool->hint
  x86, efi, kasan: #undef memset/memcpy/memmove per arch
  mm: migrate: hugetlb: putback destination hugepage to active list
  mm, dax: VMA with vm_ops->pfn_mkwrite wants to be write-notified
  userfaultfd: register uapi generic syscall (aarch64)
  userfaultfd: selftest: don't error out if pthread_mutex_t isn't identical
  userfaultfd: selftest: return an error if BOUNCE_VERIFY fails
  userfaultfd: selftest: avoid my_bcmp false positives with powerpc
  userfaultfd: selftest: only warn if __NR_userfaultfd is undefined
  userfaultfd: selftest: headers fixup
  userfaultfd: selftests: vm: pick up sanitized kernel headers
  userfaultfd: revert "userfaultfd: waitqueue: add nr wake parameter to __wake_up_locked_key"
parents d5fc4f55 012572d4
......@@ -86,6 +86,16 @@ extern u64 asmlinkage efi_call(void *fp, ...);
extern void __iomem *__init efi_ioremap(unsigned long addr, unsigned long size,
u32 type, u64 attribute);
/*
* CONFIG_KASAN may redefine memset to __memset. __memset function is present
* only in kernel binary. Since the EFI stub linked into a separate binary it
* doesn't have __memset(). So we should use standard memset from
* arch/x86/boot/compressed/string.c. The same applies to memcpy and memmove.
*/
#undef memcpy
#undef memset
#undef memmove
#endif /* CONFIG_X86_32 */
extern struct efi_scratch efi_scratch;
......
......@@ -5,10 +5,6 @@
/* error code which can't be mistaken for valid address */
#define EFI_ERROR (~0UL)
#undef memcpy
#undef memset
#undef memmove
void efi_char16_printk(efi_system_table_t *, efi_char16_t *);
efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg, void *__image,
......
......@@ -1439,6 +1439,7 @@ int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data,
int found, ret;
int set_maybe;
int dispatch_assert = 0;
int dispatched = 0;
if (!dlm_grab(dlm))
return DLM_MASTER_RESP_NO;
......@@ -1658,15 +1659,18 @@ int dlm_master_request_handler(struct o2net_msg *msg, u32 len, void *data,
mlog(ML_ERROR, "failed to dispatch assert master work\n");
response = DLM_MASTER_RESP_ERROR;
dlm_lockres_put(res);
} else
} else {
dispatched = 1;
__dlm_lockres_grab_inflight_worker(dlm, res);
}
spin_unlock(&res->spinlock);
} else {
if (res)
dlm_lockres_put(res);
}
dlm_put(dlm);
if (!dispatched)
dlm_put(dlm);
return response;
}
......@@ -2090,7 +2094,6 @@ int dlm_dispatch_assert_master(struct dlm_ctxt *dlm,
/* queue up work for dlm_assert_master_worker */
dlm_grab(dlm); /* get an extra ref for the work item */
dlm_init_work_item(dlm, item, dlm_assert_master_worker, NULL);
item->u.am.lockres = res; /* already have a ref */
/* can optionally ignore node numbers higher than this node */
......
......@@ -1694,6 +1694,7 @@ int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data,
unsigned int hash;
int master = DLM_LOCK_RES_OWNER_UNKNOWN;
u32 flags = DLM_ASSERT_MASTER_REQUERY;
int dispatched = 0;
if (!dlm_grab(dlm)) {
/* since the domain has gone away on this
......@@ -1719,8 +1720,10 @@ int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data,
dlm_put(dlm);
/* sender will take care of this and retry */
return ret;
} else
} else {
dispatched = 1;
__dlm_lockres_grab_inflight_worker(dlm, res);
}
spin_unlock(&res->spinlock);
} else {
/* put.. incase we are not the master */
......@@ -1730,7 +1733,8 @@ int dlm_master_requery_handler(struct o2net_msg *msg, u32 len, void *data,
}
spin_unlock(&dlm->spinlock);
dlm_put(dlm);
if (!dispatched)
dlm_put(dlm);
return master;
}
......
......@@ -467,8 +467,8 @@ static int userfaultfd_release(struct inode *inode, struct file *file)
* the fault_*wqh.
*/
spin_lock(&ctx->fault_pending_wqh.lock);
__wake_up_locked_key(&ctx->fault_pending_wqh, TASK_NORMAL, 0, &range);
__wake_up_locked_key(&ctx->fault_wqh, TASK_NORMAL, 0, &range);
__wake_up_locked_key(&ctx->fault_pending_wqh, TASK_NORMAL, &range);
__wake_up_locked_key(&ctx->fault_wqh, TASK_NORMAL, &range);
spin_unlock(&ctx->fault_pending_wqh.lock);
wake_up_poll(&ctx->fd_wqh, POLLHUP);
......@@ -650,10 +650,10 @@ static void __wake_userfault(struct userfaultfd_ctx *ctx,
spin_lock(&ctx->fault_pending_wqh.lock);
/* wake all in the range and autoremove */
if (waitqueue_active(&ctx->fault_pending_wqh))
__wake_up_locked_key(&ctx->fault_pending_wqh, TASK_NORMAL, 0,
__wake_up_locked_key(&ctx->fault_pending_wqh, TASK_NORMAL,
range);
if (waitqueue_active(&ctx->fault_wqh))
__wake_up_locked_key(&ctx->fault_wqh, TASK_NORMAL, 0, range);
__wake_up_locked_key(&ctx->fault_wqh, TASK_NORMAL, range);
spin_unlock(&ctx->fault_pending_wqh.lock);
}
......
......@@ -147,8 +147,7 @@ __remove_wait_queue(wait_queue_head_t *head, wait_queue_t *old)
typedef int wait_bit_action_f(struct wait_bit_key *);
void __wake_up(wait_queue_head_t *q, unsigned int mode, int nr, void *key);
void __wake_up_locked_key(wait_queue_head_t *q, unsigned int mode, int nr,
void *key);
void __wake_up_locked_key(wait_queue_head_t *q, unsigned int mode, void *key);
void __wake_up_sync_key(wait_queue_head_t *q, unsigned int mode, int nr, void *key);
void __wake_up_locked(wait_queue_head_t *q, unsigned int mode, int nr);
void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr);
......@@ -180,7 +179,7 @@ wait_queue_head_t *bit_waitqueue(void *, int);
#define wake_up_poll(x, m) \
__wake_up(x, TASK_NORMAL, 1, (void *) (m))
#define wake_up_locked_poll(x, m) \
__wake_up_locked_key((x), TASK_NORMAL, 1, (void *) (m))
__wake_up_locked_key((x), TASK_NORMAL, (void *) (m))
#define wake_up_interruptible_poll(x, m) \
__wake_up(x, TASK_INTERRUPTIBLE, 1, (void *) (m))
#define wake_up_interruptible_sync_poll(x, m) \
......
......@@ -709,17 +709,19 @@ __SYSCALL(__NR_memfd_create, sys_memfd_create)
__SYSCALL(__NR_bpf, sys_bpf)
#define __NR_execveat 281
__SC_COMP(__NR_execveat, sys_execveat, compat_sys_execveat)
#define __NR_membarrier 282
#define __NR_userfaultfd 282
__SYSCALL(__NR_userfaultfd, sys_userfaultfd)
#define __NR_membarrier 283
__SYSCALL(__NR_membarrier, sys_membarrier)
#undef __NR_syscalls
#define __NR_syscalls 283
#define __NR_syscalls 284
/*
* All syscalls below here should go away really,
* these are provided for both review and as a porting
* help for the C library version.
*
*
* Last chance: are any of these important enough to
* enable by default?
*/
......
......@@ -106,10 +106,9 @@ void __wake_up_locked(wait_queue_head_t *q, unsigned int mode, int nr)
}
EXPORT_SYMBOL_GPL(__wake_up_locked);
void __wake_up_locked_key(wait_queue_head_t *q, unsigned int mode, int nr,
void *key)
void __wake_up_locked_key(wait_queue_head_t *q, unsigned int mode, void *key)
{
__wake_up_common(q, mode, nr, 0, key);
__wake_up_common(q, mode, 1, 0, key);
}
EXPORT_SYMBOL_GPL(__wake_up_locked_key);
......@@ -284,7 +283,7 @@ void abort_exclusive_wait(wait_queue_head_t *q, wait_queue_t *wait,
if (!list_empty(&wait->task_list))
list_del_init(&wait->task_list);
else if (waitqueue_active(q))
__wake_up_locked_key(q, mode, 1, key);
__wake_up_locked_key(q, mode, key);
spin_unlock_irqrestore(&q->lock, flags);
}
EXPORT_SYMBOL(abort_exclusive_wait);
......
......@@ -21,8 +21,7 @@ static DEFINE_PER_CPU(unsigned int, iommu_hash_common);
static inline bool need_flush(struct iommu_map_table *iommu)
{
return (iommu->lazy_flush != NULL &&
(iommu->flags & IOMMU_NEED_FLUSH) != 0);
return ((iommu->flags & IOMMU_NEED_FLUSH) != 0);
}
static inline void set_flush(struct iommu_map_table *iommu)
......@@ -211,7 +210,8 @@ unsigned long iommu_tbl_range_alloc(struct device *dev,
goto bail;
}
}
if (n < pool->hint || need_flush(iommu)) {
if (iommu->lazy_flush &&
(n < pool->hint || need_flush(iommu))) {
clear_flush(iommu);
iommu->lazy_flush(iommu);
}
......
......@@ -1075,7 +1075,7 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,
if (rc != MIGRATEPAGE_SUCCESS && put_new_page)
put_new_page(new_hpage, private);
else
put_page(new_hpage);
putback_active_hugepage(new_hpage);
if (result) {
if (rc)
......
......@@ -1490,13 +1490,14 @@ SYSCALL_DEFINE1(old_mmap, struct mmap_arg_struct __user *, arg)
int vma_wants_writenotify(struct vm_area_struct *vma)
{
vm_flags_t vm_flags = vma->vm_flags;
const struct vm_operations_struct *vm_ops = vma->vm_ops;
/* If it was private or non-writable, the write bit is already clear */
if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
return 0;
/* The backer wishes to know when pages are first written to? */
if (vma->vm_ops && vma->vm_ops->page_mkwrite)
if (vm_ops && (vm_ops->page_mkwrite || vm_ops->pfn_mkwrite))
return 1;
/* The open routine did something to the protections that pgprot_modify
......
......@@ -175,7 +175,7 @@ static bool sane_reclaim(struct scan_control *sc)
if (!memcg)
return true;
#ifdef CONFIG_CGROUP_WRITEBACK
if (memcg->css.cgroup)
if (cgroup_on_dfl(memcg->css.cgroup))
return true;
#endif
return false;
......
......@@ -297,7 +297,7 @@ static int rpc_complete_task(struct rpc_task *task)
clear_bit(RPC_TASK_ACTIVE, &task->tk_runstate);
ret = atomic_dec_and_test(&task->tk_count);
if (waitqueue_active(wq))
__wake_up_locked_key(wq, TASK_NORMAL, 1, &k);
__wake_up_locked_key(wq, TASK_NORMAL, &k);
spin_unlock_irqrestore(&wq->lock, flags);
return ret;
}
......
CFLAGS += -g -I../../../../usr/include/
all:
$(CC) $(CFLAGS) membarrier_test.c -o membarrier_test
TEST_PROGS := membarrier_test
all: $(TEST_PROGS)
include ../lib.mk
clean:
$(RM) membarrier_test
$(RM) $(TEST_PROGS)
#define _GNU_SOURCE
#define __EXPORTED_HEADERS__
#include <linux/membarrier.h>
#include <asm-generic/unistd.h>
#include <sys/syscall.h>
#include <syscall.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
......
# Makefile for vm selftests
CFLAGS = -Wall
CFLAGS = -Wall -I ../../../../usr/include $(EXTRA_CFLAGS)
BINARIES = compaction_test
BINARIES += hugepage-mmap
BINARIES += hugepage-shm
......@@ -12,8 +12,11 @@ BINARIES += userfaultfd
all: $(BINARIES)
%: %.c
$(CC) $(CFLAGS) -o $@ $^ -lrt
userfaultfd: userfaultfd.c
$(CC) $(CFLAGS) -O2 -o $@ $^ -lpthread
userfaultfd: userfaultfd.c ../../../../usr/include/linux/kernel.h
$(CC) $(CFLAGS) -O2 -o $@ $< -lpthread
../../../../usr/include/linux/kernel.h:
make -C ../../../.. headers_install
TEST_PROGS := run_vmtests
TEST_FILES := $(BINARIES)
......
......@@ -64,19 +64,9 @@
#include <sys/syscall.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include "../../../../include/uapi/linux/userfaultfd.h"
#ifdef __x86_64__
#define __NR_userfaultfd 323
#elif defined(__i386__)
#define __NR_userfaultfd 374
#elif defined(__powewrpc__)
#define __NR_userfaultfd 364
#elif defined(__s390__)
#define __NR_userfaultfd 355
#else
#error "missing __NR_userfaultfd definition"
#endif
#include <linux/userfaultfd.h>
#ifdef __NR_userfaultfd
static unsigned long nr_cpus, nr_pages, nr_pages_per_cpu, page_size;
......@@ -432,7 +422,7 @@ static int userfaultfd_stress(void)
struct uffdio_register uffdio_register;
struct uffdio_api uffdio_api;
unsigned long cpu;
int uffd_flags;
int uffd_flags, err;
unsigned long userfaults[nr_cpus];
if (posix_memalign(&area, page_size, nr_pages * page_size)) {
......@@ -475,6 +465,14 @@ static int userfaultfd_stress(void)
*area_mutex(area_src, nr) = (pthread_mutex_t)
PTHREAD_MUTEX_INITIALIZER;
count_verify[nr] = *area_count(area_src, nr) = 1;
/*
* In the transition between 255 to 256, powerpc will
* read out of order in my_bcmp and see both bytes as
* zero, so leave a placeholder below always non-zero
* after the count, to avoid my_bcmp to trigger false
* positives.
*/
*(area_count(area_src, nr) + 1) = 1;
}
pipefd = malloc(sizeof(int) * nr_cpus * 2);
......@@ -501,6 +499,7 @@ static int userfaultfd_stress(void)
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, 16*1024*1024);
err = 0;
while (bounces--) {
unsigned long expected_ioctls;
......@@ -581,20 +580,13 @@ static int userfaultfd_stress(void)
/* verification */
if (bounces & BOUNCE_VERIFY) {
for (nr = 0; nr < nr_pages; nr++) {
if (my_bcmp(area_dst,
area_dst + nr * page_size,
sizeof(pthread_mutex_t))) {
fprintf(stderr,
"error mutex 2 %lu\n",
nr);
bounces = 0;
}
if (*area_count(area_dst, nr) != count_verify[nr]) {
fprintf(stderr,
"error area_count %Lu %Lu %lu\n",
*area_count(area_src, nr),
count_verify[nr],
nr);
err = 1;
bounces = 0;
}
}
......@@ -611,7 +603,7 @@ static int userfaultfd_stress(void)
printf("\n");
}
return 0;
return err;
}
int main(int argc, char **argv)
......@@ -620,8 +612,8 @@ int main(int argc, char **argv)
fprintf(stderr, "Usage: <MiB> <bounces>\n"), exit(1);
nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
page_size = sysconf(_SC_PAGE_SIZE);
if ((unsigned long) area_count(NULL, 0) + sizeof(unsigned long long) >
page_size)
if ((unsigned long) area_count(NULL, 0) + sizeof(unsigned long long) * 2
> page_size)
fprintf(stderr, "Impossible to run this test\n"), exit(2);
nr_pages_per_cpu = atol(argv[1]) * 1024*1024 / page_size /
nr_cpus;
......@@ -639,3 +631,15 @@ int main(int argc, char **argv)
nr_pages, nr_pages_per_cpu);
return userfaultfd_stress();
}
#else /* __NR_userfaultfd */
#warning "missing __NR_userfaultfd definition"
int main(void)
{
printf("skip: Skipping userfaultfd test (missing __NR_userfaultfd)\n");
return 0;
}
#endif /* __NR_userfaultfd */
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