diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-19 10:09:22 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-19 10:09:22 -0700 |
| commit | f4cdf7ca9a1fdcca413157df19753f388a5a224e (patch) | |
| tree | 60a31895b2446cd7fa27514e8c2843534a0de0da /tools/perf/tests/api-io.c | |
| download | linux-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/api-io.c')
| -rw-r--r-- | tools/perf/tests/api-io.c | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/tools/perf/tests/api-io.c b/tools/perf/tests/api-io.c new file mode 100644 index 000000000..0ba3d5cce --- /dev/null +++ b/tools/perf/tests/api-io.c @@ -0,0 +1,343 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "debug.h" +#include "tests.h" +#include <api/io.h> +#include <linux/kernel.h> +#include <linux/zalloc.h> + +#define TEMPL "/tmp/perf-test-XXXXXX" + +#define EXPECT_EQUAL(val, expected) \ +do { \ + if (val != expected) { \ + pr_debug("%s:%d: %d != %d\n", \ + __FILE__, __LINE__, val, expected); \ + ret = -1; \ + } \ +} while (0) + +#define EXPECT_EQUAL64(val, expected) \ +do { \ + if (val != expected) { \ + pr_debug("%s:%d: %lld != %lld\n", \ + __FILE__, __LINE__, val, expected); \ + ret = -1; \ + } \ +} while (0) + +static int make_test_file(char path[PATH_MAX], const char *contents) +{ + ssize_t contents_len = strlen(contents); + int fd; + + strcpy(path, TEMPL); + fd = mkstemp(path); + if (fd < 0) { + pr_debug("mkstemp failed"); + return -1; + } + if (write(fd, contents, contents_len) < contents_len) { + pr_debug("short write"); + close(fd); + unlink(path); + return -1; + } + close(fd); + return 0; +} + +static int setup_test(char path[PATH_MAX], const char *contents, + size_t buf_size, struct io *io) +{ + if (make_test_file(path, contents)) + return -1; + + io->fd = open(path, O_RDONLY); + if (io->fd < 0) { + pr_debug("Failed to open '%s'\n", path); + unlink(path); + return -1; + } + io->buf = malloc(buf_size); + if (io->buf == NULL) { + pr_debug("Failed to allocate memory"); + close(io->fd); + unlink(path); + return -1; + } + io__init(io, io->fd, io->buf, buf_size); + return 0; +} + +static void cleanup_test(char path[PATH_MAX], struct io *io) +{ + zfree(&io->buf); + close(io->fd); + unlink(path); +} + +static int do_test_get_char(const char *test_string, size_t buf_size) +{ + char path[PATH_MAX]; + struct io io; + int ch, ret = 0; + size_t i; + + if (setup_test(path, test_string, buf_size, &io)) + return -1; + + for (i = 0; i < strlen(test_string); i++) { + ch = io__get_char(&io); + + EXPECT_EQUAL(ch, test_string[i]); + EXPECT_EQUAL(io.eof, false); + } + ch = io__get_char(&io); + EXPECT_EQUAL(ch, -1); + EXPECT_EQUAL(io.eof, true); + + cleanup_test(path, &io); + return ret; +} + +static int test_get_char(void) +{ + int i, ret = 0; + size_t j; + + static const char *const test_strings[] = { + "12345678abcdef90", + "a\nb\nc\nd\n", + "\a\b\t\v\f\r", + }; + for (i = 0; i <= 10; i++) { + for (j = 0; j < ARRAY_SIZE(test_strings); j++) { + if (do_test_get_char(test_strings[j], 1 << i)) + ret = -1; + } + } + return ret; +} + +static int do_test_get_hex(const char *test_string, + __u64 val1, int ch1, + __u64 val2, int ch2, + __u64 val3, int ch3, + bool end_eof) +{ + char path[PATH_MAX]; + struct io io; + int ch, ret = 0; + __u64 hex; + + if (setup_test(path, test_string, 4, &io)) + return -1; + + ch = io__get_hex(&io, &hex); + EXPECT_EQUAL64(hex, val1); + EXPECT_EQUAL(ch, ch1); + + ch = io__get_hex(&io, &hex); + EXPECT_EQUAL64(hex, val2); + EXPECT_EQUAL(ch, ch2); + + ch = io__get_hex(&io, &hex); + EXPECT_EQUAL64(hex, val3); + EXPECT_EQUAL(ch, ch3); + + EXPECT_EQUAL(io.eof, end_eof); + + cleanup_test(path, &io); + return ret; +} + +static int test_get_hex(void) +{ + int ret = 0; + + if (do_test_get_hex("12345678abcdef90", + 0x12345678abcdef90, -1, + 0, -1, + 0, -1, + true)) + ret = -1; + + if (do_test_get_hex("1\n2\n3\n", + 1, '\n', + 2, '\n', + 3, '\n', + false)) + ret = -1; + + if (do_test_get_hex("12345678ABCDEF90;a;b", + 0x12345678abcdef90, ';', + 0xa, ';', + 0xb, -1, + true)) + ret = -1; + + if (do_test_get_hex("0x1x2x", + 0, 'x', + 1, 'x', + 2, 'x', + false)) + ret = -1; + + if (do_test_get_hex("x1x", + 0, -2, + 1, 'x', + 0, -1, + true)) + ret = -1; + + if (do_test_get_hex("10000000000000000000000000000abcdefgh99i", + 0xabcdef, 'g', + 0, -2, + 0x99, 'i', + false)) + ret = -1; + + return ret; +} + +static int do_test_get_dec(const char *test_string, + __u64 val1, int ch1, + __u64 val2, int ch2, + __u64 val3, int ch3, + bool end_eof) +{ + char path[PATH_MAX]; + struct io io; + int ch, ret = 0; + __u64 dec; + + if (setup_test(path, test_string, 4, &io)) + return -1; + + ch = io__get_dec(&io, &dec); + EXPECT_EQUAL64(dec, val1); + EXPECT_EQUAL(ch, ch1); + + ch = io__get_dec(&io, &dec); + EXPECT_EQUAL64(dec, val2); + EXPECT_EQUAL(ch, ch2); + + ch = io__get_dec(&io, &dec); + EXPECT_EQUAL64(dec, val3); + EXPECT_EQUAL(ch, ch3); + + EXPECT_EQUAL(io.eof, end_eof); + + cleanup_test(path, &io); + return ret; +} + +static int test_get_dec(void) +{ + int ret = 0; + + if (do_test_get_dec("12345678abcdef90", + 12345678, 'a', + 0, -2, + 0, -2, + false)) + ret = -1; + + if (do_test_get_dec("1\n2\n3\n", + 1, '\n', + 2, '\n', + 3, '\n', + false)) + ret = -1; + + if (do_test_get_dec("12345678;1;2", + 12345678, ';', + 1, ';', + 2, -1, + true)) + ret = -1; + + if (do_test_get_dec("0x1x2x", + 0, 'x', + 1, 'x', + 2, 'x', + false)) + ret = -1; + + if (do_test_get_dec("x1x", + 0, -2, + 1, 'x', + 0, -1, + true)) + ret = -1; + + if (do_test_get_dec("10000000000000000000000000000000000000000000000000000000000123456789ab99c", + 123456789, 'a', + 0, -2, + 99, 'c', + false)) + ret = -1; + + return ret; +} + +static int test_get_line(void) +{ + char path[PATH_MAX]; + struct io io; + char test_string[1024]; + char *line = NULL; + size_t i, line_len = 0; + size_t buf_size = 128; + int ret = 0; + + for (i = 0; i < 512; i++) + test_string[i] = 'a'; + test_string[512] = '\n'; + for (i = 513; i < 1023; i++) + test_string[i] = 'b'; + test_string[1023] = '\0'; + + if (setup_test(path, test_string, buf_size, &io)) + return -1; + + EXPECT_EQUAL((int)io__getline(&io, &line, &line_len), 513); + EXPECT_EQUAL((int)strlen(line), 513); + for (i = 0; i < 512; i++) + EXPECT_EQUAL(line[i], 'a'); + EXPECT_EQUAL(line[512], '\n'); + EXPECT_EQUAL((int)io__getline(&io, &line, &line_len), 510); + for (i = 0; i < 510; i++) + EXPECT_EQUAL(line[i], 'b'); + + free(line); + cleanup_test(path, &io); + return ret; +} + +static int test__api_io(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) +{ + int ret = 0; + + if (test_get_char()) + ret = TEST_FAIL; + if (test_get_hex()) + ret = TEST_FAIL; + if (test_get_dec()) + ret = TEST_FAIL; + if (test_get_line()) + ret = TEST_FAIL; + return ret; +} + +DEFINE_SUITE("Test api io", api_io); |
