On Sun, Jan 31, 2010 at 01:18:59PM +0000, Stuart Henderson wrote: > On 2010/01/31 09:50, David Gwynne wrote: > > On Sun, Jan 31, 2010 at 09:41:14AM +1000, David Gwynne wrote: > > > pmap_enter in this situation should fail, not panic. the error would be > > > handled properly as the stack unwinds up to ami_allocmem. > > > > > > i can change ami_allocmem to take a NOWAIT etc as an argument rather than > > > just assume it, so callers with process context (like the sensor refresh > > > shown below) can sleep waiting for mappings. > > > > here's such a change. > > > > i havent even compiled this, let alone tested it. > > no problems noticed here so far with > > ami0 at pci3 dev 14 function 0 "Symbios Logic MegaRAID SATA 4x/8x" rev 0x07: > apic 2 int 4 (irq 9) > ami0: LSI 3008, 32b, FW 814B, BIOS vH431, 128MB RAM > ami0: 1 channels, 0 FC loops, 1 logical drives > scsibus0 at ami0: 40 targets > scsibus1 at ami0: 16 targets
I know I'm kind of the peanut gallery in sys/dev, but we've already got named flags which mean something to malloc(9), and it increases legibility to use them, IMO, so I've modified dlg's diff to use M_{,NO}WAIT where appropriate. I have no ami hardware, so I can't test this, but it does compile :-\ Index: ami.c =================================================================== RCS file: /cvs/src/sys/dev/ic/ami.c,v retrieving revision 1.198 diff -u -p -r1.198 ami.c --- ami.c 6 Dec 2009 12:31:10 -0000 1.198 +++ ami.c 31 Jan 2010 13:29:55 -0000 @@ -124,7 +124,7 @@ void ami_write(struct ami_softc *, bus_ void ami_copyhds(struct ami_softc *, const u_int32_t *, const u_int8_t *, const u_int8_t *); -struct ami_mem *ami_allocmem(struct ami_softc *, size_t); +struct ami_mem *ami_allocmem(struct ami_softc *, size_t, int); void ami_freemem(struct ami_softc *, struct ami_mem *); int ami_alloc_ccbs(struct ami_softc *, int); @@ -256,31 +256,32 @@ ami_write(struct ami_softc *sc, bus_size } struct ami_mem * -ami_allocmem(struct ami_softc *sc, size_t size) +ami_allocmem(struct ami_softc *sc, size_t size, int wait) { struct ami_mem *am; int nsegs; - am = malloc(sizeof(struct ami_mem), M_DEVBUF, M_NOWAIT|M_ZERO); + am = malloc(sizeof(struct ami_mem), M_DEVBUF, M_ZERO | wait); if (am == NULL) return (NULL); am->am_size = size; + wait = (wait == M_NOWAIT ? BUS_DMA_NOWAIT : 0); if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, - BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &am->am_map) != 0) + wait | BUS_DMA_ALLOCNOW, &am->am_map) != 0) goto amfree; if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &am->am_seg, 1, - &nsegs, BUS_DMA_NOWAIT) != 0) + &nsegs, wait) != 0) goto destroy; if (bus_dmamem_map(sc->sc_dmat, &am->am_seg, nsegs, size, &am->am_kva, - BUS_DMA_NOWAIT) != 0) + wait) != 0) goto free; if (bus_dmamap_load(sc->sc_dmat, am->am_map, am->am_kva, size, NULL, - BUS_DMA_NOWAIT) != 0) + wait) != 0) goto unmap; memset(am->am_kva, 0, size); @@ -337,7 +338,8 @@ ami_alloc_ccbs(struct ami_softc *sc, int return (1); } - sc->sc_ccbmem_am = ami_allocmem(sc, sizeof(struct ami_ccbmem) * nccbs); + sc->sc_ccbmem_am = ami_allocmem(sc, + sizeof(struct ami_ccbmem) * nccbs, M_NOWAIT); if (sc->sc_ccbmem_am == NULL) { printf(": unable to allocate ccb dmamem\n"); goto free_ccbs; @@ -413,14 +415,14 @@ ami_attach(struct ami_softc *sc) paddr_t pa; int s; - am = ami_allocmem(sc, NBPG); + am = ami_allocmem(sc, NBPG, M_NOWAIT); if (am == NULL) { printf(": unable to allocate init data\n"); return (1); } pa = htole32(AMIMEM_DVA(am)); - sc->sc_mbox_am = ami_allocmem(sc, sizeof(struct ami_iocmd)); + sc->sc_mbox_am = ami_allocmem(sc, sizeof(struct ami_iocmd), M_NOWAIT); if (sc->sc_mbox_am == NULL) { printf(": unable to allocate mbox\n"); goto free_idata; @@ -1928,7 +1930,7 @@ ami_mgmt(struct ami_softc *sc, u_int8_t } if (size) { - if ((am = ami_allocmem(sc, size)) == NULL) { + if ((am = ami_allocmem(sc, size, M_WAITOK)) == NULL) { error = ENOMEM; goto memerr; }