* [PATCH v3 09/12] KVM: arm64: guest debug, HW assisted debug support
From: Alex Bennée @ 2015-05-07 9:07 UTC (permalink / raw)
To: kvm, linux-arm-kernel, kvmarm, christoffer.dall, marc.zyngier,
peter.maydell, agraf, drjones, pbonzini, zhichao.huang
Cc: Peter Zijlstra, Lorenzo Pieralisi, Russell King,
Richard Weinberger, Jonathan Corbet, Gleb Natapov, jan.kiszka,
AKASHI Takahiro, Ard Biesheuvel, Will Deacon, open list,
open list:ABI/API, open list:DOCUMENTATION, dahi, Andre Przywara,
Catalin Marinas, r65777, bp, Ingo Molnar
In-Reply-To: <1430929407-3487-1-git-send-email-alex.bennee@linaro.org>
This adds support for userspace to control the HW debug registers for
guest debug. In the debug ioctl we copy the IMPDEF defined number of
registers into a new register set called host_debug_state. There is now
a new vcpu parameter called debug_ptr which selects which register set
is to copied into the real registers when world switch occurs.
I've moved some helper functions into the hw_breakpoint.h header for
re-use.
As with single step we need to tweak the guest registers to enable the
exceptions so we need to save and restore those bits.
Two new capabilities have been added to the KVM_EXTENSION ioctl to allow
userspace to query the number of hardware break and watch points
available on the host hardware.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
v2
- switched to C setup
- replace host debug registers directly into context
- minor tweak to api docs
- setup right register for debug
- add FAR_EL2 to debug exit structure
- add support for trapping debug register access
v3
- remove stray trace statement
- fix spacing around operators (various)
- clean-up usage of trap_debug
- introduce debug_ptr, replace excessive memcpy stuff
- don't use memcpy in ioctl, just assign
- update cap ioctl documentation
- reword a number comments
- rename host_debug_state->external_debug_state
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 5ef937c..419f7a8 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2668,7 +2668,7 @@ The top 16 bits of the control field are architecture specific control
flags which can include the following:
- KVM_GUESTDBG_USE_SW_BP: using software breakpoints [x86, arm64]
- - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390]
+ - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390, arm64]
- KVM_GUESTDBG_INJECT_DB: inject DB type exception [x86]
- KVM_GUESTDBG_INJECT_BP: inject BP type exception [x86]
- KVM_GUESTDBG_EXIT_PENDING: trigger an immediate guest exit [s390]
@@ -2683,6 +2683,11 @@ updated to the correct (supplied) values.
The second part of the structure is architecture specific and
typically contains a set of debug registers.
+For arm64 the number of debug registers is implementation defined and
+can be determined by querying the KVM_CAP_GUEST_DEBUG_HW_BPS and
+KVM_CAP_GUEST_DEBUG_HW_WPS capabilities which returns a +ve number
+indicating the number of supported registers.
+
When debug events exit the main run loop with the reason
KVM_EXIT_DEBUG with the kvm_debug_exit_arch part of the kvm_run
structure containing architecture specific debug information.
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 9b3ed6d..2920185 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -279,6 +279,10 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
/* Set up the timer */
kvm_timer_vcpu_init(vcpu);
+ /* Set the debug registers to be the guests */
+ vcpu->arch.debug_ptr = (struct kvm_guest_debug_arch *)
+ &vcpu_sys_reg(vcpu, DBGBCR0_EL1);
+
return 0;
}
@@ -304,6 +308,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | \
KVM_GUESTDBG_USE_SW_BP | \
+ KVM_GUESTDBG_USE_HW_BP | \
KVM_GUESTDBG_SINGLESTEP)
/**
@@ -324,6 +329,12 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
if (dbg->control & KVM_GUESTDBG_ENABLE) {
vcpu->guest_debug = dbg->control;
+
+ /* Hardware assisted Break and Watch points */
+ if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) {
+ vcpu->arch.external_debug_state = dbg->arch;
+ }
+
} else {
/* If not enabled clear all flags */
vcpu->guest_debug = 0;
diff --git a/arch/arm64/include/asm/hw_breakpoint.h b/arch/arm64/include/asm/hw_breakpoint.h
index 52b484b..c450552 100644
--- a/arch/arm64/include/asm/hw_breakpoint.h
+++ b/arch/arm64/include/asm/hw_breakpoint.h
@@ -130,6 +130,18 @@ static inline void ptrace_hw_copy_thread(struct task_struct *task)
}
#endif
+/* Determine number of BRP registers available. */
+static inline int get_num_brps(void)
+{
+ return ((read_cpuid(ID_AA64DFR0_EL1) >> 12) & 0xf) + 1;
+}
+
+/* Determine number of WRP registers available. */
+static inline int get_num_wrps(void)
+{
+ return ((read_cpuid(ID_AA64DFR0_EL1) >> 20) & 0xf) + 1;
+}
+
extern struct pmu perf_ops_bp;
#endif /* __KERNEL__ */
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index b60fa7a..a44fb32 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -108,9 +108,18 @@ struct kvm_vcpu_arch {
/* Exception Information */
struct kvm_vcpu_fault_info fault;
- /* Debug state */
+ /* Guest debug state */
u64 debug_flags;
+ /*
+ * For debugging the guest we need to keep a set of debug
+ * registers which can override the guests own debug state
+ * while being used. These are set via the KVM_SET_GUEST_DEBUG
+ * ioctl.
+ */
+ struct kvm_guest_debug_arch *debug_ptr;
+ struct kvm_guest_debug_arch external_debug_state;
+
/* Pointer to host CPU context */
kvm_cpu_context_t *host_cpu_context;
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 04957d7..98e82ef 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -121,7 +121,7 @@ struct kvm_guest_debug_arch {
struct kvm_debug_exit_arch {
__u32 hsr;
- __u64 far;
+ __u64 far; /* used for watchpoints */
};
struct kvm_sync_regs {
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index ce7b7dd..671ab13 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -116,6 +116,7 @@ int main(void)
DEFINE(VCPU_FAR_EL2, offsetof(struct kvm_vcpu, arch.fault.far_el2));
DEFINE(VCPU_HPFAR_EL2, offsetof(struct kvm_vcpu, arch.fault.hpfar_el2));
DEFINE(VCPU_DEBUG_FLAGS, offsetof(struct kvm_vcpu, arch.debug_flags));
+ DEFINE(VCPU_DEBUG_PTR, offsetof(struct kvm_vcpu, arch.debug_ptr));
DEFINE(DEBUG_BCR, offsetof(struct kvm_guest_debug_arch, dbg_bcr));
DEFINE(DEBUG_BVR, offsetof(struct kvm_guest_debug_arch, dbg_bvr));
DEFINE(DEBUG_WCR, offsetof(struct kvm_guest_debug_arch, dbg_wcr));
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index e7d934d..3a41bbf 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -49,18 +49,6 @@ static DEFINE_PER_CPU(int, stepping_kernel_bp);
static int core_num_brps;
static int core_num_wrps;
-/* Determine number of BRP registers available. */
-static int get_num_brps(void)
-{
- return ((read_cpuid(ID_AA64DFR0_EL1) >> 12) & 0xf) + 1;
-}
-
-/* Determine number of WRP registers available. */
-static int get_num_wrps(void)
-{
- return ((read_cpuid(ID_AA64DFR0_EL1) >> 20) & 0xf) + 1;
-}
-
int hw_breakpoint_slots(int type)
{
/*
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 19346e8..1ab63dd 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -99,12 +99,6 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
MDCR_EL2_TDRA |
MDCR_EL2_TDOSA);
- /* Trap on access to debug registers? */
- if (trap_debug)
- vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
- else
- vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDA;
-
/* Is Guest debugging in effect? */
if (vcpu->guest_debug) {
vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE;
@@ -128,14 +122,54 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
vcpu_sys_reg(vcpu, MDSCR_EL1) &= ~DBG_MDSCR_SS;
}
+ /*
+ * HW Break/Watch points
+ *
+ * We simply switch the debug_ptr to point to our new
+ * external_debug_state which has been populated by the
+ * debug ioctl. The existing KVM_ARM64_DEBUG_DIRTY
+ * mechanism ensures the registers are updated on the
+ * world switch.
+ */
+ if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) {
+
+ vcpu_sys_reg(vcpu, MDSCR_EL1) |=
+ (DBG_MDSCR_KDE | DBG_MDSCR_MDE);
+
+ vcpu->arch.debug_ptr = &vcpu->arch.external_debug_state;
+ vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
+ trap_debug = true;
+ }
+
} else {
/* Debug operations can go straight to the guest */
vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDE;
}
+
+ /*
+ * If the guest debug register state is dirty (the guest is
+ * actively accessing them), then we context-switch the
+ * registers in EL2. Otherwise, we trap-and-emulate all guest
+ * accesses to them.
+ */
+ if (trap_debug)
+ vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
+ else
+ vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDA;
}
void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
{
- if (vcpu->guest_debug)
+ if (vcpu->guest_debug) {
restore_guest_debug_regs(vcpu);
+
+ /*
+ * If we were using HW debug we need to restore the
+ * debug_ptr to the guest debug state.
+ */
+ if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) {
+ vcpu->arch.debug_ptr = (struct kvm_guest_debug_arch *)
+ &vcpu_sys_reg(vcpu, DBGBCR0_EL1);
+ }
+ }
}
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index e9de13e..68a0759 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -103,7 +103,11 @@ static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu, struct kvm_run *run)
run->debug.arch.hsr = hsr;
switch (hsr >> ESR_ELx_EC_SHIFT) {
+ case ESR_ELx_EC_WATCHPT_LOW:
+ run->debug.arch.far = vcpu->arch.fault.far_el2;
+ /* fall through */
case ESR_ELx_EC_SOFTSTP_LOW:
+ case ESR_ELx_EC_BREAKPT_LOW:
case ESR_ELx_EC_BKPT32:
case ESR_ELx_EC_BRK64:
break;
@@ -132,6 +136,8 @@ static exit_handle_fn arm_exit_handlers[] = {
[ESR_ELx_EC_IABT_LOW] = kvm_handle_guest_abort,
[ESR_ELx_EC_DABT_LOW] = kvm_handle_guest_abort,
[ESR_ELx_EC_SOFTSTP_LOW]= kvm_handle_guest_debug,
+ [ESR_ELx_EC_WATCHPT_LOW]= kvm_handle_guest_debug,
+ [ESR_ELx_EC_BREAKPT_LOW]= kvm_handle_guest_debug,
[ESR_ELx_EC_BKPT32] = kvm_handle_guest_debug,
[ESR_ELx_EC_BRK64] = kvm_handle_guest_debug,
};
diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index dd51fb1..921d248 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -706,7 +706,8 @@ ENTRY(__kvm_vcpu_run)
bl __restore_fpsimd
skip_debug_state x3, 1f
- add x3, x2, #CPU_SYSREG_OFFSET(DBGBCR0_EL1)
+ ldr x3, [x0, #VCPU_DEBUG_PTR]
+ kern_hyp_va x3
bl __restore_debug
1:
restore_guest_32bit_state
@@ -727,7 +728,8 @@ __kvm_vcpu_return:
bl __save_sysregs
skip_debug_state x3, 1f
- add x3, x2, #CPU_SYSREG_OFFSET(DBGBCR0_EL1)
+ ldr x3, [x0, #VCPU_DEBUG_PTR]
+ kern_hyp_va x3
bl __save_debug
1:
save_guest_32bit_state
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 0b43265..21d5a62 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -56,6 +56,12 @@ static bool cpu_has_32bit_el1(void)
return !!(pfr0 & 0x20);
}
+/**
+ * kvm_arch_dev_ioctl_check_extension
+ *
+ * We currently assume that the number of HW registers is uniform
+ * across all CPUs (see cpuinfo_sanity_check).
+ */
int kvm_arch_dev_ioctl_check_extension(long ext)
{
int r;
@@ -64,6 +70,12 @@ int kvm_arch_dev_ioctl_check_extension(long ext)
case KVM_CAP_ARM_EL1_32BIT:
r = cpu_has_32bit_el1();
break;
+ case KVM_CAP_GUEST_DEBUG_HW_BPS:
+ r = get_num_brps();
+ break;
+ case KVM_CAP_GUEST_DEBUG_HW_WPS:
+ r = get_num_wrps();
+ break;
default:
r = 0;
}
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 3b6252e..923c2aa 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -825,6 +825,8 @@ struct kvm_ppc_smmu_info {
#define KVM_CAP_S390_INJECT_IRQ 113
#define KVM_CAP_S390_IRQ_STATE 114
#define KVM_CAP_PPC_HWRNG 115
+#define KVM_CAP_GUEST_DEBUG_HW_BPS 116
+#define KVM_CAP_GUEST_DEBUG_HW_WPS 117
#ifdef KVM_CAP_IRQ_ROUTING
--
2.3.5
_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
^ permalink raw reply related
* Re: [PATCH 00/19] converting system calls to 64-bit time_t, part 1
From: Arnd Bergmann @ 2015-05-07 8:52 UTC (permalink / raw)
To: Paul Bolle
Cc: y2038, baolin.wang, tglx, albert.aribaud, john.stultz,
bamvor.zhangjian, ruchandani.tina, linux-api, linux-kernel,
libc-alpha
In-Reply-To: <1430984358.8171.28.camel@x220>
On Thursday 07 May 2015 09:39:18 Paul Bolle wrote:
> On Thu, 2015-05-07 at 09:27 +0200, Paul Bolle wrote:
> > On Wed, 2015-05-06 at 18:30 +0200, Arnd Bergmann wrote:
> > > * After all system calls are converted, we can change one architecture
> > > at a time to select ARCH_HAS_COMPAT_TIME, and modify its system
> > > call table accordingly. In this version, I do it for ARM32, x86-32,
> > > and x86-64 for demonstration purposes.
> >
> > Perhaps this was correct for your first draft. Because this series adds
> > ARCH_HAS_COMPAT_TIME in 04/19, but it doesn't add any selects of that
> > symbol, does it? As far as I can see ARCH_HAS_COMPAT_TIME simply
> > functions as an alias for COMPAT in this series.
It is still the intention of the patch to add the selects in the later
patches that are required to see any benefit of the earlier patches.
ARCH_HAS_COMPAT_TIME is in the "x86: use COMPAT_SYS_TIME" and
"ARM: use CONFIG_COMPAT_TIME" patches of the full series available
on my git tree.
I realize the downsides of not posting the entire series at once
here, but it seemed better to avoid spamming everyone too much,
while I try to find out if we have agreement on the overall
strategy.
For reference, see below for the ARM patch.
> > > * A follow-up series changes over all other architectures.
> > >
> > > * The last patch in the series changes the CONFIG_COMPAT_TIME
> > > Kconfig symbol to be user visible. Disabling this symbol will
> > > get you a kernel that intentionally breaks support for old tasks
> > > in order to provide an interface that will survive 2038.
> >
> > This doesn't happen in 19/19, or in any other patch in this series.
> > Maybe also something that has changed since the first draft.
> >
> > > This is meant mostly as a debugging help for now, to let people
> > > build a y2038 safe distro, but at some point in the 2030s, we
> > > should remove that option and all the compat handling.
>
> And then it occurred to me to check the y2038-syscalls git branch you
> referenced. After which the above made much more sense. (Though my
> remark that ARCH_HAS_COMPAT_TIME simply functions as an alias for COMPAT
> also seems to hold for that branch.)
Right, in fact both of these happen at the end of the git tree.
Arnd
8<-------
commit 93a8526e02b6e29888df516e5750cd6483ee4472
Author: Arnd Bergmann <arnd@arndb.de>
Date: Fri Apr 24 17:12:08 2015 +0200
ARM: use CONFIG_COMPAT_TIME
This changes the ARM architecture to use the new compat system call
definitions that were added in previous patches. All system calls
that use 32-bit time_t now go through the COMPAT framework, while
a set of 25 new system calls gets added to replace them using 64-bit
data structures __kernel_timespec, __kernel_itimerspec,
__kernel_rusage, __kernel_msqid_ds, __kernel_semid_ds, __kernel_shmid_ds
and __kernel_stat.
Similarly, we add all the new system calls to the arm64 compat syscall
table.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
--
arch/arm/Kconfig | 1 +
arch/arm/include/asm/unistd.h | 11 ++--
arch/arm/include/uapi/asm/unistd.h | 22 ++++++++
arch/arm/kernel/calls.S | 101 +++++++++++++++++++++++--------------
arch/arm/kernel/sys_oabi-compat.c | 9 ++--
arch/arm64/include/asm/unistd32.h | 44 ++++++++++++++++
6 files changed, 142 insertions(+), 46 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 45df48ba0b12..491896833c76 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -2,6 +2,7 @@ config ARM
bool
default y
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
+ select ARCH_HAS_COMPAT_TIME
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_HAVE_CUSTOM_GPIO_H
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index 32640c431a08..ad7588eb9d58 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -19,7 +19,7 @@
* This may need to be greater than __NR_last_syscall+1 in order to
* account for the padding in the syscall table
*/
-#define __NR_syscalls (388)
+#define __NR_syscalls (412)
/*
* *NOTE*: This is a ghost syscall private to the kernel. Only the
@@ -28,7 +28,9 @@
*/
#define __ARM_NR_cmpxchg (__ARM_NR_BASE+0x00fff0)
+#ifdef CONFIG_COMPAT_TIME
#define __ARCH_WANT_STAT64
+#endif
#define __ARCH_WANT_SYS_GETHOSTNAME
#define __ARCH_WANT_SYS_PAUSE
#define __ARCH_WANT_SYS_GETPGRP
@@ -40,11 +42,13 @@
#define __ARCH_WANT_SYS_OLD_SELECT
#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
-#define __ARCH_WANT_SYS_TIME
+#ifdef CONFIG_COMPAT_TIME
+#define __ARCH_WANT_COMPAT_SYS_TIME
#define __ARCH_WANT_SYS_IPC
+#define __ARCH_WANT_SYS_UTIME
+#endif
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_ALARM
-#define __ARCH_WANT_SYS_UTIME
#define __ARCH_WANT_SYS_OLD_GETRLIMIT
#define __ARCH_WANT_OLD_READDIR
#define __ARCH_WANT_SYS_SOCKETCALL
@@ -52,6 +56,7 @@
#define __ARCH_WANT_SYS_FORK
#define __ARCH_WANT_SYS_VFORK
#define __ARCH_WANT_SYS_CLONE
+#define __ARCH_WANT_SYS_NEWFSTATAT
/*
* Unimplemented (or alternatively implemented) syscalls
diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h
index 0c3f5a0dafd3..4ea2d7312f15 100644
--- a/arch/arm/include/uapi/asm/unistd.h
+++ b/arch/arm/include/uapi/asm/unistd.h
@@ -414,6 +414,28 @@
#define __NR_memfd_create (__NR_SYSCALL_BASE+385)
#define __NR_bpf (__NR_SYSCALL_BASE+386)
#define __NR_execveat (__NR_SYSCALL_BASE+387)
+#define __NR_clock_gettime64 (__NR_SYSCALL_BASE+388)
+#define __NR_clock_settime64 (__NR_SYSCALL_BASE+389)
+#define __NR_clock_adjtime64 (__NR_SYSCALL_BASE+390)
+#define __NR_clock_getres64 (__NR_SYSCALL_BASE+391)
+#define __NR_clock_nanosleep64 (__NR_SYSCALL_BASE+392)
+#define __NR_timer_gettime64 (__NR_SYSCALL_BASE+393)
+#define __NR_timer_settime64 (__NR_SYSCALL_BASE+394)
+#define __NR_timerfd_gettime64 (__NR_SYSCALL_BASE+395)
+#define __NR_timerfd_settime64 (__NR_SYSCALL_BASE+396)
+#define __NR_pselect64 (__NR_SYSCALL_BASE+397)
+#define __NR_ppoll64 (__NR_SYSCALL_BASE+398)
+#define __NR_io_getevents64 (__NR_SYSCALL_BASE+399)
+#define __NR_recvmmsg64 (__NR_SYSCALL_BASE+400)
+#define __NR_semtimedop64 (__NR_SYSCALL_BASE+401)
+#define __NR_mq_timedsend64 (__NR_SYSCALL_BASE+402)
+#define __NR_mq_timedreceive64 (__NR_SYSCALL_BASE+403)
+#define __NR_utimensat64 (__NR_SYSCALL_BASE+404)
+#define __NR_newfstat64 (__NR_SYSCALL_BASE+405)
+#define __NR_newfstatat64 (__NR_SYSCALL_BASE+406)
+#define __NR_rt_sigtimedwait64 (__NR_SYSCALL_BASE+407)
+#define __NR_getrusage64 (__NR_SYSCALL_BASE+408)
+#define __NR_waitid64 (__NR_SYSCALL_BASE+409)
/*
* The following SWIs are ARM private.
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 05745eb838c5..092a2e1d979c 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -22,7 +22,7 @@
/* 10 */ CALL(sys_unlink)
CALL(sys_execve)
CALL(sys_chdir)
- CALL(OBSOLETE(sys_time)) /* used by libc4 */
+ CALL(OBSOLETE(compat_sys_time)) /* used by libc4 */
CALL(sys_mknod)
/* 15 */ CALL(sys_chmod)
CALL(sys_lchown16)
@@ -34,12 +34,12 @@
CALL(OBSOLETE(sys_oldumount)) /* used by libc4 */
CALL(sys_setuid16)
CALL(sys_getuid16)
-/* 25 */ CALL(OBSOLETE(sys_stime))
+/* 25 */ CALL(OBSOLETE(compat_sys_stime))
CALL(sys_ptrace)
CALL(OBSOLETE(sys_alarm)) /* used by libc4 */
CALL(sys_ni_syscall) /* was sys_fstat */
CALL(sys_pause)
-/* 30 */ CALL(OBSOLETE(sys_utime)) /* used by libc4 */
+/* 30 */ CALL(OBSOLETE(compat_sys_utime))/* used by libc4 */
CALL(sys_ni_syscall) /* was sys_stty */
CALL(sys_ni_syscall) /* was sys_getty */
CALL(sys_access)
@@ -86,12 +86,12 @@
CALL(sys_sethostname)
/* 75 */ CALL(sys_setrlimit)
CALL(OBSOLETE(sys_old_getrlimit)) /* used by libc4 */
- CALL(sys_getrusage)
- CALL(sys_gettimeofday)
- CALL(sys_settimeofday)
+ CALL(compat_sys_getrusage)
+ CALL(compat_sys_gettimeofday)
+ CALL(compat_sys_settimeofday)
/* 80 */ CALL(sys_getgroups16)
CALL(sys_setgroups16)
- CALL(OBSOLETE(sys_old_select)) /* used by libc4 */
+ CALL(OBSOLETE(compat_sys_old_select)) /* used by libc4 */
CALL(sys_symlink)
CALL(sys_ni_syscall) /* was sys_lstat */
/* 85 */ CALL(sys_readlink)
@@ -113,17 +113,17 @@
CALL(sys_ni_syscall) /* sys_ioperm */
CALL(OBSOLETE(ABI(sys_socketcall, sys_oabi_socketcall)))
CALL(sys_syslog)
- CALL(sys_setitimer)
-/* 105 */ CALL(sys_getitimer)
- CALL(sys_newstat)
- CALL(sys_newlstat)
- CALL(sys_newfstat)
+ CALL(compat_sys_setitimer)
+/* 105 */ CALL(compat_sys_getitimer)
+ CALL(compat_sys_newstat)
+ CALL(compat_sys_newlstat)
+ CALL(compat_sys_newfstat)
CALL(sys_ni_syscall) /* was sys_uname */
/* 110 */ CALL(sys_ni_syscall) /* was sys_iopl */
CALL(sys_vhangup)
CALL(sys_ni_syscall)
CALL(OBSOLETE(sys_syscall)) /* call a syscall */
- CALL(sys_wait4)
+ CALL(compat_sys_wait4)
/* 115 */ CALL(sys_swapoff)
CALL(sys_sysinfo)
CALL(OBSOLETE(ABI(sys_ipc, sys_oabi_ipc)))
@@ -133,7 +133,7 @@
CALL(sys_setdomainname)
CALL(sys_newuname)
CALL(sys_ni_syscall) /* modify_ldt */
- CALL(sys_adjtimex)
+ CALL(compat_sys_adjtimex)
/* 125 */ CALL(sys_mprotect)
CALL(sys_sigprocmask)
CALL(sys_ni_syscall) /* was sys_create_module */
@@ -151,7 +151,7 @@
CALL(sys_setfsgid16)
/* 140 */ CALL(sys_llseek)
CALL(sys_getdents)
- CALL(sys_select)
+ CALL(compat_sys_select)
CALL(sys_flock)
CALL(sys_msync)
/* 145 */ CALL(sys_readv)
@@ -170,8 +170,8 @@
CALL(sys_sched_yield)
CALL(sys_sched_get_priority_max)
/* 160 */ CALL(sys_sched_get_priority_min)
- CALL(sys_sched_rr_get_interval)
- CALL(sys_nanosleep)
+ CALL(compat_sys_sched_rr_get_interval)
+ CALL(compat_sys_nanosleep)
CALL(sys_mremap)
CALL(sys_setresuid16)
/* 165 */ CALL(sys_getresuid16)
@@ -186,7 +186,7 @@
CALL(sys_rt_sigaction)
/* 175 */ CALL(sys_rt_sigprocmask)
CALL(sys_rt_sigpending)
- CALL(sys_rt_sigtimedwait)
+ CALL(compat_sys_rt_sigtimedwait)
CALL(sys_rt_sigqueueinfo)
CALL(sys_rt_sigsuspend)
/* 180 */ CALL(ABI(sys_pread64, sys_oabi_pread64))
@@ -249,12 +249,12 @@
CALL(sys_fremovexattr)
CALL(sys_tkill)
CALL(sys_sendfile64)
-/* 240 */ CALL(sys_futex)
+/* 240 */ CALL(compat_sys_futex)
CALL(sys_sched_setaffinity)
CALL(sys_sched_getaffinity)
CALL(sys_io_setup)
CALL(sys_io_destroy)
-/* 245 */ CALL(sys_io_getevents)
+/* 245 */ CALL(compat_sys_io_getevents)
CALL(sys_io_submit)
CALL(sys_io_cancel)
CALL(sys_exit_group)
@@ -267,29 +267,29 @@
/* 255 */ CALL(sys_ni_syscall) /* sys_get_thread_area */
CALL(sys_set_tid_address)
CALL(sys_timer_create)
- CALL(sys_timer_settime)
- CALL(sys_timer_gettime)
+ CALL(compat_sys_timer_settime)
+ CALL(compat_sys_timer_gettime)
/* 260 */ CALL(sys_timer_getoverrun)
CALL(sys_timer_delete)
- CALL(sys_clock_settime)
- CALL(sys_clock_gettime)
- CALL(sys_clock_getres)
-/* 265 */ CALL(sys_clock_nanosleep)
+ CALL(compat_sys_clock_settime)
+ CALL(compat_sys_clock_gettime)
+ CALL(compat_sys_clock_getres)
+/* 265 */ CALL(compat_sys_clock_nanosleep)
CALL(sys_statfs64_wrapper)
CALL(sys_fstatfs64_wrapper)
CALL(sys_tgkill)
- CALL(sys_utimes)
+ CALL(compat_sys_utimes)
/* 270 */ CALL(sys_arm_fadvise64_64)
CALL(sys_pciconfig_iobase)
CALL(sys_pciconfig_read)
CALL(sys_pciconfig_write)
CALL(sys_mq_open)
/* 275 */ CALL(sys_mq_unlink)
- CALL(sys_mq_timedsend)
- CALL(sys_mq_timedreceive)
+ CALL(compat_sys_mq_timedsend)
+ CALL(compat_sys_mq_timedreceive)
CALL(sys_mq_notify)
CALL(sys_mq_getsetattr)
-/* 280 */ CALL(sys_waitid)
+/* 280 */ CALL(compat_sys_waitid)
CALL(sys_socket)
CALL(ABI(sys_bind, sys_oabi_bind))
CALL(ABI(sys_connect, sys_oabi_connect))
@@ -321,7 +321,7 @@
CALL(sys_add_key)
/* 310 */ CALL(sys_request_key)
CALL(sys_keyctl)
- CALL(ABI(sys_semtimedop, sys_oabi_semtimedop))
+ CALL(ABI(compat_sys_semtimedop, sys_oabi_semtimedop))
/* vserver */ CALL(sys_ni_syscall)
CALL(sys_ioprio_set)
/* 315 */ CALL(sys_ioprio_get)
@@ -335,7 +335,7 @@
CALL(sys_mkdirat)
CALL(sys_mknodat)
/* 325 */ CALL(sys_fchownat)
- CALL(sys_futimesat)
+ CALL(compat_sys_futimesat)
CALL(ABI(sys_fstatat64, sys_oabi_fstatat64))
CALL(sys_unlinkat)
CALL(sys_renameat)
@@ -344,8 +344,8 @@
CALL(sys_readlinkat)
CALL(sys_fchmodat)
CALL(sys_faccessat)
-/* 335 */ CALL(sys_pselect6)
- CALL(sys_ppoll)
+/* 335 */ CALL(compat_sys_pselect6)
+ CALL(compat_sys_ppoll)
CALL(sys_unshare)
CALL(sys_set_robust_list)
CALL(sys_get_robust_list)
@@ -357,13 +357,13 @@
/* 345 */ CALL(sys_getcpu)
CALL(sys_epoll_pwait)
CALL(sys_kexec_load)
- CALL(sys_utimensat)
+ CALL(compat_sys_utimensat)
CALL(sys_signalfd)
/* 350 */ CALL(sys_timerfd_create)
CALL(sys_eventfd)
CALL(sys_fallocate)
- CALL(sys_timerfd_settime)
- CALL(sys_timerfd_gettime)
+ CALL(compat_sys_timerfd_settime)
+ CALL(compat_sys_timerfd_gettime)
/* 355 */ CALL(sys_signalfd4)
CALL(sys_eventfd2)
CALL(sys_epoll_create1)
@@ -374,14 +374,14 @@
CALL(sys_pwritev)
CALL(sys_rt_tgsigqueueinfo)
CALL(sys_perf_event_open)
-/* 365 */ CALL(sys_recvmmsg)
+/* 365 */ CALL(compat_sys_recvmmsg)
CALL(sys_accept4)
CALL(sys_fanotify_init)
CALL(sys_fanotify_mark)
CALL(sys_prlimit64)
/* 370 */ CALL(sys_name_to_handle_at)
CALL(sys_open_by_handle_at)
- CALL(sys_clock_adjtime)
+ CALL(compat_sys_clock_adjtime)
CALL(sys_syncfs)
CALL(sys_sendmmsg)
/* 375 */ CALL(sys_setns)
@@ -397,6 +397,29 @@
/* 385 */ CALL(sys_memfd_create)
CALL(sys_bpf)
CALL(sys_execveat)
+ CALL(sys_clock_gettime)
+ CALL(sys_clock_settime)
+/* 390 */ CALL(sys_clock_adjtime)
+ CALL(sys_clock_getres)
+ CALL(sys_clock_nanosleep)
+ CALL(sys_timer_gettime)
+ CALL(sys_timer_settime)
+/* 395 */ CALL(sys_timerfd_gettime)
+ CALL(sys_timerfd_settime)
+ CALL(sys_pselect6)
+ CALL(sys_ppoll)
+ CALL(sys_io_getevents)
+/* 400 */ CALL(sys_recvmmsg)
+ CALL(sys_semtimedop)
+ CALL(sys_mq_timedsend)
+ CALL(sys_mq_timedreceive)
+ CALL(sys_utimensat)
+/* 405 */ CALL(sys_newfstat)
+ CALL(sys_newfstatat)
+ CALL(sys_rt_sigtimedwait)
+ CALL(sys_getrusage)
+ CALL(sys_waitid)
+
#ifndef syscalls_counted
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
#define syscalls_counted
diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c
index b83f3b7737fb..2e990b564371 100644
--- a/arch/arm/kernel/sys_oabi-compat.c
+++ b/arch/arm/kernel/sys_oabi-compat.c
@@ -73,6 +73,7 @@
* wrappers provided below.
*/
+#include <linux/compat_time.h>
#include <linux/syscalls.h>
#include <linux/errno.h>
#include <linux/fs.h>
@@ -307,10 +308,10 @@ struct oabi_sembuf {
asmlinkage long sys_oabi_semtimedop(int semid,
struct oabi_sembuf __user *tsops,
unsigned nsops,
- const struct timespec __user *timeout)
+ const struct compat_timespec __user *timeout)
{
struct sembuf *sops;
- struct timespec local_timeout;
+ struct compat_timespec local_timeout;
long err;
int i;
@@ -336,7 +337,7 @@ asmlinkage long sys_oabi_semtimedop(int semid,
} else {
mm_segment_t fs = get_fs();
set_fs(KERNEL_DS);
- err = sys_semtimedop(semid, sops, nsops, timeout);
+ err = compat_sys_semtimedop(semid, sops, nsops, timeout);
set_fs(fs);
}
kfree(sops);
@@ -361,7 +362,7 @@ asmlinkage int sys_oabi_ipc(uint call, int first, int second, int third,
return sys_oabi_semtimedop(first,
(struct oabi_sembuf __user *)ptr,
second,
- (const struct timespec __user *)fifth);
+ (const struct compat_timespec __user *)fifth);
default:
return sys_ipc(call, first, second, third, ptr, fifth);
}
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
index cef934a90f17..1659a0c68ea3 100644
--- a/arch/arm64/include/asm/unistd32.h
+++ b/arch/arm64/include/asm/unistd32.h
@@ -797,3 +797,47 @@ __SYSCALL(__NR_memfd_create, sys_memfd_create)
__SYSCALL(__NR_bpf, sys_bpf)
#define __NR_execveat 387
__SYSCALL(__NR_execveat, compat_sys_execveat)
+#define __NR_clock_gettime64 388
+_SYSCALL(__NR_clock_gettime64, sys_clock_gettime)
+#define __NR_clock_settime64 389
+_SYSCALL(__NR_clock_settime64, sys_clock_settime)
+#define __NR_clock_adjtime64 390
+_SYSCALL(__NR_clock_adjtime64, sys_clock_adjtime)
+#define __NR_clock_getres64 391
+_SYSCALL(__NR_clock_getres64, sys_clock_getres)
+#define __NR_clock_nanosleep64 392
+_SYSCALL(__NR_clock_nanosleep64, sys_clock_nanosleep)
+#define __NR_timer_gettime64 393
+_SYSCALL(__NR_timer_gettime64, sys_timer_gettime)
+#define __NR_timer_settime64 394
+_SYSCALL(__NR_timer_settime64, sys_timer_settime)
+#define __NR_timerfd_gettime64 395
+_SYSCALL(__NR_timerfd_gettime64, sys_timerfd_gettime)
+#define __NR_timerfd_settime64 396
+_SYSCALL(__NR_timerfd_settime64, sys_timerfd_settime)
+#define __NR_pselect64 397
+_SYSCALL(__NR_pselect64, compat_sys_pselect6_time64)
+#define __NR_ppoll64 398
+_SYSCALL(__NR_ppoll64, compat_sys_ppoll_time64)
+#define __NR_io_getevents64 399
+_SYSCALL(__NR_io_getevents64, sys_io_getevents)
+#define __NR_recvmmsg64 400
+_SYSCALL(__NR_recvmmsg64, compat_sys_recvmmsg64)
+#define __NR_semtimedop64 401
+_SYSCALL(__NR_semtimedop64, sys_semtimedop)
+#define __NR_mq_timedsend64 402
+_SYSCALL(__NR_mq_timedsend64, sys_mq_timedsend)
+#define __NR_mq_timedreceive64 403
+_SYSCALL(__NR_mq_timedreceive64, sys_mq_timedreceive)
+#define __NR_utimensat64 404
+_SYSCALL(__NR_utimensat64, sys_utimensat)
+#define __NR_newfstat64 405
+_SYSCALL(__NR_newfstat64, sys_newfstat)
+#define __NR_newfstatat64 406
+_SYSCALL(__NR_newfstatat64, sys_newfstatat)
+#define __NR_rt_sigtimedwait64 407
+_SYSCALL(__NR_rt_sigtimedwait64, compat_sys_rt_sigtimedwait_time64)
+#define __NR_getrusage64 408
+_SYSCALL(__NR_getrusage64, sys_getrusage)
+#define __NR_waitid64 409
+_SYSCALL(__NR_waitid64, compat_sys_waitid_time64)
^ permalink raw reply related
* RE: [PATCH v2] manpage: update FALLOC_FL_INSERT_RANGE flag in fallocate
From: Namjae Jeon @ 2015-05-07 8:29 UTC (permalink / raw)
To: 'Michael Kerrisk (man-pages)'
Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-man-u79uwXL29TY76Z2rM5mHXA, 'Linux API',
'Dave Chinner', 'Theodore Ts'o'
In-Reply-To: <554B2011.5010703-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Hello Namjae Jeon,
Hi Michael,
>
> Thanks for the revised patch. I have a question below:
>
> On 05/07/2015 07:15 AM, Namjae Jeon wrote:
> > Update FALLOC_FL_INSERT_RANGE flag in fallocate.
> >
> > Signed-off-by: Namjae Jeon <namjae.jeon-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> > Signed-off-by: Ashish Sangwan <a.sangwan-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> > ---
> > man2/fallocate.2 | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
> > 1 file changed, 84 insertions(+), 5 deletions(-)
> >
> > diff --git a/man2/fallocate.2 b/man2/fallocate.2
> > index 0cc1a00..0d31027 100644
> > --- a/man2/fallocate.2
> > +++ b/man2/fallocate.2
> > @@ -228,6 +228,59 @@ ext4, for extent-based files (since Linux 3.15)
> > .IP *
> > SMB3 (since Linux 3.17)
> > .\" commit 30175628bf7f521e9ee31ac98fa6d6fe7441a556
> > +.SS Increasing file space
> > +flag (available since Linux 4.1)
> > +.\" commit dd46c787788d5bf5b974729d43e4c405814a4c7d
> > +Specifying the
> > +.BR FALLOC_FL_INSERT_RANGE
> > +flag in
> > +.I mode
> > +will increase the file space by inserting a hole within the file size without
> > +overwriting any existing data.
> > +The hole will start at
> > +.I offset
> > +and continue for
> > +.I len
> > +bytes.
> > +For inserting hole inside file, the contents of the file starting at
> > +.I offset
> > +will be shifted towards right by
> > +.I len
> > +bytes.
> > +Inserting a hole inside the file will increase the file size by
> > +.I len
> > +bytes.
> > +
> > +This mode has the same limitation as
> > +.BR FALLOC_FL_COLLAPSE_RANGE
> > +regarding the
> > +granularity of the operation.
> > +If the granularity requirements are not met,
> > +.BR fallocate ()
> > +will fail with the error
> > +.BR EINVAL.
> > +If the
> > +.I offset
> > +overlaps with end of file OR if it is greater than end of file, an error is
>
>
> Could that last line not be simplified to
>
> if the offset is greater than or equal to the end of file
>
> ?
Yes, Looks good :)
Thanks!!
>
> Thanks,
>
> Michael
>
>
> --
> Michael Kerrisk
> Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
> Linux/UNIX System Programming Training: http://man7.org/training/
--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2] manpage: update FALLOC_FL_INSERT_RANGE flag in fallocate
From: Michael Kerrisk (man-pages) @ 2015-05-07 8:19 UTC (permalink / raw)
To: Namjae Jeon
Cc: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-man-u79uwXL29TY76Z2rM5mHXA, Linux API, Dave Chinner,
Theodore Ts'o
In-Reply-To: <006d01d08884$dcfc7ea0$96f57be0$@samsung.com>
Hello Namjae Jeon,
Thanks for the revised patch. I have a question below:
On 05/07/2015 07:15 AM, Namjae Jeon wrote:
> Update FALLOC_FL_INSERT_RANGE flag in fallocate.
>
> Signed-off-by: Namjae Jeon <namjae.jeon-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> Signed-off-by: Ashish Sangwan <a.sangwan-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> ---
> man2/fallocate.2 | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 84 insertions(+), 5 deletions(-)
>
> diff --git a/man2/fallocate.2 b/man2/fallocate.2
> index 0cc1a00..0d31027 100644
> --- a/man2/fallocate.2
> +++ b/man2/fallocate.2
> @@ -228,6 +228,59 @@ ext4, for extent-based files (since Linux 3.15)
> .IP *
> SMB3 (since Linux 3.17)
> .\" commit 30175628bf7f521e9ee31ac98fa6d6fe7441a556
> +.SS Increasing file space
> +flag (available since Linux 4.1)
> +.\" commit dd46c787788d5bf5b974729d43e4c405814a4c7d
> +Specifying the
> +.BR FALLOC_FL_INSERT_RANGE
> +flag in
> +.I mode
> +will increase the file space by inserting a hole within the file size without
> +overwriting any existing data.
> +The hole will start at
> +.I offset
> +and continue for
> +.I len
> +bytes.
> +For inserting hole inside file, the contents of the file starting at
> +.I offset
> +will be shifted towards right by
> +.I len
> +bytes.
> +Inserting a hole inside the file will increase the file size by
> +.I len
> +bytes.
> +
> +This mode has the same limitation as
> +.BR FALLOC_FL_COLLAPSE_RANGE
> +regarding the
> +granularity of the operation.
> +If the granularity requirements are not met,
> +.BR fallocate ()
> +will fail with the error
> +.BR EINVAL.
> +If the
> +.I offset
> +overlaps with end of file OR if it is greater than end of file, an error is
Could that last line not be simplified to
if the offset is greater than or equal to the end of file
?
Thanks,
Michael
--
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/
^ permalink raw reply
* Re: [PATCH 00/19] converting system calls to 64-bit time_t, part 1
From: Paul Bolle @ 2015-05-07 7:39 UTC (permalink / raw)
To: Arnd Bergmann
Cc: y2038, baolin.wang, tglx, albert.aribaud, john.stultz,
bamvor.zhangjian, ruchandani.tina, linux-api, linux-kernel,
libc-alpha
In-Reply-To: <1430983678.8171.23.camel@x220>
On Thu, 2015-05-07 at 09:27 +0200, Paul Bolle wrote:
> On Wed, 2015-05-06 at 18:30 +0200, Arnd Bergmann wrote:
> > * After all system calls are converted, we can change one architecture
> > at a time to select ARCH_HAS_COMPAT_TIME, and modify its system
> > call table accordingly. In this version, I do it for ARM32, x86-32,
> > and x86-64 for demonstration purposes.
>
> Perhaps this was correct for your first draft. Because this series adds
> ARCH_HAS_COMPAT_TIME in 04/19, but it doesn't add any selects of that
> symbol, does it? As far as I can see ARCH_HAS_COMPAT_TIME simply
> functions as an alias for COMPAT in this series.
>
> > * A follow-up series changes over all other architectures.
> >
> > * The last patch in the series changes the CONFIG_COMPAT_TIME
> > Kconfig symbol to be user visible. Disabling this symbol will
> > get you a kernel that intentionally breaks support for old tasks
> > in order to provide an interface that will survive 2038.
>
> This doesn't happen in 19/19, or in any other patch in this series.
> Maybe also something that has changed since the first draft.
>
> > This is meant mostly as a debugging help for now, to let people
> > build a y2038 safe distro, but at some point in the 2030s, we
> > should remove that option and all the compat handling.
And then it occurred to me to check the y2038-syscalls git branch you
referenced. After which the above made much more sense. (Though my
remark that ARCH_HAS_COMPAT_TIME simply functions as an alias for COMPAT
also seems to hold for that branch.)
Paul Bolle
^ permalink raw reply
* Re: [PATCH 00/19] converting system calls to 64-bit time_t, part 1
From: Paul Bolle @ 2015-05-07 7:27 UTC (permalink / raw)
To: Arnd Bergmann
Cc: y2038-cunTk1MwBs8s++Sfvej+rw, baolin.wang-QSEj5FYQhm4dnm+yROfE0A,
tglx-hfZtesqFncYOwBW4kG4KsQ, albert.aribaud-iEu9NFBzPZE,
john.stultz-QSEj5FYQhm4dnm+yROfE0A,
bamvor.zhangjian-QSEj5FYQhm4dnm+yROfE0A,
ruchandani.tina-Re5JQEeQqe8AvxtiuMwx3w,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
libc-alpha-9JcytcrH/bA+uJoB2kUjGw
In-Reply-To: <1430929826-318934-1-git-send-email-arnd-r2nGTMty4D4@public.gmane.org>
On Wed, 2015-05-06 at 18:30 +0200, Arnd Bergmann wrote:
> * After all system calls are converted, we can change one architecture
> at a time to select ARCH_HAS_COMPAT_TIME, and modify its system
> call table accordingly. In this version, I do it for ARM32, x86-32,
> and x86-64 for demonstration purposes.
Perhaps this was correct for your first draft. Because this series adds
ARCH_HAS_COMPAT_TIME in 04/19, but it doesn't add any selects of that
symbol, does it? As far as I can see ARCH_HAS_COMPAT_TIME simply
functions as an alias for COMPAT in this series.
> * A follow-up series changes over all other architectures.
>
> * The last patch in the series changes the CONFIG_COMPAT_TIME
> Kconfig symbol to be user visible. Disabling this symbol will
> get you a kernel that intentionally breaks support for old tasks
> in order to provide an interface that will survive 2038.
This doesn't happen in 19/19, or in any other patch in this series.
Maybe also something that has changed since the first draft.
> This is meant mostly as a debugging help for now, to let people
> build a y2038 safe distro, but at some point in the 2030s, we
> should remove that option and all the compat handling.
Thanks,
Paul Bolle
^ permalink raw reply
* [PATCH v2] manpage: update FALLOC_FL_INSERT_RANGE flag in fallocate
From: Namjae Jeon @ 2015-05-07 5:15 UTC (permalink / raw)
To: Michael Kerrisk
Cc: linux-fsdevel, linux-kernel, linux-man, Linux API, Dave Chinner,
Theodore Ts'o
Update FALLOC_FL_INSERT_RANGE flag in fallocate.
Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
Signed-off-by: Ashish Sangwan <a.sangwan@samsung.com>
---
man2/fallocate.2 | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 84 insertions(+), 5 deletions(-)
diff --git a/man2/fallocate.2 b/man2/fallocate.2
index 0cc1a00..0d31027 100644
--- a/man2/fallocate.2
+++ b/man2/fallocate.2
@@ -228,6 +228,59 @@ ext4, for extent-based files (since Linux 3.15)
.IP *
SMB3 (since Linux 3.17)
.\" commit 30175628bf7f521e9ee31ac98fa6d6fe7441a556
+.SS Increasing file space
+flag (available since Linux 4.1)
+.\" commit dd46c787788d5bf5b974729d43e4c405814a4c7d
+Specifying the
+.BR FALLOC_FL_INSERT_RANGE
+flag in
+.I mode
+will increase the file space by inserting a hole within the file size without
+overwriting any existing data.
+The hole will start at
+.I offset
+and continue for
+.I len
+bytes.
+For inserting hole inside file, the contents of the file starting at
+.I offset
+will be shifted towards right by
+.I len
+bytes.
+Inserting a hole inside the file will increase the file size by
+.I len
+bytes.
+
+This mode has the same limitation as
+.BR FALLOC_FL_COLLAPSE_RANGE
+regarding the
+granularity of the operation.
+If the granularity requirements are not met,
+.BR fallocate ()
+will fail with the error
+.BR EINVAL.
+If the
+.I offset
+overlaps with end of file OR if it is greater than end of file, an error is
+returned.
+For such type of operations, i.e. inserting a hole at the end of file,
+.BR ftruncate(2)
+should be used.
+In case
+.IR offset + len
+exceeds the maximum file size, errno will be set to
+.B EFBIG.
+
+No other flags may be specified in
+.IR mode
+in conjunction with
+.BR FALLOC_FL_INSERT_RANGE .
+
+As of Linux 4.1,
+.B FALLOC_FL_INSERT_RANGE
+is supported by
+XFS.
+.\" commit a904b1ca5751faf5ece8600e18cd3b674afcca1b
.SH RETURN VALUE
On success,
.BR fallocate ()
@@ -245,6 +298,12 @@ is not a valid file descriptor, or is not opened for writing.
.IR offset + len
exceeds the maximum file size.
.TP
+.B EFBIG
+.I mode
+is
+.BR FALLOC_FL_INSERT_RANGE ,
+the current file size+len exceeds the maximum file size.
+.TP
.B EINTR
A signal was caught during execution.
.TP
@@ -273,7 +332,17 @@ reaches or passes the end of the file.
.B EINVAL
.I mode
is
-.BR FALLOC_FL_COLLAPSE_RANGE ,
+.BR FALLOC_FL_INSERT_RANGE
+and the range specified by
+.I offset
+reaches or passes the end of the file.
+.TP
+.B EINVAL
+.I mode
+is
+.BR FALLOC_FL_COLLAPSE_RANGE
+or
+.BR FALLOC_FL_INSERT_RANGE ,
but either
.I offset
or
@@ -282,18 +351,24 @@ is not a multiple of the filesystem block size.
.TP
.B EINVAL
.I mode
-contains both
+contains either of
.B FALLOC_FL_COLLAPSE_RANGE
+or
+.B FALLOC_FL_INSERT_RANGE
and other flags;
no other flags are permitted with
-.BR FALLOC_FL_COLLAPSE_RANGE .
+.BR FALLOC_FL_COLLAPSE_RANGE
+or
+.BR FALLOC_FL_INSERT_RANGE .
.TP
.B EINVAL
.I mode
is
.BR FALLOC_FL_COLLAPSE_RANGE
or
-.BR FALLOC_FL_ZERO_RANGE ,
+.BR FALLOC_FL_ZERO_RANGE
+or
+.BR FALLOC_FL_INSERT_RANGE ,
but the file referred to by
.I fd
is not a regular file.
@@ -345,6 +420,8 @@ specifies
.BR FALLOC_FL_PUNCH_HOLE
or
.BR FALLOC_FL_COLLAPSE_RANGE
+or
+.BR FALLOC_FL_INSERT_RANGE
and
the file referred to by
.I fd
@@ -363,7 +440,9 @@ refers to a pipe or FIFO.
.B ETXTBSY
.I mode
specifies
-.BR FALLOC_FL_COLLAPSE_RANGE ,
+.BR FALLOC_FL_COLLAPSE_RANGE
+or
+.BR FALLOC_FL_INSERT_RANGE ,
but the file referred to by
.IR fd
is currently being executed.
--
1.8.5.5
^ permalink raw reply related
* Re: [PATCH RFC 0/3] simple copy offloading system call
From: Andy Lutomirski @ 2015-05-07 2:52 UTC (permalink / raw)
To: Michael Kerrisk
Cc: Linux FS Devel, linux-kernel@vger.kernel.org, Linux API,
Linux SCSI List, linux-nfs, Linux btrfs Developers List,
Zach Brown
In-Reply-To: <CAHO5Pa0UEhOC3vqP9Nq4+gEH_OJPG6dgoLM9XbRLOfTRsRVSCw@mail.gmail.com>
On May 6, 2015 11:45 AM, "Michael Kerrisk" <mtk.manpages@gmail.com> wrote:
>
> [CC += linux-api@vger.kernel.org]
>
> Zach,
>
> Since this is a kernel-user-space API change, please CC linux-api@.
> The kernel source file Documentation/SubmitChecklist notes that all
> Linux kernel patches that change userspace interfaces should be CCed
> to linux-api@vger.kernel.org, so that the various parties who are
> interested in API changes are informed. For further information, see
> https://www.kernel.org/doc/man-pages/linux-api-ml.html
>
> Thanks,
>
> Michael
>
>
>
>
> On Sat, Apr 11, 2015 at 12:00 AM, Zach Brown <zab@redhat.com> wrote:
> > Hello everyone!
> >
> > Here's my current attempt at the most basic system call interface for
> > offloading copying between files. The system call and vfs function
> > are relatively light wrappers around the file_operation method that
> > does the heavy lifting.
> >
> > There was interest at LSF in getting the basic infrastructure merged
> > before worrying about adding behavioural flags and more complicated
> > implementations. This series only offers a refactoring of the btrfs
> > clone ioctl as an example of an implementation of the file
> > copy_file_range method.
> >
> > I've added support for copy_file_range() to xfs_io in xfsprogs and
> > have the start of an xfstest that tests the system call. I'll send
> > those to fstests@.
> >
> > So how does this look?
> >
> > Do we want to merge this and let the NFS and block XCOPY patches add
> > their changes when they're ready?
This sounds enough like splice that I'm wondering why the API isn't splice.
--Andy
^ permalink raw reply
* Re: [PATCH v18 for v4.1-rc2 1/3] sys_membarrier(): system-wide memory barrier (generic, x86)
From: Andy Lutomirski @ 2015-05-07 2:50 UTC (permalink / raw)
To: Linus Torvalds
Cc: Mathieu Desnoyers, Josh Triplett, Andrew Morton,
Linux Kernel Mailing List, KOSAKI Motohiro, Steven Rostedt,
Nicholas Miell, Ingo Molnar, Alan Cox, Lai Jiangshan,
Stephen Hemminger, Thomas Gleixner, Peter Zijlstra, David Howells,
Pranith Kumar, Michael Kerrisk, Linux API
In-Reply-To: <CA+55aFwQbE0pvb2XRRT33rDEwwwQHKN27w5A8f4GWWJ_j6w1EA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Wed, May 6, 2015 at 1:39 PM, Linus Torvalds
<torvalds-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org> wrote:
> On Wed, May 6, 2015 at 1:33 PM, Mathieu Desnoyers
> <mathieu.desnoyers-vg+e7yoeK/dWk0Htik3J/w@public.gmane.org> wrote:
>>
>> Will try moving those parts under a "---" in the commit
>> message, and hope it does what I intend.
>
> Yeah, that should do it for anybody who then uses "git am" to apply
> the patches you send out. It's kind of hacky, and I've always worried
> a bit that somebody uses "^---$' for real in a commit message and
> things get lost, but it is *such* a useful way to add notes to emails
> that aren't fit for actually committing, that the risk has never
> outweighed the benefits.
There's also 'git format-patch --notes', which is less hacky but more
complicated.
--Andy
>
> Linus
> --
> To unsubscribe from this list: send the line "unsubscribe linux-api" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Andy Lutomirski
AMA Capital Management, LLC
^ permalink raw reply
* Re: [PATCH RFC] vfs: add a O_NOMTIME flag
From: Dave Chinner @ 2015-05-07 0:26 UTC (permalink / raw)
To: Zach Brown
Cc: Alexander Viro, Sage Weil, linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1430949612-21356-1-git-send-email-zab-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
On Wed, May 06, 2015 at 03:00:12PM -0700, Zach Brown wrote:
> Add the O_NOMTIME flag which prevents mtime from being updated which can
> greatly reduce the IO overhead of writes to allocated and initialized
> regions of files.
Hmmm. How do backup programs now work out if the file has changed
and hence needs copying again? ie. applications using this will
break other critical infrastructure in subtle ways.
> ceph servers can have loads where they perform O_DIRECT overwrites of
> allocated file data and then sync to make sure that the O_DIRECT writes
> are flushed from write caches. If the writes dirty the inode with mtime
> updates then the syncs also write out the metadata needed to track the
> inodes which can add significant iop and latency overhead.
>
> The ceph servers don't use mtime at all. They're using the local file
> system as a backing store and any backups would be driven by their upper
> level ceph metadata. For ceph, slow IO from mtime updates in the file
> system is as daft as if we had block devices slowing down IO for
> per-block write timestamps that file systems never use.
>
> In simple tests a O_DIRECT|O_NOMTIME overwriting write followed by a
> sync went from 2 serial write round trips to 1 in XFS and from 4 serial
> IO round trips to 1 in ext4.
>
> file_update_time() checks for O_NOMTIME and aborts the update if it's
> set, just like the current check for the in-kernel inode flag
> S_NOCMTIME. I didn't update any other mtime update sites. They could be
> added as we decide that it's appropriate to do so.
>
> I opted not to name the flag O_NOCMTIME because I didn't want the name
> to imply that ctime updates would be prevented for other inode changes
> like updating i_size in truncate. Not updating ctime is a side-effect
> of removing mtime updates when it's the only thing changing in the
> inode.
If adding this, wouldn't we want to unify O_NOMTIME and
FMODE_NOCMTIME at the same time?
i.e. it makes no sense to add O_NOMTIME and not add O_NOCMTIME,
likewise it makes no sense to have two different "no mtime"
detection mechanisms. i.e. file_is_nomtime(file)) should return
true for both files opened with O_NOMTIME, files that have had
FMODE_NOCMTIME added to them and inodes with the S_NOCMTIME flag
set on them.
> The criteria for using O_NOMTIME is the same as for using O_NOATIME:
> owning the file or having the CAP_FOWNER capability. If we're not
> comfortable allowing owners to prevent mtime/ctime updates then we
> should add a tunable to allow O_NOMTIME. Maybe a mount option?
I dislike "turn off safety for performance" options because Joe
SpeedRacer will always select performance over safety.
Cheers,
Dave.
--
Dave Chinner
david-FqsqvQoI3Ljby3iVrkZq2A@public.gmane.org
^ permalink raw reply
* RE: [PATCH v10 12/12] manpage: update FALLOC_FL_INSERT_RANGE flag in fallocate
From: Namjae Jeon @ 2015-05-07 0:12 UTC (permalink / raw)
To: 'Michael Kerrisk (man-pages)'
Cc: linux-man, tytso, linux-api, bfoster, linux-kernel, xfs,
a.sangwan, linux-fsdevel, linux-ext4
In-Reply-To: <554A0C6D.8070408@gmail.com>
>
> Hello Namjae Jeon,
Hi Michael,
>
> I see that FALLOC_FL_INSERT_RANGE has hit mainline. Could I ask you refresh
> this patch, please? (Against latest man-pages Git, please, since the current
> patch does not apply cleanly).
Sure. I will fix your review points on latest man-pages git.
And currently only xfs support is applied to 4.1.
Thanks for your review!
>
> See some comments below.
>
> On 02/21/2015 04:45 PM, Namjae Jeon wrote:
> > From: Namjae Jeon <namjae.jeon@samsung.com>
> >
> > Update FALLOC_FL_INSERT_RANGE flag in fallocate.
> >
> > Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
> > Signed-off-by: Ashish Sangwan <a.sangwan@samsung.com>
> > ---
> > man2/fallocate.2 | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++----
> > 1 file changed, 82 insertions(+), 6 deletions(-)
> >
> > diff --git a/man2/fallocate.2 b/man2/fallocate.2
> > index adf42db..9b3c460 100644
> > --- a/man2/fallocate.2
> > +++ b/man2/fallocate.2
> > @@ -8,7 +8,7 @@
> > .\" 2011-09-19: Added FALLOC_FL_PUNCH_HOLE
> > .\" 2011-09-19: Substantial restructuring of the page
> > .\"
> > -.TH FALLOCATE 2 2015-01-22 "Linux" "Linux Programmer's Manual"
> > +.TH FALLOCATE 2 2015-02-14 "Linux" "Linux Programmer's Manual"
>
> No need to update the timestamp on the page. I have scripts
> that do this automatically.
>
> > .SH NAME
> > fallocate \- manipulate file space
> > .SH SYNOPSIS
> > @@ -225,6 +225,56 @@ XFS (since Linux 3.14)
> > .IP *
> > ext4, for extent-based files (since Linux 3.14)
> > .\" commit b8a8684502a0fc852afa0056c6bb2a9273f6fcc0
> > +.SS Increasing file space
> > +.\" TODO: Mention commit id and supporting Linux version
>
> Yes, please add the commit ID and "Linux 4.1".
>
> > +Specifying the
> > +.BR FALLOC_FL_INSERT_RANGE
> > +flag in
> > +.I mode
> > +will increase the file space by inserting a hole within the file size without
> > +overwriting any existing data. The hole will start at
> ^
> Please start new sentences on new source lines. (Same thing at various
> lines below.)
>
> > +.I offset
> > +and continue for
> > +.I len
> > +bytes. For inserting hole inside file, the contents of the file starting at
>
> Please start new sentences on new source lines.
>
> > +.I offset
> > +will be shifted towards right by
> > +.I len
> > +bytes. Inserting a hole inside the file will increase the file size by
>
> Please start new sentences on new source lines.
>
> > +.I len
> > +bytes.
> > +
> > +This mode has the same limitation as
> > +.BR FALLOC_FL_COLLAPSE_RANGE
> > +regarding the
> > +granularity of the operation.
> > +If the granulrity requirements are not met,
>
> Spelling: "granularity"
>
> > +.BR fallocate ()
> > +will fail with the error
> > +.BR EINVAL.
> > +If the
> > +.I offset
> > +overlaps with end of file OR if it is greater than end of file, an error is
> > +returned. For such type of operations, i.e. inserting a hole at the end of
>
> Please start new sentences on new source lines.
>
> > +file,
> > +.BR ftruncate(2)
> > +should be used.
> > +In case
> > +.IR offset + len
> > +exceeds the maximum file size, errno will be set to
> > +.B EFBIG.
> > +
> > +No other flags may be specified in
> > +.IR mode
> > +in conjunction with
> > +.BR FALLOC_FL_INSERT_RANGE .
> > +
> > +As of Linux XXXX,
> > +.\" TODO: Mention commit id and supporting Linux version
> > +.B FALLOC_FL_INSERT_RANGE
> > +is supported by
> > +ext4 (only for extent-based files) and XFS.
>
> Is the ext4 support really there? Grep Linus's current Git, it appears
> that only XFS support is currently there?
>
> > +
> > .SH RETURN VALUE
> > On success,
> > .BR fallocate ()
> > @@ -242,6 +292,12 @@ is not a valid file descriptor, or is not opened for writing.
> > .IR offset + len
> > exceeds the maximum file size.
> > .TP
> > +.B EFBIG
> > +.I mode
> > +is
> > +.BR FALLOC_FL_INSERT_RANGE ,
> > +the current file size+len excceds the maximum file size.
>
> "exceeds"
>
> > +.TP
> > .B EINTR
> > A signal was caught during execution.
> > .TP
> > @@ -270,7 +326,17 @@ reaches or passes the end of the file.
> > .B EINVAL
> > .I mode
> > is
> > -.BR FALLOC_FL_COLLAPSE_RANGE ,
> > +.BR FALLOC_FL_INSERT_RANGE
> > +and the range specified by
> > +.I offset
> > +reaches or passes the end of the file.
> > +.TP
> > +.B EINVAL
> > +.I mode
> > +is
> > +.BR FALLOC_FL_COLLAPSE_RANGE
> > +or
> > +.BR FALLOC_FL_INSERT_RANGE ,
> > but either
> > .I offset
> > or
> > @@ -279,18 +345,24 @@ is not a multiple of the filesystem block size.
> > .TP
> > .B EINVAL
> > .I mode
> > -contains both
> > +contains either of
> > .B FALLOC_FL_COLLAPSE_RANGE
> > +or
> > +.B FALLOC_FL_INSERT_RANGE
> > and other flags;
> > no other flags are permitted with
> > -.BR FALLOC_FL_COLLAPSE_RANGE .
> > +.BR FALLOC_FL_COLLAPSE_RANGE
> > +or
> > +.BR FALLOC_FL_INSERT_RANGE .
> > .TP
> > .B EINVAL
> > .I mode
> > is
> > .BR FALLOC_FL_COLLAPSE_RANGE
> > or
> > -.BR FALLOC_FL_ZERO_RANGE ,
> > +.BR FALLOC_FL_ZERO_RANGE
> > +or
> > +.BR FALLOC_FL_INSERT_RANGE ,
> > but the file referred to by
> > .I fd
> > is not a regular file.
> > @@ -342,6 +414,8 @@ specifies
> > .BR FALLOC_FL_PUNCH_HOLE
> > or
> > .BR FALLOC_FL_COLLAPSE_RANGE
> > +or
> > +.BR FALLOC_FL_INSERT_RANGE
> > and
> > the file referred to by
> > .I fd
> > @@ -360,7 +434,9 @@ refers to a pipe or FIFO.
> > .B ETXTBSY
> > .I mode
> > specifies
> > -.BR FALLOC_FL_COLLAPSE_RANGE ,
> > +.BR FALLOC_FL_COLLAPSE_RANGE
> > +or
> > +.BR FALLOC_FL_INSERT_RANGE ,
> > but the file referred to by
> > .IR fd
> > is currently being executed.
> >
>
> Thanks,
>
> Michael
>
>
> --
> Michael Kerrisk
> Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
> Linux/UNIX System Programming Training: http://man7.org/training/
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply
* Re: [PATCH RFC] vfs: add a O_NOMTIME flag
From: Theodore Ts'o @ 2015-05-06 23:21 UTC (permalink / raw)
To: Sage Weil
Cc: Trond Myklebust, Zach Brown, Alexander Viro,
Linux FS-devel Mailing List, Linux Kernel Mailing List,
Linux API Mailing List
In-Reply-To: <alpine.DEB.2.00.1505061515550.28239-vIokxiIdD2AQNTJnQDzGJqxOck334EZe@public.gmane.org>
On Wed, May 06, 2015 at 03:19:13PM -0700, Sage Weil wrote:
> > Just out of curiosity, if you need to modify the application anyway,
> > why wouldn't use of fdatasync() when flushing be able to offer a
> > similar performance boost?
>
> Although fdatasync(2) doesn't have to update synchronously, it does
> eventually get written, and that can trigger lots of unwanted IO.
Something that might be worth trying out is using MS_LAZYTIME plus
fdatasync(2). That should significantly reduce the unwanted IO, while
eventually letting the mtimes get updated, plus allowing updates of
adjacent inodes in the same inode table block update the mtime "for
free".
Regards,
- Ted
^ permalink raw reply
* Re: [PATCH RFC] vfs: add a O_NOMTIME flag
From: Sage Weil @ 2015-05-06 22:46 UTC (permalink / raw)
To: Zach Brown
Cc: Trond Myklebust, Alexander Viro, Linux FS-devel Mailing List,
Linux Kernel Mailing List, Linux API Mailing List
In-Reply-To: <20150506224113.GA17282-fypN+1c5dIyjpB87vu3CluTW4wlIGRCZ@public.gmane.org>
On Wed, 6 May 2015, Zach Brown wrote:
> On Wed, May 06, 2015 at 03:19:13PM -0700, Sage Weil wrote:
> > On Wed, 6 May 2015, Trond Myklebust wrote:
> > > Hi Zach,
> > >
> > > On Wed, May 6, 2015 at 6:00 PM, Zach Brown <zab-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> > > >
> > > > Add the O_NOMTIME flag which prevents mtime from being updated which can
> > > > greatly reduce the IO overhead of writes to allocated and initialized
> > > > regions of files.
> > > >
> > > > ceph servers can have loads where they perform O_DIRECT overwrites of
> > > > allocated file data and then sync to make sure that the O_DIRECT writes
> > > > are flushed from write caches. If the writes dirty the inode with mtime
> > > > updates then the syncs also write out the metadata needed to track the
> > > > inodes which can add significant iop and latency overhead.
> > > >
> > > > The ceph servers don't use mtime at all. They're using the local file
> > > > system as a backing store and any backups would be driven by their upper
> > > > level ceph metadata. For ceph, slow IO from mtime updates in the file
> > > > system is as daft as if we had block devices slowing down IO for
> > > > per-block write timestamps that file systems never use.
> > > >
> > > > In simple tests a O_DIRECT|O_NOMTIME overwriting write followed by a
> > > > sync went from 2 serial write round trips to 1 in XFS and from 4 serial
> > > > IO round trips to 1 in ext4.
> > > >
> > > > file_update_time() checks for O_NOMTIME and aborts the update if it's
> > > > set, just like the current check for the in-kernel inode flag
> > > > S_NOCMTIME. I didn't update any other mtime update sites. They could be
> > > > added as we decide that it's appropriate to do so.
> > > >
> > > > I opted not to name the flag O_NOCMTIME because I didn't want the name
> > > > to imply that ctime updates would be prevented for other inode changes
> > > > like updating i_size in truncate. Not updating ctime is a side-effect
> > > > of removing mtime updates when it's the only thing changing in the
> > > > inode.
> > > >
> > > > The criteria for using O_NOMTIME is the same as for using O_NOATIME:
> > > > owning the file or having the CAP_FOWNER capability. If we're not
> > > > comfortable allowing owners to prevent mtime/ctime updates then we
> > > > should add a tunable to allow O_NOMTIME. Maybe a mount option?
> > > >
> > >
> > > Just out of curiosity, if you need to modify the application anyway,
> > > why wouldn't use of fdatasync() when flushing be able to offer a
> > > similar performance boost?
> >
> > Although fdatasync(2) doesn't have to update synchronously, it does
> > eventually get written, and that can trigger lots of unwanted IO.
>
> And the unwanted IO is per file. Are there circumstances where the
> write:file ratio is small enough that dirty inode writes could start to
> add up to meaningful write amplification?
Yeah, exactly: in some not-so-uncommon workloads it's approaching 1:1.
sage
^ permalink raw reply
* Re: [PATCH RFC] vfs: add a O_NOMTIME flag
From: Zach Brown @ 2015-05-06 22:41 UTC (permalink / raw)
To: Sage Weil
Cc: Trond Myklebust, Alexander Viro, Linux FS-devel Mailing List,
Linux Kernel Mailing List, Linux API Mailing List
In-Reply-To: <alpine.DEB.2.00.1505061515550.28239-vIokxiIdD2AQNTJnQDzGJqxOck334EZe@public.gmane.org>
On Wed, May 06, 2015 at 03:19:13PM -0700, Sage Weil wrote:
> On Wed, 6 May 2015, Trond Myklebust wrote:
> > Hi Zach,
> >
> > On Wed, May 6, 2015 at 6:00 PM, Zach Brown <zab-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> > >
> > > Add the O_NOMTIME flag which prevents mtime from being updated which can
> > > greatly reduce the IO overhead of writes to allocated and initialized
> > > regions of files.
> > >
> > > ceph servers can have loads where they perform O_DIRECT overwrites of
> > > allocated file data and then sync to make sure that the O_DIRECT writes
> > > are flushed from write caches. If the writes dirty the inode with mtime
> > > updates then the syncs also write out the metadata needed to track the
> > > inodes which can add significant iop and latency overhead.
> > >
> > > The ceph servers don't use mtime at all. They're using the local file
> > > system as a backing store and any backups would be driven by their upper
> > > level ceph metadata. For ceph, slow IO from mtime updates in the file
> > > system is as daft as if we had block devices slowing down IO for
> > > per-block write timestamps that file systems never use.
> > >
> > > In simple tests a O_DIRECT|O_NOMTIME overwriting write followed by a
> > > sync went from 2 serial write round trips to 1 in XFS and from 4 serial
> > > IO round trips to 1 in ext4.
> > >
> > > file_update_time() checks for O_NOMTIME and aborts the update if it's
> > > set, just like the current check for the in-kernel inode flag
> > > S_NOCMTIME. I didn't update any other mtime update sites. They could be
> > > added as we decide that it's appropriate to do so.
> > >
> > > I opted not to name the flag O_NOCMTIME because I didn't want the name
> > > to imply that ctime updates would be prevented for other inode changes
> > > like updating i_size in truncate. Not updating ctime is a side-effect
> > > of removing mtime updates when it's the only thing changing in the
> > > inode.
> > >
> > > The criteria for using O_NOMTIME is the same as for using O_NOATIME:
> > > owning the file or having the CAP_FOWNER capability. If we're not
> > > comfortable allowing owners to prevent mtime/ctime updates then we
> > > should add a tunable to allow O_NOMTIME. Maybe a mount option?
> > >
> >
> > Just out of curiosity, if you need to modify the application anyway,
> > why wouldn't use of fdatasync() when flushing be able to offer a
> > similar performance boost?
>
> Although fdatasync(2) doesn't have to update synchronously, it does
> eventually get written, and that can trigger lots of unwanted IO.
And the unwanted IO is per file. Are there circumstances where the
write:file ratio is small enough that dirty inode writes could start to
add up to meaningful write amplification?
- z
^ permalink raw reply
* Re: [PATCH RFC] vfs: add a O_NOMTIME flag
From: Sage Weil @ 2015-05-06 22:19 UTC (permalink / raw)
To: Trond Myklebust
Cc: Zach Brown, Alexander Viro, Linux FS-devel Mailing List,
Linux Kernel Mailing List, Linux API Mailing List
In-Reply-To: <CAHQdGtS0=Gjyq2E2QO+zu_HAzdrHJwxtfZ8MB5q0DjWHMEc7hw@mail.gmail.com>
On Wed, 6 May 2015, Trond Myklebust wrote:
> Hi Zach,
>
> On Wed, May 6, 2015 at 6:00 PM, Zach Brown <zab@redhat.com> wrote:
> >
> > Add the O_NOMTIME flag which prevents mtime from being updated which can
> > greatly reduce the IO overhead of writes to allocated and initialized
> > regions of files.
> >
> > ceph servers can have loads where they perform O_DIRECT overwrites of
> > allocated file data and then sync to make sure that the O_DIRECT writes
> > are flushed from write caches. If the writes dirty the inode with mtime
> > updates then the syncs also write out the metadata needed to track the
> > inodes which can add significant iop and latency overhead.
> >
> > The ceph servers don't use mtime at all. They're using the local file
> > system as a backing store and any backups would be driven by their upper
> > level ceph metadata. For ceph, slow IO from mtime updates in the file
> > system is as daft as if we had block devices slowing down IO for
> > per-block write timestamps that file systems never use.
> >
> > In simple tests a O_DIRECT|O_NOMTIME overwriting write followed by a
> > sync went from 2 serial write round trips to 1 in XFS and from 4 serial
> > IO round trips to 1 in ext4.
> >
> > file_update_time() checks for O_NOMTIME and aborts the update if it's
> > set, just like the current check for the in-kernel inode flag
> > S_NOCMTIME. I didn't update any other mtime update sites. They could be
> > added as we decide that it's appropriate to do so.
> >
> > I opted not to name the flag O_NOCMTIME because I didn't want the name
> > to imply that ctime updates would be prevented for other inode changes
> > like updating i_size in truncate. Not updating ctime is a side-effect
> > of removing mtime updates when it's the only thing changing in the
> > inode.
> >
> > The criteria for using O_NOMTIME is the same as for using O_NOATIME:
> > owning the file or having the CAP_FOWNER capability. If we're not
> > comfortable allowing owners to prevent mtime/ctime updates then we
> > should add a tunable to allow O_NOMTIME. Maybe a mount option?
> >
>
> Just out of curiosity, if you need to modify the application anyway,
> why wouldn't use of fdatasync() when flushing be able to offer a
> similar performance boost?
Although fdatasync(2) doesn't have to update synchronously, it does
eventually get written, and that can trigger lots of unwanted IO.
In practice we fsync(2) to avoid deferred IO that we can't control/bound,
but that's a long and sad story. O_NOMTIME would make for a much better
ending!
sage
^ permalink raw reply
* Re: [PATCH RFC] vfs: add a O_NOMTIME flag
From: Trond Myklebust @ 2015-05-06 22:14 UTC (permalink / raw)
To: Zach Brown
Cc: Alexander Viro, Sage Weil, Linux FS-devel Mailing List,
Linux Kernel Mailing List, Linux API Mailing List
In-Reply-To: <1430949612-21356-1-git-send-email-zab@redhat.com>
Hi Zach,
On Wed, May 6, 2015 at 6:00 PM, Zach Brown <zab@redhat.com> wrote:
>
> Add the O_NOMTIME flag which prevents mtime from being updated which can
> greatly reduce the IO overhead of writes to allocated and initialized
> regions of files.
>
> ceph servers can have loads where they perform O_DIRECT overwrites of
> allocated file data and then sync to make sure that the O_DIRECT writes
> are flushed from write caches. If the writes dirty the inode with mtime
> updates then the syncs also write out the metadata needed to track the
> inodes which can add significant iop and latency overhead.
>
> The ceph servers don't use mtime at all. They're using the local file
> system as a backing store and any backups would be driven by their upper
> level ceph metadata. For ceph, slow IO from mtime updates in the file
> system is as daft as if we had block devices slowing down IO for
> per-block write timestamps that file systems never use.
>
> In simple tests a O_DIRECT|O_NOMTIME overwriting write followed by a
> sync went from 2 serial write round trips to 1 in XFS and from 4 serial
> IO round trips to 1 in ext4.
>
> file_update_time() checks for O_NOMTIME and aborts the update if it's
> set, just like the current check for the in-kernel inode flag
> S_NOCMTIME. I didn't update any other mtime update sites. They could be
> added as we decide that it's appropriate to do so.
>
> I opted not to name the flag O_NOCMTIME because I didn't want the name
> to imply that ctime updates would be prevented for other inode changes
> like updating i_size in truncate. Not updating ctime is a side-effect
> of removing mtime updates when it's the only thing changing in the
> inode.
>
> The criteria for using O_NOMTIME is the same as for using O_NOATIME:
> owning the file or having the CAP_FOWNER capability. If we're not
> comfortable allowing owners to prevent mtime/ctime updates then we
> should add a tunable to allow O_NOMTIME. Maybe a mount option?
>
Just out of curiosity, if you need to modify the application anyway,
why wouldn't use of fdatasync() when flushing be able to offer a
similar performance boost?
Cheers
Trond
^ permalink raw reply
* [PATCH RFC] vfs: add a O_NOMTIME flag
From: Zach Brown @ 2015-05-06 22:00 UTC (permalink / raw)
To: Alexander Viro, Sage Weil, linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA
Add the O_NOMTIME flag which prevents mtime from being updated which can
greatly reduce the IO overhead of writes to allocated and initialized
regions of files.
ceph servers can have loads where they perform O_DIRECT overwrites of
allocated file data and then sync to make sure that the O_DIRECT writes
are flushed from write caches. If the writes dirty the inode with mtime
updates then the syncs also write out the metadata needed to track the
inodes which can add significant iop and latency overhead.
The ceph servers don't use mtime at all. They're using the local file
system as a backing store and any backups would be driven by their upper
level ceph metadata. For ceph, slow IO from mtime updates in the file
system is as daft as if we had block devices slowing down IO for
per-block write timestamps that file systems never use.
In simple tests a O_DIRECT|O_NOMTIME overwriting write followed by a
sync went from 2 serial write round trips to 1 in XFS and from 4 serial
IO round trips to 1 in ext4.
file_update_time() checks for O_NOMTIME and aborts the update if it's
set, just like the current check for the in-kernel inode flag
S_NOCMTIME. I didn't update any other mtime update sites. They could be
added as we decide that it's appropriate to do so.
I opted not to name the flag O_NOCMTIME because I didn't want the name
to imply that ctime updates would be prevented for other inode changes
like updating i_size in truncate. Not updating ctime is a side-effect
of removing mtime updates when it's the only thing changing in the
inode.
The criteria for using O_NOMTIME is the same as for using O_NOATIME:
owning the file or having the CAP_FOWNER capability. If we're not
comfortable allowing owners to prevent mtime/ctime updates then we
should add a tunable to allow O_NOMTIME. Maybe a mount option?
Signed-off-by: Zach Brown <zab-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Cc: Sage Weil <sweil-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
fs/fcntl.c | 12 +++++++-----
fs/inode.c | 2 +-
fs/namei.c | 4 ++--
include/linux/fs.h | 7 +------
include/uapi/asm-generic/fcntl.h | 4 ++++
5 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/fs/fcntl.c b/fs/fcntl.c
index ee85cd4..9e48092 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -27,7 +27,8 @@
#include <asm/siginfo.h>
#include <asm/uaccess.h>
-#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
+#define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME | \
+ O_NOMTIME)
static int setfl(int fd, struct file * filp, unsigned long arg)
{
@@ -41,8 +42,9 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
if (((arg ^ filp->f_flags) & O_APPEND) && IS_APPEND(inode))
return -EPERM;
- /* O_NOATIME can only be set by the owner or superuser */
- if ((arg & O_NOATIME) && !(filp->f_flags & O_NOATIME))
+ /* O_NOATIME and O_NOMTIME can only be set by the owner or superuser */
+ if (((arg & O_NOATIME) && !(filp->f_flags & O_NOATIME)) ||
+ ((arg & O_NOMTIME) && !(filp->f_flags & O_NOMTIME)))
if (!inode_owner_or_capable(inode))
return -EPERM;
@@ -740,7 +742,7 @@ static int __init fcntl_init(void)
* Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY
* is defined as O_NONBLOCK on some platforms and not on others.
*/
- BUILD_BUG_ON(21 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32(
+ BUILD_BUG_ON(22 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32(
O_RDONLY | O_WRONLY | O_RDWR |
O_CREAT | O_EXCL | O_NOCTTY |
O_TRUNC | O_APPEND | /* O_NONBLOCK | */
@@ -748,7 +750,7 @@ static int __init fcntl_init(void)
O_DIRECT | O_LARGEFILE | O_DIRECTORY |
O_NOFOLLOW | O_NOATIME | O_CLOEXEC |
__FMODE_EXEC | O_PATH | __O_TMPFILE |
- __FMODE_NONOTIFY
+ __FMODE_NONOTIFY| O_NOMTIME
));
fasync_cache = kmem_cache_create("fasync_cache",
diff --git a/fs/inode.c b/fs/inode.c
index ea37cd1..8976edc 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1721,7 +1721,7 @@ int file_update_time(struct file *file)
int ret;
/* First try to exhaust all avenues to not sync */
- if (IS_NOCMTIME(inode))
+ if (IS_NOCMTIME(inode) || (file->f_flags & O_NOMTIME))
return 0;
now = current_fs_time(inode->i_sb);
diff --git a/fs/namei.c b/fs/namei.c
index 4a8d998b..1a3ccb3 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2609,8 +2609,8 @@ static int may_open(struct path *path, int acc_mode, int flag)
return -EPERM;
}
- /* O_NOATIME can only be set by the owner or superuser */
- if (flag & O_NOATIME && !inode_owner_or_capable(inode))
+ /* O_NOATIME and O_NOMTIME can only be set by the owner or superuser */
+ if (flag & (O_NOATIME|O_NOMTIME) && !inode_owner_or_capable(inode))
return -EPERM;
return 0;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 35ec87e..34602f5 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -110,12 +110,7 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
/* 64bit hashes as llseek() offset (for directories) */
#define FMODE_64BITHASH ((__force fmode_t)0x400)
-/*
- * Don't update ctime and mtime.
- *
- * Currently a special hack for the XFS open_by_handle ioctl, but we'll
- * hopefully graduate it to a proper O_CMTIME flag supported by open(2) soon.
- */
+/* Don't update ctime and mtime. */
#define FMODE_NOCMTIME ((__force fmode_t)0x800)
/* Expect random access pattern */
diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
index e063eff..8e484ae 100644
--- a/include/uapi/asm-generic/fcntl.h
+++ b/include/uapi/asm-generic/fcntl.h
@@ -88,6 +88,10 @@
#define __O_TMPFILE 020000000
#endif
+#ifndef O_NOMTIME
+#define O_NOMTIME 040000000
+#endif
+
/* a horrid kludge trying to make sure that this will fail on old kernels */
#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
#define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT)
--
2.1.0
^ permalink raw reply related
* Re: [PATCH v18 for v4.1-rc2 1/3] sys_membarrier(): system-wide memory barrier (generic, x86)
From: Linus Torvalds @ 2015-05-06 20:39 UTC (permalink / raw)
To: Mathieu Desnoyers
Cc: Josh Triplett, Andrew Morton, Linux Kernel Mailing List,
KOSAKI Motohiro, Steven Rostedt, Nicholas Miell, Ingo Molnar,
Alan Cox, Lai Jiangshan, Stephen Hemminger, Thomas Gleixner,
Peter Zijlstra, David Howells, Pranith Kumar, Michael Kerrisk,
Linux API
In-Reply-To: <2014027751.44926.1430944422045.JavaMail.zimbra@efficios.com>
On Wed, May 6, 2015 at 1:33 PM, Mathieu Desnoyers
<mathieu.desnoyers@efficios.com> wrote:
>
> Will try moving those parts under a "---" in the commit
> message, and hope it does what I intend.
Yeah, that should do it for anybody who then uses "git am" to apply
the patches you send out. It's kind of hacky, and I've always worried
a bit that somebody uses "^---$' for real in a commit message and
things get lost, but it is *such* a useful way to add notes to emails
that aren't fit for actually committing, that the risk has never
outweighed the benefits.
Linus
^ permalink raw reply
* Re: [PATCH v18 for v4.1-rc2 1/3] sys_membarrier(): system-wide memory barrier (generic, x86)
From: Mathieu Desnoyers @ 2015-05-06 20:33 UTC (permalink / raw)
To: josh-iaAMLnmF4UmaiuxdJuQwMA
Cc: Andrew Morton, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
KOSAKI Motohiro, Steven Rostedt, Nicholas Miell, Linus Torvalds,
Ingo Molnar, Alan Cox, Lai Jiangshan, Stephen Hemminger,
Thomas Gleixner, Peter Zijlstra, David Howells, Pranith Kumar,
Michael Kerrisk, linux-api-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <371299002.44925.1430944039395.JavaMail.zimbra-vg+e7yoeK/dWk0Htik3J/w@public.gmane.org>
----- Original Message -----
> ----- Original Message -----
> > On Wed, May 06, 2015 at 03:21:06PM -0400, Mathieu Desnoyers wrote:
[...]
> > Reviewed-by: Josh Triplett <josh-iaAMLnmF4UmaiuxdJuQwMA@public.gmane.org>
> >
>
> Thanks!
>
> > But also, the "snip" and "changes since" should not be in the commit
> > message,
> > while this list of signoffs and CCs should be.
> >
>
> Is there a typical way to handle this while keeping
> it attached to a commit locally in my git branch ?
Will try moving those parts under a "---" in the commit
message, and hope it does what I intend.
Thanks,
Mathieu
--
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
^ permalink raw reply
* Re: [PATCH v18 for v4.1-rc2 1/3] sys_membarrier(): system-wide memory barrier (generic, x86)
From: Mathieu Desnoyers @ 2015-05-06 20:27 UTC (permalink / raw)
To: josh
Cc: Andrew Morton, linux-kernel, KOSAKI Motohiro, Steven Rostedt,
Nicholas Miell, Linus Torvalds, Ingo Molnar, Alan Cox,
Lai Jiangshan, Stephen Hemminger, Thomas Gleixner, Peter Zijlstra,
David Howells, Pranith Kumar, Michael Kerrisk, linux-api
In-Reply-To: <20150506202120.GA23011@cloud>
----- Original Message -----
> On Wed, May 06, 2015 at 03:21:06PM -0400, Mathieu Desnoyers wrote:
> > Here is an implementation of a new system call, sys_membarrier(), which
> > executes a memory barrier on all threads running on the system. It is
> > implemented by calling synchronize_sched(). It can be used to distribute
> > the cost of user-space memory barriers asymmetrically by transforming
> > pairs of memory barriers into pairs consisting of sys_membarrier() and a
> > compiler barrier. For synchronization primitives that distinguish
> > between read-side and write-side (e.g. userspace RCU [1], rwlocks), the
> > read-side can be accelerated significantly by moving the bulk of the
> > memory barrier overhead to the write-side.
> >
> > It is based on kernel v4.1-rc2.
> >
> > To explain the benefit of this scheme, let's introduce two example threads:
> >
> > Thread A (non-frequent, e.g. executing liburcu synchronize_rcu())
> > Thread B (frequent, e.g. executing liburcu
> > rcu_read_lock()/rcu_read_unlock())
> >
> > In a scheme where all smp_mb() in thread A are ordering memory accesses
> > with respect to smp_mb() present in Thread B, we can change each
> > smp_mb() within Thread A into calls to sys_membarrier() and each
> > smp_mb() within Thread B into compiler barriers "barrier()".
> >
> > Before the change, we had, for each smp_mb() pairs:
> >
> > Thread A Thread B
> > previous mem accesses previous mem accesses
> > smp_mb() smp_mb()
> > following mem accesses following mem accesses
> >
> > After the change, these pairs become:
> >
> > Thread A Thread B
> > prev mem accesses prev mem accesses
> > sys_membarrier() barrier()
> > follow mem accesses follow mem accesses
> >
> > As we can see, there are two possible scenarios: either Thread B memory
> > accesses do not happen concurrently with Thread A accesses (1), or they
> > do (2).
> >
> > 1) Non-concurrent Thread A vs Thread B accesses:
> >
> > Thread A Thread B
> > prev mem accesses
> > sys_membarrier()
> > follow mem accesses
> > prev mem accesses
> > barrier()
> > follow mem accesses
> >
> > In this case, thread B accesses will be weakly ordered. This is OK,
> > because at that point, thread A is not particularly interested in
> > ordering them with respect to its own accesses.
> >
> > 2) Concurrent Thread A vs Thread B accesses
> >
> > Thread A Thread B
> > prev mem accesses prev mem accesses
> > sys_membarrier() barrier()
> > follow mem accesses follow mem accesses
> >
> > In this case, thread B accesses, which are ensured to be in program
> > order thanks to the compiler barrier, will be "upgraded" to full
> > smp_mb() by synchronize_sched().
> >
> > * Benchmarks
> >
> > On Intel Xeon E5405 (8 cores)
> > (one thread is calling sys_membarrier, the other 7 threads are busy
> > looping)
> >
> > 1000 non-expedited sys_membarrier calls in 33s = 33 milliseconds/call.
> >
> > * User-space user of this system call: Userspace RCU library
> >
> > Both the signal-based and the sys_membarrier userspace RCU schemes
> > permit us to remove the memory barrier from the userspace RCU
> > rcu_read_lock() and rcu_read_unlock() primitives, thus significantly
> > accelerating them. These memory barriers are replaced by compiler
> > barriers on the read-side, and all matching memory barriers on the
> > write-side are turned into an invocation of a memory barrier on all
> > active threads in the process. By letting the kernel perform this
> > synchronization rather than dumbly sending a signal to every process
> > threads (as we currently do), we diminish the number of unnecessary wake
> > ups and only issue the memory barriers on active threads. Non-running
> > threads do not need to execute such barrier anyway, because these are
> > implied by the scheduler context switches.
> >
> > Results in liburcu:
> >
> > Operations in 10s, 6 readers, 2 writers:
> >
> > memory barriers in reader: 1701557485 reads, 2202847 writes
> > signal-based scheme: 9830061167 reads, 6700 writes
> > sys_membarrier: 9952759104 reads, 425 writes
> > sys_membarrier (dyn. check): 7970328887 reads, 425 writes
> >
> > The dynamic sys_membarrier availability check adds some overhead to
> > the read-side compared to the signal-based scheme, but besides that,
> > sys_membarrier slightly outperforms the signal-based scheme. However,
> > this non-expedited sys_membarrier implementation has a much slower grace
> > period than signal and memory barrier schemes.
> >
> > Besides diminishing the number of wake-ups, one major advantage of the
> > membarrier system call over the signal-based scheme is that it does not
> > need to reserve a signal. This plays much more nicely with libraries,
> > and with processes injected into for tracing purposes, for which we
> > cannot expect that signals will be unused by the application.
> >
> > An expedited version of this system call can be added later on to speed
> > up the grace period. Its implementation will likely depend on reading
> > the cpu_curr()->mm without holding each CPU's rq lock.
> >
> > This patch adds the system call to x86 and to asm-generic.
> >
> > membarrier(2) man page:
> > --------------- snip -------------------
> > MEMBARRIER(2) Linux Programmer's Manual
> > MEMBARRIER(2)
> >
> > NAME
> > membarrier - issue memory barriers on a set of threads
> >
> > SYNOPSIS
> > #include <linux/membarrier.h>
> >
> > int membarrier(int cmd, int flags);
> >
> > DESCRIPTION
> > The cmd argument is one of the following:
> >
> > MEMBARRIER_CMD_QUERY
> > Query the set of supported commands. It returns a bitmask
> > of
> > supported commands.
> >
> > MEMBARRIER_CMD_SHARED
> > Execute a memory barrier on all threads running on the
> > system.
> > Upon return from system call, the caller thread is ensured
> > that
> > all running threads have passed through a state where all
> > memory
> > accesses to user-space addresses match program order
> > between
> > entry to and return from the system call (non-running
> > threads
> > are de facto in such a state). This covers threads from all
> > pro‐
> > cesses running on the system. This command returns 0.
> >
> > The flags argument needs to be 0. For future extensions.
> >
> > All memory accesses performed in program order from each
> > targeted
> > thread is guaranteed to be ordered with respect to sys_membarrier().
> > If
> > we use the semantic "barrier()" to represent a compiler barrier
> > forcing
> > memory accesses to be performed in program order across the
> > barrier,
> > and smp_mb() to represent explicit memory barriers forcing full
> > memory
> > ordering across the barrier, we have the following ordering table
> > for
> > each pair of barrier(), sys_membarrier() and smp_mb():
> >
> > The pair ordering is detailed as (O: ordered, X: not ordered):
> >
> > barrier() smp_mb() sys_membarrier()
> > barrier() X X O
> > smp_mb() X O O
> > sys_membarrier() O O O
> >
> > RETURN VALUE
> > On success, these system calls return zero. On error, -1 is
> > returned,
> > and errno is set appropriately. For a given command, with flags
> > argument set to 0, this system call is guaranteed to always return
> > the
> > same value until reboot.
> >
> > ERRORS
> > ENOSYS System call is not implemented.
> >
> > EINVAL Invalid arguments.
> >
> > Linux 2015-04-15
> > MEMBARRIER(2)
> > --------------- snip -------------------
> >
> > [1] http://urcu.so
> >
> > Changes since v17:
> > - Update commit message.
> >
> > Changes since v16:
> > - Update documentation.
> > - Add man page to changelog.
> > - Build sys_membarrier on !CONFIG_SMP. It allows userspace applications
> > to not care about the number of processors on the system. Based on
> > recommendations from Stephen Hemminger and Steven Rostedt.
> > - Check that flags argument is 0, update documentation to require it.
> >
> > Changes since v15:
> > - Add flags argument in addition to cmd.
> > - Update documentation.
> >
> > Changes since v14:
> > - Take care of Thomas Gleixner's comments.
> >
> > Changes since v13:
> > - Move to kernel/membarrier.c.
> > - Remove MEMBARRIER_PRIVATE flag.
> > - Add MAINTAINERS file entry.
> >
> > Changes since v12:
> > - Remove _FLAG suffix from uapi flags.
> > - Add Expert menuconfig option CONFIG_MEMBARRIER (default=y).
> > - Remove EXPEDITED mode. Only implement non-expedited for now, until
> > reading the cpu_curr()->mm can be done without holding the CPU's rq
> > lock.
> >
> > Changes since v11:
> > - 5 years have passed.
> > - Rebase on v3.19 kernel.
> > - Add futex-alike PRIVATE vs SHARED semantic: private for per-process
> > barriers, non-private for memory mappings shared between processes.
> > - Simplify user API.
> > - Code refactoring.
> >
> > Changes since v10:
> > - Apply Randy's comments.
> > - Rebase on 2.6.34-rc4 -tip.
> >
> > Changes since v9:
> > - Clean up #ifdef CONFIG_SMP.
> >
> > Changes since v8:
> > - Go back to rq spin locks taken by sys_membarrier() rather than adding
> > memory barriers to the scheduler. It implies a potential RoS
> > (reduction of service) if sys_membarrier() is executed in a busy-loop
> > by a user, but nothing more than what is already possible with other
> > existing system calls, but saves memory barriers in the scheduler fast
> > path.
> > - re-add the memory barrier comments to x86 switch_mm() as an example to
> > other architectures.
> > - Update documentation of the memory barriers in sys_membarrier and
> > switch_mm().
> > - Append execution scenarios to the changelog showing the purpose of
> > each memory barrier.
> >
> > Changes since v7:
> > - Move spinlock-mb and scheduler related changes to separate patches.
> > - Add support for sys_membarrier on x86_32.
> > - Only x86 32/64 system calls are reserved in this patch. It is planned
> > to incrementally reserve syscall IDs on other architectures as these
> > are tested.
> >
> > Changes since v6:
> > - Remove some unlikely() not so unlikely.
> > - Add the proper scheduler memory barriers needed to only use the RCU
> > read lock in sys_membarrier rather than take each runqueue spinlock:
> > - Move memory barriers from per-architecture switch_mm() to schedule()
> > and finish_lock_switch(), where they clearly document that all data
> > protected by the rq lock is guaranteed to have memory barriers issued
> > between the scheduler update and the task execution. Replacing the
> > spin lock acquire/release barriers with these memory barriers imply
> > either no overhead (x86 spinlock atomic instruction already implies a
> > full mb) or some hopefully small overhead caused by the upgrade of the
> > spinlock acquire/release barriers to more heavyweight smp_mb().
> > - The "generic" version of spinlock-mb.h declares both a mapping to
> > standard spinlocks and full memory barriers. Each architecture can
> > specialize this header following their own need and declare
> > CONFIG_HAVE_SPINLOCK_MB to use their own spinlock-mb.h.
> > - Note: benchmarks of scheduler overhead with specialized spinlock-mb.h
> > implementations on a wide range of architecture would be welcome.
> >
> > Changes since v5:
> > - Plan ahead for extensibility by introducing mandatory/optional masks
> > to the "flags" system call parameter. Past experience with accept4(),
> > signalfd4(), eventfd2(), epoll_create1(), dup3(), pipe2(), and
> > inotify_init1() indicates that this is the kind of thing we want to
> > plan for. Return -EINVAL if the mandatory flags received are unknown.
> > - Create include/linux/membarrier.h to define these flags.
> > - Add MEMBARRIER_QUERY optional flag.
> >
> > Changes since v4:
> > - Add "int expedited" parameter, use synchronize_sched() in the
> > non-expedited case. Thanks to Lai Jiangshan for making us consider
> > seriously using synchronize_sched() to provide the low-overhead
> > membarrier scheme.
> > - Check num_online_cpus() == 1, quickly return without doing nothing.
> >
> > Changes since v3a:
> > - Confirm that each CPU indeed runs the current task's ->mm before
> > sending an IPI. Ensures that we do not disturb RT tasks in the
> > presence of lazy TLB shootdown.
> > - Document memory barriers needed in switch_mm().
> > - Surround helper functions with #ifdef CONFIG_SMP.
> >
> > Changes since v2:
> > - simply send-to-many to the mm_cpumask. It contains the list of
> > processors we have to IPI to (which use the mm), and this mask is
> > updated atomically.
> >
> > Changes since v1:
> > - Only perform the IPI in CONFIG_SMP.
> > - Only perform the IPI if the process has more than one thread.
> > - Only send IPIs to CPUs involved with threads belonging to our process.
> > - Adaptative IPI scheme (single vs many IPI with threshold).
> > - Issue smp_mb() at the beginning and end of the system call.
> >
> > Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> > Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> > CC: Josh Triplett <josh@joshtriplett.org>
>
> Reviewed-by: Josh Triplett <josh@joshtriplett.org>
>
Thanks!
> But also, the "snip" and "changes since" should not be in the commit message,
> while this list of signoffs and CCs should be.
>
Is there a typical way to handle this while keeping
it attached to a commit locally in my git branch ?
Thanks,
Mathieu
> - Josh Triplett
>
> > CC: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
> > CC: Steven Rostedt <rostedt@goodmis.org>
> > CC: Nicholas Miell <nmiell@comcast.net>
> > CC: Linus Torvalds <torvalds@linux-foundation.org>
> > CC: Ingo Molnar <mingo@redhat.com>
> > CC: Alan Cox <gnomes@lxorguk.ukuu.org.uk>
> > CC: Lai Jiangshan <laijs@cn.fujitsu.com>
> > CC: Stephen Hemminger <stephen@networkplumber.org>
> > CC: Andrew Morton <akpm@linux-foundation.org>
> > CC: Thomas Gleixner <tglx@linutronix.de>
> > CC: Peter Zijlstra <peterz@infradead.org>
> > CC: David Howells <dhowells@redhat.com>
> > CC: Pranith Kumar <bobby.prani@gmail.com>
> > CC: Michael Kerrisk <mtk.manpages@gmail.com>
> > CC: linux-api@vger.kernel.org
> > ---
> > MAINTAINERS | 8 ++++
> > arch/x86/syscalls/syscall_32.tbl | 1 +
> > arch/x86/syscalls/syscall_64.tbl | 1 +
> > include/linux/syscalls.h | 2 +
> > include/uapi/asm-generic/unistd.h | 4 ++-
> > include/uapi/linux/Kbuild | 1 +
> > include/uapi/linux/membarrier.h | 53 +++++++++++++++++++++++++++++
> > init/Kconfig | 12 +++++++
> > kernel/Makefile | 1 +
> > kernel/membarrier.c | 66
> > +++++++++++++++++++++++++++++++++++++
> > kernel/sys_ni.c | 3 ++
> > 11 files changed, 151 insertions(+), 1 deletions(-)
> > create mode 100644 include/uapi/linux/membarrier.h
> > create mode 100644 kernel/membarrier.c
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 781e099..fcb63d4 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -6370,6 +6370,14 @@ W: http://www.mellanox.com
> > Q: http://patchwork.ozlabs.org/project/netdev/list/
> > F: drivers/net/ethernet/mellanox/mlx4/en_*
> >
> > +MEMBARRIER SUPPORT
> > +M: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> > +M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
> > +L: linux-kernel@vger.kernel.org
> > +S: Supported
> > +F: kernel/membarrier.c
> > +F: include/uapi/linux/membarrier.h
> > +
> > MEMORY MANAGEMENT
> > L: linux-mm@kvack.org
> > W: http://www.linux-mm.org
> > diff --git a/arch/x86/syscalls/syscall_32.tbl
> > b/arch/x86/syscalls/syscall_32.tbl
> > index ef8187f..e63ad61 100644
> > --- a/arch/x86/syscalls/syscall_32.tbl
> > +++ b/arch/x86/syscalls/syscall_32.tbl
> > @@ -365,3 +365,4 @@
> > 356 i386 memfd_create sys_memfd_create
> > 357 i386 bpf sys_bpf
> > 358 i386 execveat sys_execveat stub32_execveat
> > +359 i386 membarrier sys_membarrier
> > diff --git a/arch/x86/syscalls/syscall_64.tbl
> > b/arch/x86/syscalls/syscall_64.tbl
> > index 9ef32d5..87f3cd6 100644
> > --- a/arch/x86/syscalls/syscall_64.tbl
> > +++ b/arch/x86/syscalls/syscall_64.tbl
> > @@ -329,6 +329,7 @@
> > 320 common kexec_file_load sys_kexec_file_load
> > 321 common bpf sys_bpf
> > 322 64 execveat stub_execveat
> > +323 common membarrier sys_membarrier
> >
> > #
> > # x32-specific system call numbers start at 512 to avoid cache impact
> > diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
> > index 76d1e38..51a9054 100644
> > --- a/include/linux/syscalls.h
> > +++ b/include/linux/syscalls.h
> > @@ -884,4 +884,6 @@ asmlinkage long sys_execveat(int dfd, const char __user
> > *filename,
> > const char __user *const __user *argv,
> > const char __user *const __user *envp, int flags);
> >
> > +asmlinkage long sys_membarrier(int cmd, int flags);
> > +
> > #endif
> > diff --git a/include/uapi/asm-generic/unistd.h
> > b/include/uapi/asm-generic/unistd.h
> > index e016bd9..8da542a 100644
> > --- a/include/uapi/asm-generic/unistd.h
> > +++ b/include/uapi/asm-generic/unistd.h
> > @@ -709,9 +709,11 @@ __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
> > +__SYSCALL(__NR_membarrier, sys_membarrier)
> >
> > #undef __NR_syscalls
> > -#define __NR_syscalls 282
> > +#define __NR_syscalls 283
> >
> > /*
> > * All syscalls below here should go away really,
> > diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
> > index 1a0006a..7bcc827 100644
> > --- a/include/uapi/linux/Kbuild
> > +++ b/include/uapi/linux/Kbuild
> > @@ -250,6 +250,7 @@ header-y += mdio.h
> > header-y += media.h
> > header-y += media-bus-format.h
> > header-y += mei.h
> > +header-y += membarrier.h
> > header-y += memfd.h
> > header-y += mempolicy.h
> > header-y += meye.h
> > diff --git a/include/uapi/linux/membarrier.h
> > b/include/uapi/linux/membarrier.h
> > new file mode 100644
> > index 0000000..e0b108b
> > --- /dev/null
> > +++ b/include/uapi/linux/membarrier.h
> > @@ -0,0 +1,53 @@
> > +#ifndef _UAPI_LINUX_MEMBARRIER_H
> > +#define _UAPI_LINUX_MEMBARRIER_H
> > +
> > +/*
> > + * linux/membarrier.h
> > + *
> > + * membarrier system call API
> > + *
> > + * Copyright (c) 2010, 2015 Mathieu Desnoyers
> > <mathieu.desnoyers@efficios.com>
> > + *
> > + * Permission is hereby granted, free of charge, to any person obtaining a
> > copy
> > + * of this software and associated documentation files (the "Software"),
> > to deal
> > + * in the Software without restriction, including without limitation the
> > rights
> > + * to use, copy, modify, merge, publish, distribute, sublicense, and/or
> > sell
> > + * copies of the Software, and to permit persons to whom the Software is
> > + * furnished to do so, subject to the following conditions:
> > + *
> > + * The above copyright notice and this permission notice shall be included
> > in
> > + * all copies or substantial portions of the Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> > OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> > MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> > THE
> > + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > FROM,
> > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> > IN THE
> > + * SOFTWARE.
> > + */
> > +
> > +/**
> > + * enum membarrier_cmd - membarrier system call command
> > + * @MEMBARRIER_CMD_QUERY: Query the set of supported commands. It
> > returns
> > + * a bitmask of valid commands.
> > + * @MEMBARRIER_CMD_SHARED: Execute a memory barrier on all running
> > threads.
> > + * Upon return from system call, the caller
> > thread
> > + * is ensured that all running threads have
> > passed
> > + * through a state where all memory accesses to
> > + * user-space addresses match program order
> > between
> > + * entry to and return from the system call
> > + * (non-running threads are de facto in such a
> > + * state). This covers threads from all processes
> > + * running on the system. This command returns 0.
> > + *
> > + * Command to be passed to the membarrier system call. The commands need
> > to
> > + * be a single bit each, except for MEMBARRIER_CMD_QUERY which is assigned
> > to
> > + * the value 0.
> > + */
> > +enum membarrier_cmd {
> > + MEMBARRIER_CMD_QUERY = 0,
> > + MEMBARRIER_CMD_SHARED = (1 << 0),
> > +};
> > +
> > +#endif /* _UAPI_LINUX_MEMBARRIER_H */
> > diff --git a/init/Kconfig b/init/Kconfig
> > index dc24dec..307e406 100644
> > --- a/init/Kconfig
> > +++ b/init/Kconfig
> > @@ -1583,6 +1583,18 @@ config PCI_QUIRKS
> > bugs/quirks. Disable this only if your target machine is
> > unaffected by PCI quirks.
> >
> > +config MEMBARRIER
> > + bool "Enable membarrier() system call" if EXPERT
> > + default y
> > + help
> > + Enable the membarrier() system call that allows issuing memory
> > + barriers across all running threads, which can be used to distribute
> > + the cost of user-space memory barriers asymmetrically by transforming
> > + pairs of memory barriers into pairs consisting of membarrier() and a
> > + compiler barrier.
> > +
> > + If unsure, say Y.
> > +
> > config EMBEDDED
> > bool "Embedded system"
> > option allnoconfig_y
> > diff --git a/kernel/Makefile b/kernel/Makefile
> > index 60c302c..05191fd 100644
> > --- a/kernel/Makefile
> > +++ b/kernel/Makefile
> > @@ -98,6 +98,7 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
> > obj-$(CONFIG_JUMP_LABEL) += jump_label.o
> > obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o
> > obj-$(CONFIG_TORTURE_TEST) += torture.o
> > +obj-$(CONFIG_MEMBARRIER) += membarrier.o
> >
> > $(obj)/configs.o: $(obj)/config_data.h
> >
> > diff --git a/kernel/membarrier.c b/kernel/membarrier.c
> > new file mode 100644
> > index 0000000..a20b279
> > --- /dev/null
> > +++ b/kernel/membarrier.c
> > @@ -0,0 +1,66 @@
> > +/*
> > + * Copyright (C) 2010, 2015 Mathieu Desnoyers
> > <mathieu.desnoyers@efficios.com>
> > + *
> > + * membarrier system call
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation; either version 2 of the License, or
> > + * (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include <linux/syscalls.h>
> > +#include <linux/membarrier.h>
> > +
> > +/*
> > + * Bitmask made from a "or" of all commands within enum membarrier_cmd,
> > + * except MEMBARRIER_CMD_QUERY.
> > + */
> > +#define MEMBARRIER_CMD_BITMASK (MEMBARRIER_CMD_SHARED)
> > +
> > +/**
> > + * sys_membarrier - issue memory barriers on a set of threads
> > + * @cmd: Takes command values defined in enum membarrier_cmd.
> > + * @flags: Currently needs to be 0. For future extensions.
> > + *
> > + * If this system call is not implemented, -ENOSYS is returned. If the
> > + * command specified does not exist, or if the command argument is
> > invalid,
> > + * this system call returns -EINVAL. For a given command, with flags
> > argument
> > + * set to 0, this system call is guaranteed to always return the same
> > value
> > + * until reboot.
> > + *
> > + * All memory accesses performed in program order from each targeted
> > thread
> > + * is guaranteed to be ordered with respect to sys_membarrier(). If we use
> > + * the semantic "barrier()" to represent a compiler barrier forcing memory
> > + * accesses to be performed in program order across the barrier, and
> > + * smp_mb() to represent explicit memory barriers forcing full memory
> > + * ordering across the barrier, we have the following ordering table for
> > + * each pair of barrier(), sys_membarrier() and smp_mb():
> > + *
> > + * The pair ordering is detailed as (O: ordered, X: not ordered):
> > + *
> > + * barrier() smp_mb() sys_membarrier()
> > + * barrier() X X O
> > + * smp_mb() X O O
> > + * sys_membarrier() O O O
> > + */
> > +SYSCALL_DEFINE2(membarrier, int, cmd, int, flags)
> > +{
> > + if (flags)
> > + return -EINVAL;
> > + switch (cmd) {
> > + case MEMBARRIER_CMD_QUERY:
> > + return MEMBARRIER_CMD_BITMASK;
> > + case MEMBARRIER_CMD_SHARED:
> > + if (num_online_cpus() > 1)
> > + synchronize_sched();
> > + return 0;
> > + default:
> > + return -EINVAL;
> > + }
> > +}
> > diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
> > index 7995ef5..eb4fde0 100644
> > --- a/kernel/sys_ni.c
> > +++ b/kernel/sys_ni.c
> > @@ -243,3 +243,6 @@ cond_syscall(sys_bpf);
> >
> > /* execveat */
> > cond_syscall(sys_execveat);
> > +
> > +/* membarrier */
> > +cond_syscall(sys_membarrier);
> > --
> > 1.7.7.3
> >
>
--
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
^ permalink raw reply
* Re: [PATCH v18 for v4.1-rc2 1/3] sys_membarrier(): system-wide memory barrier (generic, x86)
From: josh-iaAMLnmF4UmaiuxdJuQwMA @ 2015-05-06 20:21 UTC (permalink / raw)
To: Mathieu Desnoyers
Cc: Andrew Morton, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
KOSAKI Motohiro, Steven Rostedt, Nicholas Miell, Linus Torvalds,
Ingo Molnar, Alan Cox, Lai Jiangshan, Stephen Hemminger,
Thomas Gleixner, Peter Zijlstra, David Howells, Pranith Kumar,
Michael Kerrisk, linux-api-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1430940068-4326-2-git-send-email-mathieu.desnoyers-vg+e7yoeK/dWk0Htik3J/w@public.gmane.org>
On Wed, May 06, 2015 at 03:21:06PM -0400, Mathieu Desnoyers wrote:
> Here is an implementation of a new system call, sys_membarrier(), which
> executes a memory barrier on all threads running on the system. It is
> implemented by calling synchronize_sched(). It can be used to distribute
> the cost of user-space memory barriers asymmetrically by transforming
> pairs of memory barriers into pairs consisting of sys_membarrier() and a
> compiler barrier. For synchronization primitives that distinguish
> between read-side and write-side (e.g. userspace RCU [1], rwlocks), the
> read-side can be accelerated significantly by moving the bulk of the
> memory barrier overhead to the write-side.
>
> It is based on kernel v4.1-rc2.
>
> To explain the benefit of this scheme, let's introduce two example threads:
>
> Thread A (non-frequent, e.g. executing liburcu synchronize_rcu())
> Thread B (frequent, e.g. executing liburcu
> rcu_read_lock()/rcu_read_unlock())
>
> In a scheme where all smp_mb() in thread A are ordering memory accesses
> with respect to smp_mb() present in Thread B, we can change each
> smp_mb() within Thread A into calls to sys_membarrier() and each
> smp_mb() within Thread B into compiler barriers "barrier()".
>
> Before the change, we had, for each smp_mb() pairs:
>
> Thread A Thread B
> previous mem accesses previous mem accesses
> smp_mb() smp_mb()
> following mem accesses following mem accesses
>
> After the change, these pairs become:
>
> Thread A Thread B
> prev mem accesses prev mem accesses
> sys_membarrier() barrier()
> follow mem accesses follow mem accesses
>
> As we can see, there are two possible scenarios: either Thread B memory
> accesses do not happen concurrently with Thread A accesses (1), or they
> do (2).
>
> 1) Non-concurrent Thread A vs Thread B accesses:
>
> Thread A Thread B
> prev mem accesses
> sys_membarrier()
> follow mem accesses
> prev mem accesses
> barrier()
> follow mem accesses
>
> In this case, thread B accesses will be weakly ordered. This is OK,
> because at that point, thread A is not particularly interested in
> ordering them with respect to its own accesses.
>
> 2) Concurrent Thread A vs Thread B accesses
>
> Thread A Thread B
> prev mem accesses prev mem accesses
> sys_membarrier() barrier()
> follow mem accesses follow mem accesses
>
> In this case, thread B accesses, which are ensured to be in program
> order thanks to the compiler barrier, will be "upgraded" to full
> smp_mb() by synchronize_sched().
>
> * Benchmarks
>
> On Intel Xeon E5405 (8 cores)
> (one thread is calling sys_membarrier, the other 7 threads are busy
> looping)
>
> 1000 non-expedited sys_membarrier calls in 33s = 33 milliseconds/call.
>
> * User-space user of this system call: Userspace RCU library
>
> Both the signal-based and the sys_membarrier userspace RCU schemes
> permit us to remove the memory barrier from the userspace RCU
> rcu_read_lock() and rcu_read_unlock() primitives, thus significantly
> accelerating them. These memory barriers are replaced by compiler
> barriers on the read-side, and all matching memory barriers on the
> write-side are turned into an invocation of a memory barrier on all
> active threads in the process. By letting the kernel perform this
> synchronization rather than dumbly sending a signal to every process
> threads (as we currently do), we diminish the number of unnecessary wake
> ups and only issue the memory barriers on active threads. Non-running
> threads do not need to execute such barrier anyway, because these are
> implied by the scheduler context switches.
>
> Results in liburcu:
>
> Operations in 10s, 6 readers, 2 writers:
>
> memory barriers in reader: 1701557485 reads, 2202847 writes
> signal-based scheme: 9830061167 reads, 6700 writes
> sys_membarrier: 9952759104 reads, 425 writes
> sys_membarrier (dyn. check): 7970328887 reads, 425 writes
>
> The dynamic sys_membarrier availability check adds some overhead to
> the read-side compared to the signal-based scheme, but besides that,
> sys_membarrier slightly outperforms the signal-based scheme. However,
> this non-expedited sys_membarrier implementation has a much slower grace
> period than signal and memory barrier schemes.
>
> Besides diminishing the number of wake-ups, one major advantage of the
> membarrier system call over the signal-based scheme is that it does not
> need to reserve a signal. This plays much more nicely with libraries,
> and with processes injected into for tracing purposes, for which we
> cannot expect that signals will be unused by the application.
>
> An expedited version of this system call can be added later on to speed
> up the grace period. Its implementation will likely depend on reading
> the cpu_curr()->mm without holding each CPU's rq lock.
>
> This patch adds the system call to x86 and to asm-generic.
>
> membarrier(2) man page:
> --------------- snip -------------------
> MEMBARRIER(2) Linux Programmer's Manual MEMBARRIER(2)
>
> NAME
> membarrier - issue memory barriers on a set of threads
>
> SYNOPSIS
> #include <linux/membarrier.h>
>
> int membarrier(int cmd, int flags);
>
> DESCRIPTION
> The cmd argument is one of the following:
>
> MEMBARRIER_CMD_QUERY
> Query the set of supported commands. It returns a bitmask of
> supported commands.
>
> MEMBARRIER_CMD_SHARED
> Execute a memory barrier on all threads running on the system.
> Upon return from system call, the caller thread is ensured that
> all running threads have passed through a state where all memory
> accesses to user-space addresses match program order between
> entry to and return from the system call (non-running threads
> are de facto in such a state). This covers threads from all pro‐
> cesses running on the system. This command returns 0.
>
> The flags argument needs to be 0. For future extensions.
>
> All memory accesses performed in program order from each targeted
> thread is guaranteed to be ordered with respect to sys_membarrier(). If
> we use the semantic "barrier()" to represent a compiler barrier forcing
> memory accesses to be performed in program order across the barrier,
> and smp_mb() to represent explicit memory barriers forcing full memory
> ordering across the barrier, we have the following ordering table for
> each pair of barrier(), sys_membarrier() and smp_mb():
>
> The pair ordering is detailed as (O: ordered, X: not ordered):
>
> barrier() smp_mb() sys_membarrier()
> barrier() X X O
> smp_mb() X O O
> sys_membarrier() O O O
>
> RETURN VALUE
> On success, these system calls return zero. On error, -1 is returned,
> and errno is set appropriately. For a given command, with flags
> argument set to 0, this system call is guaranteed to always return the
> same value until reboot.
>
> ERRORS
> ENOSYS System call is not implemented.
>
> EINVAL Invalid arguments.
>
> Linux 2015-04-15 MEMBARRIER(2)
> --------------- snip -------------------
>
> [1] http://urcu.so
>
> Changes since v17:
> - Update commit message.
>
> Changes since v16:
> - Update documentation.
> - Add man page to changelog.
> - Build sys_membarrier on !CONFIG_SMP. It allows userspace applications
> to not care about the number of processors on the system. Based on
> recommendations from Stephen Hemminger and Steven Rostedt.
> - Check that flags argument is 0, update documentation to require it.
>
> Changes since v15:
> - Add flags argument in addition to cmd.
> - Update documentation.
>
> Changes since v14:
> - Take care of Thomas Gleixner's comments.
>
> Changes since v13:
> - Move to kernel/membarrier.c.
> - Remove MEMBARRIER_PRIVATE flag.
> - Add MAINTAINERS file entry.
>
> Changes since v12:
> - Remove _FLAG suffix from uapi flags.
> - Add Expert menuconfig option CONFIG_MEMBARRIER (default=y).
> - Remove EXPEDITED mode. Only implement non-expedited for now, until
> reading the cpu_curr()->mm can be done without holding the CPU's rq
> lock.
>
> Changes since v11:
> - 5 years have passed.
> - Rebase on v3.19 kernel.
> - Add futex-alike PRIVATE vs SHARED semantic: private for per-process
> barriers, non-private for memory mappings shared between processes.
> - Simplify user API.
> - Code refactoring.
>
> Changes since v10:
> - Apply Randy's comments.
> - Rebase on 2.6.34-rc4 -tip.
>
> Changes since v9:
> - Clean up #ifdef CONFIG_SMP.
>
> Changes since v8:
> - Go back to rq spin locks taken by sys_membarrier() rather than adding
> memory barriers to the scheduler. It implies a potential RoS
> (reduction of service) if sys_membarrier() is executed in a busy-loop
> by a user, but nothing more than what is already possible with other
> existing system calls, but saves memory barriers in the scheduler fast
> path.
> - re-add the memory barrier comments to x86 switch_mm() as an example to
> other architectures.
> - Update documentation of the memory barriers in sys_membarrier and
> switch_mm().
> - Append execution scenarios to the changelog showing the purpose of
> each memory barrier.
>
> Changes since v7:
> - Move spinlock-mb and scheduler related changes to separate patches.
> - Add support for sys_membarrier on x86_32.
> - Only x86 32/64 system calls are reserved in this patch. It is planned
> to incrementally reserve syscall IDs on other architectures as these
> are tested.
>
> Changes since v6:
> - Remove some unlikely() not so unlikely.
> - Add the proper scheduler memory barriers needed to only use the RCU
> read lock in sys_membarrier rather than take each runqueue spinlock:
> - Move memory barriers from per-architecture switch_mm() to schedule()
> and finish_lock_switch(), where they clearly document that all data
> protected by the rq lock is guaranteed to have memory barriers issued
> between the scheduler update and the task execution. Replacing the
> spin lock acquire/release barriers with these memory barriers imply
> either no overhead (x86 spinlock atomic instruction already implies a
> full mb) or some hopefully small overhead caused by the upgrade of the
> spinlock acquire/release barriers to more heavyweight smp_mb().
> - The "generic" version of spinlock-mb.h declares both a mapping to
> standard spinlocks and full memory barriers. Each architecture can
> specialize this header following their own need and declare
> CONFIG_HAVE_SPINLOCK_MB to use their own spinlock-mb.h.
> - Note: benchmarks of scheduler overhead with specialized spinlock-mb.h
> implementations on a wide range of architecture would be welcome.
>
> Changes since v5:
> - Plan ahead for extensibility by introducing mandatory/optional masks
> to the "flags" system call parameter. Past experience with accept4(),
> signalfd4(), eventfd2(), epoll_create1(), dup3(), pipe2(), and
> inotify_init1() indicates that this is the kind of thing we want to
> plan for. Return -EINVAL if the mandatory flags received are unknown.
> - Create include/linux/membarrier.h to define these flags.
> - Add MEMBARRIER_QUERY optional flag.
>
> Changes since v4:
> - Add "int expedited" parameter, use synchronize_sched() in the
> non-expedited case. Thanks to Lai Jiangshan for making us consider
> seriously using synchronize_sched() to provide the low-overhead
> membarrier scheme.
> - Check num_online_cpus() == 1, quickly return without doing nothing.
>
> Changes since v3a:
> - Confirm that each CPU indeed runs the current task's ->mm before
> sending an IPI. Ensures that we do not disturb RT tasks in the
> presence of lazy TLB shootdown.
> - Document memory barriers needed in switch_mm().
> - Surround helper functions with #ifdef CONFIG_SMP.
>
> Changes since v2:
> - simply send-to-many to the mm_cpumask. It contains the list of
> processors we have to IPI to (which use the mm), and this mask is
> updated atomically.
>
> Changes since v1:
> - Only perform the IPI in CONFIG_SMP.
> - Only perform the IPI if the process has more than one thread.
> - Only send IPIs to CPUs involved with threads belonging to our process.
> - Adaptative IPI scheme (single vs many IPI with threshold).
> - Issue smp_mb() at the beginning and end of the system call.
>
> Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers-vg+e7yoeK/dWk0Htik3J/w@public.gmane.org>
> Reviewed-by: Paul E. McKenney <paulmck-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> CC: Josh Triplett <josh-iaAMLnmF4UmaiuxdJuQwMA@public.gmane.org>
Reviewed-by: Josh Triplett <josh-iaAMLnmF4UmaiuxdJuQwMA@public.gmane.org>
But also, the "snip" and "changes since" should not be in the commit message,
while this list of signoffs and CCs should be.
- Josh Triplett
> CC: KOSAKI Motohiro <kosaki.motohiro-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
> CC: Steven Rostedt <rostedt-nx8X9YLhiw1AfugRpC6u6w@public.gmane.org>
> CC: Nicholas Miell <nmiell-Wuw85uim5zDR7s880joybQ@public.gmane.org>
> CC: Linus Torvalds <torvalds-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
> CC: Ingo Molnar <mingo-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> CC: Alan Cox <gnomes-qBU/x9rampVanCEyBjwyrvXRex20P6io@public.gmane.org>
> CC: Lai Jiangshan <laijs-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
> CC: Stephen Hemminger <stephen-OTpzqLSitTUnbdJkjeBofR2eb7JE58TQ@public.gmane.org>
> CC: Andrew Morton <akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
> CC: Thomas Gleixner <tglx-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>
> CC: Peter Zijlstra <peterz-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
> CC: David Howells <dhowells-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> CC: Pranith Kumar <bobby.prani-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> CC: Michael Kerrisk <mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> CC: linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> ---
> MAINTAINERS | 8 ++++
> arch/x86/syscalls/syscall_32.tbl | 1 +
> arch/x86/syscalls/syscall_64.tbl | 1 +
> include/linux/syscalls.h | 2 +
> include/uapi/asm-generic/unistd.h | 4 ++-
> include/uapi/linux/Kbuild | 1 +
> include/uapi/linux/membarrier.h | 53 +++++++++++++++++++++++++++++
> init/Kconfig | 12 +++++++
> kernel/Makefile | 1 +
> kernel/membarrier.c | 66 +++++++++++++++++++++++++++++++++++++
> kernel/sys_ni.c | 3 ++
> 11 files changed, 151 insertions(+), 1 deletions(-)
> create mode 100644 include/uapi/linux/membarrier.h
> create mode 100644 kernel/membarrier.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 781e099..fcb63d4 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -6370,6 +6370,14 @@ W: http://www.mellanox.com
> Q: http://patchwork.ozlabs.org/project/netdev/list/
> F: drivers/net/ethernet/mellanox/mlx4/en_*
>
> +MEMBARRIER SUPPORT
> +M: Mathieu Desnoyers <mathieu.desnoyers-vg+e7yoeK/dWk0Htik3J/w@public.gmane.org>
> +M: "Paul E. McKenney" <paulmck-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
> +L: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> +S: Supported
> +F: kernel/membarrier.c
> +F: include/uapi/linux/membarrier.h
> +
> MEMORY MANAGEMENT
> L: linux-mm-Bw31MaZKKs3YtjvyW6yDsg@public.gmane.org
> W: http://www.linux-mm.org
> diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl
> index ef8187f..e63ad61 100644
> --- a/arch/x86/syscalls/syscall_32.tbl
> +++ b/arch/x86/syscalls/syscall_32.tbl
> @@ -365,3 +365,4 @@
> 356 i386 memfd_create sys_memfd_create
> 357 i386 bpf sys_bpf
> 358 i386 execveat sys_execveat stub32_execveat
> +359 i386 membarrier sys_membarrier
> diff --git a/arch/x86/syscalls/syscall_64.tbl b/arch/x86/syscalls/syscall_64.tbl
> index 9ef32d5..87f3cd6 100644
> --- a/arch/x86/syscalls/syscall_64.tbl
> +++ b/arch/x86/syscalls/syscall_64.tbl
> @@ -329,6 +329,7 @@
> 320 common kexec_file_load sys_kexec_file_load
> 321 common bpf sys_bpf
> 322 64 execveat stub_execveat
> +323 common membarrier sys_membarrier
>
> #
> # x32-specific system call numbers start at 512 to avoid cache impact
> diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
> index 76d1e38..51a9054 100644
> --- a/include/linux/syscalls.h
> +++ b/include/linux/syscalls.h
> @@ -884,4 +884,6 @@ asmlinkage long sys_execveat(int dfd, const char __user *filename,
> const char __user *const __user *argv,
> const char __user *const __user *envp, int flags);
>
> +asmlinkage long sys_membarrier(int cmd, int flags);
> +
> #endif
> diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
> index e016bd9..8da542a 100644
> --- a/include/uapi/asm-generic/unistd.h
> +++ b/include/uapi/asm-generic/unistd.h
> @@ -709,9 +709,11 @@ __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
> +__SYSCALL(__NR_membarrier, sys_membarrier)
>
> #undef __NR_syscalls
> -#define __NR_syscalls 282
> +#define __NR_syscalls 283
>
> /*
> * All syscalls below here should go away really,
> diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
> index 1a0006a..7bcc827 100644
> --- a/include/uapi/linux/Kbuild
> +++ b/include/uapi/linux/Kbuild
> @@ -250,6 +250,7 @@ header-y += mdio.h
> header-y += media.h
> header-y += media-bus-format.h
> header-y += mei.h
> +header-y += membarrier.h
> header-y += memfd.h
> header-y += mempolicy.h
> header-y += meye.h
> diff --git a/include/uapi/linux/membarrier.h b/include/uapi/linux/membarrier.h
> new file mode 100644
> index 0000000..e0b108b
> --- /dev/null
> +++ b/include/uapi/linux/membarrier.h
> @@ -0,0 +1,53 @@
> +#ifndef _UAPI_LINUX_MEMBARRIER_H
> +#define _UAPI_LINUX_MEMBARRIER_H
> +
> +/*
> + * linux/membarrier.h
> + *
> + * membarrier system call API
> + *
> + * Copyright (c) 2010, 2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a copy
> + * of this software and associated documentation files (the "Software"), to deal
> + * in the Software without restriction, including without limitation the rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> + * SOFTWARE.
> + */
> +
> +/**
> + * enum membarrier_cmd - membarrier system call command
> + * @MEMBARRIER_CMD_QUERY: Query the set of supported commands. It returns
> + * a bitmask of valid commands.
> + * @MEMBARRIER_CMD_SHARED: Execute a memory barrier on all running threads.
> + * Upon return from system call, the caller thread
> + * is ensured that all running threads have passed
> + * through a state where all memory accesses to
> + * user-space addresses match program order between
> + * entry to and return from the system call
> + * (non-running threads are de facto in such a
> + * state). This covers threads from all processes
> + * running on the system. This command returns 0.
> + *
> + * Command to be passed to the membarrier system call. The commands need to
> + * be a single bit each, except for MEMBARRIER_CMD_QUERY which is assigned to
> + * the value 0.
> + */
> +enum membarrier_cmd {
> + MEMBARRIER_CMD_QUERY = 0,
> + MEMBARRIER_CMD_SHARED = (1 << 0),
> +};
> +
> +#endif /* _UAPI_LINUX_MEMBARRIER_H */
> diff --git a/init/Kconfig b/init/Kconfig
> index dc24dec..307e406 100644
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -1583,6 +1583,18 @@ config PCI_QUIRKS
> bugs/quirks. Disable this only if your target machine is
> unaffected by PCI quirks.
>
> +config MEMBARRIER
> + bool "Enable membarrier() system call" if EXPERT
> + default y
> + help
> + Enable the membarrier() system call that allows issuing memory
> + barriers across all running threads, which can be used to distribute
> + the cost of user-space memory barriers asymmetrically by transforming
> + pairs of memory barriers into pairs consisting of membarrier() and a
> + compiler barrier.
> +
> + If unsure, say Y.
> +
> config EMBEDDED
> bool "Embedded system"
> option allnoconfig_y
> diff --git a/kernel/Makefile b/kernel/Makefile
> index 60c302c..05191fd 100644
> --- a/kernel/Makefile
> +++ b/kernel/Makefile
> @@ -98,6 +98,7 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
> obj-$(CONFIG_JUMP_LABEL) += jump_label.o
> obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o
> obj-$(CONFIG_TORTURE_TEST) += torture.o
> +obj-$(CONFIG_MEMBARRIER) += membarrier.o
>
> $(obj)/configs.o: $(obj)/config_data.h
>
> diff --git a/kernel/membarrier.c b/kernel/membarrier.c
> new file mode 100644
> index 0000000..a20b279
> --- /dev/null
> +++ b/kernel/membarrier.c
> @@ -0,0 +1,66 @@
> +/*
> + * Copyright (C) 2010, 2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> + *
> + * membarrier system call
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/syscalls.h>
> +#include <linux/membarrier.h>
> +
> +/*
> + * Bitmask made from a "or" of all commands within enum membarrier_cmd,
> + * except MEMBARRIER_CMD_QUERY.
> + */
> +#define MEMBARRIER_CMD_BITMASK (MEMBARRIER_CMD_SHARED)
> +
> +/**
> + * sys_membarrier - issue memory barriers on a set of threads
> + * @cmd: Takes command values defined in enum membarrier_cmd.
> + * @flags: Currently needs to be 0. For future extensions.
> + *
> + * If this system call is not implemented, -ENOSYS is returned. If the
> + * command specified does not exist, or if the command argument is invalid,
> + * this system call returns -EINVAL. For a given command, with flags argument
> + * set to 0, this system call is guaranteed to always return the same value
> + * until reboot.
> + *
> + * All memory accesses performed in program order from each targeted thread
> + * is guaranteed to be ordered with respect to sys_membarrier(). If we use
> + * the semantic "barrier()" to represent a compiler barrier forcing memory
> + * accesses to be performed in program order across the barrier, and
> + * smp_mb() to represent explicit memory barriers forcing full memory
> + * ordering across the barrier, we have the following ordering table for
> + * each pair of barrier(), sys_membarrier() and smp_mb():
> + *
> + * The pair ordering is detailed as (O: ordered, X: not ordered):
> + *
> + * barrier() smp_mb() sys_membarrier()
> + * barrier() X X O
> + * smp_mb() X O O
> + * sys_membarrier() O O O
> + */
> +SYSCALL_DEFINE2(membarrier, int, cmd, int, flags)
> +{
> + if (flags)
> + return -EINVAL;
> + switch (cmd) {
> + case MEMBARRIER_CMD_QUERY:
> + return MEMBARRIER_CMD_BITMASK;
> + case MEMBARRIER_CMD_SHARED:
> + if (num_online_cpus() > 1)
> + synchronize_sched();
> + return 0;
> + default:
> + return -EINVAL;
> + }
> +}
> diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
> index 7995ef5..eb4fde0 100644
> --- a/kernel/sys_ni.c
> +++ b/kernel/sys_ni.c
> @@ -243,3 +243,6 @@ cond_syscall(sys_bpf);
>
> /* execveat */
> cond_syscall(sys_execveat);
> +
> +/* membarrier */
> +cond_syscall(sys_membarrier);
> --
> 1.7.7.3
>
^ permalink raw reply
* Re: [PATCH v2] selftests/mount: output WARN messages when mount test skipped
From: Shuah Khan @ 2015-05-06 20:15 UTC (permalink / raw)
To: Zhang Zhen, linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org >> Linux Kernel Mailing List
Cc: Eric W. Biederman, Shuah Khan
In-Reply-To: <551DEF58.3090505-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
On 04/02/2015 07:39 PM, Zhang Zhen wrote:
> Without this patch, if /proc/self/uid_map is not exist,
> the mount test case will skipped and no any prompting.
>
> After applied this patch, the case will prompt why it skipped.
> Just as follows:
> root@kernel-host:/opt/kernel> make -C tools/testing/selftests TARGETS=mount run_tests
> make: Entering directory `/opt/kernel/tools/testing/selftests'
> for TARGET in mount; do \
> make -C $TARGET; \
> done;
> make[1]: Entering directory `/opt/kernel/tools/testing/selftests/mount'
> make[1]: Nothing to be done for `all'.
> make[1]: Leaving directory `/opt/kernel/tools/testing/selftests/mount'
> for TARGET in mount; do \
> make -C $TARGET run_tests; \
> done;
> make[1]: Entering directory `/opt/kernel/tools/testing/selftests/mount'
> if [ -f /proc/self/uid_map ] ; then ./unprivileged-remount-test ; else echo "WARN: No /proc/self/uid_map exist, test skipped." ; fi
> WARN: No /proc/self/uid_map exist, test skipped.
> make[1]: Leaving directory `/opt/kernel/tools/testing/selftests/mount'
> make: Leaving directory `/opt/kernel/tools/testing/selftests'
>
> Change v1 -> v2:
> - fix syntax error when run kselftest_install.sh
>
> Signed-off-by: Zhang Zhen <zhenzhang.zhang-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
> ---
Thanks for fixing this. Applied it to linux-kselftest next
for 4.2 - I ended up making changes the commit log to fix
checkpatch warnings before applying the patch.
thanks,
-- Shuah
--
Shuah Khan
Sr. Linux Kernel Developer
Open Source Innovation Group
Samsung Research America (Silicon Valley)
shuahkh-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org | (970) 217-8978
^ permalink raw reply
* Re: [PATCH] selftests/timers: Make git ignore all binaries in timers test suite
From: Shuah Khan @ 2015-05-06 20:11 UTC (permalink / raw)
To: Zhang Zhen, linux-api-u79uwXL29TY76Z2rM5mHXA; +Cc: Shuah Khan
In-Reply-To: <55238E31.7000607-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
On 04/07/2015 01:58 AM, Zhang Zhen wrote:
> This patch includes the timers test binaries into the .gitignore
> file listing in their respective directories. This will make sure
> that git ignores all of these test binaries when displaying status.
>
> Signed-off-by: Zhang Zhen <zhenzhang.zhang-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
> ---
Thanks for fixing this. Applied to linux-kselftest next
for 4.2
thanks,
-- Shuah
--
Shuah Khan
Sr. Linux Kernel Developer
Open Source Innovation Group
Samsung Research America (Silicon Valley)
shuahkh-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org | (970) 217-8978
^ permalink raw reply
* [PATCH v18 for v4.1-rc2 1/3] sys_membarrier(): system-wide memory barrier (generic, x86)
From: Mathieu Desnoyers @ 2015-05-06 19:21 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, Mathieu Desnoyers, Josh Triplett, KOSAKI Motohiro,
Steven Rostedt, Nicholas Miell, Linus Torvalds, Ingo Molnar,
Alan Cox, Lai Jiangshan, Stephen Hemminger, Thomas Gleixner,
Peter Zijlstra, David Howells, Pranith Kumar, Michael Kerrisk,
linux-api
In-Reply-To: <1430940068-4326-1-git-send-email-mathieu.desnoyers@efficios.com>
Here is an implementation of a new system call, sys_membarrier(), which
executes a memory barrier on all threads running on the system. It is
implemented by calling synchronize_sched(). It can be used to distribute
the cost of user-space memory barriers asymmetrically by transforming
pairs of memory barriers into pairs consisting of sys_membarrier() and a
compiler barrier. For synchronization primitives that distinguish
between read-side and write-side (e.g. userspace RCU [1], rwlocks), the
read-side can be accelerated significantly by moving the bulk of the
memory barrier overhead to the write-side.
It is based on kernel v4.1-rc2.
To explain the benefit of this scheme, let's introduce two example threads:
Thread A (non-frequent, e.g. executing liburcu synchronize_rcu())
Thread B (frequent, e.g. executing liburcu
rcu_read_lock()/rcu_read_unlock())
In a scheme where all smp_mb() in thread A are ordering memory accesses
with respect to smp_mb() present in Thread B, we can change each
smp_mb() within Thread A into calls to sys_membarrier() and each
smp_mb() within Thread B into compiler barriers "barrier()".
Before the change, we had, for each smp_mb() pairs:
Thread A Thread B
previous mem accesses previous mem accesses
smp_mb() smp_mb()
following mem accesses following mem accesses
After the change, these pairs become:
Thread A Thread B
prev mem accesses prev mem accesses
sys_membarrier() barrier()
follow mem accesses follow mem accesses
As we can see, there are two possible scenarios: either Thread B memory
accesses do not happen concurrently with Thread A accesses (1), or they
do (2).
1) Non-concurrent Thread A vs Thread B accesses:
Thread A Thread B
prev mem accesses
sys_membarrier()
follow mem accesses
prev mem accesses
barrier()
follow mem accesses
In this case, thread B accesses will be weakly ordered. This is OK,
because at that point, thread A is not particularly interested in
ordering them with respect to its own accesses.
2) Concurrent Thread A vs Thread B accesses
Thread A Thread B
prev mem accesses prev mem accesses
sys_membarrier() barrier()
follow mem accesses follow mem accesses
In this case, thread B accesses, which are ensured to be in program
order thanks to the compiler barrier, will be "upgraded" to full
smp_mb() by synchronize_sched().
* Benchmarks
On Intel Xeon E5405 (8 cores)
(one thread is calling sys_membarrier, the other 7 threads are busy
looping)
1000 non-expedited sys_membarrier calls in 33s = 33 milliseconds/call.
* User-space user of this system call: Userspace RCU library
Both the signal-based and the sys_membarrier userspace RCU schemes
permit us to remove the memory barrier from the userspace RCU
rcu_read_lock() and rcu_read_unlock() primitives, thus significantly
accelerating them. These memory barriers are replaced by compiler
barriers on the read-side, and all matching memory barriers on the
write-side are turned into an invocation of a memory barrier on all
active threads in the process. By letting the kernel perform this
synchronization rather than dumbly sending a signal to every process
threads (as we currently do), we diminish the number of unnecessary wake
ups and only issue the memory barriers on active threads. Non-running
threads do not need to execute such barrier anyway, because these are
implied by the scheduler context switches.
Results in liburcu:
Operations in 10s, 6 readers, 2 writers:
memory barriers in reader: 1701557485 reads, 2202847 writes
signal-based scheme: 9830061167 reads, 6700 writes
sys_membarrier: 9952759104 reads, 425 writes
sys_membarrier (dyn. check): 7970328887 reads, 425 writes
The dynamic sys_membarrier availability check adds some overhead to
the read-side compared to the signal-based scheme, but besides that,
sys_membarrier slightly outperforms the signal-based scheme. However,
this non-expedited sys_membarrier implementation has a much slower grace
period than signal and memory barrier schemes.
Besides diminishing the number of wake-ups, one major advantage of the
membarrier system call over the signal-based scheme is that it does not
need to reserve a signal. This plays much more nicely with libraries,
and with processes injected into for tracing purposes, for which we
cannot expect that signals will be unused by the application.
An expedited version of this system call can be added later on to speed
up the grace period. Its implementation will likely depend on reading
the cpu_curr()->mm without holding each CPU's rq lock.
This patch adds the system call to x86 and to asm-generic.
membarrier(2) man page:
--------------- snip -------------------
MEMBARRIER(2) Linux Programmer's Manual MEMBARRIER(2)
NAME
membarrier - issue memory barriers on a set of threads
SYNOPSIS
#include <linux/membarrier.h>
int membarrier(int cmd, int flags);
DESCRIPTION
The cmd argument is one of the following:
MEMBARRIER_CMD_QUERY
Query the set of supported commands. It returns a bitmask of
supported commands.
MEMBARRIER_CMD_SHARED
Execute a memory barrier on all threads running on the system.
Upon return from system call, the caller thread is ensured that
all running threads have passed through a state where all memory
accesses to user-space addresses match program order between
entry to and return from the system call (non-running threads
are de facto in such a state). This covers threads from all pro‐
cesses running on the system. This command returns 0.
The flags argument needs to be 0. For future extensions.
All memory accesses performed in program order from each targeted
thread is guaranteed to be ordered with respect to sys_membarrier(). If
we use the semantic "barrier()" to represent a compiler barrier forcing
memory accesses to be performed in program order across the barrier,
and smp_mb() to represent explicit memory barriers forcing full memory
ordering across the barrier, we have the following ordering table for
each pair of barrier(), sys_membarrier() and smp_mb():
The pair ordering is detailed as (O: ordered, X: not ordered):
barrier() smp_mb() sys_membarrier()
barrier() X X O
smp_mb() X O O
sys_membarrier() O O O
RETURN VALUE
On success, these system calls return zero. On error, -1 is returned,
and errno is set appropriately. For a given command, with flags
argument set to 0, this system call is guaranteed to always return the
same value until reboot.
ERRORS
ENOSYS System call is not implemented.
EINVAL Invalid arguments.
Linux 2015-04-15 MEMBARRIER(2)
--------------- snip -------------------
[1] http://urcu.so
Changes since v17:
- Update commit message.
Changes since v16:
- Update documentation.
- Add man page to changelog.
- Build sys_membarrier on !CONFIG_SMP. It allows userspace applications
to not care about the number of processors on the system. Based on
recommendations from Stephen Hemminger and Steven Rostedt.
- Check that flags argument is 0, update documentation to require it.
Changes since v15:
- Add flags argument in addition to cmd.
- Update documentation.
Changes since v14:
- Take care of Thomas Gleixner's comments.
Changes since v13:
- Move to kernel/membarrier.c.
- Remove MEMBARRIER_PRIVATE flag.
- Add MAINTAINERS file entry.
Changes since v12:
- Remove _FLAG suffix from uapi flags.
- Add Expert menuconfig option CONFIG_MEMBARRIER (default=y).
- Remove EXPEDITED mode. Only implement non-expedited for now, until
reading the cpu_curr()->mm can be done without holding the CPU's rq
lock.
Changes since v11:
- 5 years have passed.
- Rebase on v3.19 kernel.
- Add futex-alike PRIVATE vs SHARED semantic: private for per-process
barriers, non-private for memory mappings shared between processes.
- Simplify user API.
- Code refactoring.
Changes since v10:
- Apply Randy's comments.
- Rebase on 2.6.34-rc4 -tip.
Changes since v9:
- Clean up #ifdef CONFIG_SMP.
Changes since v8:
- Go back to rq spin locks taken by sys_membarrier() rather than adding
memory barriers to the scheduler. It implies a potential RoS
(reduction of service) if sys_membarrier() is executed in a busy-loop
by a user, but nothing more than what is already possible with other
existing system calls, but saves memory barriers in the scheduler fast
path.
- re-add the memory barrier comments to x86 switch_mm() as an example to
other architectures.
- Update documentation of the memory barriers in sys_membarrier and
switch_mm().
- Append execution scenarios to the changelog showing the purpose of
each memory barrier.
Changes since v7:
- Move spinlock-mb and scheduler related changes to separate patches.
- Add support for sys_membarrier on x86_32.
- Only x86 32/64 system calls are reserved in this patch. It is planned
to incrementally reserve syscall IDs on other architectures as these
are tested.
Changes since v6:
- Remove some unlikely() not so unlikely.
- Add the proper scheduler memory barriers needed to only use the RCU
read lock in sys_membarrier rather than take each runqueue spinlock:
- Move memory barriers from per-architecture switch_mm() to schedule()
and finish_lock_switch(), where they clearly document that all data
protected by the rq lock is guaranteed to have memory barriers issued
between the scheduler update and the task execution. Replacing the
spin lock acquire/release barriers with these memory barriers imply
either no overhead (x86 spinlock atomic instruction already implies a
full mb) or some hopefully small overhead caused by the upgrade of the
spinlock acquire/release barriers to more heavyweight smp_mb().
- The "generic" version of spinlock-mb.h declares both a mapping to
standard spinlocks and full memory barriers. Each architecture can
specialize this header following their own need and declare
CONFIG_HAVE_SPINLOCK_MB to use their own spinlock-mb.h.
- Note: benchmarks of scheduler overhead with specialized spinlock-mb.h
implementations on a wide range of architecture would be welcome.
Changes since v5:
- Plan ahead for extensibility by introducing mandatory/optional masks
to the "flags" system call parameter. Past experience with accept4(),
signalfd4(), eventfd2(), epoll_create1(), dup3(), pipe2(), and
inotify_init1() indicates that this is the kind of thing we want to
plan for. Return -EINVAL if the mandatory flags received are unknown.
- Create include/linux/membarrier.h to define these flags.
- Add MEMBARRIER_QUERY optional flag.
Changes since v4:
- Add "int expedited" parameter, use synchronize_sched() in the
non-expedited case. Thanks to Lai Jiangshan for making us consider
seriously using synchronize_sched() to provide the low-overhead
membarrier scheme.
- Check num_online_cpus() == 1, quickly return without doing nothing.
Changes since v3a:
- Confirm that each CPU indeed runs the current task's ->mm before
sending an IPI. Ensures that we do not disturb RT tasks in the
presence of lazy TLB shootdown.
- Document memory barriers needed in switch_mm().
- Surround helper functions with #ifdef CONFIG_SMP.
Changes since v2:
- simply send-to-many to the mm_cpumask. It contains the list of
processors we have to IPI to (which use the mm), and this mask is
updated atomically.
Changes since v1:
- Only perform the IPI in CONFIG_SMP.
- Only perform the IPI if the process has more than one thread.
- Only send IPIs to CPUs involved with threads belonging to our process.
- Adaptative IPI scheme (single vs many IPI with threshold).
- Issue smp_mb() at the beginning and end of the system call.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
CC: Josh Triplett <josh@joshtriplett.org>
CC: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
CC: Steven Rostedt <rostedt@goodmis.org>
CC: Nicholas Miell <nmiell@comcast.net>
CC: Linus Torvalds <torvalds@linux-foundation.org>
CC: Ingo Molnar <mingo@redhat.com>
CC: Alan Cox <gnomes@lxorguk.ukuu.org.uk>
CC: Lai Jiangshan <laijs@cn.fujitsu.com>
CC: Stephen Hemminger <stephen@networkplumber.org>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: Thomas Gleixner <tglx@linutronix.de>
CC: Peter Zijlstra <peterz@infradead.org>
CC: David Howells <dhowells@redhat.com>
CC: Pranith Kumar <bobby.prani@gmail.com>
CC: Michael Kerrisk <mtk.manpages@gmail.com>
CC: linux-api@vger.kernel.org
---
MAINTAINERS | 8 ++++
arch/x86/syscalls/syscall_32.tbl | 1 +
arch/x86/syscalls/syscall_64.tbl | 1 +
include/linux/syscalls.h | 2 +
include/uapi/asm-generic/unistd.h | 4 ++-
include/uapi/linux/Kbuild | 1 +
include/uapi/linux/membarrier.h | 53 +++++++++++++++++++++++++++++
init/Kconfig | 12 +++++++
kernel/Makefile | 1 +
kernel/membarrier.c | 66 +++++++++++++++++++++++++++++++++++++
kernel/sys_ni.c | 3 ++
11 files changed, 151 insertions(+), 1 deletions(-)
create mode 100644 include/uapi/linux/membarrier.h
create mode 100644 kernel/membarrier.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 781e099..fcb63d4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6370,6 +6370,14 @@ W: http://www.mellanox.com
Q: http://patchwork.ozlabs.org/project/netdev/list/
F: drivers/net/ethernet/mellanox/mlx4/en_*
+MEMBARRIER SUPPORT
+M: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+M: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
+L: linux-kernel@vger.kernel.org
+S: Supported
+F: kernel/membarrier.c
+F: include/uapi/linux/membarrier.h
+
MEMORY MANAGEMENT
L: linux-mm@kvack.org
W: http://www.linux-mm.org
diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl
index ef8187f..e63ad61 100644
--- a/arch/x86/syscalls/syscall_32.tbl
+++ b/arch/x86/syscalls/syscall_32.tbl
@@ -365,3 +365,4 @@
356 i386 memfd_create sys_memfd_create
357 i386 bpf sys_bpf
358 i386 execveat sys_execveat stub32_execveat
+359 i386 membarrier sys_membarrier
diff --git a/arch/x86/syscalls/syscall_64.tbl b/arch/x86/syscalls/syscall_64.tbl
index 9ef32d5..87f3cd6 100644
--- a/arch/x86/syscalls/syscall_64.tbl
+++ b/arch/x86/syscalls/syscall_64.tbl
@@ -329,6 +329,7 @@
320 common kexec_file_load sys_kexec_file_load
321 common bpf sys_bpf
322 64 execveat stub_execveat
+323 common membarrier sys_membarrier
#
# x32-specific system call numbers start at 512 to avoid cache impact
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 76d1e38..51a9054 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -884,4 +884,6 @@ asmlinkage long sys_execveat(int dfd, const char __user *filename,
const char __user *const __user *argv,
const char __user *const __user *envp, int flags);
+asmlinkage long sys_membarrier(int cmd, int flags);
+
#endif
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index e016bd9..8da542a 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -709,9 +709,11 @@ __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
+__SYSCALL(__NR_membarrier, sys_membarrier)
#undef __NR_syscalls
-#define __NR_syscalls 282
+#define __NR_syscalls 283
/*
* All syscalls below here should go away really,
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index 1a0006a..7bcc827 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -250,6 +250,7 @@ header-y += mdio.h
header-y += media.h
header-y += media-bus-format.h
header-y += mei.h
+header-y += membarrier.h
header-y += memfd.h
header-y += mempolicy.h
header-y += meye.h
diff --git a/include/uapi/linux/membarrier.h b/include/uapi/linux/membarrier.h
new file mode 100644
index 0000000..e0b108b
--- /dev/null
+++ b/include/uapi/linux/membarrier.h
@@ -0,0 +1,53 @@
+#ifndef _UAPI_LINUX_MEMBARRIER_H
+#define _UAPI_LINUX_MEMBARRIER_H
+
+/*
+ * linux/membarrier.h
+ *
+ * membarrier system call API
+ *
+ * Copyright (c) 2010, 2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * enum membarrier_cmd - membarrier system call command
+ * @MEMBARRIER_CMD_QUERY: Query the set of supported commands. It returns
+ * a bitmask of valid commands.
+ * @MEMBARRIER_CMD_SHARED: Execute a memory barrier on all running threads.
+ * Upon return from system call, the caller thread
+ * is ensured that all running threads have passed
+ * through a state where all memory accesses to
+ * user-space addresses match program order between
+ * entry to and return from the system call
+ * (non-running threads are de facto in such a
+ * state). This covers threads from all processes
+ * running on the system. This command returns 0.
+ *
+ * Command to be passed to the membarrier system call. The commands need to
+ * be a single bit each, except for MEMBARRIER_CMD_QUERY which is assigned to
+ * the value 0.
+ */
+enum membarrier_cmd {
+ MEMBARRIER_CMD_QUERY = 0,
+ MEMBARRIER_CMD_SHARED = (1 << 0),
+};
+
+#endif /* _UAPI_LINUX_MEMBARRIER_H */
diff --git a/init/Kconfig b/init/Kconfig
index dc24dec..307e406 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1583,6 +1583,18 @@ config PCI_QUIRKS
bugs/quirks. Disable this only if your target machine is
unaffected by PCI quirks.
+config MEMBARRIER
+ bool "Enable membarrier() system call" if EXPERT
+ default y
+ help
+ Enable the membarrier() system call that allows issuing memory
+ barriers across all running threads, which can be used to distribute
+ the cost of user-space memory barriers asymmetrically by transforming
+ pairs of memory barriers into pairs consisting of membarrier() and a
+ compiler barrier.
+
+ If unsure, say Y.
+
config EMBEDDED
bool "Embedded system"
option allnoconfig_y
diff --git a/kernel/Makefile b/kernel/Makefile
index 60c302c..05191fd 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -98,6 +98,7 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o
obj-$(CONFIG_TORTURE_TEST) += torture.o
+obj-$(CONFIG_MEMBARRIER) += membarrier.o
$(obj)/configs.o: $(obj)/config_data.h
diff --git a/kernel/membarrier.c b/kernel/membarrier.c
new file mode 100644
index 0000000..a20b279
--- /dev/null
+++ b/kernel/membarrier.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2010, 2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * membarrier system call
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/syscalls.h>
+#include <linux/membarrier.h>
+
+/*
+ * Bitmask made from a "or" of all commands within enum membarrier_cmd,
+ * except MEMBARRIER_CMD_QUERY.
+ */
+#define MEMBARRIER_CMD_BITMASK (MEMBARRIER_CMD_SHARED)
+
+/**
+ * sys_membarrier - issue memory barriers on a set of threads
+ * @cmd: Takes command values defined in enum membarrier_cmd.
+ * @flags: Currently needs to be 0. For future extensions.
+ *
+ * If this system call is not implemented, -ENOSYS is returned. If the
+ * command specified does not exist, or if the command argument is invalid,
+ * this system call returns -EINVAL. For a given command, with flags argument
+ * set to 0, this system call is guaranteed to always return the same value
+ * until reboot.
+ *
+ * All memory accesses performed in program order from each targeted thread
+ * is guaranteed to be ordered with respect to sys_membarrier(). If we use
+ * the semantic "barrier()" to represent a compiler barrier forcing memory
+ * accesses to be performed in program order across the barrier, and
+ * smp_mb() to represent explicit memory barriers forcing full memory
+ * ordering across the barrier, we have the following ordering table for
+ * each pair of barrier(), sys_membarrier() and smp_mb():
+ *
+ * The pair ordering is detailed as (O: ordered, X: not ordered):
+ *
+ * barrier() smp_mb() sys_membarrier()
+ * barrier() X X O
+ * smp_mb() X O O
+ * sys_membarrier() O O O
+ */
+SYSCALL_DEFINE2(membarrier, int, cmd, int, flags)
+{
+ if (flags)
+ return -EINVAL;
+ switch (cmd) {
+ case MEMBARRIER_CMD_QUERY:
+ return MEMBARRIER_CMD_BITMASK;
+ case MEMBARRIER_CMD_SHARED:
+ if (num_online_cpus() > 1)
+ synchronize_sched();
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 7995ef5..eb4fde0 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -243,3 +243,6 @@ cond_syscall(sys_bpf);
/* execveat */
cond_syscall(sys_execveat);
+
+/* membarrier */
+cond_syscall(sys_membarrier);
--
1.7.7.3
^ permalink raw reply related
* Re: [GIT PULL] selftest: Add futex functional tests
From: Davidlohr Bueso @ 2015-05-06 18:34 UTC (permalink / raw)
To: Darren Hart
Cc: Linux Kernel Mailing List, Shuah Khan, linux-api, Ingo Molnar,
Peter Zijlstra, Thomas Gleixner, KOSAKI Motohiro
In-Reply-To: <cover.1427493640.git.dvhart@linux.intel.com>
On Fri, 2015-03-27 at 15:17 -0700, Darren Hart wrote:
> Hi Shuah,
>
> This series begins the process of migrating my futextest tests into kselftest.
> I've started with only the functional tests, as the performance and stress may
> not be appropriate for kselftest as they stand.
>
> I cleaned up various complaints from checkpatch, but I ignored others that would
> require significant rework of the testcases, such as not using volatile and not
> creating new typedefs.
>
> The patches will follow, but I'm providing a pull request for your convenience
> as well.
>
> The following changes since commit 0b63accf87225b5eb7e52814c374cf02d733d4bb:
>
> tools, update rtctest.c to verify passage of time (2015-03-24 22:02:59 -0600)
>
> are available in the git repository at:
>
> git://git.infradead.org/users/dvhart/linux.git futextest
>
> Darren Hart (5):
> selftests: Add futex functional tests
> selftest/futex: Update Makefile to use lib.mk
> selftest/futex: Increment ksft pass and fail counters
> selftest: Add futex tests to the top-level Makefile
> kselftest: Add exit code defines
I haven't really gone through these, but given how much I use these
tests from your tree, I'm very glad to see them converted for upstream.
I hope its as easy to use in kselftests though.
Acked-by: Davidlohr Bueso <dave@stgolabs.net>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox