Skip to content

Commit

Permalink
ALSA: seq-oss: Initialize MIDI clients asynchronously
Browse files Browse the repository at this point in the history
We've got bug reports that the module loading stuck on Debian system
with 3.10 kernel.  The debugging session revealed that the initial
registration of OSS sequencer clients stuck at module loading time,
which involves again with request_module() at the init phase.  This is
triggered only by special --install stuff Debian is using, but it's
still not good to have such loops.

As a workaround, call the registration part asynchronously.  This is a
better approach irrespective of the hang fix, in anyway.

Reported-and-tested-by: Philipp Matthias Hahn <pmhahn@pmhahn.de>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
Takashi Iwai committed Jul 17, 2013
1 parent d52392b commit 256ca9c
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 4 deletions.
16 changes: 13 additions & 3 deletions sound/core/seq/oss/seq_oss_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <linux/export.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/workqueue.h>

/*
* common variables
Expand Down Expand Up @@ -60,6 +61,14 @@ static void free_devinfo(void *private);
#define call_ctl(type,rec) snd_seq_kernel_client_ctl(system_client, type, rec)


/* call snd_seq_oss_midi_lookup_ports() asynchronously */
static void async_call_lookup_ports(struct work_struct *work)
{
snd_seq_oss_midi_lookup_ports(system_client);
}

static DECLARE_WORK(async_lookup_work, async_call_lookup_ports);

/*
* create sequencer client for OSS sequencer
*/
Expand All @@ -85,9 +94,6 @@ snd_seq_oss_create_client(void)
system_client = rc;
debug_printk(("new client = %d\n", rc));

/* look up midi devices */
snd_seq_oss_midi_lookup_ports(system_client);

/* create annoucement receiver port */
memset(port, 0, sizeof(*port));
strcpy(port->name, "Receiver");
Expand Down Expand Up @@ -115,6 +121,9 @@ snd_seq_oss_create_client(void)
}
rc = 0;

/* look up midi devices */
schedule_work(&async_lookup_work);

__error:
kfree(port);
return rc;
Expand Down Expand Up @@ -160,6 +169,7 @@ receive_announce(struct snd_seq_event *ev, int direct, void *private, int atomic
int
snd_seq_oss_delete_client(void)
{
cancel_work_sync(&async_lookup_work);
if (system_client >= 0)
snd_seq_delete_kernel_client(system_client);

Expand Down
2 changes: 1 addition & 1 deletion sound/core/seq/oss/seq_oss_midi.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ static int send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev,
* look up the existing ports
* this looks a very exhausting job.
*/
int __init
int
snd_seq_oss_midi_lookup_ports(int client)
{
struct snd_seq_client_info *clinfo;
Expand Down

0 comments on commit 256ca9c

Please sign in to comment.