On Mon, 11 Apr 2022 11:06:09 +0200, Takashi Iwai wrote:
On Mon, 11 Apr 2022 10:49:53 +0200, Zheyu Ma wrote:
On Mon, Apr 11, 2022 at 3:41 PM Takashi Iwai tiwai@suse.de wrote:
On Sun, 10 Apr 2022 11:13:55 +0200, Zheyu Ma wrote:
Hello,
I found a bug in echoaudio.c. When the driver fails at the function snd_echo_create(), it should release resources requested before, otherwise we will get the following warning:
[ 3.262866] remove_proc_entry: removing non-empty directory 'irq/21', leaking at least 'snd_indigodj' [ 3.263577] WARNING: CPU: 3 PID: 261 at fs/proc/generic.c:717 remove_proc_entry+0x389/0x3f0 [ 3.267098] RIP: 0010:remove_proc_entry+0x389/0x3f0 [ 3.269976] Call Trace: [ 3.269979] <TASK> [ 3.269988] unregister_irq_proc+0x14c/0x170 [ 3.269997] irq_free_descs+0x94/0xe0 [ 3.270004] mp_unmap_irq+0xb6/0x100 [ 3.270011] acpi_unregister_gsi_ioapic+0x27/0x40 [ 3.270017] acpi_pci_irq_disable+0x1d3/0x320 [ 3.270025] pci_disable_device+0x1ad/0x380 [ 3.270034] pcim_release+0x566/0x6d0 [ 3.270046] devres_release_all+0x1f1/0x2c0 [ 3.270057] really_probe+0xe0/0x920
Could you try the patch below?
The following patch works for me, the previous warning disappears, thank you. But I got another error, I have no idea about it.
OK, that's bad, it's basically the destructor order problem. Could you try the patch below instead of the previous one?
Sorry, the below one instead.
Takashi
--- --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c @@ -1889,13 +1889,20 @@ static void snd_echo_free(struct snd_card *card) if (chip->comm_page) rest_in_peace(chip);
- if (chip->irq >= 0) - free_irq(chip->irq, chip); - /* release chip data */ free_firmware_cache(chip); }
+static void do_free_irq(void *p) +{ + struct echoaudio *chip = p; + + if (chip->irq >= 0) { + free_irq(chip->irq, chip); + chip->irq = -1; + } +} + /* <--snd_echo_probe() */ static int snd_echo_create(struct snd_card *card, struct pci_dev *pci) @@ -1936,6 +1943,9 @@ static int snd_echo_create(struct snd_card *card, return -ENOMEM; }
+ err = devm_add_action(card->dev, do_free_irq, chip); + if (err < 0) + return err; if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED, KBUILD_MODNAME, chip)) { dev_err(chip->card->dev, "cannot grab irq\n"); @@ -1946,8 +1956,6 @@ static int snd_echo_create(struct snd_card *card, dev_dbg(card->dev, "pci=%p irq=%d subdev=%04x Init hardware...\n", chip->pci, chip->irq, chip->pci->subsystem_device);
- card->private_free = snd_echo_free; - /* Create the DSP comm page - this is the area of memory used for most of the communication with the DSP, which accesses it via bus mastering */ chip->commpage_dma_buf = @@ -1957,6 +1965,7 @@ static int snd_echo_create(struct snd_card *card, return -ENOMEM; chip->comm_page_phys = chip->commpage_dma_buf->addr; chip->comm_page = (struct comm_page *)chip->commpage_dma_buf->area; + card->private_free = snd_echo_free;
err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device); if (err >= 0)