Message ID | 20170831142117.4131-1-o-takashi@sakamocchi.jp (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Thu, 31 Aug 2017 16:21:17 +0200, Takashi Sakamoto wrote: > > Hi, > > On Aug 31 2017 21:23, Anna-Maria Gleixner wrote: > > From: Thomas Gleixner <tglx@linutronix.de> > > > > The tasklet is used to defer the execution of snd_pcm_period_elapsed() to > > the softirq context. Using the CLOCK_MONOTONIC_SOFT base invokes the timer > > callback in softirq context as well which renders the tasklet useless. > > > > Signed-off-by: Thomas Gleixner <tglx@linutronix.de> > > Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de> > > Cc: Jaroslav Kysela <perex@perex.cz> > > Cc: Takashi Iwai <tiwai@suse.com> > > Cc: Takashi Sakamoto <o-takashi@sakamocchi.jp> > > Cc: alsa-devel@alsa-project.org > > --- > > sound/drivers/dummy.c | 16 +++------------- > > 1 file changed, 3 insertions(+), 13 deletions(-) > > I prefer this patch as long as this driver can still receive callbacks > from hrtimer subsystem. > > Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> > > Unfortunately, I have too poor machine to compile whole kernel now, thus > didn't do any tests, sorry. > > I note that ALSA pcsp driver uses a combination of hrtimer/tasklet for the > same purpose. I think we can simplify it, too. Please refer to a patch in > the end of this message. (But not tested yet for the above reason...) The pcsp is a bit special. It's really high frequent irq calls for controlling the beep on/off, thus offloading the whole isn't good. thanks, Takashi
diff --git a/sound/drivers/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c index 0dd3f46eb03e..8fac38b81c4f 100644 --- a/sound/drivers/pcsp/pcsp.c +++ b/sound/drivers/pcsp/pcsp.c @@ -100,7 +100,7 @@ static int snd_card_pcsp_probe(int devnum, struct device *dev) if (devnum != 0) return -EINVAL; - hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC_SOFT, HRTIMER_MODE_REL); pcsp_chip.timer.function = pcsp_do_timer; err = snd_card_new(dev, index, id, THIS_MODULE, 0, &card); diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c index 2f5a35f38ce1..d2b67463ddd3 100644 --- a/sound/drivers/pcsp/pcsp_lib.c +++ b/sound/drivers/pcsp/pcsp_lib.c @@ -21,22 +21,6 @@ MODULE_PARM_DESC(nforce_wa, "Apply NForce chipset workaround " #define DMIX_WANTS_S16 1 -/* - * Call snd_pcm_period_elapsed in a tasklet - * This avoids spinlock messes and long-running irq contexts - */ -static void pcsp_call_pcm_elapsed(unsigned long priv) -{ - if (atomic_read(&pcsp_chip.timer_active)) { - struct snd_pcm_substream *substream; - substream = pcsp_chip.playback_substream; - if (substream) - snd_pcm_period_elapsed(substream); - } -} - -static DECLARE_TASKLET(pcsp_pcm_tasklet, pcsp_call_pcm_elapsed, 0); - /* write the port and returns the next expire time in ns; * called at the trigger-start and in hrtimer callback */ @@ -121,8 +105,11 @@ static void pcsp_pointer_update(struct snd_pcsp *chip) } spin_unlock_irqrestore(&chip->substream_lock, flags); - if (periods_elapsed) - tasklet_schedule(&pcsp_pcm_tasklet); + if (!periods_elapsed) + return; + + if (atomic_read(&pcsp_chip.timer_active)) + snd_pcm_period_elapsed(substream); } enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) @@ -195,7 +182,6 @@ void pcsp_sync_stop(struct snd_pcsp *chip) pcsp_stop_playing(chip); local_irq_enable(); hrtimer_cancel(&chip->timer); - tasklet_kill(&pcsp_pcm_tasklet); } static int snd_pcsp_playback_close(struct snd_pcm_substream *substream)