mirror of https://gitee.com/openkylin/linux.git
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: Takashi Iwai <tiwai@suse.de> Acked-by: Felipe Balbi <balbi@kernel.org> Signed-off-by: Davidlohr Bueso <dbueso@suse.de> Link: https://lore.kernel.org/r/20210111042855.73289-1-dave@stgolabs.net Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
0c0a20f6da
commit
8653d71ce3
|
@ -87,7 +87,7 @@ struct f_midi {
|
|||
struct snd_rawmidi_substream *out_substream[MAX_PORTS];
|
||||
|
||||
unsigned long out_triggered;
|
||||
struct tasklet_struct tasklet;
|
||||
struct work_struct work;
|
||||
unsigned int in_ports;
|
||||
unsigned int out_ports;
|
||||
int index;
|
||||
|
@ -698,9 +698,11 @@ static void f_midi_transmit(struct f_midi *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);
|
||||
}
|
||||
|
||||
|
@ -737,7 +739,7 @@ static void f_midi_in_trigger(struct snd_rawmidi_substream *substream, int up)
|
|||
VDBG(midi, "%s() %d\n", __func__, up);
|
||||
midi->in_ports_array[substream->number].active = 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)
|
||||
|
@ -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;
|
||||
|
||||
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);
|
||||
if (status < 0)
|
||||
goto fail_register;
|
||||
|
|
Loading…
Reference in New Issue