Commit 8653d71c authored by Davidlohr Bueso's avatar Davidlohr Bueso Committed by Greg Kroah-Hartman

usb/gadget: f_midi: Replace tasklet with work

Currently a tasklet is used to transmit input substream buffer
data. However, tasklets have long been deprecated as being too
heavy on the system by running in irq context - and this is not
a performance critical path. If a higher priority process wants
to run, it must wait for the tasklet to finish before doing so.

Deferring work to a workqueue and executing in process context
should be fine considering the callback already does
f_midi_do_transmit() under the transmit_lock and thus changes in
semantics are ok regarding concurrency - tasklets being serialized
against itself.

Cc: Takashi Iwai <tiwai@suse.de>
Reviewed-by: default avatarTakashi Iwai <tiwai@suse.de>
Acked-by: default avatarFelipe Balbi <balbi@kernel.org>
Signed-off-by: default avatarDavidlohr Bueso <dbueso@suse.de>
Link: https://lore.kernel.org/r/20210111042855.73289-1-dave@stgolabs.netSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 0c0a20f6
...@@ -87,7 +87,7 @@ struct f_midi { ...@@ -87,7 +87,7 @@ struct f_midi {
struct snd_rawmidi_substream *out_substream[MAX_PORTS]; struct snd_rawmidi_substream *out_substream[MAX_PORTS];
unsigned long out_triggered; unsigned long out_triggered;
struct tasklet_struct tasklet; struct work_struct work;
unsigned int in_ports; unsigned int in_ports;
unsigned int out_ports; unsigned int out_ports;
int index; int index;
...@@ -698,9 +698,11 @@ static void f_midi_transmit(struct f_midi *midi) ...@@ -698,9 +698,11 @@ static void f_midi_transmit(struct f_midi *midi)
f_midi_drop_out_substreams(midi); f_midi_drop_out_substreams(midi);
} }
static void f_midi_in_tasklet(struct tasklet_struct *t) static void f_midi_in_work(struct work_struct *work)
{ {
struct f_midi *midi = from_tasklet(midi, t, tasklet); struct f_midi *midi;
midi = container_of(work, struct f_midi, work);
f_midi_transmit(midi); f_midi_transmit(midi);
} }
...@@ -737,7 +739,7 @@ static void f_midi_in_trigger(struct snd_rawmidi_substream *substream, int up) ...@@ -737,7 +739,7 @@ static void f_midi_in_trigger(struct snd_rawmidi_substream *substream, int up)
VDBG(midi, "%s() %d\n", __func__, up); VDBG(midi, "%s() %d\n", __func__, up);
midi->in_ports_array[substream->number].active = up; midi->in_ports_array[substream->number].active = up;
if (up) if (up)
tasklet_hi_schedule(&midi->tasklet); queue_work(system_highpri_wq, &midi->work);
} }
static int f_midi_out_open(struct snd_rawmidi_substream *substream) static int f_midi_out_open(struct snd_rawmidi_substream *substream)
...@@ -875,7 +877,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) ...@@ -875,7 +877,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
int status, n, jack = 1, i = 0, endpoint_descriptor_index = 0; int status, n, jack = 1, i = 0, endpoint_descriptor_index = 0;
midi->gadget = cdev->gadget; midi->gadget = cdev->gadget;
tasklet_setup(&midi->tasklet, f_midi_in_tasklet); INIT_WORK(&midi->work, f_midi_in_work);
status = f_midi_register_card(midi); status = f_midi_register_card(midi);
if (status < 0) if (status < 0)
goto fail_register; goto fail_register;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment