ALSA: usx2y: Fix shmem initialization
authorTakashi Iwai <tiwai@suse.de>
Mon, 17 May 2021 13:15:42 +0000 (15:15 +0200)
committerTakashi Iwai <tiwai@suse.de>
Mon, 17 May 2021 14:05:10 +0000 (16:05 +0200)
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: Takashi Iwai <tiwai@suse.de>
sound/usb/usx2y/usX2Yhwdep.c
sound/usb/usx2y/usbusx2y.c

index ec7e3be..c29da03 100644 (file)
@@ -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;
 }
index d2e1cf1..09ead00 100644 (file)
@@ -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"");