From: Athira Rajeev <atrajeev@linux.ibm.com>
To: linuxppc-dev@lists.ozlabs.org, maddy@linux.ibm.com
Cc: linux-perf-users@vger.kernel.org, atrajeev@linux.ibm.com,
hbathini@linux.vnet.ibm.com, tejas05@linux.ibm.com,
venkat88@linux.ibm.com, tshah@linux.ibm.com, usha.r2@ibm.com
Subject: [PATCH V2 4/6] powerpc/perf: Capture the HTM memory configuration as part of perf data
Date: Mon, 20 Jul 2026 16:14:45 +0530 [thread overview]
Message-ID: <20260720104447.11843-5-atrajeev@linux.ibm.com> (raw)
In-Reply-To: <20260720104447.11843-1-atrajeev@linux.ibm.com>
The H_HTM hypervisor call can also return the system memory
configuration, which describes the physical to logical real address
mapping for logical partitions.
After dumping HTM trace data into the AUX buffer, capture the
corresponding HTM system memory configuration records and emit them as
raw perf sample data for userspace parsing.
Add AUX-private tracking for a hypervisor memory-configuration dump
buffer, a stable emit buffer, and iterator state. Once AUX trace dumping
completes, htm_event_read() switches to H_HTM_OP_DUMP_SYSMEM_CONF and
iterates over the returned records until the configuration stream is
exhausted.
Trace payload continues to be written to the AUX buffer, while memory
configuration records are emitted as raw perf samples. This keeps the
AUX stream focused on trace data and allows the configuration records to
be decoded separately in userspace.
Keep HTM tracing state in event->pmu_private via htm_target_id. AUX
private state is used only for dump progress and staging buffers.
Signed-off-by: Athira Rajeev <atrajeev@linux.ibm.com>
---
Changes in V2:
- Memory configuration records are now emitted as PERF_SAMPLE_RAW
samples directly by htm_event_read() after the AUX trace dump
completes, using H_HTM_OP_DUMP_SYSMEM_CONF. V1 embedded the
configuration data inside the AUX buffer itself and used two
PERF_SAMPLE_RAW boundary markers (start/end) to delimit it.
- The two-marker boundary scheme is removed. There is no longer any
interleaving of memory configuration data inside the AUX stream;
the AUX buffer carries only bus-trace data.
- Separate AUX-private fields for a hypervisor dump buffer, a stable
emit buffer, and iterator state are introduced to manage the
multi-call SYSMEM_CONF dump loop.
- Tracing state remains in event->pmu_private (htm_target_id); AUX
private state is used only for dump progress and staging buffers,
consistent with the restructuring in patches 1 and 3.
arch/powerpc/perf/htm-perf.c | 124 ++++++++++++++++++++++++++++++++++-
1 file changed, 123 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/perf/htm-perf.c b/arch/powerpc/perf/htm-perf.c
index edfca63e1e9b..7e6a67485800 100644
--- a/arch/powerpc/perf/htm-perf.c
+++ b/arch/powerpc/perf/htm-perf.c
@@ -104,6 +104,10 @@ struct htm_pmu_buf {
u64 size;
int collect_htm_trace;
u64 trace_records;
+ void *htm_mem_buf; /* Staging bounce area allocated node-locally */
+ void *emit_buf; /* Stable buffer for perf raw sample emission */
+ u64 mem_start; /* Hypervisor offset state iterator tracker */
+ int collect_htm_mem; /* State flag tracking whether memory logging is ongoing */
};
struct htm_pmu_ctx {
@@ -173,6 +177,99 @@ static ssize_t htm_return_check(int rc)
#define HTM_TRACING_ACTIVE 1
#define HTM_TRACING_INACTIVE 0
+#define HTM_MEM_MAX_ENTRIES 2013U
+#define HTM_MEM_BUF_SIZE (32 + HTM_MEM_MAX_ENTRIES * 32)
+
+static int htm_collect_memory_config(struct perf_event *event,
+ struct htm_pmu_buf *aux_buf)
+{
+ struct perf_sample_data data;
+ struct perf_raw_record raw;
+ struct pt_regs regs;
+ u8 *htm_mem_buf = aux_buf->htm_mem_buf;
+ __be64 *num_entries;
+ u64 next_start;
+ u64 to_copy;
+ void *emit_buf = aux_buf->emit_buf;
+ long rc;
+ int ret = 0;
+ int retries;
+ int emitted = 0;
+
+ /*
+ * htm_mem_buf is the hcall memory buffer target reused each iteration.
+ * emit_buf is a preallocated stable buffer used for perf raw
+ * sample emission, so raw.frag.data remains valid during
+ * perf_event_overflow().
+ * Size: 32-byte header + HTM_MEM_MAX_ENTRIES * 32-byte entries.
+ */
+ while (true) {
+ retries = 0;
+ do {
+ rc = htm_hcall_wrapper(htmflags, 0, 0, 0,
+ 0, H_HTM_OP_DUMP_SYSMEM_CONF,
+ virt_to_phys(aux_buf->htm_mem_buf),
+ HTM_MEM_BUF_SIZE, aux_buf->mem_start);
+ ret = htm_return_check(rc);
+ } while (ret == -EBUSY && ++retries < MAX_RETRIES);
+
+ /* H_NOT_AVAILABLE or error: no more data */
+ if (ret <= 0) {
+ aux_buf->collect_htm_mem = 0;
+ break;
+ }
+
+ /*
+ * Read next iterator value from the hcall response BEFORE
+ * emitting, but only commit it to mem_start after a
+ * successful writing of raw data/
+ */
+ next_start = be64_to_cpu(*((__be64 *)(htm_mem_buf + 0x8)));
+
+ /*
+ * The hcall was given HTM_MEM_BUF_SIZE bytes of buffer space,
+ * so num_entries is already bounded to HTM_MEM_MAX_ENTRIES.
+ * The response is a complete hcall data:
+ * [32-byte header][num_entries * 32-byte entries]
+ * Userspace can validate and parse it directly.
+ */
+ num_entries = (__be64 *)(htm_mem_buf + 0x10);
+ to_copy = 32 + (be64_to_cpu(*num_entries) * 32);
+ if (WARN_ON_ONCE(to_copy > HTM_MEM_BUF_SIZE)) {
+ ret = -EIO;
+ aux_buf->collect_htm_mem = 0;
+ break;
+ }
+
+ memcpy(emit_buf, aux_buf->htm_mem_buf, to_copy);
+
+ perf_sample_data_init(&data, 0, event->hw.last_period);
+ memset(&raw, 0, sizeof(raw));
+ raw.frag.data = emit_buf;
+ raw.frag.size = to_copy;
+ perf_sample_save_raw_data(&data, event, &raw);
+
+ if (perf_event_overflow(event, &data, ®s)) {
+ ret = 0;
+ break;
+ }
+
+ /* Record written: advance next read iterator */
+ aux_buf->mem_start = next_start;
+ emitted = 1;
+
+ if (!next_start) {
+ aux_buf->collect_htm_mem = 0;
+ break;
+ }
+ }
+
+ if (emitted)
+ return 1;
+
+ return ret;
+}
+
static void reset_htm_active(struct perf_event *event)
{
struct htm_target_id *target = event->pmu_private;
@@ -407,7 +504,7 @@ static int htm_dump_sample_data(struct perf_event *event)
if (!aux_buf)
return 0;
- if (!aux_buf->collect_htm_trace) {
+ if (!aux_buf->collect_htm_trace && !aux_buf->collect_htm_mem) {
perf_aux_output_end(&htm_ctx->handle, 0);
return 0;
}
@@ -420,6 +517,11 @@ static int htm_dump_sample_data(struct perf_event *event)
}
}
+ if (!aux_buf->collect_htm_trace) {
+ ret = htm_collect_memory_config(event, aux_buf);
+ goto out;
+ }
+
/* Derive the exact target destination point directly out of active ring pointers */
dump_offset = htm_ctx->handle.head & (aux_buf->size - 1);
page_index = dump_offset >> PAGE_SHIFT;
@@ -506,6 +608,8 @@ static int htm_dump_sample_data(struct perf_event *event)
}
aux_buf->collect_htm_trace = 0;
+ ret = htm_collect_memory_config(event, aux_buf);
+out:
perf_aux_output_end(&htm_ctx->handle, 0);
return ret;
}
@@ -568,7 +672,23 @@ static void *htm_setup_aux(struct perf_event *event, void **pages,
return NULL;
}
+ buf->htm_mem_buf = kmalloc_node(PAGE_SIZE, GFP_KERNEL, cpu_to_node(cpu));
+ if (!buf->htm_mem_buf) {
+ kfree(buf);
+ return NULL;
+ }
+
+ buf->emit_buf = kmalloc_node(HTM_MEM_BUF_SIZE, GFP_KERNEL,
+ cpu_to_node(cpu));
+ if (!buf->emit_buf) {
+ kfree(buf->htm_mem_buf);
+ kfree(buf);
+ return NULL;
+ }
+
buf->collect_htm_trace = 1;
+ buf->collect_htm_mem = 1;
+ buf->mem_start = 0;
buf->trace_records = 0;
buf->head = 0;
return buf;
@@ -584,6 +704,8 @@ static void htm_free_aux(void *aux)
if (!buf)
return;
+ kfree(buf->emit_buf);
+ kfree(buf->htm_mem_buf);
kfree(buf);
}
--
2.43.0
next prev parent reply other threads:[~2026-07-20 10:45 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-20 10:44 [PATCH V2 0/6] powerpc/perf: Add HTM PMU driver and perf AUX support Athira Rajeev
2026-07-20 10:44 ` [PATCH V2 1/6] powerpc/perf: Add HTM PMU driver to expose Hardware Trace Macro data Athira Rajeev
2026-07-20 11:00 ` sashiko-bot
2026-07-20 10:44 ` [PATCH V2 2/6] powerpc/perf: Reject duplicate HTM target reservations Athira Rajeev
2026-07-20 10:55 ` sashiko-bot
2026-07-20 10:44 ` [PATCH V2 3/6] powerpc/perf: Add AUX buffer management to capture HTM trace data Athira Rajeev
2026-07-20 11:10 ` sashiko-bot
2026-07-20 10:44 ` Athira Rajeev [this message]
2026-07-20 11:09 ` [PATCH V2 4/6] powerpc/perf: Capture the HTM memory configuration as part of perf data sashiko-bot
2026-07-20 10:44 ` [PATCH V2 5/6] docs: ABI: sysfs-bus-event_source-devices-htm: Document sysfs event format entries for htm pmu Athira Rajeev
2026-07-20 11:13 ` sashiko-bot
2026-07-20 10:44 ` [PATCH V2 6/6] powerpc/perf/htm: Add documentation for Hardware Trace Macro PMU Athira Rajeev
2026-07-20 11:17 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260720104447.11843-5-atrajeev@linux.ibm.com \
--to=atrajeev@linux.ibm.com \
--cc=hbathini@linux.vnet.ibm.com \
--cc=linux-perf-users@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=maddy@linux.ibm.com \
--cc=tejas05@linux.ibm.com \
--cc=tshah@linux.ibm.com \
--cc=usha.r2@ibm.com \
--cc=venkat88@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox