Memory leak killing spree, mostly bus_dma(9) related.

This commit is contained in:
Ariff Abdullah 2007-03-21 18:17:03 +00:00
parent e406f5a1c9
commit 703c934a48
6 changed files with 68 additions and 46 deletions

View File

@ -1111,27 +1111,30 @@ atiixp_release_resource(struct atiixp_info *sc)
}
if (sc->ih) {
bus_teardown_intr(sc->dev, sc->irq, sc->ih);
sc->ih = 0;
sc->ih = NULL;
}
if (sc->reg) {
bus_release_resource(sc->dev, sc->regtype, sc->regid, sc->reg);
sc->reg = 0;
sc->reg = NULL;
}
if (sc->irq) {
bus_release_resource(sc->dev, SYS_RES_IRQ, sc->irqid, sc->irq);
sc->irq = 0;
sc->irq = NULL;
}
if (sc->parent_dmat) {
bus_dma_tag_destroy(sc->parent_dmat);
sc->parent_dmat = 0;
sc->parent_dmat = NULL;
}
if (sc->sgd_dmamap) {
if (sc->sgd_dmamap)
bus_dmamap_unload(sc->sgd_dmat, sc->sgd_dmamap);
sc->sgd_dmamap = 0;
if (sc->sgd_table) {
bus_dmamem_free(sc->sgd_dmat, sc->sgd_table, sc->sgd_dmamap);
sc->sgd_table = NULL;
}
sc->sgd_dmamap = NULL;
if (sc->sgd_dmat) {
bus_dma_tag_destroy(sc->sgd_dmat);
sc->sgd_dmat = 0;
sc->sgd_dmat = NULL;
}
if (sc->lock) {
snd_mtxfree(sc->lock);

View File

@ -1210,7 +1210,7 @@ hdac_dma_alloc(struct hdac_softc *sc, struct hdac_dma *dma, bus_size_t size)
if (result != 0) {
device_printf(sc->dev, "%s: bus_dma_tag_create failed (%x)\n",
__func__, result);
goto fail;
goto hdac_dma_alloc_fail;
}
/*
@ -1221,7 +1221,7 @@ hdac_dma_alloc(struct hdac_softc *sc, struct hdac_dma *dma, bus_size_t size)
if (result != 0) {
device_printf(sc->dev, "%s: bus_dmamem_alloc failed (%x)\n",
__func__, result);
goto fail;
goto hdac_dma_alloc_fail;
}
/*
@ -1231,19 +1231,19 @@ hdac_dma_alloc(struct hdac_softc *sc, struct hdac_dma *dma, bus_size_t size)
(void *)dma->dma_vaddr, size, hdac_dma_cb, (void *)dma,
BUS_DMA_NOWAIT);
if (result != 0 || dma->dma_paddr == 0) {
if (result == 0)
result = ENOMEM;
device_printf(sc->dev, "%s: bus_dmamem_load failed (%x)\n",
__func__, result);
goto fail;
goto hdac_dma_alloc_fail;
}
hdac_dma_attr((vm_offset_t)dma->dma_vaddr, size, HDAC_DMA_UNCACHEABLE);
dma->dma_size = size;
return (0);
fail:
if (dma->dma_map != NULL)
bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map);
if (dma->dma_tag != NULL)
bus_dma_tag_destroy(dma->dma_tag);
hdac_dma_alloc_fail:
hdac_dma_free(dma);
return (result);
}
@ -1257,16 +1257,25 @@ hdac_dma_alloc(struct hdac_softc *sc, struct hdac_dma *dma, bus_size_t size)
static void
hdac_dma_free(struct hdac_dma *dma)
{
if (dma->dma_tag != NULL) {
if (dma->dma_map != NULL) {
/* Flush caches */
bus_dmamap_sync(dma->dma_tag, dma->dma_map,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
hdac_dma_attr((vm_offset_t)dma->dma_vaddr, dma->dma_size,
HDAC_DMA_WRITEBACK);
bus_dmamap_unload(dma->dma_tag, dma->dma_map);
bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map);
bus_dma_tag_destroy(dma->dma_tag);
}
if (dma->dma_vaddr != NULL) {
if (dma->dma_size > 0)
hdac_dma_attr((vm_offset_t)dma->dma_vaddr,
dma->dma_size, HDAC_DMA_WRITEBACK);
bus_dmamem_free(dma->dma_tag, dma->dma_vaddr, dma->dma_map);
dma->dma_vaddr = NULL;
}
dma->dma_map = NULL;
if (dma->dma_tag != NULL) {
bus_dma_tag_destroy(dma->dma_tag);
dma->dma_tag = NULL;
}
dma->dma_size = 0;
}
/****************************************************************************
@ -1330,7 +1339,7 @@ hdac_irq_alloc(struct hdac_softc *sc)
if (irq->irq_res == NULL) {
device_printf(sc->dev, "%s: Unable to allocate irq\n",
__func__);
goto fail;
goto hdac_irq_alloc_fail;
}
result = snd_setup_intr(sc->dev, irq->irq_res, INTR_MPSAFE,
hdac_intr_handler, sc, &irq->irq_handle);
@ -1338,12 +1347,12 @@ hdac_irq_alloc(struct hdac_softc *sc)
device_printf(sc->dev,
"%s: Unable to setup interrupt handler (%x)\n",
__func__, result);
goto fail;
goto hdac_irq_alloc_fail;
}
return (0);
fail:
hdac_irq_alloc_fail:
hdac_irq_free(sc);
return (ENXIO);
@ -2655,8 +2664,9 @@ hdac_channel_free(kobj_t obj, void *data)
{
struct hdac_chan *ch = data;
hdac_dma_attr((vm_offset_t)ch->b->buf, sndbuf_getmaxsize(ch->b),
HDAC_DMA_WRITEBACK);
if (ch != NULL && ch->b != NULL && ch->b->buf != NULL)
hdac_dma_attr((vm_offset_t)ch->b->buf, sndbuf_getmaxsize(ch->b),
HDAC_DMA_WRITEBACK);
return (1);
}

View File

@ -1040,6 +1040,8 @@ ich_pci_attach(device_t dev)
sc->nabmbarid, sc->nabmbar);
if (sc->dtmap)
bus_dmamap_unload(sc->dmat, sc->dtmap);
if (sc->dtbl)
bus_dmamem_free(sc->dmat, sc->dtbl, sc->dtmap);
if (sc->dmat)
bus_dma_tag_destroy(sc->dmat);
if (sc->ich_lock)
@ -1064,6 +1066,7 @@ ich_pci_detach(device_t dev)
bus_release_resource(dev, sc->regtype, sc->nambarid, sc->nambar);
bus_release_resource(dev, sc->regtype, sc->nabmbarid, sc->nabmbar);
bus_dmamap_unload(sc->dmat, sc->dtmap);
bus_dmamem_free(sc->dmat, sc->dtbl, sc->dtmap);
bus_dma_tag_destroy(sc->dmat);
snd_mtxfree(sc->ich_lock);
free(sc, M_DEVBUF);

View File

@ -1373,6 +1373,8 @@ via_attach(device_t dev)
bus_dma_tag_destroy(via->parent_dmat);
if (via->sgd_dmamap)
bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap);
if (via->sgd_table)
bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap);
if (via->sgd_dmat)
bus_dma_tag_destroy(via->sgd_dmat);
if (via->lock)
@ -1398,6 +1400,7 @@ via_detach(device_t dev)
bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq);
bus_dma_tag_destroy(via->parent_dmat);
bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap);
bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap);
bus_dma_tag_destroy(via->sgd_dmat);
snd_mtxfree(via->lock);
free(via, M_DEVBUF);

View File

@ -610,6 +610,7 @@ via_attach(device_t dev)
if (via->irq) bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq);
if (via->parent_dmat) bus_dma_tag_destroy(via->parent_dmat);
if (via->sgd_dmamap) bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap);
if (via->sgd_table) bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap);
if (via->sgd_dmat) bus_dma_tag_destroy(via->sgd_dmat);
if (via->lock) snd_mtxfree(via->lock);
if (via) free(via, M_DEVBUF);
@ -632,6 +633,7 @@ via_detach(device_t dev)
bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq);
bus_dma_tag_destroy(via->parent_dmat);
bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap);
bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap);
bus_dma_tag_destroy(via->sgd_dmat);
snd_mtxfree(via->lock);
free(via, M_DEVBUF);

View File

@ -46,12 +46,7 @@ sndbuf_create(device_t dev, char *drv, char *desc, struct pcm_channel *channel)
void
sndbuf_destroy(struct snd_dbuf *b)
{
if (b->tmpbuf)
free(b->tmpbuf, M_DEVBUF);
if (b->shadbuf)
free(b->shadbuf, M_DEVBUF);
if (!(b->flags & SNDBUF_F_MANAGED) && b->buf)
free(b->buf, M_DEVBUF);
sndbuf_free(b);
free(b, M_DEVBUF);
}
@ -93,24 +88,27 @@ sndbuf_alloc(struct snd_dbuf *b, bus_dma_tag_t dmatag, unsigned int size)
b->buf_addr = 0;
b->flags |= SNDBUF_F_MANAGED;
if (bus_dmamem_alloc(b->dmatag, (void **)&b->buf, BUS_DMA_NOWAIT,
&b->dmamap))
&b->dmamap)) {
sndbuf_free(b);
return (ENOMEM);
}
if (bus_dmamap_load(b->dmatag, b->dmamap, b->buf, b->maxsize,
sndbuf_setmap, b, 0) != 0 || b->buf_addr == 0) {
bus_dmamem_free(b->dmatag, b->buf, b->dmamap);
b->dmamap = NULL;
sndbuf_free(b);
return (ENOMEM);
}
ret = sndbuf_resize(b, 2, b->maxsize / 2);
if (ret != 0)
sndbuf_free(b);
return (ret);
}
int
sndbuf_setup(struct snd_dbuf *b, void *buf, unsigned int size)
{
b->flags &= ~SNDBUF_F_MANAGED;
if (buf)
b->flags |= SNDBUF_F_MANAGED;
b->buf = buf;
@ -124,23 +122,26 @@ sndbuf_free(struct snd_dbuf *b)
{
if (b->tmpbuf)
free(b->tmpbuf, M_DEVBUF);
b->tmpbuf = NULL;
if (b->shadbuf)
free(b->shadbuf, M_DEVBUF);
if (b->buf) {
if (b->flags & SNDBUF_F_MANAGED) {
if (b->dmamap)
bus_dmamap_unload(b->dmatag, b->dmamap);
if (b->dmatag)
bus_dmamem_free(b->dmatag, b->buf, b->dmamap);
} else
free(b->buf, M_DEVBUF);
}
b->tmpbuf = NULL;
b->shadbuf = NULL;
b->sl = 0;
if (!(b->flags & SNDBUF_F_MANAGED) && b->buf)
free(b->buf, M_DEVBUF);
if (b->dmamap)
bus_dmamap_unload(b->dmatag, b->dmamap);
if (b->dmamap && b->buf)
bus_dmamem_free(b->dmatag, b->buf, b->dmamap);
b->dmamap = NULL;
b->buf = NULL;
b->sl = 0;
b->dmatag = NULL;
b->dmamap = NULL;
}
int