Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ALSA: pcsp: Replace tasklet with work

The tasklet is an old API that should be deprecated, usually can be
converted to another decent API. This patch replaces the usage of
tasklet in pcsp driver with a simple work. In pcsp driver, a global
tasklet is used for offloading the period-elapse handling in the
hrtimer callback (introduced in commit 96c7d478efad "ALSA: pcsp - Fix
locking messes in snd-pcsp"). It can be achieved gracefully with a
work queued in the high-prio system workqueue.

This also changes tasklet_kill() with cancel_work_sync() in the
sync_stop callback, which is anyway better to assure canceling the
pending tasks.

Link: https://lore.kernel.org/r/20200903104131.21097-2-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>

+5 -7
+5 -7
sound/drivers/pcsp/pcsp_lib.c
··· 23 23 #define DMIX_WANTS_S16 1 24 24 25 25 /* 26 - * Call snd_pcm_period_elapsed in a tasklet 26 + * Call snd_pcm_period_elapsed in a work 27 27 * This avoids spinlock messes and long-running irq contexts 28 28 */ 29 - static void pcsp_call_pcm_elapsed(unsigned long priv) 29 + static void pcsp_call_pcm_elapsed(struct work_struct *work) 30 30 { 31 31 if (atomic_read(&pcsp_chip.timer_active)) { 32 32 struct snd_pcm_substream *substream; ··· 36 36 } 37 37 } 38 38 39 - static DECLARE_TASKLET_OLD(pcsp_pcm_tasklet, pcsp_call_pcm_elapsed); 39 + static DECLARE_WORK(pcsp_pcm_work, pcsp_call_pcm_elapsed); 40 40 41 41 /* write the port and returns the next expire time in ns; 42 42 * called at the trigger-start and in hrtimer callback ··· 119 119 if (periods_elapsed) { 120 120 chip->period_ptr += periods_elapsed * period_bytes; 121 121 chip->period_ptr %= buffer_bytes; 122 + queue_work(system_highpri_wq, &pcsp_pcm_work); 122 123 } 123 124 spin_unlock_irqrestore(&chip->substream_lock, flags); 124 - 125 - if (periods_elapsed) 126 - tasklet_schedule(&pcsp_pcm_tasklet); 127 125 } 128 126 129 127 enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) ··· 194 196 pcsp_stop_playing(chip); 195 197 local_irq_enable(); 196 198 hrtimer_cancel(&chip->timer); 197 - tasklet_kill(&pcsp_pcm_tasklet); 199 + cancel_work_sync(&pcsp_pcm_work); 198 200 } 199 201 200 202 static int snd_pcsp_playback_close(struct snd_pcm_substream *substream)