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

> 
> Index: ami.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/ic/ami.c,v
> retrieving revision 1.199
> diff -u -p -r1.199 ami.c
> --- ami.c     9 Jan 2010 23:15:06 -0000       1.199
> +++ ami.c     30 Jan 2010 23:49:09 -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,33 @@ 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 nowait)
>  {
>       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 |
> +         nowait ? M_NOWAIT : 0);
>       if (am == NULL)
>               return (NULL);
>  
>       am->am_size = size;
> +     nowait = 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)
> +         nowait | 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, nowait) != 0)
>               goto destroy;
>  
>       if (bus_dmamem_map(sc->sc_dmat, &am->am_seg, nsegs, size, &am->am_kva,
> -         BUS_DMA_NOWAIT) != 0)
> +         nowait) != 0)
>               goto free;
>  
>       if (bus_dmamap_load(sc->sc_dmat, am->am_map, am->am_kva, size, NULL,
> -         BUS_DMA_NOWAIT) != 0)
> +         nowait) != 0)
>               goto unmap;
>  
>       memset(am->am_kva, 0, size);
> @@ -337,7 +339,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, 1);
>       if (sc->sc_ccbmem_am == NULL) {
>               printf(": unable to allocate ccb dmamem\n");
>               goto free_ccbs;
> @@ -413,14 +416,14 @@ ami_attach(struct ami_softc *sc)
>       paddr_t pa;
>       int s;
>  
> -     am = ami_allocmem(sc, NBPG);
> +     am = ami_allocmem(sc, NBPG, 1);
>       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), 1);
>       if (sc->sc_mbox_am == NULL) {
>               printf(": unable to allocate mbox\n");
>               goto free_idata;
> @@ -1914,7 +1917,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, 0)) == NULL) {
>                       error = ENOMEM;
>                       goto memerr;
>               }

Reply via email to