* Re: [PATCH 4/4] selftests: ALSA: Cover userspace-driven timers with test @ 2024-07-28 5:40 kernel test robot 0 siblings, 0 replies; 3+ messages in thread From: kernel test robot @ 2024-07-28 5:40 UTC (permalink / raw) To: oe-kbuild; +Cc: lkp :::::: :::::: Manual check reason: "low confidence bisect report" :::::: BCC: lkp@intel.com CC: oe-kbuild-all@lists.linux.dev In-Reply-To: <20240726074750.626671-5-ivan.orlov0322@gmail.com> References: <20240726074750.626671-5-ivan.orlov0322@gmail.com> TO: Ivan Orlov <ivan.orlov0322@gmail.com> TO: perex@perex.cz TO: tiwai@suse.com TO: corbet@lwn.net TO: broonie@kernel.org TO: shuah@kernel.org CC: Ivan Orlov <ivan.orlov0322@gmail.com> CC: linux-kselftest@vger.kernel.org CC: linux-doc@vger.kernel.org CC: linux-sound@vger.kernel.org CC: linux-kernel@vger.kernel.org CC: aholzinger@gmx.de Hi Ivan, kernel test robot noticed the following build warnings: [auto build test WARNING on tiwai-sound/for-next] [also build test WARNING on tiwai-sound/for-linus linus/master v6.10 next-20240726] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Ivan-Orlov/ALSA-aloop-Allow-using-global-timers/20240726-155158 base: https://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git for-next patch link: https://lore.kernel.org/r/20240726074750.626671-5-ivan.orlov0322%40gmail.com patch subject: [PATCH 4/4] selftests: ALSA: Cover userspace-driven timers with test :::::: branch date: 2 days ago :::::: commit date: 2 days ago compiler: clang version 18.1.5 (https://github.com/llvm/llvm-project 617a15a9eac96088ae5e9134248d8236e34b91b1) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240728/202407281359.vMYdESrT-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/r/202407281359.vMYdESrT-lkp@intel.com/ All warnings (new ones prefixed by >>): >> utimer-test.c:73:1: warning: non-void function does not return a value [-Wreturn-type] 73 | } | ^ >> utimer-test.c:117:11: warning: enumeration value 'TIMER_NO_EVENT' not handled in switch [-Wswitch] 117 | switch (parse_timer_output(buf)) { | ^~~~~~~~~~~~~~~~~~~~~~~ 2 warnings generated. vim +73 tools/testing/selftests/alsa/utimer-test.c 5cf58530fa628b Ivan Orlov 2024-07-26 62 5cf58530fa628b Ivan Orlov 2024-07-26 63 static void *ticking_func(void *data) 5cf58530fa628b Ivan Orlov 2024-07-26 64 { 5cf58530fa628b Ivan Orlov 2024-07-26 65 int i; 5cf58530fa628b Ivan Orlov 2024-07-26 66 int *fd = (int *)data; 5cf58530fa628b Ivan Orlov 2024-07-26 67 5cf58530fa628b Ivan Orlov 2024-07-26 68 for (i = 0; i < TICKS_COUNT; i++) { 5cf58530fa628b Ivan Orlov 2024-07-26 69 /* Well, trigger the timer! */ 5cf58530fa628b Ivan Orlov 2024-07-26 70 ioctl(*fd, SNDRV_TIMER_IOCTL_TRIGGER, NULL); 5cf58530fa628b Ivan Orlov 2024-07-26 71 sleep(TIMER_FREQ_SEC); 5cf58530fa628b Ivan Orlov 2024-07-26 72 } 5cf58530fa628b Ivan Orlov 2024-07-26 @73 } 5cf58530fa628b Ivan Orlov 2024-07-26 74 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 0/4] Introduce userspace-driven ALSA timers
@ 2024-07-26 7:47 Ivan Orlov
2024-07-26 7:47 ` [PATCH 4/4] selftests: ALSA: Cover userspace-driven timers with test Ivan Orlov
0 siblings, 1 reply; 3+ messages in thread
From: Ivan Orlov @ 2024-07-26 7:47 UTC (permalink / raw)
To: perex, tiwai, corbet, broonie, shuah
Cc: Ivan Orlov, linux-kselftest, linux-doc, linux-sound, linux-kernel,
aholzinger
There are multiple possible timer sources which could be useful for
the sound stream synchronization: hrtimers, hardware clocks (e.g. PTP),
timer wheels (jiffies). Currently, using one of them to synchronize
the audio stream of snd-aloop module would require writing a
kernel-space driver which exports an ALSA timer through the
snd_timer interface.
However, it is not really convenient for application developers, who may
want to define their custom timer sources for audio synchronization.
For instance, we could have a network application which receives frames
and sends them to snd-aloop pcm device, and another application
listening on the other end of snd-aloop. It makes sense to transfer a
new period of data only when certain amount of frames is received
through the network, but definitely not when a certain amount of jiffies
on a local system elapses. Since all of the devices are purely virtual
it won't introduce any glitches and will help the application developers
to avoid using sample-rate conversion.
This patch series introduces userspace-driven ALSA timers: virtual
timers which are created and controlled from userspace. The timer can
be created from the userspace using the new ioctl SNDRV_TIMER_IOCTL_CREATE.
After creating a timer, it becomes available for use system-wide, so it
can be passed to snd-aloop as a timer source (timer_source parameter
would be "-1.SNDRV_TIMER_GLOBAL_UDRIVEN.{timer_id}"). When the userspace
app decides to trigger a timer, it calls another ioctl
SNDRV_TIMER_IOCTL_TRIGGER on the file descriptor of a timer. It
initiates a transfer of a new period of data.
Userspace-driven timers are associated with file descriptors. If the
application wishes to destroy the timer, it can simply release the file
descriptor of a virtual timer.
I believe introducing new ioctl calls is quite inconvenient (as we have
a limited amount of them), but other possible ways of app <-> kernel
communication (like virtual FS) seem completely inappropriate for this
task (but I'd love to discuss alternative solutions).
This patch series also updates the snd-aloop module so the global timers
can be used as a timer_source for it (it allows using userspace-driven
timers as timer source).
Ivan Orlov (4):
ALSA: aloop: Allow using global timers
Docs/sound: Add documentation for userspace-driven ALSA timers
ALSA: timer: Introduce virtual userspace-driven timers
selftests: ALSA: Cover userspace-driven timers with test
Documentation/sound/index.rst | 1 +
Documentation/sound/utimers.rst | 120 +++++++++++
include/uapi/sound/asound.h | 17 ++
sound/core/Kconfig | 11 +
sound/core/timer.c | 226 ++++++++++++++++++++
sound/drivers/aloop.c | 2 +
tools/testing/selftests/alsa/Makefile | 2 +-
tools/testing/selftests/alsa/global-timer.c | 87 ++++++++
tools/testing/selftests/alsa/utimer-test.c | 133 ++++++++++++
9 files changed, 598 insertions(+), 1 deletion(-)
create mode 100644 Documentation/sound/utimers.rst
create mode 100644 tools/testing/selftests/alsa/global-timer.c
create mode 100644 tools/testing/selftests/alsa/utimer-test.c
--
2.34.1
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH 4/4] selftests: ALSA: Cover userspace-driven timers with test 2024-07-26 7:47 [PATCH 0/4] Introduce userspace-driven ALSA timers Ivan Orlov @ 2024-07-26 7:47 ` Ivan Orlov 2024-07-28 6:10 ` kernel test robot 0 siblings, 1 reply; 3+ messages in thread From: Ivan Orlov @ 2024-07-26 7:47 UTC (permalink / raw) To: perex, tiwai, corbet, broonie, shuah Cc: Ivan Orlov, linux-kselftest, linux-doc, linux-sound, linux-kernel, aholzinger Add a test for the new functionality of userspace-driven timers and the tool which allows us to count timer ticks in a certain time period. The test: 1. Creates a userspace-driven timer with ioctl to /dev/snd/timer 2. Starts the `global-timer` application to count the ticks of the timer from step 1. 3. Asynchronously triggers the timer multiple times with some interval 4. Compares the amount of caught ticks with the amount of trigger calls. Since we can't include <alsa/asoundlib.h> and <sound/asound.h> in one file due to overlapping declarations, I have to split the test into two applications: one of them counts the amount of timer ticks in the defined time period, and another one is the actual test which creates the timer, triggers it periodically and starts the first app to count the amount of ticks in a separate thread. Besides from testing the functionality itself, the test represents a sample application showing userspace-driven ALSA timers API. Signed-off-by: Ivan Orlov <ivan.orlov0322@gmail.com> --- tools/testing/selftests/alsa/Makefile | 2 +- tools/testing/selftests/alsa/global-timer.c | 87 +++++++++++++ tools/testing/selftests/alsa/utimer-test.c | 133 ++++++++++++++++++++ 3 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/alsa/global-timer.c create mode 100644 tools/testing/selftests/alsa/utimer-test.c diff --git a/tools/testing/selftests/alsa/Makefile b/tools/testing/selftests/alsa/Makefile index c1ce39874e2b..0d5bd8ea900b 100644 --- a/tools/testing/selftests/alsa/Makefile +++ b/tools/testing/selftests/alsa/Makefile @@ -12,7 +12,7 @@ LDLIBS+=-lpthread OVERRIDE_TARGETS = 1 -TEST_GEN_PROGS := mixer-test pcm-test test-pcmtest-driver +TEST_GEN_PROGS := mixer-test pcm-test utimer-test test-pcmtest-driver global-timer TEST_GEN_PROGS_EXTENDED := libatest.so diff --git a/tools/testing/selftests/alsa/global-timer.c b/tools/testing/selftests/alsa/global-timer.c new file mode 100644 index 000000000000..c15ec0ba851a --- /dev/null +++ b/tools/testing/selftests/alsa/global-timer.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * This tool is used by the utimer test, and it allows us to + * count the ticks of a global timer in a certain time frame + * (which is set by `timeout` parameter). + * + * Author: Ivan Orlov <ivan.orlov0322@gmail.com> + */ +#include <stdio.h> +#include <stdlib.h> +#include <alsa/asoundlib.h> +#include <time.h> + +static int ticked; +static void async_callback(snd_async_handler_t *ahandler) +{ + ticked++; +} + +static char timer_name[64]; +static void bind_to_timer(int device, int subdevice, int timeout) +{ + snd_timer_t *handle; + snd_timer_params_t *params; + snd_async_handler_t *ahandler; + + time_t end; + + sprintf(timer_name, "hw:CLASS=%d,SCLASS=%d,DEV=%d,SUBDEV=%d", + SND_TIMER_CLASS_GLOBAL, SND_TIMER_SCLASS_NONE, + device, subdevice); + + snd_timer_params_alloca(¶ms); + + if (snd_timer_open(&handle, timer_name, SND_TIMER_OPEN_NONBLOCK) < 0) { + perror("Can't open the timer"); + exit(EXIT_FAILURE); + } + + snd_timer_params_set_auto_start(params, 1); + snd_timer_params_set_ticks(params, 1); + if (snd_timer_params(handle, params) < 0) { + perror("Can't set timer params"); + exit(EXIT_FAILURE); + } + + if (snd_async_add_timer_handler(&ahandler, handle, async_callback, NULL) < 0) { + perror("Can't create a handler"); + exit(EXIT_FAILURE); + } + end = time(NULL) + timeout; + if (snd_timer_start(handle) < 0) { + perror("Failed to start the timer"); + exit(EXIT_FAILURE); + } + printf("Timer has started\n"); + while (time(NULL) <= end) { + /* + * Waiting for the timeout to elapse. Can't use sleep here, as it gets + * constantly interrupted by the signal from the timer (SIGIO) + */ + } + snd_timer_stop(handle); + snd_timer_close(handle); +} + +int main(int argc, char *argv[]) +{ + int device, subdevice, timeout; + + if (argc < 4) { + perror("Usage: %s <device> <subdevice> <timeout>"); + return EXIT_FAILURE; + } + + setlinebuf(stdout); + + device = atoi(argv[1]); + subdevice = atoi(argv[2]); + timeout = atoi(argv[3]); + + bind_to_timer(device, subdevice, timeout); + + printf("Total ticks count: %d\n", ticked); + + return EXIT_SUCCESS; +} diff --git a/tools/testing/selftests/alsa/utimer-test.c b/tools/testing/selftests/alsa/utimer-test.c new file mode 100644 index 000000000000..38de90e507fe --- /dev/null +++ b/tools/testing/selftests/alsa/utimer-test.c @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * This test covers the functionality of userspace-driven ALSA timers. Such timers + * are purely virtual (so they don't directly depend on the hardware), and they could be + * created and triggered by userspace applications. + * + * Author: Ivan Orlov <ivan.orlov0322@gmail.com> + */ +#include "../kselftest_harness.h" +#include <sound/asound.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <stdlib.h> +#include <pthread.h> +#include <string.h> + +#define FRAME_RATE 8000 +#define PERIOD_SIZE 4410 +#define TICKS_COUNT 10 +#define TICKS_RECORDING_DELTA 5 +#define TIMER_OUTPUT_BUF_LEN 1024 +#define TIMER_FREQ_SEC 1 +#define RESULT_PREFIX_LEN strlen("Total ticks count: ") + +enum timer_app_event { + TIMER_APP_STARTED, + TIMER_APP_RESULT, + TIMER_NO_EVENT, +}; + +FIXTURE(timer_f) { + int utimer_fd; + struct snd_utimer_info *utimer_info; +}; + +FIXTURE_SETUP(timer_f) { + int timer_dev_fd; + + if (geteuid()) + SKIP(return, "This test needs root to run!"); + + self->utimer_info = calloc(1, sizeof(*self->utimer_info)); + ASSERT_NE(NULL, self->utimer_info); + + self->utimer_info->frame_rate = FRAME_RATE; + self->utimer_info->period_size = PERIOD_SIZE; + + timer_dev_fd = open("/dev/snd/timer", O_RDONLY); + ASSERT_GE(timer_dev_fd, 0); + + self->utimer_fd = ioctl(timer_dev_fd, SNDRV_TIMER_IOCTL_CREATE, self->utimer_info); + ASSERT_GE(self->utimer_fd, 0); + + close(timer_dev_fd); +} + +FIXTURE_TEARDOWN(timer_f) { + close(self->utimer_fd); + free(self->utimer_info); +} + +static void *ticking_func(void *data) +{ + int i; + int *fd = (int *)data; + + for (i = 0; i < TICKS_COUNT; i++) { + /* Well, trigger the timer! */ + ioctl(*fd, SNDRV_TIMER_IOCTL_TRIGGER, NULL); + sleep(TIMER_FREQ_SEC); + } +} + +static enum timer_app_event parse_timer_output(const char *s) +{ + if (strstr(s, "Timer has started")) + return TIMER_APP_STARTED; + if (strstr(s, "Total ticks count")) + return TIMER_APP_RESULT; + + return TIMER_NO_EVENT; +} + +static int parse_timer_result(const char *s) +{ + char *end; + long d; + + d = strtol(s + RESULT_PREFIX_LEN, &end, 10); + if (end == s + RESULT_PREFIX_LEN) + return -1; + + return d; +} + +/* + * This test triggers the timer and counts ticks at the same time. The amount + * of the timer trigger calls should be equal to the amount of ticks received. + */ +TEST_F(timer_f, utimer) { + char command[64]; + pthread_t ticking_thread; + int total_ticks = 0; + FILE *rfp; + char *buf = malloc(TIMER_OUTPUT_BUF_LEN); + + ASSERT_NE(buf, NULL); + + /* The timeout should be the ticks interval * count of ticks + some delta */ + sprintf(command, "./global-timer %d %d %d", SNDRV_TIMER_GLOBAL_UDRIVEN, + self->utimer_info->id, TICKS_COUNT * TIMER_FREQ_SEC + TICKS_RECORDING_DELTA); + + rfp = popen(command, "r"); + while (fgets(buf, TIMER_OUTPUT_BUF_LEN, rfp)) { + buf[TIMER_OUTPUT_BUF_LEN - 1] = 0; + switch (parse_timer_output(buf)) { + case TIMER_APP_STARTED: + /* global-timer waits for timer to trigger, so start the ticking thread */ + pthread_create(&ticking_thread, NULL, ticking_func, + &self->utimer_fd); + break; + case TIMER_APP_RESULT: + total_ticks = parse_timer_result(buf); + break; + } + } + pthread_join(ticking_thread, NULL); + ASSERT_EQ(total_ticks, TICKS_COUNT); + pclose(rfp); +} + +TEST_HARNESS_MAIN -- 2.34.1 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH 4/4] selftests: ALSA: Cover userspace-driven timers with test 2024-07-26 7:47 ` [PATCH 4/4] selftests: ALSA: Cover userspace-driven timers with test Ivan Orlov @ 2024-07-28 6:10 ` kernel test robot 0 siblings, 0 replies; 3+ messages in thread From: kernel test robot @ 2024-07-28 6:10 UTC (permalink / raw) To: Ivan Orlov, perex, tiwai, corbet, broonie, shuah Cc: oe-kbuild-all, Ivan Orlov, linux-kselftest, linux-doc, linux-sound, linux-kernel, aholzinger Hi Ivan, kernel test robot noticed the following build warnings: [auto build test WARNING on tiwai-sound/for-next] [also build test WARNING on tiwai-sound/for-linus linus/master v6.10 next-20240726] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Ivan-Orlov/ALSA-aloop-Allow-using-global-timers/20240726-155158 base: https://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git for-next patch link: https://lore.kernel.org/r/20240726074750.626671-5-ivan.orlov0322%40gmail.com patch subject: [PATCH 4/4] selftests: ALSA: Cover userspace-driven timers with test :::::: branch date: 2 days ago :::::: commit date: 2 days ago compiler: clang version 18.1.5 (https://github.com/llvm/llvm-project 617a15a9eac96088ae5e9134248d8236e34b91b1) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240728/202407281359.vMYdESrT-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/r/202407281359.vMYdESrT-lkp@intel.com/ All warnings (new ones prefixed by >>): >> utimer-test.c:73:1: warning: non-void function does not return a value [-Wreturn-type] 73 | } | ^ >> utimer-test.c:117:11: warning: enumeration value 'TIMER_NO_EVENT' not handled in switch [-Wswitch] 117 | switch (parse_timer_output(buf)) { | ^~~~~~~~~~~~~~~~~~~~~~~ 2 warnings generated. vim +73 tools/testing/selftests/alsa/utimer-test.c 5cf58530fa628b Ivan Orlov 2024-07-26 62 5cf58530fa628b Ivan Orlov 2024-07-26 63 static void *ticking_func(void *data) 5cf58530fa628b Ivan Orlov 2024-07-26 64 { 5cf58530fa628b Ivan Orlov 2024-07-26 65 int i; 5cf58530fa628b Ivan Orlov 2024-07-26 66 int *fd = (int *)data; 5cf58530fa628b Ivan Orlov 2024-07-26 67 5cf58530fa628b Ivan Orlov 2024-07-26 68 for (i = 0; i < TICKS_COUNT; i++) { 5cf58530fa628b Ivan Orlov 2024-07-26 69 /* Well, trigger the timer! */ 5cf58530fa628b Ivan Orlov 2024-07-26 70 ioctl(*fd, SNDRV_TIMER_IOCTL_TRIGGER, NULL); 5cf58530fa628b Ivan Orlov 2024-07-26 71 sleep(TIMER_FREQ_SEC); 5cf58530fa628b Ivan Orlov 2024-07-26 72 } 5cf58530fa628b Ivan Orlov 2024-07-26 @73 } 5cf58530fa628b Ivan Orlov 2024-07-26 74 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2024-07-28 6:10 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-07-28 5:40 [PATCH 4/4] selftests: ALSA: Cover userspace-driven timers with test kernel test robot -- strict thread matches above, loose matches on Subject: below -- 2024-07-26 7:47 [PATCH 0/4] Introduce userspace-driven ALSA timers Ivan Orlov 2024-07-26 7:47 ` [PATCH 4/4] selftests: ALSA: Cover userspace-driven timers with test Ivan Orlov 2024-07-28 6:10 ` kernel test robot
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.