Date: Tue, 05 May 2009 02:09:30 -0400 From: Jimmie James <jimmiejaz@gmail.com> To: freebsd-current@freebsd.org, john@baldwin.cx Subject: pci regression: "panic: resource_list_alloc: resource entry is busy" Message-ID: <49FFD81A.5040501@gmail.com> References: 200903041011.24606.jhb@freebsd.org
next in thread | raw e-mail | index | archive | help
Why is this affecting 7.2-STABLE? Does anyone test anything before a release anymore? This doesn't apply to 7.2: atching file vga_pci.c using Plan A... Hunk #1 failed at 42. Hunk #2 succeeded at 118 (offset -20 lines). Hunk #3 succeeded at 146 (offset -20 lines). 1 out of 3 hunks failed--saving rejects to vga_pci.c.rej Hmm... Ignoring the trailing garbage. done > John Baldwin wrote: > Probably at some point the agp and drm drivers for Intel will be merged which > would fix this, but this patch should help for now. We used to be leaking > a small portion of KVA due to this problem before. > > --- //depot/vendor/freebsd/src/sys/dev/pci/vga_pci.c 2008/09/19 19:15:30 > +++ //depot/user/jhb/acpipci/dev/pci/vga_pci.c 2009/03/04 15:32:08 > @@ -42,12 +42,20 @@ > #include <sys/bus.h> > #include <sys/kernel.h> > #include <sys/module.h> > +#include <sys/rman.h> > +#include <sys/systm.h> > > #include <dev/pci/pcireg.h> > #include <dev/pci/pcivar.h> > > +struct vga_resource { > + struct resource *vr_res; > + int vr_refs; > +}; > + > struct vga_pci_softc { > device_t vga_msi_child; /* Child driver using MSI. */ > + struct vga_resource vga_res[PCIR_MAX_BAR_0 + 1]; > }; > > static int > @@ -130,7 +138,27 @@ > vga_pci_alloc_resource(device_t dev, device_t child, int type, int *rid, > u_long start, u_long end, u_long count, u_int flags) > { > + struct vga_pci_softc *sc; > + int bar; > > + switch (type) { > + case SYS_RES_MEMORY: > + case SYS_RES_IOPORT: > + /* > + * For BARs, we cache the resource so that we only allocate it > + * from the PCI bus once. > + */ > + bar = PCI_RID2BAR(*rid); > + if (bar < 0 || bar > PCIR_MAX_BAR_0) > + return (NULL); > + sc = device_get_softc(dev); > + if (sc->vga_res[bar].vr_res == NULL) > + sc->vga_res[bar].vr_res = bus_alloc_resource(dev, type, > + rid, start, end, count, flags); > + if (sc->vga_res[bar].vr_res != NULL) > + sc->vga_res[bar].vr_refs++; > + return (sc->vga_res[bar].vr_res); > + } > return (bus_alloc_resource(dev, type, rid, start, end, count, flags)); > } > > @@ -138,6 +166,37 @@ > vga_pci_release_resource(device_t dev, device_t child, int type, int rid, > struct resource *r) > { > + struct vga_pci_softc *sc; > + int bar, error; > + > + switch (type) { > + case SYS_RES_MEMORY: > + case SYS_RES_IOPORT: > + /* > + * For BARs, we release the resource from the PCI bus > + * when the last child reference goes away. > + */ > + bar = PCI_RID2BAR(rid); > + if (bar < 0 || bar > PCIR_MAX_BAR_0) > + return (EINVAL); > + sc = device_get_softc(dev); > + if (sc->vga_res[bar].vr_res == NULL) > + return (EINVAL); > + KASSERT(sc->vga_res[bar].vr_res == r, > + ("vga_pci resource mismatch")); > + if (sc->vga_res[bar].vr_refs > 1) { > + sc->vga_res[bar].vr_refs--; > + return (0); > + } > + KASSERT(sc->vga_res[bar].vr_refs > 0, > + ("vga_pci resource reference count underflow")); > + error = bus_release_resource(dev, type, rid, r); > + if (error == 0) { > + sc->vga_res[bar].vr_res = NULL; > + sc->vga_res[bar].vr_refs = 0; > + } > + return (error); > + } > > return (bus_release_resource(dev, type, rid, r)); > } > -- Over the years I've come to regard you as people I've met.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?49FFD81A.5040501>