[alsa-devel] [PATCH] alsa: support module on-demand loading for seq and timer
From: Kay Sievers kay.sievers@vrfy.org Subject: alsa: support module on-demand loading for seq and timer
If CONFIG_SND_DYNAMIC_MINORS is used, assign /dev/snd/seq and /dev/snd/timer the usual static minors, and export specific module aliases to generate udev module on-demand loading instructions:
$ cat /lib/modules/$(uname -r)/modules.devname # Device nodes to trigger on-demand module loading. microcode cpu/microcode c10:184 fuse fuse c10:229 ppp_generic ppp c108:0 tun net/tun c10:200 uinput uinput c10:223 dm_mod mapper/control c10:236 snd_timer snd/timer c116:33 snd_seq snd/seq c116:1
The last two lines instruct udev to create device nodes, even when the modules are not loaded at that time.
As soon as userspace accesses any of these nodes, the in-kernel module-loader will load the module, and the device can be used.
The header file minor calculation needed to be simplified to make __stringify() (supports only two indirections) in the MODULE_ALIAS macro work.
This is part of systemd's effort to get rid of unconditional module load instructions and needless init scripts.
Cc: Lennart Poettering lennart@poettering.net Signed-off-by: Kay Sievers kay.sievers@vrfy.org ---
diff --git a/include/sound/minors.h b/include/sound/minors.h index a81798a..8f76420 100644 --- a/include/sound/minors.h +++ b/include/sound/minors.h @@ -31,8 +31,8 @@ /* these minors can still be used for autoloading devices (/dev/aload*) */ #define SNDRV_MINOR_CONTROL 0 /* 0 */ #define SNDRV_MINOR_GLOBAL 1 /* 1 */ -#define SNDRV_MINOR_SEQUENCER (SNDRV_MINOR_GLOBAL + 0 * 32) -#define SNDRV_MINOR_TIMER (SNDRV_MINOR_GLOBAL + 1 * 32) +#define SNDRV_MINOR_SEQUENCER 1 /* SNDRV_MINOR_GLOBAL + 0 * 32 */ +#define SNDRV_MINOR_TIMER 33 /* SNDRV_MINOR_GLOBAL + 1 * 32 */
#ifndef CONFIG_SND_DYNAMIC_MINORS /* 2 - 3 (reserved) */ diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c index bf09a5a..119fddb6 100644 --- a/sound/core/seq/seq.c +++ b/sound/core/seq/seq.c @@ -32,6 +32,7 @@ #include "seq_timer.h" #include "seq_system.h" #include "seq_info.h" +#include <sound/minors.h> #include <sound/seq_device.h>
#if defined(CONFIG_SND_SEQ_DUMMY_MODULE) @@ -73,6 +74,9 @@ MODULE_PARM_DESC(seq_default_timer_subdevice, "The default timer subdevice numbe module_param(seq_default_timer_resolution, int, 0644); MODULE_PARM_DESC(seq_default_timer_resolution, "The default timer resolution in Hz.");
+MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_SEQUENCER); +MODULE_ALIAS("devname:snd/seq"); + /* * INIT PART */ diff --git a/sound/core/sound.c b/sound/core/sound.c index 66691fe..1c7a3ef 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c @@ -188,14 +188,22 @@ static const struct file_operations snd_fops = };
#ifdef CONFIG_SND_DYNAMIC_MINORS -static int snd_find_free_minor(void) +static int snd_find_free_minor(int type) { int minor;
+ /* static minors for module auto loading */ + if (type == SNDRV_DEVICE_TYPE_SEQUENCER) + return SNDRV_MINOR_SEQUENCER; + if (type == SNDRV_DEVICE_TYPE_TIMER) + return SNDRV_MINOR_TIMER; + for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) { - /* skip minors still used statically for autoloading devices */ - if (SNDRV_MINOR_DEVICE(minor) == SNDRV_MINOR_CONTROL || - minor == SNDRV_MINOR_SEQUENCER) + /* skip static minors still used for module auto loading */ + if (SNDRV_MINOR_DEVICE(minor) == SNDRV_MINOR_CONTROL) + continue; + if (minor == SNDRV_MINOR_SEQUENCER || + minor == SNDRV_MINOR_TIMER) continue; if (!snd_minors[minor]) return minor; @@ -269,7 +277,7 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev, preg->private_data = private_data; mutex_lock(&sound_mutex); #ifdef CONFIG_SND_DYNAMIC_MINORS - minor = snd_find_free_minor(); + minor = snd_find_free_minor(type); #else minor = snd_kernel_minor(type, card, dev); if (minor >= 0 && snd_minors[minor]) diff --git a/sound/core/timer.c b/sound/core/timer.c index 13afb60..17df52a 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -52,6 +52,9 @@ MODULE_PARM_DESC(timer_limit, "Maximum global timers in system."); module_param(timer_tstamp_monotonic, int, 0444); MODULE_PARM_DESC(timer_tstamp_monotonic, "Use posix monotonic clock source for timestamps (default).");
+MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_TIMER); +MODULE_ALIAS("devname:snd/timer"); + struct snd_timer_user { struct snd_timer_instance *timeri; int tread; /* enhanced read with timestamps and events */
Kay Sievers wrote:
If CONFIG_SND_DYNAMIC_MINORS is used, assign /dev/snd/seq and /dev/snd/timer the usual static minors, and export specific module aliases to generate udev module on-demand loading instructions: ... As soon as userspace accesses any of these nodes, the in-kernel module-loader will load the module, and the device can be used.
Is this another mechanism than sound/core/sound.c::autoload_device()? Because in this case, that function can go away.
+++ b/sound/core/seq/seq.c +MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_SEQUENCER); +MODULE_ALIAS("devname:snd/seq");
The device name that alsa-lib tries to use for autoloading is actually /dev/aloadSEQ.
This is part of systemd's effort to get rid of unconditional module load instructions and needless init scripts.
So you're going to add the entries for card driver autoloading (/dev/aloadC*), too?
Regards, Clemens
On Tue, Nov 23, 2010 at 16:45, Clemens Ladisch clemens@ladisch.de wrote:
Kay Sievers wrote:
If CONFIG_SND_DYNAMIC_MINORS is used, assign /dev/snd/seq and /dev/snd/timer the usual static minors, and export specific module aliases to generate udev module on-demand loading instructions: ... As soon as userspace accesses any of these nodes, the in-kernel module-loader will load the module, and the device can be used.
Is this another mechanism than sound/core/sound.c::autoload_device()? Because in this case, that function can go away.
No, the kernel needs to match the minor to the module name to load.
+++ b/sound/core/seq/seq.c +MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_SEQUENCER); +MODULE_ALIAS("devname:snd/seq");
The device name that alsa-lib tries to use for autoloading is actually /dev/aloadSEQ.
That might need to be changed then, if something depends on that, but nothing ever tries to open /dev/snd/seq. These names will never exist on any usual system where CONFIG_SND_DYNAMIC_MINORS is used.
This is part of systemd's effort to get rid of unconditional module load instructions and needless init scripts.
So you're going to add the entries for card driver autoloading (/dev/aloadC*), too?
No, we only ever handle single-instance devices with a single fixed dev_t, not ones with an arbitrary number of device instances.
Card drivers are loaded by hardware matches today, not on-demand, and not by an card number.
There are no configured numbered module aliases for sound cards anymore, that can't work with today's setups.
Kay
Kay Sievers wrote:
On Tue, Nov 23, 2010 at 16:45, Clemens Ladisch clemens@ladisch.de wrote:
Kay Sievers wrote:
+MODULE_ALIAS("devname:snd/seq");
The device name that alsa-lib tries to use for autoloading is actually /dev/aloadSEQ.
That might need to be changed then, if something depends on that, but nothing ever tries to open /dev/snd/seq.
No, alsa-lib pokes /dev/aloadSEQ only if opening /dev/snd/seq has failed. (Something historical, I believe.)
So you're going to add the entries for card driver autoloading (/dev/aloadC*), too?
No, we only ever handle single-instance devices with a single fixed dev_t, not ones with an arbitrary number of device instances.
Card drivers are loaded by hardware matches today, not on-demand, and not by an card number.
There are card drivers without matching hardware (such as MIDI over a serial port, or virtual devices).
There are no configured numbered module aliases for sound cards anymore, that can't work with today's setups.
Just that it cannot work with systemd doesn't imply that nobody still uses it or that it could be dropped without regards for backward compatibility.
Anyway, this patch is independent of ALSA's old autoload code. Applied.
Regards, Clemens
On Tue, Nov 23, 2010 at 17:56, Clemens Ladisch clemens@ladisch.de wrote:
Kay Sievers wrote:
On Tue, Nov 23, 2010 at 16:45, Clemens Ladisch clemens@ladisch.de wrote:
Kay Sievers wrote:
+MODULE_ALIAS("devname:snd/seq");
The device name that alsa-lib tries to use for autoloading is actually /dev/aloadSEQ.
That might need to be changed then, if something depends on that, but nothing ever tries to open /dev/snd/seq.
No, alsa-lib pokes /dev/aloadSEQ only if opening /dev/snd/seq has failed. (Something historical, I believe.)
Yeah, that can probably removed some day. No system with dynamic minors, which needs devtmpfs/udev, can really have these nodes. And static /dev systems have the real node anyway.
So you're going to add the entries for card driver autoloading (/dev/aloadC*), too?
No, we only ever handle single-instance devices with a single fixed dev_t, not ones with an arbitrary number of device instances.
Card drivers are loaded by hardware matches today, not on-demand, and not by an card number.
There are card drivers without matching hardware (such as MIDI over a serial port, or virtual devices).
Right, but they require manual configuration anyway, which is a problem we can not solve here in such simple way. :)
This is only about the common case, making hotplug of sound hardware work and on-demand setup work, without having init scripts that load modules unconditionally, and things like this.
There are no configured numbered module aliases for sound cards anymore, that can't work with today's setups.
Just that it cannot work with systemd doesn't imply that nobody still uses it or that it could be dropped without regards for backward compatibility.
Right, the stuff might be in use in old setups.
It has nothing really to do with systemd, it's just nothing that recent systems do. They all support dynamic reconfiguration without prior setup of numbered lists of aliases, that get out-of-sync pretty fast in today's hotplug world.
Anyway, this patch is independent of ALSA's old autoload code. Applied.
Cool.
Many thanks, Kay
participants (2)
-
Clemens Ladisch
-
Kay Sievers