Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 5/8] KVM: Add event to trace tlb invalidations
From: Punit Agrawal @ 2016-10-26 17:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026174148.17172-1-punit.agrawal@arm.com>

As TLB operations can have an impact on system performance, add a trace
event to enable monitoring of guest TLB maintenance operations.

Signed-off-by: Punit Agrawal <punit.agrawal@arm.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
---
 include/trace/events/kvm.h | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h
index 8ade3eb..4b3d07e 100644
--- a/include/trace/events/kvm.h
+++ b/include/trace/events/kvm.h
@@ -393,6 +393,23 @@ TRACE_EVENT(kvm_halt_poll_ns,
 #define trace_kvm_halt_poll_ns_shrink(vcpu_id, new, old) \
 	trace_kvm_halt_poll_ns(false, vcpu_id, new, old)
 
+TRACE_EVENT(kvm_tlb_invalidate,
+	TP_PROTO(unsigned long vcpu_pc, u32 opcode),
+	TP_ARGS(vcpu_pc, opcode),
+
+	TP_STRUCT__entry(
+		__field(unsigned long, vcpu_pc)
+		__field(u32, opcode)
+	),
+
+	TP_fast_assign(
+		__entry->vcpu_pc = vcpu_pc;
+		__entry->opcode = opcode;
+	),
+
+	TP_printk("vcpu_pc=0x%16lx opcode=%08x", __entry->vcpu_pc, __entry->opcode)
+);
+
 #endif /* _TRACE_KVM_MAIN_H */
 
 /* This part must be outside protection */
-- 
2.9.3

^ permalink raw reply related

* [PATCH v2 4/8] KVM: arm/arm64: Register perf trace event notifier
From: Punit Agrawal @ 2016-10-26 17:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026174148.17172-1-punit.agrawal@arm.com>

Register a notifier to track state changes of perf trace events.

The notifier will enable taking appropriate action for trace events
targeting VM.

Signed-off-by: Punit Agrawal <punit.agrawal@arm.com>
Cc: Christoffer Dall <christoffer.dall@linaro.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/kvm_host.h   |   8 +++
 arch/arm/kvm/Kconfig              |   4 ++
 arch/arm/kvm/Makefile             |   1 +
 arch/arm/kvm/arm.c                |   2 +
 arch/arm64/include/asm/kvm_host.h |   8 +++
 arch/arm64/kvm/Kconfig            |   4 ++
 arch/arm64/kvm/Makefile           |   1 +
 virt/kvm/arm/perf_trace.c         | 122 ++++++++++++++++++++++++++++++++++++++
 8 files changed, 150 insertions(+)
 create mode 100644 virt/kvm/arm/perf_trace.c

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 2d19e02..e92c4f7 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -285,6 +285,14 @@ static inline int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
 int kvm_perf_init(void);
 int kvm_perf_teardown(void);
 
+#if !defined(CONFIG_KVM_PERF_TRACE)
+static inline int kvm_perf_trace_init(void) { return 0; }
+static inline int kvm_perf_trace_teardown(void) { return 0; }
+#else
+int kvm_perf_trace_init(void);
+int kvm_perf_trace_teardown(void);
+#endif
+
 void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
 
 struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
index 3e1cd04..f7d1020 100644
--- a/arch/arm/kvm/Kconfig
+++ b/arch/arm/kvm/Kconfig
@@ -16,6 +16,9 @@ menuconfig VIRTUALIZATION
 
 if VIRTUALIZATION
 
+config KVM_PERF_TRACE
+        bool
+
 config KVM
 	bool "Kernel-based Virtual Machine (KVM) support"
 	depends on MMU && OF
@@ -34,6 +37,7 @@ config KVM
 	select HAVE_KVM_IRQFD
 	select HAVE_KVM_IRQCHIP
 	select HAVE_KVM_IRQ_ROUTING
+	select KVM_PERF_TRACE if EVENT_TRACING && PERF_EVENTS
 	depends on ARM_VIRT_EXT && ARM_LPAE && ARM_ARCH_TIMER
 	---help---
 	  Support hosting virtualized guest machines.
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
index f19842e..cc3c811 100644
--- a/arch/arm/kvm/Makefile
+++ b/arch/arm/kvm/Makefile
@@ -22,6 +22,7 @@ obj-y += kvm-arm.o init.o interrupts.o
 obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o
 obj-y += coproc.o coproc_a15.o coproc_a7.o mmio.o psci.o perf.o
 obj-y += $(KVM)/arm/aarch32.o
+obj-$(CONFIG_KVM_PERF_TRACE) += $(KVM)/arm/perf_trace.o
 
 obj-y += $(KVM)/arm/vgic/vgic.o
 obj-y += $(KVM)/arm/vgic/vgic-init.o
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 08bb84f..b5b0b63 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -1232,6 +1232,7 @@ static int init_subsystems(void)
 		goto out;
 
 	kvm_perf_init();
+	kvm_perf_trace_init();
 	kvm_coproc_table_init();
 
 out:
@@ -1422,6 +1423,7 @@ int kvm_arch_init(void *opaque)
 void kvm_arch_exit(void)
 {
 	kvm_perf_teardown();
+	kvm_perf_trace_teardown();
 }
 
 static int arm_init(void)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index bd94e67..582d381 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -345,6 +345,14 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
 int kvm_perf_init(void);
 int kvm_perf_teardown(void);
 
+#if !defined(CONFIG_KVM_PERF_TRACE)
+static inline int kvm_perf_trace_init(void) { return 0; }
+static inline int kvm_perf_trace_teardown(void) { return 0; }
+#else
+int kvm_perf_trace_init(void);
+int kvm_perf_trace_teardown(void);
+#endif
+
 struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
 
 static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 6eaf12c..3618dfc 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -19,6 +19,9 @@ if VIRTUALIZATION
 config KVM_ARM_VGIC_V3_ITS
 	bool
 
+config KVM_PERF_TRACE
+        bool
+
 config KVM
 	bool "Kernel-based Virtual Machine (KVM) support"
 	depends on OF
@@ -39,6 +42,7 @@ config KVM
 	select HAVE_KVM_MSI
 	select HAVE_KVM_IRQCHIP
 	select HAVE_KVM_IRQ_ROUTING
+	select KVM_PERF_TRACE if EVENT_TRACING && PERF_EVENTS
 	---help---
 	  Support hosting virtualized guest machines.
 	  We don't support KVM with 16K page tables yet, due to the multiple
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index d50a82a..0c2d925 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -20,6 +20,7 @@ kvm-$(CONFIG_KVM_ARM_HOST) += inject_fault.o regmap.o
 kvm-$(CONFIG_KVM_ARM_HOST) += hyp.o hyp-init.o handle_exit.o
 kvm-$(CONFIG_KVM_ARM_HOST) += guest.o debug.o reset.o sys_regs.o sys_regs_generic_v8.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/aarch32.o
+kvm-$(CONFIG_KVM_PERF_TRACE) += $(KVM)/arm/perf_trace.o
 
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic.o
 kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-init.o
diff --git a/virt/kvm/arm/perf_trace.c b/virt/kvm/arm/perf_trace.c
new file mode 100644
index 0000000..1cafbc9
--- /dev/null
+++ b/virt/kvm/arm/perf_trace.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2016 ARM Ltd.
+ * Author: Punit Agrawal <punit.agrawal@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/kvm_host.h>
+#include <linux/trace_events.h>
+
+typedef int (*perf_trace_callback_fn)(struct kvm *kvm, bool enable);
+
+struct kvm_trace_hook {
+	char *key;		/* Name of the tracepoint to match */
+	perf_trace_callback_fn setup_fn;
+};
+
+static struct kvm_trace_hook trace_hook[] = {
+	{ },
+};
+
+static perf_trace_callback_fn find_trace_callback(const char *trace_key)
+{
+	int i;
+
+	for (i = 0; trace_hook[i].key; i++)
+		if (!strcmp(trace_key, trace_hook[i].key))
+			return trace_hook[i].setup_fn;
+
+	return NULL;
+}
+
+static int kvm_perf_trace_notifier(struct notifier_block *nb,
+				   unsigned long event, void *data)
+{
+	struct perf_event *p_event = data;
+	struct trace_event_call *tp_event = p_event->tp_event;
+	perf_trace_callback_fn setup_trace_fn;
+	struct kvm *kvm = NULL;
+	struct pid *pid;
+	bool found = false;
+
+	/*
+	 * Is this a trace point?
+	 */
+	if (!(tp_event->flags & TRACE_EVENT_FL_TRACEPOINT))
+		goto out;
+
+	/*
+	 * We'll get here for events we care to monitor for KVM. As we
+	 * only care about events attached to a VM, check that there
+	 * is a task associated with the perf event.
+	 */
+	if (p_event->attach_state != PERF_ATTACH_TASK)
+		goto out;
+
+	/*
+	 * This notifier gets called when perf trace event instance is
+	 * added or removed. Until we can restrict this to events of
+	 * interest in core, minimise the overhead below.
+	 *
+	 * Do we care about it? i.e., is there a callback for this
+	 * trace point?
+	 */
+	setup_trace_fn = find_trace_callback(tp_event->tp->name);
+	if (!setup_trace_fn)
+		goto out;
+
+	pid = get_task_pid(p_event->hw.target, PIDTYPE_PID);
+
+	/*
+	 * Does it match any of the VMs?
+	 */
+	spin_lock(&kvm_lock);
+	list_for_each_entry(kvm, &vm_list, vm_list) {
+		if (kvm->pid == pid) {
+			found = true;
+			break;
+		}
+	}
+	spin_unlock(&kvm_lock);
+
+	put_pid(pid);
+	if (!found)
+		goto out;
+
+	switch (event) {
+	case TRACE_REG_PERF_OPEN:
+		setup_trace_fn(kvm, true);
+		break;
+
+	case TRACE_REG_PERF_CLOSE:
+		setup_trace_fn(kvm, false);
+		break;
+	}
+
+out:
+	return 0;
+}
+
+static struct notifier_block kvm_perf_trace_notifier_block = {
+	.notifier_call = kvm_perf_trace_notifier,
+};
+
+int kvm_perf_trace_init(void)
+{
+	return perf_trace_notifier_register(&kvm_perf_trace_notifier_block);
+}
+
+int kvm_perf_trace_teardown(void)
+{
+	return perf_trace_notifier_unregister(&kvm_perf_trace_notifier_block);
+}
-- 
2.9.3

^ permalink raw reply related

* [PATCH v2 3/8] perf/trace: Add notification for perf trace events
From: Punit Agrawal @ 2016-10-26 17:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026174148.17172-1-punit.agrawal@arm.com>

Add a mechanism to notify listeners about perf trace event state
changes. This enables listeners to take actions requiring the event
context (e.g., attached process).

The notification mechanism can be used to reduce trace point based
profiling overhead by enabling/disabling hardware traps for specific
contexts (e.g., virtual machines).

Signed-off-by: Punit Agrawal <punit.agrawal@arm.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
---
 include/linux/trace_events.h    |  3 +++
 kernel/trace/trace_event_perf.c | 24 ++++++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
index be00761..5924032 100644
--- a/include/linux/trace_events.h
+++ b/include/linux/trace_events.h
@@ -505,6 +505,9 @@ perf_trace_buf_submit(void *raw_data, int size, int rctx, u16 type,
 {
 	perf_tp_event(type, count, raw_data, size, regs, head, rctx, task);
 }
+
+extern int perf_trace_notifier_register(struct notifier_block *nb);
+extern int perf_trace_notifier_unregister(struct notifier_block *nb);
 #endif
 
 #endif /* _LINUX_TRACE_EVENT_H */
diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c
index 562fa69..9aaaacf 100644
--- a/kernel/trace/trace_event_perf.c
+++ b/kernel/trace/trace_event_perf.c
@@ -6,10 +6,12 @@
  */
 
 #include <linux/module.h>
+#include <linux/notifier.h>
 #include <linux/kprobes.h>
 #include "trace.h"
 
 static char __percpu *perf_trace_buf[PERF_NR_CONTEXTS];
+static RAW_NOTIFIER_HEAD(perf_trace_notifier_list);
 
 /*
  * Force it to be aligned to unsigned long to avoid misaligned accesses
@@ -86,6 +88,26 @@ static int perf_trace_event_perm(struct trace_event_call *tp_event,
 	return 0;
 }
 
+int perf_trace_notifier_register(struct notifier_block *nb)
+{
+	return raw_notifier_chain_register(&perf_trace_notifier_list, nb);
+}
+
+int perf_trace_notifier_unregister(struct notifier_block *nb)
+{
+	return raw_notifier_chain_unregister(&perf_trace_notifier_list, nb);
+}
+
+static void perf_trace_notify(enum trace_reg event, struct perf_event *p_event)
+{
+	/*
+	 * We use raw notifiers here as we are called with the
+	 * event_mutex held.
+	 */
+	raw_notifier_call_chain(&perf_trace_notifier_list,
+				     event, p_event);
+}
+
 static int perf_trace_event_reg(struct trace_event_call *tp_event,
 				struct perf_event *p_event)
 {
@@ -176,6 +198,7 @@ static void perf_trace_event_unreg(struct perf_event *p_event)
 static int perf_trace_event_open(struct perf_event *p_event)
 {
 	struct trace_event_call *tp_event = p_event->tp_event;
+	perf_trace_notify(TRACE_REG_PERF_OPEN, p_event);
 	return tp_event->class->reg(tp_event, TRACE_REG_PERF_OPEN, p_event);
 }
 
@@ -183,6 +206,7 @@ static void perf_trace_event_close(struct perf_event *p_event)
 {
 	struct trace_event_call *tp_event = p_event->tp_event;
 	tp_event->class->reg(tp_event, TRACE_REG_PERF_CLOSE, p_event);
+	perf_trace_notify(TRACE_REG_PERF_CLOSE, p_event);
 }
 
 static int perf_trace_event_init(struct trace_event_call *tp_event,
-- 
2.9.3

^ permalink raw reply related

* [PATCH v2 2/8] KVM: Track the pid of the VM process
From: Punit Agrawal @ 2016-10-26 17:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026174148.17172-1-punit.agrawal@arm.com>

Userspace tools such as perf can be used to profile individual
processes.

Track the PID of the virtual machine process to match profiling requests
targeted at it. This can be used to take appropriate action to enable
the requested profiling operations for the VMs of interest.

Signed-off-by: Punit Agrawal <punit.agrawal@arm.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Radim Kr?m??" <rkrcmar@redhat.com>
Cc: Christoffer Dall <christoffer.dall@linaro.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
---
 include/linux/kvm_host.h | 1 +
 virt/kvm/kvm_main.c      | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 01c0b9c..4caff20 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -375,6 +375,7 @@ struct kvm_memslots {
 struct kvm {
 	spinlock_t mmu_lock;
 	struct mutex slots_lock;
+	struct pid *pid;
 	struct mm_struct *mm; /* userspace tied to this vm */
 	struct kvm_memslots *memslots[KVM_ADDRESS_SPACE_NUM];
 	struct srcu_struct srcu;
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 28510e7..ed3823c 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -615,6 +615,7 @@ static struct kvm *kvm_create_vm(unsigned long type)
 	spin_lock_init(&kvm->mmu_lock);
 	atomic_inc(&current->mm->mm_count);
 	kvm->mm = current->mm;
+	kvm->pid = get_task_pid(current->group_leader, PIDTYPE_PID);
 	kvm_eventfd_init(kvm);
 	mutex_init(&kvm->lock);
 	mutex_init(&kvm->irq_lock);
@@ -714,6 +715,7 @@ static void kvm_destroy_vm(struct kvm *kvm)
 	int i;
 	struct mm_struct *mm = kvm->mm;
 
+	put_pid(kvm->pid);
 	kvm_destroy_vm_debugfs(kvm);
 	kvm_arch_sync_events(kvm);
 	spin_lock(&kvm_lock);
-- 
2.9.3

^ permalink raw reply related

* [PATCH v2 1/8] arm64/kvm: hyp: tlb: use __tlbi() helper
From: Punit Agrawal @ 2016-10-26 17:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026174148.17172-1-punit.agrawal@arm.com>

From: Mark Rutland <mark.rutland@arm.com>

Now that we have a __tlbi() helper, make use of this in the arm64 KVM hyp
code to get rid of asm() boilerplate. At the same time, we simplify
__tlb_flush_vm_context by using __flush_icache_all(), as this has the
appropriate instruction cache maintenance and barrier.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
[ rename tlbi -> __tlbi, convert additional sites, update commit log ]
Signed-off-by: Punit Agrawal <punit.agrawal@arm.com>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
---
 arch/arm64/kvm/hyp/tlb.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kvm/hyp/tlb.c b/arch/arm64/kvm/hyp/tlb.c
index 9cc0ea7..74eb562 100644
--- a/arch/arm64/kvm/hyp/tlb.c
+++ b/arch/arm64/kvm/hyp/tlb.c
@@ -16,6 +16,7 @@
  */
 
 #include <asm/kvm_hyp.h>
+#include <asm/tlbflush.h>
 
 void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
 {
@@ -32,7 +33,7 @@ void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
 	 * whole of Stage-1. Weep...
 	 */
 	ipa >>= 12;
-	asm volatile("tlbi ipas2e1is, %0" : : "r" (ipa));
+	__tlbi(ipas2e1is, ipa);
 
 	/*
 	 * We have to ensure completion of the invalidation at Stage-2,
@@ -41,7 +42,7 @@ void __hyp_text __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
 	 * the Stage-1 invalidation happened first.
 	 */
 	dsb(ish);
-	asm volatile("tlbi vmalle1is" : : );
+	__tlbi(vmalle1is);
 	dsb(ish);
 	isb();
 
@@ -57,7 +58,7 @@ void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm)
 	write_sysreg(kvm->arch.vttbr, vttbr_el2);
 	isb();
 
-	asm volatile("tlbi vmalls12e1is" : : );
+	__tlbi(vmalls12e1is);
 	dsb(ish);
 	isb();
 
@@ -67,7 +68,6 @@ void __hyp_text __kvm_tlb_flush_vmid(struct kvm *kvm)
 void __hyp_text __kvm_flush_vm_context(void)
 {
 	dsb(ishst);
-	asm volatile("tlbi alle1is	\n"
-		     "ic ialluis	  ": : );
-	dsb(ish);
+	__tlbi(alle1is);
+	__flush_icache_all(); /* contains a dsb(ish) */
 }
-- 
2.9.3

^ permalink raw reply related

* [PATCH v2 0/8] Add support for monitoring guest TLB operations
From: Punit Agrawal @ 2016-10-26 17:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

This is the fourth posting of this series. The biggest change compared
to previous vesion is the addition of support for ARM hosts. With the
addition of ARM support, the patchset is now more complete. Prior
versions can be found at [0][1][2].

I would particularly appreciate feedback from maintainers on the
approach to tie the control of TLB monitoring with perf trace events
(Patch 3 and 4) especially if there are any suggestions on avoiding
(or reducing) the overhead of "perf trace" notifications.

I looked at using regfunc/unregfunc tracepoint hooks but they don't
include the event context. But the bigger problem was that the
callbacks are only called on the first instance of simultaneously
executing perf stat invocations.

Changelog and previous cover-letter follows.

Changes:

v1 -> v2

* New (Patch 6) - Add support for trapping and emulating TLB
  operations to ARM hosts
* Move common code to handle perf trace notifications to virt/kvm/arm
* Move tracepoint to include/trace/events/kvm.h
* Drop patch to introduce __tlbi helper as it is now merged
* Reorder patches

RFC v2 -> v1
* Dropped the RFC tag
* Patch 2 - Use VM thread group id for identification
* Patch 4 - Update comment for clarity
* Patch 6 - Add comment explaining switch to hype-role when VHE is enabled
* Patch 7 - Add comment to clarify struct kvm_trace_hook

RFC -> RFC v2
* Patch 4 - Rename left-over TLBI macro to __TLBI
* Patch 6 - Replace individual TLB operation emulation with
  invalidating all stage 1 TLB for the VM. TLB monitoring is expected
  to be a debug feature and performance is not critical.

Although there are no PMU events to monitor TLB operations, ARMv8
supports trapping guest TLB maintenance operations to the
hypervisor. This trapping mechanism can be used to monitor the use of
guest TLB instructions.

As taking a trap for every TLB operation can have significant
overhead, trapping should only be enabled -

* on user request
* for the VM of interest

This patchset adds support to listen to perf trace event state change
notifications. The notifications and associated context are then used
to enable trapping of guest TLB operations when requested by the
user. The trap handling generates trace events (kvm_tlb_invalidate)
which can already be counted using existing perf trace functionality.

With this patchset, 'perf' tool when attached to a VM process can be
used to monitor the TLB operations. E.g., to monitor a VM with process
id 4166 -

# perf stat -e "kvm:kvm_tlb_invalidate" -p 4166

Perform some operations in VM (running 'make -j 7' on the kernel
sources in this instance). Breaking out of perf shows -

Performance counter stats for process id '4166':

         7,471,974      kvm:kvm_tlb_invalidate

     374.235405282 seconds time elapsed

Thanks,
Punit

[0] http://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1210715.html
[1] http://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1224353.html
[2] https://marc.info/?l=linux-kernel&m=147376184208258&w=2

Mark Rutland (1):
  arm64/kvm: hyp: tlb: use __tlbi() helper

Punit Agrawal (7):
  KVM: Track the pid of the VM process
  perf/trace: Add notification for perf trace events
  KVM: arm/arm64: Register perf trace event notifier
  KVM: Add event to trace tlb invalidations
  arm: KVM: Handle trappable TLB instructions
  arm64: KVM: Handle trappable TLB instructions
  KVM: arm/arm64: Enable selective trapping of TLB instructions

 arch/arm/include/asm/kvm_asm.h    |   1 +
 arch/arm/include/asm/kvm_host.h   |   8 ++
 arch/arm/kvm/Kconfig              |   4 +
 arch/arm/kvm/Makefile             |   1 +
 arch/arm/kvm/arm.c                |   2 +
 arch/arm/kvm/coproc.c             |  55 ++++++++++++++
 arch/arm/kvm/hyp/tlb.c            |  33 ++++++++
 arch/arm64/include/asm/kvm_asm.h  |   1 +
 arch/arm64/include/asm/kvm_host.h |   8 ++
 arch/arm64/kvm/Kconfig            |   4 +
 arch/arm64/kvm/Makefile           |   1 +
 arch/arm64/kvm/hyp/tlb.c          |  87 +++++++++++++++++++--
 arch/arm64/kvm/sys_regs.c         |  81 ++++++++++++++++++++
 include/linux/kvm_host.h          |   1 +
 include/linux/trace_events.h      |   3 +
 include/trace/events/kvm.h        |  17 +++++
 kernel/trace/trace_event_perf.c   |  24 ++++++
 virt/kvm/arm/perf_trace.c         | 154 ++++++++++++++++++++++++++++++++++++++
 virt/kvm/kvm_main.c               |   2 +
 19 files changed, 481 insertions(+), 6 deletions(-)
 create mode 100644 virt/kvm/arm/perf_trace.c

-- 
2.9.3

^ permalink raw reply

* [PATCH 2/2] ARM: bus: da8xx-mstpri: new driver
From: Bartosz Golaszewski @ 2016-10-26 17:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477503355-2600-1-git-send-email-bgolaszewski@baylibre.com>

Create the driver for the da8xx master peripheral priority
configuration and implement support for writing to the three
Master Priority registers on da850 SoCs.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 .../devicetree/bindings/bus/ti,da850-mstpri.txt    |  20 ++
 drivers/bus/Kconfig                                |   9 +
 drivers/bus/Makefile                               |   2 +
 drivers/bus/da8xx-mstpri.c                         | 266 +++++++++++++++++++++
 4 files changed, 297 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/bus/ti,da850-mstpri.txt
 create mode 100644 drivers/bus/da8xx-mstpri.c

diff --git a/Documentation/devicetree/bindings/bus/ti,da850-mstpri.txt b/Documentation/devicetree/bindings/bus/ti,da850-mstpri.txt
new file mode 100644
index 0000000..225af09
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/ti,da850-mstpri.txt
@@ -0,0 +1,20 @@
+* Device tree bindings for Texas Instruments da8xx master peripheral
+  priority driver
+
+DA8XX SoCs feature a set of registers allowing to change the priority of all
+peripherals classified as masters.
+
+Documentation:
+OMAP-L138 (DA850) - http://www.ti.com/lit/ug/spruh82c/spruh82c.pdf
+
+Required properties:
+
+- compatible:		"ti,da850-mstpri", "syscon" - for da850 based boards
+- reg:			offset and length of the mstpri registers
+
+Example for da850-lcdk is shown below.
+
+mstpri {
+	compatible = "ti,da850-mstpri";
+	reg = <0x14110 0x0c>;
+};
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 7010dca..ed6a89c 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -166,4 +166,13 @@ config VEXPRESS_CONFIG
 	help
 	  Platform configuration infrastructure for the ARM Ltd.
 	  Versatile Express.
+
+config DA8XX_MSTPRI
+	bool "TI da8xx master peripheral priority driver"
+	depends on ARCH_DAVINCI_DA8XX
+	help
+	  Driver for Texas Instruments da8xx master peripheral priority
+	  configuration. Allows to adjust the priorities of all master
+	  peripherals.
+
 endmenu
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index c6cfa6b..2adb540 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -21,3 +21,5 @@ obj-$(CONFIG_SIMPLE_PM_BUS)	+= simple-pm-bus.o
 obj-$(CONFIG_TEGRA_ACONNECT)	+= tegra-aconnect.o
 obj-$(CONFIG_UNIPHIER_SYSTEM_BUS)	+= uniphier-system-bus.o
 obj-$(CONFIG_VEXPRESS_CONFIG)	+= vexpress-config.o
+
+obj-$(CONFIG_DA8XX_MSTPRI)	+= da8xx-mstpri.o
diff --git a/drivers/bus/da8xx-mstpri.c b/drivers/bus/da8xx-mstpri.c
new file mode 100644
index 0000000..00c4f83
--- /dev/null
+++ b/drivers/bus/da8xx-mstpri.c
@@ -0,0 +1,266 @@
+/*
+ * TI da8xx master peripheral priority driver
+ *
+ * Copyright (C) 2016 BayLibre SAS
+ *
+ * Author:
+ *   Bartosz Golaszewski <bgolaszewski@baylibre.com.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of_fdt.h>
+
+/*
+ * REVISIT: Linux doesn't have a good framework for the kind of performance
+ * knobs this driver controls. We can't use device tree properties as it deals
+ * with hardware configuration rather than description. We also don't want to
+ * commit to maintaining some random sysfs attributes.
+ *
+ * For now we just hardcode the register values for the boards that need
+ * some changes (as is the case for the LCD controller on da850-lcdk - the
+ * first board we support here). When linux gets an appropriate framework,
+ * we'll easily convert the driver to it.
+ */
+
+#define DA8XX_MSTPRI0_OFFSET		0
+#define DA8XX_MSTPRI1_OFFSET		4
+#define DA8XX_MSTPRI2_OFFSET		8
+
+enum {
+	DA8XX_MSTPRI_ARM_I = 0,
+	DA8XX_MSTPRI_ARM_D,
+	DA8XX_MSTPRI_UPP,
+	DA8XX_MSTPRI_SATA,
+	DA8XX_MSTPRI_PRU0,
+	DA8XX_MSTPRI_PRU1,
+	DA8XX_MSTPRI_EDMA30TC0,
+	DA8XX_MSTPRI_EDMA30TC1,
+	DA8XX_MSTPRI_EDMA31TC0,
+	DA8XX_MSTPRI_VPIF_DMA_0,
+	DA8XX_MSTPRI_VPIF_DMA_1,
+	DA8XX_MSTPRI_EMAC,
+	DA8XX_MSTPRI_USB0CFG,
+	DA8XX_MSTPRI_USB0CDMA,
+	DA8XX_MSTPRI_UHPI,
+	DA8XX_MSTPRI_USB1,
+	DA8XX_MSTPRI_LCDC,
+};
+
+struct da8xx_mstpri_descr {
+	int reg;
+	int shift;
+	int mask;
+};
+
+static const struct da8xx_mstpri_descr da8xx_mstpri_priority_list[] = {
+	[DA8XX_MSTPRI_ARM_I] = {
+		.reg = DA8XX_MSTPRI0_OFFSET,
+		.shift = 0,
+		.mask = 0x0000000f,
+	},
+	[DA8XX_MSTPRI_ARM_D] = {
+		.reg = DA8XX_MSTPRI0_OFFSET,
+		.shift = 4,
+		.mask = 0x000000f0,
+	},
+	[DA8XX_MSTPRI_UPP] = {
+		.reg = DA8XX_MSTPRI0_OFFSET,
+		.shift = 16,
+		.mask = 0x000f0000,
+	},
+	[DA8XX_MSTPRI_SATA] = {
+		.reg = DA8XX_MSTPRI0_OFFSET,
+		.shift = 20,
+		.mask = 0x00f00000,
+	},
+	[DA8XX_MSTPRI_PRU0] = {
+		.reg = DA8XX_MSTPRI1_OFFSET,
+		.shift = 0,
+		.mask = 0x0000000f,
+	},
+	[DA8XX_MSTPRI_PRU1] = {
+		.reg = DA8XX_MSTPRI1_OFFSET,
+		.shift = 4,
+		.mask = 0x000000f0,
+	},
+	[DA8XX_MSTPRI_EDMA30TC0] = {
+		.reg = DA8XX_MSTPRI1_OFFSET,
+		.shift = 8,
+		.mask = 0x00000f00,
+	},
+	[DA8XX_MSTPRI_EDMA30TC1] = {
+		.reg = DA8XX_MSTPRI1_OFFSET,
+		.shift = 12,
+		.mask = 0x0000f000,
+	},
+	[DA8XX_MSTPRI_EDMA31TC0] = {
+		.reg = DA8XX_MSTPRI1_OFFSET,
+		.shift = 16,
+		.mask = 0x000f0000,
+	},
+	[DA8XX_MSTPRI_VPIF_DMA_0] = {
+		.reg = DA8XX_MSTPRI1_OFFSET,
+		.shift = 24,
+		.mask = 0x0f000000,
+	},
+	[DA8XX_MSTPRI_VPIF_DMA_1] = {
+		.reg = DA8XX_MSTPRI1_OFFSET,
+		.shift = 28,
+		.mask = 0xf0000000,
+	},
+	[DA8XX_MSTPRI_EMAC] = {
+		.reg = DA8XX_MSTPRI2_OFFSET,
+		.shift = 0,
+		.mask = 0x0000000f,
+	},
+	[DA8XX_MSTPRI_USB0CFG] = {
+		.reg = DA8XX_MSTPRI2_OFFSET,
+		.shift = 8,
+		.mask = 0x00000f00,
+	},
+	[DA8XX_MSTPRI_USB0CDMA] = {
+		.reg = DA8XX_MSTPRI2_OFFSET,
+		.shift = 12,
+		.mask = 0x0000f000,
+	},
+	[DA8XX_MSTPRI_UHPI] = {
+		.reg = DA8XX_MSTPRI2_OFFSET,
+		.shift = 20,
+		.mask = 0x00f00000,
+	},
+	[DA8XX_MSTPRI_USB1] = {
+		.reg = DA8XX_MSTPRI2_OFFSET,
+		.shift = 24,
+		.mask = 0x0f000000,
+	},
+	[DA8XX_MSTPRI_LCDC] = {
+		.reg = DA8XX_MSTPRI2_OFFSET,
+		.shift = 28,
+		.mask = 0xf0000000,
+	},
+};
+
+struct da8xx_mstpri_priority {
+	int which;
+	u32 val;
+};
+
+struct da8xx_mstpri_board_priorities {
+	const char *board;
+	const struct da8xx_mstpri_priority *priorities;
+	size_t numprio;
+};
+
+/*
+ * Default memory settings of da850 do not meet the throughput/latency
+ * requirements of tilcdc. This results in the image displayed being
+ * incorrect and the following warning being displayed by the LCDC
+ * drm driver:
+ *
+ *   tilcdc da8xx_lcdc.0: tilcdc_crtc_irq(0x00000020): FIFO underfow
+ */
+static const struct da8xx_mstpri_priority da850_lcdk_priorities[] = {
+	{
+		.which = DA8XX_MSTPRI_LCDC,
+		.val = 0,
+	},
+	{
+		.which = DA8XX_MSTPRI_EDMA30TC1,
+		.val = 0,
+	},
+	{
+		.which = DA8XX_MSTPRI_EDMA30TC0,
+		.val = 1,
+	},
+};
+
+static const struct da8xx_mstpri_board_priorities da8xx_mstpri_board_confs[] = {
+	{
+		.board = "ti,da850-lcdk",
+		.priorities = da850_lcdk_priorities,
+		.numprio = ARRAY_SIZE(da850_lcdk_priorities),
+	},
+};
+
+static const struct da8xx_mstpri_board_priorities *
+da8xx_mstpri_get_board_prio(void)
+{
+	const struct da8xx_mstpri_board_priorities *board_prio;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(da8xx_mstpri_board_confs); i++) {
+		board_prio = &da8xx_mstpri_board_confs[i];
+
+		if (of_machine_is_compatible(board_prio->board))
+			return board_prio;
+	}
+
+	return NULL;
+}
+
+static int da8xx_mstpri_probe(struct platform_device *pdev)
+{
+	const struct da8xx_mstpri_board_priorities *prio_list;
+	const struct da8xx_mstpri_descr *prio_descr;
+	const struct da8xx_mstpri_priority *prio;
+	struct device *dev = &pdev->dev;
+	struct regmap *mstpri;
+	int i, ret;
+
+	mstpri = syscon_regmap_lookup_by_compatible("ti,da850-mstpri");
+	if (IS_ERR(mstpri)) {
+		dev_err(dev, "unable to map mstpri registers\n");
+		return PTR_ERR(mstpri);
+	}
+
+	prio_list = da8xx_mstpri_get_board_prio();
+	if (!prio_list) {
+		dev_err(dev, "no master priotities defined for board '%s'\n",
+			of_flat_dt_get_machine_name());
+		return -EINVAL;
+	}
+
+	for (i = 0; i < prio_list->numprio; i++) {
+		prio = &prio_list->priorities[i];
+		prio_descr = &da8xx_mstpri_priority_list[prio->which];
+
+		ret = regmap_update_bits(mstpri, prio_descr->reg,
+					 prio_descr->mask,
+					 prio->val << prio_descr->shift);
+		if (ret) {
+			dev_warn(dev,
+				 "error updating bits for register [%d]: %d\n",
+				 prio_descr->reg, ret);
+			continue;
+		}
+	}
+
+	return 0;
+}
+
+static const struct of_device_id da8xx_mstpri_of_match[] = {
+	{ .compatible = "ti,da850-mstpri", },
+	{ },
+};
+
+static struct platform_driver da8xx_mstpri_driver = {
+	.probe = da8xx_mstpri_probe,
+	.driver = {
+		.name = "da8xx-mstpri",
+		.of_match_table = da8xx_mstpri_of_match,
+	},
+};
+module_platform_driver(da8xx_mstpri_driver);
+
+MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
+MODULE_DESCRIPTION("TI da8xx master peripheral priority driver");
+MODULE_LICENSE("GPL v2");
-- 
2.9.3

^ permalink raw reply related

* [PATCH 1/2] ARM: memory: da8xx-ddrctl: new driver
From: Bartosz Golaszewski @ 2016-10-26 17:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477503355-2600-1-git-send-email-bgolaszewski@baylibre.com>

Create a new driver for the da8xx DDR2/mDDR controller and implement
support for writing to the Peripheral Bus Burst Priority Register.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
 .../memory-controllers/ti-da8xx-ddrctl.txt         |  20 +++
 drivers/memory/Kconfig                             |   8 +
 drivers/memory/Makefile                            |   1 +
 drivers/memory/da8xx-ddrctl.c                      | 175 +++++++++++++++++++++
 4 files changed, 204 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt
 create mode 100644 drivers/memory/da8xx-ddrctl.c

diff --git a/Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt b/Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt
new file mode 100644
index 0000000..7e271dd
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt
@@ -0,0 +1,20 @@
+* Device tree bindings for Texas Instruments da8xx DDR2/mDDR memory controller
+
+The DDR2/mDDR memory controller present on Texas Instruments da8xx SoCs features
+a set of registers which allow to tweak the controller's behavior.
+
+Documentation:
+OMAP-L138 (DA850) - http://www.ti.com/lit/ug/spruh82c/spruh82c.pdf
+
+Required properties:
+
+- compatible:		"ti,da850-ddr-controller" - for da850 SoC based boards
+- reg:			a tuple containing the base address of the memory
+			controller and the size of the memory area to map
+
+Example for da850 shown below.
+
+ddrctl {
+	compatible = "ti,da850-ddr-controller";
+	reg = <0xB0000000 0x100>;
+};
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index 4b4c0c3..ec80e35 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -134,6 +134,14 @@ config MTK_SMI
 	  mainly help enable/disable iommu and control the power domain and
 	  clocks for each local arbiter.
 
+config DA8XX_DDRCTL
+	bool "Texas Instruments da8xx DDR2/mDDR driver"
+	depends on ARCH_DAVINCI_DA8XX
+	help
+	  This driver is for the DDR2/mDDR Memory Controller present on
+	  Texas Instruments da8xx SoCs. It's used to tweak various memory
+	  controller configuration options.
+
 source "drivers/memory/samsung/Kconfig"
 source "drivers/memory/tegra/Kconfig"
 
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index b20ae38..e88097fb 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_MVEBU_DEVBUS)	+= mvebu-devbus.o
 obj-$(CONFIG_TEGRA20_MC)	+= tegra20-mc.o
 obj-$(CONFIG_JZ4780_NEMC)	+= jz4780-nemc.o
 obj-$(CONFIG_MTK_SMI)		+= mtk-smi.o
+obj-$(CONFIG_DA8XX_DDRCTL)	+= da8xx-ddrctl.o
 
 obj-$(CONFIG_SAMSUNG_MC)	+= samsung/
 obj-$(CONFIG_TEGRA_MC)		+= tegra/
diff --git a/drivers/memory/da8xx-ddrctl.c b/drivers/memory/da8xx-ddrctl.c
new file mode 100644
index 0000000..900e131
--- /dev/null
+++ b/drivers/memory/da8xx-ddrctl.c
@@ -0,0 +1,175 @@
+/*
+ * TI da8xx DDR2/mDDR controller driver
+ *
+ * Copyright (C) 2016 BayLibre SAS
+ *
+ * Author:
+ *   Bartosz Golaszewski <bgolaszewski@baylibre.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_fdt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+/*
+ * REVISIT: Linux doesn't have a good framework for the kind of performance
+ * knobs this driver controls. We can't use device tree properties as it deals
+ * with hardware configuration rather than description. We also don't want to
+ * commit to maintaining some random sysfs attributes.
+ *
+ * For now we just hardcode the register values for the boards that need
+ * some changes (as is the case for the LCD controller on da850-lcdk - the
+ * first board we support here). When linux gets an appropriate framework,
+ * we'll easily convert the driver to it.
+ */
+
+struct da8xx_ddrctl_config_knob {
+	const char *name;
+	u32 reg;
+	u32 mask;
+	u32 shift;
+};
+
+static const struct da8xx_ddrctl_config_knob da8xx_ddrctl_knobs[] = {
+	{
+		.name = "da850-pbbpr",
+		.reg = 0x20,
+		.mask = 0xffffff00,
+		.shift = 0,
+	},
+};
+
+struct da8xx_ddrctl_setting {
+	const char *name;
+	u32 val;
+};
+
+struct da8xx_ddrctl_board_settings {
+	const char *board;
+	const struct da8xx_ddrctl_setting *settings;
+};
+
+static const struct da8xx_ddrctl_setting da850_lcdk_ddrctl_settings[] = {
+	{
+		.name = "da850-pbbpr",
+		.val = 0x20,
+	},
+	{ }
+};
+
+static const struct da8xx_ddrctl_board_settings da8xx_ddrctl_board_confs[] = {
+	{
+		.board = "ti,da850-lcdk",
+		.settings = da850_lcdk_ddrctl_settings,
+	},
+};
+
+static const struct da8xx_ddrctl_config_knob *
+da8xx_ddrctl_match_knob(const struct da8xx_ddrctl_setting *setting)
+{
+	const struct da8xx_ddrctl_config_knob *knob;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(da8xx_ddrctl_knobs); i++) {
+		knob = &da8xx_ddrctl_knobs[i];
+
+		if (strcmp(knob->name, setting->name) == 0)
+			return knob;
+	}
+
+	return NULL;
+}
+
+static const struct da8xx_ddrctl_setting *da8xx_ddrctl_get_board_settings(void)
+{
+	const struct da8xx_ddrctl_board_settings *board_settings;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(da8xx_ddrctl_board_confs); i++) {
+		board_settings = &da8xx_ddrctl_board_confs[i];
+
+		if (of_machine_is_compatible(board_settings->board))
+			return board_settings->settings;
+	}
+
+	return NULL;
+}
+
+static int da8xx_ddrctl_probe(struct platform_device *pdev)
+{
+	const struct da8xx_ddrctl_config_knob *knob;
+	const struct da8xx_ddrctl_setting *setting;
+	struct device_node *node;
+	struct resource *res;
+	void __iomem *ddrctl;
+	struct device *dev;
+	u32 reg;
+
+	dev = &pdev->dev;
+	node = dev->of_node;
+
+	setting = da8xx_ddrctl_get_board_settings();
+	if (!setting) {
+		dev_err(dev, "no settings for board '%s'\n",
+			of_flat_dt_get_machine_name());
+		return -EINVAL;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	ddrctl = devm_ioremap_resource(dev, res);
+	if (IS_ERR(ddrctl)) {
+		dev_err(dev, "unable to map memory controller registers\n");
+		return PTR_ERR(ddrctl);
+	}
+
+	for (; setting->name; setting++) {
+		knob = da8xx_ddrctl_match_knob(setting);
+		if (!knob) {
+			dev_warn(dev,
+				 "no such config option: %s\n", setting->name);
+			continue;
+		}
+
+		if (knob->reg > (res->end - res->start - sizeof(u32))) {
+			dev_warn(dev,
+				 "register offset of '%s' exceeds mapped memory size\n",
+				 knob->name);
+			continue;
+		}
+
+		reg = __raw_readl(ddrctl + knob->reg);
+		reg &= knob->mask;
+		reg |= setting->val << knob->shift;
+
+		dev_dbg(dev, "writing 0x%08x to %s\n", reg, setting->name);
+
+		__raw_writel(reg, ddrctl + knob->reg);
+	}
+
+	return 0;
+}
+
+static const struct of_device_id da8xx_ddrctl_of_match[] = {
+	{ .compatible = "ti,da850-ddr-controller", },
+	{ },
+};
+
+static struct platform_driver da8xx_ddrctl_driver = {
+	.probe = da8xx_ddrctl_probe,
+	.driver = {
+		.name = "da850-ddr-controller",
+		.of_match_table = da8xx_ddrctl_of_match,
+	},
+};
+module_platform_driver(da8xx_ddrctl_driver);
+
+MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
+MODULE_DESCRIPTION("TI da8xx DDR2/mDDR controller driver");
+MODULE_LICENSE("GPL v2");
-- 
2.9.3

^ permalink raw reply related

* [PATCH 0/2] ARM: da850: new drivers for better LCDC support
From: Bartosz Golaszewski @ 2016-10-26 17:35 UTC (permalink / raw)
  To: linux-arm-kernel

This series adds two new drivers in order to better support the LCDC
rev1 present on the da850 boards.

The first patch adds a new memory driver which allows to write to the
DDR2/mDDR memory controller present on the da8xx SoCs. Since the
memory controller region is not mapped by anyone else, I went with
platform_get_resource() and ioremap() approach.

The second patch adds a new bus driver which allows to interact with
the MSTPRI registers of the SYSCFG0 module. The SYSCFG0 registers
are used by many drivers, hence the syscon/regmap approach.

As is mentioned in the comments: we don't want to commit to supporting
stable interfaces (DT bindings or sysfs attributes) so we hardcode the
settings required by some boards (for now only da850-lcdk) with the
hope that linux gets an appropriate framework for performance knobs
in the future.

Potential extensions of these drivers should be straightforward in the
future.

Tested on a da850-lcdk with a display connected over VGA and some
additional work on the tilcdc driver.

NOTE I'm sending this as v1, but it's a follow-up to a series I sent
previously and the RFC with the ddrctl driver. I dropped the dt patch
for now.

Bartosz Golaszewski (2):
  ARM: memory: da8xx-ddrctl: new driver
  ARM: bus: da8xx-mstpri: new driver

 .../devicetree/bindings/bus/ti,da850-mstpri.txt    |  20 ++
 .../memory-controllers/ti-da8xx-ddrctl.txt         |  20 ++
 drivers/bus/Kconfig                                |   9 +
 drivers/bus/Makefile                               |   2 +
 drivers/bus/da8xx-mstpri.c                         | 266 +++++++++++++++++++++
 drivers/memory/Kconfig                             |   8 +
 drivers/memory/Makefile                            |   1 +
 drivers/memory/da8xx-ddrctl.c                      | 175 ++++++++++++++
 8 files changed, 501 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/bus/ti,da850-mstpri.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti-da8xx-ddrctl.txt
 create mode 100644 drivers/bus/da8xx-mstpri.c
 create mode 100644 drivers/memory/da8xx-ddrctl.c

-- 
2.9.3

^ permalink raw reply

* [PATCH v3] drivers: psci: PSCI checker module
From: Lorenzo Pieralisi @ 2016-10-26 17:35 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026172252.GV3716@linux.vnet.ibm.com>

On Wed, Oct 26, 2016 at 10:22:52AM -0700, Paul E. McKenney wrote:
> On Wed, Oct 26, 2016 at 06:10:06PM +0100, Lorenzo Pieralisi wrote:
> > On Wed, Oct 26, 2016 at 08:18:58AM -0700, Paul E. McKenney wrote:
> > > On Wed, Oct 26, 2016 at 02:17:52PM +0100, Lorenzo Pieralisi wrote:
> > > > On Tue, Oct 25, 2016 at 11:34:36AM -0700, Paul E. McKenney wrote:
> > > > 
> > > > [...]
> > > > 
> > > > > > > +static int __init psci_checker(void)
> > > > > > > +{
> > > > > > > +	int ret;
> > > > > > > +
> > > > > > > +	/*
> > > > > > > +	 * Since we're in an initcall, we assume that all the CPUs that all
> > > > > > > +	 * CPUs that can be onlined have been onlined.
> > > > > > > +	 *
> > > > > > > +	 * The tests assume that hotplug is enabled but nobody else is using it,
> > > > > > > +	 * otherwise the results will be unpredictable. However, since there
> > > > > > > +	 * is no userspace yet in initcalls, that should be fine.
> > > > > > 
> > > > > > I do not think it is. If you run a kernel with, say,
> > > > > > CONFIG_LOCK_TORTURE_TEST, cpus may disappear from the radar while
> > > > > > running the PSCI checker test itself; that at least would confuse the
> > > > > > checker, and that's just an example.
> > > > > > 
> > > > > > I added Paul to check what are the assumptions behind the torture test
> > > > > > hotplug tests, in particular if there are any implicit assumptions for
> > > > > > it to work (ie it is the only kernel test hotplugging cpus in and out
> > > > > > (?)), what I know is that the PSCI checker assumptions are not correct.
> > > > > 
> > > > > Both CONFIG_LOCK_TORTURE_TEST and CONFIG_RCU_TORTURE_TEST can and will
> > > > > hotplug CPUs.  The locktorture.onoff_holdoff and rcutorture.onoff_holdoff
> > > > > kernel parameters can delay the start of CPU-hotplug testing, and in
> > > > > my testing I set this delay to 30 seconds after boot.
> > > > > 
> > > > > One approach would be to make your test refuse to run if either of
> > > > > the lock/RCU torture tests was running.  Or do what Lorenzo suggests
> > > > > below.  The torture tests aren't crazy enough to offline the last CPU.
> > > > > Though they do try, just for effect, in cases where the last CPU is
> > > > > marked cpu_is_hotpluggable().  ;-)
> > > > 
> > > > Thank you Paul. I have an additional question though. Is there any
> > > > implicit assumption in LOCK/RCU torture tests whereby nothing else
> > > > in the kernel is hotplugging cpus in/out (through cpu_down()/up())
> > > > while they are running ?
> > > > 
> > > > I am asking because that's the main reason behind my query. Those tests
> > > > hotplug cpus in and out through cpu_down/up() but AFAICS nothing
> > > > prevents another piece of code in the kernel to call those functions and
> > > > the tests may just fail in that case (ie trying to cpu_down() a cpu
> > > > that is not online).
> > > > 
> > > > Are false negatives contemplated (or I am missing something) ?
> > > 
> > > The current code assumes nothing else doing CPU-hotplug operations,
> > > and will therefore print "RCU_HOTPLUG" error (or "LOCK_HOTPLUG" for
> > > locktorture) if any of the hotplug operations failed.
> > > 
> > > > I just would like to understand if what this patch currently does
> > > > is safe and sound. I think that calling cpu_down() and cpu_up()
> > > > is always safe, but the test can result in false negatives if
> > > > other kernel subsystems (eg LOCK torture test) are calling those
> > > > APIs in parallel (because cpu_down()/cpu_up() calls can fail - eg
> > > > trying to cpu_down() a cpu that is not online any longer, since it
> > > > was taken down by another kernel control path), that's the question
> > > > I have.
> > > 
> > > I am assuming that these added calls to cpu_down() and cpu_up() aren't
> > > enabled by default.  If they are, rcutorture and locktorture need some
> > > way to turn the off.
> > > 
> > > So maybe we need to have some sort of API that detects concurrent
> > > CPU-hotplug torturing?  Maybe something like the following?
> > > 
> > > 	static atomic_t n_cpu_hotplug_torturers;
> > > 	static atomic_t cpu_hotplug_concurrent_torture;
> > > 
> > > 	void torture_start_cpu_hotplug(void)
> > > 	{
> > > 		if (atomic_inc_return(&n_cpu_hotplug_torturers) > 1)
> > > 			atomic_inc(&cpu_hotplug_concurrent_torture);
> > > 	}
> > > 
> > > 	void torture_end_cpu_hotplug(void)
> > > 	{
> > > 		atomic_dec(&n_cpu_hotplug_torturers);
> > > 	}
> > > 
> > > 	bool torture_cpu_hotplug_was_concurrent(void)
> > > 	{
> > > 		return !!atomic_read(&cpu_hotplug_concurrent_torture);
> > > 	}
> > > 
> > > The locktorture and rcutorture code could then ignore CPU-hotplug
> > > errors that could be caused by concurrent access.  And complain
> > > bitterly about the concurrent access, of course!  ;-)
> > 
> > This could do, even better if we extend the torture hotplug tests to
> > take a cpumask so that basically Kevin's patch will be based on torture
> > hotplug tests infrastructure :D (ie he/we wanted to hotplug a subset of
> > the online mask corresponding to a "cluster" of cpus, that's to test the
> > PSCI CPU ON/OFF firmware interface behind cpu hotplug operations).
> > 
> > Still, this implies logging every possible cpu_down()/cpu_up() caller
> > through torture_start_cpu_hotplug().
> > 
> > What about userspace and sysfs interface that allow to offline cpus then ?
> > Point is, the torture hotplug tests take a snapshot of the maxcpu at
> > kthread init time and then randomize the logical cpu number, but it is
> > definitely possible unless I am mistaken that some of those cpus
> > disappear while the test is running and this will cause failures that
> > you can't detect through the API above.
> > 
> > That's why I suggested using the:
> > 
> > freeze_secondary_cpus(int primary);
> > 
> > for this patch because that allows us to quiesce all cpus other than
> > primary at once, with no interference possible from other kernel control
> > paths (but it is not a perfect solution either).
> > 
> > Userspace notwithstanding, I think the best solution consists in either
> > making this patch hotplug tests work on top of the torture hotplug tests
> > API or solving the dependency at kconfig level by disabling the PSCI
> > checker if any of torture tests are enabled which is not ideal but
> > I do not see any other option.
> > 
> > Thanks a lot for your feedback, thoughts appreciated.
> 
> Let me ask the question more directly.
> 
> Why on earth are we trying to run these tests concurrently?

We must prevent that, no question about that, that's why I started
this discussion. It is not fine to enable this checker and the
RCU/LOCK torture hotplug tests at the same time.

> After all, if we just run one at a time in isolation, there is no
> problem.

Fine by me, it was to understand if the current assumptions we made
are correct and they are definitely not. If we enable the PSCI checker
we must disable the torture rcu/lock hotplug tests either statically or
dynamically.

Thanks,
Lorenz

^ permalink raw reply

* [PATCH 2/2] clk: uniphier: add clock data for cpufreq
From: Masahiro Yamada @ 2016-10-26 17:31 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477503088-26508-1-git-send-email-yamada.masahiro@socionext.com>

Data needed for CPU-gear change (cpufreq).

Note:
At this moment, some clock data for Pro5/Pxs2 (32bit SoCs) are
a bit faked because clock rates greater than LONG_MAX (~2.15 GHz)
must be avoided on 32 bit systems.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

I raised a flag in the following post:
https://www.spinics.net/lists/kernel/msg2361374.html

I have not had any comments.
Anyway, I am moving forward.
I can fix the data arrays to reflect the real
clock topology.


 drivers/clk/uniphier/clk-uniphier-sys.c | 111 ++++++++++++++++++++++++++++++++
 drivers/clk/uniphier/clk-uniphier.h     |  35 +++++++++-
 2 files changed, 145 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/uniphier/clk-uniphier-sys.c b/drivers/clk/uniphier/clk-uniphier-sys.c
index 5d02999..74ab179 100644
--- a/drivers/clk/uniphier/clk-uniphier-sys.c
+++ b/drivers/clk/uniphier/clk-uniphier-sys.c
@@ -41,6 +41,19 @@
 #define UNIPHIER_PRO4_SYS_CLK_USB3(idx, ch)				\
 	UNIPHIER_CLK_GATE("usb3" #ch, (idx), NULL, 0x2104, 16 + (ch))
 
+#define UNIPHIER_PRO5_SYS_CPUGEARS					\
+	UNIPHIER_CLK_DIV8("cpll", 2, 3, 4, 6, 8, 12, 16, 24),		\
+	UNIPHIER_CLK_DIV8("spll", 2, 3, 4, 6, 8, 12, 16, 24),		\
+	UNIPHIER_CLK_DIV8("ippll", 2, 3, 4, 6, 8, 12, 16, 24),		\
+	UNIPHIER_CLK_CPUGEAR("cpu-ca9", 32, 0x8000, 0x1f, 16,		\
+			     "cpll/2", "spll/2", "cpll/3", "spll/3",	\
+			     "cpll/4", "spll/4", "cpll/6", "spll/6",	\
+			     "cpll/8", "spll/8", "cpll/12", "spll/12",	\
+			     "cpll/16", "spll/16", "cpll/24", "spll/24"),\
+	UNIPHIER_CLK_CPUGEAR("cpu-ipp", 34, 0x8100, 0xf, 8,		\
+			     "ippll/2", "spll/2", "ippll/3", "spll/3",	\
+			     "spll/4", "spll/8", "ippll/4", "ippll/8")
+
 const struct uniphier_clk_data uniphier_sld3_sys_clk_data[] = {
 	UNIPHIER_CLK_FACTOR("spll", -1, "ref", 65, 1),		/* 1597.44 MHz */
 	UNIPHIER_CLK_FACTOR("upll", -1, "ref", 6000, 512),	/* 288 MHz */
@@ -96,6 +109,8 @@
 };
 
 const struct uniphier_clk_data uniphier_pro5_sys_clk_data[] = {
+	UNIPHIER_CLK_FACTOR("cpll", -1, "ref", 140, 1),		/* 2800 MHz */
+	UNIPHIER_CLK_FACTOR("ippll", -1, "ref", 130, 1),	/* 2600 MHz */
 	UNIPHIER_CLK_FACTOR("spll", -1, "ref", 120, 1),		/* 2400 MHz */
 	UNIPHIER_CLK_FACTOR("dapll1", -1, "ref", 128, 1),	/* 2560 MHz */
 	UNIPHIER_CLK_FACTOR("dapll2", -1, "ref", 144, 125),	/* 2949.12 MHz */
@@ -106,10 +121,43 @@
 	UNIPHIER_PRO4_SYS_CLK_GIO(12),				/* PCIe, USB3 */
 	UNIPHIER_PRO4_SYS_CLK_USB3(14, 0),
 	UNIPHIER_PRO4_SYS_CLK_USB3(15, 1),
+#if 1
+	/*
+	 * TODO:
+	 * The return type of .round_rate() is "long", which is 32 bit wide on
+	 * 32 bit systems.  Clock rate greater than LONG_MAX (~ 2.15 GHz) is
+	 * treated as an error.  Needs a workaround until the problem is fixed.
+	 */
+	UNIPHIER_CLK_FACTOR("cpll/2", -1, "ref", 70, 1),
+	UNIPHIER_CLK_FACTOR("cpll/3", -1, "ref", 140, 3),
+	UNIPHIER_CLK_FACTOR("cpll/4", -1, "ref", 35, 1),
+	UNIPHIER_CLK_FACTOR("cpll/6", -1, "ref", 70, 3),
+	UNIPHIER_CLK_FACTOR("cpll/8", -1, "ref", 35, 2),
+	UNIPHIER_CLK_FACTOR("cpll/12", -1, "ref", 35, 3),
+	UNIPHIER_CLK_FACTOR("cpll/16", -1, "ref", 35, 4),
+	UNIPHIER_CLK_FACTOR("cpll/24", -1, "ref", 35, 6),
+	UNIPHIER_CLK_FACTOR("spll/2", -1, "ref", 60, 1),
+	UNIPHIER_CLK_FACTOR("spll/3", -1, "ref", 40, 1),
+	UNIPHIER_CLK_FACTOR("spll/4", -1, "ref", 30, 1),
+	UNIPHIER_CLK_FACTOR("spll/6", -1, "ref", 20, 1),
+	UNIPHIER_CLK_FACTOR("spll/8", -1, "ref", 15, 1),
+	UNIPHIER_CLK_FACTOR("spll/12", -1, "ref", 10, 1),
+	UNIPHIER_CLK_FACTOR("spll/16", -1, "ref", 15, 2),
+	UNIPHIER_CLK_FACTOR("spll/24", -1, "ref", 5, 1),
+	UNIPHIER_CLK_CPUGEAR("cpu-ca9", 32, 0x8000, 0x1f, 16,
+			     "cpll/2", "spll/2", "cpll/3", "spll/3",
+			     "cpll/4", "spll/4", "cpll/6", "spll/6",
+			     "cpll/8", "spll/8", "cpll/12", "spll/12",
+			     "cpll/16", "spll/16", "cpll/24", "spll/24"),
+#else
+	UNIPHIER_PRO5_SYS_CPUGEARS,
+#endif
 	{ /* sentinel */ }
 };
 
 const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[] = {
+	UNIPHIER_CLK_FACTOR("cpll", -1, "ref", 96, 1),		/* 2400 MHz */
+	UNIPHIER_CLK_FACTOR("ippll", -1, "ref", 96, 1),		/* 2400 MHz */
 	UNIPHIER_CLK_FACTOR("spll", -1, "ref", 96, 1),		/* 2400 MHz */
 	UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 27),
 	UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 48),
@@ -121,20 +169,70 @@
 	/* The document mentions 0x2104 bit 18, but not functional */
 	UNIPHIER_CLK_GATE("usb30-phy", 16, NULL, 0x2104, 19),
 	UNIPHIER_CLK_GATE("usb31-phy", 20, NULL, 0x2104, 20),
+#if 1
+	/*
+	 * TODO:
+	 * The return type of .round_rate() is "long", which is 32 bit wide on
+	 * 32 bit systems.  Clock rate greater than LONG_MAX (~ 2.15 GHz) is
+	 * treated as an error.  Needs a workaround until the problem is fixed.
+	 */
+	UNIPHIER_CLK_FACTOR("cpll/2", -1, "ref", 48, 1),
+	UNIPHIER_CLK_FACTOR("cpll/3", -1, "ref", 32, 1),
+	UNIPHIER_CLK_FACTOR("cpll/4", -1, "ref", 24, 1),
+	UNIPHIER_CLK_FACTOR("cpll/6", -1, "ref", 16, 1),
+	UNIPHIER_CLK_FACTOR("cpll/8", -1, "ref", 12, 1),
+	UNIPHIER_CLK_FACTOR("cpll/12", -1, "ref", 8, 1),
+	UNIPHIER_CLK_FACTOR("cpll/16", -1, "ref", 6, 1),
+	UNIPHIER_CLK_FACTOR("cpll/24", -1, "ref", 4, 1),
+	UNIPHIER_CLK_FACTOR("spll/2", -1, "ref", 48, 1),
+	UNIPHIER_CLK_FACTOR("spll/3", -1, "ref", 32, 1),
+	UNIPHIER_CLK_FACTOR("spll/4", -1, "ref", 24, 1),
+	UNIPHIER_CLK_FACTOR("spll/6", -1, "ref", 16, 1),
+	UNIPHIER_CLK_FACTOR("spll/8", -1, "ref", 12, 1),
+	UNIPHIER_CLK_FACTOR("spll/12", -1, "ref", 8, 1),
+	UNIPHIER_CLK_FACTOR("spll/16", -1, "ref", 6, 1),
+	UNIPHIER_CLK_FACTOR("spll/24", -1, "ref", 4, 1),
+	UNIPHIER_CLK_CPUGEAR("cpu-ca9", 32, 0x8000, 0x1f, 16,
+			     "cpll/2", "spll/2", "cpll/3", "spll/3",
+			     "cpll/4", "spll/4", "cpll/6", "spll/6",
+			     "cpll/8", "spll/8", "cpll/12", "spll/12",
+			     "cpll/16", "spll/16", "cpll/24", "spll/24"),
+#else
+	UNIPHIER_PRO5_SYS_CPUGEARS,
+#endif
 	{ /* sentinel */ }
 };
 
 const struct uniphier_clk_data uniphier_ld11_sys_clk_data[] = {
+	UNIPHIER_CLK_FACTOR("cpll", -1, "ref", 392, 5),		/* 1960 MHz */
+	UNIPHIER_CLK_FACTOR("mpll", -1, "ref", 64, 1),		/* 1600 MHz */
 	UNIPHIER_CLK_FACTOR("spll", -1, "ref", 80, 1),		/* 2000 MHz */
+	UNIPHIER_CLK_FACTOR("vspll", -1, "ref", 80, 1),		/* 2000 MHz */
 	UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 34),
 	UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 40),
 	UNIPHIER_LD11_SYS_CLK_STDMAC(8),			/* HSC, MIO */
 	UNIPHIER_CLK_FACTOR("usb2", -1, "ref", 24, 25),
+	/* CPU gears */
+	UNIPHIER_CLK_DIV4("cpll", 2, 3, 4, 8),
+	UNIPHIER_CLK_DIV4("mpll", 2, 3, 4, 8),
+	UNIPHIER_CLK_DIV3("spll", 3, 4, 8),
+	/* Note: both gear1 and gear4 are spll/4.  This is not a bug. */
+	UNIPHIER_CLK_CPUGEAR("cpu-ca53", 33, 0x8080, 0xf, 8,
+			     "cpll/2", "spll/4", "cpll/3", "spll/3",
+			     "spll/4", "spll/8", "cpll/4", "cpll/8"),
+	UNIPHIER_CLK_CPUGEAR("cpu-ipp", 34, 0x8100, 0xf, 8,
+			     "mpll/2", "spll/4", "mpll/3", "spll/3",
+			     "spll/4", "spll/8", "mpll/4", "mpll/8"),
 	{ /* sentinel */ }
 };
 
 const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = {
+	UNIPHIER_CLK_FACTOR("cpll", -1, "ref", 88, 1),		/* ARM: 2200 MHz */
+	UNIPHIER_CLK_FACTOR("gppll", -1, "ref", 52, 1),		/* Mali: 1300 MHz */
+	UNIPHIER_CLK_FACTOR("mpll", -1, "ref", 64, 1),		/* Codec: 1600 MHz */
 	UNIPHIER_CLK_FACTOR("spll", -1, "ref", 80, 1),		/* 2000 MHz */
+	UNIPHIER_CLK_FACTOR("s2pll", -1, "ref", 88, 1),		/* IPP: 2200 MHz */
+	UNIPHIER_CLK_FACTOR("vppll", -1, "ref", 504, 5),	/* 2520 MHz */
 	UNIPHIER_CLK_FACTOR("uart", 0, "spll", 1, 34),
 	UNIPHIER_CLK_FACTOR("i2c", 1, "spll", 1, 40),
 	UNIPHIER_LD20_SYS_CLK_SD,
@@ -147,5 +245,18 @@
 	UNIPHIER_CLK_GATE("usb30", 14, NULL, 0x210c, 14),
 	UNIPHIER_CLK_GATE("usb30-phy0", 16, NULL, 0x210c, 12),
 	UNIPHIER_CLK_GATE("usb30-phy1", 17, NULL, 0x210c, 13),
+	/* CPU gears */
+	UNIPHIER_CLK_DIV4("cpll", 2, 3, 4, 8),
+	UNIPHIER_CLK_DIV4("spll", 2, 3, 4, 8),
+	UNIPHIER_CLK_DIV4("s2pll", 2, 3, 4, 8),
+	UNIPHIER_CLK_CPUGEAR("cpu-ca72", 32, 0x8000, 0xf, 8,
+			     "cpll/2", "spll/2", "cpll/3", "spll/3",
+			     "spll/4", "spll/8", "cpll/4", "cpll/8"),
+	UNIPHIER_CLK_CPUGEAR("cpu-ca53", 33, 0x8080, 0xf, 8,
+			     "cpll/2", "spll/2", "cpll/3", "spll/3",
+			     "spll/4", "spll/8", "cpll/4", "cpll/8"),
+	UNIPHIER_CLK_CPUGEAR("cpu-ipp", 34, 0x8100, 0xf, 8,
+			     "s2pll/2", "spll/2", "s2pll/3", "spll/3",
+			     "spll/4", "spll/8", "s2pll/4", "s2pll/8"),
 	{ /* sentinel */ }
 };
diff --git a/drivers/clk/uniphier/clk-uniphier.h b/drivers/clk/uniphier/clk-uniphier.h
index 9707b0f..849824a 100644
--- a/drivers/clk/uniphier/clk-uniphier.h
+++ b/drivers/clk/uniphier/clk-uniphier.h
@@ -75,6 +75,20 @@ struct uniphier_clk_data {
 	} data;
 };
 
+#define UNIPHIER_CLK_CPUGEAR(_name, _idx, _regbase, _mask,	\
+			     _num_parents, ...)			\
+	{							\
+		.name = (_name),				\
+		.type = UNIPHIER_CLK_TYPE_CPUGEAR,		\
+		.idx = (_idx),					\
+		.data.cpugear = {				\
+			.parent_names = { __VA_ARGS__ },	\
+			.num_parents = (_num_parents),		\
+			.regbase = (_regbase),			\
+			.mask = (_mask)				\
+		 },						\
+	}
+
 #define UNIPHIER_CLK_FACTOR(_name, _idx, _parent, _mult, _div)	\
 	{							\
 		.name = (_name),				\
@@ -87,7 +101,6 @@ struct uniphier_clk_data {
 		},						\
 	}
 
-
 #define UNIPHIER_CLK_GATE(_name, _idx, _parent, _reg, _bit)	\
 	{							\
 		.name = (_name),				\
@@ -100,6 +113,26 @@ struct uniphier_clk_data {
 		},						\
 	}
 
+#define UNIPHIER_CLK_DIV(parent, div)				\
+	UNIPHIER_CLK_FACTOR(parent "/" #div, -1, parent, 1, div)
+
+#define UNIPHIER_CLK_DIV2(parent, div0, div1)			\
+	UNIPHIER_CLK_DIV(parent, div0),				\
+	UNIPHIER_CLK_DIV(parent, div1)
+
+#define UNIPHIER_CLK_DIV3(parent, div0, div1, div2)		\
+	UNIPHIER_CLK_DIV2(parent, div0, div1),			\
+	UNIPHIER_CLK_DIV(parent, div2)
+
+#define UNIPHIER_CLK_DIV4(parent, div0, div1, div2, div3)	\
+	UNIPHIER_CLK_DIV2(parent, div0, div1),			\
+	UNIPHIER_CLK_DIV2(parent, div2, div3)
+
+#define UNIPHIER_CLK_DIV8(parent, div0, div1, div2, div3,	\
+			  div4, div5, div6, div7)		\
+	UNIPHIER_CLK_DIV4(parent, div0, div1, div2, div3),	\
+	UNIPHIER_CLK_DIV4(parent, div4, div5, div6, div7)
+
 struct clk_hw *uniphier_clk_register_cpugear(struct device *dev,
 					     struct regmap *regmap,
 					     const char *name,
-- 
1.9.1

^ permalink raw reply related

* [PATCH 1/2] clk: uniphier: add CPU-gear change (cpufreq) support
From: Masahiro Yamada @ 2016-10-26 17:31 UTC (permalink / raw)
  To: linux-arm-kernel

Core support code for CPU frequency changes, which will be used by
the generic cpufreq driver.

The register view is different from the generic clk-mux; it has
a separate status register, and an update bit to load the register
setting.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---

 drivers/clk/uniphier/Makefile               |   3 +
 drivers/clk/uniphier/clk-uniphier-core.c    |   3 +
 drivers/clk/uniphier/clk-uniphier-cpugear.c | 115 ++++++++++++++++++++++++++++
 drivers/clk/uniphier/clk-uniphier.h         |  17 +++-
 4 files changed, 136 insertions(+), 2 deletions(-)
 create mode 100644 drivers/clk/uniphier/clk-uniphier-cpugear.c

diff --git a/drivers/clk/uniphier/Makefile b/drivers/clk/uniphier/Makefile
index f27b3603..665d1d6 100644
--- a/drivers/clk/uniphier/Makefile
+++ b/drivers/clk/uniphier/Makefile
@@ -1,8 +1,11 @@
 obj-y	+= clk-uniphier-core.o
+
+obj-y	+= clk-uniphier-cpugear.o
 obj-y	+= clk-uniphier-fixed-factor.o
 obj-y	+= clk-uniphier-fixed-rate.o
 obj-y	+= clk-uniphier-gate.o
 obj-y	+= clk-uniphier-mux.o
+
 obj-y	+= clk-uniphier-sys.o
 obj-y	+= clk-uniphier-mio.o
 obj-y	+= clk-uniphier-peri.o
diff --git a/drivers/clk/uniphier/clk-uniphier-core.c b/drivers/clk/uniphier/clk-uniphier-core.c
index 26c53f7..0007218 100644
--- a/drivers/clk/uniphier/clk-uniphier-core.c
+++ b/drivers/clk/uniphier/clk-uniphier-core.c
@@ -27,6 +27,9 @@ static struct clk_hw *uniphier_clk_register(struct device *dev,
 					const struct uniphier_clk_data *data)
 {
 	switch (data->type) {
+	case UNIPHIER_CLK_TYPE_CPUGEAR:
+		return uniphier_clk_register_cpugear(dev, regmap, data->name,
+						     &data->data.cpugear);
 	case UNIPHIER_CLK_TYPE_FIXED_FACTOR:
 		return uniphier_clk_register_fixed_factor(dev, data->name,
 							  &data->data.factor);
diff --git a/drivers/clk/uniphier/clk-uniphier-cpugear.c b/drivers/clk/uniphier/clk-uniphier-cpugear.c
new file mode 100644
index 0000000..9bff26e
--- /dev/null
+++ b/drivers/clk/uniphier/clk-uniphier-cpugear.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2016 Socionext Inc.
+ *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/regmap.h>
+
+#include "clk-uniphier.h"
+
+#define UNIPHIER_CLK_CPUGEAR_STAT	0	/* status */
+#define UNIPHIER_CLK_CPUGEAR_SET	4	/* set */
+#define UNIPHIER_CLK_CPUGEAR_UPD	8	/* update */
+#define   UNIPHIER_CLK_CPUGEAR_UPD_BIT	BIT(0)
+
+struct uniphier_clk_cpugear {
+	struct clk_hw hw;
+	struct regmap *regmap;
+	unsigned int regbase;
+	unsigned int mask;
+};
+
+#define to_uniphier_clk_cpugear(_hw) \
+			container_of(_hw, struct uniphier_clk_cpugear, hw)
+
+static int uniphier_clk_cpugear_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct uniphier_clk_cpugear *gear = to_uniphier_clk_cpugear(hw);
+	int ret;
+	unsigned int val;
+
+	ret = regmap_write_bits(gear->regmap,
+				gear->regbase + UNIPHIER_CLK_CPUGEAR_SET,
+				gear->mask, index);
+	if (ret)
+		return ret;
+
+	ret = regmap_write_bits(gear->regmap,
+				gear->regbase + UNIPHIER_CLK_CPUGEAR_SET,
+				UNIPHIER_CLK_CPUGEAR_UPD_BIT,
+				UNIPHIER_CLK_CPUGEAR_UPD_BIT);
+	if (ret)
+		return ret;
+
+	return regmap_read_poll_timeout(gear->regmap,
+				gear->regbase + UNIPHIER_CLK_CPUGEAR_UPD,
+				val, !(val & UNIPHIER_CLK_CPUGEAR_UPD_BIT),
+				0, 1);
+}
+
+static u8 uniphier_clk_cpugear_get_parent(struct clk_hw *hw)
+{
+	struct uniphier_clk_cpugear *gear = to_uniphier_clk_cpugear(hw);
+	int num_parents = clk_hw_get_num_parents(hw);
+	int ret;
+	unsigned int val;
+
+	ret = regmap_read(gear->regmap,
+			  gear->regbase + UNIPHIER_CLK_CPUGEAR_STAT, &val);
+	if (ret)
+		return ret;
+
+	val &= gear->mask;
+
+	return val < num_parents ? val : -EINVAL;
+}
+
+static const struct clk_ops uniphier_clk_cpugear_ops = {
+	.determine_rate = __clk_mux_determine_rate,
+	.set_parent = uniphier_clk_cpugear_set_parent,
+	.get_parent = uniphier_clk_cpugear_get_parent,
+};
+
+struct clk_hw *uniphier_clk_register_cpugear(struct device *dev,
+					 struct regmap *regmap,
+					 const char *name,
+				const struct uniphier_clk_cpugear_data *data)
+{
+	struct uniphier_clk_cpugear *gear;
+	struct clk_init_data init;
+	int ret;
+
+	gear = devm_kzalloc(dev, sizeof(*gear), GFP_KERNEL);
+	if (!gear)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &uniphier_clk_cpugear_ops;
+	init.flags = CLK_SET_RATE_PARENT;
+	init.parent_names = data->parent_names;
+	init.num_parents = data->num_parents,
+
+	gear->regmap = regmap;
+	gear->regbase = data->regbase;
+	gear->mask = data->mask;
+	gear->hw.init = &init;
+
+	ret = devm_clk_hw_register(dev, &gear->hw);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return &gear->hw;
+}
diff --git a/drivers/clk/uniphier/clk-uniphier.h b/drivers/clk/uniphier/clk-uniphier.h
index 0244dba..9707b0f 100644
--- a/drivers/clk/uniphier/clk-uniphier.h
+++ b/drivers/clk/uniphier/clk-uniphier.h
@@ -20,15 +20,24 @@
 struct device;
 struct regmap;
 
-#define UNIPHIER_CLK_MUX_MAX_PARENTS	8
+#define UNIPHIER_CLK_CPUGEAR_MAX_PARENTS	16
+#define UNIPHIER_CLK_MUX_MAX_PARENTS		8
 
 enum uniphier_clk_type {
+	UNIPHIER_CLK_TYPE_CPUGEAR,
 	UNIPHIER_CLK_TYPE_FIXED_FACTOR,
 	UNIPHIER_CLK_TYPE_FIXED_RATE,
 	UNIPHIER_CLK_TYPE_GATE,
 	UNIPHIER_CLK_TYPE_MUX,
 };
 
+struct uniphier_clk_cpugear_data {
+	const char *parent_names[UNIPHIER_CLK_CPUGEAR_MAX_PARENTS];
+	unsigned int num_parents;
+	unsigned int regbase;
+	unsigned int mask;
+};
+
 struct uniphier_clk_fixed_factor_data {
 	const char *parent_name;
 	unsigned int mult;
@@ -58,6 +67,7 @@ struct uniphier_clk_data {
 	enum uniphier_clk_type type;
 	int idx;
 	union {
+		struct uniphier_clk_cpugear_data cpugear;
 		struct uniphier_clk_fixed_factor_data factor;
 		struct uniphier_clk_fixed_rate_data rate;
 		struct uniphier_clk_gate_data gate;
@@ -90,7 +100,10 @@ struct uniphier_clk_data {
 		},						\
 	}
 
-
+struct clk_hw *uniphier_clk_register_cpugear(struct device *dev,
+					     struct regmap *regmap,
+					     const char *name,
+				const struct uniphier_clk_cpugear_data *data);
 struct clk_hw *uniphier_clk_register_fixed_factor(struct device *dev,
 						  const char *name,
 			const struct uniphier_clk_fixed_factor_data *data);
-- 
1.9.1

^ permalink raw reply related

* [RFC PATCH 4/5] w1: add a callback to call slave when a new device is connected
From: Antoine Tenart @ 2016-10-26 17:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CANLsYkxfnF9-H9mawt3BWTgy5gjf8Qs3O6iSRGiLQ=8vfYACTQ@mail.gmail.com>

Hello Mathieu,

On Wed, Oct 26, 2016 at 10:42:28AM -0600, Mathieu Poirier wrote:
> On 26 October 2016 at 08:57, Antoine Tenart
> <antoine.tenart@free-electrons.com> wrote:
> >                 }
> > +               if (fops->callback) {
> > +                       err = fops->callback(sl);
> > +                       /*
> > +                        * Do not return an error as the slave driver correctly
> > +                        * probed.
> > +                        */
> 
> I don't get this part.  What's the point of calling a callback if a
> failure is not important - maybe I'm just missing something.
> 
> > +                       if (err)
> > +                               dev_err(&sl->dev,
> > +                                       "callback call failed. err=%d\n", err);
> > +               }

In our case it can be not that important: if we fail to apply an
overlay, we can still use the w1 interfaces to access the eeprom.

Anyway, all those errors weren't taken into account by the w1 framework
before (see my other patch). Also, the w1 patches are given for the
example and could be improved. Part of the reason is the w1 framework
itself :-)

Antoine

-- 
Antoine T?nart, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161026/0499f6d0/attachment.sig>

^ permalink raw reply

* [PATCH 1/2] ARM: dma-mapping: Support cache sync after arm_dma_get_sgtable
From: Robin Murphy @ 2016-10-26 17:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477501448-30915-2-git-send-email-thierry.escande@collabora.com>

On 26/10/16 18:04, Thierry Escande wrote:
> From: Heng-Ruey Hsu <henryhsu@chromium.org>
> 
> Currently arm_dma_sync_sg_* require dma_address to do cache sync. But
> dma address is set by map_sg(). We can't do cache sync after
> arm_dma_get_sgtable. The behavior is different from iommu_ops.
> 
> We don't have to get dma address in arm_dma_sync_sg_* and convert the
> address to physical address in arm_dma_sync_single_*. With this change
> sg_page() is used to get physical address and do sync directly.
> 
> Signed-off-by: Heng-Ruey Hsu <henryhsu@chromium.org>
> Tested-by: Heng-ruey Hsu <henryhsu@chromium.org>
> Reviewed-by: Tomasz Figa <tfiga@chromium.org>
> Signed-off-by: Thierry Escande <thierry.escande@collabora.com>
> ---
>  arch/arm/mm/dma-mapping.c | 8 ++------
>  1 file changed, 2 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index ab4f745..dc42ca6 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -1120,13 +1120,11 @@ void arm_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
>  void arm_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
>  			int nents, enum dma_data_direction dir)
>  {
> -	struct dma_map_ops *ops = get_dma_ops(dev);
>  	struct scatterlist *s;
>  	int i;
>  
>  	for_each_sg(sg, s, nents, i)
> -		ops->sync_single_for_cpu(dev, sg_dma_address(s), s->length,
> -					 dir);
> +		__dma_page_dev_to_cpu(sg_page(s), s->offset, s->length, dir);

This breaks dmabounce. The .sync_single_for_cpu implementation there is
non-trivial.

Robin.

>  }
>  
>  /**
> @@ -1139,13 +1137,11 @@ void arm_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
>  void arm_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
>  			int nents, enum dma_data_direction dir)
>  {
> -	struct dma_map_ops *ops = get_dma_ops(dev);
>  	struct scatterlist *s;
>  	int i;
>  
>  	for_each_sg(sg, s, nents, i)
> -		ops->sync_single_for_device(dev, sg_dma_address(s), s->length,
> -					    dir);
> +		__dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir);
>  }
>  
>  /*
> 

^ permalink raw reply

* [PATCH v3] drivers: psci: PSCI checker module
From: Paul E. McKenney @ 2016-10-26 17:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026171006.GA16248@red-moon>

On Wed, Oct 26, 2016 at 06:10:06PM +0100, Lorenzo Pieralisi wrote:
> On Wed, Oct 26, 2016 at 08:18:58AM -0700, Paul E. McKenney wrote:
> > On Wed, Oct 26, 2016 at 02:17:52PM +0100, Lorenzo Pieralisi wrote:
> > > On Tue, Oct 25, 2016 at 11:34:36AM -0700, Paul E. McKenney wrote:
> > > 
> > > [...]
> > > 
> > > > > > +static int __init psci_checker(void)
> > > > > > +{
> > > > > > +	int ret;
> > > > > > +
> > > > > > +	/*
> > > > > > +	 * Since we're in an initcall, we assume that all the CPUs that all
> > > > > > +	 * CPUs that can be onlined have been onlined.
> > > > > > +	 *
> > > > > > +	 * The tests assume that hotplug is enabled but nobody else is using it,
> > > > > > +	 * otherwise the results will be unpredictable. However, since there
> > > > > > +	 * is no userspace yet in initcalls, that should be fine.
> > > > > 
> > > > > I do not think it is. If you run a kernel with, say,
> > > > > CONFIG_LOCK_TORTURE_TEST, cpus may disappear from the radar while
> > > > > running the PSCI checker test itself; that at least would confuse the
> > > > > checker, and that's just an example.
> > > > > 
> > > > > I added Paul to check what are the assumptions behind the torture test
> > > > > hotplug tests, in particular if there are any implicit assumptions for
> > > > > it to work (ie it is the only kernel test hotplugging cpus in and out
> > > > > (?)), what I know is that the PSCI checker assumptions are not correct.
> > > > 
> > > > Both CONFIG_LOCK_TORTURE_TEST and CONFIG_RCU_TORTURE_TEST can and will
> > > > hotplug CPUs.  The locktorture.onoff_holdoff and rcutorture.onoff_holdoff
> > > > kernel parameters can delay the start of CPU-hotplug testing, and in
> > > > my testing I set this delay to 30 seconds after boot.
> > > > 
> > > > One approach would be to make your test refuse to run if either of
> > > > the lock/RCU torture tests was running.  Or do what Lorenzo suggests
> > > > below.  The torture tests aren't crazy enough to offline the last CPU.
> > > > Though they do try, just for effect, in cases where the last CPU is
> > > > marked cpu_is_hotpluggable().  ;-)
> > > 
> > > Thank you Paul. I have an additional question though. Is there any
> > > implicit assumption in LOCK/RCU torture tests whereby nothing else
> > > in the kernel is hotplugging cpus in/out (through cpu_down()/up())
> > > while they are running ?
> > > 
> > > I am asking because that's the main reason behind my query. Those tests
> > > hotplug cpus in and out through cpu_down/up() but AFAICS nothing
> > > prevents another piece of code in the kernel to call those functions and
> > > the tests may just fail in that case (ie trying to cpu_down() a cpu
> > > that is not online).
> > > 
> > > Are false negatives contemplated (or I am missing something) ?
> > 
> > The current code assumes nothing else doing CPU-hotplug operations,
> > and will therefore print "RCU_HOTPLUG" error (or "LOCK_HOTPLUG" for
> > locktorture) if any of the hotplug operations failed.
> > 
> > > I just would like to understand if what this patch currently does
> > > is safe and sound. I think that calling cpu_down() and cpu_up()
> > > is always safe, but the test can result in false negatives if
> > > other kernel subsystems (eg LOCK torture test) are calling those
> > > APIs in parallel (because cpu_down()/cpu_up() calls can fail - eg
> > > trying to cpu_down() a cpu that is not online any longer, since it
> > > was taken down by another kernel control path), that's the question
> > > I have.
> > 
> > I am assuming that these added calls to cpu_down() and cpu_up() aren't
> > enabled by default.  If they are, rcutorture and locktorture need some
> > way to turn the off.
> > 
> > So maybe we need to have some sort of API that detects concurrent
> > CPU-hotplug torturing?  Maybe something like the following?
> > 
> > 	static atomic_t n_cpu_hotplug_torturers;
> > 	static atomic_t cpu_hotplug_concurrent_torture;
> > 
> > 	void torture_start_cpu_hotplug(void)
> > 	{
> > 		if (atomic_inc_return(&n_cpu_hotplug_torturers) > 1)
> > 			atomic_inc(&cpu_hotplug_concurrent_torture);
> > 	}
> > 
> > 	void torture_end_cpu_hotplug(void)
> > 	{
> > 		atomic_dec(&n_cpu_hotplug_torturers);
> > 	}
> > 
> > 	bool torture_cpu_hotplug_was_concurrent(void)
> > 	{
> > 		return !!atomic_read(&cpu_hotplug_concurrent_torture);
> > 	}
> > 
> > The locktorture and rcutorture code could then ignore CPU-hotplug
> > errors that could be caused by concurrent access.  And complain
> > bitterly about the concurrent access, of course!  ;-)
> 
> This could do, even better if we extend the torture hotplug tests to
> take a cpumask so that basically Kevin's patch will be based on torture
> hotplug tests infrastructure :D (ie he/we wanted to hotplug a subset of
> the online mask corresponding to a "cluster" of cpus, that's to test the
> PSCI CPU ON/OFF firmware interface behind cpu hotplug operations).
> 
> Still, this implies logging every possible cpu_down()/cpu_up() caller
> through torture_start_cpu_hotplug().
> 
> What about userspace and sysfs interface that allow to offline cpus then ?
> Point is, the torture hotplug tests take a snapshot of the maxcpu at
> kthread init time and then randomize the logical cpu number, but it is
> definitely possible unless I am mistaken that some of those cpus
> disappear while the test is running and this will cause failures that
> you can't detect through the API above.
> 
> That's why I suggested using the:
> 
> freeze_secondary_cpus(int primary);
> 
> for this patch because that allows us to quiesce all cpus other than
> primary at once, with no interference possible from other kernel control
> paths (but it is not a perfect solution either).
> 
> Userspace notwithstanding, I think the best solution consists in either
> making this patch hotplug tests work on top of the torture hotplug tests
> API or solving the dependency at kconfig level by disabling the PSCI
> checker if any of torture tests are enabled which is not ideal but
> I do not see any other option.
> 
> Thanks a lot for your feedback, thoughts appreciated.

Let me ask the question more directly.

Why on earth are we trying to run these tests concurrently?

After all, if we just run one at a time in isolation, there is no problem.

							Thanx, Paul

^ permalink raw reply

* [PATCH V3 0/8] IOMMU probe deferral support
From: Robin Murphy @ 2016-10-26 17:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <003a01d22f97$82534c70$86f9e550$@codeaurora.org>

On 26/10/16 15:44, Sricharan wrote:
> Hi Robin,
> 
>> On 04/10/16 18:03, Sricharan R wrote:
>>> Initial post from Laurent Pinchart[1]. This is
>>> series calls the dma ops configuration for the devices
>>> at a generic place so that it works for all busses.
>>> The dma_configure_ops for a device is now called during
>>> the device_attach callback just before the probe of the
>>> bus/driver is called. Similarly dma_deconfigure is called during
>>> device/driver_detach path.
>>>
>>>
>>> pci_bus_add_devices    (platform/amba)(_device_create/driver_register)
>>>        |                         |
>>> pci_bus_add_device     (device_add/driver_register)
>>>        |                         |
>>> device_attach           device_initial_probe
>>>        |                         |
>>> __device_attach_driver    __device_attach_driver
>>>        |
>>> driver_probe_device
>>>        |
>>> really_probe
>>>        |
>>> dma_configure
>>>
>>>  Similarly on the device/driver_unregister path __device_release_driver is
>>>  called which inturn calls dma_deconfigure.
>>>
>>>  If the ACPI bus code follows the same, we can add acpi_dma_configure
>>>  at the same place as of_dma_configure.
>>>
>>>  This series is based on the recently merged Generic DT bindings for
>>>  PCI IOMMUs and ARM SMMU from Robin Murphy robin.murphy at arm.com [2]
>>>
>>>  This time tested this with platform and pci device for probe deferral
>>>  and reprobe on arm64 based platform. There is an issue on the cleanup
>>>  path for arm64 though, where there is WARN_ON if the dma_ops is reset while
>>>  device is attached to an domain in arch_teardown_dma_ops.
>>>  But with iommu_groups created from the iommu driver, the device is always
>>>  attached to a domain/default_domain. So so the WARN has to be removed/handled
>>>  probably.
>>
>> I've finally got the chance to take a proper look at this series (sorry
>> for the delay). First up, with these patches on top of 4.9-rc2, my
>> little script for unbinding some PCI devices and rebinding them to VFIO
>> now goes horribly, horribly wrong.
>>
>> Robin.
>>
> 
>    Thanks for looking in to this.
>     I was trying to reproduce the below with a command like this in my setup.
> 
> echo 0002\:00\:00.0 >  /sys/bus/pci/devices/0002\:00\:000.0/driver/unbind0.0/driver/unbind
> echo 0x17cb 0x0104 > /sys/bus/pci/drivers/vfio-pci/new_id
> 
> But for me the unbind and reconfiguring/adding the iommus_ops to vfio-pci did
> succeed, although the WARN_ON in arch_teardown_dma_ops was there, that

Oh, yes, I hacked that out already to cut the noise down.

> could be suppresed.  The vfio_pci_probe was not going through because
>  the pci hdr_type was not PCI_HEADER_TYPE_NORMAL.
>  But anyways iommu unbind/rebind seemed to be going through.
> 
> If i can get what your script is doing, i can try that and see what happens.

---8<---
#!/bin/sh

#Juno Sky2, SATA
DEVICES='0000:08:00.0 0000:03:00.0'

for DEV in $DEVICES
do
	BUSDEV=/sys/bus/pci/devices/$DEV
	GROUP=$(basename $(readlink $BUSDEV/iommu_group))
	DRV=$(readlink -f $BUSDEV/driver)
	read VID < $BUSDEV/vendor
	read DID < $BUSDEV/device

	echo $DEV > $BUSDEV/driver/unbind
	echo $VID $DID > /sys/bus/pci/drivers/vfio-pci/new_id
done
# it would then goes on to launch kvmtool and rebind the original
# drivers afterwards, but that doesn't matter here
--->8---

The segfault doesn't always happen, but the kref warnings and the
vfio-pci driver failing to probe certainly do.

> 
> Regards,
>   Sricharan
> 
> 
> 
>> [   39.901592] iommu: Removing device 0000:08:00.0 from group 0

Yikes, on second look, that definitely shouldn't be happening.
Everything below is probably the resulting fallout.

Robin.

>> [   39.907383] ------------[ cut here ]------------
>> [   39.911969] WARNING: CPU: 0 PID: 174 at
>> arch/arm64/mm/dma-mapping.c:856 arch_teardown_dma_ops+0x48/0x68
>> [   39.921266] Modules linked in:
>> [   39.924290]
>> [   39.925766] CPU: 0 PID: 174 Comm: vfio Not tainted 4.9.0-rc2+ #1249
>> [   39.931967] Hardware name: ARM Juno development board (r1) (DT)
>> [   39.937826] task: ffffffc975ee9900 task.stack: ffffffc974d60000
>> [   39.943687] PC is at arch_teardown_dma_ops+0x48/0x68
>> [   39.948603] LR is at arch_teardown_dma_ops+0x34/0x68
>> [   39.953516] pc : [<ffffff80080948f8>] lr : [<ffffff80080948e4>]
>> pstate: 60000145
>> [   39.960834] sp : ffffffc974d63ca0
>> [   39.964112] x29: ffffffc974d63ca0 x28: ffffffc974d60000
>> [   39.969377] x27: ffffff80088a2000 x26: 0000000000000040
>> [   39.974642] x25: 0000000000000123 x24: ffffffc976a48918
>> [   39.979907] x23: ffffffc974d63eb8 x22: ffffff8008db7550
>> [   39.985171] x21: 000000000000000d x20: ffffffc9763e9b50
>> [   39.990435] x19: ffffffc9763f20a0 x18: 0000000000000010
>> [   39.995699] x17: 0000007f99c18018 x16: ffffff80080c0580
>> [   40.000964] x15: ffffff8008bb7000 x14: 000137c100013798
>> [   40.006228] x13: ffffffffff000000 x12: ffffffffffffffff
>> [   40.011492] x11: 0000000000000018 x10: 000000000000000d
>> [   40.016757] x9 : 0000000040000000 x8 : 0000000000210d00
>> [   40.022021] x7 : 00000049771bc000 x6 : 00000000001f17ed
>> [   40.027286] x5 : ffffff80084c4208 x4 : 0000000000000080
>> [   40.032551] x3 : ffffffc975ea9800 x2 : ffffffbf25d7aa50
>> [   40.037815] x1 : 0000000000000000 x0 : 0000000000000080
>> [   40.043078]
>> [   40.044549] ---[ end trace 35c1e743d6e6c035 ]---
>> [   40.049117] Call trace:
>> [   40.051537] Exception stack(0xffffffc974d63ad0 to 0xffffffc974d63c00)
>> [   40.057914] 3ac0:                                   ffffffc9763f20a0
>> 0000008000000000
>> [   40.065668] 3ae0: ffffffc974d63ca0 ffffff80080948f8 ffffffbf25d7aa40
>> ffffffc975ea9800
>> [   40.073421] 3b00: ffffffc974d60000 000000000002fc80 ffffffc976801e00
>> ffffffc974d60000
>> [   40.081175] 3b20: ffffff80084c4208 0000000000000040 ffffff80088a2000
>> ffffffc974d60000
>> [   40.088928] 3b40: ffffff80084caf78 ffffffc974d60000 ffffffc974d60000
>> ffffffc974d60000
>> [   40.096682] 3b60: ffffffc975ea9800 ffffffc974d60000 0000000000000080
>> 0000000000000000
>> [   40.104435] 3b80: ffffffbf25d7aa50 ffffffc975ea9800 0000000000000080
>> ffffff80084c4208
>> [   40.112188] 3ba0: 00000000001f17ed 00000049771bc000 0000000000210d00
>> 0000000040000000
>> [   40.119941] 3bc0: 000000000000000d 0000000000000018 ffffffffffffffff
>> ffffffffff000000
>> [   40.127695] 3be0: 000137c100013798 ffffff8008bb7000 ffffff80080c0580
>> 0000007f99c18018
>> [   40.135450] [<ffffff80080948f8>] arch_teardown_dma_ops+0x48/0x68
>> [   40.141400] [<ffffff8008764a14>] of_dma_deconfigure+0xc/0x18
>> [   40.147005] [<ffffff8008552804>] dma_deconfigure+0xc/0x18
>> [   40.152353] [<ffffff800853ba10>] __device_release_driver+0x88/0x120
>> [   40.158560] [<ffffff800853bacc>] device_release_driver+0x24/0x38
>> [   40.164507] [<ffffff800853a868>] unbind_store+0xe8/0x110
>> [   40.169767] [<ffffff8008539c70>] drv_attr_store+0x20/0x30
>> [   40.175113] [<ffffff800823ab18>] sysfs_kf_write+0x48/0x58
>> [   40.180458] [<ffffff8008239ea8>] kernfs_fop_write+0xb0/0x1d8
>> [   40.186063] [<ffffff80081c507c>] __vfs_write+0x1c/0x100
>> [   40.191237] [<ffffff80081c5e80>] vfs_write+0xa0/0x1b8
>> [   40.196239] [<ffffff80081c7274>] SyS_write+0x44/0xa0
>> [   40.201155] [<ffffff8008082ef0>] el0_svc_naked+0x24/0x28
>> [   40.206703] vfio-pci 0000:08:00.0: Failed to setup iommu ops
>> [   40.212382] vfio-pci: probe of 0000:08:00.0 failed with error -22
>> [   40.228075] ------------[ cut here ]------------
>> [   40.235263] WARNING: CPU: 1 PID: 174 at ./include/linux/kref.h:46
>> kobject_get+0x64/0x88
>> [   40.243181] Modules linked in:
>> [   40.246201]
>> [   40.247673] CPU: 1 PID: 174 Comm: vfio Tainted: G        W
>> 4.9.0-rc2+ #1249
>> [   40.255076] Hardware name: ARM Juno development board (r1) (DT)
>> [   40.260932] task: ffffffc975ee9900 task.stack: ffffffc974d60000
>> [   40.266787] PC is at kobject_get+0x64/0x88
>> [   40.270840] LR is at iommu_bus_notifier+0x40/0x110
>> [   40.275577] pc : [<ffffff800834d20c>] lr : [<ffffff80084c3fd0>]
>> pstate: 80000145
>> [   40.282894] sp : ffffffc974d63c00
>> [   40.286169] x29: ffffffc974d63c00 x28: ffffffc974d60000
>> [   40.291431] x27: ffffff80088a2000 x26: 0000000000000040
>> [   40.296692] x25: 0000000000000123 x24: ffffffc974c8f418
>> [   40.301953] x23: 0000000000000006 x22: ffffffc9763f10a0
>> [   40.307214] x21: ffffffc9763e9a00 x20: ffffffc9763f10a0
>> [   40.312474] x19: ffffffc9763ebc80 x18: 0000007fd65069e0
>> [   40.317734] x17: 0000007f8d0ae3c0 x16: ffffff80081c7230
>> [   40.322995] x15: 0000007f8d136588 x14: ffffffffffffffff
>> [   40.328255] x13: 0000000000000004 x12: 0000000000000030
>> [   40.333515] x11: 0000000000000030 x10: 0101010101010101
>> [   40.338775] x9 : feff716475687163 x8 : 7f7f7f7f7f7f7f7f
>> [   40.344035] x7 : feff716475687163 x6 : ffffffc976abf400
>> [   40.349295] x5 : ffffffc976abf400 x4 : 0000000000000000
>> [   40.354555] x3 : ffffff80084c3f90 x2 : ffffffc9763ebcb8
>> [   40.359814] x1 : 0000000000000001 x0 : ffffff8008d4f000
>> [   40.365074]
>> [   40.366542] ---[ end trace 35c1e743d6e6c036 ]---
>> [   40.371107] Call trace:
>> [   40.373523] Exception stack(0xffffffc974d63a30 to 0xffffffc974d63b60)
>> [   40.379895] 3a20:                                   ffffffc9763ebc80
>> 0000008000000000
>> [   40.387643] 3a40: ffffffc974d63c00 ffffff800834d20c ffffffc976812400
>> ffffff8008237d94
>> [   40.395391] 3a60: ffffffbf25d78940 ffffffc974d60000 ffffffc975e259d8
>> 0000000000005b81
>> [   40.403139] 3a80: ffffffc974d60000 ffffff8008d4b31f ffffff8008b0f000
>> ffffffc976811c80
>> [   40.410887] 3aa0: ffffffc974d60000 ffffffc974d60000 ffffffc974d60000
>> ffffff8008237000
>> [   40.418634] 3ac0: ffffffc975e259d8 ffffff8008b1b9a8 ffffff8008d4f000
>> 0000000000000001
>> [   40.426382] 3ae0: ffffffc9763ebcb8 ffffff80084c3f90 0000000000000000
>> ffffffc976abf400
>> [   40.434130] 3b00: ffffffc976abf400 feff716475687163 7f7f7f7f7f7f7f7f
>> feff716475687163
>> [   40.441877] 3b20: 0101010101010101 0000000000000030 0000000000000030
>> 0000000000000004
>> [   40.449625] 3b40: ffffffffffffffff 0000007f8d136588 ffffff80081c7230
>> 0000007f8d0ae3c0
>> [   40.457372] [<ffffff800834d20c>] kobject_get+0x64/0x88
>> [   40.462455] [<ffffff80084c3fd0>] iommu_bus_notifier+0x40/0x110
>> [   40.468227] [<ffffff80080da288>] notifier_call_chain+0x50/0x90
>> [   40.473997] [<ffffff80080da694>] __blocking_notifier_call_chain+0x4c/0x90
>> [   40.480713] [<ffffff80080da6ec>] blocking_notifier_call_chain+0x14/0x20
>> [   40.487259] [<ffffff800853b9e4>] __device_release_driver+0x5c/0x120
>> [   40.493460] [<ffffff800853bacc>] device_release_driver+0x24/0x38
>> [   40.499402] [<ffffff800853a868>] unbind_store+0xe8/0x110
>> [   40.504656] [<ffffff8008539c70>] drv_attr_store+0x20/0x30
>> [   40.509997] [<ffffff800823ab18>] sysfs_kf_write+0x48/0x58
>> [   40.515337] [<ffffff8008239ea8>] kernfs_fop_write+0xb0/0x1d8
>> [   40.520936] [<ffffff80081c507c>] __vfs_write+0x1c/0x100
>> [   40.526104] [<ffffff80081c5e80>] vfs_write+0xa0/0x1b8
>> [   40.531100] [<ffffff80081c7274>] SyS_write+0x44/0xa0
>> [   40.536011] [<ffffff8008082ef0>] el0_svc_naked+0x24/0x28
>> [   40.541324] ata1.00: disabled
>> [   40.544878] sd 0:0:0:0: [sda] Synchronizing SCSI cache
>> [   40.550062] sd 0:0:0:0: [sda] Synchronize Cache(10) failed: Result:
>> hostbyte=0x04 driverbyte=0x00
>> [   40.558871] sd 0:0:0:0: [sda] Stopping disk
>> [   40.563037] sd 0:0:0:0: [sda] Start/Stop Unit failed: Result:
>> hostbyte=0x04 driverbyte=0x00
>> [   40.586990] Unable to handle kernel paging request at virtual address
>> 0002003e
>> [   40.594702] pgd = ffffffc974c80000
>> [   40.598165] [0002003e] *pgd=00000009f5102003[   40.602241] ,
>> *pud=00000009f5102003
>> , *pmd=0000000000000000[   40.607694]
>> [   40.609171] Internal error: Oops: 96000006 [#1] PREEMPT SMP
>> [   40.614684] Modules linked in:
>> [   40.617712] CPU: 3 PID: 174 Comm: vfio Tainted: G        W
>> 4.9.0-rc2+ #1249
>> [   40.625118] Hardware name: ARM Juno development board (r1) (DT)
>> [   40.630977] task: ffffffc975ee9900 task.stack: ffffffc974d60000
>> [   40.636841] PC is at kobject_get+0x14/0x88
>> [   40.640897] LR is at iommu_get_domain_for_dev+0x1c/0x48
>> [   40.646068] pc : [<ffffff800834d1bc>] lr : [<ffffff80084c3dec>]
>> pstate: 60000145
>> [   40.653387] sp : ffffffc974d63c60
>> [   40.656664] x29: ffffffc974d63c60 x28: ffffffc974d60000
>> [   40.661928] x27: ffffff80088a2000 x26: 0000000000000040
>> [   40.667193] x25: 0000000000000123 x24: ffffffc974c8f418
>> [   40.672457] x23: ffffffc974d63eb8 x22: ffffff8008dab568
>> [   40.677720] x21: 000000000000000d x20: ffffff8008dab568
>> [   40.682984] x19: 0000000000020002 x18: 0000000000000000
>> [   40.688246] x17: 0000000000000007 x16: 0000000000000001
>> [   40.693509] x15: ffffffc974cd091c x14: ffffffffffffffff
>> [   40.698773] x13: ffffffc974cd01cd x12: 0000000000000030
>> [   40.704036] x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f
>> [   40.709300] x9 : 0000000040000000 x8 : 0000000000210d00
>> [   40.714563] x7 : ffffffc975f95018 x6 : 0000000000000000
>> [   40.719826] x5 : 0000000000000000 x4 : ffffffc9763f1210
>> [   40.725088] x3 : 0000000000000000 x2 : ffffffc9763f10e8
>> [   40.730351] x1 : 0000000000000000 x0 : 0000000000020002
>> [   40.735613]
>> [   40.737085] Process vfio (pid: 174, stack limit = 0xffffffc974d60020)
>> [   40.743460] Stack: (0xffffffc974d63c60 to 0xffffffc974d64000)
>> [   40.749150] 3c60: ffffffc974d63c80 ffffff80084c3dec ffffffc9763e9a00
>> ffffff80085377a4
>> [   40.756904] 3c80: ffffffc974d63ca0 ffffff80080948c4 ffffffc9763f10a0
>> ffffff8008dab568
>> [   40.764658] 3ca0: ffffffc974d63cc0 ffffff8008764a14 ffffffc9763f10a0
>> ffffff8008dab568
>> [   40.772411] 3cc0: ffffffc974d63cd0 ffffff8008552804 ffffffc974d63ce0
>> ffffff800853ba10
>> [   40.780165] 3ce0: ffffffc974d63d00 ffffff800853bacc ffffffc9763f1100
>> ffffffc9763f10a0
>> [   40.787918] 3d00: ffffffc974d63d20 ffffff800853a868 ffffff8008d68f18
>> ffffffc9763f10a0
>> [   40.795672] 3d20: ffffffc974d63d50 ffffff8008539c70 000000000000000d
>> ffffffc974c8f400
>> [   40.803425] 3d40: ffffffc9757d5880 0000000000000000 ffffffc974d63d60
>> ffffff800823ab18
>> [   40.811178] 3d60: ffffffc974d63d70 ffffff8008239ea8 ffffffc974d63dc0
>> ffffff80081c507c
>> [   40.818931] 3d80: 000000000000000d 0000000000000000 ffffffc974c8f100
>> ffffffc974d63eb8
>> [   40.826684] 3da0: 000000001285f6a0 0000000000000015 0000000000000123
>> ffffff80080bf6ac
>> [   40.834437] 3dc0: ffffffc974d63e40 ffffff80081c5e80 000000000000000d
>> 0000000000000000
>> [   40.842190] 3de0: ffffffc974d63e30 ffffff80080c087c ffffffc974d63e20
>> ffffff80081c5c0c
>> [   40.849943] 3e00: ffffffc974c8f100 0000000000000001 ffffffc974c8f100
>> ffffffc974d63eb8
>> [   40.857696] 3e20: ffffffc974d63e40 ffffff80081c5f48 000000000000000d
>> ffffffc974c8f100
>> [   40.865450] 3e40: ffffffc974d63e80 ffffff80081c7274 ffffffc974c8f100
>> ffffffc974c8f100
>> [   40.873203] 3e60: 000000001285f6a0 000000000000000d 0000000060000000
>> 0000000000000000
>> [   40.880956] 3e80: 0000000000000000 ffffff8008082ef0 0000000000000000
>> 0000000000000001
>> [   40.888709] 3ea0: ffffffffffffffff 0000007f8d0ae3dc 0000000000000000
>> 0000000000000000
>> [   40.896461] 3ec0: 0000000000000001 000000001285f6a0 000000000000000d
>> 0000000000000000
>> [   40.904215] 3ee0: ae2e2e2e3f464b49 0000000000000000 000000001285f6b0
>> 39322f392f2f2f2f
>> [   40.911968] 3f00: 0000000000000040 fefefeff2f2d2f2f 7f7f7f7f7f7f7f7f
>> 0101010101010101
>> [   40.919721] 3f20: 0000000000000002 0000000000000004 ffffffffffffffff
>> 0000007f8d136588
>> [   40.927474] 3f40: 0000000000000000 0000007f8d0ae3c0 0000007fd65069e0
>> 00000000004ee000
>> [   40.935226] 3f60: 0000000000000001 000000001285f6a0 000000000000000d
>> 0000000000000001
>> [   40.942980] 3f80: 0000000000000020 000000001285eed8 00000000004ba158
>> 0000000000000000
>> [   40.950732] 3fa0: 0000000000000000 0000007fd6507f30 000000000040e74c
>> 0000007fd6507130
>> [   40.958485] 3fc0: 0000007f8d0ae3dc 0000000060000000 0000000000000001
>> 0000000000000040
>> [   40.966238] 3fe0: 0000000000000000 0000000000000000 0000002000103a00
>> 4000000010000000
>> [   40.973986] Call trace:
>> [   40.976405] Exception stack(0xffffffc974d63a90 to 0xffffffc974d63bc0)
>> [   40.982780] 3a80:                                   0000000000020002
>> 0000008000000000
>> [   40.990533] 3aa0: ffffffc974d63c60 ffffff800834d1bc ffffffc974d63ae0
>> ffffff80085377a4
>> [   40.998287] 3ac0: ffffffc974d63b10 ffffff8008537424 ffffffc975e3ac28
>> ffffffc975e3ac38
>> [   41.006041] 3ae0: ffffffc974d63b30 ffffff80081737cc ffffffc975e3ac38
>> ffffff8008da62c0
>> [   41.013794] 3b00: ffffffc975e98100 ffffff80085401b0 0000000000000001
>> ffffff8008540a08
>> [   41.021547] 3b20: 00000000000036b8 0000000000000040 0000000000020002
>> 0000000000000000
>> [   41.029300] 3b40: ffffffc9763f10e8 0000000000000000 ffffffc9763f1210
>> 0000000000000000
>> [   41.037053] 3b60: 0000000000000000 ffffffc975f95018 0000000000210d00
>> 0000000040000000
>> [   41.044805] 3b80: 7f7f7f7f7f7f7f7f 0101010101010101 0000000000000030
>> ffffffc974cd01cd
>> [   41.052558] 3ba0: ffffffffffffffff ffffffc974cd091c 0000000000000001
>> 0000000000000007
>> [   41.060311] [<ffffff800834d1bc>] kobject_get+0x14/0x88
>> [   41.065398] [<ffffff80084c3dec>] iommu_get_domain_for_dev+0x1c/0x48
>> [   41.071607] [<ffffff80080948c4>] arch_teardown_dma_ops+0x14/0x68
>> [   41.077556] [<ffffff8008764a14>] of_dma_deconfigure+0xc/0x18
>> [   41.083161] [<ffffff8008552804>] dma_deconfigure+0xc/0x18
>> [   41.088509] [<ffffff800853ba10>] __device_release_driver+0x88/0x120
>> [   41.094715] [<ffffff800853bacc>] device_release_driver+0x24/0x38
>> [   41.100663] [<ffffff800853a868>] unbind_store+0xe8/0x110
>> [   41.105922] [<ffffff8008539c70>] drv_attr_store+0x20/0x30
>> [   41.111268] [<ffffff800823ab18>] sysfs_kf_write+0x48/0x58
>> [   41.116612] [<ffffff8008239ea8>] kernfs_fop_write+0xb0/0x1d8
>> [   41.122216] [<ffffff80081c507c>] __vfs_write+0x1c/0x100
>> [   41.127390] [<ffffff80081c5e80>] vfs_write+0xa0/0x1b8
>> [   41.132391] [<ffffff80081c7274>] SyS_write+0x44/0xa0
>> [   41.137307] [<ffffff8008082ef0>] el0_svc_naked+0x24/0x28
>> [   41.142567] Code: 910003fd f9000bf3 aa0003f3 b4000180 (3940f000)
>> [   41.148667] ---[ end trace 35c1e743d6e6c037 ]---
>> Segmentation fault
>> / #
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 

^ permalink raw reply

* [PATCH v6 1/5] ARM: davinci: da8xx: add usb phy clocks
From: Sekhar Nori @ 2016-10-26 17:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <0302c410-4b05-3a5b-3801-5ab73089a9e2@lechnology.com>

On Wednesday 26 October 2016 10:07 PM, David Lechner wrote:
> On 10/26/2016 02:59 AM, Sekhar Nori wrote:
>> On Wednesday 26 October 2016 08:36 AM, David Lechner wrote:
>>> Up to this point, the USB phy clock configuration was handled
>>> manually in
>>> the board files and in the usb drivers. This adds proper clocks so that
>>> the usb drivers can use clk_get and clk_enable and not have to worry
>>> about
>>> the details. Also, the related code is removed from the board files and
>>> replaced with the new clock registration functions.
>>>
>>> Signed-off-by: David Lechner <david@lechnology.com>
>>> Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
>>> ---
>>>
>>> I have added "ARM: davinci: da8xx: Enable the usb20 "per" clk on
>>> phy_clk_enable"
>>> from Axel Haslam to this patch.
>>>
>>> In the review of Axel's patch, Sekhar said:
>>>
>>>> We should not be using a NULL device pointer here. Can you pass the
>>>> musb
>>>> device pointer available in the same file? Also, da850_clks[] in
>>>> da850.c
>>>> needs to be fixed to add the matching device name.
>>>
>>> However, the musb device may not be registered. The usb20_clk can be
>>> used to
>>> supply a 48MHz clock to USB 1.1 (ohci) without using the musb device.
>>> So, I am
>>> inclined to leave this as NULL.
>>
>> But clock look-up has nothing to do with device being registered AFAICT.
>> It is used to identify the clock consumer. Passing NULL there means the
>> clock is not associated with any device. Which is not correct as we are
>> specifically looking at MUSB module clock.
>>
>> Thanks,
>> Sekhar
>>
> 
> FWIW, clk_get() uses dev_name() to get the device name, which will
> return NULL until after the platform device is registered.

I believe you can set init_name in the device to setup an initial name
until registration.

> 
> I can add the device references anyway. However, this is complicated by
> the fact that the musb platform device declaration is inside of an #if
> IS_ENABLED(CONFIG_USB_MUSB_HDRC). I can either remove the #if or add
> more #if's. Do you have a preference on this?

Please remove the #if's. Usually device registration is never done
conditionally based on whether the driver is built or not. So this seems
incorrect anyway.

Thanks,
Sekhar

^ permalink raw reply

* [PATCH v3] drivers: psci: PSCI checker module
From: Lorenzo Pieralisi @ 2016-10-26 17:10 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026151858.GQ3716@linux.vnet.ibm.com>

On Wed, Oct 26, 2016 at 08:18:58AM -0700, Paul E. McKenney wrote:
> On Wed, Oct 26, 2016 at 02:17:52PM +0100, Lorenzo Pieralisi wrote:
> > On Tue, Oct 25, 2016 at 11:34:36AM -0700, Paul E. McKenney wrote:
> > 
> > [...]
> > 
> > > > > +static int __init psci_checker(void)
> > > > > +{
> > > > > +	int ret;
> > > > > +
> > > > > +	/*
> > > > > +	 * Since we're in an initcall, we assume that all the CPUs that all
> > > > > +	 * CPUs that can be onlined have been onlined.
> > > > > +	 *
> > > > > +	 * The tests assume that hotplug is enabled but nobody else is using it,
> > > > > +	 * otherwise the results will be unpredictable. However, since there
> > > > > +	 * is no userspace yet in initcalls, that should be fine.
> > > > 
> > > > I do not think it is. If you run a kernel with, say,
> > > > CONFIG_LOCK_TORTURE_TEST, cpus may disappear from the radar while
> > > > running the PSCI checker test itself; that at least would confuse the
> > > > checker, and that's just an example.
> > > > 
> > > > I added Paul to check what are the assumptions behind the torture test
> > > > hotplug tests, in particular if there are any implicit assumptions for
> > > > it to work (ie it is the only kernel test hotplugging cpus in and out
> > > > (?)), what I know is that the PSCI checker assumptions are not correct.
> > > 
> > > Both CONFIG_LOCK_TORTURE_TEST and CONFIG_RCU_TORTURE_TEST can and will
> > > hotplug CPUs.  The locktorture.onoff_holdoff and rcutorture.onoff_holdoff
> > > kernel parameters can delay the start of CPU-hotplug testing, and in
> > > my testing I set this delay to 30 seconds after boot.
> > > 
> > > One approach would be to make your test refuse to run if either of
> > > the lock/RCU torture tests was running.  Or do what Lorenzo suggests
> > > below.  The torture tests aren't crazy enough to offline the last CPU.
> > > Though they do try, just for effect, in cases where the last CPU is
> > > marked cpu_is_hotpluggable().  ;-)
> > 
> > Thank you Paul. I have an additional question though. Is there any
> > implicit assumption in LOCK/RCU torture tests whereby nothing else
> > in the kernel is hotplugging cpus in/out (through cpu_down()/up())
> > while they are running ?
> > 
> > I am asking because that's the main reason behind my query. Those tests
> > hotplug cpus in and out through cpu_down/up() but AFAICS nothing
> > prevents another piece of code in the kernel to call those functions and
> > the tests may just fail in that case (ie trying to cpu_down() a cpu
> > that is not online).
> > 
> > Are false negatives contemplated (or I am missing something) ?
> 
> The current code assumes nothing else doing CPU-hotplug operations,
> and will therefore print "RCU_HOTPLUG" error (or "LOCK_HOTPLUG" for
> locktorture) if any of the hotplug operations failed.
> 
> > I just would like to understand if what this patch currently does
> > is safe and sound. I think that calling cpu_down() and cpu_up()
> > is always safe, but the test can result in false negatives if
> > other kernel subsystems (eg LOCK torture test) are calling those
> > APIs in parallel (because cpu_down()/cpu_up() calls can fail - eg
> > trying to cpu_down() a cpu that is not online any longer, since it
> > was taken down by another kernel control path), that's the question
> > I have.
> 
> I am assuming that these added calls to cpu_down() and cpu_up() aren't
> enabled by default.  If they are, rcutorture and locktorture need some
> way to turn the off.
> 
> So maybe we need to have some sort of API that detects concurrent
> CPU-hotplug torturing?  Maybe something like the following?
> 
> 	static atomic_t n_cpu_hotplug_torturers;
> 	static atomic_t cpu_hotplug_concurrent_torture;
> 
> 	void torture_start_cpu_hotplug(void)
> 	{
> 		if (atomic_inc_return(&n_cpu_hotplug_torturers) > 1)
> 			atomic_inc(&cpu_hotplug_concurrent_torture);
> 	}
> 
> 	void torture_end_cpu_hotplug(void)
> 	{
> 		atomic_dec(&n_cpu_hotplug_torturers);
> 	}
> 
> 	bool torture_cpu_hotplug_was_concurrent(void)
> 	{
> 		return !!atomic_read(&cpu_hotplug_concurrent_torture);
> 	}
> 
> The locktorture and rcutorture code could then ignore CPU-hotplug
> errors that could be caused by concurrent access.  And complain
> bitterly about the concurrent access, of course!  ;-)

This could do, even better if we extend the torture hotplug tests to
take a cpumask so that basically Kevin's patch will be based on torture
hotplug tests infrastructure :D (ie he/we wanted to hotplug a subset of
the online mask corresponding to a "cluster" of cpus, that's to test the
PSCI CPU ON/OFF firmware interface behind cpu hotplug operations).

Still, this implies logging every possible cpu_down()/cpu_up() caller
through torture_start_cpu_hotplug().

What about userspace and sysfs interface that allow to offline cpus then ?
Point is, the torture hotplug tests take a snapshot of the maxcpu at
kthread init time and then randomize the logical cpu number, but it is
definitely possible unless I am mistaken that some of those cpus
disappear while the test is running and this will cause failures that
you can't detect through the API above.

That's why I suggested using the:

freeze_secondary_cpus(int primary);

for this patch because that allows us to quiesce all cpus other than
primary at once, with no interference possible from other kernel control
paths (but it is not a perfect solution either).

Userspace notwithstanding, I think the best solution consists in either
making this patch hotplug tests work on top of the torture hotplug tests
API or solving the dependency at kconfig level by disabling the PSCI
checker if any of torture tests are enabled which is not ideal but
I do not see any other option.

Thanks a lot for your feedback, thoughts appreciated.

Lorenzo

> 
> Or am I missing your point?
> 
> 							Thanx, Paul
> 
> > Thanks !
> > Lorenzo
> > 
> > > 
> > > 						Thanx, Paul
> > > 
> > > > There is something simple you can do to get this "fixed".
> > > > 
> > > > You can use the new API James implemented for hibernate,
> > > > that allows you to disable (ie PSCI CPU OFF) all "secondary" cpus
> > > > other than the primary one passed in as parameter:
> > > > 
> > > > freeze_secondary_cpus(int primary);
> > > > 
> > > > that function will _cpu_down() all online cpus other than "primary"
> > > > in one go, without any interference allowed from other bits of the
> > > > kernel. It requires an enable_nonboot_cpus() counterpart, and you
> > > > can do that for every online cpus you detect (actually you can even
> > > > avoid using the online cpu mask and use the present mask to carry
> > > > out the test). If there is a resident trusted OS you can just
> > > > trigger the test with primary == tos_resident_cpu, since all
> > > > others are bound to fail (well, you can run them and check they
> > > > do fail, it is a checker after all).
> > > > 
> > > > You would lose the capability of hotplugging a "cluster" at a time, but
> > > > I do not think it is a big problem, the test above would cover it
> > > > and more importantly, it is safe to execute.
> > > > 
> > > > Or we can augment the torture test API to restrict the cpumask
> > > > it actually uses to offline/online cpus (I am referring to
> > > > torture_onoff(), kernel/torture.c).
> > > > 
> > > > Further comments appreciated since I am not sure I grokked the
> > > > assumption the torture tests make about hotplugging cpus in and out,
> > > > I will go through the commits logs again to find more info.
> > > > 
> > > > Thanks !
> > > > Lorenzo
> > > > 
> > > > > +	 */
> > > > > +	nb_available_cpus = num_online_cpus();
> > > > > +
> > > > > +	/* Check PSCI operations are set up and working. */
> > > > > +	ret = psci_ops_check();
> > > > > +	if (ret)
> > > > > +		return ret;
> > > > > +
> > > > > +	pr_info("PSCI checker started using %u CPUs\n", nb_available_cpus);
> > > > > +
> > > > > +	pr_info("Starting hotplug tests\n");
> > > > > +	ret = hotplug_tests();
> > > > > +	if (ret == 0)
> > > > > +		pr_info("Hotplug tests passed OK\n");
> > > > > +	else if (ret > 0)
> > > > > +		pr_err("%d error(s) encountered in hotplug tests\n", ret);
> > > > > +	else {
> > > > > +		pr_err("Out of memory\n");
> > > > > +		return ret;
> > > > > +	}
> > > > > +
> > > > > +	pr_info("Starting suspend tests (%d cycles per state)\n",
> > > > > +		NUM_SUSPEND_CYCLE);
> > > > > +	ret = suspend_tests();
> > > > > +	if (ret == 0)
> > > > > +		pr_info("Suspend tests passed OK\n");
> > > > > +	else if (ret > 0)
> > > > > +		pr_err("%d error(s) encountered in suspend tests\n", ret);
> > > > > +	else {
> > > > > +		switch (ret) {
> > > > > +		case -ENOMEM:
> > > > > +			pr_err("Out of memory\n");
> > > > > +			break;
> > > > > +		case -ENODEV:
> > > > > +			pr_warn("Could not start suspend tests on any CPU\n");
> > > > > +			break;
> > > > > +		}
> > > > > +	}
> > > > > +
> > > > > +	pr_info("PSCI checker completed\n");
> > > > > +	return ret < 0 ? ret : 0;
> > > > > +}
> > > > > +late_initcall(psci_checker);
> > > > > -- 
> > > > > 2.10.0
> > > > > 
> > > > 
> > > 
> > 
> 

^ permalink raw reply

* [v12, 5/8] soc: fsl: add GUTS driver for QorIQ platforms
From: Scott Wood @ 2016-10-26 17:06 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474441040-11946-6-git-send-email-yangbo.lu@nxp.com>

On Wed, 2016-09-21 at 14:57 +0800, Yangbo Lu wrote:
> diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig
> new file mode 100644
> index 0000000..b99764c
> --- /dev/null
> +++ b/drivers/soc/fsl/Kconfig
> @@ -0,0 +1,19 @@
> +#
> +# Freescale SOC drivers
> +#
> +
> +source "drivers/soc/fsl/qe/Kconfig"
> +
> +config FSL_GUTS
> +	bool "Freescale QorIQ GUTS driver"
> +	select SOC_BUS
> +	help
> +	??The global utilities block controls power management, I/O device
> +	??enabling, power-onreset(POR) configuration monitoring, alternate
> +	??function selection for multiplexed signals,and clock control.
> +	??This driver is to manage and access global utilities block.
> +	??Initially only reading SVR and registering soc device are
> supported.
> +	??Other guts accesses, such as reading RCW, should eventually be
> moved
> +	??into this driver as well.
> +
> +	??If you want GUTS driver support, you should say Y here.

This is user-enablable without dependencies, which means it will break some
randconfigs. ?If this is to be enabled via select then remove the text after
"bool".

> +/* SoC die attribute definition for QorIQ platform */
> +static const struct fsl_soc_die_attr fsl_soc_die[] = {
> +#ifdef CONFIG_PPC
> +	/*
> +	?* Power Architecture-based SoCs T Series
> +	?*/
> +
> +	/* Die: T4240, SoC: T4240/T4160/T4080 */
> +	{ .die		= "T4240",
> +	??.svr		= 0x82400000,
> +	??.mask		= 0xfff00000,
> +	},
> +	/* Die: T1040, SoC: T1040/T1020/T1042/T1022 */
> +	{ .die		= "T1040",
> +	??.svr		= 0x85200000,
> +	??.mask		= 0xfff00000,
> +	},
> +	/* Die: T2080, SoC: T2080/T2081 */
> +	{ .die		= "T2080",
> +	??.svr		= 0x85300000,
> +	??.mask		= 0xfff00000,
> +	},
> +	/* Die: T1024, SoC: T1024/T1014/T1023/T1013 */
> +	{ .die		= "T1024",
> +	??.svr		= 0x85400000,
> +	??.mask		= 0xfff00000,
> +	},
> +#endif /* CONFIG_PPC */
> +#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_ARCH_LAYERSCAPE)

Will this driver ever be probed on MXC? ?Why do we need these ifdefs at all?


> +	/*
> +	?* ARM-based SoCs LS Series
> +	?*/
> +
> +	/* Die: LS1043A, SoC: LS1043A/LS1023A */
> +	{ .die		= "LS1043A",
> +	??.svr		= 0x87920000,
> +	??.mask		= 0xffff0000,
> +	},
> +	/* Die: LS2080A, SoC: LS2080A/LS2040A/LS2085A */
> +	{ .die		= "LS2080A",
> +	??.svr		= 0x87010000,
> +	??.mask		= 0xff3f0000,
> +	},
> +	/* Die: LS1088A, SoC: LS1088A/LS1048A/LS1084A/LS1044A */
> +	{ .die		= "LS1088A",
> +	??.svr		= 0x87030000,
> +	??.mask		= 0xff3f0000,
> +	},
> +	/* Die: LS1012A, SoC: LS1012A */
> +	{ .die		= "LS1012A",
> +	??.svr		= 0x87040000,
> +	??.mask		= 0xffff0000,
> +	},
> +	/* Die: LS1046A, SoC: LS1046A/LS1026A */
> +	{ .die		= "LS1046A",
> +	??.svr		= 0x87070000,
> +	??.mask		= 0xffff0000,
> +	},
> +	/* Die: LS2088A, SoC: LS2088A/LS2048A/LS2084A/LS2044A */
> +	{ .die		= "LS2088A",
> +	??.svr		= 0x87090000,
> +	??.mask		= 0xff3f0000,
> +	},
> +	/* Die: LS1021A, SoC: LS1021A/LS1020A/LS1022A
> +	?* Note: Put this die at the end in cause of incorrect
> identification
> +	?*/
> +	{ .die		= "LS1021A",
> +	??.svr		= 0x87000000,
> +	??.mask		= 0xfff00000,
> +	},
> +#endif /* CONFIG_ARCH_MXC || CONFIG_ARCH_LAYERSCAPE */

Instead of relying on ordering, add more bits to the mask so that there's no
overlap. ?I think 0xfff70000 would work.

> +out:
> +	kfree(soc_dev_attr.machine);
> +	kfree(soc_dev_attr.family);
> +	kfree(soc_dev_attr.soc_id);
> +	kfree(soc_dev_attr.revision);
> +	iounmap(guts->regs);
> +out_free:
> +	kfree(guts);
> +	return ret;
> +}

Please use devm.

-Scott

^ permalink raw reply

* [PATCH 2/2] ARM: dma-mapping: Handle prot with non-consistent dma attribute
From: Thierry Escande @ 2016-10-26 17:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477501448-30915-1-git-send-email-thierry.escande@collabora.com>

From: Heng-Ruey Hsu <henryhsu@chromium.org>

With this change, __get_dma_pgprot() now returns the VMA access
protection passed directly instead of overriding it if called with
NON_CONSISTENT DMA attribute.

Signed-off-by: Heng-Ruey Hsu <henryhsu@chromium.org>
Tested-by: Heng-ruey Hsu <henryhsu@chromium.org>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Thierry Escande <thierry.escande@collabora.com>
---
 arch/arm/mm/dma-mapping.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index dc42ca6..d608c185 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -640,6 +640,9 @@ static void __free_from_contiguous(struct device *dev, struct page *page,
 
 static inline pgprot_t __get_dma_pgprot(unsigned long attrs, pgprot_t prot)
 {
+	if (attrs & DMA_ATTR_NON_CONSISTENT)
+		return prot;
+
 	prot = (attrs & DMA_ATTR_WRITE_COMBINE) ?
 			pgprot_writecombine(prot) :
 			pgprot_dmacoherent(prot);
-- 
2.7.4

^ permalink raw reply related

* [PATCH 1/2] ARM: dma-mapping: Support cache sync after arm_dma_get_sgtable
From: Thierry Escande @ 2016-10-26 17:04 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477501448-30915-1-git-send-email-thierry.escande@collabora.com>

From: Heng-Ruey Hsu <henryhsu@chromium.org>

Currently arm_dma_sync_sg_* require dma_address to do cache sync. But
dma address is set by map_sg(). We can't do cache sync after
arm_dma_get_sgtable. The behavior is different from iommu_ops.

We don't have to get dma address in arm_dma_sync_sg_* and convert the
address to physical address in arm_dma_sync_single_*. With this change
sg_page() is used to get physical address and do sync directly.

Signed-off-by: Heng-Ruey Hsu <henryhsu@chromium.org>
Tested-by: Heng-ruey Hsu <henryhsu@chromium.org>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Thierry Escande <thierry.escande@collabora.com>
---
 arch/arm/mm/dma-mapping.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index ab4f745..dc42ca6 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1120,13 +1120,11 @@ void arm_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
 void arm_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
 			int nents, enum dma_data_direction dir)
 {
-	struct dma_map_ops *ops = get_dma_ops(dev);
 	struct scatterlist *s;
 	int i;
 
 	for_each_sg(sg, s, nents, i)
-		ops->sync_single_for_cpu(dev, sg_dma_address(s), s->length,
-					 dir);
+		__dma_page_dev_to_cpu(sg_page(s), s->offset, s->length, dir);
 }
 
 /**
@@ -1139,13 +1137,11 @@ void arm_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
 void arm_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
 			int nents, enum dma_data_direction dir)
 {
-	struct dma_map_ops *ops = get_dma_ops(dev);
 	struct scatterlist *s;
 	int i;
 
 	for_each_sg(sg, s, nents, i)
-		ops->sync_single_for_device(dev, sg_dma_address(s), s->length,
-					    dir);
+		__dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir);
 }
 
 /*
-- 
2.7.4

^ permalink raw reply related

* [PATCH 0/2] ARM DMA mapping
From: Thierry Escande @ 2016-10-26 17:04 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

This series introduces 2 changes in ARM DMA mapping. The first one is
about supporting cache maintenance after calling arm_dma_get_sgtable().
The other one handles VMA access protection in __get_dma_pgprot().

Heng-Ruey Hsu (2):
  ARM: dma-mapping: Support cache sync after arm_dma_get_sgtable
  ARM: dma-mapping: Handle prot with non-consistent dma attribute

 arch/arm/mm/dma-mapping.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

-- 
2.7.4

^ permalink raw reply

* [RESEND PATCH] arm: assabet_defconfig: disable IDE subsystem
From: Bartlomiej Zolnierkiewicz @ 2016-10-26 17:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <4264651.gPKphdYuCx@wuerfel>


Hi,

On Wednesday, July 13, 2016 04:37:31 PM Arnd Bergmann wrote:
> On Wednesday, July 13, 2016 12:59:23 PM CEST Bartlomiej Zolnierkiewicz wrote:
> > 
> > On Friday, July 08, 2016 10:23:48 PM Arnd Bergmann wrote:
> > > On Friday, July 8, 2016 5:24:41 PM CEST Bartlomiej Zolnierkiewicz wrote:
> > > > This patch disables deprecated IDE subsystem in assabet_defconfig
> > > > (no IDE host drivers are selected in this config so there is no
> > > > valid reason to enable IDE subsystem itself).
> > > > 
> > > > Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> > > > Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> > > 
> > > I think the series makes a lot of sense. I have checked your assertions
> > > in the changelogs and found no flaws in your logic, so I think we should
> > > take them all through arm-soc unless there are other concerns.
> > 
> > Thank you.
> > 
> > Should I resend everything or just patches that were not reposted yet
> > (the ones that were marked as RFT initially and got no feedback)?
> 
> I'd be fine with just getting a pull request with all the patches that
> had no negative feedback and that were not already applied (if any).

Here it is (sorry for taking so long).

The following changes since commit 07d9a380680d1c0eb51ef87ff2eab5c994949e69:

  Linux 4.9-rc2 (2016-10-23 17:10:14 -0700)

are available in the git repository at:

  https://github.com/bzolnier/linux.git v4.9-rc2-arm-configs-pata

for you to fetch changes up to bc9c6cc857849ec0d83bd13c1812bae9345dc553:

  arm: spitz_defconfig: convert to use libata PATA drivers (2016-10-26 18:43:33 +0200)

----------------------------------------------------------------
Bartlomiej Zolnierkiewicz (16):
      arm: assabet_defconfig: disable IDE subsystem
      arm: badge4_defconfig: disable IDE subsystem
      arm: cerfcube_defconfig: disable IDE subsystem
      arm: lart_defconfig: disable IDE subsystem
      arm: mainstone_defconfig: disable IDE subsystem
      arm: shannon_defconfig: disable IDE subsystem
      arm: collie_defconfig: convert to use libata PATA drivers
      arm: omap1_defconfig: convert to use libata PATA drivers
      arm: am200epdkit_defconfig: convert to use libata PATA drivers
      arm: corgi_defconfig: convert to use libata PATA drivers
      arm: h3600_defconfig: convert to use libata PATA drivers
      arm: ixp4xx_defconfig: convert to use libata PATA drivers
      arm: jornada720_defconfig: convert to use libata PATA drivers
      arm: netwinder_defconfig: convert to use libata PATA drivers
      arm: s3c2410_defconfig: convert to use libata PATA drivers
      arm: spitz_defconfig: convert to use libata PATA drivers

 arch/arm/configs/am200epdkit_defconfig |  5 +++--
 arch/arm/configs/assabet_defconfig     |  1 -
 arch/arm/configs/badge4_defconfig      |  2 --
 arch/arm/configs/cerfcube_defconfig    |  1 -
 arch/arm/configs/collie_defconfig      |  5 +++--
 arch/arm/configs/corgi_defconfig       |  7 +++----
 arch/arm/configs/h3600_defconfig       |  5 +++--
 arch/arm/configs/ixp4xx_defconfig      |  9 +++++----
 arch/arm/configs/jornada720_defconfig  |  5 +++--
 arch/arm/configs/lart_defconfig        |  2 --
 arch/arm/configs/mainstone_defconfig   |  1 -
 arch/arm/configs/netwinder_defconfig   |  7 ++++---
 arch/arm/configs/omap1_defconfig       |  4 ++--
 arch/arm/configs/s3c2410_defconfig     | 10 +++-------
 arch/arm/configs/shannon_defconfig     |  1 -
 arch/arm/configs/spitz_defconfig       |  8 +++-----
 16 files changed, 32 insertions(+), 41 deletions(-)

^ permalink raw reply

* [PATCH 1/2] of, numa: Add function to disable of_node_to_nid().
From: David Daney @ 2016-10-26 17:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161026134301.GV25086@rric.localdomain>

On 10/26/2016 06:43 AM, Robert Richter wrote:
> On 25.10.16 14:31:00, David Daney wrote:
>> From: David Daney <david.daney@cavium.com>
>>
>> On arm64 NUMA kernels we can pass "numa=off" on the command line to
>> disable NUMA.  A side effect of this is that kmalloc_node() calls to
>> non-zero nodes will crash the system with an OOPS:
>>
>> [    0.000000] [<fffffc00081bba84>] __alloc_pages_nodemask+0xa4/0xe68
>> [    0.000000] [<fffffc00082163a8>] new_slab+0xd0/0x57c
>> [    0.000000] [<fffffc000821879c>] ___slab_alloc+0x2e4/0x514
>> [    0.000000] [<fffffc000823882c>] __slab_alloc+0x48/0x58
>> [    0.000000] [<fffffc00082195a0>] __kmalloc_node+0xd0/0x2e0
>> [    0.000000] [<fffffc00081119b8>] __irq_domain_add+0x7c/0x164
>> [    0.000000] [<fffffc0008b75d30>] its_probe+0x784/0x81c
>> [    0.000000] [<fffffc0008b75e10>] its_init+0x48/0x1b0
>> .
>> .
>> .
>>
>> This is caused by code like this in kernel/irq/irqdomain.c
>>
>>      domain = kzalloc_node(sizeof(*domain) + (sizeof(unsigned int) * size),
>>                    GFP_KERNEL, of_node_to_nid(of_node));
>>
>> When NUMA is disabled, the concept of a node is really undefined, so
>> of_node_to_nid() should unconditionally return NUMA_NO_NODE.
>>
>> Add __of_force_no_numa() to allow of_node_to_nid() to be forced to
>> return NUMA_NO_NODE.
>>
>> The follow on patch will call this new function from the arm64 numa
>> code.
>
> Didn't that work before?

I am fairly certain that it used to work.

> numa=off just maps all mem to node 0.

Yes, that is the current behavior.

> If mem
> allocation is requested for another node it should just fall back to a
> node with mem (node 0 then).

This is the root of the problem.  The ITS code is allocating memory. It 
calls of_node_to_nid() to determine which node it resides on.  The 
answer in the failing case is node-1.  Since we have mapped all the 
memory to node-0 the  __kmalloc_node(..., 1) call fails with the OOPS shown.

It could be that __kmalloc_node() used to allocate memory on a node 
other than the requested node if the request couldn't be met.  But in 
v4.8 and later it produces that OOPS.

If you pass a node containing free memory or NUMA_NO_NODE to 
__kmalloc_node(), the allocation succeeds.

When we first did these patches, I advocated removing the numa=off 
feature, and requiring people to install usable firmware on their 
systems.  That was rejected on the grounds that not everybody has the 
ability to change their firmware and we would like to allow NUMA kernels 
to run on systems with defective firmware by supplying this command line 
parameter.  Now that I have seen requests from the wild for this, I 
think it is a good idea to allow numa=off to be used to work around this 
bad firmware.

The change in this patch set is fairly small, and seems to get the job 
done.  An alternative would be to change __kmalloc_node() to ignore the 
node parameter if the request cannot be made, but I assume that there 
were good reasons to have the current behavior, so that would be a much 
more complicated change to make.



> I suspect there is something wrong with
> the page initialization, see:
>
>   http://www.spinics.net/lists/arm-kernel/msg535191.html
>   https://bugzilla.redhat.com/show_bug.cgi?id=1387793
>
> What is the complete oops?
>
> So I think k*alloc_node() must be able to handle requests to
> non-existing nodes. Otherwise your fix is incomplete, assume a failed
> of_numa_init() causing a dummy init but still some devices reporting a
> node.

.
.
.
EFI stub: Booting Linux Kernel...
EFI stub: Using DTB from configuration table
EFI stub: Exiting boot services and installing virtual address map...
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.8.0-rc8-dd (ddaney at localhost.localdomain) 
(gcc version 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC) ) #29 SMP Tue Sep 
27 15:50:35 PDT 2016
[    0.000000] Boot CPU: AArch64 Processor [431f0a10]
[    0.000000] NUMA turned off
[    0.000000] earlycon: pl11 at MMIO 0x000087e024000000 (options '')
[    0.000000] bootconsole [pl11] enabled
[    0.000000] efi: Getting EFI parameters from FDT:
[    0.000000] efi: EFI v2.40 by Cavium Thunder cn88xx EFI 
jenkins_weekly_build_40-0-ga1f880f Sep 13 2016 17:05:35
[    0.000000] efi:  ACPI=0xfffff000  ACPI 2.0=0xfffff014  SMBIOS 
3.0=0x10ffafcf000
[    0.000000] cma: Reserved 512 MiB at 0x00000000c0000000
[    0.000000] NUMA disabled
[    0.000000] NUMA: Faking a node at [mem 
0x0000000000000000-0x0000010fffffffff]
[    0.000000] NUMA: Adding memblock [0x1400000 - 0xfffdffff] on node 0
[    0.000000] NUMA: Adding memblock [0xfffe0000 - 0xffffffff] on node 0
[    0.000000] NUMA: Adding memblock [0x100000000 - 0xfffffffff] on node 0
[    0.000000] NUMA: Adding memblock [0x10000400000 - 0x10ffa38ffff] on 
node 0
[    0.000000] NUMA: Adding memblock [0x10ffa390000 - 0x10ffa41ffff] on 
node 0
[    0.000000] NUMA: Adding memblock [0x10ffa420000 - 0x10ffaeaffff] on 
node 0
[    0.000000] NUMA: Adding memblock [0x10ffaeb0000 - 0x10ffaffffff] on 
node 0
[    0.000000] NUMA: Adding memblock [0x10ffb000000 - 0x10ffffaffff] on 
node 0
[    0.000000] NUMA: Adding memblock [0x10ffffb0000 - 0x10fffffffff] on 
node 0
[    0.000000] NUMA: Initmem setup node 0 [mem 0x01400000-0x10fffffffff]
[    0.000000] NUMA: NODE_DATA [mem 0x10ffffae480-0x10ffffaff7f]
[    0.000000] Zone ranges:
[    0.000000]   DMA      [mem 0x0000000001400000-0x00000000ffffffff]
[    0.000000]   Normal   [mem 0x0000000100000000-0x0000010fffffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000001400000-0x00000000fffdffff]
[    0.000000]   node   0: [mem 0x00000000fffe0000-0x00000000ffffffff]
[    0.000000]   node   0: [mem 0x0000000100000000-0x0000000fffffffff]
[    0.000000]   node   0: [mem 0x0000010000400000-0x0000010ffa38ffff]
[    0.000000]   node   0: [mem 0x0000010ffa390000-0x0000010ffa41ffff]
[    0.000000]   node   0: [mem 0x0000010ffa420000-0x0000010ffaeaffff]
[    0.000000]   node   0: [mem 0x0000010ffaeb0000-0x0000010ffaffffff]
[    0.000000]   node   0: [mem 0x0000010ffb000000-0x0000010ffffaffff]
[    0.000000]   node   0: [mem 0x0000010ffffb0000-0x0000010fffffffff]
[    0.000000] Initmem setup node 0 [mem 
0x0000000001400000-0x0000010fffffffff]
[    0.000000] psci: probing for conduit method from DT.
[    0.000000] psci: PSCIv0.2 detected in firmware.
[    0.000000] psci: Using standard PSCI v0.2 function IDs
[    0.000000] psci: Trusted OS resident on physical CPU 0x0
[    0.000000] percpu: Embedded 3 pages/cpu @ffffff0ff6900000 s116736 
r8192 d71680 u196608
[    0.000000] Detected VIPT I-cache on CPU0
[    0.000000] CPU features: enabling workaround for Cavium erratum 27456
[    0.000000] Built 1 zonelists in Node order, mobility grouping on. 
Total pages: 2094720
[    0.000000] Policy zone: Normal
[    0.000000] Kernel command line: BOOT_IMAGE=/vmlinuz-4.8.0-rc8-dd 
root=/dev/mapper/rhel-root ro crashkernel=auto rd.lvm.lv=rhel/root 
rd.lvm.lv=rhel/swap LANG=en_US.UTF-8 numa=off console=ttyAMA0,115200n8 
earlycon=pl011,0x87e024000000
[    0.000000] log_buf_len individual max cpu contribution: 4096 bytes
[    0.000000] log_buf_len total cpu_extra contributions: 389120 bytes
[    0.000000] log_buf_len min size: 524288 bytes
[    0.000000] log_buf_len: 1048576 bytes
[    0.000000] early log buf free: 519176(99%)
[    0.000000] PID hash table entries: 4096 (order: -1, 32768 bytes)
[    0.000000] software IO TLB [mem 0xfbfd0000-0xfffd0000] (64MB) mapped 
at [fffffe00fbfd0000-fffffe00fffcffff]
[    0.000000] Memory: 133391936K/134193152K available (7356K kernel 
code, 1359K rwdata, 3392K rodata, 1216K init, 6799K bss, 276928K 
reserved, 524288K cma-reserved)
[    0.000000] Virtual kernel memory layout:
[    0.000000]     modules : 0xfffffc0000000000 - 0xfffffc0008000000   ( 
   128 MB)
[    0.000000]     vmalloc : 0xfffffc0008000000 - 0xfffffdff5fff0000   ( 
  2045 GB)
[    0.000000]       .text : 0xfffffc0008080000 - 0xfffffc00087b0000   ( 
  7360 KB)
[    0.000000]     .rodata : 0xfffffc00087b0000 - 0xfffffc0008b10000   ( 
  3456 KB)
[    0.000000]       .init : 0xfffffc0008b10000 - 0xfffffc0008c40000   ( 
  1216 KB)
[    0.000000]       .data : 0xfffffc0008c40000 - 0xfffffc0008d93e00   ( 
  1360 KB)
[    0.000000]        .bss : 0xfffffc0008d93e00 - 0xfffffc0009437d48   ( 
  6800 KB)
[    0.000000]     fixed   : 0xfffffdff7e7d0000 - 0xfffffdff7ec00000   ( 
  4288 KB)
[    0.000000]     PCI I/O : 0xfffffdff7ee00000 - 0xfffffdff7fe00000   ( 
    16 MB)
[    0.000000]     vmemmap : 0xfffffdff80000000 - 0xfffffe0000000000   ( 
     2 GB maximum)
[    0.000000]               0xfffffdff80005000 - 0xfffffdffc4000000   ( 
  1087 MB actual)
[    0.000000]     memory  : 0xfffffe0001400000 - 0xffffff1000000000 
(1114092 MB)
[    0.000000] SLUB: HWalign=128, Order=0-3, MinObjects=0, CPUs=96, Nodes=1
[    0.000000] Hierarchical RCU implementation.
[    0.000000] 	Build-time adjustment of leaf fanout to 64.
[    0.000000] 	RCU restricting CPUs from NR_CPUS=4096 to nr_cpu_ids=96.
[    0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=64, nr_cpu_ids=96
[    0.000000] NR_IRQS:64 nr_irqs:64 0
[    0.000000] GICv3: GIC: Using split EOI/Deactivate mode
[    0.000000] ITS: /interrupt-controller at 801000000000/gic-its at 801000020000
[    0.000000] ITS at 0x0000801000020000: allocated 2097152 Devices 
@10001000000 (flat, esz 8, psz 64K, shr 1)
[    0.000000] ITS: /interrupt-controller at 801000000000/gic-its at 901000020000
[    0.000000] ITS at 0x0000901000020000: allocated 2097152 Devices 
@10002000000 (flat, esz 8, psz 64K, shr 1)
[    0.000000] Unable to handle kernel NULL pointer dereference at 
virtual address 00001680
[    0.000000] pgd = fffffc0009470000
[    0.000000] [00001680] *pgd=0000010ffff90003, *pud=0000010ffff90003, 
*pmd=0000010ffff90003, *pte=0000000000000000
[    0.000000] Internal error: Oops: 96000006 [#1] SMP
[    0.000000] Modules linked in:
[    0.000000] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.8.0-rc8-dd #29
[    0.000000] Hardware name: Cavium ThunderX CN88XX board (DT)
[    0.000000] task: fffffc0008c71c80 task.stack: fffffc0008c40000
[    0.000000] PC is at __alloc_pages_nodemask+0xa4/0xe68
[    0.000000] LR is at __alloc_pages_nodemask+0x38/0xe68
[    0.000000] pc : [<fffffc00081c8950>] lr : [<fffffc00081c88e4>] 
pstate: 600000c5
[    0.000000] sp : fffffc0008c43880
[    0.000000] x29: fffffc0008c43880 x28: ffffff000041fc00
[    0.000000] x27: 0000000000201200 x26: 0000000000000000
[    0.000000] x25: 0000000000000001 x24: 0000000000001680
[    0.000000] x23: 0000000000201200 x22: fffffc0008c439c8
[    0.000000] x21: fffffc0008c63000 x20: 0000000000201200
[    0.000000] x19: 0000000000000000 x18: 0000000000000070
[    0.000000] x17: 0000000000000008 x16: 0000000000000000
[    0.000000] x15: 0000000000000000 x14: 2820303030303030
[    0.000000] x13: 3230303031402073 x12: 6563697665442032
[    0.000000] x11: 0000000000000020 x10: fffffc0009334000
[    0.000000] x9 : 0000000001bfff3f x8 : 7f7f7f7f7f7f7f7f
[    0.000000] x7 : 0000000001210111 x6 : fffffdffc00010a0
[    0.000000] x5 : 0000000000000000 x4 : 0000000000000000
[    0.000000] x3 : 0000000000000000 x2 : 0000000000000000
[    0.000000] x1 : 0000000000000000 x0 : fffffc0008c63bb0
[    0.000000]
[    0.000000] Process swapper/0 (pid: 0, stack limit = 0xfffffc0008c40020)
[    0.000000] Stack: (0xfffffc0008c43880 to 0xfffffc0008c44000)
[    0.000000] 3880: fffffc0008c439f0 fffffc000821fa70 ffffff000041fc00 
0000000000000200
[    0.000000] 38a0: fffffc0008115374 0000000000000000 0000000000000000 
0000000000000001
[    0.000000] 38c0: 0000000000000000 0000000000000000 0000000000201200 
ffffff000041fc00
[    0.000000] 38e0: fffffc0008c43960 fffffc000810bc20 fffffc0008c43960 
fffffc0008c43960
[    0.000000] 3900: fffffc0008c43930 00000000ffffffd0 fffffc0008c43960 
fffffc0008c43960
[    0.000000] 3920: fffffc0008c43930 00000000ffffffd0 fffffc0008c43970 
fffffc0008221658
[    0.000000] 3940: 7f7f7f7f7f7f7f7f 0000000000000002 0101010101010101 
0000000000000020
[    0.000000] 3960: fffffc0008c43a70 fffffc0008221c04 0000000000000001 
00000000024080c0
[    0.000000] 3980: fffffc0008115374 fffffc0008bf8648 0000000000001000 
0000000000000000
[    0.000000] 39a0: ffffff000041fc00 0000000000000001 ffffff0ff691e840 
ffffff000041fc00
[    0.000000] 39c0: ffffff0ff691e840 0000000000001680 0000000000000000 
0000000000000000
[    0.000000] 39e0: 0000000100000000 0000000000000000 fffffc0008c43a70 
fffffc0008221e24
[    0.000000] 3a00: 0000000000000001 00000000024080c0 fffffc0008115374 
fffffc0008bf8648
[    0.000000] 3a20: 0000000000001000 0000000000000000 0000000000000000 
0000000000000001
[    0.000000] 3a40: ffffff0ff691e840 ffffff000041fc00 fffffc000928a1e8 
024080c000000006
[    0.000000] 3a60: fffffc0008ca6a38 000000000000005c fffffc0008c43b90 
fffffc0008239498
[    0.000000] 3a80: 00000000000000c0 ffffff000041fc00 ffffff0000424f00 
0000000000000070
[    0.000000] 3aa0: 0000000000000001 fffffc0008115374 ffffff000041fc00 
fffffc00093f1000
[    0.000000] 3ac0: ffffff0002000000 ffffff0000433000 fffffc0008c43bd0 
fffffc0008a308f0
[    0.000000] 3ae0: 0000000000010000 0000020000000000 0000000000000000 
0000000000000001
[    0.000000] 3b00: fffffc0008c43b30 fffffc000861f07c fffffc000941efc0 
00000000000000c0
[    0.000000] 3b20: ffffff0ffff44e60 00000000000000c0 fffffc0008c43b70 
fffffc000861f234
[    0.000000] 3b40: ffffff0ffff44e60 0000000000000004 ffffff0ffff44e60 
fffffc0008c43c70
[    0.000000] 3b60: 0000000000000000 fffffc0008a74460 fffffc0008c43ba0 
fffffc000861f3fc
[    0.000000] 3b80: fffffc0008c43ba0 fffffc00083ca55c fffffc0008c43bd0 
fffffc0008222c20
[    0.000000] 3ba0: ffffff000041fc00 00000000024080c0 ffffff0ff691e840 
fffffc0008115374
[    0.000000] 3bc0: 0000000000000001 00000000024080c0 fffffc0008c43c20 
fffffc0008115374
[    0.000000] 3be0: 0000000000000070 ffffff0ffff44e80 ffffff0ffff44e60 
0000000000000000
[    0.000000] 3c00: fffffc0008849a18 ffffffffffffffff 0000000000000000 
ffffff0000433000
[    0.000000] 3c20: fffffc0008c43c80 fffffc0008b461dc ffffff0000424e80 
2800000000000000
[    0.000000] 3c40: 0000000000010000 0000020000000000 0000000000000000 
0000000000000400
[    0.000000] 3c60: 0000000000000400 ffffff00004330f8 0000000000000001 
ffffff0ffffabe00
[    0.000000] 3c80: fffffc0008c43dc0 fffffc0008b462bc fffffc0008d33488 
fffffc0008d33000
[    0.000000] 3ca0: ffffff0ffff44e60 fffffc0008c6c840 ffffff0000424b00 
ffffff0000424880
[    0.000000] 3cc0: 0000000000000002 0000000000000000 0000000001bae074 
0000000001f1001c
[    0.000000] 3ce0: 0000000000000000 fffffc0008a30890 ffffff0000424b00 
fffffc0008849940
[    0.000000] 3d00: ffffff0000433020 fffffc0008a308f0 ffffff0000433008 
ffffff0ffff44e60
[    0.000000] 3d20: fffffc000ac00000 0000000000000008 0000000000000001 
8107000000000000
[    0.000000] 3d40: 00000000000000c0 0000000001000000 00000008fff44e60 
0000010002000000
[    0.000000] 3d60: 0000000000000100 81070000000000ff fffffc0008c43dc0 
0000000008b462cc
[    0.000000] 3d80: 0000901000020000 000090100021ffff ffffff0ffff44f08 
0000000000000200
[    0.000000] 3da0: 0000000000000000 0000000000000000 0000000000000000 
0000000000000000
[    0.000000] 3dc0: fffffc0008c43e10 fffffc0008b4543c fffffc0008c6c828 
fffffc0008d32000
[    0.000000] 3de0: fffffc0008c6c000 ffffff0ffff44470 fffffc0008849000 
ffffff0000424880
[    0.000000] 3e00: fffffc0008c43e10 fffffc0008b45420 fffffc0008c43e60 
fffffc0008b456bc
[    0.000000] 3e20: 0000000000000002 0000000000000003 0000000000000030 
ffffff0000424880
[    0.000000] 3e40: ffffff0ffff44470 0000000000000000 0000000000000018 
fffffc0008000000
[    0.000000] 3e60: fffffc0008c43f00 fffffc0008b5aec8 ffffff0000424700 
fffffc0008c43f60
[    0.000000] 3e80: fffffc0008c43f60 0000000000000000 fffffc0008c43f70 
fffffc0008d92000
[    0.000000] 3ea0: fffffc0008a734e0 fffffc0008a734b8 fffffc0008c43f00 
0000000208b5ae3c
[    0.000000] 3ec0: 0000000000000000 00009010805fffff ffffff0ffff44518 
0000000000000200
[    0.000000] 3ee0: 0000000000000000 0000000000000000 0000000000000000 
0000000000000000
[    0.000000] 3f00: fffffc0008c43f80 fffffc0008b43f9c fffffc0008c60000 
fffffc0008b66628
[    0.000000] 3f20: fffffc0008b66628 fffffc0008dc0000 fffffc0008c60000 
ffffff0ffffac580
[    0.000000] 3f40: 0000000002840000 0000000002870000 0000000000000020 
0000000000000000
[    0.000000] 3f60: fffffc0008c43f60 fffffc0008c43f60 fffffc0008c43f70 
fffffc0008c43f70
[    0.000000] 3f80: fffffc0008c43f90 fffffc0008b12d60 fffffc0008c43fa0 
fffffc0008b10a3c
[    0.000000] 3fa0: 0000000000000000 fffffc0008b101c4 0000010ff7a35218 
0000000000000e12
[    0.000000] 3fc0: 0000000021200000 0000000030d00980 0000000000000000 
0000000001400000
[    0.000000] 3fe0: 0000000000000000 fffffc0008b66628 0000000000000000 
0000000000000000
[    0.000000] Call trace:
[    0.000000] Exception stack(0xfffffc0008c436b0 to 0xfffffc0008c437e0)
[    0.000000] 36a0:                                   0000000000000000 
0000040000000000
[    0.000000] 36c0: fffffc0008c43880 fffffc00081c8950 ffffff0ffffaf180 
0000000000000003
[    0.000000] 36e0: fffffc0008c63000 00000000ffffffff 0000000000000001 
0000000000000000
[    0.000000] 3700: fffffc0008c43720 fffffc00081e25cc 0000000000000000 
0000000001bfff3f
[    0.000000] 3720: fffffc0008c43750 fffffc00081c8454 0000000000000012 
0000000000000000
[    0.000000] 3740: fffffffffffffff8 0000000000000012 fffffc0008c63bb0 
0000000000000000
[    0.000000] 3760: 0000000000000000 0000000000000000 0000000000000000 
0000000000000000
[    0.000000] 3780: fffffdffc00010a0 0000000001210111 7f7f7f7f7f7f7f7f 
0000000001bfff3f
[    0.000000] 37a0: fffffc0009334000 0000000000000020 6563697665442032 
3230303031402073
[    0.000000] 37c0: 2820303030303030 0000000000000000 0000000000000000 
0000000000000008
[    0.000000] [<fffffc00081c8950>] __alloc_pages_nodemask+0xa4/0xe68
[    0.000000] [<fffffc000821fa70>] new_slab+0xd0/0x564
[    0.000000] [<fffffc0008221e24>] ___slab_alloc+0x2e4/0x514
[    0.000000] [<fffffc0008239498>] __slab_alloc+0x48/0x58
[    0.000000] [<fffffc0008222c20>] __kmalloc_node+0xd0/0x2dc
[    0.000000] [<fffffc0008115374>] __irq_domain_add+0x7c/0x164
[    0.000000] [<fffffc0008b461dc>] its_probe+0x784/0x81c
[    0.000000] [<fffffc0008b462bc>] its_init+0x48/0x1b0
[    0.000000] [<fffffc0008b4543c>] gic_init_bases+0x228/0x360
[    0.000000] [<fffffc0008b456bc>] gic_of_init+0x148/0x1cc
[    0.000000] [<fffffc0008b5aec8>] of_irq_init+0x184/0x298
[    0.000000] [<fffffc0008b43f9c>] irqchip_init+0x14/0x38
[    0.000000] [<fffffc0008b12d60>] init_IRQ+0xc/0x30
[    0.000000] [<fffffc0008b10a3c>] start_kernel+0x240/0x3b8
[    0.000000] [<fffffc0008b101c4>] __primary_switched+0x30/0x6c
[    0.000000] Code: 912ec2a0 b9403809 0a0902fb 37b007db (f9400300)
[    0.000000] ---[ end trace 0000000000000000 ]---
[    0.000000] Kernel panic - not syncing: Fatal exception
[    0.000000] ---[ end Kernel panic - not syncing: Fatal exception


Same thing on v4.8.x and v4.9-rc?




>
> -Robert
>

^ permalink raw reply

* [PATCH 02/12] ASoC: dapm: Implement stereo mixer control support
From: Mark Brown @ 2016-10-26 16:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161003110804.28235-3-wens@csie.org>

On Mon, Oct 03, 2016 at 07:07:54PM +0800, Chen-Yu Tsai wrote:

> While DAPM is mono or single channel, its controls can be shared between
> widgets, such as sharing one stereo mixer control between the left and
> right channel widgets.

> This patch introduces support for such shared mixer controls.

Based on this changelog I'm really not sure what the intended semantic
of this change is which makes it difficult to review.  What are you
expecting these controls to look like and how are you expecting them to
work?

> -static void dapm_set_mixer_path_status(struct snd_soc_dapm_path *p, int i)
> +static void dapm_set_mixer_path_status(struct snd_soc_dapm_path *p, int i,
> +				       int nth_path)

It looks like the goal is to attach more than one path to a single
control somehow?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161026/f0e9a8c2/attachment.sig>

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox