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 ec7e3beed4f9b3dadc0a19ee8a451b005f503668..c29da0341bc5b3f1a002c1b9f1f92cc34b9c6462 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 d2e1cf1635216fa4a193d66f72e5cf07f3ea5c51..09ead00e395e6dd298b3653830c27bf95d64e17c 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"");