Message ID | 1374657129-11947-1-git-send-email-luis.henriques@canonical.com |
---|---|
State | New |
Headers | show |
At Wed, 24 Jul 2013 10:12:09 +0100, Luis Henriques wrote: > > This is a note to let you know that I have just added a patch titled > > ALSA: seq-oss: Initialize MIDI clients asynchronously > > to the linux-3.5.y-queue branch of the 3.5.y.z extended stable tree > which can be found at: > > http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.5.y-queue > > If you, or anyone else, feels it should not be added to this tree, please > reply to this email. > > For more information about the 3.5.y.z tree, see > https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable This problem was reported to appear since 3.10, so no need to patch older kernels, although it's not that bad to apply it. Takashi > > Thanks. > -Luis > > ------ > > >From 84d0ac92d9bc06b1a5a6df8b12c44e2ab47249df Mon Sep 17 00:00:00 2001 > From: Takashi Iwai <tiwai@suse.de> > Date: Tue, 16 Jul 2013 12:17:49 +0200 > Subject: [PATCH] ALSA: seq-oss: Initialize MIDI clients asynchronously > > commit 256ca9c3ad5013ff8a8f165e5a82fab437628c8e upstream. > > 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> > Signed-off-by: Takashi Iwai <tiwai@suse.de> > Signed-off-by: Luis Henriques <luis.henriques@canonical.com> > --- > sound/core/seq/oss/seq_oss_init.c | 16 +++++++++++++--- > sound/core/seq/oss/seq_oss_midi.c | 2 +- > 2 files changed, 14 insertions(+), 4 deletions(-) > > diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c > index e3cb46f..b3f39b5 100644 > --- a/sound/core/seq/oss/seq_oss_init.c > +++ b/sound/core/seq/oss/seq_oss_init.c > @@ -31,6 +31,7 @@ > #include <linux/export.h> > #include <linux/moduleparam.h> > #include <linux/slab.h> > +#include <linux/workqueue.h> > > /* > * common variables > @@ -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 > */ > @@ -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"); > @@ -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; > @@ -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); > > diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c > index 677dc84..862d8489 100644 > --- a/sound/core/seq/oss/seq_oss_midi.c > +++ b/sound/core/seq/oss/seq_oss_midi.c > @@ -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; > -- > 1.8.1.2 >
Takashi Iwai <tiwai@suse.de> writes: > At Wed, 24 Jul 2013 10:12:09 +0100, > Luis Henriques wrote: >> >> This is a note to let you know that I have just added a patch titled >> >> ALSA: seq-oss: Initialize MIDI clients asynchronously >> >> to the linux-3.5.y-queue branch of the 3.5.y.z extended stable tree >> which can be found at: >> >> http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.5.y-queue >> >> If you, or anyone else, feels it should not be added to this tree, please >> reply to this email. >> >> For more information about the 3.5.y.z tree, see >> https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable > > This problem was reported to appear since 3.10, so no need to patch > older kernels, although it's not that bad to apply it. > > > Takashi > Thank you for your feedback. I'll drop this patch from the 3.5 queue. Cheers,
diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c index e3cb46f..b3f39b5 100644 --- a/sound/core/seq/oss/seq_oss_init.c +++ b/sound/core/seq/oss/seq_oss_init.c @@ -31,6 +31,7 @@ #include <linux/export.h> #include <linux/moduleparam.h> #include <linux/slab.h> +#include <linux/workqueue.h> /* * common variables @@ -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 */ @@ -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"); @@ -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; @@ -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); diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c index 677dc84..862d8489 100644 --- a/sound/core/seq/oss/seq_oss_midi.c +++ b/sound/core/seq/oss/seq_oss_midi.c @@ -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;