[tip:perf/urgent] trace_kprobe: Remove warning message "Could not insert probe at..."
Commit-ID: 5c8dad48e4f53d6fd0a7e4f95d7c1c983374de88 Gitweb: https://git.kernel.org/tip/5c8dad48e4f53d6fd0a7e4f95d7c1c983374de88 Author: Song LiuAuthorDate: Fri, 13 Apr 2018 11:55:13 -0700 Committer: Ingo Molnar CommitDate: Tue, 17 Apr 2018 07:54:57 +0200 trace_kprobe: Remove warning message "Could not insert probe at..." This warning message is not very helpful, as the return value should already show information about the error. Also, this message will spam dmesg if the user space does testing in a loop, like: for x in {0..5} do echo p:xx xx+$x >> /sys/kernel/debug/tracing/kprobe_events done Reported-by: Vince Weaver Signed-off-by: Song Liu Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: kernel-t...@fb.com Link: http://lkml.kernel.org/r/20180413185513.3626052-1-songliubrav...@fb.com Signed-off-by: Ingo Molnar --- kernel/trace/trace_kprobe.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 1cd3fb4d70f8..02aed76e0978 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -512,8 +512,6 @@ static int __register_trace_kprobe(struct trace_kprobe *tk) if (ret == 0) tk->tp.flags |= TP_FLAG_REGISTERED; else { - pr_warn("Could not insert probe at %s+%lu: %d\n", - trace_kprobe_symbol(tk), trace_kprobe_offset(tk), ret); if (ret == -ENOENT && trace_kprobe_is_on_module(tk)) { pr_warn("This probe might be able to register after target module is loaded. Continue.\n"); ret = 0;
[tip:perf/urgent] trace_kprobe: Remove warning message "Could not insert probe at..."
Commit-ID: 5c8dad48e4f53d6fd0a7e4f95d7c1c983374de88 Gitweb: https://git.kernel.org/tip/5c8dad48e4f53d6fd0a7e4f95d7c1c983374de88 Author: Song Liu AuthorDate: Fri, 13 Apr 2018 11:55:13 -0700 Committer: Ingo Molnar CommitDate: Tue, 17 Apr 2018 07:54:57 +0200 trace_kprobe: Remove warning message "Could not insert probe at..." This warning message is not very helpful, as the return value should already show information about the error. Also, this message will spam dmesg if the user space does testing in a loop, like: for x in {0..5} do echo p:xx xx+$x >> /sys/kernel/debug/tracing/kprobe_events done Reported-by: Vince Weaver Signed-off-by: Song Liu Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: kernel-t...@fb.com Link: http://lkml.kernel.org/r/20180413185513.3626052-1-songliubrav...@fb.com Signed-off-by: Ingo Molnar --- kernel/trace/trace_kprobe.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 1cd3fb4d70f8..02aed76e0978 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -512,8 +512,6 @@ static int __register_trace_kprobe(struct trace_kprobe *tk) if (ret == 0) tk->tp.flags |= TP_FLAG_REGISTERED; else { - pr_warn("Could not insert probe at %s+%lu: %d\n", - trace_kprobe_symbol(tk), trace_kprobe_offset(tk), ret); if (ret == -ENOENT && trace_kprobe_is_on_module(tk)) { pr_warn("This probe might be able to register after target module is loaded. Continue.\n"); ret = 0;
Re: [PATCH 0/3] clk: add duty cycle support
Quoting Jerome Brunet (2018-04-16 10:57:40) > This patchset adds the possibility to control the duty cycle ratio of a > clock within the clock framework. > > This useful when the duty cycle ratio depends on another parameter > controlled by the clock framework. For example, the duty cycle ratio may > depends on the value of a divider (ratio = N / div). > > This is also useful if the related clock is part of large tree. In this > case, using CCF to control the clock tree and the PWM framework for the > duty cycle would be a nightmare for the provider and the consumer. Can you please Cc the PWM maintainer on this patch series? > > A clock provider is not required to implement the operation to set and get > the duty cycle. If it does not implement .get_duty_cycle(), the ratio is > assumed to be 50%. > > This series also provides pass-through operations ready to be used for > clock which don't resample the clock signal (such as gates and muxes). > This is provided to make things easier for consumers. Clocks are usually > made of several elements, like a composite clocks with a mux, a divider, > and a gate. With the pass-through ops set on the gate, the consumer does > not need to be aware that the duty cycle is actually controlled by the > divider, it can continue to use the clock through the gate, as usual. The > simple propagation will stop at the first clock which resample the signal > (such as a divider). > > Patch 2 and 3 add the pass-through ops to the generic gate and mux ops. In > this first version, it is unconditional, but maybe we should provide a flag > to let people decide what is best for them ? > > The series has been developed to handled the sample clocks provided by > audio clock controller of amlogic's A113 SoC. To support i2s modes, this > clock need to have a 50% duty cycle ratio, while it should be just one > pulse of the parent clock in dsp modes. Cool. I've heard rumblings from some other SoC manufacturers that they want duty cycle control via the clk framework but nothing came of it, so thanks for picking this up. > > PS: Checkpatch complains heavily about the white space in the trace header > file. I believe I have respected the style already used in this > file. Please let me know if it should be done differently. The trace file looks fine. Ignore checkpatch.
Re: [PATCH 0/3] clk: add duty cycle support
Quoting Jerome Brunet (2018-04-16 10:57:40) > This patchset adds the possibility to control the duty cycle ratio of a > clock within the clock framework. > > This useful when the duty cycle ratio depends on another parameter > controlled by the clock framework. For example, the duty cycle ratio may > depends on the value of a divider (ratio = N / div). > > This is also useful if the related clock is part of large tree. In this > case, using CCF to control the clock tree and the PWM framework for the > duty cycle would be a nightmare for the provider and the consumer. Can you please Cc the PWM maintainer on this patch series? > > A clock provider is not required to implement the operation to set and get > the duty cycle. If it does not implement .get_duty_cycle(), the ratio is > assumed to be 50%. > > This series also provides pass-through operations ready to be used for > clock which don't resample the clock signal (such as gates and muxes). > This is provided to make things easier for consumers. Clocks are usually > made of several elements, like a composite clocks with a mux, a divider, > and a gate. With the pass-through ops set on the gate, the consumer does > not need to be aware that the duty cycle is actually controlled by the > divider, it can continue to use the clock through the gate, as usual. The > simple propagation will stop at the first clock which resample the signal > (such as a divider). > > Patch 2 and 3 add the pass-through ops to the generic gate and mux ops. In > this first version, it is unconditional, but maybe we should provide a flag > to let people decide what is best for them ? > > The series has been developed to handled the sample clocks provided by > audio clock controller of amlogic's A113 SoC. To support i2s modes, this > clock need to have a 50% duty cycle ratio, while it should be just one > pulse of the parent clock in dsp modes. Cool. I've heard rumblings from some other SoC manufacturers that they want duty cycle control via the clk framework but nothing came of it, so thanks for picking this up. > > PS: Checkpatch complains heavily about the white space in the trace header > file. I believe I have respected the style already used in this > file. Please let me know if it should be done differently. The trace file looks fine. Ignore checkpatch.
[PATCH 2/3] KVM: X86: Allow userspace to disable ioport intercept
From: Wanpeng LiAllow to disable ioport intercept by userspace. Cc: Paolo Bonzini Cc: Radim Krčmář Cc: Tim Shearer Cc: Liran Alon Signed-off-by: Wanpeng Li --- Documentation/virtual/kvm/api.txt | 11 +++ arch/x86/include/asm/kvm_host.h | 2 ++ arch/x86/kvm/x86.c| 5 + include/uapi/linux/kvm.h | 1 + 4 files changed, 19 insertions(+) diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 1c7958b..3d0488e 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -4378,6 +4378,17 @@ all such vmexits. Do not enable KVM_FEATURE_PV_UNHALT if you disable HLT exits. +7.14 KVM_CAP_IOPORT_DISABLE_INTERCEPT + +Architectures: x86 +Parameters: args[0] defines whether ioport intercept + +When disable intercept (args[0] == 1), some ioports which frequently +access will not be intercepted. + +When enable intercept (args[0] == 0), behavior is as if this facility +is unsupported. + 8. Other capabilities. -- diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index c25775f..2f29f64 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -808,6 +808,8 @@ struct kvm_arch { bool hlt_in_guest; bool pause_in_guest; + bool ioport_disable_intercept; + unsigned long irq_sources_bitmap; s64 kvmclock_offset; raw_spinlock_t tsc_write_lock; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 51ecd38..044e314 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2881,6 +2881,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_SPLIT_IRQCHIP: case KVM_CAP_IMMEDIATE_EXIT: case KVM_CAP_GET_MSR_FEATURES: + case KVM_CAP_IOPORT_DISABLE_INTERCEPT: r = 1; break; case KVM_CAP_SYNC_REGS: @@ -4250,6 +4251,10 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, kvm->arch.pause_in_guest = true; r = 0; break; + case KVM_CAP_IOPORT_DISABLE_INTERCEPT: + kvm->arch.ioport_disable_intercept = cap->args[0]; + r = 0; + break; default: r = -EINVAL; break; diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 1065006..92730d8 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -941,6 +941,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_S390_BPB 152 #define KVM_CAP_GET_MSR_FEATURES 153 #define KVM_CAP_HYPERV_EVENTFD 154 +#define KVM_CAP_IOPORT_DISABLE_INTERCEPT 155 #ifdef KVM_CAP_IRQ_ROUTING -- 2.7.4
[PATCH 1/3] KVM: VMX: Introduce per-VM I/O permission bitmaps
From: Wanpeng LiThis patch introduces per-VM I/O permission bitmaps, it will be used by later patches. Cc: Paolo Bonzini Cc: Radim Krčmář Cc: Tim Shearer Cc: Liran Alon Signed-off-by: Wanpeng Li --- arch/x86/kvm/vmx.c | 34 +++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 5b49ad4..ebf1140 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -189,12 +189,19 @@ module_param(ple_window_max, uint, 0444); extern const ulong vmx_return; +enum { + VMX_IO_BITMAP_A, + VMX_IO_BITMAP_B, + VMX_IO_BITMAP_NR +}; + struct kvm_vmx { struct kvm kvm; unsigned int tss_addr; bool ept_identity_pagetable_done; gpa_t ept_identity_map_addr; + unsigned long *vmx_io_bitmap[VMX_IO_BITMAP_NR]; }; #define NR_AUTOLOAD_MSRS 8 @@ -3963,7 +3970,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) #endif CPU_BASED_CR3_LOAD_EXITING | CPU_BASED_CR3_STORE_EXITING | - CPU_BASED_UNCOND_IO_EXITING | + CPU_BASED_USE_IO_BITMAPS | CPU_BASED_MOV_DR_EXITING | CPU_BASED_USE_TSC_OFFSETING | CPU_BASED_MWAIT_EXITING | @@ -5940,6 +5947,12 @@ static void vmx_vcpu_setup(struct vcpu_vmx *vmx) #endif int i; + /* I/O */ + vmcs_write64(IO_BITMAP_A, + __pa(to_kvm_vmx(vmx->vcpu.kvm)->vmx_io_bitmap[VMX_IO_BITMAP_A])); + vmcs_write64(IO_BITMAP_B, + __pa(to_kvm_vmx(vmx->vcpu.kvm)->vmx_io_bitmap[VMX_IO_BITMAP_B])); + if (enable_shadow_vmcs) { vmcs_write64(VMREAD_BITMAP, __pa(vmx_vmread_bitmap)); vmcs_write64(VMWRITE_BITMAP, __pa(vmx_vmwrite_bitmap)); @@ -10093,9 +10106,24 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) static int vmx_vm_init(struct kvm *kvm) { + int i; + struct kvm_vmx *kvm_vmx = to_kvm_vmx(kvm); + if (!ple_gap) kvm->arch.pause_in_guest = true; + + for (i = 0; i < VMX_IO_BITMAP_NR; i++) { + kvm_vmx->vmx_io_bitmap[i] = (unsigned long *)__get_free_page(GFP_KERNEL); + if (!kvm_vmx->vmx_io_bitmap[i]) + goto out; + memset(kvm_vmx->vmx_io_bitmap[i], 0xff, PAGE_SIZE); + } return 0; + +out: + for (i = 0; i < VMX_IO_BITMAP_NR; i++) + free_page((unsigned long)kvm_vmx->vmx_io_bitmap[i]); + return -ENOMEM; } static void __init vmx_check_processor_compat(void *rtn) @@ -11128,8 +11156,8 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, } /* -* A vmexit (to either L1 hypervisor or L0 userspace) is always needed -* for I/O port accesses. +* Merging of IO bitmap not currently supported. +* Rather, exit every time. */ exec_control &= ~CPU_BASED_USE_IO_BITMAPS; exec_control |= CPU_BASED_UNCOND_IO_EXITING; -- 2.7.4
[PATCH 3/3] KVM: VMX: Allow I/O port 0x80 bypass when userspace prefer
From: Wanpeng LiTim Shearer reported that "There is a guest which is running a packet forwarding app based on the DPDK (dpdk.org). The packet receive routine writes to 0xc070 using glibc's "outw_p" function which does an additional write to I/O port 80. It does this write for every packet that's received, causing a flood of KVM userspace context switches". He uses mpstat to observe a CPU performing L2 packet forwarding on a pinned guest vCPU, the guest time is 95 percent when allowing I/O port 0x80 bypass, however, it is 65.78 percent when I/O port 0x80 bypss is disabled. This patch allows I/O port 0x80 bypass when userspace prefer. Cc: Paolo Bonzini Cc: Radim Krčmář Cc: Tim Shearer Cc: Liran Alon Signed-off-by: Wanpeng Li --- arch/x86/kvm/vmx.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index ebf1140..d3e5fef 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -10118,6 +10118,13 @@ static int vmx_vm_init(struct kvm *kvm) goto out; memset(kvm_vmx->vmx_io_bitmap[i], 0xff, PAGE_SIZE); } + if (kvm->arch.ioport_disable_intercept) { + /* +* Allow direct access to the PC debug port (it is often used for I/O +* delays, but the vmexits simply slow things down). +*/ + clear_bit(0x80, kvm_vmx->vmx_io_bitmap[VMX_IO_BITMAP_A]); + } return 0; out: -- 2.7.4
[PATCH 1/3] KVM: VMX: Introduce per-VM I/O permission bitmaps
From: Wanpeng Li This patch introduces per-VM I/O permission bitmaps, it will be used by later patches. Cc: Paolo Bonzini Cc: Radim Krčmář Cc: Tim Shearer Cc: Liran Alon Signed-off-by: Wanpeng Li --- arch/x86/kvm/vmx.c | 34 +++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 5b49ad4..ebf1140 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -189,12 +189,19 @@ module_param(ple_window_max, uint, 0444); extern const ulong vmx_return; +enum { + VMX_IO_BITMAP_A, + VMX_IO_BITMAP_B, + VMX_IO_BITMAP_NR +}; + struct kvm_vmx { struct kvm kvm; unsigned int tss_addr; bool ept_identity_pagetable_done; gpa_t ept_identity_map_addr; + unsigned long *vmx_io_bitmap[VMX_IO_BITMAP_NR]; }; #define NR_AUTOLOAD_MSRS 8 @@ -3963,7 +3970,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) #endif CPU_BASED_CR3_LOAD_EXITING | CPU_BASED_CR3_STORE_EXITING | - CPU_BASED_UNCOND_IO_EXITING | + CPU_BASED_USE_IO_BITMAPS | CPU_BASED_MOV_DR_EXITING | CPU_BASED_USE_TSC_OFFSETING | CPU_BASED_MWAIT_EXITING | @@ -5940,6 +5947,12 @@ static void vmx_vcpu_setup(struct vcpu_vmx *vmx) #endif int i; + /* I/O */ + vmcs_write64(IO_BITMAP_A, + __pa(to_kvm_vmx(vmx->vcpu.kvm)->vmx_io_bitmap[VMX_IO_BITMAP_A])); + vmcs_write64(IO_BITMAP_B, + __pa(to_kvm_vmx(vmx->vcpu.kvm)->vmx_io_bitmap[VMX_IO_BITMAP_B])); + if (enable_shadow_vmcs) { vmcs_write64(VMREAD_BITMAP, __pa(vmx_vmread_bitmap)); vmcs_write64(VMWRITE_BITMAP, __pa(vmx_vmwrite_bitmap)); @@ -10093,9 +10106,24 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id) static int vmx_vm_init(struct kvm *kvm) { + int i; + struct kvm_vmx *kvm_vmx = to_kvm_vmx(kvm); + if (!ple_gap) kvm->arch.pause_in_guest = true; + + for (i = 0; i < VMX_IO_BITMAP_NR; i++) { + kvm_vmx->vmx_io_bitmap[i] = (unsigned long *)__get_free_page(GFP_KERNEL); + if (!kvm_vmx->vmx_io_bitmap[i]) + goto out; + memset(kvm_vmx->vmx_io_bitmap[i], 0xff, PAGE_SIZE); + } return 0; + +out: + for (i = 0; i < VMX_IO_BITMAP_NR; i++) + free_page((unsigned long)kvm_vmx->vmx_io_bitmap[i]); + return -ENOMEM; } static void __init vmx_check_processor_compat(void *rtn) @@ -11128,8 +11156,8 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, } /* -* A vmexit (to either L1 hypervisor or L0 userspace) is always needed -* for I/O port accesses. +* Merging of IO bitmap not currently supported. +* Rather, exit every time. */ exec_control &= ~CPU_BASED_USE_IO_BITMAPS; exec_control |= CPU_BASED_UNCOND_IO_EXITING; -- 2.7.4
[PATCH 3/3] KVM: VMX: Allow I/O port 0x80 bypass when userspace prefer
From: Wanpeng Li Tim Shearer reported that "There is a guest which is running a packet forwarding app based on the DPDK (dpdk.org). The packet receive routine writes to 0xc070 using glibc's "outw_p" function which does an additional write to I/O port 80. It does this write for every packet that's received, causing a flood of KVM userspace context switches". He uses mpstat to observe a CPU performing L2 packet forwarding on a pinned guest vCPU, the guest time is 95 percent when allowing I/O port 0x80 bypass, however, it is 65.78 percent when I/O port 0x80 bypss is disabled. This patch allows I/O port 0x80 bypass when userspace prefer. Cc: Paolo Bonzini Cc: Radim Krčmář Cc: Tim Shearer Cc: Liran Alon Signed-off-by: Wanpeng Li --- arch/x86/kvm/vmx.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index ebf1140..d3e5fef 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -10118,6 +10118,13 @@ static int vmx_vm_init(struct kvm *kvm) goto out; memset(kvm_vmx->vmx_io_bitmap[i], 0xff, PAGE_SIZE); } + if (kvm->arch.ioport_disable_intercept) { + /* +* Allow direct access to the PC debug port (it is often used for I/O +* delays, but the vmexits simply slow things down). +*/ + clear_bit(0x80, kvm_vmx->vmx_io_bitmap[VMX_IO_BITMAP_A]); + } return 0; out: -- 2.7.4
[PATCH 2/3] KVM: X86: Allow userspace to disable ioport intercept
From: Wanpeng Li Allow to disable ioport intercept by userspace. Cc: Paolo Bonzini Cc: Radim Krčmář Cc: Tim Shearer Cc: Liran Alon Signed-off-by: Wanpeng Li --- Documentation/virtual/kvm/api.txt | 11 +++ arch/x86/include/asm/kvm_host.h | 2 ++ arch/x86/kvm/x86.c| 5 + include/uapi/linux/kvm.h | 1 + 4 files changed, 19 insertions(+) diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt index 1c7958b..3d0488e 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -4378,6 +4378,17 @@ all such vmexits. Do not enable KVM_FEATURE_PV_UNHALT if you disable HLT exits. +7.14 KVM_CAP_IOPORT_DISABLE_INTERCEPT + +Architectures: x86 +Parameters: args[0] defines whether ioport intercept + +When disable intercept (args[0] == 1), some ioports which frequently +access will not be intercepted. + +When enable intercept (args[0] == 0), behavior is as if this facility +is unsupported. + 8. Other capabilities. -- diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index c25775f..2f29f64 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -808,6 +808,8 @@ struct kvm_arch { bool hlt_in_guest; bool pause_in_guest; + bool ioport_disable_intercept; + unsigned long irq_sources_bitmap; s64 kvmclock_offset; raw_spinlock_t tsc_write_lock; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 51ecd38..044e314 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2881,6 +2881,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_SPLIT_IRQCHIP: case KVM_CAP_IMMEDIATE_EXIT: case KVM_CAP_GET_MSR_FEATURES: + case KVM_CAP_IOPORT_DISABLE_INTERCEPT: r = 1; break; case KVM_CAP_SYNC_REGS: @@ -4250,6 +4251,10 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, kvm->arch.pause_in_guest = true; r = 0; break; + case KVM_CAP_IOPORT_DISABLE_INTERCEPT: + kvm->arch.ioport_disable_intercept = cap->args[0]; + r = 0; + break; default: r = -EINVAL; break; diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 1065006..92730d8 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -941,6 +941,7 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_S390_BPB 152 #define KVM_CAP_GET_MSR_FEATURES 153 #define KVM_CAP_HYPERV_EVENTFD 154 +#define KVM_CAP_IOPORT_DISABLE_INTERCEPT 155 #ifdef KVM_CAP_IRQ_ROUTING -- 2.7.4
[PATCH 0/3] KVM: VMX: Allow to disable ioport intercept per-VM by userspace
Tim Shearer reported that "There is a guest which is running a packet forwarding app based on the DPDK (dpdk.org). The packet receive routine writes to 0xc070 using glibc's "outw_p" function which does an additional write to I/O port 0x80. It does this write for every packet that's received, causing a flood of KVM userspace context switches". He uses mpstat to observe a CPU performing L2 packet forwarding on a pinned guest vCPU, the guest time is 95 percent when allowing I/O port 0x80 bypass, however, it is 65.78 percent when I/O port 0x80 bypss is disabled. This patchset introduces per-VM I/O permission bitmaps, the userspace can disable the ioport intercept when they are more concern the performance than the security. Cc: Paolo BonziniCc: Radim Krčmář Cc: Tim Shearer Cc: Liran Alon Wanpeng Li (3): KVM: VMX: Introduce per-VM I/O permission bitmaps KVM: X86: Allow userspace to disable ioport intercept KVM: VMX: Allow I/O port 0x80 bypass when userspace prefer Documentation/virtual/kvm/api.txt | 11 +++ arch/x86/include/asm/kvm_host.h | 2 ++ arch/x86/kvm/vmx.c| 41 --- arch/x86/kvm/x86.c| 5 + include/uapi/linux/kvm.h | 1 + 5 files changed, 57 insertions(+), 3 deletions(-) -- 2.7.4
[PATCH 0/3] KVM: VMX: Allow to disable ioport intercept per-VM by userspace
Tim Shearer reported that "There is a guest which is running a packet forwarding app based on the DPDK (dpdk.org). The packet receive routine writes to 0xc070 using glibc's "outw_p" function which does an additional write to I/O port 0x80. It does this write for every packet that's received, causing a flood of KVM userspace context switches". He uses mpstat to observe a CPU performing L2 packet forwarding on a pinned guest vCPU, the guest time is 95 percent when allowing I/O port 0x80 bypass, however, it is 65.78 percent when I/O port 0x80 bypss is disabled. This patchset introduces per-VM I/O permission bitmaps, the userspace can disable the ioport intercept when they are more concern the performance than the security. Cc: Paolo Bonzini Cc: Radim Krčmář Cc: Tim Shearer Cc: Liran Alon Wanpeng Li (3): KVM: VMX: Introduce per-VM I/O permission bitmaps KVM: X86: Allow userspace to disable ioport intercept KVM: VMX: Allow I/O port 0x80 bypass when userspace prefer Documentation/virtual/kvm/api.txt | 11 +++ arch/x86/include/asm/kvm_host.h | 2 ++ arch/x86/kvm/vmx.c| 41 --- arch/x86/kvm/x86.c| 5 + include/uapi/linux/kvm.h | 1 + 5 files changed, 57 insertions(+), 3 deletions(-) -- 2.7.4
Re: [PATCH 1/3] clk: add duty cycle support
Quoting Jerome Brunet (2018-04-16 10:57:41) > diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c > index 7af555f0e60c..fff7890ae355 100644 > --- a/drivers/clk/clk.c > +++ b/drivers/clk/clk.c > @@ -68,6 +68,8 @@ struct clk_core { > unsigned long max_rate; > unsigned long accuracy; > int phase; > + unsigned intduty_num; > + unsigned intduty_den; Maybe this can be a struct? struct duty { unsigned int num; unsigned int den; }; Or even more generically, a struct frac? > struct hlist_head children; > struct hlist_node child_node; > struct hlist_head clks; > @@ -2401,6 +2403,164 @@ int clk_get_phase(struct clk *clk) > } > EXPORT_SYMBOL_GPL(clk_get_phase); > > +static int clk_core_update_duty_cycle_nolock(struct clk_core *core) > +{ > + int ret; > + unsigned int num, den; > + > + if (!core || !core->ops->get_duty_cycle) Does !core happen? > + return 0; > + > + /* Update the duty cycle if the callback is available */ > + ret = core->ops->get_duty_cycle(core->hw, , ); > + if (ret) > + return ret; > + > + /* Don't trust the clock provider too much */ > + if (den == 0 || (num > den)) Drop useless parenthesis please. > + return -EINVAL; > + > + core->duty_num = num; > + core->duty_den = den; > + > + return 0; > +} > + > +static int clk_core_get_duty_cycle_nolock(struct clk_core *core, > + unsigned int *num, > + unsigned int *den) > +{ > + int ret; > + > + if (!core) > + return 0; Shouldn't this return 50%? At least it seems like the "no clk" case should be the default 50% duty cycle case. > + > + ret = clk_core_update_duty_cycle_nolock(core); > + > + if (!ret) { > + *num = core->duty_num; > + *den = core->duty_den; > + } > + > + return ret; > +} > + > +static int clk_core_set_duty_cycle_nolock(struct clk_core *core, > + unsigned int num, > + unsigned int den) > +{ > + int ret; > + > + lockdep_assert_held(_lock); > + > + if (!core || !core->ops->set_duty_cycle) Does the !core case happen? > + return 0; > + > + if (clk_core_rate_is_protected(core)) > + return -EBUSY; > + > + trace_clk_set_duty_cycle(core, num, den); > + > + ret = core->ops->set_duty_cycle(core->hw, num, den); Is the assumption that we aren't going to need to adjust the duty cycle of any parent clks when we set the duty cycle on a clk? > + if (ret) > + return ret; > + > + core->duty_num = num; > + core->duty_den = den; > + > + trace_clk_set_duty_cycle_complete(core, num, den); > + > + return ret; > +} > + > +/** > + * clk_set_duty_cycle - adjust the duty cycle ratio of a clock signal > + * @clk: clock signal source > + * @ratio: duty cycle ratio in milli-percent This doesn't match anymore. > + * > + * ADD BLURB HERE Please do! :) > + */ > +int clk_set_duty_cycle(struct clk *clk, unsigned int num, unsigned int den) > +{ > + int ret; > + > + if (!clk) > + return 0; > + > + /* sanity check the ratio */ > + if (den == 0 || (num > den)) Drop useless parenthesis please. > + return -EINVAL; > + > + clk_prepare_lock(); > + > + if (clk->exclusive_count) > + clk_core_rate_unprotect(clk->core); > + > + ret = clk_core_set_duty_cycle_nolock(clk->core, num, den); > + > + if (clk->exclusive_count) > + clk_core_rate_protect(clk->core); > + > + clk_prepare_unlock(); > + > + return ret; > +} > +EXPORT_SYMBOL_GPL(clk_set_duty_cycle); > + > +static unsigned int clk_core_get_scaled_duty_cycle(struct clk_core *core, > + unsigned int scale) > +{ > + int ret; > + unsigned int duty; > + > + clk_prepare_lock(); > + ret = clk_core_update_duty_cycle_nolock(core); > + if (ret) > + return 0; > + > + duty = DIV_ROUND_CLOSEST_ULL((u64)core->duty_num * scale, > +core->duty_den); Just use mult_frac() instead of casting and rounding to closest? I haven't looked closely so feel free to correct me if that doesn't make sense. > + > + clk_prepare_unlock(); > + > + return duty; > +} > + > +/** > + * clk_get_scaled_duty_cycle - return the duty cycle ratio of a clock signal > + * @clk: clock signal source > + * @scale: scaling factor to be applied to represent the ratio as an integer > + * > + * Returns the duty cycle ratio of a clock node multiplied by the provided > + * scaling
Re: [PATCH 1/3] clk: add duty cycle support
Quoting Jerome Brunet (2018-04-16 10:57:41) > diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c > index 7af555f0e60c..fff7890ae355 100644 > --- a/drivers/clk/clk.c > +++ b/drivers/clk/clk.c > @@ -68,6 +68,8 @@ struct clk_core { > unsigned long max_rate; > unsigned long accuracy; > int phase; > + unsigned intduty_num; > + unsigned intduty_den; Maybe this can be a struct? struct duty { unsigned int num; unsigned int den; }; Or even more generically, a struct frac? > struct hlist_head children; > struct hlist_node child_node; > struct hlist_head clks; > @@ -2401,6 +2403,164 @@ int clk_get_phase(struct clk *clk) > } > EXPORT_SYMBOL_GPL(clk_get_phase); > > +static int clk_core_update_duty_cycle_nolock(struct clk_core *core) > +{ > + int ret; > + unsigned int num, den; > + > + if (!core || !core->ops->get_duty_cycle) Does !core happen? > + return 0; > + > + /* Update the duty cycle if the callback is available */ > + ret = core->ops->get_duty_cycle(core->hw, , ); > + if (ret) > + return ret; > + > + /* Don't trust the clock provider too much */ > + if (den == 0 || (num > den)) Drop useless parenthesis please. > + return -EINVAL; > + > + core->duty_num = num; > + core->duty_den = den; > + > + return 0; > +} > + > +static int clk_core_get_duty_cycle_nolock(struct clk_core *core, > + unsigned int *num, > + unsigned int *den) > +{ > + int ret; > + > + if (!core) > + return 0; Shouldn't this return 50%? At least it seems like the "no clk" case should be the default 50% duty cycle case. > + > + ret = clk_core_update_duty_cycle_nolock(core); > + > + if (!ret) { > + *num = core->duty_num; > + *den = core->duty_den; > + } > + > + return ret; > +} > + > +static int clk_core_set_duty_cycle_nolock(struct clk_core *core, > + unsigned int num, > + unsigned int den) > +{ > + int ret; > + > + lockdep_assert_held(_lock); > + > + if (!core || !core->ops->set_duty_cycle) Does the !core case happen? > + return 0; > + > + if (clk_core_rate_is_protected(core)) > + return -EBUSY; > + > + trace_clk_set_duty_cycle(core, num, den); > + > + ret = core->ops->set_duty_cycle(core->hw, num, den); Is the assumption that we aren't going to need to adjust the duty cycle of any parent clks when we set the duty cycle on a clk? > + if (ret) > + return ret; > + > + core->duty_num = num; > + core->duty_den = den; > + > + trace_clk_set_duty_cycle_complete(core, num, den); > + > + return ret; > +} > + > +/** > + * clk_set_duty_cycle - adjust the duty cycle ratio of a clock signal > + * @clk: clock signal source > + * @ratio: duty cycle ratio in milli-percent This doesn't match anymore. > + * > + * ADD BLURB HERE Please do! :) > + */ > +int clk_set_duty_cycle(struct clk *clk, unsigned int num, unsigned int den) > +{ > + int ret; > + > + if (!clk) > + return 0; > + > + /* sanity check the ratio */ > + if (den == 0 || (num > den)) Drop useless parenthesis please. > + return -EINVAL; > + > + clk_prepare_lock(); > + > + if (clk->exclusive_count) > + clk_core_rate_unprotect(clk->core); > + > + ret = clk_core_set_duty_cycle_nolock(clk->core, num, den); > + > + if (clk->exclusive_count) > + clk_core_rate_protect(clk->core); > + > + clk_prepare_unlock(); > + > + return ret; > +} > +EXPORT_SYMBOL_GPL(clk_set_duty_cycle); > + > +static unsigned int clk_core_get_scaled_duty_cycle(struct clk_core *core, > + unsigned int scale) > +{ > + int ret; > + unsigned int duty; > + > + clk_prepare_lock(); > + ret = clk_core_update_duty_cycle_nolock(core); > + if (ret) > + return 0; > + > + duty = DIV_ROUND_CLOSEST_ULL((u64)core->duty_num * scale, > +core->duty_den); Just use mult_frac() instead of casting and rounding to closest? I haven't looked closely so feel free to correct me if that doesn't make sense. > + > + clk_prepare_unlock(); > + > + return duty; > +} > + > +/** > + * clk_get_scaled_duty_cycle - return the duty cycle ratio of a clock signal > + * @clk: clock signal source > + * @scale: scaling factor to be applied to represent the ratio as an integer > + * > + * Returns the duty cycle ratio of a clock node multiplied by the provided > + * scaling
Re: [PATCH 4/7] ocxl: Rename pnv_ocxl_spa_remove_pe to clarify it's action
On 17/04/18 12:09, Alastair D'Silva wrote: From: Alastair D'SilvaThe function removes the process element from NPU cache. Signed-off-by: Alastair D'Silva Hmm, personally I'd suggest pnv_ocxl_spa_clear_cache() because it's just a wrapper around the OPAL call of a similar name. But I don't feel strongly about this at all, so: Acked-by: Andrew Donnellan -- Andrew Donnellan OzLabs, ADL Canberra andrew.donnel...@au1.ibm.com IBM Australia Limited
Re: [PATCH 4/7] ocxl: Rename pnv_ocxl_spa_remove_pe to clarify it's action
On 17/04/18 12:09, Alastair D'Silva wrote: From: Alastair D'Silva The function removes the process element from NPU cache. Signed-off-by: Alastair D'Silva Hmm, personally I'd suggest pnv_ocxl_spa_clear_cache() because it's just a wrapper around the OPAL call of a similar name. But I don't feel strongly about this at all, so: Acked-by: Andrew Donnellan -- Andrew Donnellan OzLabs, ADL Canberra andrew.donnel...@au1.ibm.com IBM Australia Limited
Re: [PATCH 2/7] powerpc: Use TIDR CPU feature to control TIDR allocation
On Tue, 2018-04-17 at 14:21 +1000, Andrew Donnellan wrote: > On 17/04/18 12:09, Alastair D'Silva wrote: > > From: Alastair D'Silva> > > > Switch the use of TIDR on it's CPU feature, rather than assuming it > > is available based on architecture. > > > > Signed-off-by: Alastair D'Silva > > There's a use of TIDR in restore_sprs() that's behind the ARCH_300 > flag > as well, ideally it should never trigger in the !P9_TIDR case, but > you > might want to update that too for clarity? > Thanks for the review, I'll include your suggestions in the next set. -- Alastair D'Silva Open Source Developer Linux Technology Centre, IBM Australia mob: 0423 762 819
Re: [PATCH 2/7] powerpc: Use TIDR CPU feature to control TIDR allocation
On Tue, 2018-04-17 at 14:21 +1000, Andrew Donnellan wrote: > On 17/04/18 12:09, Alastair D'Silva wrote: > > From: Alastair D'Silva > > > > Switch the use of TIDR on it's CPU feature, rather than assuming it > > is available based on architecture. > > > > Signed-off-by: Alastair D'Silva > > There's a use of TIDR in restore_sprs() that's behind the ARCH_300 > flag > as well, ideally it should never trigger in the !P9_TIDR case, but > you > might want to update that too for clarity? > Thanks for the review, I'll include your suggestions in the next set. -- Alastair D'Silva Open Source Developer Linux Technology Centre, IBM Australia mob: 0423 762 819
Re: [lustre-devel] [PATCH 1/6] staging: lustre: move stack-check macros to libcfs_debug.h
On Apr 16, 2018, at 16:48, Doug Oucharekwrote: > >> >> On Apr 16, 2018, at 3:42 PM, James Simmons wrote: >> >> >>> James, >>> >>> If I understand correctly, you're saying you want to be able to build >>> without debug support...? I'm not convinced that building a client without >>> debug support is interesting or useful. In fact, I think it would be >>> harmful, and we shouldn't open up the possibility - this is switchable >>> debug with very low overhead when not actually "on". It would be really >>> awful to get a problem on a running system and discover there's no debug >>> support - that you can't even enable debug without a reinstall. >>> >>> If I've understood you correctly, then I would want to see proof of a >>> significant performance cost when debug is built but *off* before agreeing >>> to even exposing this option. (I know it's a choice they'd have to make, >>> but if it's not really useful with a side order of potentially harmful, we >>> shouldn't even give people the choice.) >> >> I'm not saying add the option today but this is more for the long game. >> While the Intel lustre developers deeply love lustre's debugging >> infrastructure I see a future where something better will come along to >> replace it. When that day comes we will have a period where both >> debugging infrastructurs will exist and some deployers of lustre will >> want to turn off the old debugging infrastructure and just use the new. >> That is what I have in mind. A switch to flip between options. > > Yes please!! An option for users which says “no, you do not have the right > to panic my system via LASSERT whenever you like” would be a blessing. Note that LASSERT() itself does not panic the system, unless you configure it with panic_on_lbug=1. Otherwise, it just blocks that thread (though this can also have an impact on other threads if you are holding locks at that time). That said, the LASSERT() should not be hit unless there is bad code, data corruption, or the LASSERT() itself is incorrect (essentially bad code also). So "whenever you like" is "whenever the system is about to corrupt your data", and people are not very forgiving if a filesystem corrupts their data... Cheers, Andreas -- Andreas Dilger Lustre Principal Architect Intel Corporation
Re: [lustre-devel] [PATCH 1/6] staging: lustre: move stack-check macros to libcfs_debug.h
On Apr 16, 2018, at 16:48, Doug Oucharek wrote: > >> >> On Apr 16, 2018, at 3:42 PM, James Simmons wrote: >> >> >>> James, >>> >>> If I understand correctly, you're saying you want to be able to build >>> without debug support...? I'm not convinced that building a client without >>> debug support is interesting or useful. In fact, I think it would be >>> harmful, and we shouldn't open up the possibility - this is switchable >>> debug with very low overhead when not actually "on". It would be really >>> awful to get a problem on a running system and discover there's no debug >>> support - that you can't even enable debug without a reinstall. >>> >>> If I've understood you correctly, then I would want to see proof of a >>> significant performance cost when debug is built but *off* before agreeing >>> to even exposing this option. (I know it's a choice they'd have to make, >>> but if it's not really useful with a side order of potentially harmful, we >>> shouldn't even give people the choice.) >> >> I'm not saying add the option today but this is more for the long game. >> While the Intel lustre developers deeply love lustre's debugging >> infrastructure I see a future where something better will come along to >> replace it. When that day comes we will have a period where both >> debugging infrastructurs will exist and some deployers of lustre will >> want to turn off the old debugging infrastructure and just use the new. >> That is what I have in mind. A switch to flip between options. > > Yes please!! An option for users which says “no, you do not have the right > to panic my system via LASSERT whenever you like” would be a blessing. Note that LASSERT() itself does not panic the system, unless you configure it with panic_on_lbug=1. Otherwise, it just blocks that thread (though this can also have an impact on other threads if you are holding locks at that time). That said, the LASSERT() should not be hit unless there is bad code, data corruption, or the LASSERT() itself is incorrect (essentially bad code also). So "whenever you like" is "whenever the system is about to corrupt your data", and people are not very forgiving if a filesystem corrupts their data... Cheers, Andreas -- Andreas Dilger Lustre Principal Architect Intel Corporation
Re: [PATCH] security: remove security_settime
On Sun, 1 Apr 2018, Sargun Dhillon wrote: > security_settime was a wrapper around security_settime64. There are no more > users of it. Therefore it can be removed. It was removed in: > commit 4eb1bca17933 ("time: Use do_settimeofday64() internally") > > Signed-off-by: Sargun DhillonApplied to git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git next-general and next-testing -- James Morris
Re: [PATCH] security: remove security_settime
On Sun, 1 Apr 2018, Sargun Dhillon wrote: > security_settime was a wrapper around security_settime64. There are no more > users of it. Therefore it can be removed. It was removed in: > commit 4eb1bca17933 ("time: Use do_settimeofday64() internally") > > Signed-off-by: Sargun Dhillon Applied to git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git next-general and next-testing -- James Morris
[PATCH] usb: always build usb/common/ targets; fixes extcon-axp288 build error
From: Randy DunlapThe extcon-axp288 driver selects USB_ROLE_SWITCH, but the USB Makefile does not currently build drivers/usb/common/ (where USB_ROLE_SWITCH code is) unless USB_COMMON is set, so modify the USB Makefile to always descend into drivers/usb/common/ to build its configured targets. Fixes these build errors: ERROR: "usb_role_switch_get" [drivers/extcon/extcon-axp288.ko] undefined! ERROR: "usb_role_switch_set_role" [drivers/extcon/extcon-axp288.ko] undefined! ERROR: "usb_role_switch_get_role" [drivers/extcon/extcon-axp288.ko] undefined! ERROR: "usb_role_switch_put" [drivers/extcon/extcon-axp288.ko] undefined! An alternative patch would be to select USB_COMMON in the EXTCON_AXP288 driver Kconfig entry, but this would build more code in drivers/usb/common/ than is necessary. Reported-by: Fengguang Wu Signed-off-by: Randy Dunlap Cc: MyungJoo Ham Cc: Chanwoo Choi Cc: Hans de Goede Cc: Greg Kroah-Hartman Cc: Andy Shevchenko Cc: Heikki Krogerus Cc: linux-...@vger.kernel.org --- drivers/usb/Makefile |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- lnx-417-rc1.orig/drivers/usb/Makefile +++ lnx-417-rc1/drivers/usb/Makefile @@ -60,7 +60,7 @@ obj-$(CONFIG_USB_CHIPIDEA)+= chipidea/ obj-$(CONFIG_USB_RENESAS_USBHS)+= renesas_usbhs/ obj-$(CONFIG_USB_GADGET) += gadget/ -obj-$(CONFIG_USB_COMMON) += common/ +obj-y += common/ obj-$(CONFIG_USBIP_CORE) += usbip/
[PATCH] usb: always build usb/common/ targets; fixes extcon-axp288 build error
From: Randy Dunlap The extcon-axp288 driver selects USB_ROLE_SWITCH, but the USB Makefile does not currently build drivers/usb/common/ (where USB_ROLE_SWITCH code is) unless USB_COMMON is set, so modify the USB Makefile to always descend into drivers/usb/common/ to build its configured targets. Fixes these build errors: ERROR: "usb_role_switch_get" [drivers/extcon/extcon-axp288.ko] undefined! ERROR: "usb_role_switch_set_role" [drivers/extcon/extcon-axp288.ko] undefined! ERROR: "usb_role_switch_get_role" [drivers/extcon/extcon-axp288.ko] undefined! ERROR: "usb_role_switch_put" [drivers/extcon/extcon-axp288.ko] undefined! An alternative patch would be to select USB_COMMON in the EXTCON_AXP288 driver Kconfig entry, but this would build more code in drivers/usb/common/ than is necessary. Reported-by: Fengguang Wu Signed-off-by: Randy Dunlap Cc: MyungJoo Ham Cc: Chanwoo Choi Cc: Hans de Goede Cc: Greg Kroah-Hartman Cc: Andy Shevchenko Cc: Heikki Krogerus Cc: linux-...@vger.kernel.org --- drivers/usb/Makefile |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- lnx-417-rc1.orig/drivers/usb/Makefile +++ lnx-417-rc1/drivers/usb/Makefile @@ -60,7 +60,7 @@ obj-$(CONFIG_USB_CHIPIDEA)+= chipidea/ obj-$(CONFIG_USB_RENESAS_USBHS)+= renesas_usbhs/ obj-$(CONFIG_USB_GADGET) += gadget/ -obj-$(CONFIG_USB_COMMON) += common/ +obj-y += common/ obj-$(CONFIG_USBIP_CORE) += usbip/
Re: [PATCH 2/2] mm: vmalloc: Pass proper vm_start into debugobjects
On 4/17/2018 8:39 AM, Anshuman Khandual wrote: On 04/16/2018 05:39 PM, Chintan Pandya wrote: On 4/13/2018 5:31 PM, Anshuman Khandual wrote: On 04/13/2018 05:03 PM, Chintan Pandya wrote: Client can call vunmap with some intermediate 'addr' which may not be the start of the VM area. Entire unmap code works with vm->vm_start which is proper but debug object API is called with 'addr'. This could be a problem within debug objects. Pass proper start address into debug object API. Signed-off-by: Chintan Pandya--- mm/vmalloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 9ff21a1..28034c55 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -1526,8 +1526,8 @@ static void __vunmap(const void *addr, int deallocate_pages) return; } -debug_check_no_locks_freed(addr, get_vm_area_size(area)); -debug_check_no_obj_freed(addr, get_vm_area_size(area)); +debug_check_no_locks_freed(area->addr, get_vm_area_size(area)); +debug_check_no_obj_freed(area->addr, get_vm_area_size(area)); This kind of makes sense to me but I am not sure. We also have another instance of this inside the function vm_unmap_ram() where we call for Right, I missed it. I plan to add below stub in v2. --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -1124,15 +1124,15 @@ void vm_unmap_ram(const void *mem, unsigned int count) BUG_ON(addr > VMALLOC_END); BUG_ON(!PAGE_ALIGNED(addr)); - debug_check_no_locks_freed(mem, size); - if (likely(count <= VMAP_MAX_ALLOC)) { + debug_check_no_locks_freed(mem, size); It should have been 'va->va_start' instead of 'mem' in here but as said before it looks correct to me but I am not really sure. vb_free() doesn't honor va->va_start. If mem is not va_start and deliberate, one will provide proper size. And that should be okay to do as per the code. So, I don't think this particular debug_check should have passed va_start in args. Chintan -- Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
Re: [PATCH 2/2] mm: vmalloc: Pass proper vm_start into debugobjects
On 4/17/2018 8:39 AM, Anshuman Khandual wrote: On 04/16/2018 05:39 PM, Chintan Pandya wrote: On 4/13/2018 5:31 PM, Anshuman Khandual wrote: On 04/13/2018 05:03 PM, Chintan Pandya wrote: Client can call vunmap with some intermediate 'addr' which may not be the start of the VM area. Entire unmap code works with vm->vm_start which is proper but debug object API is called with 'addr'. This could be a problem within debug objects. Pass proper start address into debug object API. Signed-off-by: Chintan Pandya --- mm/vmalloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 9ff21a1..28034c55 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -1526,8 +1526,8 @@ static void __vunmap(const void *addr, int deallocate_pages) return; } -debug_check_no_locks_freed(addr, get_vm_area_size(area)); -debug_check_no_obj_freed(addr, get_vm_area_size(area)); +debug_check_no_locks_freed(area->addr, get_vm_area_size(area)); +debug_check_no_obj_freed(area->addr, get_vm_area_size(area)); This kind of makes sense to me but I am not sure. We also have another instance of this inside the function vm_unmap_ram() where we call for Right, I missed it. I plan to add below stub in v2. --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -1124,15 +1124,15 @@ void vm_unmap_ram(const void *mem, unsigned int count) BUG_ON(addr > VMALLOC_END); BUG_ON(!PAGE_ALIGNED(addr)); - debug_check_no_locks_freed(mem, size); - if (likely(count <= VMAP_MAX_ALLOC)) { + debug_check_no_locks_freed(mem, size); It should have been 'va->va_start' instead of 'mem' in here but as said before it looks correct to me but I am not really sure. vb_free() doesn't honor va->va_start. If mem is not va_start and deliberate, one will provide proper size. And that should be okay to do as per the code. So, I don't think this particular debug_check should have passed va_start in args. Chintan -- Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[PATCH] staging: bcm2835-audio: Disconnect and free vchi_instance on module_exit()
In the current implementation, vchi_instance is inited during the first call of bcm2835_audio_open_connection(), and is never freed. It causes a memory leak when the module `snd_bcm2835` is removed. Here is how this commit fixes it: * the VCHI context (including vchi_instance) is created once in the platform's devres * the VCHI context is allocated and connected once during module_init() * all created bcm2835_chips have a pointer to this VCHI context * bcm2835_audio_open_connection() can access the VCHI context through the associated bcm2835_chip * the VCHI context is disconnected and freed once during module_exit() After this commit is applied, I don't see other issues with the module's init/exit, so I also remove the associated TODO task. Steps to reproduce the memory leak before this commit: root@raspberrypi:/home/pi# aplay test0.wav Playing WAVE 'test0.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Ster ^CAborted by signal Interrupt... root@raspberrypi:/home/pi# rmmod snd_bcm2835 root@raspberrypi:/home/pi# modprobe snd_bcm2835 root@raspberrypi:/home/pi# aplay test0.wav Playing WAVE 'test0.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Ster ^CAborted by signal Interrupt... root@raspberrypi:/home/pi# echo scan > /sys/kernel/debug/kmemleak root@raspberrypi:/home/pi# cat /sys/kernel/debug/kmemleak unreferenced object 0xb6794c00 (size 128): comm "aplay", pid 406, jiffies 36870 (age 116.650s) hex dump (first 32 bytes): 08 a5 82 81 01 00 00 00 08 4c 79 b6 08 4c 79 b6 .Ly..Ly. 00 00 00 00 00 00 00 00 ad 4e ad de ff ff ff ff .N.. backtrace: [<802af5e0>] kmem_cache_alloc_trace+0x294/0x3d0 [<806ce620>] vchiq_initialise+0x98/0x1b0 [<806d0b34>] vchi_initialise+0x24/0x34 [<7f1311ec>] 0x7f1311ec [<7f1303bc>] 0x7f1303bc [<7f130590>] 0x7f130590 [<7f111fd8>] snd_pcm_open_substream+0x68/0xc4 [snd_pcm] [<7f112108>] snd_pcm_open+0xd4/0x248 [snd_pcm] [<7f112334>] snd_pcm_playback_open+0x4c/0x6c [snd_pcm] [<7f0e250c>] snd_open+0xa8/0x14c [snd] [<802ce590>] chrdev_open+0xac/0x188 [<802c57b4>] do_dentry_open+0x10c/0x314 [<802c6ba8>] vfs_open+0x5c/0x88 [<802d9a68>] path_openat+0x368/0x944 [<802dacd4>] do_filp_open+0x70/0xc4 [<802c6f70>] do_sys_open+0x110/0x1d4 Signed-off-by: Kirill MarinushkinCc: Eric Anholt Cc: Stefan Wahren Cc: Greg Kroah-Hartman Cc: Florian Fainelli Cc: Ray Jui Cc: Scott Branden Cc: Andy Shevchenko Cc: bcm-kernel-feedback-l...@broadcom.com Cc: linux-rpi-ker...@lists.infradead.org Cc: linux-arm-ker...@lists.infradead.org Cc: de...@driverdev.osuosl.org Cc: linux-kernel@vger.kernel.org --- .../vc04_services/bcm2835-audio/bcm2835-vchiq.c| 64 +- .../staging/vc04_services/bcm2835-audio/bcm2835.c | 43 ++- .../staging/vc04_services/bcm2835-audio/bcm2835.h | 12 3 files changed, 91 insertions(+), 28 deletions(-) diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c index 3c6f1d91d22d..389a18f9350a 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c @@ -33,7 +33,6 @@ /* Include Files */ -#include "interface/vchi/vchi.h" #include "vc_vchi_audioserv_defs.h" /* Private Constants and Types -- */ @@ -371,14 +370,46 @@ static int vc_vchi_audio_deinit(struct bcm2835_audio_instance *instance) return 0; } +int bcm2835_new_vchi_ctx(struct bcm2835_vchi_ctx *vchi_ctx) +{ + int ret; + + /* Initialize and create a VCHI connection */ + ret = vchi_initialise(_ctx->vchi_instance); + if (ret) { + LOG_ERR("%s: failed to initialise VCHI instance (ret=%d)\n", + __func__, ret); + + return -EIO; + } + + ret = vchi_connect(NULL, 0, vchi_ctx->vchi_instance); + if (ret) { + LOG_ERR("%s: failed to connect VCHI instance (ret=%d)\n", + __func__, ret); + + kfree(vchi_ctx->vchi_instance); + vchi_ctx->vchi_instance = NULL; + + return -EIO; + } + + return 0; +} + +void bcm2835_free_vchi_ctx(struct bcm2835_vchi_ctx *vchi_ctx) +{ + /* Close the VCHI connection - it will also free vchi_instance */ + WARN_ON(vchi_disconnect(vchi_ctx->vchi_instance)); + + vchi_ctx->vchi_instance = NULL; +} + static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream) { - static VCHI_INSTANCE_T vchi_instance; - static VCHI_CONNECTION_T *vchi_connection; - static int initted;
[PATCH] staging: bcm2835-audio: Disconnect and free vchi_instance on module_exit()
In the current implementation, vchi_instance is inited during the first call of bcm2835_audio_open_connection(), and is never freed. It causes a memory leak when the module `snd_bcm2835` is removed. Here is how this commit fixes it: * the VCHI context (including vchi_instance) is created once in the platform's devres * the VCHI context is allocated and connected once during module_init() * all created bcm2835_chips have a pointer to this VCHI context * bcm2835_audio_open_connection() can access the VCHI context through the associated bcm2835_chip * the VCHI context is disconnected and freed once during module_exit() After this commit is applied, I don't see other issues with the module's init/exit, so I also remove the associated TODO task. Steps to reproduce the memory leak before this commit: root@raspberrypi:/home/pi# aplay test0.wav Playing WAVE 'test0.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Ster ^CAborted by signal Interrupt... root@raspberrypi:/home/pi# rmmod snd_bcm2835 root@raspberrypi:/home/pi# modprobe snd_bcm2835 root@raspberrypi:/home/pi# aplay test0.wav Playing WAVE 'test0.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Ster ^CAborted by signal Interrupt... root@raspberrypi:/home/pi# echo scan > /sys/kernel/debug/kmemleak root@raspberrypi:/home/pi# cat /sys/kernel/debug/kmemleak unreferenced object 0xb6794c00 (size 128): comm "aplay", pid 406, jiffies 36870 (age 116.650s) hex dump (first 32 bytes): 08 a5 82 81 01 00 00 00 08 4c 79 b6 08 4c 79 b6 .Ly..Ly. 00 00 00 00 00 00 00 00 ad 4e ad de ff ff ff ff .N.. backtrace: [<802af5e0>] kmem_cache_alloc_trace+0x294/0x3d0 [<806ce620>] vchiq_initialise+0x98/0x1b0 [<806d0b34>] vchi_initialise+0x24/0x34 [<7f1311ec>] 0x7f1311ec [<7f1303bc>] 0x7f1303bc [<7f130590>] 0x7f130590 [<7f111fd8>] snd_pcm_open_substream+0x68/0xc4 [snd_pcm] [<7f112108>] snd_pcm_open+0xd4/0x248 [snd_pcm] [<7f112334>] snd_pcm_playback_open+0x4c/0x6c [snd_pcm] [<7f0e250c>] snd_open+0xa8/0x14c [snd] [<802ce590>] chrdev_open+0xac/0x188 [<802c57b4>] do_dentry_open+0x10c/0x314 [<802c6ba8>] vfs_open+0x5c/0x88 [<802d9a68>] path_openat+0x368/0x944 [<802dacd4>] do_filp_open+0x70/0xc4 [<802c6f70>] do_sys_open+0x110/0x1d4 Signed-off-by: Kirill Marinushkin Cc: Eric Anholt Cc: Stefan Wahren Cc: Greg Kroah-Hartman Cc: Florian Fainelli Cc: Ray Jui Cc: Scott Branden Cc: Andy Shevchenko Cc: bcm-kernel-feedback-l...@broadcom.com Cc: linux-rpi-ker...@lists.infradead.org Cc: linux-arm-ker...@lists.infradead.org Cc: de...@driverdev.osuosl.org Cc: linux-kernel@vger.kernel.org --- .../vc04_services/bcm2835-audio/bcm2835-vchiq.c| 64 +- .../staging/vc04_services/bcm2835-audio/bcm2835.c | 43 ++- .../staging/vc04_services/bcm2835-audio/bcm2835.h | 12 3 files changed, 91 insertions(+), 28 deletions(-) diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c index 3c6f1d91d22d..389a18f9350a 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c @@ -33,7 +33,6 @@ /* Include Files */ -#include "interface/vchi/vchi.h" #include "vc_vchi_audioserv_defs.h" /* Private Constants and Types -- */ @@ -371,14 +370,46 @@ static int vc_vchi_audio_deinit(struct bcm2835_audio_instance *instance) return 0; } +int bcm2835_new_vchi_ctx(struct bcm2835_vchi_ctx *vchi_ctx) +{ + int ret; + + /* Initialize and create a VCHI connection */ + ret = vchi_initialise(_ctx->vchi_instance); + if (ret) { + LOG_ERR("%s: failed to initialise VCHI instance (ret=%d)\n", + __func__, ret); + + return -EIO; + } + + ret = vchi_connect(NULL, 0, vchi_ctx->vchi_instance); + if (ret) { + LOG_ERR("%s: failed to connect VCHI instance (ret=%d)\n", + __func__, ret); + + kfree(vchi_ctx->vchi_instance); + vchi_ctx->vchi_instance = NULL; + + return -EIO; + } + + return 0; +} + +void bcm2835_free_vchi_ctx(struct bcm2835_vchi_ctx *vchi_ctx) +{ + /* Close the VCHI connection - it will also free vchi_instance */ + WARN_ON(vchi_disconnect(vchi_ctx->vchi_instance)); + + vchi_ctx->vchi_instance = NULL; +} + static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream) { - static VCHI_INSTANCE_T vchi_instance; - static VCHI_CONNECTION_T *vchi_connection; - static int initted; struct bcm2835_audio_instance *instance = (struct bcm2835_audio_instance *)alsa_stream->instance; - int ret; + struct bcm2835_vchi_ctx *vhci_ctx =
[PATCH 4/4] ASoC: amd: enabling bt i2s config after acp reset
On ST/CZ based platforms, for specific platform bt uart mux to be defined for bt i2s. By default, these pins will be used for uart. After acp reset , it requires to reprogram bt i2s config mux pins to enable bt i2s instance. added bt i2s enablement sequence during acp init. Signed-off-by: Vijendar MukundaSigned-off-by: Akshu Agrawal --- sound/soc/amd/acp-da7219-max98357a.c | 2 ++ sound/soc/amd/acp-pcm-dma.c | 9 + sound/soc/amd/acp.h | 1 + 3 files changed, 12 insertions(+) diff --git a/sound/soc/amd/acp-da7219-max98357a.c b/sound/soc/amd/acp-da7219-max98357a.c index b205c78..6dad0cb 100644 --- a/sound/soc/amd/acp-da7219-max98357a.c +++ b/sound/soc/amd/acp-da7219-max98357a.c @@ -44,6 +44,7 @@ static struct snd_soc_jack cz_jack; struct clk *da7219_dai_clk; +extern int bt_pad_enable; static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd) { @@ -81,6 +82,7 @@ static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd) } da7219_aad_jack_det(component, _jack); + bt_pad_enable = device_property_read_bool(>dev, "bt-pad-enable"); return 0; } diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index 7c392fe..b52c660 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -46,6 +46,8 @@ #define DRV_NAME "acp_audio_dma" +bool bt_pad_enable = false; +EXPORT_SYMBOL(bt_pad_enable); static const struct snd_pcm_hardware acp_pcm_hardware_playback = { .info = SNDRV_PCM_INFO_INTERLEAVED | @@ -525,6 +527,13 @@ static int acp_init(void __iomem *acp_mmio, u32 asic_type) val &= ~ACP_SOFT_RESET__SoftResetAud_MASK; acp_reg_write(val, acp_mmio, mmACP_SOFT_RESET); + /* For BT instance change pins from UART to BT */ + if (bt_pad_enable) { + val = acp_reg_read(acp_mmio, mmACP_BT_UART_PAD_SEL); + val |= ACP_BT_UART_PAD_SELECT_MASK; + acp_reg_write(val, acp_mmio, mmACP_BT_UART_PAD_SEL); + } + /* initiailize Onion control DAGB register */ acp_reg_write(ACP_ONION_CNTL_DEFAULT, acp_mmio, mmACP_AXI2DAGB_ONION_CNTL); diff --git a/sound/soc/amd/acp.h b/sound/soc/amd/acp.h index 460365c..6b43144 100644 --- a/sound/soc/amd/acp.h +++ b/sound/soc/amd/acp.h @@ -107,6 +107,7 @@ #define ACP_I2S_MIC_16BIT_RESOLUTION_EN 0x01 #define ACP_I2S_SP_16BIT_RESOLUTION_EN 0x02 #define ACP_I2S_BT_16BIT_RESOLUTION_EN 0x04 +#define ACP_BT_UART_PAD_SELECT_MASK0x1 enum acp_dma_priority_level { /* 0x0 Specifies the DMA channel is given normal priority */ -- 2.7.4
[PATCH 4/4] ASoC: amd: enabling bt i2s config after acp reset
On ST/CZ based platforms, for specific platform bt uart mux to be defined for bt i2s. By default, these pins will be used for uart. After acp reset , it requires to reprogram bt i2s config mux pins to enable bt i2s instance. added bt i2s enablement sequence during acp init. Signed-off-by: Vijendar Mukunda Signed-off-by: Akshu Agrawal --- sound/soc/amd/acp-da7219-max98357a.c | 2 ++ sound/soc/amd/acp-pcm-dma.c | 9 + sound/soc/amd/acp.h | 1 + 3 files changed, 12 insertions(+) diff --git a/sound/soc/amd/acp-da7219-max98357a.c b/sound/soc/amd/acp-da7219-max98357a.c index b205c78..6dad0cb 100644 --- a/sound/soc/amd/acp-da7219-max98357a.c +++ b/sound/soc/amd/acp-da7219-max98357a.c @@ -44,6 +44,7 @@ static struct snd_soc_jack cz_jack; struct clk *da7219_dai_clk; +extern int bt_pad_enable; static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd) { @@ -81,6 +82,7 @@ static int cz_da7219_init(struct snd_soc_pcm_runtime *rtd) } da7219_aad_jack_det(component, _jack); + bt_pad_enable = device_property_read_bool(>dev, "bt-pad-enable"); return 0; } diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index 7c392fe..b52c660 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -46,6 +46,8 @@ #define DRV_NAME "acp_audio_dma" +bool bt_pad_enable = false; +EXPORT_SYMBOL(bt_pad_enable); static const struct snd_pcm_hardware acp_pcm_hardware_playback = { .info = SNDRV_PCM_INFO_INTERLEAVED | @@ -525,6 +527,13 @@ static int acp_init(void __iomem *acp_mmio, u32 asic_type) val &= ~ACP_SOFT_RESET__SoftResetAud_MASK; acp_reg_write(val, acp_mmio, mmACP_SOFT_RESET); + /* For BT instance change pins from UART to BT */ + if (bt_pad_enable) { + val = acp_reg_read(acp_mmio, mmACP_BT_UART_PAD_SEL); + val |= ACP_BT_UART_PAD_SELECT_MASK; + acp_reg_write(val, acp_mmio, mmACP_BT_UART_PAD_SEL); + } + /* initiailize Onion control DAGB register */ acp_reg_write(ACP_ONION_CNTL_DEFAULT, acp_mmio, mmACP_AXI2DAGB_ONION_CNTL); diff --git a/sound/soc/amd/acp.h b/sound/soc/amd/acp.h index 460365c..6b43144 100644 --- a/sound/soc/amd/acp.h +++ b/sound/soc/amd/acp.h @@ -107,6 +107,7 @@ #define ACP_I2S_MIC_16BIT_RESOLUTION_EN 0x01 #define ACP_I2S_SP_16BIT_RESOLUTION_EN 0x02 #define ACP_I2S_BT_16BIT_RESOLUTION_EN 0x04 +#define ACP_BT_UART_PAD_SELECT_MASK0x1 enum acp_dma_priority_level { /* 0x0 Specifies the DMA channel is given normal priority */ -- 2.7.4
[PATCH 2/4] ASoC: amd: fixed checkpatch pl warnings
fixed checkpatch pl warnings. Signed-off-by: Vijendar Mukunda--- sound/soc/amd/acp-pcm-dma.c | 259 sound/soc/amd/acp.h | 22 ++-- 2 files changed, 153 insertions(+), 128 deletions(-) diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index 540088d..5ffe2ef 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -130,7 +130,8 @@ static void acp_reg_write(u32 val, void __iomem *acp_mmio, u32 reg) writel(val, acp_mmio + (reg * 4)); } -/* Configure a given dma channel parameters - enable/disable, +/* + * Configure a given dma channel parameters - enable/disable, * number of descriptors, priority */ static void config_acp_dma_channel(void __iomem *acp_mmio, u8 ch_num, @@ -149,11 +150,12 @@ static void config_acp_dma_channel(void __iomem *acp_mmio, u8 ch_num, & dscr_strt_idx), acp_mmio, mmACP_DMA_DSCR_STRT_IDX_0 + ch_num); - /* program a DMA channel with the number of descriptors to be + /* +* program a DMA channel with the number of descriptors to be * processed in the transfer - */ +*/ acp_reg_write(ACP_DMA_DSCR_CNT_0__DMAChDscrCnt_MASK & num_dscrs, - acp_mmio, mmACP_DMA_DSCR_CNT_0 + ch_num); + acp_mmio, mmACP_DMA_DSCR_CNT_0 + ch_num); /* set DMA channel priority */ acp_reg_write(priority_level, acp_mmio, mmACP_DMA_PRIO_0 + ch_num); @@ -180,13 +182,15 @@ static void config_dma_descriptor_in_sram(void __iomem *acp_mmio, acp_reg_write(descr_info->xfer_val, acp_mmio, mmACP_SRBM_Targ_Idx_Data); } -/* Initialize the DMA descriptor information for transfer between +/* + * Initialize the DMA descriptor information for transfer between * system memory <-> ACP SRAM */ static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio, - u32 size, int direction, u32 pte_offset, - u16 ch, u32 sram_bank, - u16 dma_dscr_idx, u32 asic_type) + u32 size, int direction, + u32 pte_offset, u16 ch, + u32 sram_bank, u16 dma_dscr_idx, + u32 asic_type) { u16 i; acp_dma_dscr_transfer_t dmadscr[NUM_DSCRS_PER_CHANNEL]; @@ -195,58 +199,58 @@ static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio, dmadscr[i].xfer_val = 0; if (direction == SNDRV_PCM_STREAM_PLAYBACK) { dma_dscr_idx = dma_dscr_idx + i; - dmadscr[i].dest = sram_bank + (i * (size/2)); + dmadscr[i].dest = sram_bank + (i * (size / 2)); dmadscr[i].src = ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS - + (pte_offset * SZ_4K) + (i * (size/2)); + + (pte_offset * SZ_4K) + (i * (size / 2)); switch (asic_type) { case CHIP_STONEY: dmadscr[i].xfer_val |= - (ACP_DMA_ATTRIBUTES_DAGB_GARLIC_TO_SHAREDMEM << 16) | + (ACP_DMA_ATTR_DAGB_GARLIC_TO_SHAREDMEM << 16) | (size / 2); break; default: dmadscr[i].xfer_val |= - (ACP_DMA_ATTRIBUTES_DAGB_ONION_TO_SHAREDMEM << 16) | + (ACP_DMA_ATTR_DAGB_ONION_TO_SHAREDMEM << 16) | (size / 2); } } else { dma_dscr_idx = dma_dscr_idx + i; - dmadscr[i].src = sram_bank + (i * (size/2)); + dmadscr[i].src = sram_bank + (i * (size / 2)); dmadscr[i].dest = ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS + - (pte_offset * SZ_4K) + (i * (size/2)); + (pte_offset * SZ_4K) + (i * (size / 2)); switch (asic_type) { case CHIP_STONEY: dmadscr[i].xfer_val |= BIT(22) | - (ACP_DMA_ATTRIBUTES_SHARED_MEM_TO_DAGB_GARLIC << 16) | + (ACP_DMA_ATTR_SHARED_MEM_TO_DAGB_GARLIC << 16) | (size / 2); break; default: dmadscr[i].xfer_val |= BIT(22) | - (ACP_DMA_ATTRIBUTES_SHAREDMEM_TO_DAGB_ONION << 16) | +
[PATCH 2/4] ASoC: amd: fixed checkpatch pl warnings
fixed checkpatch pl warnings. Signed-off-by: Vijendar Mukunda --- sound/soc/amd/acp-pcm-dma.c | 259 sound/soc/amd/acp.h | 22 ++-- 2 files changed, 153 insertions(+), 128 deletions(-) diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index 540088d..5ffe2ef 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -130,7 +130,8 @@ static void acp_reg_write(u32 val, void __iomem *acp_mmio, u32 reg) writel(val, acp_mmio + (reg * 4)); } -/* Configure a given dma channel parameters - enable/disable, +/* + * Configure a given dma channel parameters - enable/disable, * number of descriptors, priority */ static void config_acp_dma_channel(void __iomem *acp_mmio, u8 ch_num, @@ -149,11 +150,12 @@ static void config_acp_dma_channel(void __iomem *acp_mmio, u8 ch_num, & dscr_strt_idx), acp_mmio, mmACP_DMA_DSCR_STRT_IDX_0 + ch_num); - /* program a DMA channel with the number of descriptors to be + /* +* program a DMA channel with the number of descriptors to be * processed in the transfer - */ +*/ acp_reg_write(ACP_DMA_DSCR_CNT_0__DMAChDscrCnt_MASK & num_dscrs, - acp_mmio, mmACP_DMA_DSCR_CNT_0 + ch_num); + acp_mmio, mmACP_DMA_DSCR_CNT_0 + ch_num); /* set DMA channel priority */ acp_reg_write(priority_level, acp_mmio, mmACP_DMA_PRIO_0 + ch_num); @@ -180,13 +182,15 @@ static void config_dma_descriptor_in_sram(void __iomem *acp_mmio, acp_reg_write(descr_info->xfer_val, acp_mmio, mmACP_SRBM_Targ_Idx_Data); } -/* Initialize the DMA descriptor information for transfer between +/* + * Initialize the DMA descriptor information for transfer between * system memory <-> ACP SRAM */ static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio, - u32 size, int direction, u32 pte_offset, - u16 ch, u32 sram_bank, - u16 dma_dscr_idx, u32 asic_type) + u32 size, int direction, + u32 pte_offset, u16 ch, + u32 sram_bank, u16 dma_dscr_idx, + u32 asic_type) { u16 i; acp_dma_dscr_transfer_t dmadscr[NUM_DSCRS_PER_CHANNEL]; @@ -195,58 +199,58 @@ static void set_acp_sysmem_dma_descriptors(void __iomem *acp_mmio, dmadscr[i].xfer_val = 0; if (direction == SNDRV_PCM_STREAM_PLAYBACK) { dma_dscr_idx = dma_dscr_idx + i; - dmadscr[i].dest = sram_bank + (i * (size/2)); + dmadscr[i].dest = sram_bank + (i * (size / 2)); dmadscr[i].src = ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS - + (pte_offset * SZ_4K) + (i * (size/2)); + + (pte_offset * SZ_4K) + (i * (size / 2)); switch (asic_type) { case CHIP_STONEY: dmadscr[i].xfer_val |= - (ACP_DMA_ATTRIBUTES_DAGB_GARLIC_TO_SHAREDMEM << 16) | + (ACP_DMA_ATTR_DAGB_GARLIC_TO_SHAREDMEM << 16) | (size / 2); break; default: dmadscr[i].xfer_val |= - (ACP_DMA_ATTRIBUTES_DAGB_ONION_TO_SHAREDMEM << 16) | + (ACP_DMA_ATTR_DAGB_ONION_TO_SHAREDMEM << 16) | (size / 2); } } else { dma_dscr_idx = dma_dscr_idx + i; - dmadscr[i].src = sram_bank + (i * (size/2)); + dmadscr[i].src = sram_bank + (i * (size / 2)); dmadscr[i].dest = ACP_INTERNAL_APERTURE_WINDOW_0_ADDRESS + - (pte_offset * SZ_4K) + (i * (size/2)); + (pte_offset * SZ_4K) + (i * (size / 2)); switch (asic_type) { case CHIP_STONEY: dmadscr[i].xfer_val |= BIT(22) | - (ACP_DMA_ATTRIBUTES_SHARED_MEM_TO_DAGB_GARLIC << 16) | + (ACP_DMA_ATTR_SHARED_MEM_TO_DAGB_GARLIC << 16) | (size / 2); break; default: dmadscr[i].xfer_val |= BIT(22) | - (ACP_DMA_ATTRIBUTES_SHAREDMEM_TO_DAGB_ONION << 16) | +
[PATCH 3/4] ASoC: amd: dma driver changes for BT I2S instance
With in ACP, There are three I2S controllers can be configured/enabled ( I2S SP, I2S MICSP, I2S BT). Default enabled I2S controller instance is I2S SP. This patch provides required changes to support I2S BT controller Instance. Signed-off-by: Vijendar Mukunda--- sound/soc/amd/Kconfig | 1 + sound/soc/amd/acp-pcm-dma.c | 388 +++- sound/soc/amd/acp.h | 64 +++- 3 files changed, 295 insertions(+), 158 deletions(-) diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig index 6cbf9cf..6b7c620 100644 --- a/sound/soc/amd/Kconfig +++ b/sound/soc/amd/Kconfig @@ -1,5 +1,6 @@ config SND_SOC_AMD_ACP tristate "AMD Audio Coprocessor support" + select SND_DESIGNWARE_PCM help This option enables ACP DMA support on AMD platform. diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index 5ffe2ef..7c392fe 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -23,6 +23,8 @@ #include #include "acp.h" +#include "../dwc/local.h" + #define DRV_NAME "acp_audio_dma" #define PLAYBACK_MIN_NUM_PERIODS2 @@ -37,13 +39,14 @@ #define MAX_BUFFER (PLAYBACK_MAX_PERIOD_SIZE * PLAYBACK_MAX_NUM_PERIODS) #define MIN_BUFFER MAX_BUFFER -#define ST_PLAYBACK_MAX_PERIOD_SIZE 8192 +#define ST_PLAYBACK_MAX_PERIOD_SIZE 4096 #define ST_CAPTURE_MAX_PERIOD_SIZE ST_PLAYBACK_MAX_PERIOD_SIZE #define ST_MAX_BUFFER (ST_PLAYBACK_MAX_PERIOD_SIZE * PLAYBACK_MAX_NUM_PERIODS) #define ST_MIN_BUFFER ST_MAX_BUFFER #define DRV_NAME "acp_audio_dma" + static const struct snd_pcm_hardware acp_pcm_hardware_playback = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | @@ -317,54 +320,21 @@ static void acp_pte_config(void __iomem *acp_mmio, struct page *pg, } static void config_acp_dma(void __iomem *acp_mmio, - struct audio_substream_data *audio_config, + struct audio_substream_data *rtd, u32 asic_type) { - u32 pte_offset, sram_bank; - u16 ch1, ch2, destination, dma_dscr_idx; - - if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK) { - pte_offset = ACP_PLAYBACK_PTE_OFFSET; - ch1 = SYSRAM_TO_ACP_CH_NUM; - ch2 = ACP_TO_I2S_DMA_CH_NUM; - sram_bank = ACP_SHARED_RAM_BANK_1_ADDRESS; - destination = TO_ACP_I2S_1; - - } else { - pte_offset = ACP_CAPTURE_PTE_OFFSET; - ch1 = SYSRAM_TO_ACP_CH_NUM; - ch2 = ACP_TO_I2S_DMA_CH_NUM; - switch (asic_type) { - case CHIP_STONEY: - sram_bank = ACP_SHARED_RAM_BANK_3_ADDRESS; - break; - default: - sram_bank = ACP_SHARED_RAM_BANK_5_ADDRESS; - } - destination = FROM_ACP_I2S_1; - } - - acp_pte_config(acp_mmio, audio_config->pg, audio_config->num_of_pages, - pte_offset); - if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK) - dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH12; - else - dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH14; - + acp_pte_config(acp_mmio, rtd->pg, rtd->num_of_pages, + rtd->pte_offset); /* Configure System memory <-> ACP SRAM DMA descriptors */ - set_acp_sysmem_dma_descriptors(acp_mmio, audio_config->size, - audio_config->direction, pte_offset, ch1, - sram_bank, dma_dscr_idx, asic_type); - - if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK) - dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH13; - else - dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH15; + set_acp_sysmem_dma_descriptors(acp_mmio, rtd->size, + rtd->direction, rtd->pte_offset, + rtd->ch1, rtd->sram_bank, + rtd->dma_dscr_idx_1, asic_type); /* Configure ACP SRAM <-> I2S DMA descriptors */ - set_acp_to_i2s_dma_descriptors(acp_mmio, audio_config->size, - audio_config->direction, sram_bank, - destination, ch2, dma_dscr_idx, - asic_type); + set_acp_to_i2s_dma_descriptors(acp_mmio, rtd->size, + rtd->direction, rtd->sram_bank, + rtd->destination, rtd->ch2, + rtd->dma_dscr_idx_2, asic_type); } /* Start a given DMA channel transfer */ @@ -390,6 +360,9 @@ static void acp_dma_start(void __iomem *acp_mmio, case ACP_TO_I2S_DMA_CH_NUM: case ACP_TO_SYSRAM_CH_NUM: case
[PATCH 3/4] ASoC: amd: dma driver changes for BT I2S instance
With in ACP, There are three I2S controllers can be configured/enabled ( I2S SP, I2S MICSP, I2S BT). Default enabled I2S controller instance is I2S SP. This patch provides required changes to support I2S BT controller Instance. Signed-off-by: Vijendar Mukunda --- sound/soc/amd/Kconfig | 1 + sound/soc/amd/acp-pcm-dma.c | 388 +++- sound/soc/amd/acp.h | 64 +++- 3 files changed, 295 insertions(+), 158 deletions(-) diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig index 6cbf9cf..6b7c620 100644 --- a/sound/soc/amd/Kconfig +++ b/sound/soc/amd/Kconfig @@ -1,5 +1,6 @@ config SND_SOC_AMD_ACP tristate "AMD Audio Coprocessor support" + select SND_DESIGNWARE_PCM help This option enables ACP DMA support on AMD platform. diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index 5ffe2ef..7c392fe 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -23,6 +23,8 @@ #include #include "acp.h" +#include "../dwc/local.h" + #define DRV_NAME "acp_audio_dma" #define PLAYBACK_MIN_NUM_PERIODS2 @@ -37,13 +39,14 @@ #define MAX_BUFFER (PLAYBACK_MAX_PERIOD_SIZE * PLAYBACK_MAX_NUM_PERIODS) #define MIN_BUFFER MAX_BUFFER -#define ST_PLAYBACK_MAX_PERIOD_SIZE 8192 +#define ST_PLAYBACK_MAX_PERIOD_SIZE 4096 #define ST_CAPTURE_MAX_PERIOD_SIZE ST_PLAYBACK_MAX_PERIOD_SIZE #define ST_MAX_BUFFER (ST_PLAYBACK_MAX_PERIOD_SIZE * PLAYBACK_MAX_NUM_PERIODS) #define ST_MIN_BUFFER ST_MAX_BUFFER #define DRV_NAME "acp_audio_dma" + static const struct snd_pcm_hardware acp_pcm_hardware_playback = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | @@ -317,54 +320,21 @@ static void acp_pte_config(void __iomem *acp_mmio, struct page *pg, } static void config_acp_dma(void __iomem *acp_mmio, - struct audio_substream_data *audio_config, + struct audio_substream_data *rtd, u32 asic_type) { - u32 pte_offset, sram_bank; - u16 ch1, ch2, destination, dma_dscr_idx; - - if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK) { - pte_offset = ACP_PLAYBACK_PTE_OFFSET; - ch1 = SYSRAM_TO_ACP_CH_NUM; - ch2 = ACP_TO_I2S_DMA_CH_NUM; - sram_bank = ACP_SHARED_RAM_BANK_1_ADDRESS; - destination = TO_ACP_I2S_1; - - } else { - pte_offset = ACP_CAPTURE_PTE_OFFSET; - ch1 = SYSRAM_TO_ACP_CH_NUM; - ch2 = ACP_TO_I2S_DMA_CH_NUM; - switch (asic_type) { - case CHIP_STONEY: - sram_bank = ACP_SHARED_RAM_BANK_3_ADDRESS; - break; - default: - sram_bank = ACP_SHARED_RAM_BANK_5_ADDRESS; - } - destination = FROM_ACP_I2S_1; - } - - acp_pte_config(acp_mmio, audio_config->pg, audio_config->num_of_pages, - pte_offset); - if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK) - dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH12; - else - dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH14; - + acp_pte_config(acp_mmio, rtd->pg, rtd->num_of_pages, + rtd->pte_offset); /* Configure System memory <-> ACP SRAM DMA descriptors */ - set_acp_sysmem_dma_descriptors(acp_mmio, audio_config->size, - audio_config->direction, pte_offset, ch1, - sram_bank, dma_dscr_idx, asic_type); - - if (audio_config->direction == SNDRV_PCM_STREAM_PLAYBACK) - dma_dscr_idx = PLAYBACK_START_DMA_DESCR_CH13; - else - dma_dscr_idx = CAPTURE_START_DMA_DESCR_CH15; + set_acp_sysmem_dma_descriptors(acp_mmio, rtd->size, + rtd->direction, rtd->pte_offset, + rtd->ch1, rtd->sram_bank, + rtd->dma_dscr_idx_1, asic_type); /* Configure ACP SRAM <-> I2S DMA descriptors */ - set_acp_to_i2s_dma_descriptors(acp_mmio, audio_config->size, - audio_config->direction, sram_bank, - destination, ch2, dma_dscr_idx, - asic_type); + set_acp_to_i2s_dma_descriptors(acp_mmio, rtd->size, + rtd->direction, rtd->sram_bank, + rtd->destination, rtd->ch2, + rtd->dma_dscr_idx_2, asic_type); } /* Start a given DMA channel transfer */ @@ -390,6 +360,9 @@ static void acp_dma_start(void __iomem *acp_mmio, case ACP_TO_I2S_DMA_CH_NUM: case ACP_TO_SYSRAM_CH_NUM: case I2S_TO_ACP_DMA_CH_NUM: +
[PATCH 1/4] ASoC: dwc: I2S Controller instance param added
When multiple I2S controller instances created, i2s_instance parameter refers to i2s controller instance value. Signed-off-by: Vijendar MukundaReviewed-by: Alex Deucher --- include/sound/designware_i2s.h | 6 ++ sound/soc/dwc/dwc-i2s.c| 1 + sound/soc/dwc/local.h | 1 + 3 files changed, 8 insertions(+) diff --git a/include/sound/designware_i2s.h b/include/sound/designware_i2s.h index 830f5ca..8113759 100644 --- a/include/sound/designware_i2s.h +++ b/include/sound/designware_i2s.h @@ -44,6 +44,10 @@ struct i2s_platform_data { int channel; u32 snd_fmts; u32 snd_rates; + /* i2s_instance parameter returns I2S controller instance value +* when multiple I2S controllers instantiated +*/ + u32 i2s_instance; #define DW_I2S_QUIRK_COMP_REG_OFFSET(1 << 0) #define DW_I2S_QUIRK_COMP_PARAM1(1 << 1) @@ -74,5 +78,7 @@ struct i2s_dma_data { #define FOUR_CHANNEL_SUPPORT 4 /* up to 3.1 */ #define SIX_CHANNEL_SUPPORT6 /* up to 5.1 */ #define EIGHT_CHANNEL_SUPPORT 8 /* up to 7.1 */ +#define I2S_SP_INSTANCE1 +#define I2S_BT_INSTANCE2 #endif /* __SOUND_DESIGNWARE_I2S_H */ diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c index 65112b9..58f81a4 100644 --- a/sound/soc/dwc/dwc-i2s.c +++ b/sound/soc/dwc/dwc-i2s.c @@ -553,6 +553,7 @@ static int dw_configure_dai_by_pd(struct dw_i2s_dev *dev, if (dev->quirks & DW_I2S_QUIRK_16BIT_IDX_OVERRIDE) idx = 1; + dev->i2s_instance = pdata->i2s_instance; /* Set DMA slaves info */ dev->play_dma_data.pd.data = pdata->play_dma_data; dev->capture_dma_data.pd.data = pdata->capture_dma_data; diff --git a/sound/soc/dwc/local.h b/sound/soc/dwc/local.h index 91dc70a..e89e464 100644 --- a/sound/soc/dwc/local.h +++ b/sound/soc/dwc/local.h @@ -98,6 +98,7 @@ struct dw_i2s_dev { u32 ccr; u32 xfer_resolution; u32 fifo_th; + u32 i2s_instance; /* data related to DMA transfers b/w i2s and DMAC */ union dw_i2s_snd_dma_data play_dma_data; -- 2.7.4
[PATCH 1/4] ASoC: dwc: I2S Controller instance param added
When multiple I2S controller instances created, i2s_instance parameter refers to i2s controller instance value. Signed-off-by: Vijendar Mukunda Reviewed-by: Alex Deucher --- include/sound/designware_i2s.h | 6 ++ sound/soc/dwc/dwc-i2s.c| 1 + sound/soc/dwc/local.h | 1 + 3 files changed, 8 insertions(+) diff --git a/include/sound/designware_i2s.h b/include/sound/designware_i2s.h index 830f5ca..8113759 100644 --- a/include/sound/designware_i2s.h +++ b/include/sound/designware_i2s.h @@ -44,6 +44,10 @@ struct i2s_platform_data { int channel; u32 snd_fmts; u32 snd_rates; + /* i2s_instance parameter returns I2S controller instance value +* when multiple I2S controllers instantiated +*/ + u32 i2s_instance; #define DW_I2S_QUIRK_COMP_REG_OFFSET(1 << 0) #define DW_I2S_QUIRK_COMP_PARAM1(1 << 1) @@ -74,5 +78,7 @@ struct i2s_dma_data { #define FOUR_CHANNEL_SUPPORT 4 /* up to 3.1 */ #define SIX_CHANNEL_SUPPORT6 /* up to 5.1 */ #define EIGHT_CHANNEL_SUPPORT 8 /* up to 7.1 */ +#define I2S_SP_INSTANCE1 +#define I2S_BT_INSTANCE2 #endif /* __SOUND_DESIGNWARE_I2S_H */ diff --git a/sound/soc/dwc/dwc-i2s.c b/sound/soc/dwc/dwc-i2s.c index 65112b9..58f81a4 100644 --- a/sound/soc/dwc/dwc-i2s.c +++ b/sound/soc/dwc/dwc-i2s.c @@ -553,6 +553,7 @@ static int dw_configure_dai_by_pd(struct dw_i2s_dev *dev, if (dev->quirks & DW_I2S_QUIRK_16BIT_IDX_OVERRIDE) idx = 1; + dev->i2s_instance = pdata->i2s_instance; /* Set DMA slaves info */ dev->play_dma_data.pd.data = pdata->play_dma_data; dev->capture_dma_data.pd.data = pdata->capture_dma_data; diff --git a/sound/soc/dwc/local.h b/sound/soc/dwc/local.h index 91dc70a..e89e464 100644 --- a/sound/soc/dwc/local.h +++ b/sound/soc/dwc/local.h @@ -98,6 +98,7 @@ struct dw_i2s_dev { u32 ccr; u32 xfer_resolution; u32 fifo_th; + u32 i2s_instance; /* data related to DMA transfers b/w i2s and DMAC */ union dw_i2s_snd_dma_data play_dma_data; -- 2.7.4
Re: [PATCH 2/2] parisc: use the asm-generic version for readX()
Hi Sinan, Thank you for the patch! Yet something to improve: [auto build test ERROR on hp-parisc/for-next] [also build test ERROR on v4.17-rc1 next-20180416] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Sinan-Kaya/parisc-use-the-asm-generic-version-for-writeX/20180417-103119 base: https://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux.git for-next config: parisc-c3000_defconfig (attached as .config) compiler: hppa-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=parisc All errors (new ones prefixed by >>): In file included from arch/parisc/include/asm/hardirq.h:13:0, from include/linux/hardirq.h:9, from arch/parisc/kernel/asm-offsets.c:34: include/linux/irq.h: In function 'irq_reg_writel': include/linux/irq.h:1126:3: error: implicit declaration of function 'writel'; did you mean 'iowrite8'? [-Werror=implicit-function-declaration] writel(val, gc->reg_base + reg_offset); ^~ iowrite8 include/linux/irq.h: In function 'irq_reg_readl': >> include/linux/irq.h:1135:10: error: implicit declaration of function >> 'readl'; did you mean 'ioread8'? [-Werror=implicit-function-declaration] return readl(gc->reg_base + reg_offset); ^ ioread8 cc1: some warnings being treated as errors make[2]: *** [arch/parisc/kernel/asm-offsets.s] Error 1 make[2]: Target '__build' not remade because of errors. make[1]: *** [prepare0] Error 2 make[1]: Target 'prepare' not remade because of errors. make: *** [sub-make] Error 2 vim +1135 include/linux/irq.h 7d828062 Thomas Gleixner 2011-04-03 1109 ebf9ff75 Boris Brezillon 2016-09-13 1110 /* ebf9ff75 Boris Brezillon 2016-09-13 * The irqsave variants are for usage in non interrupt code. Do not use ebf9ff75 Boris Brezillon 2016-09-13 1112 * them in irq_chip callbacks. Use irq_gc_lock() instead. ebf9ff75 Boris Brezillon 2016-09-13 1113 */ ebf9ff75 Boris Brezillon 2016-09-13 1114 #define irq_gc_lock_irqsave(gc, flags) \ ebf9ff75 Boris Brezillon 2016-09-13 1115 raw_spin_lock_irqsave(&(gc)->lock, flags) ebf9ff75 Boris Brezillon 2016-09-13 1116 ebf9ff75 Boris Brezillon 2016-09-13 1117 #define irq_gc_unlock_irqrestore(gc, flags) \ ebf9ff75 Boris Brezillon 2016-09-13 1118 raw_spin_unlock_irqrestore(&(gc)->lock, flags) ebf9ff75 Boris Brezillon 2016-09-13 1119 332fd7c4 Kevin Cernekee 2014-11-06 1120 static inline void irq_reg_writel(struct irq_chip_generic *gc, 332fd7c4 Kevin Cernekee 2014-11-06 1121 u32 val, int reg_offset) 332fd7c4 Kevin Cernekee 2014-11-06 1122 { 2b280376 Kevin Cernekee 2014-11-06 1123 if (gc->reg_writel) 2b280376 Kevin Cernekee 2014-11-06 1124 gc->reg_writel(val, gc->reg_base + reg_offset); 2b280376 Kevin Cernekee 2014-11-06 1125 else 332fd7c4 Kevin Cernekee 2014-11-06 @1126 writel(val, gc->reg_base + reg_offset); 332fd7c4 Kevin Cernekee 2014-11-06 1127 } 332fd7c4 Kevin Cernekee 2014-11-06 1128 332fd7c4 Kevin Cernekee 2014-11-06 1129 static inline u32 irq_reg_readl(struct irq_chip_generic *gc, 332fd7c4 Kevin Cernekee 2014-11-06 1130 int reg_offset) 332fd7c4 Kevin Cernekee 2014-11-06 1131 { 2b280376 Kevin Cernekee 2014-11-06 1132 if (gc->reg_readl) 2b280376 Kevin Cernekee 2014-11-06 1133 return gc->reg_readl(gc->reg_base + reg_offset); 2b280376 Kevin Cernekee 2014-11-06 1134 else 332fd7c4 Kevin Cernekee 2014-11-06 @1135 return readl(gc->reg_base + reg_offset); 332fd7c4 Kevin Cernekee 2014-11-06 1136 } 332fd7c4 Kevin Cernekee 2014-11-06 1137 :: The code at line 1135 was first introduced by commit :: 332fd7c4fef5f3b166e93decb07fd69eb24f7998 genirq: Generic chip: Change irq_reg_{readl,writel} arguments :: TO: Kevin Cernekee <cerne...@gmail.com> :: CC: Jason Cooper <ja...@lakedaemon.net> --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH 2/2] parisc: use the asm-generic version for readX()
Hi Sinan, Thank you for the patch! Yet something to improve: [auto build test ERROR on hp-parisc/for-next] [also build test ERROR on v4.17-rc1 next-20180416] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Sinan-Kaya/parisc-use-the-asm-generic-version-for-writeX/20180417-103119 base: https://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux.git for-next config: parisc-c3000_defconfig (attached as .config) compiler: hppa-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=parisc All errors (new ones prefixed by >>): In file included from arch/parisc/include/asm/hardirq.h:13:0, from include/linux/hardirq.h:9, from arch/parisc/kernel/asm-offsets.c:34: include/linux/irq.h: In function 'irq_reg_writel': include/linux/irq.h:1126:3: error: implicit declaration of function 'writel'; did you mean 'iowrite8'? [-Werror=implicit-function-declaration] writel(val, gc->reg_base + reg_offset); ^~ iowrite8 include/linux/irq.h: In function 'irq_reg_readl': >> include/linux/irq.h:1135:10: error: implicit declaration of function >> 'readl'; did you mean 'ioread8'? [-Werror=implicit-function-declaration] return readl(gc->reg_base + reg_offset); ^ ioread8 cc1: some warnings being treated as errors make[2]: *** [arch/parisc/kernel/asm-offsets.s] Error 1 make[2]: Target '__build' not remade because of errors. make[1]: *** [prepare0] Error 2 make[1]: Target 'prepare' not remade because of errors. make: *** [sub-make] Error 2 vim +1135 include/linux/irq.h 7d828062 Thomas Gleixner 2011-04-03 1109 ebf9ff75 Boris Brezillon 2016-09-13 1110 /* ebf9ff75 Boris Brezillon 2016-09-13 * The irqsave variants are for usage in non interrupt code. Do not use ebf9ff75 Boris Brezillon 2016-09-13 1112 * them in irq_chip callbacks. Use irq_gc_lock() instead. ebf9ff75 Boris Brezillon 2016-09-13 1113 */ ebf9ff75 Boris Brezillon 2016-09-13 1114 #define irq_gc_lock_irqsave(gc, flags) \ ebf9ff75 Boris Brezillon 2016-09-13 1115 raw_spin_lock_irqsave(&(gc)->lock, flags) ebf9ff75 Boris Brezillon 2016-09-13 1116 ebf9ff75 Boris Brezillon 2016-09-13 1117 #define irq_gc_unlock_irqrestore(gc, flags) \ ebf9ff75 Boris Brezillon 2016-09-13 1118 raw_spin_unlock_irqrestore(&(gc)->lock, flags) ebf9ff75 Boris Brezillon 2016-09-13 1119 332fd7c4 Kevin Cernekee 2014-11-06 1120 static inline void irq_reg_writel(struct irq_chip_generic *gc, 332fd7c4 Kevin Cernekee 2014-11-06 1121 u32 val, int reg_offset) 332fd7c4 Kevin Cernekee 2014-11-06 1122 { 2b280376 Kevin Cernekee 2014-11-06 1123 if (gc->reg_writel) 2b280376 Kevin Cernekee 2014-11-06 1124 gc->reg_writel(val, gc->reg_base + reg_offset); 2b280376 Kevin Cernekee 2014-11-06 1125 else 332fd7c4 Kevin Cernekee 2014-11-06 @1126 writel(val, gc->reg_base + reg_offset); 332fd7c4 Kevin Cernekee 2014-11-06 1127 } 332fd7c4 Kevin Cernekee 2014-11-06 1128 332fd7c4 Kevin Cernekee 2014-11-06 1129 static inline u32 irq_reg_readl(struct irq_chip_generic *gc, 332fd7c4 Kevin Cernekee 2014-11-06 1130 int reg_offset) 332fd7c4 Kevin Cernekee 2014-11-06 1131 { 2b280376 Kevin Cernekee 2014-11-06 1132 if (gc->reg_readl) 2b280376 Kevin Cernekee 2014-11-06 1133 return gc->reg_readl(gc->reg_base + reg_offset); 2b280376 Kevin Cernekee 2014-11-06 1134 else 332fd7c4 Kevin Cernekee 2014-11-06 @1135 return readl(gc->reg_base + reg_offset); 332fd7c4 Kevin Cernekee 2014-11-06 1136 } 332fd7c4 Kevin Cernekee 2014-11-06 1137 :: The code at line 1135 was first introduced by commit :: 332fd7c4fef5f3b166e93decb07fd69eb24f7998 genirq: Generic chip: Change irq_reg_{readl,writel} arguments :: TO: Kevin Cernekee :: CC: Jason Cooper --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH] blk-mq: start request gstate with gen 1
On Tue, Apr 17, 2018 at 11:46:20AM +0800, Jianchao Wang wrote: > rq->gstate and rq->aborted_gstate both are zero before rqs are > allocated. If we have a small timeout, when the timer fires, > there could be rqs that are never allocated, and also there could > be rq that has been allocated but not initialized and started. At > the moment, the rq->gstate and rq->aborted_gstate both are 0, thus > the blk_mq_terminate_expired will identify the rq is timed out and > invoke .timeout early. > > For scsi, this will cause scsi_times_out to be invoked before the > scsi_cmnd is not initialized, scsi_cmnd->device is still NULL at > the moment, then we will get crash. > > Cc: Bart Van Assche> Cc: Tejun Heo > Cc: Ming Lei > Cc: Martin Steigerwald > Cc: sta...@vger.kernel.org > Signed-off-by: Jianchao Wang > --- > block/blk-core.c | 4 > block/blk-mq.c | 7 +++ > 2 files changed, 11 insertions(+) > > diff --git a/block/blk-core.c b/block/blk-core.c > index abcb868..ce62681 100644 > --- a/block/blk-core.c > +++ b/block/blk-core.c > @@ -201,6 +201,10 @@ void blk_rq_init(struct request_queue *q, struct request > *rq) > rq->part = NULL; > seqcount_init(>gstate_seq); > u64_stats_init(>aborted_gstate_sync); > + /* > + * See comment of blk_mq_init_request > + */ > + WRITE_ONCE(rq->gstate, MQ_RQ_GEN_INC); > } > EXPORT_SYMBOL(blk_rq_init); > > diff --git a/block/blk-mq.c b/block/blk-mq.c > index f5c7dbc..d62030a 100644 > --- a/block/blk-mq.c > +++ b/block/blk-mq.c > @@ -2069,6 +2069,13 @@ static int blk_mq_init_request(struct blk_mq_tag_set > *set, struct request *rq, > > seqcount_init(>gstate_seq); > u64_stats_init(>aborted_gstate_sync); > + /* > + * start gstate with gen 1 instead of 0, otherwise it will be equal > + * to aborted_gstate, and be identified timed out by > + * blk_mq_terminate_expired. > + */ > + WRITE_ONCE(rq->gstate, MQ_RQ_GEN_INC); > + > return 0; > } Good catch, blk_mq_check_expired() is bypassed, but it is still hit by blk_mq_terminate_expired(). Reviewed-by: Ming Lei -- Ming
Re: [PATCH] blk-mq: start request gstate with gen 1
On Tue, Apr 17, 2018 at 11:46:20AM +0800, Jianchao Wang wrote: > rq->gstate and rq->aborted_gstate both are zero before rqs are > allocated. If we have a small timeout, when the timer fires, > there could be rqs that are never allocated, and also there could > be rq that has been allocated but not initialized and started. At > the moment, the rq->gstate and rq->aborted_gstate both are 0, thus > the blk_mq_terminate_expired will identify the rq is timed out and > invoke .timeout early. > > For scsi, this will cause scsi_times_out to be invoked before the > scsi_cmnd is not initialized, scsi_cmnd->device is still NULL at > the moment, then we will get crash. > > Cc: Bart Van Assche > Cc: Tejun Heo > Cc: Ming Lei > Cc: Martin Steigerwald > Cc: sta...@vger.kernel.org > Signed-off-by: Jianchao Wang > --- > block/blk-core.c | 4 > block/blk-mq.c | 7 +++ > 2 files changed, 11 insertions(+) > > diff --git a/block/blk-core.c b/block/blk-core.c > index abcb868..ce62681 100644 > --- a/block/blk-core.c > +++ b/block/blk-core.c > @@ -201,6 +201,10 @@ void blk_rq_init(struct request_queue *q, struct request > *rq) > rq->part = NULL; > seqcount_init(>gstate_seq); > u64_stats_init(>aborted_gstate_sync); > + /* > + * See comment of blk_mq_init_request > + */ > + WRITE_ONCE(rq->gstate, MQ_RQ_GEN_INC); > } > EXPORT_SYMBOL(blk_rq_init); > > diff --git a/block/blk-mq.c b/block/blk-mq.c > index f5c7dbc..d62030a 100644 > --- a/block/blk-mq.c > +++ b/block/blk-mq.c > @@ -2069,6 +2069,13 @@ static int blk_mq_init_request(struct blk_mq_tag_set > *set, struct request *rq, > > seqcount_init(>gstate_seq); > u64_stats_init(>aborted_gstate_sync); > + /* > + * start gstate with gen 1 instead of 0, otherwise it will be equal > + * to aborted_gstate, and be identified timed out by > + * blk_mq_terminate_expired. > + */ > + WRITE_ONCE(rq->gstate, MQ_RQ_GEN_INC); > + > return 0; > } Good catch, blk_mq_check_expired() is bypassed, but it is still hit by blk_mq_terminate_expired(). Reviewed-by: Ming Lei -- Ming
[PATCH] x86/headers/UAPI: Move DISABLE_EXITS KVM capability bits to the UAPI
Move DISABLE_EXITS KVM capability bits to the UAPI just like the rest of capabilities. Cc: Paolo BonziniCc: Radim Krčmář Cc: Thomas Gleixner Cc: Ingo Molnar Cc: H. Peter Anvin Cc: x...@kernel.org Cc: k...@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: KarimAllah Ahmed --- arch/x86/kvm/x86.h | 7 --- include/uapi/linux/kvm.h | 7 +++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index 98d3503..acb1502 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -303,13 +303,6 @@ static inline u64 nsec_to_cycles(struct kvm_vcpu *vcpu, u64 nsec) __rem; \ }) -#define KVM_X86_DISABLE_EXITS_MWAIT (1 << 0) -#define KVM_X86_DISABLE_EXITS_HTL(1 << 1) -#define KVM_X86_DISABLE_EXITS_PAUSE (1 << 2) -#define KVM_X86_DISABLE_VALID_EXITS (KVM_X86_DISABLE_EXITS_MWAIT | \ - KVM_X86_DISABLE_EXITS_HTL | \ - KVM_X86_DISABLE_EXITS_PAUSE) - static inline bool kvm_mwait_in_guest(struct kvm *kvm) { return kvm->arch.mwait_in_guest; diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index aefaf6c..077d16f 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -676,6 +676,13 @@ struct kvm_ioeventfd { __u8 pad[36]; }; +#define KVM_X86_DISABLE_EXITS_MWAIT (1 << 0) +#define KVM_X86_DISABLE_EXITS_HTL(1 << 1) +#define KVM_X86_DISABLE_EXITS_PAUSE (1 << 2) +#define KVM_X86_DISABLE_VALID_EXITS (KVM_X86_DISABLE_EXITS_MWAIT | \ + KVM_X86_DISABLE_EXITS_HTL | \ + KVM_X86_DISABLE_EXITS_PAUSE) + /* for KVM_ENABLE_CAP */ struct kvm_enable_cap { /* in */ -- 2.7.4
[PATCH] x86/headers/UAPI: Move DISABLE_EXITS KVM capability bits to the UAPI
Move DISABLE_EXITS KVM capability bits to the UAPI just like the rest of capabilities. Cc: Paolo Bonzini Cc: Radim Krčmář Cc: Thomas Gleixner Cc: Ingo Molnar Cc: H. Peter Anvin Cc: x...@kernel.org Cc: k...@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: KarimAllah Ahmed --- arch/x86/kvm/x86.h | 7 --- include/uapi/linux/kvm.h | 7 +++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index 98d3503..acb1502 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -303,13 +303,6 @@ static inline u64 nsec_to_cycles(struct kvm_vcpu *vcpu, u64 nsec) __rem; \ }) -#define KVM_X86_DISABLE_EXITS_MWAIT (1 << 0) -#define KVM_X86_DISABLE_EXITS_HTL(1 << 1) -#define KVM_X86_DISABLE_EXITS_PAUSE (1 << 2) -#define KVM_X86_DISABLE_VALID_EXITS (KVM_X86_DISABLE_EXITS_MWAIT | \ - KVM_X86_DISABLE_EXITS_HTL | \ - KVM_X86_DISABLE_EXITS_PAUSE) - static inline bool kvm_mwait_in_guest(struct kvm *kvm) { return kvm->arch.mwait_in_guest; diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index aefaf6c..077d16f 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -676,6 +676,13 @@ struct kvm_ioeventfd { __u8 pad[36]; }; +#define KVM_X86_DISABLE_EXITS_MWAIT (1 << 0) +#define KVM_X86_DISABLE_EXITS_HTL(1 << 1) +#define KVM_X86_DISABLE_EXITS_PAUSE (1 << 2) +#define KVM_X86_DISABLE_VALID_EXITS (KVM_X86_DISABLE_EXITS_MWAIT | \ + KVM_X86_DISABLE_EXITS_HTL | \ + KVM_X86_DISABLE_EXITS_PAUSE) + /* for KVM_ENABLE_CAP */ struct kvm_enable_cap { /* in */ -- 2.7.4
Re: [PATCH v4 3/3] clk: qcom: Add Global Clock controller (GCC) driver for SDM845
Quoting Amit Nischal (2018-04-08 23:14:53) > From: Taniya Das> > Add support for the global clock controller found on SDM845 > based devices. This should allow most non-multimedia device > drivers to probe and control their clocks. > > Signed-off-by: Taniya Das > Signed-off-by: Amit Nischal > --- I think my review comments on v3 still apply to v4.
Re: [PATCH v4 3/3] clk: qcom: Add Global Clock controller (GCC) driver for SDM845
Quoting Amit Nischal (2018-04-08 23:14:53) > From: Taniya Das > > Add support for the global clock controller found on SDM845 > based devices. This should allow most non-multimedia device > drivers to probe and control their clocks. > > Signed-off-by: Taniya Das > Signed-off-by: Amit Nischal > --- I think my review comments on v3 still apply to v4.
Re: [PATCH v4 1/3] clk: qcom: Clear hardware clock control bit of RCG
Quoting Amit Nischal (2018-04-08 23:14:51) > For upcoming targets like sdm845, POR value of the hardware clock control > bit is set for most of root clocks which needs to be cleared for software > to be able to control. For older targets like MSM8996, this bit is reserved > bit and having POR value as 0 so this patch will work for the older targets > too. So update the configuration mask to take care of the same to clear > hardware clock control bit. > > Signed-off-by: Amit NischalThis one's already been applied. Please stop sending it.
Re: [PATCH v4 1/3] clk: qcom: Clear hardware clock control bit of RCG
Quoting Amit Nischal (2018-04-08 23:14:51) > For upcoming targets like sdm845, POR value of the hardware clock control > bit is set for most of root clocks which needs to be cleared for software > to be able to control. For older targets like MSM8996, this bit is reserved > bit and having POR value as 0 so this patch will work for the older targets > too. So update the configuration mask to take care of the same to clear > hardware clock control bit. > > Signed-off-by: Amit Nischal This one's already been applied. Please stop sending it.
[PATCH v3 0/9] trace_uprobe: Support SDT markers having reference count (semaphore)
Userspace Statically Defined Tracepoints[1] are dtrace style markers inside userspace applications. Applications like PostgreSQL, MySQL, Pthread, Perl, Python, Java, Ruby, Node.js, libvirt, QEMU, glib etc have these markers embedded in them. These markers are added by developer at important places in the code. Each marker source expands to a single nop instruction in the compiled code but there may be additional overhead for computing the marker arguments which expands to couple of instructions. In case the overhead is more, execution of it can be omitted by runtime if() condition when no one is tracing on the marker: if (reference_counter > 0) { Execute marker instructions; } Default value of reference counter is 0. Tracer has to increment the reference counter before tracing on a marker and decrement it when done with the tracing. Currently, perf tool has limited supports for SDT markers. I.e. it can not trace markers surrounded by reference counter. Also, it's not easy to add reference counter logic in userspace tool like perf, so basic idea for this patchset is to add reference counter logic in the trace_uprobe infrastructure. Ex,[2] # cat tick.c ... for (i = 0; i < 100; i++) { DTRACE_PROBE1(tick, loop1, i); if (TICK_LOOP2_ENABLED()) { DTRACE_PROBE1(tick, loop2, i); } printf("hi: %d\n", i); sleep(1); } ... Here tick:loop1 is marker without reference counter where as tick:loop2 is surrounded by reference counter condition. # perf buildid-cache --add /tmp/tick # perf probe sdt_tick:loop1 # perf probe sdt_tick:loop2 # perf stat -e sdt_tick:loop1,sdt_tick:loop2 -- /tmp/tick hi: 0 hi: 1 hi: 2 ^C Performance counter stats for '/tmp/tick': 3 sdt_tick:loop1 0 sdt_tick:loop2 2.747086086 seconds time elapsed Perf failed to record data for tick:loop2. Same experiment with this patch series: # ./perf buildid-cache --add /tmp/tick # ./perf probe sdt_tick:loop2 # ./perf stat -e sdt_tick:loop2 /tmp/tick hi: 0 hi: 1 hi: 2 ^C Performance counter stats for '/tmp/tick': 3 sdt_tick:loop2 2.561851452 seconds time elapsed Note: - 'reference counter' is called as 'semaphore' in original Dtrace (or Systemtap, bcc and even in ELF) documentation and code. But the term 'semaphore' is misleading in this context. This is just a counter used to hold number of tracers tracing on a marker. This is not really used for any synchronization. So we are referring it as 'reference counter' in kernel / perf code. v3 changes: - [PATCH v3 6/9] Fix build failure. - [PATCH v3 6/9] Move uprobe_mmap_callback() after no_uprobe_events() check. Actually, it should be moved after MMF_HAS_UPROBES as well. But current implementation is sub-optimal. If there are multiple instances of same application running and user wants to trace any particular instance, trace_uprobe is updating reference counter in all instances. This is not a problem on user side because instruction is not replaced with trap/int3 and thus user will only see samples from his interested process. But still this is more of a correctness issue. I'm working on a fix for this. Once this gets fixed, we can move uprobe_mmap_callback() call after MMF_HAS_UPROBES. - [PATCH v3 7/9] Remove mmu_notifier. Instead, use callback from uprobe_clear_state(). Again, uprobe_clear_state_callback() should be moved after MMF_HAS_UPROBES. But that should be done when move uprobe_mmap_callback() first. - [PATCH v3 7/9] Properly handle error cases for sdt_increment_ref_ctr() and trace_uprobe_mmap(). - [PATCH v3 9/9] Show warning if kernel doesn't support ref_ctr logic and user tries to use it. Also, return error in this case instead of adding entry in uprobe_events. - [PATCH v3 9/9] Don't check kernel ref_ctr support while adding files into buildid-cache. v2 can be found at: https://lkml.org/lkml/2018/4/4/127 v2 changes: - [PATCH v2 3/9] is new. build_map_info() has a side effect. One has to perform mmput() when he is done with the mm. Let free_map_info() take care of mmput() so that one does not need to worry about it. - [PATCH v2 6/9] sdt_update_ref_ctr(). No need to use memcpy(). Reference counter can be directly updated using normal assignment. - [PATCH v2 6/9] Check valid vma is returned by sdt_find_vma() before incrementing / decrementing a reference counter. - [PATCH v2 6/9] Introduce utility functions for taking write lock on dup_mmap_sem. Use these functions in trace_uprobe to avoid race with fork / dup_mmap(). - [PATCH v2 6/9] Don't check presence of mm in tu->sml at decrement time. Purpose of maintaining the list is to ensure increment happen only once for each {trace_uprobe,mm} tuple. - [PATCH v2 7/9] v1 was not removing mm from tu->sml when process exits and tracing is
[PATCH v3 0/9] trace_uprobe: Support SDT markers having reference count (semaphore)
Userspace Statically Defined Tracepoints[1] are dtrace style markers inside userspace applications. Applications like PostgreSQL, MySQL, Pthread, Perl, Python, Java, Ruby, Node.js, libvirt, QEMU, glib etc have these markers embedded in them. These markers are added by developer at important places in the code. Each marker source expands to a single nop instruction in the compiled code but there may be additional overhead for computing the marker arguments which expands to couple of instructions. In case the overhead is more, execution of it can be omitted by runtime if() condition when no one is tracing on the marker: if (reference_counter > 0) { Execute marker instructions; } Default value of reference counter is 0. Tracer has to increment the reference counter before tracing on a marker and decrement it when done with the tracing. Currently, perf tool has limited supports for SDT markers. I.e. it can not trace markers surrounded by reference counter. Also, it's not easy to add reference counter logic in userspace tool like perf, so basic idea for this patchset is to add reference counter logic in the trace_uprobe infrastructure. Ex,[2] # cat tick.c ... for (i = 0; i < 100; i++) { DTRACE_PROBE1(tick, loop1, i); if (TICK_LOOP2_ENABLED()) { DTRACE_PROBE1(tick, loop2, i); } printf("hi: %d\n", i); sleep(1); } ... Here tick:loop1 is marker without reference counter where as tick:loop2 is surrounded by reference counter condition. # perf buildid-cache --add /tmp/tick # perf probe sdt_tick:loop1 # perf probe sdt_tick:loop2 # perf stat -e sdt_tick:loop1,sdt_tick:loop2 -- /tmp/tick hi: 0 hi: 1 hi: 2 ^C Performance counter stats for '/tmp/tick': 3 sdt_tick:loop1 0 sdt_tick:loop2 2.747086086 seconds time elapsed Perf failed to record data for tick:loop2. Same experiment with this patch series: # ./perf buildid-cache --add /tmp/tick # ./perf probe sdt_tick:loop2 # ./perf stat -e sdt_tick:loop2 /tmp/tick hi: 0 hi: 1 hi: 2 ^C Performance counter stats for '/tmp/tick': 3 sdt_tick:loop2 2.561851452 seconds time elapsed Note: - 'reference counter' is called as 'semaphore' in original Dtrace (or Systemtap, bcc and even in ELF) documentation and code. But the term 'semaphore' is misleading in this context. This is just a counter used to hold number of tracers tracing on a marker. This is not really used for any synchronization. So we are referring it as 'reference counter' in kernel / perf code. v3 changes: - [PATCH v3 6/9] Fix build failure. - [PATCH v3 6/9] Move uprobe_mmap_callback() after no_uprobe_events() check. Actually, it should be moved after MMF_HAS_UPROBES as well. But current implementation is sub-optimal. If there are multiple instances of same application running and user wants to trace any particular instance, trace_uprobe is updating reference counter in all instances. This is not a problem on user side because instruction is not replaced with trap/int3 and thus user will only see samples from his interested process. But still this is more of a correctness issue. I'm working on a fix for this. Once this gets fixed, we can move uprobe_mmap_callback() call after MMF_HAS_UPROBES. - [PATCH v3 7/9] Remove mmu_notifier. Instead, use callback from uprobe_clear_state(). Again, uprobe_clear_state_callback() should be moved after MMF_HAS_UPROBES. But that should be done when move uprobe_mmap_callback() first. - [PATCH v3 7/9] Properly handle error cases for sdt_increment_ref_ctr() and trace_uprobe_mmap(). - [PATCH v3 9/9] Show warning if kernel doesn't support ref_ctr logic and user tries to use it. Also, return error in this case instead of adding entry in uprobe_events. - [PATCH v3 9/9] Don't check kernel ref_ctr support while adding files into buildid-cache. v2 can be found at: https://lkml.org/lkml/2018/4/4/127 v2 changes: - [PATCH v2 3/9] is new. build_map_info() has a side effect. One has to perform mmput() when he is done with the mm. Let free_map_info() take care of mmput() so that one does not need to worry about it. - [PATCH v2 6/9] sdt_update_ref_ctr(). No need to use memcpy(). Reference counter can be directly updated using normal assignment. - [PATCH v2 6/9] Check valid vma is returned by sdt_find_vma() before incrementing / decrementing a reference counter. - [PATCH v2 6/9] Introduce utility functions for taking write lock on dup_mmap_sem. Use these functions in trace_uprobe to avoid race with fork / dup_mmap(). - [PATCH v2 6/9] Don't check presence of mm in tu->sml at decrement time. Purpose of maintaining the list is to ensure increment happen only once for each {trace_uprobe,mm} tuple. - [PATCH v2 7/9] v1 was not removing mm from tu->sml when process exits and tracing is
[PATCH v3 5/9] Uprobe: Export uprobe_map_info along with uprobe_{build/free}_map_info()
From: Ravi BangoriaGiven the file(inode) and offset, build_map_info() finds all existing mm that map the portion of file containing offset. Exporting these functions and data structure will help to use them in other set of files. Signed-off-by: Ravi Bangoria Reviewed-by: Jérôme Glisse --- include/linux/uprobes.h | 9 + kernel/events/uprobes.c | 14 +++--- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h index 0a294e9..7bd2760 100644 --- a/include/linux/uprobes.h +++ b/include/linux/uprobes.h @@ -109,12 +109,19 @@ enum rp_check { RP_CHECK_RET, }; +struct address_space; struct xol_area; struct uprobes_state { struct xol_area *xol_area; }; +struct uprobe_map_info { + struct uprobe_map_info *next; + struct mm_struct *mm; + unsigned long vaddr; +}; + extern int set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); extern int set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); extern bool is_swbp_insn(uprobe_opcode_t *insn); @@ -149,6 +156,8 @@ struct uprobes_state { extern bool arch_uprobe_ignore(struct arch_uprobe *aup, struct pt_regs *regs); extern void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr, void *src, unsigned long len); +extern struct uprobe_map_info *uprobe_free_map_info(struct uprobe_map_info *info); +extern struct uprobe_map_info *uprobe_build_map_info(struct address_space *mapping, loff_t offset, bool is_register); #else /* !CONFIG_UPROBES */ struct uprobes_state { }; diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 477dc42..096d1e6 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -695,14 +695,7 @@ static void delete_uprobe(struct uprobe *uprobe) put_uprobe(uprobe); } -struct uprobe_map_info { - struct uprobe_map_info *next; - struct mm_struct *mm; - unsigned long vaddr; -}; - -static inline struct uprobe_map_info * -uprobe_free_map_info(struct uprobe_map_info *info) +struct uprobe_map_info *uprobe_free_map_info(struct uprobe_map_info *info) { struct uprobe_map_info *next = info->next; mmput(info->mm); @@ -710,9 +703,8 @@ struct uprobe_map_info { return next; } -static struct uprobe_map_info * -uprobe_build_map_info(struct address_space *mapping, loff_t offset, - bool is_register) +struct uprobe_map_info *uprobe_build_map_info(struct address_space *mapping, + loff_t offset, bool is_register) { unsigned long pgoff = offset >> PAGE_SHIFT; struct vm_area_struct *vma; -- 1.8.3.1
[PATCH v3 5/9] Uprobe: Export uprobe_map_info along with uprobe_{build/free}_map_info()
From: Ravi Bangoria Given the file(inode) and offset, build_map_info() finds all existing mm that map the portion of file containing offset. Exporting these functions and data structure will help to use them in other set of files. Signed-off-by: Ravi Bangoria Reviewed-by: Jérôme Glisse --- include/linux/uprobes.h | 9 + kernel/events/uprobes.c | 14 +++--- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h index 0a294e9..7bd2760 100644 --- a/include/linux/uprobes.h +++ b/include/linux/uprobes.h @@ -109,12 +109,19 @@ enum rp_check { RP_CHECK_RET, }; +struct address_space; struct xol_area; struct uprobes_state { struct xol_area *xol_area; }; +struct uprobe_map_info { + struct uprobe_map_info *next; + struct mm_struct *mm; + unsigned long vaddr; +}; + extern int set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); extern int set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); extern bool is_swbp_insn(uprobe_opcode_t *insn); @@ -149,6 +156,8 @@ struct uprobes_state { extern bool arch_uprobe_ignore(struct arch_uprobe *aup, struct pt_regs *regs); extern void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr, void *src, unsigned long len); +extern struct uprobe_map_info *uprobe_free_map_info(struct uprobe_map_info *info); +extern struct uprobe_map_info *uprobe_build_map_info(struct address_space *mapping, loff_t offset, bool is_register); #else /* !CONFIG_UPROBES */ struct uprobes_state { }; diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 477dc42..096d1e6 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -695,14 +695,7 @@ static void delete_uprobe(struct uprobe *uprobe) put_uprobe(uprobe); } -struct uprobe_map_info { - struct uprobe_map_info *next; - struct mm_struct *mm; - unsigned long vaddr; -}; - -static inline struct uprobe_map_info * -uprobe_free_map_info(struct uprobe_map_info *info) +struct uprobe_map_info *uprobe_free_map_info(struct uprobe_map_info *info) { struct uprobe_map_info *next = info->next; mmput(info->mm); @@ -710,9 +703,8 @@ struct uprobe_map_info { return next; } -static struct uprobe_map_info * -uprobe_build_map_info(struct address_space *mapping, loff_t offset, - bool is_register) +struct uprobe_map_info *uprobe_build_map_info(struct address_space *mapping, + loff_t offset, bool is_register) { unsigned long pgoff = offset >> PAGE_SHIFT; struct vm_area_struct *vma; -- 1.8.3.1
[PATCH v3 6/9] trace_uprobe: Support SDT markers having reference count (semaphore)
From: Ravi BangoriaUserspace Statically Defined Tracepoints[1] are dtrace style markers inside userspace applications. Applications like PostgreSQL, MySQL, Pthread, Perl, Python, Java, Ruby, Node.js, libvirt, QEMU, glib etc have these markers embedded in them. These markers are added by developer at important places in the code. Each marker source expands to a single nop instruction in the compiled code but there may be additional overhead for computing the marker arguments which expands to couple of instructions. In case the overhead is more, execution of it can be omitted by runtime if() condition when no one is tracing on the marker: if (reference_counter > 0) { Execute marker instructions; } Default value of reference counter is 0. Tracer has to increment the reference counter before tracing on a marker and decrement it when done with the tracing. Implement the reference counter logic in trace_uprobe, leaving core uprobe infrastructure as is, except one new callback from uprobe_mmap() to trace_uprobe. trace_uprobe definition with reference counter will now be: :[(ref_ctr_offset)] There are two different cases while enabling the marker, 1. Trace existing process. In this case, find all suitable processes and increment the reference counter in them. 2. Enable trace before running target binary. In this case, all mmaps will get notified to trace_uprobe and trace_uprobe will increment the reference counter if corresponding uprobe is enabled. At the time of disabling probes, decrement reference counter in all existing target processes. [1] https://sourceware.org/systemtap/wiki/UserSpaceProbeImplementation Note: 'reference counter' is called as 'semaphore' in original Dtrace (or Systemtap, bcc and even in ELF) documentation and code. But the term 'semaphore' is misleading in this context. This is just a counter used to hold number of tracers tracing on a marker. This is not really used for any synchronization. So we are referring it as 'reference counter' in kernel / perf code. Signed-off-by: Ravi Bangoria Signed-off-by: Fengguang Wu [Fengguang reported/fixed build failure] --- include/linux/uprobes.h | 10 +++ kernel/events/uprobes.c | 21 +- kernel/trace/trace_uprobe.c | 162 +++- 3 files changed, 190 insertions(+), 3 deletions(-) diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h index 7bd2760..2db3ed1 100644 --- a/include/linux/uprobes.h +++ b/include/linux/uprobes.h @@ -122,6 +122,8 @@ struct uprobe_map_info { unsigned long vaddr; }; +extern void (*uprobe_mmap_callback)(struct vm_area_struct *vma); + extern int set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); extern int set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); extern bool is_swbp_insn(uprobe_opcode_t *insn); @@ -136,6 +138,8 @@ struct uprobe_map_info { extern void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end); extern void uprobe_start_dup_mmap(void); extern void uprobe_end_dup_mmap(void); +extern void uprobe_down_write_dup_mmap(void); +extern void uprobe_up_write_dup_mmap(void); extern void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm); extern void uprobe_free_utask(struct task_struct *t); extern void uprobe_copy_process(struct task_struct *t, unsigned long flags); @@ -192,6 +196,12 @@ static inline void uprobe_start_dup_mmap(void) static inline void uprobe_end_dup_mmap(void) { } +static inline void uprobe_down_write_dup_mmap(void) +{ +} +static inline void uprobe_up_write_dup_mmap(void) +{ +} static inline void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm) { diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 096d1e6..e26ad83 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -1044,6 +1044,9 @@ static void build_probe_list(struct inode *inode, spin_unlock(_treelock); } +/* Rightnow the only user of this is trace_uprobe. */ +void (*uprobe_mmap_callback)(struct vm_area_struct *vma); + /* * Called from mmap_region/vma_adjust with mm->mmap_sem acquired. * @@ -1056,7 +1059,13 @@ int uprobe_mmap(struct vm_area_struct *vma) struct uprobe *uprobe, *u; struct inode *inode; - if (no_uprobe_events() || !valid_vma(vma, true)) + if (no_uprobe_events()) + return 0; + + if (uprobe_mmap_callback) + uprobe_mmap_callback(vma); + + if (!valid_vma(vma, true)) return 0; inode = file_inode(vma->vm_file); @@ -1247,6 +1256,16 @@ void uprobe_end_dup_mmap(void) percpu_up_read(_mmap_sem); } +void uprobe_down_write_dup_mmap(void) +{ + percpu_down_write(_mmap_sem); +} + +void uprobe_up_write_dup_mmap(void) +{ + percpu_up_write(_mmap_sem); +} +
[PATCH v3 6/9] trace_uprobe: Support SDT markers having reference count (semaphore)
From: Ravi Bangoria Userspace Statically Defined Tracepoints[1] are dtrace style markers inside userspace applications. Applications like PostgreSQL, MySQL, Pthread, Perl, Python, Java, Ruby, Node.js, libvirt, QEMU, glib etc have these markers embedded in them. These markers are added by developer at important places in the code. Each marker source expands to a single nop instruction in the compiled code but there may be additional overhead for computing the marker arguments which expands to couple of instructions. In case the overhead is more, execution of it can be omitted by runtime if() condition when no one is tracing on the marker: if (reference_counter > 0) { Execute marker instructions; } Default value of reference counter is 0. Tracer has to increment the reference counter before tracing on a marker and decrement it when done with the tracing. Implement the reference counter logic in trace_uprobe, leaving core uprobe infrastructure as is, except one new callback from uprobe_mmap() to trace_uprobe. trace_uprobe definition with reference counter will now be: :[(ref_ctr_offset)] There are two different cases while enabling the marker, 1. Trace existing process. In this case, find all suitable processes and increment the reference counter in them. 2. Enable trace before running target binary. In this case, all mmaps will get notified to trace_uprobe and trace_uprobe will increment the reference counter if corresponding uprobe is enabled. At the time of disabling probes, decrement reference counter in all existing target processes. [1] https://sourceware.org/systemtap/wiki/UserSpaceProbeImplementation Note: 'reference counter' is called as 'semaphore' in original Dtrace (or Systemtap, bcc and even in ELF) documentation and code. But the term 'semaphore' is misleading in this context. This is just a counter used to hold number of tracers tracing on a marker. This is not really used for any synchronization. So we are referring it as 'reference counter' in kernel / perf code. Signed-off-by: Ravi Bangoria Signed-off-by: Fengguang Wu [Fengguang reported/fixed build failure] --- include/linux/uprobes.h | 10 +++ kernel/events/uprobes.c | 21 +- kernel/trace/trace_uprobe.c | 162 +++- 3 files changed, 190 insertions(+), 3 deletions(-) diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h index 7bd2760..2db3ed1 100644 --- a/include/linux/uprobes.h +++ b/include/linux/uprobes.h @@ -122,6 +122,8 @@ struct uprobe_map_info { unsigned long vaddr; }; +extern void (*uprobe_mmap_callback)(struct vm_area_struct *vma); + extern int set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); extern int set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr); extern bool is_swbp_insn(uprobe_opcode_t *insn); @@ -136,6 +138,8 @@ struct uprobe_map_info { extern void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end); extern void uprobe_start_dup_mmap(void); extern void uprobe_end_dup_mmap(void); +extern void uprobe_down_write_dup_mmap(void); +extern void uprobe_up_write_dup_mmap(void); extern void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm); extern void uprobe_free_utask(struct task_struct *t); extern void uprobe_copy_process(struct task_struct *t, unsigned long flags); @@ -192,6 +196,12 @@ static inline void uprobe_start_dup_mmap(void) static inline void uprobe_end_dup_mmap(void) { } +static inline void uprobe_down_write_dup_mmap(void) +{ +} +static inline void uprobe_up_write_dup_mmap(void) +{ +} static inline void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm) { diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 096d1e6..e26ad83 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -1044,6 +1044,9 @@ static void build_probe_list(struct inode *inode, spin_unlock(_treelock); } +/* Rightnow the only user of this is trace_uprobe. */ +void (*uprobe_mmap_callback)(struct vm_area_struct *vma); + /* * Called from mmap_region/vma_adjust with mm->mmap_sem acquired. * @@ -1056,7 +1059,13 @@ int uprobe_mmap(struct vm_area_struct *vma) struct uprobe *uprobe, *u; struct inode *inode; - if (no_uprobe_events() || !valid_vma(vma, true)) + if (no_uprobe_events()) + return 0; + + if (uprobe_mmap_callback) + uprobe_mmap_callback(vma); + + if (!valid_vma(vma, true)) return 0; inode = file_inode(vma->vm_file); @@ -1247,6 +1256,16 @@ void uprobe_end_dup_mmap(void) percpu_up_read(_mmap_sem); } +void uprobe_down_write_dup_mmap(void) +{ + percpu_down_write(_mmap_sem); +} + +void uprobe_up_write_dup_mmap(void) +{ + percpu_up_write(_mmap_sem); +} + void uprobe_dup_mmap(struct mm_struct *oldmm, struct mm_struct *newmm) {
[PATCH v3 9/9] perf probe: Support SDT markers having reference counter (semaphore)
From: Ravi BangoriaWith this, perf buildid-cache will save SDT markers with reference counter in probe cache. Perf probe will be able to probe markers having reference counter. Ex, # readelf -n /tmp/tick | grep -A1 loop2 Name: loop2 ... Semaphore: 0x10020036 # ./perf buildid-cache --add /tmp/tick # ./perf probe sdt_tick:loop2 # ./perf stat -e sdt_tick:loop2 /tmp/tick hi: 0 hi: 1 hi: 2 ^C Performance counter stats for '/tmp/tick': 3 sdt_tick:loop2 2.561851452 seconds time elapsed Signed-off-by: Ravi Bangoria --- tools/perf/util/probe-event.c | 39 tools/perf/util/probe-event.h | 1 + tools/perf/util/probe-file.c | 34 ++-- tools/perf/util/probe-file.h | 1 + tools/perf/util/symbol-elf.c | 46 --- tools/perf/util/symbol.h | 7 +++ 6 files changed, 106 insertions(+), 22 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index e1dbc98..9b9c26e 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -1832,6 +1832,12 @@ int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev) tp->offset = strtoul(fmt2_str, NULL, 10); } + if (tev->uprobes) { + fmt2_str = strchr(p, '('); + if (fmt2_str) + tp->ref_ctr_offset = strtoul(fmt2_str + 1, NULL, 0); + } + tev->nargs = argc - 2; tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); if (tev->args == NULL) { @@ -2025,6 +2031,22 @@ static int synthesize_probe_trace_arg(struct probe_trace_arg *arg, return err; } +static int +synthesize_uprobe_trace_def(struct probe_trace_event *tev, struct strbuf *buf) +{ + struct probe_trace_point *tp = >point; + int err; + + err = strbuf_addf(buf, "%s:0x%lx", tp->module, tp->address); + + if (err >= 0 && tp->ref_ctr_offset) { + if (!uprobe_ref_ctr_is_supported()) + return -1; + err = strbuf_addf(buf, "(0x%lx)", tp->ref_ctr_offset); + } + return err >= 0 ? 0 : -1; +} + char *synthesize_probe_trace_command(struct probe_trace_event *tev) { struct probe_trace_point *tp = >point; @@ -2054,15 +2076,17 @@ char *synthesize_probe_trace_command(struct probe_trace_event *tev) } /* Use the tp->address for uprobes */ - if (tev->uprobes) - err = strbuf_addf(, "%s:0x%lx", tp->module, tp->address); - else if (!strncmp(tp->symbol, "0x", 2)) + if (tev->uprobes) { + err = synthesize_uprobe_trace_def(tev, ); + } else if (!strncmp(tp->symbol, "0x", 2)) { /* Absolute address. See try_to_find_absolute_address() */ err = strbuf_addf(, "%s%s0x%lx", tp->module ?: "", tp->module ? ":" : "", tp->address); - else + } else { err = strbuf_addf(, "%s%s%s+%lu", tp->module ?: "", tp->module ? ":" : "", tp->symbol, tp->offset); + } + if (err) goto error; @@ -2646,6 +2670,13 @@ static void warn_uprobe_event_compat(struct probe_trace_event *tev) { int i; char *buf = synthesize_probe_trace_command(tev); + struct probe_trace_point *tp = >point; + + if (tp->ref_ctr_offset && !uprobe_ref_ctr_is_supported()) { + pr_warning("A semaphore is associated with %s:%s and " + "seems your kernel doesn't support it.\n", + tev->group, tev->event); + } /* Old uprobe event doesn't support memory dereference */ if (!tev->uprobes || tev->nargs == 0 || !buf) diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h index 45b14f0..15a98c3 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h @@ -27,6 +27,7 @@ struct probe_trace_point { char*symbol;/* Base symbol */ char*module;/* Module name */ unsigned long offset; /* Offset from symbol */ + unsigned long ref_ctr_offset; /* SDT reference counter offset */ unsigned long address;/* Actual address of the trace point */ boolretprobe; /* Return probe flag */ }; diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index 4ae1123..a17ba6a 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -697,8 +697,16 @@ int probe_cache__add_entry(struct probe_cache *pcache, #ifdef HAVE_GELF_GETNOTE_SUPPORT static unsigned long long sdt_note__get_addr(struct sdt_note *note) { - return note->bit32 ? (unsigned long
[PATCH v3 8/9] trace_uprobe/sdt: Document about reference counter
From: Ravi BangoriaReference counter gate the invocation of probe. If present, by default reference count is 0. Kernel needs to increment it before tracing the probe and decrement it when done. This is identical to semaphore in Userspace Statically Defined Tracepoints (USDT). Document usage of reference counter. Signed-off-by: Ravi Bangoria --- Documentation/trace/uprobetracer.txt | 16 +--- kernel/trace/trace.c | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Documentation/trace/uprobetracer.txt b/Documentation/trace/uprobetracer.txt index bf526a7c..cb6751d 100644 --- a/Documentation/trace/uprobetracer.txt +++ b/Documentation/trace/uprobetracer.txt @@ -19,15 +19,25 @@ user to calculate the offset of the probepoint in the object. Synopsis of uprobe_tracer - - p[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a uprobe - r[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a return uprobe (uretprobe) - -:[GRP/]EVENT : Clear uprobe or uretprobe event + p[:[GRP/]EVENT] PATH:OFFSET[(REF_CTR_OFFSET)] [FETCHARGS] + r[:[GRP/]EVENT] PATH:OFFSET[(REF_CTR_OFFSET)] [FETCHARGS] + -:[GRP/]EVENT + + p : Set a uprobe + r : Set a return uprobe (uretprobe) + - : Clear uprobe or uretprobe event GRP : Group name. If omitted, "uprobes" is the default value. EVENT : Event name. If omitted, the event name is generated based on PATH+OFFSET. PATH : Path to an executable or a library. OFFSET: Offset where the probe is inserted. + REF_CTR_OFFSET: Reference counter offset. Optional field. Reference count + gate the invocation of probe. If present, by default + reference count is 0. Kernel needs to increment it before + tracing the probe and decrement it when done. This is + identical to semaphore in Userspace Statically Defined + Tracepoints (USDT). FETCHARGS : Arguments. Each probe can have up to 128 args. %REG : Fetch register REG diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 300f4ea..d211937 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4604,7 +4604,7 @@ static int tracing_trace_options_open(struct inode *inode, struct file *file) "place (kretprobe): [:][+]|\n" #endif #ifdef CONFIG_UPROBE_EVENTS - "\tplace: :\n" + " place (uprobe): :[(ref_ctr_offset)]\n" #endif "\t args: =fetcharg[:type]\n" "\t fetcharg: %, @, @[+|-],\n" -- 1.8.3.1
[PATCH v3 9/9] perf probe: Support SDT markers having reference counter (semaphore)
From: Ravi Bangoria With this, perf buildid-cache will save SDT markers with reference counter in probe cache. Perf probe will be able to probe markers having reference counter. Ex, # readelf -n /tmp/tick | grep -A1 loop2 Name: loop2 ... Semaphore: 0x10020036 # ./perf buildid-cache --add /tmp/tick # ./perf probe sdt_tick:loop2 # ./perf stat -e sdt_tick:loop2 /tmp/tick hi: 0 hi: 1 hi: 2 ^C Performance counter stats for '/tmp/tick': 3 sdt_tick:loop2 2.561851452 seconds time elapsed Signed-off-by: Ravi Bangoria --- tools/perf/util/probe-event.c | 39 tools/perf/util/probe-event.h | 1 + tools/perf/util/probe-file.c | 34 ++-- tools/perf/util/probe-file.h | 1 + tools/perf/util/symbol-elf.c | 46 --- tools/perf/util/symbol.h | 7 +++ 6 files changed, 106 insertions(+), 22 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index e1dbc98..9b9c26e 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -1832,6 +1832,12 @@ int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev) tp->offset = strtoul(fmt2_str, NULL, 10); } + if (tev->uprobes) { + fmt2_str = strchr(p, '('); + if (fmt2_str) + tp->ref_ctr_offset = strtoul(fmt2_str + 1, NULL, 0); + } + tev->nargs = argc - 2; tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); if (tev->args == NULL) { @@ -2025,6 +2031,22 @@ static int synthesize_probe_trace_arg(struct probe_trace_arg *arg, return err; } +static int +synthesize_uprobe_trace_def(struct probe_trace_event *tev, struct strbuf *buf) +{ + struct probe_trace_point *tp = >point; + int err; + + err = strbuf_addf(buf, "%s:0x%lx", tp->module, tp->address); + + if (err >= 0 && tp->ref_ctr_offset) { + if (!uprobe_ref_ctr_is_supported()) + return -1; + err = strbuf_addf(buf, "(0x%lx)", tp->ref_ctr_offset); + } + return err >= 0 ? 0 : -1; +} + char *synthesize_probe_trace_command(struct probe_trace_event *tev) { struct probe_trace_point *tp = >point; @@ -2054,15 +2076,17 @@ char *synthesize_probe_trace_command(struct probe_trace_event *tev) } /* Use the tp->address for uprobes */ - if (tev->uprobes) - err = strbuf_addf(, "%s:0x%lx", tp->module, tp->address); - else if (!strncmp(tp->symbol, "0x", 2)) + if (tev->uprobes) { + err = synthesize_uprobe_trace_def(tev, ); + } else if (!strncmp(tp->symbol, "0x", 2)) { /* Absolute address. See try_to_find_absolute_address() */ err = strbuf_addf(, "%s%s0x%lx", tp->module ?: "", tp->module ? ":" : "", tp->address); - else + } else { err = strbuf_addf(, "%s%s%s+%lu", tp->module ?: "", tp->module ? ":" : "", tp->symbol, tp->offset); + } + if (err) goto error; @@ -2646,6 +2670,13 @@ static void warn_uprobe_event_compat(struct probe_trace_event *tev) { int i; char *buf = synthesize_probe_trace_command(tev); + struct probe_trace_point *tp = >point; + + if (tp->ref_ctr_offset && !uprobe_ref_ctr_is_supported()) { + pr_warning("A semaphore is associated with %s:%s and " + "seems your kernel doesn't support it.\n", + tev->group, tev->event); + } /* Old uprobe event doesn't support memory dereference */ if (!tev->uprobes || tev->nargs == 0 || !buf) diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h index 45b14f0..15a98c3 100644 --- a/tools/perf/util/probe-event.h +++ b/tools/perf/util/probe-event.h @@ -27,6 +27,7 @@ struct probe_trace_point { char*symbol;/* Base symbol */ char*module;/* Module name */ unsigned long offset; /* Offset from symbol */ + unsigned long ref_ctr_offset; /* SDT reference counter offset */ unsigned long address;/* Actual address of the trace point */ boolretprobe; /* Return probe flag */ }; diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index 4ae1123..a17ba6a 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -697,8 +697,16 @@ int probe_cache__add_entry(struct probe_cache *pcache, #ifdef HAVE_GELF_GETNOTE_SUPPORT static unsigned long long sdt_note__get_addr(struct sdt_note *note) { - return note->bit32 ? (unsigned long long)note->addr.a32[0] -: (unsigned long
[PATCH v3 8/9] trace_uprobe/sdt: Document about reference counter
From: Ravi Bangoria Reference counter gate the invocation of probe. If present, by default reference count is 0. Kernel needs to increment it before tracing the probe and decrement it when done. This is identical to semaphore in Userspace Statically Defined Tracepoints (USDT). Document usage of reference counter. Signed-off-by: Ravi Bangoria --- Documentation/trace/uprobetracer.txt | 16 +--- kernel/trace/trace.c | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Documentation/trace/uprobetracer.txt b/Documentation/trace/uprobetracer.txt index bf526a7c..cb6751d 100644 --- a/Documentation/trace/uprobetracer.txt +++ b/Documentation/trace/uprobetracer.txt @@ -19,15 +19,25 @@ user to calculate the offset of the probepoint in the object. Synopsis of uprobe_tracer - - p[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a uprobe - r[:[GRP/]EVENT] PATH:OFFSET [FETCHARGS] : Set a return uprobe (uretprobe) - -:[GRP/]EVENT : Clear uprobe or uretprobe event + p[:[GRP/]EVENT] PATH:OFFSET[(REF_CTR_OFFSET)] [FETCHARGS] + r[:[GRP/]EVENT] PATH:OFFSET[(REF_CTR_OFFSET)] [FETCHARGS] + -:[GRP/]EVENT + + p : Set a uprobe + r : Set a return uprobe (uretprobe) + - : Clear uprobe or uretprobe event GRP : Group name. If omitted, "uprobes" is the default value. EVENT : Event name. If omitted, the event name is generated based on PATH+OFFSET. PATH : Path to an executable or a library. OFFSET: Offset where the probe is inserted. + REF_CTR_OFFSET: Reference counter offset. Optional field. Reference count + gate the invocation of probe. If present, by default + reference count is 0. Kernel needs to increment it before + tracing the probe and decrement it when done. This is + identical to semaphore in Userspace Statically Defined + Tracepoints (USDT). FETCHARGS : Arguments. Each probe can have up to 128 args. %REG : Fetch register REG diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 300f4ea..d211937 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4604,7 +4604,7 @@ static int tracing_trace_options_open(struct inode *inode, struct file *file) "place (kretprobe): [:][+]|\n" #endif #ifdef CONFIG_UPROBE_EVENTS - "\tplace: :\n" + " place (uprobe): :[(ref_ctr_offset)]\n" #endif "\t args: =fetcharg[:type]\n" "\t fetcharg: %, @, @[+|-],\n" -- 1.8.3.1
[PATCH v3 7/9] trace_uprobe/sdt: Fix multiple update of same reference counter
From: Ravi BangoriaWhen virtual memory map for binary/library is being prepared, there is no direct one to one mapping between mmap() and virtual memory area. Ex, when loader loads the library, it first calls mmap(size = total_size), where total_size is addition of size of all elf sections that are going to be mapped. Then it splits individual vmas with new mmap()/mprotect() calls. Loader does this to ensure it gets continuous address range for a library. load_elf_binary() also uses similar tricks while preparing mappings of binary. Ex for pyhton library, # strace -o out python mmap(NULL, 2738968, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fff9246 mmap(0x7fff926a, 327680, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x23) = 0x7fff926a mprotect(0x7fff926a, 65536, PROT_READ) = 0 Here, the first mmap() maps the whole library into one region. Second mmap() and third mprotect() split out the whole region into smaller vmas and sets appropriate protection flags. Now, in this case, trace_uprobe_mmap_callback() update the reference counter twice -- by second mmap() call and by third mprotect() call -- because both regions contain reference counter. But while de-registration, reference counter will get decremented only by once leaving reference counter > 0 even if no one is tracing on that marker. Example with python library before patch: # readelf -n /lib64/libpython2.7.so.1.0 | grep -A1 function__entry Name: function__entry ... Semaphore: 0x002899d8 Probe on a marker: # echo "p:sdt_python/function__entry /usr/lib64/libpython2.7.so.1.0:0x16a4d4(0x2799d8)" > uprobe_events Start tracing: # perf record -e sdt_python:function__entry -a Run python workload: # python # cat /proc/`pgrep python`/maps | grep libpython 7fffadb0-7fffadd4 r-xp 08:05 403934 /usr/lib64/libpython2.7.so.1.0 7fffadd4-7fffadd5 r--p 0023 08:05 403934 /usr/lib64/libpython2.7.so.1.0 7fffadd5-7fffadd9 rw-p 0024 08:05 403934 /usr/lib64/libpython2.7.so.1.0 Reference counter value has been incremented twice: # dd if=/proc/`pgrep python`/mem bs=1 count=1 skip=$(( 0x7fffadd899d8 )) 2>/dev/null | xxd 000: 02 . Kill perf: # ^C[ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.322 MB perf.data (1273 samples) ] Reference conter is still 1 even when no one is tracing on it: # dd if=/proc/`pgrep python`/mem bs=1 count=1 skip=$(( 0x7fffadd899d8 )) 2>/dev/null | xxd 000: 01 . Ensure increment and decrement happens in sync by keeping list of mms in trace_uprobe. Check presence of mm in the list before incrementing the reference counter. I.e. for each {trace_uprobe,mm} tuple, reference counter must be incremented only by one. Note that we don't check the presence of mm in the list at decrement time. We consider only two case while incrementing the reference counter: 1. Target binary is already running when we start tracing. In this case, find all mm which maps region of target binary containing reference counter. Loop over all mms and increment the counter if mm is not already present in the list. 2. Tracer is already tracing before target binary starts execution. In this case, all mmap(vma) gets notified to trace_uprobe. Trace_uprobe will update reference counter if vma->vm_mm is not already present in the list. There is also a third case which we don't consider, a fork() case. When process with markers forks itself, we don't explicitly increment the reference counter in child process because it should be taken care by dup_mmap(). We also don't add the child mm in the list. This is fine because we don't check presence of mm in the list at decrement time. After patch: Start perf record and then run python... Reference counter value has been incremented only once: # dd if=/proc/`pgrep python`/mem bs=1 count=1 skip=$(( 0x7fff9cbf99d8 )) 2>/dev/null | xxd 000: 01 . Kill perf: # ^C[ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.364 MB perf.data (1427 samples) ] Reference conter is reset to 0: # dd if=/proc/`pgrep python`/mem bs=1 count=1 skip=$(( 0x7fff9cbb99d8 )) 2>/dev/null | xxd 000: 00 . Signed-off-by: Ravi Bangoria --- include/linux/uprobes.h | 1 + kernel/events/uprobes.c | 6 +++ kernel/trace/trace_uprobe.c | 121 +--- 3 files changed, 122 insertions(+), 6 deletions(-) diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h index 2db3ed1..e447991 100644 ---
[PATCH v3 7/9] trace_uprobe/sdt: Fix multiple update of same reference counter
From: Ravi Bangoria When virtual memory map for binary/library is being prepared, there is no direct one to one mapping between mmap() and virtual memory area. Ex, when loader loads the library, it first calls mmap(size = total_size), where total_size is addition of size of all elf sections that are going to be mapped. Then it splits individual vmas with new mmap()/mprotect() calls. Loader does this to ensure it gets continuous address range for a library. load_elf_binary() also uses similar tricks while preparing mappings of binary. Ex for pyhton library, # strace -o out python mmap(NULL, 2738968, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fff9246 mmap(0x7fff926a, 327680, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x23) = 0x7fff926a mprotect(0x7fff926a, 65536, PROT_READ) = 0 Here, the first mmap() maps the whole library into one region. Second mmap() and third mprotect() split out the whole region into smaller vmas and sets appropriate protection flags. Now, in this case, trace_uprobe_mmap_callback() update the reference counter twice -- by second mmap() call and by third mprotect() call -- because both regions contain reference counter. But while de-registration, reference counter will get decremented only by once leaving reference counter > 0 even if no one is tracing on that marker. Example with python library before patch: # readelf -n /lib64/libpython2.7.so.1.0 | grep -A1 function__entry Name: function__entry ... Semaphore: 0x002899d8 Probe on a marker: # echo "p:sdt_python/function__entry /usr/lib64/libpython2.7.so.1.0:0x16a4d4(0x2799d8)" > uprobe_events Start tracing: # perf record -e sdt_python:function__entry -a Run python workload: # python # cat /proc/`pgrep python`/maps | grep libpython 7fffadb0-7fffadd4 r-xp 08:05 403934 /usr/lib64/libpython2.7.so.1.0 7fffadd4-7fffadd5 r--p 0023 08:05 403934 /usr/lib64/libpython2.7.so.1.0 7fffadd5-7fffadd9 rw-p 0024 08:05 403934 /usr/lib64/libpython2.7.so.1.0 Reference counter value has been incremented twice: # dd if=/proc/`pgrep python`/mem bs=1 count=1 skip=$(( 0x7fffadd899d8 )) 2>/dev/null | xxd 000: 02 . Kill perf: # ^C[ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.322 MB perf.data (1273 samples) ] Reference conter is still 1 even when no one is tracing on it: # dd if=/proc/`pgrep python`/mem bs=1 count=1 skip=$(( 0x7fffadd899d8 )) 2>/dev/null | xxd 000: 01 . Ensure increment and decrement happens in sync by keeping list of mms in trace_uprobe. Check presence of mm in the list before incrementing the reference counter. I.e. for each {trace_uprobe,mm} tuple, reference counter must be incremented only by one. Note that we don't check the presence of mm in the list at decrement time. We consider only two case while incrementing the reference counter: 1. Target binary is already running when we start tracing. In this case, find all mm which maps region of target binary containing reference counter. Loop over all mms and increment the counter if mm is not already present in the list. 2. Tracer is already tracing before target binary starts execution. In this case, all mmap(vma) gets notified to trace_uprobe. Trace_uprobe will update reference counter if vma->vm_mm is not already present in the list. There is also a third case which we don't consider, a fork() case. When process with markers forks itself, we don't explicitly increment the reference counter in child process because it should be taken care by dup_mmap(). We also don't add the child mm in the list. This is fine because we don't check presence of mm in the list at decrement time. After patch: Start perf record and then run python... Reference counter value has been incremented only once: # dd if=/proc/`pgrep python`/mem bs=1 count=1 skip=$(( 0x7fff9cbf99d8 )) 2>/dev/null | xxd 000: 01 . Kill perf: # ^C[ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.364 MB perf.data (1427 samples) ] Reference conter is reset to 0: # dd if=/proc/`pgrep python`/mem bs=1 count=1 skip=$(( 0x7fff9cbb99d8 )) 2>/dev/null | xxd 000: 00 . Signed-off-by: Ravi Bangoria --- include/linux/uprobes.h | 1 + kernel/events/uprobes.c | 6 +++ kernel/trace/trace_uprobe.c | 121 +--- 3 files changed, 122 insertions(+), 6 deletions(-) diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h index 2db3ed1..e447991 100644 --- a/include/linux/uprobes.h +++ b/include/linux/uprobes.h @@ -123,6 +123,7 @@
[PATCH v3 3/9] Uprobe: Move mmput() into free_map_info()
From: Oleg Nesterovbuild_map_info() has a side effect like one need to perform mmput() when done with the mm. Add mmput() in free_map_info() so that user does not have to call it explicitly. Signed-off-by: Oleg Nesterov Signed-off-by: Ravi Bangoria --- kernel/events/uprobes.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 535fd39..1d439c7 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -704,6 +704,7 @@ struct map_info { static inline struct map_info *free_map_info(struct map_info *info) { struct map_info *next = info->next; + mmput(info->mm); kfree(info); return next; } @@ -773,8 +774,11 @@ static inline struct map_info *free_map_info(struct map_info *info) goto again; out: - while (prev) - prev = free_map_info(prev); + while (prev) { + info = prev; + prev = prev->next; + kfree(info); + } return curr; } @@ -824,7 +828,6 @@ static inline struct map_info *free_map_info(struct map_info *info) unlock: up_write(>mmap_sem); free: - mmput(mm); info = free_map_info(info); } out: -- 1.8.3.1
[PATCH v3 3/9] Uprobe: Move mmput() into free_map_info()
From: Oleg Nesterov build_map_info() has a side effect like one need to perform mmput() when done with the mm. Add mmput() in free_map_info() so that user does not have to call it explicitly. Signed-off-by: Oleg Nesterov Signed-off-by: Ravi Bangoria --- kernel/events/uprobes.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 535fd39..1d439c7 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -704,6 +704,7 @@ struct map_info { static inline struct map_info *free_map_info(struct map_info *info) { struct map_info *next = info->next; + mmput(info->mm); kfree(info); return next; } @@ -773,8 +774,11 @@ static inline struct map_info *free_map_info(struct map_info *info) goto again; out: - while (prev) - prev = free_map_info(prev); + while (prev) { + info = prev; + prev = prev->next; + kfree(info); + } return curr; } @@ -824,7 +828,6 @@ static inline struct map_info *free_map_info(struct map_info *info) unlock: up_write(>mmap_sem); free: - mmput(mm); info = free_map_info(info); } out: -- 1.8.3.1
[PATCH v3 1/9] Uprobe: Export vaddr <-> offset conversion functions
From: Ravi BangoriaThese are generic functions which operates on file offset and virtual address. Make these functions available outside of uprobe code so that other can use it as well. Signed-off-by: Ravi Bangoria Reviewed-by: Jérôme Glisse --- include/linux/mm.h | 12 kernel/events/uprobes.c | 10 -- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index ccac106..de0cc08 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2272,6 +2272,18 @@ struct vm_unmapped_area_info { return unmapped_area(info); } +static inline unsigned long +offset_to_vaddr(struct vm_area_struct *vma, loff_t offset) +{ + return vma->vm_start + offset - ((loff_t)vma->vm_pgoff << PAGE_SHIFT); +} + +static inline loff_t +vaddr_to_offset(struct vm_area_struct *vma, unsigned long vaddr) +{ + return ((loff_t)vma->vm_pgoff << PAGE_SHIFT) + (vaddr - vma->vm_start); +} + /* truncate.c */ extern void truncate_inode_pages(struct address_space *, loff_t); extern void truncate_inode_pages_range(struct address_space *, diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index ce6848e..bd6f230 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -130,16 +130,6 @@ static bool valid_vma(struct vm_area_struct *vma, bool is_register) return vma->vm_file && (vma->vm_flags & flags) == VM_MAYEXEC; } -static unsigned long offset_to_vaddr(struct vm_area_struct *vma, loff_t offset) -{ - return vma->vm_start + offset - ((loff_t)vma->vm_pgoff << PAGE_SHIFT); -} - -static loff_t vaddr_to_offset(struct vm_area_struct *vma, unsigned long vaddr) -{ - return ((loff_t)vma->vm_pgoff << PAGE_SHIFT) + (vaddr - vma->vm_start); -} - /** * __replace_page - replace page in vma by new page. * based on replace_page in mm/ksm.c -- 1.8.3.1
[PATCH v3 1/9] Uprobe: Export vaddr <-> offset conversion functions
From: Ravi Bangoria These are generic functions which operates on file offset and virtual address. Make these functions available outside of uprobe code so that other can use it as well. Signed-off-by: Ravi Bangoria Reviewed-by: Jérôme Glisse --- include/linux/mm.h | 12 kernel/events/uprobes.c | 10 -- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index ccac106..de0cc08 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2272,6 +2272,18 @@ struct vm_unmapped_area_info { return unmapped_area(info); } +static inline unsigned long +offset_to_vaddr(struct vm_area_struct *vma, loff_t offset) +{ + return vma->vm_start + offset - ((loff_t)vma->vm_pgoff << PAGE_SHIFT); +} + +static inline loff_t +vaddr_to_offset(struct vm_area_struct *vma, unsigned long vaddr) +{ + return ((loff_t)vma->vm_pgoff << PAGE_SHIFT) + (vaddr - vma->vm_start); +} + /* truncate.c */ extern void truncate_inode_pages(struct address_space *, loff_t); extern void truncate_inode_pages_range(struct address_space *, diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index ce6848e..bd6f230 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -130,16 +130,6 @@ static bool valid_vma(struct vm_area_struct *vma, bool is_register) return vma->vm_file && (vma->vm_flags & flags) == VM_MAYEXEC; } -static unsigned long offset_to_vaddr(struct vm_area_struct *vma, loff_t offset) -{ - return vma->vm_start + offset - ((loff_t)vma->vm_pgoff << PAGE_SHIFT); -} - -static loff_t vaddr_to_offset(struct vm_area_struct *vma, unsigned long vaddr) -{ - return ((loff_t)vma->vm_pgoff << PAGE_SHIFT) + (vaddr - vma->vm_start); -} - /** * __replace_page - replace page in vma by new page. * based on replace_page in mm/ksm.c -- 1.8.3.1
[PATCH v3 2/9] mm: Prefix vma_ to vaddr_to_offset() and offset_to_vaddr()
From: Ravi BangoriaMake function names more meaningful by adding vma_ prefix to them. Signed-off-by: Ravi Bangoria Reviewed-by: Jérôme Glisse --- include/linux/mm.h | 4 ++-- kernel/events/uprobes.c | 14 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index de0cc08..47fd8a9 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2273,13 +2273,13 @@ struct vm_unmapped_area_info { } static inline unsigned long -offset_to_vaddr(struct vm_area_struct *vma, loff_t offset) +vma_offset_to_vaddr(struct vm_area_struct *vma, loff_t offset) { return vma->vm_start + offset - ((loff_t)vma->vm_pgoff << PAGE_SHIFT); } static inline loff_t -vaddr_to_offset(struct vm_area_struct *vma, unsigned long vaddr) +vma_vaddr_to_offset(struct vm_area_struct *vma, unsigned long vaddr) { return ((loff_t)vma->vm_pgoff << PAGE_SHIFT) + (vaddr - vma->vm_start); } diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index bd6f230..535fd39 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -748,7 +748,7 @@ static inline struct map_info *free_map_info(struct map_info *info) curr = info; info->mm = vma->vm_mm; - info->vaddr = offset_to_vaddr(vma, offset); + info->vaddr = vma_offset_to_vaddr(vma, offset); } i_mmap_unlock_read(mapping); @@ -807,7 +807,7 @@ static inline struct map_info *free_map_info(struct map_info *info) goto unlock; if (vma->vm_start > info->vaddr || - vaddr_to_offset(vma, info->vaddr) != uprobe->offset) + vma_vaddr_to_offset(vma, info->vaddr) != uprobe->offset) goto unlock; if (is_register) { @@ -977,7 +977,7 @@ static int unapply_uprobe(struct uprobe *uprobe, struct mm_struct *mm) uprobe->offset >= offset + vma->vm_end - vma->vm_start) continue; - vaddr = offset_to_vaddr(vma, uprobe->offset); + vaddr = vma_offset_to_vaddr(vma, uprobe->offset); err |= remove_breakpoint(uprobe, mm, vaddr); } up_read(>mmap_sem); @@ -1023,7 +1023,7 @@ static void build_probe_list(struct inode *inode, struct uprobe *u; INIT_LIST_HEAD(head); - min = vaddr_to_offset(vma, start); + min = vma_vaddr_to_offset(vma, start); max = min + (end - start) - 1; spin_lock(_treelock); @@ -1076,7 +1076,7 @@ int uprobe_mmap(struct vm_area_struct *vma) list_for_each_entry_safe(uprobe, u, _list, pending_list) { if (!fatal_signal_pending(current) && filter_chain(uprobe, UPROBE_FILTER_MMAP, vma->vm_mm)) { - unsigned long vaddr = offset_to_vaddr(vma, uprobe->offset); + unsigned long vaddr = vma_offset_to_vaddr(vma, uprobe->offset); install_breakpoint(uprobe, vma->vm_mm, vma, vaddr); } put_uprobe(uprobe); @@ -1095,7 +1095,7 @@ int uprobe_mmap(struct vm_area_struct *vma) inode = file_inode(vma->vm_file); - min = vaddr_to_offset(vma, start); + min = vma_vaddr_to_offset(vma, start); max = min + (end - start) - 1; spin_lock(_treelock); @@ -1730,7 +1730,7 @@ static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp) if (vma && vma->vm_start <= bp_vaddr) { if (valid_vma(vma, false)) { struct inode *inode = file_inode(vma->vm_file); - loff_t offset = vaddr_to_offset(vma, bp_vaddr); + loff_t offset = vma_vaddr_to_offset(vma, bp_vaddr); uprobe = find_uprobe(inode, offset); } -- 1.8.3.1
[PATCH v3 4/9] Uprobe: Rename map_info to uprobe_map_info
From: Ravi Bangoriamap_info is very generic name, rename it to uprobe_map_info. Renaming will help to export this structure outside of the file. Also rename free_map_info() to uprobe_free_map_info() and build_map_info() to uprobe_build_map_info(). Signed-off-by: Ravi Bangoria Reviewed-by: Jérôme Glisse --- kernel/events/uprobes.c | 30 -- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 1d439c7..477dc42 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -695,28 +695,30 @@ static void delete_uprobe(struct uprobe *uprobe) put_uprobe(uprobe); } -struct map_info { - struct map_info *next; +struct uprobe_map_info { + struct uprobe_map_info *next; struct mm_struct *mm; unsigned long vaddr; }; -static inline struct map_info *free_map_info(struct map_info *info) +static inline struct uprobe_map_info * +uprobe_free_map_info(struct uprobe_map_info *info) { - struct map_info *next = info->next; + struct uprobe_map_info *next = info->next; mmput(info->mm); kfree(info); return next; } -static struct map_info * -build_map_info(struct address_space *mapping, loff_t offset, bool is_register) +static struct uprobe_map_info * +uprobe_build_map_info(struct address_space *mapping, loff_t offset, + bool is_register) { unsigned long pgoff = offset >> PAGE_SHIFT; struct vm_area_struct *vma; - struct map_info *curr = NULL; - struct map_info *prev = NULL; - struct map_info *info; + struct uprobe_map_info *curr = NULL; + struct uprobe_map_info *prev = NULL; + struct uprobe_map_info *info; int more = 0; again: @@ -730,7 +732,7 @@ static inline struct map_info *free_map_info(struct map_info *info) * Needs GFP_NOWAIT to avoid i_mmap_rwsem recursion through * reclaim. This is optimistic, no harm done if it fails. */ - prev = kmalloc(sizeof(struct map_info), + prev = kmalloc(sizeof(struct uprobe_map_info), GFP_NOWAIT | __GFP_NOMEMALLOC | __GFP_NOWARN); if (prev) prev->next = NULL; @@ -763,7 +765,7 @@ static inline struct map_info *free_map_info(struct map_info *info) } do { - info = kmalloc(sizeof(struct map_info), GFP_KERNEL); + info = kmalloc(sizeof(struct uprobe_map_info), GFP_KERNEL); if (!info) { curr = ERR_PTR(-ENOMEM); goto out; @@ -786,11 +788,11 @@ static inline struct map_info *free_map_info(struct map_info *info) register_for_each_vma(struct uprobe *uprobe, struct uprobe_consumer *new) { bool is_register = !!new; - struct map_info *info; + struct uprobe_map_info *info; int err = 0; percpu_down_write(_mmap_sem); - info = build_map_info(uprobe->inode->i_mapping, + info = uprobe_build_map_info(uprobe->inode->i_mapping, uprobe->offset, is_register); if (IS_ERR(info)) { err = PTR_ERR(info); @@ -828,7 +830,7 @@ static inline struct map_info *free_map_info(struct map_info *info) unlock: up_write(>mmap_sem); free: - info = free_map_info(info); + info = uprobe_free_map_info(info); } out: percpu_up_write(_mmap_sem); -- 1.8.3.1
[PATCH v3 4/9] Uprobe: Rename map_info to uprobe_map_info
From: Ravi Bangoria map_info is very generic name, rename it to uprobe_map_info. Renaming will help to export this structure outside of the file. Also rename free_map_info() to uprobe_free_map_info() and build_map_info() to uprobe_build_map_info(). Signed-off-by: Ravi Bangoria Reviewed-by: Jérôme Glisse --- kernel/events/uprobes.c | 30 -- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 1d439c7..477dc42 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -695,28 +695,30 @@ static void delete_uprobe(struct uprobe *uprobe) put_uprobe(uprobe); } -struct map_info { - struct map_info *next; +struct uprobe_map_info { + struct uprobe_map_info *next; struct mm_struct *mm; unsigned long vaddr; }; -static inline struct map_info *free_map_info(struct map_info *info) +static inline struct uprobe_map_info * +uprobe_free_map_info(struct uprobe_map_info *info) { - struct map_info *next = info->next; + struct uprobe_map_info *next = info->next; mmput(info->mm); kfree(info); return next; } -static struct map_info * -build_map_info(struct address_space *mapping, loff_t offset, bool is_register) +static struct uprobe_map_info * +uprobe_build_map_info(struct address_space *mapping, loff_t offset, + bool is_register) { unsigned long pgoff = offset >> PAGE_SHIFT; struct vm_area_struct *vma; - struct map_info *curr = NULL; - struct map_info *prev = NULL; - struct map_info *info; + struct uprobe_map_info *curr = NULL; + struct uprobe_map_info *prev = NULL; + struct uprobe_map_info *info; int more = 0; again: @@ -730,7 +732,7 @@ static inline struct map_info *free_map_info(struct map_info *info) * Needs GFP_NOWAIT to avoid i_mmap_rwsem recursion through * reclaim. This is optimistic, no harm done if it fails. */ - prev = kmalloc(sizeof(struct map_info), + prev = kmalloc(sizeof(struct uprobe_map_info), GFP_NOWAIT | __GFP_NOMEMALLOC | __GFP_NOWARN); if (prev) prev->next = NULL; @@ -763,7 +765,7 @@ static inline struct map_info *free_map_info(struct map_info *info) } do { - info = kmalloc(sizeof(struct map_info), GFP_KERNEL); + info = kmalloc(sizeof(struct uprobe_map_info), GFP_KERNEL); if (!info) { curr = ERR_PTR(-ENOMEM); goto out; @@ -786,11 +788,11 @@ static inline struct map_info *free_map_info(struct map_info *info) register_for_each_vma(struct uprobe *uprobe, struct uprobe_consumer *new) { bool is_register = !!new; - struct map_info *info; + struct uprobe_map_info *info; int err = 0; percpu_down_write(_mmap_sem); - info = build_map_info(uprobe->inode->i_mapping, + info = uprobe_build_map_info(uprobe->inode->i_mapping, uprobe->offset, is_register); if (IS_ERR(info)) { err = PTR_ERR(info); @@ -828,7 +830,7 @@ static inline struct map_info *free_map_info(struct map_info *info) unlock: up_write(>mmap_sem); free: - info = free_map_info(info); + info = uprobe_free_map_info(info); } out: percpu_up_write(_mmap_sem); -- 1.8.3.1
[PATCH v3 2/9] mm: Prefix vma_ to vaddr_to_offset() and offset_to_vaddr()
From: Ravi Bangoria Make function names more meaningful by adding vma_ prefix to them. Signed-off-by: Ravi Bangoria Reviewed-by: Jérôme Glisse --- include/linux/mm.h | 4 ++-- kernel/events/uprobes.c | 14 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index de0cc08..47fd8a9 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2273,13 +2273,13 @@ struct vm_unmapped_area_info { } static inline unsigned long -offset_to_vaddr(struct vm_area_struct *vma, loff_t offset) +vma_offset_to_vaddr(struct vm_area_struct *vma, loff_t offset) { return vma->vm_start + offset - ((loff_t)vma->vm_pgoff << PAGE_SHIFT); } static inline loff_t -vaddr_to_offset(struct vm_area_struct *vma, unsigned long vaddr) +vma_vaddr_to_offset(struct vm_area_struct *vma, unsigned long vaddr) { return ((loff_t)vma->vm_pgoff << PAGE_SHIFT) + (vaddr - vma->vm_start); } diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index bd6f230..535fd39 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -748,7 +748,7 @@ static inline struct map_info *free_map_info(struct map_info *info) curr = info; info->mm = vma->vm_mm; - info->vaddr = offset_to_vaddr(vma, offset); + info->vaddr = vma_offset_to_vaddr(vma, offset); } i_mmap_unlock_read(mapping); @@ -807,7 +807,7 @@ static inline struct map_info *free_map_info(struct map_info *info) goto unlock; if (vma->vm_start > info->vaddr || - vaddr_to_offset(vma, info->vaddr) != uprobe->offset) + vma_vaddr_to_offset(vma, info->vaddr) != uprobe->offset) goto unlock; if (is_register) { @@ -977,7 +977,7 @@ static int unapply_uprobe(struct uprobe *uprobe, struct mm_struct *mm) uprobe->offset >= offset + vma->vm_end - vma->vm_start) continue; - vaddr = offset_to_vaddr(vma, uprobe->offset); + vaddr = vma_offset_to_vaddr(vma, uprobe->offset); err |= remove_breakpoint(uprobe, mm, vaddr); } up_read(>mmap_sem); @@ -1023,7 +1023,7 @@ static void build_probe_list(struct inode *inode, struct uprobe *u; INIT_LIST_HEAD(head); - min = vaddr_to_offset(vma, start); + min = vma_vaddr_to_offset(vma, start); max = min + (end - start) - 1; spin_lock(_treelock); @@ -1076,7 +1076,7 @@ int uprobe_mmap(struct vm_area_struct *vma) list_for_each_entry_safe(uprobe, u, _list, pending_list) { if (!fatal_signal_pending(current) && filter_chain(uprobe, UPROBE_FILTER_MMAP, vma->vm_mm)) { - unsigned long vaddr = offset_to_vaddr(vma, uprobe->offset); + unsigned long vaddr = vma_offset_to_vaddr(vma, uprobe->offset); install_breakpoint(uprobe, vma->vm_mm, vma, vaddr); } put_uprobe(uprobe); @@ -1095,7 +1095,7 @@ int uprobe_mmap(struct vm_area_struct *vma) inode = file_inode(vma->vm_file); - min = vaddr_to_offset(vma, start); + min = vma_vaddr_to_offset(vma, start); max = min + (end - start) - 1; spin_lock(_treelock); @@ -1730,7 +1730,7 @@ static struct uprobe *find_active_uprobe(unsigned long bp_vaddr, int *is_swbp) if (vma && vma->vm_start <= bp_vaddr) { if (valid_vma(vma, false)) { struct inode *inode = file_inode(vma->vm_file); - loff_t offset = vaddr_to_offset(vma, bp_vaddr); + loff_t offset = vma_vaddr_to_offset(vma, bp_vaddr); uprobe = find_uprobe(inode, offset); } -- 1.8.3.1
Re: [PATCH 1/2] parisc: use the asm-generic version for writeX()
Hi Sinan, Thank you for the patch! Yet something to improve: [auto build test ERROR on hp-parisc/for-next] [also build test ERROR on v4.17-rc1 next-20180416] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Sinan-Kaya/parisc-use-the-asm-generic-version-for-writeX/20180417-103119 base: https://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux.git for-next config: parisc-c3000_defconfig (attached as .config) compiler: hppa-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=parisc All errors (new ones prefixed by >>): In file included from arch/parisc/include/asm/hardirq.h:13:0, from include/linux/hardirq.h:9, from arch/parisc/kernel/asm-offsets.c:34: include/linux/irq.h: In function 'irq_reg_writel': >> include/linux/irq.h:1126:3: error: implicit declaration of function >> 'writel'; did you mean 'iowrite8'? [-Werror=implicit-function-declaration] writel(val, gc->reg_base + reg_offset); ^~ iowrite8 cc1: some warnings being treated as errors make[2]: *** [arch/parisc/kernel/asm-offsets.s] Error 1 make[2]: Target '__build' not remade because of errors. make[1]: *** [prepare0] Error 2 make[1]: Target 'prepare' not remade because of errors. make: *** [sub-make] Error 2 vim +1126 include/linux/irq.h 7d828062 Thomas Gleixner 2011-04-03 1109 ebf9ff75 Boris Brezillon 2016-09-13 1110 /* ebf9ff75 Boris Brezillon 2016-09-13 * The irqsave variants are for usage in non interrupt code. Do not use ebf9ff75 Boris Brezillon 2016-09-13 1112 * them in irq_chip callbacks. Use irq_gc_lock() instead. ebf9ff75 Boris Brezillon 2016-09-13 1113 */ ebf9ff75 Boris Brezillon 2016-09-13 1114 #define irq_gc_lock_irqsave(gc, flags) \ ebf9ff75 Boris Brezillon 2016-09-13 1115 raw_spin_lock_irqsave(&(gc)->lock, flags) ebf9ff75 Boris Brezillon 2016-09-13 1116 ebf9ff75 Boris Brezillon 2016-09-13 1117 #define irq_gc_unlock_irqrestore(gc, flags) \ ebf9ff75 Boris Brezillon 2016-09-13 1118 raw_spin_unlock_irqrestore(&(gc)->lock, flags) ebf9ff75 Boris Brezillon 2016-09-13 1119 332fd7c4 Kevin Cernekee 2014-11-06 1120 static inline void irq_reg_writel(struct irq_chip_generic *gc, 332fd7c4 Kevin Cernekee 2014-11-06 1121 u32 val, int reg_offset) 332fd7c4 Kevin Cernekee 2014-11-06 1122 { 2b280376 Kevin Cernekee 2014-11-06 1123 if (gc->reg_writel) 2b280376 Kevin Cernekee 2014-11-06 1124 gc->reg_writel(val, gc->reg_base + reg_offset); 2b280376 Kevin Cernekee 2014-11-06 1125 else 332fd7c4 Kevin Cernekee 2014-11-06 @1126 writel(val, gc->reg_base + reg_offset); 332fd7c4 Kevin Cernekee 2014-11-06 1127 } 332fd7c4 Kevin Cernekee 2014-11-06 1128 :: The code at line 1126 was first introduced by commit :: 332fd7c4fef5f3b166e93decb07fd69eb24f7998 genirq: Generic chip: Change irq_reg_{readl,writel} arguments :: TO: Kevin Cernekee <cerne...@gmail.com> :: CC: Jason Cooper <ja...@lakedaemon.net> --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH 1/2] parisc: use the asm-generic version for writeX()
Hi Sinan, Thank you for the patch! Yet something to improve: [auto build test ERROR on hp-parisc/for-next] [also build test ERROR on v4.17-rc1 next-20180416] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Sinan-Kaya/parisc-use-the-asm-generic-version-for-writeX/20180417-103119 base: https://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux.git for-next config: parisc-c3000_defconfig (attached as .config) compiler: hppa-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=parisc All errors (new ones prefixed by >>): In file included from arch/parisc/include/asm/hardirq.h:13:0, from include/linux/hardirq.h:9, from arch/parisc/kernel/asm-offsets.c:34: include/linux/irq.h: In function 'irq_reg_writel': >> include/linux/irq.h:1126:3: error: implicit declaration of function >> 'writel'; did you mean 'iowrite8'? [-Werror=implicit-function-declaration] writel(val, gc->reg_base + reg_offset); ^~ iowrite8 cc1: some warnings being treated as errors make[2]: *** [arch/parisc/kernel/asm-offsets.s] Error 1 make[2]: Target '__build' not remade because of errors. make[1]: *** [prepare0] Error 2 make[1]: Target 'prepare' not remade because of errors. make: *** [sub-make] Error 2 vim +1126 include/linux/irq.h 7d828062 Thomas Gleixner 2011-04-03 1109 ebf9ff75 Boris Brezillon 2016-09-13 1110 /* ebf9ff75 Boris Brezillon 2016-09-13 * The irqsave variants are for usage in non interrupt code. Do not use ebf9ff75 Boris Brezillon 2016-09-13 1112 * them in irq_chip callbacks. Use irq_gc_lock() instead. ebf9ff75 Boris Brezillon 2016-09-13 1113 */ ebf9ff75 Boris Brezillon 2016-09-13 1114 #define irq_gc_lock_irqsave(gc, flags) \ ebf9ff75 Boris Brezillon 2016-09-13 1115 raw_spin_lock_irqsave(&(gc)->lock, flags) ebf9ff75 Boris Brezillon 2016-09-13 1116 ebf9ff75 Boris Brezillon 2016-09-13 1117 #define irq_gc_unlock_irqrestore(gc, flags) \ ebf9ff75 Boris Brezillon 2016-09-13 1118 raw_spin_unlock_irqrestore(&(gc)->lock, flags) ebf9ff75 Boris Brezillon 2016-09-13 1119 332fd7c4 Kevin Cernekee 2014-11-06 1120 static inline void irq_reg_writel(struct irq_chip_generic *gc, 332fd7c4 Kevin Cernekee 2014-11-06 1121 u32 val, int reg_offset) 332fd7c4 Kevin Cernekee 2014-11-06 1122 { 2b280376 Kevin Cernekee 2014-11-06 1123 if (gc->reg_writel) 2b280376 Kevin Cernekee 2014-11-06 1124 gc->reg_writel(val, gc->reg_base + reg_offset); 2b280376 Kevin Cernekee 2014-11-06 1125 else 332fd7c4 Kevin Cernekee 2014-11-06 @1126 writel(val, gc->reg_base + reg_offset); 332fd7c4 Kevin Cernekee 2014-11-06 1127 } 332fd7c4 Kevin Cernekee 2014-11-06 1128 :: The code at line 1126 was first introduced by commit :: 332fd7c4fef5f3b166e93decb07fd69eb24f7998 genirq: Generic chip: Change irq_reg_{readl,writel} arguments :: TO: Kevin Cernekee :: CC: Jason Cooper --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH v2 3/3] clk: qcom: gdsc: Add support to poll CFG register to check GDSC state
Quoting Taniya Das (2018-04-09 01:41:46) > @@ -64,18 +69,43 @@ static int gdsc_hwctrl(struct gdsc *sc, bool en) > return regmap_update_bits(sc->regmap, sc->gdscr, HW_CONTROL_MASK, > val); > } > > +static int gdsc_is_enabled_by_poll_cfg_reg(struct gdsc *sc, bool en) > +{ > + u32 val; > + int ret; > + > + ret = regmap_read(sc->regmap, sc->gdscr + CFG_GDSCR_OFFSET, ); > + if (ret) > + return ret; > + > + if (en) > + return !!(val & GDSC_POWER_UP_COMPLETE); > + > + return !(val & GDSC_POWER_DOWN_COMPLETE); > +} > + > static int gdsc_poll_status(struct gdsc *sc, unsigned int reg, bool en) > { > ktime_t start; > > start = ktime_get(); > do { > - if (gdsc_is_enabled(sc, reg) == en) > - return 0; > + if (sc->flags & POLL_CFG_GDSCR) { > + if (gdsc_is_enabled_by_poll_cfg_reg(sc, en) == en) > + return 0; > + } else { > + if (gdsc_is_enabled(sc, reg) == en) > + return 0; Ok, I thought you would bury the is_enabled_by_poll_cfg_reg() stuff into gdsc_is_enabled() directly. Because that function is used in one more place than here, in gdsc_init(), to figure out if a GDSC is on at boot time. The sc->gds_hw_ctrl check should be able to get buried into gdsc_is_enabled() as well so that the function doesn't have to take a register at all. > + } > } while (ktime_us_delta(ktime_get(), start) < TIMEOUT_US); > > - if (gdsc_is_enabled(sc, reg) == en) > - return 0; > + if (sc->flags & POLL_CFG_GDSCR) { > + if (gdsc_is_enabled_by_poll_cfg_reg(sc, en) == en) > + return 0; > + } else { > + if (gdsc_is_enabled(sc, reg) == en) > + return 0; > + } And then this duplicate diff wouldn't happen either. > > return -ETIMEDOUT; > } > @@ -254,6 +284,7 @@ static int gdsc_disable(struct generic_pm_domain *domain) > udelay(1); > > reg = sc->gds_hw_ctrl ? sc->gds_hw_ctrl : sc->gdscr; > + This change shouldn't be here? > ret = gdsc_poll_status(sc, reg, true); > if (ret) > return ret;
Re: [PATCH v2 3/3] clk: qcom: gdsc: Add support to poll CFG register to check GDSC state
Quoting Taniya Das (2018-04-09 01:41:46) > @@ -64,18 +69,43 @@ static int gdsc_hwctrl(struct gdsc *sc, bool en) > return regmap_update_bits(sc->regmap, sc->gdscr, HW_CONTROL_MASK, > val); > } > > +static int gdsc_is_enabled_by_poll_cfg_reg(struct gdsc *sc, bool en) > +{ > + u32 val; > + int ret; > + > + ret = regmap_read(sc->regmap, sc->gdscr + CFG_GDSCR_OFFSET, ); > + if (ret) > + return ret; > + > + if (en) > + return !!(val & GDSC_POWER_UP_COMPLETE); > + > + return !(val & GDSC_POWER_DOWN_COMPLETE); > +} > + > static int gdsc_poll_status(struct gdsc *sc, unsigned int reg, bool en) > { > ktime_t start; > > start = ktime_get(); > do { > - if (gdsc_is_enabled(sc, reg) == en) > - return 0; > + if (sc->flags & POLL_CFG_GDSCR) { > + if (gdsc_is_enabled_by_poll_cfg_reg(sc, en) == en) > + return 0; > + } else { > + if (gdsc_is_enabled(sc, reg) == en) > + return 0; Ok, I thought you would bury the is_enabled_by_poll_cfg_reg() stuff into gdsc_is_enabled() directly. Because that function is used in one more place than here, in gdsc_init(), to figure out if a GDSC is on at boot time. The sc->gds_hw_ctrl check should be able to get buried into gdsc_is_enabled() as well so that the function doesn't have to take a register at all. > + } > } while (ktime_us_delta(ktime_get(), start) < TIMEOUT_US); > > - if (gdsc_is_enabled(sc, reg) == en) > - return 0; > + if (sc->flags & POLL_CFG_GDSCR) { > + if (gdsc_is_enabled_by_poll_cfg_reg(sc, en) == en) > + return 0; > + } else { > + if (gdsc_is_enabled(sc, reg) == en) > + return 0; > + } And then this duplicate diff wouldn't happen either. > > return -ETIMEDOUT; > } > @@ -254,6 +284,7 @@ static int gdsc_disable(struct generic_pm_domain *domain) > udelay(1); > > reg = sc->gds_hw_ctrl ? sc->gds_hw_ctrl : sc->gdscr; > + This change shouldn't be here? > ret = gdsc_poll_status(sc, reg, true); > if (ret) > return ret;
linux-next: Tree for Apr 17
Hi all, Changes since 20180416: The bpf tree lost its build failure. The netfilter tree gained a build failure for which I applied a patch. The sound-asoc tree gained a build failure so I used the version from next-20180416. The efi-lock-down tree gained a conflict against the modules tree. Non-merge commits (relative to Linus' tree): 676 705 files changed, 21421 insertions(+), 12310 deletions(-) I have created today's linux-next tree at git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git (patches at http://www.kernel.org/pub/linux/kernel/next/ ). If you are tracking the linux-next tree using git, you should not use "git pull" to do so as that will try to merge the new linux-next release with the old one. You should use "git fetch" and checkout or reset to the new master. You can see which trees have been included by looking in the Next/Trees file in the source. There are also quilt-import.log and merge.log files in the Next directory. Between each merge, the tree was built with a ppc64_defconfig for powerpc, an allmodconfig for x86_64, a multi_v7_defconfig for arm and a native build of tools/perf. After the final fixups (if any), I do an x86_64 modules_install followed by builds for x86_64 allnoconfig, powerpc allnoconfig (32 and 64 bit), ppc44x_defconfig, allyesconfig and pseries_le_defconfig and i386, sparc and sparc64 defconfig. And finally, a simple boot test of the powerpc pseries_le_defconfig kernel in qemu (with and without kvm enabled). Below is a summary of the state of the merge. I am currently merging 258 trees (counting Linus' and 44 trees of bug fix patches pending for the current merge release). Stats about the size of the tree over time can be seen at http://neuling.org/linux-next-size.html . Status of my local build tests will be at http://kisskb.ellerman.id.au/linux-next . If maintainers want to give advice about cross compilers/configs that work, we are always open to add more builds. Thanks to Randy Dunlap for doing many randconfig builds. And to Paul Gortmaker for triage and bug fixes. -- Cheers, Stephen Rothwell $ git checkout master $ git reset --hard stable Merging origin/master (a27fc14219f2 Merge branch 'parisc-4.17-3' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux) Merging fixes/master (147a89bc71e7 Merge tag 'kconfig-v4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild) Merging kbuild-current/fixes (28913ee8191a netfilter: nf_nat_snmp_basic: add correct dependency to Makefile) Merging arc-current/for-curr (661e50bc8532 Linux 4.16-rc4) Merging arm-current/fixes (fe680ca02c1e ARM: replace unnecessary perl with sed and the shell $(( )) operator) Merging arm64-fixes/for-next/fixes (e21da1c99200 arm64: Relax ARM_SMCCC_ARCH_WORKAROUND_1 discovery) Merging m68k-current/for-linus (ecd685580c8f m68k/mac: Remove bogus "FIXME" comment) Merging powerpc-fixes/fixes (81b654c27391 powerpc/64s: Fix CPU_FTRS_ALWAYS vs DT CPU features) Merging sparc/master (17dec0a94915 Merge branch 'userns-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace) Merging fscrypt-current/for-stable (ae64f9bd1d36 Linux 4.15-rc2) Merging net/master (5968a70d7af5 textsearch: fix kernel-doc warnings and add kernel-api section) Merging bpf/master (3a38bb98d9ab bpf/tracing: fix a deadlock in perf_event_detach_bpf_prog) Merging ipsec/master (4b66af2d6356 af_key: Always verify length of provided sadb_key) Merging netfilter/master (2f6adf481527 netfilter: nf_tables: free set name in error path) Merging ipvs/master (f7fb77fc1235 netfilter: nft_compat: check extension hook mask only if set) Merging wireless-drivers/master (77e30e10ee28 iwlwifi: mvm: query regdb for wmm rule if needed) Merging mac80211/master (b5dbc28762fd Merge tag 'kbuild-fixes-v4.16-3' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild) Merging rdma-fixes/for-rc (60cc43fc8884 Linux 4.17-rc1) Merging sound-current/for-linus (7ecb46e9ee9a ALSA: line6: Use correct endpoint type for midi output) Merging pci-current/for-linus (60cc43fc8884 Linux 4.17-rc1) Merging driver-core.current/driver-core-linus (38c23685b273 Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc) Merging tty.current/tty-linus (38c23685b273 Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc) Merging usb.current/usb-linus (38c23685b273 Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc) Merging usb-gadget-fixes/fixes (c6ba5084ce0d usb: gadget: udc: renesas_usb3: add binging for r8a77965) Merging usb-serial-fixes/usb-linus (470b5d6f0cf4 USB: serial: ftdi_sio: use jtag quirk for Arrow USB Blaster) Merging usb-chipidea-fixes/ci-for-usb-stable (964728f9f407 USB: chipidea: msm: fix ulpi-node lookup) Merging phy/fixes (59fba0869aca phy
linux-next: Tree for Apr 17
Hi all, Changes since 20180416: The bpf tree lost its build failure. The netfilter tree gained a build failure for which I applied a patch. The sound-asoc tree gained a build failure so I used the version from next-20180416. The efi-lock-down tree gained a conflict against the modules tree. Non-merge commits (relative to Linus' tree): 676 705 files changed, 21421 insertions(+), 12310 deletions(-) I have created today's linux-next tree at git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git (patches at http://www.kernel.org/pub/linux/kernel/next/ ). If you are tracking the linux-next tree using git, you should not use "git pull" to do so as that will try to merge the new linux-next release with the old one. You should use "git fetch" and checkout or reset to the new master. You can see which trees have been included by looking in the Next/Trees file in the source. There are also quilt-import.log and merge.log files in the Next directory. Between each merge, the tree was built with a ppc64_defconfig for powerpc, an allmodconfig for x86_64, a multi_v7_defconfig for arm and a native build of tools/perf. After the final fixups (if any), I do an x86_64 modules_install followed by builds for x86_64 allnoconfig, powerpc allnoconfig (32 and 64 bit), ppc44x_defconfig, allyesconfig and pseries_le_defconfig and i386, sparc and sparc64 defconfig. And finally, a simple boot test of the powerpc pseries_le_defconfig kernel in qemu (with and without kvm enabled). Below is a summary of the state of the merge. I am currently merging 258 trees (counting Linus' and 44 trees of bug fix patches pending for the current merge release). Stats about the size of the tree over time can be seen at http://neuling.org/linux-next-size.html . Status of my local build tests will be at http://kisskb.ellerman.id.au/linux-next . If maintainers want to give advice about cross compilers/configs that work, we are always open to add more builds. Thanks to Randy Dunlap for doing many randconfig builds. And to Paul Gortmaker for triage and bug fixes. -- Cheers, Stephen Rothwell $ git checkout master $ git reset --hard stable Merging origin/master (a27fc14219f2 Merge branch 'parisc-4.17-3' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux) Merging fixes/master (147a89bc71e7 Merge tag 'kconfig-v4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild) Merging kbuild-current/fixes (28913ee8191a netfilter: nf_nat_snmp_basic: add correct dependency to Makefile) Merging arc-current/for-curr (661e50bc8532 Linux 4.16-rc4) Merging arm-current/fixes (fe680ca02c1e ARM: replace unnecessary perl with sed and the shell $(( )) operator) Merging arm64-fixes/for-next/fixes (e21da1c99200 arm64: Relax ARM_SMCCC_ARCH_WORKAROUND_1 discovery) Merging m68k-current/for-linus (ecd685580c8f m68k/mac: Remove bogus "FIXME" comment) Merging powerpc-fixes/fixes (81b654c27391 powerpc/64s: Fix CPU_FTRS_ALWAYS vs DT CPU features) Merging sparc/master (17dec0a94915 Merge branch 'userns-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace) Merging fscrypt-current/for-stable (ae64f9bd1d36 Linux 4.15-rc2) Merging net/master (5968a70d7af5 textsearch: fix kernel-doc warnings and add kernel-api section) Merging bpf/master (3a38bb98d9ab bpf/tracing: fix a deadlock in perf_event_detach_bpf_prog) Merging ipsec/master (4b66af2d6356 af_key: Always verify length of provided sadb_key) Merging netfilter/master (2f6adf481527 netfilter: nf_tables: free set name in error path) Merging ipvs/master (f7fb77fc1235 netfilter: nft_compat: check extension hook mask only if set) Merging wireless-drivers/master (77e30e10ee28 iwlwifi: mvm: query regdb for wmm rule if needed) Merging mac80211/master (b5dbc28762fd Merge tag 'kbuild-fixes-v4.16-3' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild) Merging rdma-fixes/for-rc (60cc43fc8884 Linux 4.17-rc1) Merging sound-current/for-linus (7ecb46e9ee9a ALSA: line6: Use correct endpoint type for midi output) Merging pci-current/for-linus (60cc43fc8884 Linux 4.17-rc1) Merging driver-core.current/driver-core-linus (38c23685b273 Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc) Merging tty.current/tty-linus (38c23685b273 Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc) Merging usb.current/usb-linus (38c23685b273 Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc) Merging usb-gadget-fixes/fixes (c6ba5084ce0d usb: gadget: udc: renesas_usb3: add binging for r8a77965) Merging usb-serial-fixes/usb-linus (470b5d6f0cf4 USB: serial: ftdi_sio: use jtag quirk for Arrow USB Blaster) Merging usb-chipidea-fixes/ci-for-usb-stable (964728f9f407 USB: chipidea: msm: fix ulpi-node lookup) Merging phy/fixes (59fba0869aca phy
[PATCH RESEND net-next] net/ncsi: Refactor MAC, VLAN filters
The NCSI driver defines a generic ncsi_channel_filter struct that can be used to store arbitrarily formatted filters, and several generic methods of accessing data stored in such a filter. However in both the driver and as defined in the NCSI specification there are only two actual filters: VLAN ID filters and MAC address filters. The splitting of the MAC filter into unicast, multicast, and mixed is also technically not necessary as these are stored in the same location in hardware. To save complexity, particularly in the set up and accessing of these generic filters, remove them in favour of two specific structs. These can be acted on directly and do not need several generic helper functions to use. This also fixes a memory error found by KASAN on ARM32 (which is not upstream yet), where response handlers accessing a filter's data field could write past allocated memory. [ 114.926512] == [ 114.933861] BUG: KASAN: slab-out-of-bounds in ncsi_configure_channel+0x4b8/0xc58 [ 114.941304] Read of size 2 at addr 94888558 by task kworker/0:2/546 [ 114.947593] [ 114.949146] CPU: 0 PID: 546 Comm: kworker/0:2 Not tainted 4.16.0-rc6-00119-ge156398bfcad #13 ... [ 115.170233] The buggy address belongs to the object at 94888540 [ 115.170233] which belongs to the cache kmalloc-32 of size 32 [ 115.181917] The buggy address is located 24 bytes inside of [ 115.181917] 32-byte region [94888540, 94888560) [ 115.192115] The buggy address belongs to the page: [ 115.196943] page:9eeac100 count:1 mapcount:0 mapping:94888000 index:0x94888fc1 [ 115.204200] flags: 0x100(slab) [ 115.207330] raw: 0100 94888000 94888fc1 003f 0001 9eea2014 9eecaa74 96c003e0 [ 115.215444] page dumped because: kasan: bad access detected [ 115.221036] [ 115.222544] Memory state around the buggy address: [ 115.227384] 94888400: fb fb fb fb fc fc fc fc 04 fc fc fc fc fc fc fc [ 115.233959] 94888480: 00 00 00 fc fc fc fc fc 00 04 fc fc fc fc fc fc [ 115.240529] >94888500: 00 00 04 fc fc fc fc fc 00 00 04 fc fc fc fc fc [ 115.247077] ^ [ 115.252523] 94888580: 00 04 fc fc fc fc fc fc 06 fc fc fc fc fc fc fc [ 115.259093] 94888600: 00 00 06 fc fc fc fc fc 00 00 04 fc fc fc fc fc [ 115.265639] == Reported-by: Joel StanleySigned-off-by: Samuel Mendoza-Jonas --- net/ncsi/internal.h | 34 +++--- net/ncsi/ncsi-manage.c | 226 +--- net/ncsi/ncsi-netlink.c | 20 ++-- net/ncsi/ncsi-rsp.c | 178 +-- 4 files changed, 147 insertions(+), 311 deletions(-) diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h index 8da84312cd3b..8055e3965cef 100644 --- a/net/ncsi/internal.h +++ b/net/ncsi/internal.h @@ -68,15 +68,6 @@ enum { NCSI_MODE_MAX }; -enum { - NCSI_FILTER_BASE= 0, - NCSI_FILTER_VLAN= 0, - NCSI_FILTER_UC, - NCSI_FILTER_MC, - NCSI_FILTER_MIXED, - NCSI_FILTER_MAX -}; - struct ncsi_channel_version { u32 version;/* Supported BCD encoded NCSI version */ u32 alpha2; /* Supported BCD encoded NCSI version */ @@ -98,11 +89,18 @@ struct ncsi_channel_mode { u32 data[8];/* Data entries*/ }; -struct ncsi_channel_filter { - u32 index; /* Index of channel filters */ - u32 total; /* Total entries in the filter table */ - u64 bitmap; /* Bitmap of valid entries */ - u32 data[]; /* Data for the valid entries*/ +struct ncsi_channel_mac_filter { + u8 n_uc; + u8 n_mc; + u8 n_mixed; + u64 bitmap; + unsigned char *addrs; +}; + +struct ncsi_channel_vlan_filter { + u8 n_vids; + u64 bitmap; + u16 *vids; }; struct ncsi_channel_stats { @@ -186,7 +184,9 @@ struct ncsi_channel { struct ncsi_channel_version version; struct ncsi_channel_cap caps[NCSI_CAP_MAX]; struct ncsi_channel_modemodes[NCSI_MODE_MAX]; - struct ncsi_channel_filter *filters[NCSI_FILTER_MAX]; + /* Filtering Settings */ + struct ncsi_channel_mac_filter mac_filter; + struct ncsi_channel_vlan_filter vlan_filter; struct ncsi_channel_stats stats; struct { struct timer_list timer; @@ -320,10 +320,6 @@ extern spinlock_t ncsi_dev_lock; list_for_each_entry_rcu(nc, >channels, node) /* Resources */ -u32 *ncsi_get_filter(struct ncsi_channel *nc, int table, int index); -int ncsi_find_filter(struct ncsi_channel *nc, int table, void *data); -int ncsi_add_filter(struct ncsi_channel *nc, int table, void *data); -int ncsi_remove_filter(struct ncsi_channel *nc, int table, int index); void ncsi_start_channel_monitor(struct
[PATCH RESEND net-next] net/ncsi: Refactor MAC, VLAN filters
The NCSI driver defines a generic ncsi_channel_filter struct that can be used to store arbitrarily formatted filters, and several generic methods of accessing data stored in such a filter. However in both the driver and as defined in the NCSI specification there are only two actual filters: VLAN ID filters and MAC address filters. The splitting of the MAC filter into unicast, multicast, and mixed is also technically not necessary as these are stored in the same location in hardware. To save complexity, particularly in the set up and accessing of these generic filters, remove them in favour of two specific structs. These can be acted on directly and do not need several generic helper functions to use. This also fixes a memory error found by KASAN on ARM32 (which is not upstream yet), where response handlers accessing a filter's data field could write past allocated memory. [ 114.926512] == [ 114.933861] BUG: KASAN: slab-out-of-bounds in ncsi_configure_channel+0x4b8/0xc58 [ 114.941304] Read of size 2 at addr 94888558 by task kworker/0:2/546 [ 114.947593] [ 114.949146] CPU: 0 PID: 546 Comm: kworker/0:2 Not tainted 4.16.0-rc6-00119-ge156398bfcad #13 ... [ 115.170233] The buggy address belongs to the object at 94888540 [ 115.170233] which belongs to the cache kmalloc-32 of size 32 [ 115.181917] The buggy address is located 24 bytes inside of [ 115.181917] 32-byte region [94888540, 94888560) [ 115.192115] The buggy address belongs to the page: [ 115.196943] page:9eeac100 count:1 mapcount:0 mapping:94888000 index:0x94888fc1 [ 115.204200] flags: 0x100(slab) [ 115.207330] raw: 0100 94888000 94888fc1 003f 0001 9eea2014 9eecaa74 96c003e0 [ 115.215444] page dumped because: kasan: bad access detected [ 115.221036] [ 115.222544] Memory state around the buggy address: [ 115.227384] 94888400: fb fb fb fb fc fc fc fc 04 fc fc fc fc fc fc fc [ 115.233959] 94888480: 00 00 00 fc fc fc fc fc 00 04 fc fc fc fc fc fc [ 115.240529] >94888500: 00 00 04 fc fc fc fc fc 00 00 04 fc fc fc fc fc [ 115.247077] ^ [ 115.252523] 94888580: 00 04 fc fc fc fc fc fc 06 fc fc fc fc fc fc fc [ 115.259093] 94888600: 00 00 06 fc fc fc fc fc 00 00 04 fc fc fc fc fc [ 115.265639] == Reported-by: Joel Stanley Signed-off-by: Samuel Mendoza-Jonas --- net/ncsi/internal.h | 34 +++--- net/ncsi/ncsi-manage.c | 226 +--- net/ncsi/ncsi-netlink.c | 20 ++-- net/ncsi/ncsi-rsp.c | 178 +-- 4 files changed, 147 insertions(+), 311 deletions(-) diff --git a/net/ncsi/internal.h b/net/ncsi/internal.h index 8da84312cd3b..8055e3965cef 100644 --- a/net/ncsi/internal.h +++ b/net/ncsi/internal.h @@ -68,15 +68,6 @@ enum { NCSI_MODE_MAX }; -enum { - NCSI_FILTER_BASE= 0, - NCSI_FILTER_VLAN= 0, - NCSI_FILTER_UC, - NCSI_FILTER_MC, - NCSI_FILTER_MIXED, - NCSI_FILTER_MAX -}; - struct ncsi_channel_version { u32 version;/* Supported BCD encoded NCSI version */ u32 alpha2; /* Supported BCD encoded NCSI version */ @@ -98,11 +89,18 @@ struct ncsi_channel_mode { u32 data[8];/* Data entries*/ }; -struct ncsi_channel_filter { - u32 index; /* Index of channel filters */ - u32 total; /* Total entries in the filter table */ - u64 bitmap; /* Bitmap of valid entries */ - u32 data[]; /* Data for the valid entries*/ +struct ncsi_channel_mac_filter { + u8 n_uc; + u8 n_mc; + u8 n_mixed; + u64 bitmap; + unsigned char *addrs; +}; + +struct ncsi_channel_vlan_filter { + u8 n_vids; + u64 bitmap; + u16 *vids; }; struct ncsi_channel_stats { @@ -186,7 +184,9 @@ struct ncsi_channel { struct ncsi_channel_version version; struct ncsi_channel_cap caps[NCSI_CAP_MAX]; struct ncsi_channel_modemodes[NCSI_MODE_MAX]; - struct ncsi_channel_filter *filters[NCSI_FILTER_MAX]; + /* Filtering Settings */ + struct ncsi_channel_mac_filter mac_filter; + struct ncsi_channel_vlan_filter vlan_filter; struct ncsi_channel_stats stats; struct { struct timer_list timer; @@ -320,10 +320,6 @@ extern spinlock_t ncsi_dev_lock; list_for_each_entry_rcu(nc, >channels, node) /* Resources */ -u32 *ncsi_get_filter(struct ncsi_channel *nc, int table, int index); -int ncsi_find_filter(struct ncsi_channel *nc, int table, void *data); -int ncsi_add_filter(struct ncsi_channel *nc, int table, void *data); -int ncsi_remove_filter(struct ncsi_channel *nc, int table, int index); void ncsi_start_channel_monitor(struct ncsi_channel *nc); void
Re: [PATCH 2/7] powerpc: Use TIDR CPU feature to control TIDR allocation
On 17/04/18 12:09, Alastair D'Silva wrote: From: Alastair D'SilvaSwitch the use of TIDR on it's CPU feature, rather than assuming it is available based on architecture. Signed-off-by: Alastair D'Silva There's a use of TIDR in restore_sprs() that's behind the ARCH_300 flag as well, ideally it should never trigger in the !P9_TIDR case, but you might want to update that too for clarity? --- arch/powerpc/kernel/process.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 1237f13fed51..a3e0a3e06d5a 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1570,7 +1570,7 @@ void clear_thread_tidr(struct task_struct *t) if (!t->thread.tidr) return; - if (!cpu_has_feature(CPU_FTR_ARCH_300)) { + if (!cpu_has_feature(CPU_FTR_P9_TIDR)) { WARN_ON_ONCE(1); return; } @@ -1593,7 +1593,7 @@ int set_thread_tidr(struct task_struct *t) { int rc; - if (!cpu_has_feature(CPU_FTR_ARCH_300)) + if (!cpu_has_feature(CPU_FTR_P9_TIDR)) return -EINVAL; if (t != current) -- Andrew Donnellan OzLabs, ADL Canberra andrew.donnel...@au1.ibm.com IBM Australia Limited
Re: [PATCH 2/7] powerpc: Use TIDR CPU feature to control TIDR allocation
On 17/04/18 12:09, Alastair D'Silva wrote: From: Alastair D'Silva Switch the use of TIDR on it's CPU feature, rather than assuming it is available based on architecture. Signed-off-by: Alastair D'Silva There's a use of TIDR in restore_sprs() that's behind the ARCH_300 flag as well, ideally it should never trigger in the !P9_TIDR case, but you might want to update that too for clarity? --- arch/powerpc/kernel/process.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 1237f13fed51..a3e0a3e06d5a 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1570,7 +1570,7 @@ void clear_thread_tidr(struct task_struct *t) if (!t->thread.tidr) return; - if (!cpu_has_feature(CPU_FTR_ARCH_300)) { + if (!cpu_has_feature(CPU_FTR_P9_TIDR)) { WARN_ON_ONCE(1); return; } @@ -1593,7 +1593,7 @@ int set_thread_tidr(struct task_struct *t) { int rc; - if (!cpu_has_feature(CPU_FTR_ARCH_300)) + if (!cpu_has_feature(CPU_FTR_P9_TIDR)) return -EINVAL; if (t != current) -- Andrew Donnellan OzLabs, ADL Canberra andrew.donnel...@au1.ibm.com IBM Australia Limited
[PATCH v2 3/3] perf/buildid-cache: Support --purge-all option
User can remove files from cache using --remove/--purge options but both needs list of files as an argument. It's not convenient when you want to flush out entire cache. Add an option to purge all files from cache. Ex, # perf buildid-cache -l 8a86ef73e44067bca52cc3f6cd3e5446c783391c /tmp/a.out ebe71fdcf4b366518cc154d570a33cd461a51c36 /tmp/a.out.1 # perf buildid-cache -P -v Removing /tmp/a.out (8a86ef73e44067bca52cc3f6cd3e5446c783391c): Ok Removing /tmp/a.out.1 (ebe71fdcf4b366518cc154d570a33cd461a51c36): Ok Purged all: Ok Signed-off-by: Ravi Bangoria--- tools/perf/Documentation/perf-buildid-cache.txt | 3 +++ tools/perf/builtin-buildid-cache.c | 36 - 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-buildid-cache.txt b/tools/perf/Documentation/perf-buildid-cache.txt index 3f285ba6e1f9..f6de0952ff3c 100644 --- a/tools/perf/Documentation/perf-buildid-cache.txt +++ b/tools/perf/Documentation/perf-buildid-cache.txt @@ -48,6 +48,9 @@ OPTIONS --purge=:: Purge all cached binaries including older caches which have specified path from the cache. +-P:: +--purge-all:: + Purge all cached binaries. This will flush out entire cache. -M:: --missing=:: List missing build ids in the cache for the specified file. diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index fd0a08661b42..d11226f76fbc 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -240,6 +240,34 @@ static int build_id_cache__purge_path(const char *pathname, struct nsinfo *nsi) return err; } +static int build_id_cache__purge_all(void) +{ + struct strlist *list; + struct str_node *pos; + int err; + char *buf; + + list = build_id_cache__list_all(false); + if (!list) { + pr_debug("Failed to get buildids: -%d\n", errno); + return -EINVAL; + } + + strlist__for_each_entry(pos, list) { + buf = build_id_cache__origname(pos->s); + err = build_id_cache__remove_s(pos->s); + pr_debug("Removing %s (%s): %s\n", buf, pos->s, +err ? "FAIL" : "Ok"); + free(buf); + if (err) + break; + } + strlist__delete(list); + + pr_debug("Purged all: %s\n", err ? "FAIL" : "Ok"); + return err; +} + static bool dso__missing_buildid_cache(struct dso *dso, int parm __maybe_unused) { char filename[PATH_MAX]; @@ -327,6 +355,7 @@ int cmd_buildid_cache(int argc, const char **argv) bool force = false; bool list_files = false; bool opts_flag = false; + bool purge_all = false; char const *add_name_list_str = NULL, *remove_name_list_str = NULL, *purge_name_list_str = NULL, @@ -350,6 +379,7 @@ int cmd_buildid_cache(int argc, const char **argv) "file(s) to remove"), OPT_STRING('p', "purge", _name_list_str, "file list", "file(s) to remove (remove old caches too)"), + OPT_BOOLEAN('P', "purge-all", _all, "purge all cached files"), OPT_BOOLEAN('l', "list", _files, "list all cached files"), OPT_STRING('M', "missing", _filename, "file", "to find missing build ids in the cache"), @@ -370,7 +400,8 @@ int cmd_buildid_cache(int argc, const char **argv) opts_flag = add_name_list_str || kcore_filename || remove_name_list_str || purge_name_list_str || - missing_filename || update_name_list_str; + missing_filename || update_name_list_str || + purge_all; if (argc || !(list_files || opts_flag)) usage_with_options(buildid_cache_usage, buildid_cache_options); @@ -457,6 +488,9 @@ int cmd_buildid_cache(int argc, const char **argv) } } + if (purge_all) + ret = build_id_cache__purge_all(); + if (missing_filename) ret = build_id_cache__fprintf_missing(session, stdout); -- 2.14.3
[PATCH v2 3/3] perf/buildid-cache: Support --purge-all option
User can remove files from cache using --remove/--purge options but both needs list of files as an argument. It's not convenient when you want to flush out entire cache. Add an option to purge all files from cache. Ex, # perf buildid-cache -l 8a86ef73e44067bca52cc3f6cd3e5446c783391c /tmp/a.out ebe71fdcf4b366518cc154d570a33cd461a51c36 /tmp/a.out.1 # perf buildid-cache -P -v Removing /tmp/a.out (8a86ef73e44067bca52cc3f6cd3e5446c783391c): Ok Removing /tmp/a.out.1 (ebe71fdcf4b366518cc154d570a33cd461a51c36): Ok Purged all: Ok Signed-off-by: Ravi Bangoria --- tools/perf/Documentation/perf-buildid-cache.txt | 3 +++ tools/perf/builtin-buildid-cache.c | 36 - 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-buildid-cache.txt b/tools/perf/Documentation/perf-buildid-cache.txt index 3f285ba6e1f9..f6de0952ff3c 100644 --- a/tools/perf/Documentation/perf-buildid-cache.txt +++ b/tools/perf/Documentation/perf-buildid-cache.txt @@ -48,6 +48,9 @@ OPTIONS --purge=:: Purge all cached binaries including older caches which have specified path from the cache. +-P:: +--purge-all:: + Purge all cached binaries. This will flush out entire cache. -M:: --missing=:: List missing build ids in the cache for the specified file. diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index fd0a08661b42..d11226f76fbc 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -240,6 +240,34 @@ static int build_id_cache__purge_path(const char *pathname, struct nsinfo *nsi) return err; } +static int build_id_cache__purge_all(void) +{ + struct strlist *list; + struct str_node *pos; + int err; + char *buf; + + list = build_id_cache__list_all(false); + if (!list) { + pr_debug("Failed to get buildids: -%d\n", errno); + return -EINVAL; + } + + strlist__for_each_entry(pos, list) { + buf = build_id_cache__origname(pos->s); + err = build_id_cache__remove_s(pos->s); + pr_debug("Removing %s (%s): %s\n", buf, pos->s, +err ? "FAIL" : "Ok"); + free(buf); + if (err) + break; + } + strlist__delete(list); + + pr_debug("Purged all: %s\n", err ? "FAIL" : "Ok"); + return err; +} + static bool dso__missing_buildid_cache(struct dso *dso, int parm __maybe_unused) { char filename[PATH_MAX]; @@ -327,6 +355,7 @@ int cmd_buildid_cache(int argc, const char **argv) bool force = false; bool list_files = false; bool opts_flag = false; + bool purge_all = false; char const *add_name_list_str = NULL, *remove_name_list_str = NULL, *purge_name_list_str = NULL, @@ -350,6 +379,7 @@ int cmd_buildid_cache(int argc, const char **argv) "file(s) to remove"), OPT_STRING('p', "purge", _name_list_str, "file list", "file(s) to remove (remove old caches too)"), + OPT_BOOLEAN('P', "purge-all", _all, "purge all cached files"), OPT_BOOLEAN('l', "list", _files, "list all cached files"), OPT_STRING('M', "missing", _filename, "file", "to find missing build ids in the cache"), @@ -370,7 +400,8 @@ int cmd_buildid_cache(int argc, const char **argv) opts_flag = add_name_list_str || kcore_filename || remove_name_list_str || purge_name_list_str || - missing_filename || update_name_list_str; + missing_filename || update_name_list_str || + purge_all; if (argc || !(list_files || opts_flag)) usage_with_options(buildid_cache_usage, buildid_cache_options); @@ -457,6 +488,9 @@ int cmd_buildid_cache(int argc, const char **argv) } } + if (purge_all) + ret = build_id_cache__purge_all(); + if (missing_filename) ret = build_id_cache__fprintf_missing(session, stdout); -- 2.14.3
[PATCH v2 1/3] tools/parse-options: Add '\n' at the end of error messages
Few error messages does not have '\n' at the end and thus next prompt gets printed in the same line. Ex, linux~$ perf buildid-cache -verbose --add ./a.out Error: did you mean `--verbose` (with two dashes ?)linux~$ Fix it. Signed-off-by: Ravi BangoriaReviewed-by: Masami Hiramatsu --- tools/lib/subcmd/parse-options.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/lib/subcmd/parse-options.c b/tools/lib/subcmd/parse-options.c index f6a1babcbac4..cb7154eccbdc 100644 --- a/tools/lib/subcmd/parse-options.c +++ b/tools/lib/subcmd/parse-options.c @@ -433,7 +433,7 @@ static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg, if (ambiguous_option) { fprintf(stderr, -" Error: Ambiguous option: %s (could be --%s%s or --%s%s)", +" Error: Ambiguous option: %s (could be --%s%s or --%s%s)\n", arg, (ambiguous_flags & OPT_UNSET) ? "no-" : "", ambiguous_option->long_name, @@ -458,7 +458,7 @@ static void check_typos(const char *arg, const struct option *options) return; if (strstarts(arg, "no-")) { - fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg); + fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)\n", arg); exit(129); } @@ -466,7 +466,7 @@ static void check_typos(const char *arg, const struct option *options) if (!options->long_name) continue; if (strstarts(options->long_name, arg)) { - fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg); + fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)\n", arg); exit(129); } } -- 2.14.3
[PATCH v2 0/3] perf/buildid-cache: Add --list and --purge-all options
First patch is a trivial error message fix. Second and third adds new options --list and --purge-all to 'buildid-cache' subcommand. v2 changes: - [PATCH v2 2/3] Display optput of 'perf buildid-cache -l' same as 'perf buildid-list'. - [PATCH v2 2/3] Other minor changes as suggested by Jiri. v1 can be found at: https://lkml.org/lkml/2018/4/9/295 Ravi Bangoria (3): tools/parse-options: Add '\n' at the end of error messages perf/buildid-cache: Support --list option perf/buildid-cache: Support --purge-all option tools/lib/subcmd/parse-options.c| 6 +- tools/perf/Documentation/perf-buildid-cache.txt | 7 ++- tools/perf/builtin-buildid-cache.c | 77 - 3 files changed, 83 insertions(+), 7 deletions(-) -- 2.14.3
[PATCH v2 1/3] tools/parse-options: Add '\n' at the end of error messages
Few error messages does not have '\n' at the end and thus next prompt gets printed in the same line. Ex, linux~$ perf buildid-cache -verbose --add ./a.out Error: did you mean `--verbose` (with two dashes ?)linux~$ Fix it. Signed-off-by: Ravi Bangoria Reviewed-by: Masami Hiramatsu --- tools/lib/subcmd/parse-options.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/lib/subcmd/parse-options.c b/tools/lib/subcmd/parse-options.c index f6a1babcbac4..cb7154eccbdc 100644 --- a/tools/lib/subcmd/parse-options.c +++ b/tools/lib/subcmd/parse-options.c @@ -433,7 +433,7 @@ static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg, if (ambiguous_option) { fprintf(stderr, -" Error: Ambiguous option: %s (could be --%s%s or --%s%s)", +" Error: Ambiguous option: %s (could be --%s%s or --%s%s)\n", arg, (ambiguous_flags & OPT_UNSET) ? "no-" : "", ambiguous_option->long_name, @@ -458,7 +458,7 @@ static void check_typos(const char *arg, const struct option *options) return; if (strstarts(arg, "no-")) { - fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg); + fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)\n", arg); exit(129); } @@ -466,7 +466,7 @@ static void check_typos(const char *arg, const struct option *options) if (!options->long_name) continue; if (strstarts(options->long_name, arg)) { - fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg); + fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)\n", arg); exit(129); } } -- 2.14.3
[PATCH v2 0/3] perf/buildid-cache: Add --list and --purge-all options
First patch is a trivial error message fix. Second and third adds new options --list and --purge-all to 'buildid-cache' subcommand. v2 changes: - [PATCH v2 2/3] Display optput of 'perf buildid-cache -l' same as 'perf buildid-list'. - [PATCH v2 2/3] Other minor changes as suggested by Jiri. v1 can be found at: https://lkml.org/lkml/2018/4/9/295 Ravi Bangoria (3): tools/parse-options: Add '\n' at the end of error messages perf/buildid-cache: Support --list option perf/buildid-cache: Support --purge-all option tools/lib/subcmd/parse-options.c| 6 +- tools/perf/Documentation/perf-buildid-cache.txt | 7 ++- tools/perf/builtin-buildid-cache.c | 77 - 3 files changed, 83 insertions(+), 7 deletions(-) -- 2.14.3
[PATCH v2 2/3] perf/buildid-cache: Support --list option
Perf buildid-cache allows to add/remove files into cache but there is no option to list all cached files. Add --list option to list all _valid_ cached files. Ex, # perf buildid-cache --add /tmp/a.out # perf buildid-cache -l 8a86ef73e44067bca52cc3f6cd3e5446c783391c /tmp/a.out Signed-off-by: Ravi Bangoria--- tools/perf/Documentation/perf-buildid-cache.txt | 4 ++- tools/perf/builtin-buildid-cache.c | 43 +++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/tools/perf/Documentation/perf-buildid-cache.txt b/tools/perf/Documentation/perf-buildid-cache.txt index 73c2650bd0db..3f285ba6e1f9 100644 --- a/tools/perf/Documentation/perf-buildid-cache.txt +++ b/tools/perf/Documentation/perf-buildid-cache.txt @@ -59,7 +59,9 @@ OPTIONS exactly same build-id, that is replaced by new one. It can be used to update kallsyms and kernel dso to vmlinux in order to support annotation. - +-l:: +--list:: + List all valid binaries from cache. -v:: --verbose:: Be more verbose. diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index 41db2cba77eb..fd0a08661b42 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -25,6 +25,7 @@ #include "util/session.h" #include "util/symbol.h" #include "util/time-utils.h" +#include "util/probe-file.h" static int build_id_cache__kcore_buildid(const char *proc_dir, char *sbuildid) { @@ -297,6 +298,26 @@ static int build_id_cache__update_file(const char *filename, struct nsinfo *nsi) return err; } +static int build_id_cache__show_all(void) +{ + struct strlist *bidlist; + struct str_node *nd; + char *buf; + + bidlist = build_id_cache__list_all(true); + if (!bidlist) { + pr_debug("Failed to get buildids: -%d\n", errno); + return -1; + } + strlist__for_each_entry(nd, bidlist) { + buf = build_id_cache__origname(nd->s); + fprintf(stdout, "%s %s\n", nd->s, buf); + free(buf); + } + strlist__delete(bidlist); + return 0; +} + int cmd_buildid_cache(int argc, const char **argv) { struct strlist *list; @@ -304,6 +325,8 @@ int cmd_buildid_cache(int argc, const char **argv) int ret = 0; int ns_id = -1; bool force = false; + bool list_files = false; + bool opts_flag = false; char const *add_name_list_str = NULL, *remove_name_list_str = NULL, *purge_name_list_str = NULL, @@ -327,6 +350,7 @@ int cmd_buildid_cache(int argc, const char **argv) "file(s) to remove"), OPT_STRING('p', "purge", _name_list_str, "file list", "file(s) to remove (remove old caches too)"), + OPT_BOOLEAN('l', "list", _files, "list all cached files"), OPT_STRING('M', "missing", _filename, "file", "to find missing build ids in the cache"), OPT_BOOLEAN('f', "force", , "don't complain, do it"), @@ -344,11 +368,19 @@ int cmd_buildid_cache(int argc, const char **argv) argc = parse_options(argc, argv, buildid_cache_options, buildid_cache_usage, 0); - if (argc || (!add_name_list_str && !kcore_filename && -!remove_name_list_str && !purge_name_list_str && -!missing_filename && !update_name_list_str)) + opts_flag = add_name_list_str || kcore_filename || + remove_name_list_str || purge_name_list_str || + missing_filename || update_name_list_str; + + if (argc || !(list_files || opts_flag)) usage_with_options(buildid_cache_usage, buildid_cache_options); + /* -l is exclusive. It can not be used with other options. */ + if (list_files && opts_flag) { + usage_with_options_msg(buildid_cache_usage, + buildid_cache_options, "-l is exclusive.\n"); + } + if (ns_id > 0) nsi = nsinfo__new(ns_id); @@ -366,6 +398,11 @@ int cmd_buildid_cache(int argc, const char **argv) setup_pager(); + if (list_files) { + ret = build_id_cache__show_all(); + goto out; + } + if (add_name_list_str) { list = strlist__new(add_name_list_str, NULL); if (list) { -- 2.14.3
[PATCH v2 2/3] perf/buildid-cache: Support --list option
Perf buildid-cache allows to add/remove files into cache but there is no option to list all cached files. Add --list option to list all _valid_ cached files. Ex, # perf buildid-cache --add /tmp/a.out # perf buildid-cache -l 8a86ef73e44067bca52cc3f6cd3e5446c783391c /tmp/a.out Signed-off-by: Ravi Bangoria --- tools/perf/Documentation/perf-buildid-cache.txt | 4 ++- tools/perf/builtin-buildid-cache.c | 43 +++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/tools/perf/Documentation/perf-buildid-cache.txt b/tools/perf/Documentation/perf-buildid-cache.txt index 73c2650bd0db..3f285ba6e1f9 100644 --- a/tools/perf/Documentation/perf-buildid-cache.txt +++ b/tools/perf/Documentation/perf-buildid-cache.txt @@ -59,7 +59,9 @@ OPTIONS exactly same build-id, that is replaced by new one. It can be used to update kallsyms and kernel dso to vmlinux in order to support annotation. - +-l:: +--list:: + List all valid binaries from cache. -v:: --verbose:: Be more verbose. diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index 41db2cba77eb..fd0a08661b42 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -25,6 +25,7 @@ #include "util/session.h" #include "util/symbol.h" #include "util/time-utils.h" +#include "util/probe-file.h" static int build_id_cache__kcore_buildid(const char *proc_dir, char *sbuildid) { @@ -297,6 +298,26 @@ static int build_id_cache__update_file(const char *filename, struct nsinfo *nsi) return err; } +static int build_id_cache__show_all(void) +{ + struct strlist *bidlist; + struct str_node *nd; + char *buf; + + bidlist = build_id_cache__list_all(true); + if (!bidlist) { + pr_debug("Failed to get buildids: -%d\n", errno); + return -1; + } + strlist__for_each_entry(nd, bidlist) { + buf = build_id_cache__origname(nd->s); + fprintf(stdout, "%s %s\n", nd->s, buf); + free(buf); + } + strlist__delete(bidlist); + return 0; +} + int cmd_buildid_cache(int argc, const char **argv) { struct strlist *list; @@ -304,6 +325,8 @@ int cmd_buildid_cache(int argc, const char **argv) int ret = 0; int ns_id = -1; bool force = false; + bool list_files = false; + bool opts_flag = false; char const *add_name_list_str = NULL, *remove_name_list_str = NULL, *purge_name_list_str = NULL, @@ -327,6 +350,7 @@ int cmd_buildid_cache(int argc, const char **argv) "file(s) to remove"), OPT_STRING('p', "purge", _name_list_str, "file list", "file(s) to remove (remove old caches too)"), + OPT_BOOLEAN('l', "list", _files, "list all cached files"), OPT_STRING('M', "missing", _filename, "file", "to find missing build ids in the cache"), OPT_BOOLEAN('f', "force", , "don't complain, do it"), @@ -344,11 +368,19 @@ int cmd_buildid_cache(int argc, const char **argv) argc = parse_options(argc, argv, buildid_cache_options, buildid_cache_usage, 0); - if (argc || (!add_name_list_str && !kcore_filename && -!remove_name_list_str && !purge_name_list_str && -!missing_filename && !update_name_list_str)) + opts_flag = add_name_list_str || kcore_filename || + remove_name_list_str || purge_name_list_str || + missing_filename || update_name_list_str; + + if (argc || !(list_files || opts_flag)) usage_with_options(buildid_cache_usage, buildid_cache_options); + /* -l is exclusive. It can not be used with other options. */ + if (list_files && opts_flag) { + usage_with_options_msg(buildid_cache_usage, + buildid_cache_options, "-l is exclusive.\n"); + } + if (ns_id > 0) nsi = nsinfo__new(ns_id); @@ -366,6 +398,11 @@ int cmd_buildid_cache(int argc, const char **argv) setup_pager(); + if (list_files) { + ret = build_id_cache__show_all(); + goto out; + } + if (add_name_list_str) { list = strlist__new(add_name_list_str, NULL); if (list) { -- 2.14.3
Re: [PATCH v2 2/3] clk: qcom: gdsc: Add support to poll for higher timeout value
Quoting Taniya Das (2018-04-09 01:41:45) > From: Amit Nischal> > For some gdscs, it might take longer time up to 500us for updating their > status. Update the timeout value for all GDSC polling status. > > Signed-off-by: Amit Nischal > Signed-off-by: Taniya Das > --- Applied to clk-next
Re: [PATCH v2 1/3] clk: qcom: gdsc: Add support to reset AON and block reset logic
Quoting Taniya Das (2018-04-09 01:41:44) > From: Amit Nischal> > For some of the gdsc power domains, there could be need to reset the > AON logic or assert/deassert the block control reset before removing > the clamp_io. Add support for the same by introducing new flags > SW_RESET and AON_RESET. Both SW reset and AON reset requires to be > asserted for at least 1us before being de-asserted. > > Signed-off-by: Taniya Das > Signed-off-by: Amit Nischal > --- Applied to clk-next
Re: [PATCH v2 2/3] clk: qcom: gdsc: Add support to poll for higher timeout value
Quoting Taniya Das (2018-04-09 01:41:45) > From: Amit Nischal > > For some gdscs, it might take longer time up to 500us for updating their > status. Update the timeout value for all GDSC polling status. > > Signed-off-by: Amit Nischal > Signed-off-by: Taniya Das > --- Applied to clk-next
Re: [PATCH v2 1/3] clk: qcom: gdsc: Add support to reset AON and block reset logic
Quoting Taniya Das (2018-04-09 01:41:44) > From: Amit Nischal > > For some of the gdsc power domains, there could be need to reset the > AON logic or assert/deassert the block control reset before removing > the clamp_io. Add support for the same by introducing new flags > SW_RESET and AON_RESET. Both SW reset and AON reset requires to be > asserted for at least 1us before being de-asserted. > > Signed-off-by: Taniya Das > Signed-off-by: Amit Nischal > --- Applied to clk-next
Re: [PATCH 1/2] parisc: use the asm-generic version for writeX()
On 4/16/2018 7:48 PM, Sinan Kaya wrote: > On 4/16/2018 7:44 PM, Sinan Kaya wrote: >>> John David Anglin dave.ang...@bell.net >>> >>> >>> io.log >>> >>> >>> CC arch/parisc/kernel/asm-offsets.s >>> In file included from ./arch/parisc/include/asm/io.h:262:0, >>> from ./include/linux/io.h:25, >>> from ./include/linux/irq.h:25, >>> from ./arch/parisc/include/asm/hardirq.h:13, >>> from ./include/linux/hardirq.h:9, >>> from arch/parisc/kernel/asm-offsets.c:34: >>> ./include/asm-generic/io.h:37:21: error: redefinition of '__raw_readb' >>> #define __raw_readb __raw_readb >>> ^ >> This one is easy to fix: >> >> https://elixir.bootlin.com/linux/latest/source/arch/parisc/include/asm/io.h#L146 >> >> Remove 146..179. > > I'll try to get a hold of a cross compiler and re-test. The above is a hack. > I need to do a better job on this. > > Thanks for the help. I'll post V2 when it is ready. > Converting this to asm-generic turned out to be a much bigger task. I placed compiler barriers instead to existing version and posted as follows: [PATCH v2 1/2] parisc: define stronger ordering for the default writeX() [PATCH v2 2/2] parisc: define stronger ordering for the default readX() -- Sinan Kaya Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
Re: [PATCH 1/2] parisc: use the asm-generic version for writeX()
On 4/16/2018 7:48 PM, Sinan Kaya wrote: > On 4/16/2018 7:44 PM, Sinan Kaya wrote: >>> John David Anglin dave.ang...@bell.net >>> >>> >>> io.log >>> >>> >>> CC arch/parisc/kernel/asm-offsets.s >>> In file included from ./arch/parisc/include/asm/io.h:262:0, >>> from ./include/linux/io.h:25, >>> from ./include/linux/irq.h:25, >>> from ./arch/parisc/include/asm/hardirq.h:13, >>> from ./include/linux/hardirq.h:9, >>> from arch/parisc/kernel/asm-offsets.c:34: >>> ./include/asm-generic/io.h:37:21: error: redefinition of '__raw_readb' >>> #define __raw_readb __raw_readb >>> ^ >> This one is easy to fix: >> >> https://elixir.bootlin.com/linux/latest/source/arch/parisc/include/asm/io.h#L146 >> >> Remove 146..179. > > I'll try to get a hold of a cross compiler and re-test. The above is a hack. > I need to do a better job on this. > > Thanks for the help. I'll post V2 when it is ready. > Converting this to asm-generic turned out to be a much bigger task. I placed compiler barriers instead to existing version and posted as follows: [PATCH v2 1/2] parisc: define stronger ordering for the default writeX() [PATCH v2 2/2] parisc: define stronger ordering for the default readX() -- Sinan Kaya Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
[RFC v4 0/4] Centralize and unify usage of preempt/irq tracepoints
Hello, This is the next revision of preempt/irq tracepoint centralization and unified usage across the kernel [1]. The preempt/irq tracepoints exist but not everything in the kernel is using it. This makes things not work simultaneously (for ex, only lockdep or irqsoff events can be used). This series is an attempt to solve that. I fixed several issues since last rev and I'm posting it slightly early than I wanted to for some feedback especially for the new patches 1-3 in this series. Also any testing is deeply appreciated. Status: Currently I'm noticing a performance issue with "enabling" of the preemptoff tracer (not during its running but the enabling/startup of it). I narrowed this down to rcu_irq_enter_irqson and rcu_irq_exit_irqson calls in tracepoint.h. Commenting these out makes the perf issue go away. I also notice that disabling function tracer also makes the issue go away. Note that I ran hackbench and don't notice any performance issues with my patch itself per-se, however the preemptoff tracer startup seems slow and I'm debugging that. If you have a clue why this might be happening, please let me know. Note that I skipped v3 because I used that number already for some internal reviews of these patches. Also I changed the subject back to RFC in light of the lockdep issues I fixed this time and added some more folks for review. Thanks much for any review or testing. [1] https://www.spinics.net/lists/kernel/msg2750826.html Joel Fernandes (4): tracepoint: Add API to not do lockdep checks during RCU ops softirq: reorder trace_softirqs_on to prevent lockdep splat irqflags: Avoid unnecessary calls to trace_ if you can tracing: Centralize preemptirq tracepoints and unify their usage include/linux/ftrace.h| 11 +- include/linux/irqflags.h | 32 +++-- include/linux/lockdep.h | 8 +- include/linux/preempt.h | 2 +- include/linux/tracepoint.h| 32 - include/trace/events/preemptirq.h | 23 ++-- init/main.c | 5 +- kernel/locking/lockdep.c | 35 ++--- kernel/sched/core.c | 2 +- kernel/softirq.c | 6 +- kernel/trace/Kconfig | 22 +++- kernel/trace/Makefile | 2 +- kernel/trace/trace_irqsoff.c | 206 +++--- kernel/trace/trace_preemptirq.c | 73 +++ 14 files changed, 229 insertions(+), 230 deletions(-) create mode 100644 kernel/trace/trace_preemptirq.c Cc: Steven RostedtCc: Peter Zilstra Cc: Ingo Molnar Cc: Mathieu Desnoyers Cc: Tom Zanussi Cc: Namhyung Kim Cc: Thomas Glexiner Cc: Boqun Feng Cc: Paul McKenney Cc: Frederic Weisbecker Cc: Randy Dunlap Cc: Masami Hiramatsu Cc: Fenguang Wu Cc: Baohong Liu Cc: Vedang Patel -- 2.17.0.484.g0c8726318c-goog
[RFC v4 0/4] Centralize and unify usage of preempt/irq tracepoints
Hello, This is the next revision of preempt/irq tracepoint centralization and unified usage across the kernel [1]. The preempt/irq tracepoints exist but not everything in the kernel is using it. This makes things not work simultaneously (for ex, only lockdep or irqsoff events can be used). This series is an attempt to solve that. I fixed several issues since last rev and I'm posting it slightly early than I wanted to for some feedback especially for the new patches 1-3 in this series. Also any testing is deeply appreciated. Status: Currently I'm noticing a performance issue with "enabling" of the preemptoff tracer (not during its running but the enabling/startup of it). I narrowed this down to rcu_irq_enter_irqson and rcu_irq_exit_irqson calls in tracepoint.h. Commenting these out makes the perf issue go away. I also notice that disabling function tracer also makes the issue go away. Note that I ran hackbench and don't notice any performance issues with my patch itself per-se, however the preemptoff tracer startup seems slow and I'm debugging that. If you have a clue why this might be happening, please let me know. Note that I skipped v3 because I used that number already for some internal reviews of these patches. Also I changed the subject back to RFC in light of the lockdep issues I fixed this time and added some more folks for review. Thanks much for any review or testing. [1] https://www.spinics.net/lists/kernel/msg2750826.html Joel Fernandes (4): tracepoint: Add API to not do lockdep checks during RCU ops softirq: reorder trace_softirqs_on to prevent lockdep splat irqflags: Avoid unnecessary calls to trace_ if you can tracing: Centralize preemptirq tracepoints and unify their usage include/linux/ftrace.h| 11 +- include/linux/irqflags.h | 32 +++-- include/linux/lockdep.h | 8 +- include/linux/preempt.h | 2 +- include/linux/tracepoint.h| 32 - include/trace/events/preemptirq.h | 23 ++-- init/main.c | 5 +- kernel/locking/lockdep.c | 35 ++--- kernel/sched/core.c | 2 +- kernel/softirq.c | 6 +- kernel/trace/Kconfig | 22 +++- kernel/trace/Makefile | 2 +- kernel/trace/trace_irqsoff.c | 206 +++--- kernel/trace/trace_preemptirq.c | 73 +++ 14 files changed, 229 insertions(+), 230 deletions(-) create mode 100644 kernel/trace/trace_preemptirq.c Cc: Steven Rostedt Cc: Peter Zilstra Cc: Ingo Molnar Cc: Mathieu Desnoyers Cc: Tom Zanussi Cc: Namhyung Kim Cc: Thomas Glexiner Cc: Boqun Feng Cc: Paul McKenney Cc: Frederic Weisbecker Cc: Randy Dunlap Cc: Masami Hiramatsu Cc: Fenguang Wu Cc: Baohong Liu Cc: Vedang Patel -- 2.17.0.484.g0c8726318c-goog
Re: [PATCH 1/7] powerpc: Add TIDR CPU feature for Power9
On 17/04/18 12:09, Alastair D'Silva wrote: diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index be8c9fa23983..5b03d8a82409 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h @@ -94,6 +94,5 @@ static inline void clear_task_ebb(struct task_struct *t) extern int set_thread_uses_vas(void); extern int set_thread_tidr(struct task_struct *t); -extern void clear_thread_tidr(struct task_struct *t); This hunk looks like it really belongs in patch 3. Apart from that, I'm not really familiar with the CPU features code but nothing seems overly wrong... Reviewed-by: Andrew Donnellan-- Andrew Donnellan OzLabs, ADL Canberra andrew.donnel...@au1.ibm.com IBM Australia Limited
Re: [PATCH 1/7] powerpc: Add TIDR CPU feature for Power9
On 17/04/18 12:09, Alastair D'Silva wrote: diff --git a/arch/powerpc/include/asm/switch_to.h b/arch/powerpc/include/asm/switch_to.h index be8c9fa23983..5b03d8a82409 100644 --- a/arch/powerpc/include/asm/switch_to.h +++ b/arch/powerpc/include/asm/switch_to.h @@ -94,6 +94,5 @@ static inline void clear_task_ebb(struct task_struct *t) extern int set_thread_uses_vas(void); extern int set_thread_tidr(struct task_struct *t); -extern void clear_thread_tidr(struct task_struct *t); This hunk looks like it really belongs in patch 3. Apart from that, I'm not really familiar with the CPU features code but nothing seems overly wrong... Reviewed-by: Andrew Donnellan -- Andrew Donnellan OzLabs, ADL Canberra andrew.donnel...@au1.ibm.com IBM Australia Limited
[RFC v4 3/4] irqflags: Avoid unnecessary calls to trace_ if you can
With TRACE_IRQFLAGS, we call trace_ API too many times. We don't need to if local_irq_restore or local_irq_save didn't actually do anything. This gives around a 4% improvement in performance when doing the following command: "time find / > /dev/null" Also its best to avoid these calls where possible, since in this series, the RCU code in tracepoint.h seems to be call these quite a bit and I'd like to keep this overhead low. Cc: Steven RostedtCc: Peter Zilstra Cc: Ingo Molnar Cc: Mathieu Desnoyers Cc: Tom Zanussi Cc: Namhyung Kim Cc: Thomas Glexiner Cc: Boqun Feng Cc: Paul McKenney Cc: Frederic Weisbecker Cc: Randy Dunlap Cc: Masami Hiramatsu Cc: Fenguang Wu Cc: Baohong Liu Cc: Vedang Patel Signed-off-by: Joel Fernandes --- include/linux/irqflags.h | 21 +++-- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h index 9700f00bbc04..ea8df0ac57d3 100644 --- a/include/linux/irqflags.h +++ b/include/linux/irqflags.h @@ -104,19 +104,20 @@ do { \ #define local_irq_save(flags) \ do {\ raw_local_irq_save(flags); \ - trace_hardirqs_off(); \ + if (!raw_irqs_disabled_flags(flags))\ + trace_hardirqs_off(); \ } while (0) -#define local_irq_restore(flags) \ - do {\ - if (raw_irqs_disabled_flags(flags)) { \ - raw_local_irq_restore(flags); \ - trace_hardirqs_off(); \ - } else {\ - trace_hardirqs_on();\ - raw_local_irq_restore(flags); \ - } \ +#define local_irq_restore(flags) \ + do { \ + if (raw_irqs_disabled_flags(flags) && !irqs_disabled()) { \ + raw_local_irq_restore(flags); \ + trace_hardirqs_off(); \ + } else if (!raw_irqs_disabled_flags(flags) && irqs_disabled()) {\ + trace_hardirqs_on(); \ + raw_local_irq_restore(flags); \ + } \ } while (0) #define safe_halt()\ -- 2.17.0.484.g0c8726318c-goog
[RFC v4 3/4] irqflags: Avoid unnecessary calls to trace_ if you can
With TRACE_IRQFLAGS, we call trace_ API too many times. We don't need to if local_irq_restore or local_irq_save didn't actually do anything. This gives around a 4% improvement in performance when doing the following command: "time find / > /dev/null" Also its best to avoid these calls where possible, since in this series, the RCU code in tracepoint.h seems to be call these quite a bit and I'd like to keep this overhead low. Cc: Steven Rostedt Cc: Peter Zilstra Cc: Ingo Molnar Cc: Mathieu Desnoyers Cc: Tom Zanussi Cc: Namhyung Kim Cc: Thomas Glexiner Cc: Boqun Feng Cc: Paul McKenney Cc: Frederic Weisbecker Cc: Randy Dunlap Cc: Masami Hiramatsu Cc: Fenguang Wu Cc: Baohong Liu Cc: Vedang Patel Signed-off-by: Joel Fernandes --- include/linux/irqflags.h | 21 +++-- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h index 9700f00bbc04..ea8df0ac57d3 100644 --- a/include/linux/irqflags.h +++ b/include/linux/irqflags.h @@ -104,19 +104,20 @@ do { \ #define local_irq_save(flags) \ do {\ raw_local_irq_save(flags); \ - trace_hardirqs_off(); \ + if (!raw_irqs_disabled_flags(flags))\ + trace_hardirqs_off(); \ } while (0) -#define local_irq_restore(flags) \ - do {\ - if (raw_irqs_disabled_flags(flags)) { \ - raw_local_irq_restore(flags); \ - trace_hardirqs_off(); \ - } else {\ - trace_hardirqs_on();\ - raw_local_irq_restore(flags); \ - } \ +#define local_irq_restore(flags) \ + do { \ + if (raw_irqs_disabled_flags(flags) && !irqs_disabled()) { \ + raw_local_irq_restore(flags); \ + trace_hardirqs_off(); \ + } else if (!raw_irqs_disabled_flags(flags) && irqs_disabled()) {\ + trace_hardirqs_on(); \ + raw_local_irq_restore(flags); \ + } \ } while (0) #define safe_halt()\ -- 2.17.0.484.g0c8726318c-goog
[PATCH v2 2/2] parisc: define stronger ordering for the default readX()
parisc architecture seems to be mapping readX() and readX_relaxed() APIs to __raw_readX() API. __raw_readX() API doesn't provide any kind of ordering guarantees. commit 032d59e1cde9 ("io: define stronger ordering for the default readX() implementation") changed asm-generic implementation to use a more conservative approach towards the readX() API. Place a barrier() after the register read so that compiler doesn't optimize across the regiter operation. Signed-off-by: Sinan Kaya--- arch/parisc/include/asm/io.h | 23 +++ 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/arch/parisc/include/asm/io.h b/arch/parisc/include/asm/io.h index 2ec6405..e04c4ef 100644 --- a/arch/parisc/include/asm/io.h +++ b/arch/parisc/include/asm/io.h @@ -179,19 +179,34 @@ static inline void __raw_writeq(unsigned long long b, volatile void __iomem *add static inline unsigned char readb(const volatile void __iomem *addr) { - return __raw_readb(addr); + unsigned char ret; + + ret = __raw_readb(addr); + barrier(); + return ret; } static inline unsigned short readw(const volatile void __iomem *addr) { - return le16_to_cpu((__le16 __force) __raw_readw(addr)); + unsigned short ret; + + ret = le16_to_cpu((__le16 __force) __raw_readw(addr)); + barrier(); + return ret; } static inline unsigned int readl(const volatile void __iomem *addr) { - return le32_to_cpu((__le32 __force) __raw_readl(addr)); + unsigned int ret; + ret = le32_to_cpu((__le32 __force) __raw_readl(addr)); + barrier(); + return ret; } static inline unsigned long long readq(const volatile void __iomem *addr) { - return le64_to_cpu((__le64 __force) __raw_readq(addr)); + unsigned long long ret; + + ret = le64_to_cpu((__le64 __force) __raw_readq(addr)); + barrier(); + return ret; } static inline void writeb(unsigned char b, volatile void __iomem *addr) -- 2.7.4
[PATCH v2 2/2] parisc: define stronger ordering for the default readX()
parisc architecture seems to be mapping readX() and readX_relaxed() APIs to __raw_readX() API. __raw_readX() API doesn't provide any kind of ordering guarantees. commit 032d59e1cde9 ("io: define stronger ordering for the default readX() implementation") changed asm-generic implementation to use a more conservative approach towards the readX() API. Place a barrier() after the register read so that compiler doesn't optimize across the regiter operation. Signed-off-by: Sinan Kaya --- arch/parisc/include/asm/io.h | 23 +++ 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/arch/parisc/include/asm/io.h b/arch/parisc/include/asm/io.h index 2ec6405..e04c4ef 100644 --- a/arch/parisc/include/asm/io.h +++ b/arch/parisc/include/asm/io.h @@ -179,19 +179,34 @@ static inline void __raw_writeq(unsigned long long b, volatile void __iomem *add static inline unsigned char readb(const volatile void __iomem *addr) { - return __raw_readb(addr); + unsigned char ret; + + ret = __raw_readb(addr); + barrier(); + return ret; } static inline unsigned short readw(const volatile void __iomem *addr) { - return le16_to_cpu((__le16 __force) __raw_readw(addr)); + unsigned short ret; + + ret = le16_to_cpu((__le16 __force) __raw_readw(addr)); + barrier(); + return ret; } static inline unsigned int readl(const volatile void __iomem *addr) { - return le32_to_cpu((__le32 __force) __raw_readl(addr)); + unsigned int ret; + ret = le32_to_cpu((__le32 __force) __raw_readl(addr)); + barrier(); + return ret; } static inline unsigned long long readq(const volatile void __iomem *addr) { - return le64_to_cpu((__le64 __force) __raw_readq(addr)); + unsigned long long ret; + + ret = le64_to_cpu((__le64 __force) __raw_readq(addr)); + barrier(); + return ret; } static inline void writeb(unsigned char b, volatile void __iomem *addr) -- 2.7.4
[PATCH v2 1/2] parisc: define stronger ordering for the default writeX()
parisc architecture seems to be mapping writeX() and writeX_relaxed() APIs to __raw_writeX() API. __raw_writeX() API doesn't provide any kind of ordering guarantees. commit 755bd04aaf4b ("io: define stronger ordering for the default writeX() implementation") changed asm-generic implementation to use a more conservative approach towards the writeX() API. Place a barrier() before the register write so that compiler doesn't optimize across the regiter operation. Signed-off-by: Sinan Kaya--- arch/parisc/include/asm/io.h | 4 1 file changed, 4 insertions(+) diff --git a/arch/parisc/include/asm/io.h b/arch/parisc/include/asm/io.h index afe493b..2ec6405 100644 --- a/arch/parisc/include/asm/io.h +++ b/arch/parisc/include/asm/io.h @@ -196,18 +196,22 @@ static inline unsigned long long readq(const volatile void __iomem *addr) static inline void writeb(unsigned char b, volatile void __iomem *addr) { + barrier(); __raw_writeb(b, addr); } static inline void writew(unsigned short w, volatile void __iomem *addr) { + barrier(); __raw_writew((__u16 __force) cpu_to_le16(w), addr); } static inline void writel(unsigned int l, volatile void __iomem *addr) { + barrier(); __raw_writel((__u32 __force) cpu_to_le32(l), addr); } static inline void writeq(unsigned long long q, volatile void __iomem *addr) { + barrier(); __raw_writeq((__u64 __force) cpu_to_le64(q), addr); } -- 2.7.4
[PATCH v2 1/2] parisc: define stronger ordering for the default writeX()
parisc architecture seems to be mapping writeX() and writeX_relaxed() APIs to __raw_writeX() API. __raw_writeX() API doesn't provide any kind of ordering guarantees. commit 755bd04aaf4b ("io: define stronger ordering for the default writeX() implementation") changed asm-generic implementation to use a more conservative approach towards the writeX() API. Place a barrier() before the register write so that compiler doesn't optimize across the regiter operation. Signed-off-by: Sinan Kaya --- arch/parisc/include/asm/io.h | 4 1 file changed, 4 insertions(+) diff --git a/arch/parisc/include/asm/io.h b/arch/parisc/include/asm/io.h index afe493b..2ec6405 100644 --- a/arch/parisc/include/asm/io.h +++ b/arch/parisc/include/asm/io.h @@ -196,18 +196,22 @@ static inline unsigned long long readq(const volatile void __iomem *addr) static inline void writeb(unsigned char b, volatile void __iomem *addr) { + barrier(); __raw_writeb(b, addr); } static inline void writew(unsigned short w, volatile void __iomem *addr) { + barrier(); __raw_writew((__u16 __force) cpu_to_le16(w), addr); } static inline void writel(unsigned int l, volatile void __iomem *addr) { + barrier(); __raw_writel((__u32 __force) cpu_to_le32(l), addr); } static inline void writeq(unsigned long long q, volatile void __iomem *addr) { + barrier(); __raw_writeq((__u64 __force) cpu_to_le64(q), addr); } -- 2.7.4