At Wed, 31 Oct 2007 02:19:36 +0100, Roel Kluin wrote: > > I can confirm that it builds. > -- > Free after memory allocation failure > > Signed-off-by: Roel Kluin <12o3l@xxxxxxxxxx> Thanks for the patch. But, this fix isn't correct because snd_emu10k1_free() is always called in the error path. snd_emu10k1_free() calls free_pm_buffer() that eventually releases all buffers allocated via alloc_pm_buffer() (and *_alloc_pm_buffer() from it). Takashi > --- > diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c > index 97c41d7..88f8fb3 100644 > --- a/sound/pci/emu10k1/emu10k1_main.c > +++ b/sound/pci/emu10k1/emu10k1_main.c > @@ -1894,25 +1894,31 @@ static unsigned char saved_regs_audigy[] = { > static int __devinit alloc_pm_buffer(struct snd_emu10k1 *emu) > { > int size; > > size = ARRAY_SIZE(saved_regs); > if (emu->audigy) > size += ARRAY_SIZE(saved_regs_audigy); > emu->saved_ptr = vmalloc(4 * NUM_G * size); > if (! emu->saved_ptr) > return -ENOMEM; > - if (snd_emu10k1_efx_alloc_pm_buffer(emu) < 0) > + > + if (snd_emu10k1_efx_alloc_pm_buffer(emu) < 0) { > + vfree(emu->saved_ptr); > return -ENOMEM; > + } > + > if (emu->card_capabilities->ca0151_chip && > - snd_p16v_alloc_pm_buffer(emu) < 0) > + snd_p16v_alloc_pm_buffer(emu) < 0) { > + vfree(emu->saved_ptr); > return -ENOMEM; > + } > return 0; > } > > static void free_pm_buffer(struct snd_emu10k1 *emu) > { > vfree(emu->saved_ptr); > snd_emu10k1_efx_free_pm_buffer(emu); > if (emu->card_capabilities->ca0151_chip) > snd_p16v_free_pm_buffer(emu); > } > diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c > index 9bf1cd5..a31ad02 100644 > --- a/sound/pci/emu10k1/emufx.c > +++ b/sound/pci/emu10k1/emufx.c > @@ -2634,30 +2634,43 @@ int __devinit snd_emu10k1_fx8010_new(struct snd_emu10k1 *emu, int device, struct > > #ifdef CONFIG_PM > int __devinit snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu) > { > int len; > > len = emu->audigy ? 0x200 : 0x100; > emu->saved_gpr = kmalloc(len * 4, GFP_KERNEL); > if (! emu->saved_gpr) > return -ENOMEM; > + > len = emu->audigy ? 0x100 : 0xa0; > emu->tram_val_saved = kmalloc(len * 4, GFP_KERNEL); > + if (! emu->tram_val_saved) > + goto free_gpr; > + > emu->tram_addr_saved = kmalloc(len * 4, GFP_KERNEL); > - if (! emu->tram_val_saved || ! emu->tram_addr_saved) > - return -ENOMEM; > + if (! emu->tram_addr_saved) > + goto free_tram_val; > + > len = emu->audigy ? 2 * 1024 : 2 * 512; > emu->saved_icode = vmalloc(len * 4); > if (! emu->saved_icode) > - return -ENOMEM; > + goto free_tram_addr; > + > return 0; > +free_gpr: > + kfree(emu->saved_gpr); > +free_tram_val: > + kfree(emu->tram_val_saved); > +free_tram_addr: > + kfree(emu->tram_addr_saved); > + return -ENOMEM; > } > > void snd_emu10k1_efx_free_pm_buffer(struct snd_emu10k1 *emu) > { > kfree(emu->saved_gpr); > kfree(emu->tram_val_saved); > kfree(emu->tram_addr_saved); > vfree(emu->saved_icode); > } > > _______________________________________________ > Alsa-devel mailing list > Alsa-devel@xxxxxxxxxxxxxxxx > http://mailman.alsa-project.org/mailman/listinfo/alsa-devel > _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel