Commit 64a06f19 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: usx2y: Fix shmem initialization

Currently us428ctls_shmem pages are allocated dynamically upon the
mmap call, but this is quite racy.  Since the shared memory itself is
mandatory for the mmap, let's allocate it at the beginning of the card
initialization.  Also, fix the initialization of the wait queue, too.

Link: https://lore.kernel.org/r/20210517131545.27252-9-tiwai@suse.de


Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent c1f24841
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -60,14 +60,6 @@ static int snd_us428ctls_mmap(struct snd_hwdep *hw, struct file *filp, struct vm
		return -EINVAL;
	}

	if (!us428->us428ctls_sharedmem) {
		init_waitqueue_head(&us428->us428ctls_wait_queue_head);
		us428->us428ctls_sharedmem = alloc_pages_exact(US428_SHAREDMEM_PAGES, GFP_KERNEL);
		if (!us428->us428ctls_sharedmem)
			return -ENOMEM;
		memset(us428->us428ctls_sharedmem, -1, US428_SHAREDMEM_PAGES);
		us428->us428ctls_sharedmem->ctl_snapshot_last = -2;
	}
	area->vm_ops = &us428ctls_vm_ops;
	area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
	area->vm_private_data = hw->private_data;
@@ -232,18 +224,26 @@ int usx2y_hwdep_new(struct snd_card *card, struct usb_device *device)
{
	int err;
	struct snd_hwdep *hw;
	struct usx2ydev	*us428 = usx2y(card);

	err = snd_hwdep_new(card, SND_USX2Y_LOADER_ID, 0, &hw);
	if (err < 0)
		return err;

	hw->iface = SNDRV_HWDEP_IFACE_USX2Y;
	hw->private_data = usx2y(card);
	hw->private_data = us428;
	hw->ops.dsp_status = snd_usx2y_hwdep_dsp_status;
	hw->ops.dsp_load = snd_usx2y_hwdep_dsp_load;
	hw->ops.mmap = snd_us428ctls_mmap;
	hw->ops.poll = snd_us428ctls_poll;
	hw->exclusive = 1;
	sprintf(hw->name, "/dev/bus/usb/%03d/%03d", device->bus->busnum, device->devnum);

	us428->us428ctls_sharedmem = alloc_pages_exact(US428_SHAREDMEM_PAGES, GFP_KERNEL);
	if (!us428->us428ctls_sharedmem)
		return -ENOMEM;
	memset(us428->us428ctls_sharedmem, -1, US428_SHAREDMEM_PAGES);
	us428->us428ctls_sharedmem->ctl_snapshot_last = -2;

	return 0;
}
+1 −0
Original line number Diff line number Diff line
@@ -375,6 +375,7 @@ static int usx2y_create_card(struct usb_device *device,
	card->private_free = snd_usx2y_card_private_free;
	usx2y(card)->dev = device;
	init_waitqueue_head(&usx2y(card)->prepare_wait_queue);
	init_waitqueue_head(&usx2y(card)->us428ctls_wait_queue_head);
	mutex_init(&usx2y(card)->pcm_mutex);
	INIT_LIST_HEAD(&usx2y(card)->midi_list);
	strcpy(card->driver, "USB "NAME_ALLCAPS"");