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.

Merge tag 'sound-4.5-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
"This update contains again a few more fixes for ALSA core stuff
although it's no longer high flux: two race fixes in sequencer and one
PCM race fix for non-atomic PCM ops.

In addition, HD-audio gained a similar fix for race at reloading the
driver"

* tag 'sound-4.5-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
ALSA: pcm: Fix rwsem deadlock for non-atomic PCM stream
ALSA: seq: Fix double port list deletion
ALSA: hda - Cancel probe work instead of flush at remove
ALSA: seq: Fix leak of pool buffer at concurrent writes

+33 -13
+14 -2
sound/core/pcm_native.c
··· 74 74 static DEFINE_RWLOCK(snd_pcm_link_rwlock); 75 75 static DECLARE_RWSEM(snd_pcm_link_rwsem); 76 76 77 + /* Writer in rwsem may block readers even during its waiting in queue, 78 + * and this may lead to a deadlock when the code path takes read sem 79 + * twice (e.g. one in snd_pcm_action_nonatomic() and another in 80 + * snd_pcm_stream_lock()). As a (suboptimal) workaround, let writer to 81 + * spin until it gets the lock. 82 + */ 83 + static inline void down_write_nonblock(struct rw_semaphore *lock) 84 + { 85 + while (!down_write_trylock(lock)) 86 + cond_resched(); 87 + } 88 + 77 89 /** 78 90 * snd_pcm_stream_lock - Lock the PCM stream 79 91 * @substream: PCM substream ··· 1825 1813 res = -ENOMEM; 1826 1814 goto _nolock; 1827 1815 } 1828 - down_write(&snd_pcm_link_rwsem); 1816 + down_write_nonblock(&snd_pcm_link_rwsem); 1829 1817 write_lock_irq(&snd_pcm_link_rwlock); 1830 1818 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN || 1831 1819 substream->runtime->status->state != substream1->runtime->status->state || ··· 1872 1860 struct snd_pcm_substream *s; 1873 1861 int res = 0; 1874 1862 1875 - down_write(&snd_pcm_link_rwsem); 1863 + down_write_nonblock(&snd_pcm_link_rwsem); 1876 1864 write_lock_irq(&snd_pcm_link_rwlock); 1877 1865 if (!snd_pcm_stream_linked(substream)) { 1878 1866 res = -EALREADY;
+9 -4
sound/core/seq/seq_memory.c
··· 383 383 384 384 if (snd_BUG_ON(!pool)) 385 385 return -EINVAL; 386 - if (pool->ptr) /* should be atomic? */ 387 - return 0; 388 386 389 - pool->ptr = vmalloc(sizeof(struct snd_seq_event_cell) * pool->size); 390 - if (!pool->ptr) 387 + cellptr = vmalloc(sizeof(struct snd_seq_event_cell) * pool->size); 388 + if (!cellptr) 391 389 return -ENOMEM; 392 390 393 391 /* add new cells to the free cell list */ 394 392 spin_lock_irqsave(&pool->lock, flags); 393 + if (pool->ptr) { 394 + spin_unlock_irqrestore(&pool->lock, flags); 395 + vfree(cellptr); 396 + return 0; 397 + } 398 + 399 + pool->ptr = cellptr; 395 400 pool->free = NULL; 396 401 397 402 for (cell = 0; cell < pool->size; cell++) {
+8 -5
sound/core/seq/seq_ports.c
··· 535 535 bool is_src, bool ack) 536 536 { 537 537 struct snd_seq_port_subs_info *grp; 538 + struct list_head *list; 539 + bool empty; 538 540 539 541 grp = is_src ? &port->c_src : &port->c_dest; 542 + list = is_src ? &subs->src_list : &subs->dest_list; 540 543 down_write(&grp->list_mutex); 541 544 write_lock_irq(&grp->list_lock); 542 - if (is_src) 543 - list_del(&subs->src_list); 544 - else 545 - list_del(&subs->dest_list); 545 + empty = list_empty(list); 546 + if (!empty) 547 + list_del_init(list); 546 548 grp->exclusive = 0; 547 549 write_unlock_irq(&grp->list_lock); 548 550 up_write(&grp->list_mutex); 549 551 550 - unsubscribe_port(client, port, grp, &subs->info, ack); 552 + if (!empty) 553 + unsubscribe_port(client, port, grp, &subs->info, ack); 551 554 } 552 555 553 556 /* connect two ports */
+2 -2
sound/pci/hda/hda_intel.c
··· 2168 2168 struct hda_intel *hda; 2169 2169 2170 2170 if (card) { 2171 - /* flush the pending probing work */ 2171 + /* cancel the pending probing work */ 2172 2172 chip = card->private_data; 2173 2173 hda = container_of(chip, struct hda_intel, chip); 2174 - flush_work(&hda->probe_work); 2174 + cancel_work_sync(&hda->probe_work); 2175 2175 2176 2176 snd_card_free(card); 2177 2177 }