All of lore.kernel.org
 help / color / mirror / Atom feed
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 V3 1/6] powerpc/perf: Add HTM PMU driver to expose Hardware Trace Macro data
Date: Sat, 25 Jul 2026 12:29:37 +0530	[thread overview]
Message-ID: <20260725065942.78839-2-atrajeev@linux.ibm.com> (raw)
In-Reply-To: <20260725065942.78839-1-atrajeev@linux.ibm.com>

The H_HTM hypervisor call (hcall) provides an interface to the Hardware
Trace Macro (HTM) function on POWER systems.  HTM captures hardware-level
trace data for a specific node/chip/core target within a logical partition.

Add a new "htm" Performance Monitoring Unit (PMU) that exposes HTM control
via the standard perf interface.  The event configuration is a 28-bit value
packed into the perf config field:

  bits  0-3:  htm_type         (HTM_CORE=2, HTM_NEST=1)
  bits  4-11: nodeindex
  bits 12-19: nodalchipindex
  bits 20-27: coreindexonchip

PMU lifecycle:

  add/del:    Issue H_HTM_OP_CONFIGURE / H_HTM_OP_DECONFIGURE to reserve
              and release the hardware trace resource.

  start/stop: Issue H_HTM_OP_START / H_HTM_OP_STOP to control tracing.
              HTM traces at node/chip/core scope continuously for the
              duration of the event.  Context-switch-triggered start/stop
              callbacks (PERF_EF_RELOAD / PERF_EF_UPDATE) are ignored to
              keep tracing uninterrupted.  Explicit ioctl(ENABLE/DISABLE)
              and event deletion do control the hardware.

State tracking uses event->pmu_private (HTM_TRACING_ACTIVE/INACTIVE) as
the source of information, with event->hw.state kept in sync as a hint
for the perf core.  This avoids conflicts with infrastructure writes to
event->hw.state.

H_BUSY, H_LONG_BUSY_* and other erros handling:

  All PMU callbacks (add, del, start, stop) are invoked in an atomic
  context with interrupts disabled and hardware context locks held;
  sleeping is not possible anywhere in the driver.

  H_BUSY (transient): retried in a spin loop up to MAX_RETRIES times.

  H_LONG_BUSY_* (hypervisor requests a long delay before retry) and
  other errors: not retried.  The correct response differs by callsite:

  - pmu->add (H_HTM_OP_CONFIGURE): returns -ENODEV on any non-success
    result from the configure hcall.  Returning -EAGAIN from pmu->add()
    would cause the perf core to re-queue the event and call pmu->add()
    again on every context switch, flooding the hypervisor with
    H_HTM_OP_CONFIGURE hcalls exactly when it has requested a long
    backoff delay.  -ENODEV is a hard failure that the perf core does
    not reschedule.

  - pmu->stop (H_HTM_OP_STOP): exits immediately on any failure,
    leaving tracing_active as HTM_TRACING_ACTIVE.  The perf core always
    calls pmu->del() after pmu->stop(), so htm_event_del() is the
    guaranteed retry point for the stop hcall.

  - pmu->del (H_HTM_OP_STOP retry and H_HTM_OP_DECONFIGURE): retries
    the stop hcall first.  H_HTM_OP_DECONFIGURE requires the trace to be
    stopped first; if the stop retry fails, the deconfigure will
    fail too.  Both failures are surfaced via pr_err with target
    identifiers (node/chip/core/type).
    A workqueue-based deferred cleanup was considered but rejected as
    over-engineering for a firmware-maintenance-only edge case that is
    consistent with how all other in-tree POWER hcall-backed PMU drivers

Note: this patch does not prevent two concurrent perf_event_open() calls
for the same HTM hardware target (node/chip/core) from being opened
simultaneously on different CPUs.  PERF_PMU_CAP_EXCLUSIVE only enforces
exclusivity within the same per-CPU context and does not cover this case.
A global reserved-targets list to reject duplicate reservations is added
in the next patch.

After this patch the PMU is visible under sysfs:

 # ls /sys/bus/event_source/devices/ |grep htm
 htm

 # ls /sys/bus/event_source/devices/htm/
 events  format  perf_event_mux_interval_ms  power  subsystem  type  uevent

Signed-off-by: Athira Rajeev <atrajeev@linux.ibm.com>
---
Changes in V3:
- Expanded the H_BUSY, H_LONG_BUSY_* and other errors handling section to
  give per-callsite rationale for each hcall (configure, stop, del).
  V2 described the retry policy but not why each site responds differently.
- Added explicit note that this patch does not yet prevent duplicate concurrent
  perf_event_open() calls for the same HTM target; that is handled in patch 2.
  V2 omitted this cross-reference.
- Diffstat grows from 379 to 422 lines added (the extra lines come from the
  expanded commit message body; no functional change to the driver code
  itself).
- No functional change to the driver code in this patch.

Changes in V2:
- Moved the HTM PMU driver from arch/powerpc/htm/ to arch/powerpc/perf/
  and renamed the source file from htm.c to htm-perf.c to follow the
  naming convention of other PMU drivers in that directory.
- Replaced direct H_HTM_OP_CONFIGURE/DECONFIGURE calls in htm_event_add()
  and htm_event_del() with separate htm_event_init() and destroy paths.
  State tracking is now via event->pmu_private (HTM_TRACING_ACTIVE /
  HTM_TRACING_INACTIVE) as the authoritative source, with event->hw.state
  kept in sync as a hint for the perf core, avoiding conflicts with
  infrastructure writes to event->hw.state.
- Context-switch callbacks (PERF_EF_RELOAD / PERF_EF_UPDATE) are now
  explicitly ignored in htm_event_start()/stop() to keep tracing
  uninterrupted across task switches; previously these paths were absent.
- H_BUSY retry loop is capped at MAX_RETRIES; H_LONG_BUSY_* is not
  retried in atomic context to avoid deadlocks (was unconditionally
  retried in V1).

 arch/powerpc/perf/Makefile   |   2 +-
 arch/powerpc/perf/htm-perf.c | 422 +++++++++++++++++++++++++++++++++++
 2 files changed, 423 insertions(+), 1 deletion(-)
 create mode 100644 arch/powerpc/perf/htm-perf.c

diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
index 78dd7e25219e..26ef30c0693c 100644
--- a/arch/powerpc/perf/Makefile
+++ b/arch/powerpc/perf/Makefile
@@ -14,7 +14,7 @@ obj-$(CONFIG_PPC_POWERNV)	+= imc-pmu.o
 obj-$(CONFIG_FSL_EMB_PERF_EVENT) += core-fsl-emb.o
 obj-$(CONFIG_FSL_EMB_PERF_EVENT_E500) += e500-pmu.o e6500-pmu.o
 
-obj-$(CONFIG_HV_PERF_CTRS) += hv-24x7.o hv-gpci.o hv-common.o vpa-dtl.o
+obj-$(CONFIG_HV_PERF_CTRS) += hv-24x7.o hv-gpci.o hv-common.o vpa-dtl.o htm-perf.o
 
 obj-$(CONFIG_VPA_PMU) += vpa-pmu.o
 
diff --git a/arch/powerpc/perf/htm-perf.c b/arch/powerpc/perf/htm-perf.c
new file mode 100644
index 000000000000..4e4c924ecfd0
--- /dev/null
+++ b/arch/powerpc/perf/htm-perf.c
@@ -0,0 +1,422 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Perf interface to expose HTM Trace data.
+ *
+ * Copyright (C) 2026 Athira Rajeev, IBM Corporation
+ */
+
+#define pr_fmt(fmt) "htm: " fmt
+
+#include <asm/dtl.h>
+#include <linux/perf_event.h>
+#include <asm/plpar_wrappers.h>
+#include <asm/firmware.h>
+
+#define EVENT(_name, _code)	enum{_name = _code}
+#define	MAX_RETRIES	100
+
+EVENT(HTM_CORE,		0x2);
+EVENT(HTM_NEST,		0x1);
+
+GENERIC_EVENT_ATTR(htm_core, HTM_CORE);
+GENERIC_EVENT_ATTR(htm_nest, HTM_NEST);
+
+PMU_FORMAT_ATTR(event, "config:0-27");
+PMU_FORMAT_ATTR(htm_type, "config:0-3");
+PMU_FORMAT_ATTR(nodeindex, "config:4-11");
+PMU_FORMAT_ATTR(nodalchipindex, "config:12-19");
+PMU_FORMAT_ATTR(coreindexonchip, "config:20-27");
+
+static struct attribute *events_attr[] = {
+	GENERIC_EVENT_PTR(HTM_NEST),
+	GENERIC_EVENT_PTR(HTM_CORE),
+	NULL
+};
+
+static struct attribute_group event_group = {
+	.name = "events",
+	.attrs = events_attr,
+};
+
+static struct attribute *format_attrs[] = {
+	&format_attr_event.attr,
+	&format_attr_htm_type.attr,
+	&format_attr_nodeindex.attr,
+	&format_attr_nodalchipindex.attr,
+	&format_attr_coreindexonchip.attr,
+	NULL,
+};
+
+static const struct attribute_group format_group = {
+	.name = "format",
+	.attrs = format_attrs,
+};
+
+static const struct attribute_group *attr_groups[] = {
+	&format_group,
+	&event_group,
+	NULL,
+};
+
+static u64 htmflags = H_HTM_FLAGS_NOWRAP;
+
+struct htm_config {
+	u32 htmtype;
+	u32 nodeindex;
+	u32 nodalchipindex;
+	u32 coreindexonchip;
+};
+
+/*
+ * Per-event private state.  Allocated in htm_event_init(), freed via the
+ * event->destroy callback (reset_htm_active()).
+ *
+ * cfg stores the HTM target identity parsed from event->attr.config.
+ * tracing_active tracks whether H_HTM_OP_START has been successfully issued
+ * for this event. It is the source of information used by
+ * htm_event_start() and htm_event_stop() to make hcall decisions.
+ * event->hw.state is kept in sync for the perf core only.
+ */
+struct htm_target_id {
+	struct htm_config cfg;
+	int tracing_active;		/* HTM_TRACING_ACTIVE / HTM_TRACING_INACTIVE */
+};
+
+/* Helper to parse the 28-bit event config into distinct fields */
+static inline void parse_htm_config(u64 config, struct htm_config *cfg)
+{
+	cfg->htmtype = config & 0xf;
+	cfg->nodeindex = (config >> 4) & 0xff;
+	cfg->nodalchipindex = (config >> 12) & 0xff;
+	cfg->coreindexonchip = (config >> 20) & 0xff;
+}
+
+/*
+ * Check the return code for H_HTM hcall.
+ * Return 1 if either H_PARTIAL or H_SUCCESS is returned.
+ * Return 0 if H_NOT_AVAILABLE.
+ * Return exact negative error codes for expected issues.
+ */
+static ssize_t htm_return_check(int rc)
+{
+	switch (rc) {
+	case H_SUCCESS:
+	case H_PARTIAL:
+		return 1;
+	case H_NOT_AVAILABLE:
+		return 0;
+	case H_BUSY:
+		/* Transient busy: retry loop will spin up to MAX_RETRIES */
+		return -EBUSY;
+	case H_LONG_BUSY_ORDER_1_MSEC:
+	case H_LONG_BUSY_ORDER_10_MSEC:
+	case H_LONG_BUSY_ORDER_100_MSEC:
+	case H_LONG_BUSY_ORDER_1_SEC:
+	case H_LONG_BUSY_ORDER_10_SEC:
+	case H_LONG_BUSY_ORDER_100_SEC:
+		/*
+		 * Hypervisor requests a long delay before retry.  All PMU
+		 * callbacks (add, del, start, stop) are invoked in an atomic
+		 * context with interrupts disabled and hardware context locks
+		 * held. sleeping is not possible anywhere in the driver.
+		 * Return -EAGAIN so every caller can distinguish this from
+		 * transient H_BUSY and treat it as a hard failure without
+		 * spinning or sleeping. See the per-callsite comments for how
+		 * each caller handles it.
+		 */
+		return -EAGAIN;
+	case H_PARAMETER:
+	case H_P2:
+	case H_P3:
+	case H_P4:
+	case H_P5:
+	case H_P6:
+		return -EINVAL;
+	case H_STATE:
+		return -EIO;
+	case H_AUTHORITY:
+		return -EPERM;
+	default:
+		/* Prevent silent fallthrough mapping of unhandled errors to 1 */
+		return -EIO;
+	}
+}
+
+/*
+ * HTM_TRACING_ACTIVE/INACTIVE: values for htm_target_id.tracing_active.
+ * Tracks whether H_HTM_OP_START has been successfully issued.
+ * HTM traces at node/chip/core scope, not per-task. Once started,
+ * context-switch-triggered stop/start (PERF_EF_UPDATE / PERF_EF_RELOAD)
+ * must not stop/restart the hardware. Only explicit API calls
+ * (ioctl DISABLE/ENABLE) and event_del should control the hcall.
+ */
+#define HTM_TRACING_ACTIVE	1
+#define HTM_TRACING_INACTIVE	0
+
+static void reset_htm_active(struct perf_event *event)
+{
+	kfree(event->pmu_private);
+	event->pmu_private = NULL;
+}
+
+static int htm_event_init(struct perf_event *event)
+{
+	u64 config = event->attr.config;
+	struct htm_config cfg;
+
+	if (event->attr.inherit)
+		return -EOPNOTSUPP;
+
+	if (event->attr.type != event->pmu->type)
+		return -ENOENT;
+
+	if (!perfmon_capable())
+		return -EACCES;
+
+	if (!is_sampling_event(event))
+		return -EOPNOTSUPP;
+
+	if (has_branch_stack(event))
+		return -EOPNOTSUPP;
+
+	parse_htm_config(config, &cfg);
+	switch (cfg.htmtype) {
+	case HTM_CORE:
+	case HTM_NEST:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Allocate per-event private state; freed via event->destroy */
+	event->pmu_private = kzalloc(sizeof(struct htm_target_id), GFP_KERNEL);
+	if (!event->pmu_private)
+		return -ENOMEM;
+
+	((struct htm_target_id *)event->pmu_private)->cfg = cfg;
+	event->destroy = reset_htm_active;
+	return 0;
+}
+
+static void htm_event_start(struct perf_event *event, int flags)
+{
+	int rc, ret, retries = 0;
+	struct htm_config cfg;
+	struct htm_target_id *target = event->pmu_private;
+
+	/*
+	 * Ignore context-switch re-enables. The perf core passes
+	 * PERF_EF_RELOAD on context-switch-in. HTM tracing is
+	 * continuous at hardware level, no hcall needed.
+	 */
+	if (flags & PERF_EF_RELOAD)
+		return;
+
+	/* Already tracing, don't issue a second start hcall */
+	if (target->tracing_active == HTM_TRACING_ACTIVE)
+		return;
+
+	cfg = target->cfg;
+
+	/* Only retry on transient H_BUSY; H_LONG_BUSY_* (-EAGAIN) exits immediately */
+	do {
+		rc = htm_hcall_wrapper(htmflags, cfg.nodeindex, cfg.nodalchipindex,
+				       cfg.coreindexonchip, cfg.htmtype,
+				       H_HTM_OP_START, 0, 0, 0);
+		ret = htm_return_check(rc);
+	} while (ret == -EBUSY && ++retries < MAX_RETRIES);
+
+	if (ret > 0) {
+		target->tracing_active = HTM_TRACING_ACTIVE;
+		event->hw.state &= ~PERF_HES_STOPPED;
+	}
+}
+
+static void htm_event_stop(struct perf_event *event, int flags)
+{
+	int rc, ret, retries = 0;
+	struct htm_config cfg;
+	struct htm_target_id *target = event->pmu_private;
+
+	/*
+	 * Ignore context-switch-out stops. The perf core passes
+	 * PERF_EF_UPDATE on context-switch-out. Do not stop the hcall.
+	 */
+	if (flags & PERF_EF_UPDATE)
+		return;
+
+	/* Not tracing, nothing to stop */
+	if (target->tracing_active == HTM_TRACING_INACTIVE)
+		return;
+
+	cfg = target->cfg;
+
+	/* Only retry on transient H_BUSY; H_LONG_BUSY_* (-EAGAIN) exits immediately */
+	do {
+		rc = htm_hcall_wrapper(htmflags, cfg.nodeindex, cfg.nodalchipindex,
+				       cfg.coreindexonchip, cfg.htmtype,
+				       H_HTM_OP_STOP, 0, 0, 0);
+		ret = htm_return_check(rc);
+	} while (ret == -EBUSY && ++retries < MAX_RETRIES);
+
+	/*
+	 * Only mark stopped if the hcall succeeded.  If the stop failed
+	 * (e.g. -EAGAIN on long-busy), leave tracing_active as ACTIVE so
+	 * that htm_event_del will retry the stop hcall rather than
+	 * skipping it and leaving the hypervisor permanently configured.
+	 */
+	if (ret > 0) {
+		target->tracing_active = HTM_TRACING_INACTIVE;
+		event->hw.state |= PERF_HES_STOPPED;
+	}
+}
+
+static int htm_event_add(struct perf_event *event, int flags)
+{
+	int rc, ret, retries = 0;
+	unsigned long param1 = -1, param2 = -1;
+	struct htm_target_id *target = event->pmu_private;
+	struct htm_config cfg = target->cfg;
+
+	/*
+	 * pmu->add() is invoked in an atomic context with interrupts disabled
+	 * and hardware context locks held. sleeping is impossible.  Only retry
+	 * on transient H_BUSY. On H_LONG_BUSY_* (-EAGAIN) and other errors, the
+	 * loop exits and we return -ENODEV, which is a hard failure: the perf
+	 * core will not reschedule the event. Returning -EAGAIN here would cause
+	 * the perf core to re-queue the event and call pmu->add() again on every
+	 * context switch, flooding the hypervisor with H_HTM_OP_CONFIGURE hcalls
+	 * exactly when it has requested a long backoff delay.
+	 */
+	do {
+		rc = htm_hcall_wrapper(htmflags, cfg.nodeindex, cfg.nodalchipindex,
+				       cfg.coreindexonchip, cfg.htmtype,
+				       H_HTM_OP_CONFIGURE, param1, param2, 0);
+		ret = htm_return_check(rc);
+	} while (ret == -EBUSY && ++retries < MAX_RETRIES);
+
+	if (ret <= 0)
+		return -ENODEV;
+
+	/*
+	 * htm_event_init() allocated event->pmu_private (struct htm_target_id)
+	 * and set event->destroy = reset_htm_active to free it on teardown.
+	 * Initialise the tracing state and hw.state before calling start.
+	 */
+	target->tracing_active = HTM_TRACING_INACTIVE;
+	event->hw.state = PERF_HES_STOPPED;
+
+	/*
+	 * Start tracing via the .start callback so the standard
+	 * PERF_EF_START / ioctl(ENABLE) path is honoured.
+	 */
+	if (flags & PERF_EF_START) {
+		htm_event_start(event, 0);	/* flags=0: not a context switch */
+		if (target->tracing_active == HTM_TRACING_INACTIVE) {
+			/*
+			 * Start failed.  Attempt to deconfigure to avoid leaving
+			 * the hypervisor resource permanently reserved.
+			 * pmu->add() is atomic, only H_BUSY is retried.  If
+			 * H_LONG_BUSY_* or other eerros is returned here, the
+			 * resource cannot be reclaimed in this context; log the
+			 * failure so it is visible in the kernel log.
+			 */
+			retries = 0;
+			do {
+				rc = htm_hcall_wrapper(htmflags, cfg.nodeindex,
+						       cfg.nodalchipindex, cfg.coreindexonchip,
+						       cfg.htmtype, H_HTM_OP_DECONFIGURE, 0, 0, 0);
+				ret = htm_return_check(rc);
+			} while (ret == -EBUSY && ++retries < MAX_RETRIES);
+			if (ret <= 0) {
+				pr_err("DECONFIGURE failed in htm event add (ret=%d) node:%u chip:%u core:%u type:%u;\n",
+						ret, cfg.nodeindex, cfg.nodalchipindex, cfg.coreindexonchip, cfg.htmtype);
+			}
+			return -EIO;
+		}
+	}
+
+	return 0;
+}
+
+static void htm_event_del(struct perf_event *event, int flags)
+{
+	int rc, ret, retries = 0;
+	struct htm_target_id *target = event->pmu_private;
+	struct htm_config cfg = target->cfg;
+
+	/*
+	 * pmu->del() is called by the perf core after pmu->stop(), whether
+	 * triggered by ioctl(PERF_EVENT_IOC_DISABLE) or event destruction.
+	 * pmu->del() is invoked in an atomic context with IRQs disabled,
+	 * sleeping is impossible.
+	 *
+	 * If a prior htm_event_stop() call returned with tracing_active still
+	 * set to HTM_TRACING_ACTIVE (because H_LONG_BUSY_* caused an immediate
+	 * exit), calling htm_event_stop() again here with flags=0 retries the
+	 * H_HTM_OP_STOP hcall.  This del path is the guaranteed retry point:
+	 * the perf core will always reach del after stop, so the trace is not
+	 * permanently left running in the hypervisor.  Only H_BUSY is retried
+	 * here; H_LONG_BUSY_* or any erroes on stop is treated as a best-effort,
+	 * ie the deconfigure that follows will still be attempted and error logged.
+	 */
+	htm_event_stop(event, 0);
+
+	/*
+	 * Deconfigure the hardware resource.  Only H_BUSY is retried.
+	 * If H_LONG_BUSY_* or any other error is returned, the resource
+	 * cannot be reclaimed in this atomic context; log the failure so it
+	 * is visible in the kernel log.
+	 */
+	do {
+		rc = htm_hcall_wrapper(htmflags, cfg.nodeindex, cfg.nodalchipindex,
+				       cfg.coreindexonchip, cfg.htmtype,
+				       H_HTM_OP_DECONFIGURE, 0, 0, 0);
+		ret = htm_return_check(rc);
+	} while (ret == -EBUSY && ++retries < MAX_RETRIES);
+	if (ret <= 0) {
+		pr_err("DECONFIGURE failed in htm event del (ret=%d) node:%u chip:%u core:%u type:%u;\n",
+				ret, cfg.nodeindex, cfg.nodalchipindex, cfg.coreindexonchip, cfg.htmtype);
+	}
+	/* pmu_private freed by event->destroy = reset_htm_active */
+}
+
+static void htm_event_read(struct perf_event *event)
+{
+}
+
+static struct pmu htm_pmu = {
+	.task_ctx_nr  = perf_invalid_context,
+	.name         = "htm",
+	.attr_groups  = attr_groups,
+	.event_init   = htm_event_init,
+	.add          = htm_event_add,
+	.del          = htm_event_del,
+	.read         = htm_event_read,
+	.start        = htm_event_start,
+	.stop         = htm_event_stop,
+	.capabilities = PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_EXCLUSIVE,
+};
+
+static int htm_init(void)
+{
+	int r;
+
+	if (!firmware_has_feature(FW_FEATURE_LPAR)) {
+		pr_debug("Only supported on LPAR platforms running under a Hypervisor\n");
+		return -ENODEV;
+	}
+
+	if (is_kvm_guest()) {
+		pr_debug("Only supported for L1 host system\n");
+		return -ENODEV;
+	}
+
+	r = perf_pmu_register(&htm_pmu, htm_pmu.name, -1);
+	if (r)
+		return r;
+
+	return 0;
+}
+
+device_initcall(htm_init);
-- 
2.43.0



  reply	other threads:[~2026-07-25  7:00 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-25  6:59 [PATCH V3 0/6] powerpc/perf: Add HTM PMU driver and perf AUX support Athira Rajeev
2026-07-25  6:59 ` Athira Rajeev [this message]
2026-07-25  7:45   ` [PATCH V3 1/6] powerpc/perf: Add HTM PMU driver to expose Hardware Trace Macro data sashiko-bot
2026-07-25  6:59 ` [PATCH V3 2/6] powerpc/perf: Reject duplicate HTM target reservations Athira Rajeev
2026-07-25  6:59 ` [PATCH V3 3/6] powerpc/perf: Add AUX buffer management to capture HTM trace data Athira Rajeev
2026-07-25  7:45   ` sashiko-bot
2026-07-25  6:59 ` [PATCH V3 4/6] powerpc/perf: Capture the HTM memory configuration as part of perf data Athira Rajeev
2026-07-25  7:43   ` sashiko-bot
2026-07-25  6:59 ` [PATCH V3 5/6] docs: ABI: sysfs-bus-event_source-devices-htm: Document sysfs event format entries for htm pmu Athira Rajeev
2026-07-25  6:59 ` [PATCH V3 6/6] powerpc/perf/htm: Add documentation for Hardware Trace Macro PMU Athira Rajeev

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=20260725065942.78839-2-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 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.