Linux Test Project
 help / color / mirror / Atom feed
* [LTP] [PATCH 0/3] pmc_core: cover the PkgC LTR blocker counters
@ 2026-09-04 12:40 Piotr Kubaj
  2026-09-04 12:40 ` [LTP] [PATCH 1/3] lib: add tst_test.needs_debugfs flag Piotr Kubaj
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Piotr Kubaj @ 2026-09-04 12:40 UTC (permalink / raw)
  To: ltp; +Cc: helena.anna.dubel, tomasz.ossowski, rafael.j.wysocki,
	daniel.niestepski

The intel_pmc_core driver gained a pkgc_ltr_blocker_show debugfs file in
kernel commit 38c79dd63b72 ("platform/x86/intel/pmc: Enable PkgC LTR
blocking counter"), first released in v7.2, and nothing covers it yet.
It reports, per source, how many times an LTR posted by that source
blocked a package C-state entry.

Both tests added here need debugfs mounted, so the first patch moves the
mount handling into the test library instead of open coding it twice.

1/3 adds tst_test.needs_debugfs: the library mounts debugfs at
    /sys/kernel/debug during setup unless it is mounted there already,
    reports TCONF if it cannot, and unmounts it afterwards only if it did
    the mount. A lib/newlib_tests self-test covers both cases. Tests
    reading any other debugfs file can use it as well.

2/3 checks what the file says: every line is a PKGC_PREVENT_LTR_<SOURCE>
    token followed by one u32 value, the file reads to EOF rather than
    erroring out mid-way, the counter set is stable across two reads, and
    no counter advances by more entries than the package could have
    attempted over the interval.

3/3 checks the invariant behind the counters: a package C-state entry is
    only attempted once every CPU in the package is idle, so counters
    that keep advancing with every CPU busy are not counting blocked
    entries. The test proves the counters are alive while idling first,
    so that a counter stuck at a constant value cannot pass for free.

Both tests bound what they accept in time rather than against a hardcoded
counter list, because the counter set is platform specific. That is what
catches a telemetry region read at the wrong offset, which overshoots the
bounds by orders of magnitude.

Tested on Nova Lake running 7.3.0-rc1, with debugfs both mounted and
unmounted beforehand, and in the latter case the mount state is restored
after the run. The TFAIL and TCONF paths were exercised against fake
counter files.

Piotr Kubaj (3):
  lib: add tst_test.needs_debugfs flag
  pmc_core: add test for pkgc_ltr_blocker_show
  pmc_core: add ltr_counter test

 doc/developers/writing_tests.rst              |   3 +
 include/tst_fs.h                              |   4 +
 include/tst_test.h                            |   8 +
 lib/newlib_tests/.gitignore                   |   1 +
 lib/newlib_tests/runtest.sh                   |   1 +
 lib/newlib_tests/tst_needs_debugfs.c          |  37 ++
 lib/tst_test.c                                |  35 ++
 metadata/metaparse.c                          |   1 +
 runtest/power_management_tests                |   2 +
 testcases/kernel/power_management/.gitignore  |   2 +
 .../kernel/power_management/ltr_counter.c     | 355 ++++++++++++++++++
 .../power_management/pkgc_ltr_blocker_show.c  | 294 +++++++++++++++
 12 files changed, 743 insertions(+)
 create mode 100644 lib/newlib_tests/tst_needs_debugfs.c
 create mode 100644 testcases/kernel/power_management/ltr_counter.c
 create mode 100644 testcases/kernel/power_management/pkgc_ltr_blocker_show.c


base-commit: 82568ba8fad0120a9305f7a263ddb6d9d74c4f61
-- 
2.47.3

---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
ul. Slowackiego 173 | 80-298 Gdansk | Sad Rejonowy Gdansk Polnoc | VII Wydzial Gospodarczy Krajowego Rejestru Sadowego - KRS 101882 | NIP 957-07-52-316 | Kapital zakladowy 200.000 PLN.
Spolka oswiadcza, ze posiada status duzego przedsiebiorcy w rozumieniu ustawy z dnia 8 marca 2013 r. o przeciwdzialaniu nadmiernym opoznieniom w transakcjach handlowych.

Ta wiadomosc wraz z zalacznikami jest przeznaczona dla okreslonego adresata i moze zawierac informacje poufne. W razie przypadkowego otrzymania tej wiadomosci, prosimy o powiadomienie nadawcy oraz trwale jej usuniecie; jakiekolwiek przegladanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by others is strictly prohibited.


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* [LTP] [PATCH 1/3] lib: add tst_test.needs_debugfs flag
  2026-09-04 12:40 [LTP] [PATCH 0/3] pmc_core: cover the PkgC LTR blocker counters Piotr Kubaj
@ 2026-09-04 12:40 ` Piotr Kubaj
  2026-09-04 12:40 ` [LTP] [PATCH 2/3] pmc_core: add test for pkgc_ltr_blocker_show Piotr Kubaj
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Piotr Kubaj @ 2026-09-04 12:40 UTC (permalink / raw)
  To: ltp; +Cc: helena.anna.dubel, tomasz.ossowski, rafael.j.wysocki,
	daniel.niestepski

Tests that read debugfs files have to check that debugfs is mounted at
/sys/kernel/debug and mount it when it is not. The mount point exists as
a plain sysfs directory whenever CONFIG_DEBUG_FS is enabled, whether or
not debugfs is mounted on it, so a test that only checks that the path is
there reports the platform as unsupported when debugfs simply is not
mounted, and each test ends up carrying the same statfs() and mount()
dance.

Move it into the library: with tst_test.needs_debugfs set the library
mounts debugfs during setup, exits with TCONF if it cannot, and unmounts
it at the end of the test if it was the one that mounted it. Add
TST_DEBUGFS_PATH so that tests build their paths from the library
constant, register the flag in the metadata parser, and add a
lib/newlib_tests self-test that covers both the mounted and the unmounted
case.

Signed-off-by: Piotr Kubaj <piotr.kubaj@intel.com>
---
 doc/developers/writing_tests.rst     |  3 +++
 include/tst_fs.h                     |  4 +++
 include/tst_test.h                   |  8 ++++++
 lib/newlib_tests/.gitignore          |  1 +
 lib/newlib_tests/runtest.sh          |  1 +
 lib/newlib_tests/tst_needs_debugfs.c | 37 ++++++++++++++++++++++++++++
 lib/tst_test.c                       | 35 ++++++++++++++++++++++++++
 metadata/metaparse.c                 |  1 +
 8 files changed, 90 insertions(+)
 create mode 100644 lib/newlib_tests/tst_needs_debugfs.c

diff --git a/doc/developers/writing_tests.rst b/doc/developers/writing_tests.rst
index 992374f8b..20b5b5088 100644
--- a/doc/developers/writing_tests.rst
+++ b/doc/developers/writing_tests.rst
@@ -429,6 +429,9 @@ LTP C And Shell Test API Comparison
     * - .needs_cmds
       - TST_NEEDS_CMDS
 
+    * - .needs_debugfs
+      - \-
+
     * - .needs_devfs
       - \-
 
diff --git a/include/tst_fs.h b/include/tst_fs.h
index ceae78e7e..d7353dbb2 100644
--- a/include/tst_fs.h
+++ b/include/tst_fs.h
@@ -8,6 +8,7 @@
 
 /* man 2 statfs or kernel-source/include/uapi/linux/magic.h */
 #define TST_BTRFS_MAGIC    0x9123683E
+#define TST_DEBUGFS_MAGIC  0x64626720
 #define TST_NFS_MAGIC      0x6969
 #define TST_RAMFS_MAGIC    0x858458f6
 #define TST_TMPFS_MAGIC    0x01021994
@@ -57,6 +58,9 @@ enum {
 #define OVL_WORK	OVL_BASE_MNTPOINT"/work"
 #define OVL_MNT		OVL_BASE_MNTPOINT"/ovl"
 
+/* Where debugfs is mounted by the tst_test.needs_debugfs flag */
+#define TST_DEBUGFS_PATH "/sys/kernel/debug"
+
 /*
  * @path: path is the pathname of any file within the mounted file system
  * @mult: mult should be TST_KB, TST_MB or TST_GB
diff --git a/include/tst_test.h b/include/tst_test.h
index ddfe9d4d6..905fe0d0f 100644
--- a/include/tst_test.h
+++ b/include/tst_test.h
@@ -352,6 +352,13 @@ struct tst_fs {
  *               needed for tests that need to create device files since tmpfs
  *               at /tmp is usually mounted with 'nodev' option.
  *
+ * @needs_debugfs: If set debugfs is mounted at TST_DEBUGFS_PATH i.e.
+ *                 /sys/kernel/debug, unless it is mounted there already, and
+ *                 the test exits with TCONF if it cannot be. The library
+ *                 unmounts it at the end of the test if it mounted it. Note
+ *                 that both mounting debugfs and reading its content require
+ *                 root, so tests using this also set tst_test.needs_root.
+ *
  * @restore_wallclock: Saves wall clock at the start of the test and restores
  *                     it at the end with the help of monotonic timers.
  *                     Testcases that modify system wallclock use this to
@@ -561,6 +568,7 @@ struct tst_fs {
 	unsigned int child_needs_reinit:1;
 	unsigned int runs_script:1;
 	unsigned int needs_devfs:1;
+	unsigned int needs_debugfs:1;
 	unsigned int restore_wallclock:1;
 
 	unsigned int all_filesystems:1;
diff --git a/lib/newlib_tests/.gitignore b/lib/newlib_tests/.gitignore
index 1586e0ad6..794e61453 100644
--- a/lib/newlib_tests/.gitignore
+++ b/lib/newlib_tests/.gitignore
@@ -60,6 +60,7 @@ tst_needs_cmds05
 tst_needs_cmds06
 tst_needs_cmds07
 tst_needs_cmds08
+tst_needs_debugfs
 test_runtime01
 test_runtime02
 test_children_cleanup
diff --git a/lib/newlib_tests/runtest.sh b/lib/newlib_tests/runtest.sh
index 71808ef8b..1a51d8b7a 100755
--- a/lib/newlib_tests/runtest.sh
+++ b/lib/newlib_tests/runtest.sh
@@ -27,6 +27,7 @@ tst_expiration_timer
 tst_filesystems01
 tst_fuzzy_sync0[1-3]
 tst_needs_cmds0[1-36-8]
+tst_needs_debugfs
 tst_res_hexd
 tst_safe_sscanf
 tst_strstatus}"
diff --git a/lib/newlib_tests/tst_needs_debugfs.c b/lib/newlib_tests/tst_needs_debugfs.c
new file mode 100644
index 000000000..fd6adf7a5
--- /dev/null
+++ b/lib/newlib_tests/tst_needs_debugfs.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2026 Piotr Kubaj <piotr.kubaj@intel.com>
+ */
+
+/*
+ * Test that tst_test.needs_debugfs gets debugfs mounted for the test.
+ *
+ * Run it both with debugfs mounted and with it unmounted, it has to pass either
+ * way. In the latter case the library reports mounting debugfs and has to leave
+ * it unmounted once the test is over.
+ */
+
+#include <sys/vfs.h>
+#include "tst_test.h"
+
+static void run(void)
+{
+	struct statfs sfs;
+
+	SAFE_STATFS(TST_DEBUGFS_PATH, &sfs);
+
+	if (sfs.f_type == TST_DEBUGFS_MAGIC)
+		tst_res(TPASS, "debugfs is mounted at %s", TST_DEBUGFS_PATH);
+	else
+		tst_res(TFAIL, "debugfs is not mounted at %s", TST_DEBUGFS_PATH);
+}
+
+static struct tst_test test = {
+	.needs_root = 1,
+	.needs_debugfs = 1,
+	.needs_kconfigs = (const char *const []) {
+		"CONFIG_DEBUG_FS",
+		NULL
+	},
+	.test_all = run,
+};
diff --git a/lib/tst_test.c b/lib/tst_test.c
index 239494b6f..58c9c7843 100644
--- a/lib/tst_test.c
+++ b/lib/tst_test.c
@@ -15,6 +15,7 @@
 #include <errno.h>
 #include <sys/mount.h>
 #include <sys/types.h>
+#include <sys/vfs.h>
 #include <sys/utsname.h>
 #include <sys/wait.h>
 #include <math.h>
@@ -83,6 +84,7 @@ struct context {
 	tst_atomic_t abort_flag;
 	uint32_t mntpoint_mounted:1;
 	uint32_t ovl_mounted:1;
+	uint32_t debugfs_mounted:1;
 	uint32_t tdebug:1;
 };
 
@@ -1209,6 +1211,31 @@ static void prepare_and_mount_dev_fs(const char *mntpoint)
 	}
 }
 
+static void mount_debugfs(void)
+{
+	struct statfs sfs;
+
+	/*
+	 * TST_DEBUGFS_PATH exists as a plain sysfs directory whenever
+	 * CONFIG_DEBUG_FS is enabled, whether or not debugfs is mounted on it,
+	 * so the filesystem type has to be checked rather than the directory
+	 * being present.
+	 */
+	if (statfs(TST_DEBUGFS_PATH, &sfs))
+		tst_brk(TCONF | TERRNO, "Can't statfs %s", TST_DEBUGFS_PATH);
+
+	if (sfs.f_type == TST_DEBUGFS_MAGIC)
+		return;
+
+	if (mount("debugfs", TST_DEBUGFS_PATH, "debugfs", 0, NULL)) {
+		tst_brk(TCONF | TERRNO, "Can't mount debugfs at %s",
+			TST_DEBUGFS_PATH);
+	}
+
+	tst_res(TINFO, "Mounted debugfs at %s", TST_DEBUGFS_PATH);
+	context->debugfs_mounted = 1;
+}
+
 static void prepare_and_mount_hugetlb_fs(void)
 {
 	if (access(PATH_HUGEPAGES, F_OK))
@@ -1545,6 +1572,9 @@ static void do_setup(int argc, char *argv[])
 			"Two or more of needs_{rofs, devfs, device, hugetlbfs} are set");
 	}
 
+	if (tst_test->needs_debugfs)
+		mount_debugfs();
+
 	if (tst_test->needs_devfs)
 		prepare_and_mount_dev_fs(tst_test->mntpoint);
 
@@ -1656,6 +1686,11 @@ static void do_cleanup(void)
 	if (context->mntpoint_mounted)
 		tst_umount(tst_test->mntpoint);
 
+	if (context->debugfs_mounted) {
+		tst_umount(TST_DEBUGFS_PATH);
+		context->debugfs_mounted = 0;
+	}
+
 	if (tst_test->needs_device && tdev.dev)
 		tst_release_device(tdev.dev);
 
diff --git a/metadata/metaparse.c b/metadata/metaparse.c
index c495d2eb5..37251ae6a 100644
--- a/metadata/metaparse.c
+++ b/metadata/metaparse.c
@@ -994,6 +994,7 @@ static struct typemap tst_test_typemap[] = {
 	{.id = "child_needs_reinit", .type = DATA_BOOL},
 	{.id = "runs_script", .type = DATA_BOOL},
 	{.id = "needs_devfs", .type = DATA_BOOL},
+	{.id = "needs_debugfs", .type = DATA_BOOL},
 	{.id = "restore_wallclock", .type = DATA_BOOL},
 	{.id = "all_filesystems", .type = DATA_BOOL},
 	{.id = "skip_in_lockdown", .type = DATA_BOOL},
-- 
2.47.3

---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
ul. Slowackiego 173 | 80-298 Gdansk | Sad Rejonowy Gdansk Polnoc | VII Wydzial Gospodarczy Krajowego Rejestru Sadowego - KRS 101882 | NIP 957-07-52-316 | Kapital zakladowy 200.000 PLN.
Spolka oswiadcza, ze posiada status duzego przedsiebiorcy w rozumieniu ustawy z dnia 8 marca 2013 r. o przeciwdzialaniu nadmiernym opoznieniom w transakcjach handlowych.

Ta wiadomosc wraz z zalacznikami jest przeznaczona dla okreslonego adresata i moze zawierac informacje poufne. W razie przypadkowego otrzymania tej wiadomosci, prosimy o powiadomienie nadawcy oraz trwale jej usuniecie; jakiekolwiek przegladanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by others is strictly prohibited.


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* [LTP] [PATCH 2/3] pmc_core: add test for pkgc_ltr_blocker_show
  2026-09-04 12:40 [LTP] [PATCH 0/3] pmc_core: cover the PkgC LTR blocker counters Piotr Kubaj
  2026-09-04 12:40 ` [LTP] [PATCH 1/3] lib: add tst_test.needs_debugfs flag Piotr Kubaj
@ 2026-09-04 12:40 ` Piotr Kubaj
  2026-09-04 12:40 ` [LTP] [PATCH 3/3] pmc_core: add ltr_counter test Piotr Kubaj
  2026-09-07  6:28 ` [LTP] [PATCH 0/3] pmc_core: cover the PkgC LTR blocker counters Andrea Cervesato via ltp
  3 siblings, 0 replies; 6+ messages in thread
From: Piotr Kubaj @ 2026-09-04 12:40 UTC (permalink / raw)
  To: ltp; +Cc: helena.anna.dubel, tomasz.ossowski, rafael.j.wysocki,
	daniel.niestepski

Add coverage for the pkgc_ltr_blocker_show debugfs file added in kernel
commit 38c79dd63b72 ("platform/x86/intel/pmc: Enable PkgC LTR blocking
counter") and first released in v7.2. The counters report how many times
an LTR posted by each source blocked a package C-state entry, and so far
nothing checked that the driver exports them correctly.

The counter set is platform specific, so instead of a hardcoded list of
names the test samples the file twice and checks that it can be read in
full, that every line is a PKGC_PREVENT_LTR_<SOURCE> token followed by
exactly one value that fits in u32, that the counter set does not change
between the reads, and that no counter advances by more entries than the
package could have attempted over the interval.

The last check is the one that catches a telemetry region read at the
wrong offset. The values wrap, so the advance is evaluated modulo 2^32
and bounded by the time the counter had to advance over, widened by how
stale the first sample can be, because the PMC refreshes the telemetry
region behind the counters asynchronously. An arbitrary u32 read out of
the wrong offset overshoots that bound by orders of magnitude.

Tested on Nova Lake running 7.3.0-rc1.

Signed-off-by: Piotr Kubaj <piotr.kubaj@intel.com>
---
 runtest/power_management_tests                |   1 +
 testcases/kernel/power_management/.gitignore  |   1 +
 .../power_management/pkgc_ltr_blocker_show.c  | 294 ++++++++++++++++++
 3 files changed, 296 insertions(+)
 create mode 100644 testcases/kernel/power_management/pkgc_ltr_blocker_show.c

diff --git a/runtest/power_management_tests b/runtest/power_management_tests
index 884e615cd..93b5a5c10 100644
--- a/runtest/power_management_tests
+++ b/runtest/power_management_tests
@@ -1,4 +1,5 @@
 #POWER_MANAGEMENT
+pkgc_ltr_blocker_show pkgc_ltr_blocker_show
 runpwtests01 runpwtests01.sh
 runpwtests02 runpwtests02.sh
 runpwtests03 runpwtests03.sh
diff --git a/testcases/kernel/power_management/.gitignore b/testcases/kernel/power_management/.gitignore
index 0c2a3ed4b..0d7db221b 100644
--- a/testcases/kernel/power_management/.gitignore
+++ b/testcases/kernel/power_management/.gitignore
@@ -1 +1,2 @@
 pm_get_sched_values
+pkgc_ltr_blocker_show
diff --git a/testcases/kernel/power_management/pkgc_ltr_blocker_show.c b/testcases/kernel/power_management/pkgc_ltr_blocker_show.c
new file mode 100644
index 000000000..ef6b2110c
--- /dev/null
+++ b/testcases/kernel/power_management/pkgc_ltr_blocker_show.c
@@ -0,0 +1,294 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/*
+ * Copyright (C) 2026 Piotr Kubaj <piotr.kubaj@intel.com>
+ */
+
+/*\
+ * Verify that pkgc_ltr_blocker_show reports well-formed package C-state LTR
+ * blocker counters that advance at a plausible rate.
+ *
+ * The intel_pmc_core driver prints one line per counter as "%-30s %-30u",
+ * where the name is a PKGC_PREVENT_LTR_<SOURCE> token and the value counts how
+ * many times an LTR posted by <SOURCE> blocked a package C-state entry.
+ *
+ * The counter set is platform specific, so instead of checking a hardcoded
+ * list the test samples the file twice and verifies that
+ *
+ * - the file can be read in full, so that a failing telemetry read in the
+ *   driver is not mistaken for a short counter list,
+ * - every line is a PKGC_PREVENT_LTR_<SOURCE> token followed by exactly one
+ *   unsigned value that fits in u32,
+ * - the set of counters does not change between the two reads,
+ * - no counter advances by more entries than the package could have attempted
+ *   over the interval.
+ *
+ * The last check is the one that catches a telemetry region read at the wrong
+ * offset. The values are u32 and wrap, so the advance has to be evaluated
+ * modulo 2^32, and a wrap is then indistinguishable from a bogus read unless
+ * the delta is bounded by the time the counter had to advance over. An
+ * arbitrary u32 read out of the wrong offset averages 2^31, orders of
+ * magnitude past what the bound allows.
+ *
+ * The debugfs file is only created for a PMC that exposes a package C-state
+ * telemetry endpoint (pc_guid in the driver's pmc_dev_info), so on platforms
+ * without one the test is not applicable.
+ *
+ * The test needs root because /sys/kernel/debug is mode 0700 and owned by
+ * root, so the counter file cannot be opened otherwise, and because the test
+ * library mounts debugfs if it is not mounted already.
+ */
+
+#include <time.h>
+#include "tst_clocks.h"
+#include "tst_safe_stdio.h"
+#include "tst_test.h"
+#include "tst_timer.h"
+
+#define PATH TST_DEBUGFS_PATH "/pmc_core/pkgc_ltr_blocker_show"
+#define PREFIX "PKGC_PREVENT_LTR_"
+
+/* Nova Lake reports 5 counters, leave room for future platforms */
+#define MAX_COUNTERS 64
+#define NAME_LEN 64
+
+/*
+ * Cap, in seconds, on how long to poll for a second sample that differs from
+ * the first one. On an idle Nova Lake the counters advance in bursts a few
+ * seconds apart, because a blocked entry needs the package to attempt a C-state
+ * entry in the first place, so a window of a few seconds is what it takes for
+ * the delta check to have anything to look at. TST_RETRY_FN_EXP_BACKOFF() ends
+ * up sleeping about twice the cap in total, hence the modest value here.
+ */
+#define MAX_SAMPLE_DELAY 4
+
+/*
+ * Allowance for how stale the first sample can be. The PMC refreshes the
+ * telemetry region behind these counters asynchronously, so the first read can
+ * land just before a refresh and return a snapshot that is almost a whole
+ * refresh period old. The retry then observes a period worth of blocked entries
+ * after only microseconds of measured time, which the measured interval on its
+ * own does not account for.
+ *
+ * The allowance is the same window the test is willing to poll a refresh out
+ * of, which on Nova Lake is several times the observed refresh period.
+ */
+#define REFRESH_AGE_US (MAX_SAMPLE_DELAY * 1000000ULL)
+
+/*
+ * Blocked entries per microsecond the bound allows. Each count stands for one
+ * package C-state entry that was blocked, and entries can only be attempted as
+ * fast as the package can cycle between idle and running, which takes
+ * microseconds. Ten per microsecond is therefore already past what the hardware
+ * can produce - the counters were observed advancing by about 6 per second on
+ * an idle Nova Lake - and the headroom costs the check nothing, because the
+ * bogus read it exists to catch overshoots it by orders of magnitude anyway.
+ */
+#define MAX_BLOCKS_PER_US 10
+
+struct snapshot {
+	char names[MAX_COUNTERS][NAME_LEN];
+	uint32_t values[MAX_COUNTERS];
+	int cnt;
+};
+
+static struct snapshot first, second;
+
+/*
+ * Largest advance a counter can plausibly show over two samples taken
+ * @elapsed_us microseconds apart.
+ *
+ * The interval the counter had to advance over is the measured one widened by
+ * REFRESH_AGE_US, because the sampled values come from a telemetry snapshot
+ * that is already up to a refresh period old, not from the instants the file
+ * was read.
+ */
+static unsigned long long max_plausible_delta(unsigned long long elapsed_us)
+{
+	return (elapsed_us + REFRESH_AGE_US) * MAX_BLOCKS_PER_US;
+}
+
+static void read_snapshot(struct snapshot *snap)
+{
+	char line[256];
+	FILE *fp;
+
+	snap->cnt = 0;
+	fp = SAFE_FOPEN(PATH, "r");
+
+	while (fgets(line, sizeof(line), fp)) {
+		char name[NAME_LEN], value[NAME_LEN], extra;
+		unsigned long long parsed;
+
+		line[strcspn(line, "\n")] = '\0';
+
+		/*
+		 * The value is scanned as a string rather than with %u so that
+		 * a signed or out of range value is rejected instead of being
+		 * quietly converted. The trailing %c rejects a third token; the
+		 * space in front of it skips the padding the driver emits.
+		 */
+		if (sscanf(line, "%63s %63s %c", name, value, &extra) != 2) {
+			tst_res(TFAIL, "malformed counter line: '%s'", line);
+			continue;
+		}
+
+		if (strncmp(name, PREFIX, sizeof(PREFIX) - 1) ||
+		    !name[sizeof(PREFIX) - 1]) {
+			tst_res(TFAIL, "counter '%s' is not a " PREFIX "<SOURCE> token",
+				name);
+			continue;
+		}
+
+		if (value[strspn(value, "0123456789")]) {
+			tst_res(TFAIL, "counter '%s' has a non-numeric value '%s'",
+				name, value);
+			continue;
+		}
+
+		parsed = strtoull(value, NULL, 10);
+
+		if (parsed > UINT32_MAX) {
+			tst_res(TFAIL, "counter '%s' value '%s' does not fit in u32",
+				name, value);
+			continue;
+		}
+
+		if (snap->cnt == MAX_COUNTERS)
+			tst_brk(TBROK, "more than %d counters reported", MAX_COUNTERS);
+
+		strcpy(snap->names[snap->cnt], name);
+		snap->values[snap->cnt] = parsed;
+		snap->cnt++;
+	}
+
+	/*
+	 * A telemetry read that fails in the driver aborts the seq_file read
+	 * instead of ending it at EOF, so without this the counters lost to the
+	 * error would look like a platform reporting fewer of them.
+	 */
+	if (ferror(fp))
+		tst_brk(TFAIL, "reading " PATH " failed after %d counters", snap->cnt);
+
+	SAFE_FCLOSE(fp);
+}
+
+static void setup(void)
+{
+	if (access(PATH, R_OK))
+		tst_brk(TCONF | TERRNO, "%s not available", PATH);
+}
+
+/*
+ * Take the second sample, reporting whether it differs from the first one.
+ *
+ * A blocked entry is a sporadic event and the counters are backed by a PMT
+ * telemetry region that the PMC refreshes asynchronously, so the second sample
+ * is retried until it observes a change instead of being taken after a fixed
+ * delay. A differing counter count also counts as a difference, so that the
+ * mismatch is reported rather than polled over.
+ */
+static int second_sample_differs(void)
+{
+	read_snapshot(&second);
+
+	if (first.cnt != second.cnt)
+		return 1;
+
+	for (int i = 0; i < first.cnt; i++) {
+		if (first.values[i] != second.values[i])
+			return 1;
+	}
+
+	return 0;
+}
+
+static void run(void)
+{
+	struct timespec start, end;
+	unsigned long long elapsed_us, max_delta;
+	int differs, fails = 0;
+
+	tst_clock_gettime(CLOCK_MONOTONIC, &start);
+	read_snapshot(&first);
+
+	if (!first.cnt)
+		tst_brk(TFAIL, "no LTR blocker counters reported");
+
+	differs = TST_RETRY_FN_EXP_BACKOFF(second_sample_differs(),
+					   TST_RETVAL_NOTNULL, MAX_SAMPLE_DELAY);
+
+	tst_clock_gettime(CLOCK_MONOTONIC, &end);
+
+	elapsed_us = tst_timespec_diff_us(end, start);
+	max_delta = max_plausible_delta(elapsed_us);
+
+	if (!differs) {
+		tst_res(TINFO, "no counter changed over %lluus, no entry was blocked",
+			elapsed_us);
+	}
+
+	if (first.cnt != second.cnt) {
+		tst_brk(TFAIL, "counter count changed between reads: %d -> %d",
+			first.cnt, second.cnt);
+	}
+
+	for (int i = 0; i < first.cnt; i++) {
+		uint32_t delta;
+
+		if (strcmp(first.names[i], second.names[i])) {
+			tst_res(TFAIL, "counter %d renamed between reads: %s -> %s",
+				i, first.names[i], second.names[i]);
+			fails++;
+			continue;
+		}
+
+		tst_res(TDEBUG, "%s: %u -> %u", first.names[i],
+			first.values[i], second.values[i]);
+
+		/*
+		 * The values are u32 and wrap, so the advance has to be
+		 * computed with modular arithmetic rather than by comparing the
+		 * second value against the first one. A delta of 0 is normal:
+		 * it means no entry was blocked by that source over the
+		 * interval, and most counters on an idle system read 0
+		 * permanently.
+		 */
+		delta = second.values[i] - first.values[i];
+
+		if (delta > max_delta) {
+			tst_res(TFAIL,
+				"%s advanced by %u over %lluus, at most %llu plausible: %u -> %u",
+				first.names[i], delta, elapsed_us, max_delta,
+				first.values[i], second.values[i]);
+			fails++;
+		}
+	}
+
+	if (!fails) {
+		tst_res(TPASS, "%d LTR blocker counters well-formed, advancing plausibly",
+			first.cnt);
+	}
+}
+
+static struct tst_test test = {
+	.min_kver = "7.2",
+	.needs_root = 1,
+	.needs_debugfs = 1,
+	.needs_kconfigs = (const char *const []) {
+		"CONFIG_DEBUG_FS",
+		"CONFIG_INTEL_PMC_CORE",
+		NULL
+	},
+	.supported_archs = (const char *const []) {
+		"x86",
+		"x86_64",
+		NULL
+	},
+	.tags = (const struct tst_tag[]) {
+		{"linux-git", "38c79dd63b72e36919ef097d4e5025ca0fa17f34"},
+		{}
+	},
+	.setup = setup,
+	.test_all = run
+};
-- 
2.47.3

---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
ul. Slowackiego 173 | 80-298 Gdansk | Sad Rejonowy Gdansk Polnoc | VII Wydzial Gospodarczy Krajowego Rejestru Sadowego - KRS 101882 | NIP 957-07-52-316 | Kapital zakladowy 200.000 PLN.
Spolka oswiadcza, ze posiada status duzego przedsiebiorcy w rozumieniu ustawy z dnia 8 marca 2013 r. o przeciwdzialaniu nadmiernym opoznieniom w transakcjach handlowych.

Ta wiadomosc wraz z zalacznikami jest przeznaczona dla okreslonego adresata i moze zawierac informacje poufne. W razie przypadkowego otrzymania tej wiadomosci, prosimy o powiadomienie nadawcy oraz trwale jej usuniecie; jakiekolwiek przegladanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by others is strictly prohibited.


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* [LTP] [PATCH 3/3] pmc_core: add ltr_counter test
  2026-09-04 12:40 [LTP] [PATCH 0/3] pmc_core: cover the PkgC LTR blocker counters Piotr Kubaj
  2026-09-04 12:40 ` [LTP] [PATCH 1/3] lib: add tst_test.needs_debugfs flag Piotr Kubaj
  2026-09-04 12:40 ` [LTP] [PATCH 2/3] pmc_core: add test for pkgc_ltr_blocker_show Piotr Kubaj
@ 2026-09-04 12:40 ` Piotr Kubaj
  2026-09-07  6:28 ` [LTP] [PATCH 0/3] pmc_core: cover the PkgC LTR blocker counters Andrea Cervesato via ltp
  3 siblings, 0 replies; 6+ messages in thread
From: Piotr Kubaj @ 2026-09-04 12:40 UTC (permalink / raw)
  To: ltp; +Cc: helena.anna.dubel, tomasz.ossowski, rafael.j.wysocki,
	daniel.niestepski

Add a test for the invariant behind the pkgc_ltr_blocker_show counters:
they only advance while a package C-state entry can be attempted, which
needs every CPU in the package to be idle. A counter that keeps advancing
with every CPU busy is not counting blocked package C-state entries,
which is what a telemetry region read at the wrong offset looks like.

The test first lets the system idle until it sees a counter advance, so
that a counter stuck at a constant value cannot pass the load phase for
free, and then pins a busy loop to every CPU it may run on and requires
the counters to hold still.

The counters are backed by a PMT telemetry region that the PMC refreshes
asynchronously and in bursts - roughly six seconds apart on Nova Lake -
so the load phase waits for the counters to go quiet rather than sampling
them after a fixed delay. Entries blocked before the load took hold
surface in a later refresh, while a counter that is not tracking blocked
entries never goes quiet at all and runs the window out.

Tested on Nova Lake running 7.3.0-rc1.

Signed-off-by: Piotr Kubaj <piotr.kubaj@intel.com>
---
 runtest/power_management_tests                |   1 +
 testcases/kernel/power_management/.gitignore  |   1 +
 .../kernel/power_management/ltr_counter.c     | 355 ++++++++++++++++++
 3 files changed, 357 insertions(+)
 create mode 100644 testcases/kernel/power_management/ltr_counter.c

diff --git a/runtest/power_management_tests b/runtest/power_management_tests
index 93b5a5c10..d272d04af 100644
--- a/runtest/power_management_tests
+++ b/runtest/power_management_tests
@@ -1,4 +1,5 @@
 #POWER_MANAGEMENT
+ltr_counter ltr_counter
 pkgc_ltr_blocker_show pkgc_ltr_blocker_show
 runpwtests01 runpwtests01.sh
 runpwtests02 runpwtests02.sh
diff --git a/testcases/kernel/power_management/.gitignore b/testcases/kernel/power_management/.gitignore
index 0d7db221b..4f21ece13 100644
--- a/testcases/kernel/power_management/.gitignore
+++ b/testcases/kernel/power_management/.gitignore
@@ -1,2 +1,3 @@
 pm_get_sched_values
+ltr_counter
 pkgc_ltr_blocker_show
diff --git a/testcases/kernel/power_management/ltr_counter.c b/testcases/kernel/power_management/ltr_counter.c
new file mode 100644
index 000000000..0012d47fc
--- /dev/null
+++ b/testcases/kernel/power_management/ltr_counter.c
@@ -0,0 +1,355 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/*
+ * Copyright (C) 2026 Intel - http://www.intel.com/
+ */
+
+/*\
+ * Verify that the package C-state LTR blocker counters only advance while a
+ * package C-state entry can be attempted.
+ *
+ * The pkgc_ltr_blocker_show debugfs file reports, per source, how many times an
+ * LTR posted by that source blocked a package C-state entry. Such an entry is
+ * only attempted once every CPU in the package has gone idle, so a workload
+ * that keeps every CPU busy has to stop the counters. A counter that keeps
+ * advancing under full load is not counting blocked package C-state entries,
+ * which is what a telemetry region read at the wrong offset looks like.
+ *
+ * The test first lets the system idle until it sees a counter advance, so that
+ * a counter stuck at a constant value cannot pass the load phase for free. It
+ * then pins a busy loop to every CPU and requires the counters to hold still.
+ *
+ * The counters are backed by a PMT telemetry region that the PMC refreshes
+ * asynchronously and in bursts - roughly six seconds apart on Nova Lake - so
+ * the load phase waits for the counters to go quiet rather than sampling them
+ * after a fixed delay. Entries blocked before the load took hold surface in a
+ * later refresh, while a counter that is not tracking blocked entries never
+ * goes quiet at all and runs the window out.
+ *
+ * The test needs root because /sys/kernel/debug is mode 0700 and owned by
+ * root, so the counter file cannot be opened otherwise, and because the test
+ * library mounts debugfs if it is not mounted already.
+ */
+
+#define _GNU_SOURCE
+
+#include <sched.h>
+#include <signal.h>
+#include <time.h>
+#include "tst_clocks.h"
+#include "tst_safe_stdio.h"
+#include "tst_test.h"
+#include "tst_timer.h"
+
+#define PATH TST_DEBUGFS_PATH "/pmc_core/pkgc_ltr_blocker_show"
+
+/* Nova Lake reports 5 counters, leave room for future platforms */
+#define MAX_COUNTERS 64
+#define NAME_LEN 64
+
+#define POLL_MS 500
+
+/*
+ * Seconds to wait for a counter to advance while the system idles. The bursts
+ * are about six seconds apart on Nova Lake, so this leaves room for two of
+ * them before giving up on the platform blocking a package C-state entry at
+ * all.
+ */
+#define IDLE_WINDOW 15
+
+/*
+ * How long, in seconds, the counters have to hold still under load, and the cap
+ * on how long to wait for that. One burst period of silence is what tells a
+ * stopped counter from one that is merely between refreshes, and the cap has to
+ * be long enough on top of that for a burst counted before the load took hold
+ * to arrive and drain.
+ */
+#define QUIET_WINDOW 6
+#define LOAD_WINDOW 20
+
+static char names[MAX_COUNTERS][NAME_LEN];
+static int cnt;
+static pid_t *spinners;
+static int nr_spinners;
+static volatile unsigned long long burn;
+
+/*
+ * Read the counter values, checking that the counter set itself has not changed
+ * since setup(). Only the values are of interest here - the format of the file
+ * is what the pkgc_ltr_blocker_show test covers - so anything unexpected about
+ * the lines makes this test unable to run rather than failing it.
+ */
+static void read_counters(uint32_t *values)
+{
+	char line[256];
+	FILE *fp;
+	int n = 0;
+
+	fp = SAFE_FOPEN(PATH, "r");
+
+	while (fgets(line, sizeof(line), fp)) {
+		char name[NAME_LEN];
+		unsigned int value;
+
+		line[strcspn(line, "\n")] = '\0';
+
+		if (n == MAX_COUNTERS)
+			tst_brk(TBROK, "more than %d counters reported", MAX_COUNTERS);
+
+		if (sscanf(line, "%63s %u", name, &value) != 2)
+			tst_brk(TBROK, "unexpected line format: '%s'", line);
+
+		values[n] = value;
+
+		if (cnt && strcmp(name, names[n])) {
+			tst_brk(TBROK, "counter %d renamed during the test: %s -> %s",
+				n, names[n], name);
+		}
+
+		if (!cnt)
+			strcpy(names[n], name);
+
+		n++;
+	}
+
+	/*
+	 * A telemetry read that fails in the driver aborts the seq_file read
+	 * instead of ending it at EOF, so without this the counters lost to the
+	 * error would look like counters that stopped advancing.
+	 */
+	if (ferror(fp))
+		tst_brk(TBROK, "reading " PATH " failed after %d counters", n);
+
+	SAFE_FCLOSE(fp);
+
+	if (cnt && n != cnt)
+		tst_brk(TBROK, "counter count changed during the test: %d -> %d", cnt, n);
+
+	cnt = n;
+}
+
+static void spin(void)
+{
+	/* volatile so that the loop survives optimization */
+	for (;;)
+		burn++;
+}
+
+/*
+ * Keep every CPU the test may run on busy, so that the package cannot go idle
+ * and no package C-state entry can be attempted.
+ *
+ * The spinners are pinned one per CPU taken from the test's own affinity mask,
+ * rather than left to the load balancer, so that a CPU is not left idle by a
+ * scheduling decision. Offline CPUs and a restricted mask are handled by
+ * construction.
+ */
+static void start_load(void)
+{
+	cpu_set_t mask;
+	int cpu = 0;
+
+	if (sched_getaffinity(0, sizeof(mask), &mask))
+		tst_brk(TBROK | TERRNO, "sched_getaffinity() failed");
+
+	nr_spinners = CPU_COUNT(&mask);
+	spinners = SAFE_MALLOC(nr_spinners * sizeof(*spinners));
+
+	for (int i = 0; i < nr_spinners; i++) {
+		pid_t pid;
+
+		while (!CPU_ISSET(cpu, &mask))
+			cpu++;
+
+		pid = SAFE_FORK();
+
+		if (!pid) {
+			cpu_set_t one;
+
+			CPU_ZERO(&one);
+			CPU_SET(cpu, &one);
+
+			if (sched_setaffinity(0, sizeof(one), &one)) {
+				tst_brk(TBROK | TERRNO,
+					"sched_setaffinity(CPU %d) failed", cpu);
+			}
+
+			spin();
+		}
+
+		spinners[i] = pid;
+		cpu++;
+	}
+
+	tst_res(TINFO, "keeping %d CPUs busy", nr_spinners);
+}
+
+static void stop_load(void)
+{
+	if (!spinners)
+		return;
+
+	for (int i = 0; i < nr_spinners; i++) {
+		SAFE_KILL(spinners[i], SIGKILL);
+		SAFE_WAITPID(spinners[i], NULL, 0);
+	}
+
+	free(spinners);
+	spinners = NULL;
+}
+
+/*
+ * Wait for a counter to advance while the system idles, reporting how many did.
+ *
+ * This is what tells a counter that stops under load from one that never moves.
+ * On an idle system most counters read 0 permanently, because nothing posts an
+ * LTR that would block a package C-state entry, so a single counter advancing
+ * is enough.
+ */
+static int wait_for_advance(const uint32_t *baseline)
+{
+	uint32_t values[MAX_COUNTERS];
+	struct timespec start, now;
+	int advanced = 0;
+
+	tst_clock_gettime(CLOCK_MONOTONIC, &start);
+
+	for (;;) {
+		read_counters(values);
+
+		for (int i = 0; i < cnt; i++) {
+			if (values[i] == baseline[i])
+				continue;
+
+			tst_res(TINFO, "%s advanced by %u while idle", names[i],
+				values[i] - baseline[i]);
+			advanced++;
+		}
+
+		if (advanced)
+			return advanced;
+
+		tst_clock_gettime(CLOCK_MONOTONIC, &now);
+
+		if (tst_timespec_diff_ms(now, start) >= IDLE_WINDOW * 1000)
+			return 0;
+
+		usleep(POLL_MS * 1000);
+	}
+}
+
+/*
+ * Require the counters to hold still for QUIET_WINDOW seconds of full load.
+ */
+static void check_counters_stop(void)
+{
+	uint32_t first[MAX_COUNTERS], prev[MAX_COUNTERS], values[MAX_COUNTERS];
+	bool moved[MAX_COUNTERS] = {};
+	struct timespec start, last_change, now;
+
+	read_counters(first);
+	memcpy(prev, first, sizeof(prev));
+
+	tst_clock_gettime(CLOCK_MONOTONIC, &start);
+	last_change = start;
+
+	for (;;) {
+		usleep(POLL_MS * 1000);
+
+		read_counters(values);
+		tst_clock_gettime(CLOCK_MONOTONIC, &now);
+
+		for (int i = 0; i < cnt; i++) {
+			if (values[i] == prev[i])
+				continue;
+
+			moved[i] = true;
+			last_change = now;
+		}
+
+		memcpy(prev, values, sizeof(prev));
+
+		if (tst_timespec_diff_ms(now, last_change) >= QUIET_WINDOW * 1000) {
+			tst_res(TPASS,
+				"%d counters held still over %ds with every CPU busy",
+				cnt, QUIET_WINDOW);
+			return;
+		}
+
+		if (tst_timespec_diff_ms(now, start) < LOAD_WINDOW * 1000)
+			continue;
+
+		for (int i = 0; i < cnt; i++) {
+			if (!moved[i])
+				continue;
+
+			tst_res(TFAIL,
+				"%s kept advancing over %ds with every CPU busy: %u -> %u",
+				names[i], LOAD_WINDOW, first[i], values[i]);
+		}
+
+		return;
+	}
+}
+
+static void setup(void)
+{
+	uint32_t values[MAX_COUNTERS];
+
+	if (access(PATH, R_OK))
+		tst_brk(TCONF | TERRNO, "%s not available", PATH);
+
+	/* Learns the counter set the rest of the test compares against */
+	read_counters(values);
+
+	if (!cnt)
+		tst_brk(TBROK, "no LTR blocker counters reported");
+}
+
+static void cleanup(void)
+{
+	stop_load();
+}
+
+static void run(void)
+{
+	uint32_t baseline[MAX_COUNTERS];
+
+	read_counters(baseline);
+
+	if (!wait_for_advance(baseline)) {
+		tst_brk(TCONF,
+			"no LTR blocked a package C-state entry over %ds of idling, "
+			"a counter that stops under load cannot be told from a stuck one",
+			IDLE_WINDOW);
+	}
+
+	start_load();
+	check_counters_stop();
+	stop_load();
+}
+
+static struct tst_test test = {
+	.min_kver = "7.2",
+	.timeout = 90,
+	.needs_root = 1,
+	.needs_debugfs = 1,
+	.forks_child = 1,
+	.needs_kconfigs = (const char *const []) {
+		"CONFIG_DEBUG_FS",
+		"CONFIG_INTEL_PMC_CORE",
+		NULL
+	},
+	.supported_archs = (const char *const []) {
+		"x86",
+		"x86_64",
+		NULL
+	},
+	.tags = (const struct tst_tag[]) {
+		{"linux-git", "38c79dd63b72e36919ef097d4e5025ca0fa17f34"},
+		{}
+	},
+	.setup = setup,
+	.cleanup = cleanup,
+	.test_all = run
+};
-- 
2.47.3

---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
ul. Slowackiego 173 | 80-298 Gdansk | Sad Rejonowy Gdansk Polnoc | VII Wydzial Gospodarczy Krajowego Rejestru Sadowego - KRS 101882 | NIP 957-07-52-316 | Kapital zakladowy 200.000 PLN.
Spolka oswiadcza, ze posiada status duzego przedsiebiorcy w rozumieniu ustawy z dnia 8 marca 2013 r. o przeciwdzialaniu nadmiernym opoznieniom w transakcjach handlowych.

Ta wiadomosc wraz z zalacznikami jest przeznaczona dla okreslonego adresata i moze zawierac informacje poufne. W razie przypadkowego otrzymania tej wiadomosci, prosimy o powiadomienie nadawcy oraz trwale jej usuniecie; jakiekolwiek przegladanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by others is strictly prohibited.


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* Re: [LTP] [PATCH 0/3] pmc_core: cover the PkgC LTR blocker counters
  2026-09-04 12:40 [LTP] [PATCH 0/3] pmc_core: cover the PkgC LTR blocker counters Piotr Kubaj
                   ` (2 preceding siblings ...)
  2026-09-04 12:40 ` [LTP] [PATCH 3/3] pmc_core: add ltr_counter test Piotr Kubaj
@ 2026-09-07  6:28 ` Andrea Cervesato via ltp
  2026-09-07 12:12   ` Kubaj, Piotr
  3 siblings, 1 reply; 6+ messages in thread
From: Andrea Cervesato via ltp @ 2026-09-07  6:28 UTC (permalink / raw)
  To: Piotr Kubaj
  Cc: daniel.niestepski, tomasz.ossowski, helena.anna.dubel,
	rafael.j.wysocki, ltp

Hi Piotr,

can you please send a patch version that applies?
All CI is failing at the moment:

https://patchwork.kernel.org/project/ltp/patch/20260904124042.212065-2-piotr.kubaj@intel.com/

--
Andrea Cervesato
SUSE QE Automation Engineer Linux
andrea.cervesato@suse.com

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

* Re: [LTP] [PATCH 0/3] pmc_core: cover the PkgC LTR blocker counters
  2026-09-07  6:28 ` [LTP] [PATCH 0/3] pmc_core: cover the PkgC LTR blocker counters Andrea Cervesato via ltp
@ 2026-09-07 12:12   ` Kubaj, Piotr
  0 siblings, 0 replies; 6+ messages in thread
From: Kubaj, Piotr @ 2026-09-07 12:12 UTC (permalink / raw)
  To: andrea.cervesato@suse.com
  Cc: Wysocki, Rafael J, Ossowski, Tomasz, Dubel, Helena Anna,
	Niestepski, Daniel, ltp@lists.linux.it

W dniu pon, 07.09.2026 o godzinie 06∶28 +0000, użytkownik Andrea
Cervesato napisał:
> Hi Piotr,
> 
> can you please send a patch version that applies?
> All CI is failing at the moment:
> 
> https://patchwork.kernel.org/project/ltp/patch/20260904124042.212065-2-piotr.kubaj@intel.com/
> 
> --
> Andrea Cervesato
> SUSE QE Automation Engineer Linux
> andrea.cervesato@suse.com
Hi,

resubmitted after rebasing.
---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
ul. Slowackiego 173 | 80-298 Gdansk | Sad Rejonowy Gdansk Polnoc | VII Wydzial Gospodarczy Krajowego Rejestru Sadowego - KRS 101882 | NIP 957-07-52-316 | Kapital zakladowy 200.000 PLN.
Spolka oswiadcza, ze posiada status duzego przedsiebiorcy w rozumieniu ustawy z dnia 8 marca 2013 r. o przeciwdzialaniu nadmiernym opoznieniom w transakcjach handlowych.

Ta wiadomosc wraz z zalacznikami jest przeznaczona dla okreslonego adresata i moze zawierac informacje poufne. W razie przypadkowego otrzymania tej wiadomosci, prosimy o powiadomienie nadawcy oraz trwale jej usuniecie; jakiekolwiek przegladanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by others is strictly prohibited.

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

end of thread, other threads:[~2026-09-07 12:12 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-04 12:40 [LTP] [PATCH 0/3] pmc_core: cover the PkgC LTR blocker counters Piotr Kubaj
2026-09-04 12:40 ` [LTP] [PATCH 1/3] lib: add tst_test.needs_debugfs flag Piotr Kubaj
2026-09-04 12:40 ` [LTP] [PATCH 2/3] pmc_core: add test for pkgc_ltr_blocker_show Piotr Kubaj
2026-09-04 12:40 ` [LTP] [PATCH 3/3] pmc_core: add ltr_counter test Piotr Kubaj
2026-09-07  6:28 ` [LTP] [PATCH 0/3] pmc_core: cover the PkgC LTR blocker counters Andrea Cervesato via ltp
2026-09-07 12:12   ` Kubaj, Piotr

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