mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 22:51:42 +00:00
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"
This commit is contained in:
commit
bfbaa60d18
@ -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 @@ send_response:
|
||||
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 @@ out:
|
||||
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;
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
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)
|
||||
|
@ -1,9 +1,6 @@
|
||||
#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>
|
||||
|
@ -1,6 +1,6 @@
|
||||
# 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"
|
||||
#include <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
|
||||
#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 */
|
||||
|
Loading…
Reference in New Issue
Block a user