summaryrefslogtreecommitdiffstats
path: root/tools/perf/tests/time-utils-test.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-08-19 10:09:22 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-08-19 10:09:22 -0700
commitf4cdf7ca9a1fdcca413157df19753f388a5a224e (patch)
tree60a31895b2446cd7fa27514e8c2843534a0de0da /tools/perf/tests/time-utils-test.c
downloadlinux-stable-f4cdf7ca9a1fdcca413157df19753f388a5a224e.tar.gz
linux-stable-f4cdf7ca9a1fdcca413157df19753f388a5a224e.zip
Merge tag 'media/v7.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-mediagrafted
Pull media updates from Mauro Carvalho Chehab: - v4l2-core: added ISP statistics support and per-block validation - v4l2-core: Allow unknown HDR10 white point and luminance - New camera sensors: Sony IMX678 and IMX471m, Himax HM1092 IR sensor - New codec: Milos: VPU v2.0 codec support - isp driver: gained support for Dreamchip RPPX1 ISP framework - vsp1 driver: gained support for RZ/T2H and RZ/N2H - Novalake driver: gained CVS support for new NVL hardware - dvb-core: fix feed leak on failed DMX_ADD_PID - several driver fixes, cleanups and minor improvements * tag 'media/v7.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (308 commits) media: ipu-bridge: check all DMI entries when overriding sensor rotation media: v4l2-async: avoid deleting unlinked ASC entry on link error media: rzg2l-cru: Align bytesperline to hardware DMA stride requirement media: intel/ipu6: fix async notifier cleanup leak on parse error media: staging/ipu7: fix async notifier UAF on probe error path media: amd: isp4: fix self-deadlock in isp4sd_pwron_and_init() error path media: amd: isp4: release partial allocations in isp4if_alloc_fw_gpumem() media: rcar-isp: Fix VSPX reference leaks media: rcar-isp: Release ISPCORE resources media: i2c: imx415: Release runtime PM reference on VBLANK error media: i2c: imx415: Return test pattern write errors media: renesas: vsp1: Declare index variables in for loop statement media: renesas: vsp1: Make reset control optional to support platforms without a reset line media: dt-bindings: media: renesas,vsp1: Document RZ/T2H and RZ/N2H SoCs media: dt-bindings: media: renesas,fcp: Document RZ/T2H and RZ/N2H SoCs media: nxp: imx8-isi: Add additional 32-bit RGB format support media: nxp: imx8-isi: Add 16-bit raw Bayer format support media: nxp: imx8-isi: Implement per-stream reference counting for multiplexed streams media: nxp: imx8-isi: Use BIT_ULL() for 64-bit stream masks media: nxp: imx8-isi: Correct color map between V4L2 and ISI ...
Diffstat (limited to 'tools/perf/tests/time-utils-test.c')
-rw-r--r--tools/perf/tests/time-utils-test.c253
1 files changed, 253 insertions, 0 deletions
diff --git a/tools/perf/tests/time-utils-test.c b/tools/perf/tests/time-utils-test.c
new file mode 100644
index 000000000..38df10373
--- /dev/null
+++ b/tools/perf/tests/time-utils-test.c
@@ -0,0 +1,253 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/compiler.h>
+#include <linux/time64.h>
+#include <inttypes.h>
+#include <string.h>
+#include "time-utils.h"
+#include "evlist.h"
+#include "session.h"
+#include "debug.h"
+#include "tests.h"
+
+static bool test__parse_nsec_time(const char *str, u64 expected)
+{
+ u64 ptime;
+ int err;
+
+ pr_debug("\nparse_nsec_time(\"%s\")\n", str);
+
+ err = parse_nsec_time(str, &ptime);
+ if (err) {
+ pr_debug("error %d\n", err);
+ return false;
+ }
+
+ if (ptime != expected) {
+ pr_debug("Failed. ptime %" PRIu64 " expected %" PRIu64 "\n",
+ ptime, expected);
+ return false;
+ }
+
+ pr_debug("%" PRIu64 "\n", ptime);
+
+ return true;
+}
+
+static bool test__perf_time__parse_str(const char *ostr, u64 start, u64 end)
+{
+ struct perf_time_interval ptime;
+ int err;
+
+ pr_debug("\nperf_time__parse_str(\"%s\")\n", ostr);
+
+ err = perf_time__parse_str(&ptime, ostr);
+ if (err) {
+ pr_debug("Error %d\n", err);
+ return false;
+ }
+
+ if (ptime.start != start || ptime.end != end) {
+ pr_debug("Failed. Expected %" PRIu64 " to %" PRIu64 "\n",
+ start, end);
+ return false;
+ }
+
+ return true;
+}
+
+#define TEST_MAX 64
+
+struct test_data {
+ const char *str;
+ u64 first;
+ u64 last;
+ struct perf_time_interval ptime[TEST_MAX];
+ int num;
+ u64 skip[TEST_MAX];
+ u64 noskip[TEST_MAX];
+};
+
+static bool test__perf_time__parse_for_ranges(struct test_data *d)
+{
+ struct evlist evlist = {
+ .first_sample_time = d->first,
+ .last_sample_time = d->last,
+ };
+ struct perf_session session = { .evlist = &evlist };
+ struct perf_time_interval *ptime = NULL;
+ int range_size, range_num;
+ bool pass = false;
+ int i, err;
+
+ pr_debug("\nperf_time__parse_for_ranges(\"%s\")\n", d->str);
+
+ if (strchr(d->str, '%'))
+ pr_debug("first_sample_time %" PRIu64 " last_sample_time %" PRIu64 "\n",
+ d->first, d->last);
+
+ err = perf_time__parse_for_ranges(d->str, &session, &ptime, &range_size,
+ &range_num);
+ if (err) {
+ pr_debug("error %d\n", err);
+ goto out;
+ }
+
+ if (range_size < d->num || range_num != d->num) {
+ pr_debug("bad size: range_size %d range_num %d expected num %d\n",
+ range_size, range_num, d->num);
+ goto out;
+ }
+
+ for (i = 0; i < d->num; i++) {
+ if (ptime[i].start != d->ptime[i].start ||
+ ptime[i].end != d->ptime[i].end) {
+ pr_debug("bad range %d expected %" PRIu64 " to %" PRIu64 "\n",
+ i, d->ptime[i].start, d->ptime[i].end);
+ goto out;
+ }
+ }
+
+ if (perf_time__ranges_skip_sample(ptime, d->num, 0)) {
+ pr_debug("failed to keep 0\n");
+ goto out;
+ }
+
+ for (i = 0; i < TEST_MAX; i++) {
+ if (d->skip[i] &&
+ !perf_time__ranges_skip_sample(ptime, d->num, d->skip[i])) {
+ pr_debug("failed to skip %" PRIu64 "\n", d->skip[i]);
+ goto out;
+ }
+ if (d->noskip[i] &&
+ perf_time__ranges_skip_sample(ptime, d->num, d->noskip[i])) {
+ pr_debug("failed to keep %" PRIu64 "\n", d->noskip[i]);
+ goto out;
+ }
+ }
+
+ pass = true;
+out:
+ free(ptime);
+ return pass;
+}
+
+static int test__time_utils(struct test_suite *t __maybe_unused, int subtest __maybe_unused)
+{
+ bool pass = true;
+
+ pass &= test__parse_nsec_time("0", 0);
+ pass &= test__parse_nsec_time("1", 1000000000ULL);
+ pass &= test__parse_nsec_time("0.000000001", 1);
+ pass &= test__parse_nsec_time("1.000000001", 1000000001ULL);
+ pass &= test__parse_nsec_time("123456.123456", 123456123456000ULL);
+ pass &= test__parse_nsec_time("1234567.123456789", 1234567123456789ULL);
+ pass &= test__parse_nsec_time("18446744073.709551615",
+ 0xFFFFFFFFFFFFFFFFULL);
+
+ pass &= test__perf_time__parse_str("1234567.123456789,1234567.123456789",
+ 1234567123456789ULL, 1234567123456789ULL);
+ pass &= test__perf_time__parse_str("1234567.123456789,1234567.123456790",
+ 1234567123456789ULL, 1234567123456790ULL);
+ pass &= test__perf_time__parse_str("1234567.123456789,",
+ 1234567123456789ULL, 0);
+ pass &= test__perf_time__parse_str(",1234567.123456789",
+ 0, 1234567123456789ULL);
+ pass &= test__perf_time__parse_str("0,1234567.123456789",
+ 0, 1234567123456789ULL);
+
+ {
+ u64 b = 1234567123456789ULL;
+ struct test_data d = {
+ .str = "1234567.123456789,1234567.123456790",
+ .ptime = { {b, b + 1}, },
+ .num = 1,
+ .skip = { b - 1, b + 2, },
+ .noskip = { b, b + 1, },
+ };
+
+ pass &= test__perf_time__parse_for_ranges(&d);
+ }
+
+ {
+ u64 b = 1234567123456789ULL;
+ u64 c = 7654321987654321ULL;
+ u64 e = 8000000000000000ULL;
+ struct test_data d = {
+ .str = "1234567.123456789,1234567.123456790 "
+ "7654321.987654321,7654321.987654444 "
+ "8000000,8000000.000000005",
+ .ptime = { {b, b + 1}, {c, c + 123}, {e, e + 5}, },
+ .num = 3,
+ .skip = { b - 1, b + 2, c - 1, c + 124, e - 1, e + 6 },
+ .noskip = { b, b + 1, c, c + 123, e, e + 5 },
+ };
+
+ pass &= test__perf_time__parse_for_ranges(&d);
+ }
+
+ {
+ u64 b = 7654321ULL * NSEC_PER_SEC;
+ struct test_data d = {
+ .str = "10%/1",
+ .first = b,
+ .last = b + 100,
+ .ptime = { {b, b + 9}, },
+ .num = 1,
+ .skip = { b - 1, b + 10, },
+ .noskip = { b, b + 9, },
+ };
+
+ pass &= test__perf_time__parse_for_ranges(&d);
+ }
+
+ {
+ u64 b = 7654321ULL * NSEC_PER_SEC;
+ struct test_data d = {
+ .str = "10%/2",
+ .first = b,
+ .last = b + 100,
+ .ptime = { {b + 10, b + 19}, },
+ .num = 1,
+ .skip = { b + 9, b + 20, },
+ .noskip = { b + 10, b + 19, },
+ };
+
+ pass &= test__perf_time__parse_for_ranges(&d);
+ }
+
+ {
+ u64 b = 11223344ULL * NSEC_PER_SEC;
+ struct test_data d = {
+ .str = "10%/1,10%/2",
+ .first = b,
+ .last = b + 100,
+ .ptime = { {b, b + 9}, {b + 10, b + 19}, },
+ .num = 2,
+ .skip = { b - 1, b + 20, },
+ .noskip = { b, b + 8, b + 9, b + 10, b + 11, b + 12, b + 19, },
+ };
+
+ pass &= test__perf_time__parse_for_ranges(&d);
+ }
+
+ {
+ u64 b = 11223344ULL * NSEC_PER_SEC;
+ struct test_data d = {
+ .str = "10%/1,10%/3,10%/10",
+ .first = b,
+ .last = b + 100,
+ .ptime = { {b, b + 9}, {b + 20, b + 29}, { b + 90, b + 100}, },
+ .num = 3,
+ .skip = { b - 1, b + 10, b + 19, b + 30, b + 89, b + 101 },
+ .noskip = { b, b + 9, b + 20, b + 29, b + 90, b + 100},
+ };
+
+ pass &= test__perf_time__parse_for_ranges(&d);
+ }
+
+ pr_debug("\n");
+
+ return pass ? 0 : TEST_FAIL;
+}
+
+DEFINE_SUITE("time utils", time_utils);