Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 May 2009 16:56:02 +0300
From:      Kostik Belousov <kostikbel@gmail.com>
To:        Gavin Atkinson <gavin@freebsd.org>
Cc:        freebsd-stable@freebsd.org, Guido Falsi <mad@madpilot.net>, jhb@freebsd.org
Subject:   Re: [PANIC] recent 7.2-STABLE when probing drm
Message-ID:  <20090505135602.GO1948@deviant.kiev.zoral.com.ua>
In-Reply-To: <1241526927.47323.5.camel@buffy.york.ac.uk>
References:  <20090505110624.GA83487@megatron.madpilot.net> <1241521951.47323.3.camel@buffy.york.ac.uk> <20090505121247.GN1948@deviant.kiev.zoral.com.ua> <1241526927.47323.5.camel@buffy.york.ac.uk>

next in thread | previous in thread | raw e-mail | index | archive | help

--f0PSjARDFl/vfYT5
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Tue, May 05, 2009 at 01:35:27PM +0100, Gavin Atkinson wrote:
> On Tue, 2009-05-05 at 15:12 +0300, Kostik Belousov wrote:
> > On Tue, May 05, 2009 at 12:12:31PM +0100, Gavin Atkinson wrote:
> > > On Tue, 2009-05-05 at 13:06 +0200, Guido Falsi wrote:
> > > > Hi!
> > > >=20
> > > > I'm using FreeBSD/i386 stable on a HP DC7800 PC.
> > > >=20
> > > > It has an Intel Q35 graphic chip.
> > > >=20
> > > > After upgrading to a recent stable I experienced a pani on boot, ju=
st
> > > > after probing drm.
> > > >=20
> > > > I investigated a little and found out that reverting the file
> > > >=20
> > > > src/sys/dev/pci/pci.c
> > > >=20
> > > > to rev. 1.355.2.9 (SVN Rev 190092) solves the crash.
> > > >=20
> > > > I could not investigatte urther right away, but some regression was
> > > > introduced with this rev.
> > > >=20
> > > > Is any more information needed?
> > >=20
> > > When it panics, can you please type "bt" (assuming you have the debug=
ger
> > > compiled in) and show the output?
> >=20
> > I have this too. I have dump too.
> >=20
> > drm0: <Intel i945GM> on vgapci0
> > panic: resource_list_alloc: resource entry is busy
> > KDB: stack backtrace:
> > db_trace_self_wrapper(c07214ff,c2b46764,c04c928f,c071f823,c078b080,...)=
 at 0xc044df46 =3D db_trace_self_wrapper+0x26
> > kdb_backtrace(c071f823,c078b080,c07211b1,c2b46770,c2b46770,...) at 0xc0=
4f41f9 =3D kdb_backtrace+0x29
> > panic(c07211b1,3,10,c04e9484,c2e37000,...) at 0xc04c928f =3D panic+0xaf
> > resource_list_alloc(c2cffb04,c2d00a80,c2d00c80,3,c2d2a1fc,...) at 0xc04=
f0c06 =3D resource_list_alloc+0xd6
> > pci_alloc_resource(c2d00a80,c2d00c80,3,c2d2a1fc,0,ffffffff,1,4) at 0xc0=
45a2d1 =3D pci_alloc_resource+0x581
> > bus_alloc_resource(c2d00c80,3,c2d2a1fc,0,ffffffff,...) at 0xc04f0a8c =
=3D bus_alloc_resource+0x7c
> > vga_pci_alloc_resource(c2d00c80,c2cfa080,3,c2d2a1fc,0,ffffffff,1,4) at =
0xc04600ab =3D vga_pci_alloc_resource+0x3b
> [...]
>=20
> I wonder if r189373 also needs merging?

Thanks for the hint. We need both r183095 and r189373, but the
actual bugfix is r189373, as you rightly pointed out. Below is the patch
that works for me.

Index: dev/pci/vga_pci.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- dev/pci/vga_pci.c	(revision 191816)
+++ dev/pci/vga_pci.c	(working copy)
@@ -42,10 +42,22 @@
 #include <sys/bus.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/systm.h>
=20
 #include <dev/pci/pcireg.h>
 #include <dev/pci/pcivar.h>
=20
+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
 vga_pci_probe(device_t dev)
 {
@@ -110,7 +122,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;
=20
+	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 =3D PCI_RID2BAR(*rid);
+		if (bar < 0 || bar > PCIR_MAX_BAR_0)
+			return (NULL);
+		sc =3D device_get_softc(dev);
+		if (sc->vga_res[bar].vr_res =3D=3D NULL)
+			sc->vga_res[bar].vr_res =3D bus_alloc_resource(dev, type,
+			    rid, start, end, count, flags);
+		if (sc->vga_res[bar].vr_res !=3D 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));
 }
=20
@@ -118,7 +150,38 @@
 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;
=20
+	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 =3D PCI_RID2BAR(rid);
+		if (bar < 0 || bar > PCIR_MAX_BAR_0)
+			return (EINVAL);
+		sc =3D device_get_softc(dev);
+		if (sc->vga_res[bar].vr_res =3D=3D NULL)
+			return (EINVAL);
+		KASSERT(sc->vga_res[bar].vr_res =3D=3D 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 =3D bus_release_resource(dev, type, rid, r);
+		if (error =3D=3D 0) {
+			sc->vga_res[bar].vr_res =3D NULL;
+			sc->vga_res[bar].vr_refs =3D 0;
+		}
+		return (error);
+	}
+
 	return (bus_release_resource(dev, type, rid, r));
 }
=20
@@ -176,6 +239,21 @@
 }
=20
 static int
+vga_pci_get_vpd_ident(device_t dev, device_t child, const char **identptr)
+{
+
+	return (pci_get_vpd_ident(dev, identptr));
+}
+
+static int
+vga_pci_get_vpd_readonly(device_t dev, device_t child, const char *kw,
+    const char **vptr)
+{
+
+	return (pci_get_vpd_readonly(dev, kw, vptr));
+}
+
+static int
 vga_pci_set_powerstate(device_t dev, device_t child, int state)
 {
=20
@@ -210,6 +288,77 @@
 	return (pci_find_extcap(dev, capability, capreg));
 }
=20
+static int
+vga_pci_alloc_msi(device_t dev, device_t child, int *count)
+{
+	struct vga_pci_softc *sc;
+	int error;
+
+	sc =3D device_get_softc(dev);
+	if (sc->vga_msi_child !=3D NULL)
+		return (EBUSY);
+	error =3D pci_alloc_msi(dev, count);
+	if (error =3D=3D 0)
+		sc->vga_msi_child =3D child;
+	return (error);
+}
+
+static int
+vga_pci_alloc_msix(device_t dev, device_t child, int *count)
+{
+	struct vga_pci_softc *sc;
+	int error;
+
+	sc =3D device_get_softc(dev);
+	if (sc->vga_msi_child !=3D NULL)
+		return (EBUSY);
+	error =3D pci_alloc_msix(dev, count);
+	if (error =3D=3D 0)
+		sc->vga_msi_child =3D child;
+	return (error);
+}
+
+static int
+vga_pci_remap_msix(device_t dev, device_t child, int count,
+    const u_int *vectors)
+{
+	struct vga_pci_softc *sc;
+
+	sc =3D device_get_softc(dev);
+	if (sc->vga_msi_child !=3D child)
+		return (ENXIO);
+	return (pci_remap_msix(dev, count, vectors));
+}
+
+static int
+vga_pci_release_msi(device_t dev, device_t child)
+{
+	struct vga_pci_softc *sc;
+	int error;
+
+	sc =3D device_get_softc(dev);
+	if (sc->vga_msi_child !=3D child)
+		return (ENXIO);
+	error =3D pci_release_msi(dev);
+	if (error =3D=3D 0)
+		sc->vga_msi_child =3D NULL;
+	return (error);
+}
+
+static int
+vga_pci_msi_count(device_t dev, device_t child)
+{
+
+	return (pci_msi_count(dev));
+}
+
+static int
+vga_pci_msix_count(device_t dev, device_t child)
+{
+
+	return (pci_msix_count(dev));
+}
+
 static device_method_t vga_pci_methods[] =3D {
 	/* Device interface */
 	DEVMETHOD(device_probe,		vga_pci_probe),
@@ -236,10 +385,18 @@
 	DEVMETHOD(pci_disable_busmaster, vga_pci_disable_busmaster),
 	DEVMETHOD(pci_enable_io,	vga_pci_enable_io),
 	DEVMETHOD(pci_disable_io,	vga_pci_disable_io),
+	DEVMETHOD(pci_get_vpd_ident,	vga_pci_get_vpd_ident),
+	DEVMETHOD(pci_get_vpd_readonly,	vga_pci_get_vpd_readonly),
 	DEVMETHOD(pci_get_powerstate,	vga_pci_get_powerstate),
 	DEVMETHOD(pci_set_powerstate,	vga_pci_set_powerstate),
 	DEVMETHOD(pci_assign_interrupt,	vga_pci_assign_interrupt),
 	DEVMETHOD(pci_find_extcap,	vga_pci_find_extcap),
+	DEVMETHOD(pci_alloc_msi,	vga_pci_alloc_msi),
+	DEVMETHOD(pci_alloc_msix,	vga_pci_alloc_msix),
+	DEVMETHOD(pci_remap_msix,	vga_pci_remap_msix),
+	DEVMETHOD(pci_release_msi,	vga_pci_release_msi),
+	DEVMETHOD(pci_msi_count,	vga_pci_msi_count),
+	DEVMETHOD(pci_msix_count,	vga_pci_msix_count),
=20
 	{ 0, 0 }
 };
@@ -247,7 +404,7 @@
 static driver_t vga_pci_driver =3D {
 	"vgapci",
 	vga_pci_methods,
-	1,
+	sizeof(struct vga_pci_softc),
 };
=20
 static devclass_t vga_devclass;

--f0PSjARDFl/vfYT5
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (FreeBSD)

iEYEARECAAYFAkoARXIACgkQC3+MBN1Mb4hGdgCg4cQHGq+ELgmVnhAv4DjmVaO/
kxYAn0g4ylHxrZPIlBmScl8Q8tKzxw7z
=g7aU
-----END PGP SIGNATURE-----

--f0PSjARDFl/vfYT5--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20090505135602.GO1948>