[PATCH] ALSA: pcsp: code optimization for hrtimer in software IRQ context

From: Takashi Sakamoto
Date: Thu Aug 31 2017 - 09:52:33 EST


In a development period for v4.14, code refactoring was done for hrtimer
subsystem. This enables to receive callbacks from hrtimer in software IRQ
context.

Currently, ALSA pcsp driver uses hrtimer callback to handle period elapse
of PCM buffer and actual calculation of pointer position is done in
software IRQ context of tasklet. This can be simplified to the introduced
hrtimer in software IRQ context.

This commit applies an optimization for the above reason.

Signed-off-by: Takashi Sakamoto <o-takashi@xxxxxxxxxxxxx>
---
sound/drivers/pcsp/pcsp.c | 2 +-
sound/drivers/pcsp/pcsp_lib.c | 24 +++++-------------------
2 files changed, 6 insertions(+), 20 deletions(-)

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)
--
2.11.0