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;
                }

Reply via email to