All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/4] Add a tracepoint for DTL entries
@ 2018-09-19  8:08 Naveen N. Rao
  2018-09-19  8:08 ` [RFC PATCH 1/4] powerpc/pseries: Use macros for referring to the DTL enable mask Naveen N. Rao
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Naveen N. Rao @ 2018-09-19  8:08 UTC (permalink / raw)
  To: Michael Ellerman, Nathan Fontenot, Michael Bringmann; +Cc: linuxppc-dev

Add a tracepoint for the DTL entries to enable processing the DTL 
entries via the kernel tracing infrastructure. In addition to that, the 
tracpoint also exposes where a vcpu was dispatched in a SPLPAR 
environment, relative to the Power Hypervisor's idea of that vcpu's home 
node.

This is working fine for me, so posting this out to get some early 
feedback. The one aspect I need to look into is in terms of updating the 
pcpu associativity masks on appropriate events.


- Naveen


Naveen N. Rao (4):
  powerpc/pseries: Use macros for referring to the DTL enable mask
  powerpc/pseries: Do not save the previous DTL mask value
  powerpc/pseries: Introduce helpers to change the DTL enable mask
  powerpc/pseries: Introduce dtl_entry tracepoint

 arch/powerpc/include/asm/lppaca.h      | 15 ++++
 arch/powerpc/include/asm/trace.h       | 53 +++++++++++++++
 arch/powerpc/kernel/time.c             |  9 +++
 arch/powerpc/mm/numa.c                 | 94 ++++++++++++++++++++++++--
 arch/powerpc/platforms/pseries/dtl.c   | 15 ++--
 arch/powerpc/platforms/pseries/lpar.c  | 64 +++++++++++++++++-
 arch/powerpc/platforms/pseries/setup.c |  2 +-
 7 files changed, 233 insertions(+), 19 deletions(-)

-- 
2.18.0

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [RFC PATCH 1/4] powerpc/pseries: Use macros for referring to the DTL enable mask
  2018-09-19  8:08 [RFC PATCH 0/4] Add a tracepoint for DTL entries Naveen N. Rao
@ 2018-09-19  8:08 ` Naveen N. Rao
  2018-09-19  8:08 ` [RFC PATCH 2/4] powerpc/pseries: Do not save the previous DTL mask value Naveen N. Rao
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Naveen N. Rao @ 2018-09-19  8:08 UTC (permalink / raw)
  To: Michael Ellerman, Nathan Fontenot, Michael Bringmann; +Cc: linuxppc-dev

Introduce macros to encode the DTL enable mask fields and use those
instead of hardcoding numbers.

Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/lppaca.h      | 11 +++++++++++
 arch/powerpc/platforms/pseries/dtl.c   |  8 +-------
 arch/powerpc/platforms/pseries/lpar.c  |  2 +-
 arch/powerpc/platforms/pseries/setup.c |  2 +-
 4 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h
index 7c23ce8a5a4c..2c7e31187726 100644
--- a/arch/powerpc/include/asm/lppaca.h
+++ b/arch/powerpc/include/asm/lppaca.h
@@ -154,6 +154,17 @@ struct dtl_entry {
 #define DISPATCH_LOG_BYTES	4096	/* bytes per cpu */
 #define N_DISPATCH_LOG		(DISPATCH_LOG_BYTES / sizeof(struct dtl_entry))
 
+/*
+ * Dispatch trace log event enable mask:
+ *   0x1: voluntary virtual processor waits
+ *   0x2: time-slice preempts
+ *   0x4: virtual partition memory page faults
+ */
+#define DTL_LOG_CEDE		0x1
+#define DTL_LOG_PREEMPT		0x2
+#define DTL_LOG_FAULT		0x4
+#define DTL_LOG_ALL		(DTL_LOG_CEDE | DTL_LOG_PREEMPT | DTL_LOG_FAULT)
+
 extern struct kmem_cache *dtl_cache;
 
 /*
diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c
index 18014cdeb590..e0421aa6eafa 100644
--- a/arch/powerpc/platforms/pseries/dtl.c
+++ b/arch/powerpc/platforms/pseries/dtl.c
@@ -40,13 +40,7 @@ struct dtl {
 };
 static DEFINE_PER_CPU(struct dtl, cpu_dtl);
 
-/*
- * Dispatch trace log event mask:
- * 0x7: 0x1: voluntary virtual processor waits
- *      0x2: time-slice preempts
- *      0x4: virtual partition memory page faults
- */
-static u8 dtl_event_mask = 0x7;
+static u8 dtl_event_mask = DTL_LOG_ALL;
 
 
 /*
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index d3992ced0782..dd024a192512 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -125,7 +125,7 @@ void vpa_init(int cpu)
 			pr_err("WARNING: DTL registration of cpu %d (hw %d) "
 			       "failed with %ld\n", smp_processor_id(),
 			       hwcpu, ret);
-		lppaca_of(cpu).dtl_enable_mask = 2;
+		lppaca_of(cpu).dtl_enable_mask = DTL_LOG_PREEMPT;
 	}
 }
 
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index ba1791fd3234..a48cb9757be2 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -293,7 +293,7 @@ static int alloc_dispatch_logs(void)
 		pr_err("WARNING: DTL registration of cpu %d (hw %d) failed "
 		       "with %d\n", smp_processor_id(),
 		       hard_smp_processor_id(), ret);
-	get_paca()->lppaca_ptr->dtl_enable_mask = 2;
+	get_paca()->lppaca_ptr->dtl_enable_mask = DTL_LOG_PREEMPT;
 
 	return 0;
 }
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [RFC PATCH 2/4] powerpc/pseries: Do not save the previous DTL mask value
  2018-09-19  8:08 [RFC PATCH 0/4] Add a tracepoint for DTL entries Naveen N. Rao
  2018-09-19  8:08 ` [RFC PATCH 1/4] powerpc/pseries: Use macros for referring to the DTL enable mask Naveen N. Rao
@ 2018-09-19  8:08 ` Naveen N. Rao
  2018-09-19  8:08 ` [RFC PATCH 3/4] powerpc/pseries: Introduce helpers to change the DTL enable mask Naveen N. Rao
  2018-09-19  8:08 ` [RFC PATCH 4/4] powerpc/pseries: Introduce dtl_entry tracepoint Naveen N. Rao
  3 siblings, 0 replies; 5+ messages in thread
From: Naveen N. Rao @ 2018-09-19  8:08 UTC (permalink / raw)
  To: Michael Ellerman, Nathan Fontenot, Michael Bringmann; +Cc: linuxppc-dev

When CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is enabled, we always initialize
DTL enable mask to DTL_LOG_PREEMPT (0x2). There are no other places
where the mask is changed. As such, when reading the DTL log buffer
through debugfs, there is no need to save and restore the previous mask
value.

We don't need to save and restore the earlier mask value if
CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is not enabled. So, remove the field
from the structure as well.

Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/dtl.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c
index e0421aa6eafa..fe333c2525fb 100644
--- a/arch/powerpc/platforms/pseries/dtl.c
+++ b/arch/powerpc/platforms/pseries/dtl.c
@@ -55,7 +55,6 @@ struct dtl_ring {
 	struct dtl_entry *write_ptr;
 	struct dtl_entry *buf;
 	struct dtl_entry *buf_end;
-	u8	saved_dtl_mask;
 };
 
 static DEFINE_PER_CPU(struct dtl_ring, dtl_rings);
@@ -105,7 +104,6 @@ static int dtl_start(struct dtl *dtl)
 	dtlr->write_ptr = dtl->buf;
 
 	/* enable event logging */
-	dtlr->saved_dtl_mask = lppaca_of(dtl->cpu).dtl_enable_mask;
 	lppaca_of(dtl->cpu).dtl_enable_mask |= dtl_event_mask;
 
 	dtl_consumer = consume_dtle;
@@ -123,7 +121,7 @@ static void dtl_stop(struct dtl *dtl)
 	dtlr->buf = NULL;
 
 	/* restore dtl_enable_mask */
-	lppaca_of(dtl->cpu).dtl_enable_mask = dtlr->saved_dtl_mask;
+	lppaca_of(dtl->cpu).dtl_enable_mask = DTL_LOG_PREEMPT;
 
 	if (atomic_dec_and_test(&dtl_count))
 		dtl_consumer = NULL;
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [RFC PATCH 3/4] powerpc/pseries: Introduce helpers to change the DTL enable mask
  2018-09-19  8:08 [RFC PATCH 0/4] Add a tracepoint for DTL entries Naveen N. Rao
  2018-09-19  8:08 ` [RFC PATCH 1/4] powerpc/pseries: Use macros for referring to the DTL enable mask Naveen N. Rao
  2018-09-19  8:08 ` [RFC PATCH 2/4] powerpc/pseries: Do not save the previous DTL mask value Naveen N. Rao
@ 2018-09-19  8:08 ` Naveen N. Rao
  2018-09-19  8:08 ` [RFC PATCH 4/4] powerpc/pseries: Introduce dtl_entry tracepoint Naveen N. Rao
  3 siblings, 0 replies; 5+ messages in thread
From: Naveen N. Rao @ 2018-09-19  8:08 UTC (permalink / raw)
  To: Michael Ellerman, Nathan Fontenot, Michael Bringmann; +Cc: linuxppc-dev

In a subsequent patch, we want to be able to change the DTL enable mask
globally for all cpus. This conflicts with the current debugfs interface
that provides access to the DTL buffer contents.

To ensure consistent behavior, we introduce helpers to change the DTL
enable mask on either a specific cpu, or globally for all cpus. Setting
the DTL enable mask globally prevents changes to cpu-specific DTL enable
mask, and vice versa. We also introduce 'dtl_mask' so that when the DTL
enable mask is changed globally, new cpus also honor that.

Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/lppaca.h      |  4 ++
 arch/powerpc/platforms/pseries/dtl.c   |  5 +-
 arch/powerpc/platforms/pseries/lpar.c  | 64 +++++++++++++++++++++++++-
 arch/powerpc/platforms/pseries/setup.c |  2 +-
 4 files changed, 71 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h
index 2c7e31187726..144862f86392 100644
--- a/arch/powerpc/include/asm/lppaca.h
+++ b/arch/powerpc/include/asm/lppaca.h
@@ -165,6 +165,10 @@ struct dtl_entry {
 #define DTL_LOG_FAULT		0x4
 #define DTL_LOG_ALL		(DTL_LOG_CEDE | DTL_LOG_PREEMPT | DTL_LOG_FAULT)
 
+extern u8 dtl_mask;
+int set_dtl_mask(int cpu, int mask);
+void reset_dtl_mask(int cpu);
+
 extern struct kmem_cache *dtl_cache;
 
 /*
diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c
index fe333c2525fb..3b98fc19c53f 100644
--- a/arch/powerpc/platforms/pseries/dtl.c
+++ b/arch/powerpc/platforms/pseries/dtl.c
@@ -104,7 +104,8 @@ static int dtl_start(struct dtl *dtl)
 	dtlr->write_ptr = dtl->buf;
 
 	/* enable event logging */
-	lppaca_of(dtl->cpu).dtl_enable_mask |= dtl_event_mask;
+	if (set_dtl_mask(dtl->cpu, dtl_event_mask))
+		return -EBUSY;
 
 	dtl_consumer = consume_dtle;
 	atomic_inc(&dtl_count);
@@ -121,7 +122,7 @@ static void dtl_stop(struct dtl *dtl)
 	dtlr->buf = NULL;
 
 	/* restore dtl_enable_mask */
-	lppaca_of(dtl->cpu).dtl_enable_mask = DTL_LOG_PREEMPT;
+	reset_dtl_mask(dtl->cpu);
 
 	if (atomic_dec_and_test(&dtl_count))
 		dtl_consumer = NULL;
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index dd024a192512..6563e7a782a3 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -58,12 +58,74 @@
 #define HBR_AVPN	0x0200000000000000UL
 #define HBR_ANDCOND	0x0100000000000000UL
 
+u8 dtl_mask = DTL_LOG_PREEMPT;
+static u8 dtl_mask_global_refctr, dtl_mask_percpu_inuse;
+static DEFINE_MUTEX(dtl_mask_mutex);
 
 /* in hvCall.S */
 EXPORT_SYMBOL(plpar_hcall);
 EXPORT_SYMBOL(plpar_hcall9);
 EXPORT_SYMBOL(plpar_hcall_norets);
 
+int set_dtl_mask(int cpu, int mask)
+{
+	int rc = 0;
+
+	mutex_lock(&dtl_mask_mutex);
+
+	if ((cpu == -1 && dtl_mask_percpu_inuse) ||
+	    (cpu >= 0 && dtl_mask_global_refctr)) {
+		rc = -1;
+		goto out;
+	}
+
+	if (cpu >= 0) {
+		dtl_mask_percpu_inuse++;
+		lppaca_of(cpu).dtl_enable_mask = mask;
+		goto out;
+	}
+
+	if (dtl_mask_global_refctr && mask != dtl_mask) {
+		rc = -1;
+		goto out;
+	}
+
+	if (!dtl_mask_global_refctr) {
+		dtl_mask = mask;
+		for_each_present_cpu(cpu)
+			lppaca_of(cpu).dtl_enable_mask = mask;
+	}
+
+	dtl_mask_global_refctr++;
+
+out:
+	mutex_unlock(&dtl_mask_mutex);
+
+	return rc;
+}
+
+void reset_dtl_mask(int cpu)
+{
+	mutex_lock(&dtl_mask_mutex);
+
+	if (cpu >= 0) {
+		dtl_mask_percpu_inuse--;
+		lppaca_of(cpu).dtl_enable_mask = DTL_LOG_PREEMPT;
+		goto out;
+	}
+
+	dtl_mask_global_refctr--;
+
+	if (!dtl_mask_global_refctr) {
+		dtl_mask = DTL_LOG_PREEMPT;
+		for_each_present_cpu(cpu)
+			lppaca_of(cpu).dtl_enable_mask = dtl_mask;
+	}
+
+out:
+	mutex_unlock(&dtl_mask_mutex);
+}
+
 void vpa_init(int cpu)
 {
 	int hwcpu = get_hard_smp_processor_id(cpu);
@@ -125,7 +187,7 @@ void vpa_init(int cpu)
 			pr_err("WARNING: DTL registration of cpu %d (hw %d) "
 			       "failed with %ld\n", smp_processor_id(),
 			       hwcpu, ret);
-		lppaca_of(cpu).dtl_enable_mask = DTL_LOG_PREEMPT;
+		lppaca_of(cpu).dtl_enable_mask = dtl_mask;
 	}
 }
 
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index a48cb9757be2..285a35f32d3d 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -293,7 +293,7 @@ static int alloc_dispatch_logs(void)
 		pr_err("WARNING: DTL registration of cpu %d (hw %d) failed "
 		       "with %d\n", smp_processor_id(),
 		       hard_smp_processor_id(), ret);
-	get_paca()->lppaca_ptr->dtl_enable_mask = DTL_LOG_PREEMPT;
+	get_paca()->lppaca_ptr->dtl_enable_mask = dtl_mask;
 
 	return 0;
 }
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [RFC PATCH 4/4] powerpc/pseries: Introduce dtl_entry tracepoint
  2018-09-19  8:08 [RFC PATCH 0/4] Add a tracepoint for DTL entries Naveen N. Rao
                   ` (2 preceding siblings ...)
  2018-09-19  8:08 ` [RFC PATCH 3/4] powerpc/pseries: Introduce helpers to change the DTL enable mask Naveen N. Rao
@ 2018-09-19  8:08 ` Naveen N. Rao
  3 siblings, 0 replies; 5+ messages in thread
From: Naveen N. Rao @ 2018-09-19  8:08 UTC (permalink / raw)
  To: Michael Ellerman, Nathan Fontenot, Michael Bringmann; +Cc: linuxppc-dev

This tracepoint provides access to the fields of each DTL entry in the
Dispatch Trace Log buffer, and is hit when processing the DTL buffer for
accounting stolen time. As such, this tracepoint is only available when
CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is enabled.

Apart from making the DTL entries available for processing through the
usual trace interface, this tracepoint also adds a new field 'distance'
to each DTL entry, enabling enhanced statistics around the vcpu dispatch
behavior of the hypervisor.

For Shared Processor LPARs, the POWER Hypervisor maintains a relatively
static mapping of LPAR vcpus to physical processor cores and tries to
always dispatch vcpus on their associated physical processor core. The
LPAR can discover this through the H_VPHN(flags=1) hcall to obtain the
associativity of the LPAR vcpus.

However, under certain scenarios, vcpus may be dispatched on a different
processor core. The actual physical processor number on which a certain
vcpu is dispatched is available to the LPAR in the 'processor_id' field
of each DTL entry. The LPAR can then discover the associativity of that
physical processor through the H_VPHN(flags=2) hcall. This can then be
compared to the home node associativity for that specific vcpu to
determine if the vcpu was dispatched on the same core or not.  If the
vcpu was not dispatched on the home node, it is possible to determine if
the vcpu was dispatched in a different chip, socket or drawer.

The tracepoint field 'distance' encodes this information. If distance is
0, then the vcpu was dispatched on its home node. If not, increasing
values of 'distance' indicate a dispatch on a different core in the same
chip, different chip in a DCM, different socket or a different drawer.

Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/trace.h | 53 ++++++++++++++++++
 arch/powerpc/kernel/time.c       |  9 +++
 arch/powerpc/mm/numa.c           | 94 ++++++++++++++++++++++++++++++--
 3 files changed, 150 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/include/asm/trace.h b/arch/powerpc/include/asm/trace.h
index d018e8602694..27ccb2c8afc3 100644
--- a/arch/powerpc/include/asm/trace.h
+++ b/arch/powerpc/include/asm/trace.h
@@ -101,6 +101,59 @@ TRACE_EVENT_FN_COND(hcall_exit,
 
 	hcall_tracepoint_regfunc, hcall_tracepoint_unregfunc
 );
+
+extern int dtl_entry_tracepoint_regfunc(void);
+extern void dtl_entry_tracepoint_unregfunc(void);
+extern u8 compute_dispatch_distance(unsigned int pcpu);
+
+TRACE_EVENT_FN(dtl_entry,
+
+	TP_PROTO(u8 dispatch_reason, u8 preempt_reason, u16 processor_id,
+		u32 enqueue_to_dispatch_time, u32 ready_to_enqueue_time,
+		u32 waiting_to_ready_time, u64 timebase, u64 fault_addr,
+		u64 srr0, u64 srr1),
+
+	TP_ARGS(dispatch_reason, preempt_reason, processor_id,
+		enqueue_to_dispatch_time, ready_to_enqueue_time,
+		waiting_to_ready_time, timebase, fault_addr,
+		srr0, srr1),
+
+	TP_STRUCT__entry(
+		__field(u8, dispatch_reason)
+		__field(u8, preempt_reason)
+		__field(u16, processor_id)
+		__field(u32, enqueue_to_dispatch_time)
+		__field(u32, ready_to_enqueue_time)
+		__field(u32, waiting_to_ready_time)
+		__field(u64, timebase)
+		__field(u64, fault_addr)
+		__field(u64, srr0)
+		__field(u64, srr1)
+		__field(u8, distance)
+	),
+
+	TP_fast_assign(
+		__entry->dispatch_reason = dispatch_reason;
+		__entry->preempt_reason = preempt_reason;
+		__entry->processor_id = processor_id;
+		__entry->enqueue_to_dispatch_time = enqueue_to_dispatch_time;
+		__entry->ready_to_enqueue_time = ready_to_enqueue_time;
+		__entry->waiting_to_ready_time = waiting_to_ready_time;
+		__entry->timebase = timebase;
+		__entry->fault_addr = fault_addr;
+		__entry->srr0 = srr0;
+		__entry->srr1 = srr1;
+		__entry->distance = compute_dispatch_distance(processor_id);
+	),
+
+	TP_printk("dispatch_reason=%u preempt_reason=%u processor_id=%u enq_to_disp=%u ready_to_enq=%u wait_to_ready=%u tb=%llu fault_addr=0x%llx srr0=0x%llx srr1=0x%llx distance=%u",
+		__entry->dispatch_reason, __entry->preempt_reason, __entry->processor_id,
+		__entry->enqueue_to_dispatch_time, __entry->ready_to_enqueue_time,
+		__entry->waiting_to_ready_time, __entry->timebase, __entry->fault_addr,
+		__entry->srr0, __entry->srr1, __entry->distance),
+
+	dtl_entry_tracepoint_regfunc, dtl_entry_tracepoint_unregfunc
+);
 #endif
 
 #ifdef CONFIG_PPC_POWERNV
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 70f145e02487..94802fc22521 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -220,6 +220,15 @@ static u64 scan_dispatch_log(u64 stop_tb)
 			break;
 		if (dtl_consumer)
 			dtl_consumer(dtl, i);
+		trace_dtl_entry(dtl->dispatch_reason, dtl->preempt_reason,
+				be16_to_cpu(dtl->processor_id),
+				be32_to_cpu(dtl->enqueue_to_dispatch_time),
+				be32_to_cpu(dtl->ready_to_enqueue_time),
+				be32_to_cpu(dtl->waiting_to_ready_time),
+				be64_to_cpu(dtl->timebase),
+				be64_to_cpu(dtl->fault_addr),
+				be64_to_cpu(dtl->srr0),
+				be64_to_cpu(dtl->srr1));
 		stolen += tb_delta;
 		++i;
 		++dtl;
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 35ac5422903a..b3fcdf6a8b4a 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -41,6 +41,7 @@
 #include <asm/setup.h>
 #include <asm/vdso.h>
 #include <asm/drmem.h>
+#include <asm/trace.h>
 
 static int numa_enabled = 1;
 
@@ -1078,6 +1079,9 @@ static int prrn_enabled;
 static void reset_topology_timer(void);
 static int topology_timer_secs = 1;
 static int topology_inited;
+static __be32 vcpu_associativity[NR_CPUS][VPHN_ASSOC_BUFSIZE];
+static __be32 pcpu_associativity[NR_CPUS][VPHN_ASSOC_BUFSIZE];
+static unsigned int associativity_depth;
 
 /*
  * Change polling interval for associativity changes.
@@ -1157,14 +1161,12 @@ static int update_cpu_associativity_changes_mask(void)
  * Retrieve the new associativity information for a virtual processor's
  * home node.
  */
-static long hcall_vphn(unsigned long cpu, __be32 *associativity)
+static long hcall_vphn(unsigned long cpu, unsigned long flags, __be32 *associativity)
 {
 	long rc;
 	long retbuf[PLPAR_HCALL9_BUFSIZE] = {0};
-	u64 flags = 1;
-	int hwcpu = get_hard_smp_processor_id(cpu);
 
-	rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, retbuf, flags, hwcpu);
+	rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, retbuf, flags, cpu);
 	vphn_unpack_associativity(retbuf, associativity);
 
 	return rc;
@@ -1175,7 +1177,7 @@ static long vphn_get_associativity(unsigned long cpu,
 {
 	long rc;
 
-	rc = hcall_vphn(cpu, associativity);
+	rc = hcall_vphn(get_hard_smp_processor_id(cpu), 1, associativity);
 
 	switch (rc) {
 	case H_FUNCTION:
@@ -1200,7 +1202,7 @@ static long vphn_get_associativity(unsigned long cpu,
 
 int find_and_online_cpu_nid(int cpu)
 {
-	__be32 associativity[VPHN_ASSOC_BUFSIZE] = {0};
+	__be32 *associativity = vcpu_associativity[cpu];
 	int new_nid;
 
 	/* Use associativity from first thread for all siblings */
@@ -1234,6 +1236,86 @@ int find_and_online_cpu_nid(int cpu)
 	return new_nid;
 }
 
+static unsigned int find_possible_pcpus(void)
+{
+	struct device_node *rtas;
+	unsigned int max_depth, num_pcpus = 0;
+
+	rtas = of_find_node_by_path("/rtas");
+	if (min_common_depth <= 0 || !rtas)
+		return 0;
+
+	if (!of_property_read_u32(rtas,
+				"ibm,max-associativity-domains",
+				&max_depth))
+		of_property_read_u32_index(rtas,
+					   "ibm,max-associativity-domains",
+					   max_depth, &num_pcpus);
+
+	of_node_put(rtas);
+
+	return num_pcpus;
+}
+
+int dtl_entry_tracepoint_regfunc(void)
+{
+	unsigned int i, num_pcpus, pcpu_associativity_depth = 0;
+	long rc;
+
+	num_pcpus = find_possible_pcpus();
+	if (num_pcpus <= 0)
+		num_pcpus = NR_CPUS;
+	else
+		/*
+		 * The OF property reports the maximum cpu number.
+		 * We instead want the maximum number of cpus.
+		 */
+		num_pcpus++;
+
+	for (i = 0; i < NR_CPUS; i++) {
+		pcpu_associativity[i][0] = NR_CPUS;
+		if (i < num_pcpus && vphn_enabled) {
+			rc = hcall_vphn(i, 2, pcpu_associativity[i]);
+			if (!pcpu_associativity_depth && rc == H_SUCCESS)
+				pcpu_associativity_depth = pcpu_associativity[i][0];
+		}
+	}
+
+	if (vphn_enabled)
+		associativity_depth = min(pcpu_associativity_depth,
+				vcpu_associativity[smp_processor_id()][0]);
+
+	if (set_dtl_mask(-1, DTL_LOG_ALL))
+		return -EBUSY;
+
+	return 0;
+}
+
+void dtl_entry_tracepoint_unregfunc(void)
+{
+	reset_dtl_mask(-1);
+}
+
+u8 compute_dispatch_distance(unsigned int pcpu)
+{
+	__be32 *pcpu_assoc, *vcpu_assoc;
+	unsigned int i, distance = associativity_depth;
+
+	vcpu_assoc = vcpu_associativity[smp_processor_id()];
+	pcpu_assoc = pcpu_associativity[pcpu];
+
+	if (!vphn_enabled || pcpu_assoc[0] == NR_CPUS)
+		return 255;
+
+	for (i = 1; i <= associativity_depth; i++)
+		if (vcpu_assoc[i] == pcpu_assoc[i])
+			distance--;
+		else
+			break;
+
+	return distance;
+}
+
 /*
  * Update the CPU maps and sysfs entries for a single CPU when its NUMA
  * characteristics change. This function doesn't perform any locking and is
-- 
2.18.0

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-09-19  9:08 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-19  8:08 [RFC PATCH 0/4] Add a tracepoint for DTL entries Naveen N. Rao
2018-09-19  8:08 ` [RFC PATCH 1/4] powerpc/pseries: Use macros for referring to the DTL enable mask Naveen N. Rao
2018-09-19  8:08 ` [RFC PATCH 2/4] powerpc/pseries: Do not save the previous DTL mask value Naveen N. Rao
2018-09-19  8:08 ` [RFC PATCH 3/4] powerpc/pseries: Introduce helpers to change the DTL enable mask Naveen N. Rao
2018-09-19  8:08 ` [RFC PATCH 4/4] powerpc/pseries: Introduce dtl_entry tracepoint Naveen N. Rao

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.