-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 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 > _at__at_ -42,12 +42,20 _at__at_ > #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 > _at__at_ -130,7 +138,27 _at__at_ > 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)); > } > > _at__at_ -138,6 +166,37 _at__at_ > 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)); > } > This works perfectly, thanks! :-) Michael -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (FreeBSD) iEYEARECAAYFAkmu0d8ACgkQQv9rrgRC1JKdQwCgzcOUZGUkAH+ynHyU8eyheGBJ pagAnRKOf6s/9KaMewqDRtUc32CXtxpw =SQHc -----END PGP SIGNATURE-----Received on Wed Mar 04 2009 - 18:09:26 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:43 UTC