Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 Jan 2008 23:11:49 +0200
From:      Kostik Belousov <kostikbel@gmail.com>
To:        Joe Marcus Clarke <marcus@freebsd.org>
Cc:        FreeBSD Current <freebsd-current@freebsd.org>
Subject:   Re: page fault panic in scioctl and console-kit-daemon
Message-ID:  <20080123211149.GA57756@deviant.kiev.zoral.com.ua>
In-Reply-To: <1201118159.38742.17.camel@shumai.marcuscom.com>
References:  <4792C32C.5010205@gmail.com> <20080122133835.GT57756@deviant.kiev.zoral.com.ua> <4796356D.9080809@gmail.com> <20080123051648.GV57756@deviant.kiev.zoral.com.ua> <479796E1.4000500@gmail.com> <1201118159.38742.17.camel@shumai.marcuscom.com>

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

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

On Wed, Jan 23, 2008 at 02:55:59PM -0500, Joe Marcus Clarke wrote:
>=20
> On Wed, 2008-01-23 at 20:34 +0100, Pawel Worach wrote:
> > Kostik Belousov wrote:
> > > On Tue, Jan 22, 2008 at 07:26:53PM +0100, Pawel Worach wrote:
> > >> Kostik Belousov wrote:
> > >>> On Sun, Jan 20, 2008 at 04:42:36AM +0100, Pawel Worach wrote:
> > >>>> Hi,
> > >>>>
> > >>>> While starting console-kit-daemon (sysutils/consolekit 0.2.3) duri=
ng=20
> > >>>> boot or in single-user mode the system panics. If I start it post-=
boot=20
> > >>>> it runs fine. This is on 8.0-CURRENT from about 12 hours ago, anot=
her=20
> > >>>> user also reported the same on RELENG_7. Any other information I c=
an=20
> > >>>> provide ?
> > >>>>
> > >>>> Fatal trap 12: page fault while in kernel mode
> > >>>> fault virtual address	=3D 0x4
> > >>>> fault code		=3D supervisor read, page not present
> > >>>> instruction pointer	=3D 0x20:0xc04d2ab4
> > >>>> stack pointer	        =3D 0x28:0xe6499b18
> > >>>> frame pointer	        =3D 0x28:0xe6499b80
> > >>>> code segment		=3D base 0x0, limit 0xfffff, type 0x1b
> > >>>> 			=3D DPL 0, pres 1, def32 1, gran 1
> > >>>> processor eflags	=3D interrupt enabled, resume, IOPL =3D 0
> > >>>> current process		=3D 134 (console-kit-daemon)
> > >>>> Physical memory: 1014 MB
> > >>>> Dumping 43 MB: 28 12
> > >>>>
> > >>>> #8  0xc07a34a2 in trap (frame=3D0xe6499ad8) at=20
> > >>>> /usr/src/sys/i386/i386/trap.c:489
> > >>>> #9  0xc079183b in calltrap () at /usr/src/sys/i386/i386/exception.=
s:146
> > >>>> #10 0xc04d2ab4 in scioctl (dev=3D0xc3b20d00, cmd=3D537163270,
> > >>>>    data=3D0xe6499c70 "\002", flag=3D1, td=3D0xc3d3c880)
> > >>>>    at /usr/src/sys/dev/syscons/syscons.c:1073
> > >>>> #11 0xc051ed1a in giant_ioctl (dev=3D0xc3b20d00, cmd=3D537163270,
> > >>>>    data=3D0xe6499c70 "\002", fflag=3D1, td=3D0xc3d3c880)
> > >>>>    at /usr/src/sys/kern/kern_conf.c:349
> > >>>> #12 0xc0598194 in cnioctl (dev=3D0xc3b20d00, cmd=3D537163270,
> > >>>>    data=3D0xe6499c70 "\002", flag=3D1, td=3D0xc3d3c880)
> > >>>> ---Type <return> to continue, or q <return> to quit---
> > >>>>    at /usr/src/sys/kern/tty_cons.c:521
> > >>> Unless the virtual screen is opened, the screen state scr_stat stru=
cture
> > >>> is not allocated. The following patch would fix the panic, but I do=
 not
> > >>> know how the console-kit would react to the ENXIO from the
> > >>> VT_WAITACTIVE ioctl. Please, test it.
> > >> Thanks! The patch works.
> > >=20
> > > To clarify: do you see any problems with the console-kit after the pa=
tch ?
> > > In particular, can you verify that the program functions correctly, e=
sp.
> > > on the virtual terminals 1, 2 ... , whatever this means ?
> >=20
> > The panic is of course gone, while chatting a bit with Marcus (CCd) it=
=20
> > looks like console-kit does not do any error handling at all. I've not=
=20
> > looked at what c-k does so maybe Marcus can answer the question better.
>=20
> It tries to install a wait thread on each available VT.  That thread
> sets the WAITACTIVE ioctl, and waits for its VT to become active.  When
> it does, it sets the CK active VT accordingly, and reattaches the wait.
>=20
> When an error occurs in the ioctl, no wait is attached, and CK will not
> know when a particular VT becomes active.  This will essentially cripple
> CK (assuming the VT really does become available at a later point). =20
>=20
> Now, admittedly, there is no error correction in CK for this situation.
> It would be trivial to add something that periodically attempts to
> reestablish a failed wait.  However, I am very curious why only a few
> users are seeing this panic (me excluded on two different machines).  It
> seems to me that the scp should be initialized when sc_attach_unit() is
> called during device probing.  I don't see anything special in init(8)'s
> code that would cause these VT devices to become initialized.  I would
> assume that if one can open(2) them, then they should be available for
> ioctls?

=46rom my reading of the code, scp would be non-NULL after the first open
of the corresponding /dev/ttyvX. sc_attach_unit() creates the scp for
the console and the consolectl devices.

VT_WAITACTIVE ioctl is performed on arbitrary syscons /dev node, and
can wait for any other screens, in particular, the screens that are
not opened at the moment (the reason for the reported panic).

The patch I posted may be improved by making the VT_WAITACTIVE ioctl
to wait for the scp being allocated, and only then for the screen to be
switched too. Please, test.


diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index e0c9725..3127ae6 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -178,6 +178,7 @@ static int scparam(struct tty *tp, struct termios *t);
 static void scstart(struct tty *tp);
 static void scinit(int unit, int flags);
 static scr_stat *sc_get_stat(struct cdev *devptr);
+static void sc_set_stat(struct cdev *devptr, scr_stat *st);
 static void scterm(int unit, int flags);
 static void scshutdown(void *arg, int howto);
 static u_int scgetc(sc_softc_t *sc, u_int flags);
@@ -421,7 +422,7 @@ sc_attach_unit(int unit, int flags)
 		    UID_ROOT, GID_WHEEL, 0600, "ttyv%r", vc + unit * MAXCONS);
 	    	sc_alloc_tty(sc->dev[vc]);
 		if (vc =3D=3D 0 && sc->dev =3D=3D main_devs)
-			SC_STAT(sc->dev[0]) =3D &main_console;
+			sc_set_stat(sc->dev[0], &main_console);
 	}
 	/*
 	 * The first vty already has struct tty and scr_stat initialized
@@ -434,7 +435,7 @@ sc_attach_unit(int unit, int flags)
 		   UID_ROOT, GID_WHEEL, 0600, "consolectl");
     sc_console_tty =3D sc_alloc_tty(dev);
     ttyconsolemode(sc_console_tty, 0);
-    SC_STAT(dev) =3D sc_console;
+    sc_set_stat(dev, sc_console);
=20
     return 0;
 }
@@ -525,7 +526,8 @@ scopen(struct cdev *dev, int flag, int mode, struct thr=
ead *td)
=20
     scp =3D sc_get_stat(dev);
     if (scp =3D=3D NULL) {
-	scp =3D SC_STAT(dev) =3D alloc_scp(sc, SC_VTY(dev));
+	scp =3D alloc_scp(sc, SC_VTY(dev));
+	sc_set_stat(dev, scp);
 	if (ISGRAPHSC(scp))
 	    sc_set_pixel_mode(scp, NULL, COL, ROW, 16, 8);
     }
@@ -1063,6 +1065,7 @@ scioctl(struct cdev *dev, u_long cmd, caddr_t data, i=
nt flag, struct thread *td)
 #endif
     case VT_WAITACTIVE: 	/* wait for switch to occur */
 	i =3D (*(int *)data =3D=3D 0) ? scp->index : (*(int *)data - 1);
+    wait_active:
 	if ((i < sc->first_vty) || (i >=3D sc->first_vty + sc->vtys))
 	    return EINVAL;
 	s =3D spltty();
@@ -1071,6 +1074,12 @@ scioctl(struct cdev *dev, u_long cmd, caddr_t data, =
int flag, struct thread *td)
 	if (error)
 	    return error;
 	scp =3D sc_get_stat(SC_DEV(sc, i));
+	if (scp =3D=3D NULL) {
+		error =3D tsleep(&(dev)->si_drv1, PZERO | PCATCH, "waitvt0", 0);
+		if (error)
+			return (error);
+		goto wait_active;
+	}
 	if (scp =3D=3D scp->sc->cur_scp)
 	    return 0;
 	error =3D tsleep(&scp->smode, PZERO | PCATCH, "waitvt", 0);
@@ -2769,7 +2778,7 @@ scinit(int unit, int flags)
 	        UID_ROOT, GID_WHEEL, 0600, "ttyv%r", unit * MAXCONS);
 	    sc_alloc_tty(sc->dev[0]);
 	    scp =3D alloc_scp(sc, sc->first_vty);
-	    SC_STAT(sc->dev[0]) =3D scp;
+	    sc_set_stat(sc->dev[0], scp);
 	}
 	sc->cur_scp =3D scp;
=20
@@ -3662,6 +3671,14 @@ sc_get_stat(struct cdev *devptr)
 	return (SC_STAT(devptr));
 }
=20
+static void
+sc_set_stat(struct cdev *devptr, scr_stat *st)
+{
+
+	SC_STAT(devptr) =3D st;
+	wakeup(&devptr->si_drv1);
+}
+
 /*
  * Allocate active keyboard. Try to allocate "kbdmux" keyboard first, and,
  * if found, add all non-busy keyboards to "kbdmux". Otherwise look for

--gwHyQuq5wHWsurqv
Content-Type: application/pgp-signature
Content-Disposition: inline

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

iEYEARECAAYFAkeXrZMACgkQC3+MBN1Mb4gkGgCdEr2DgrZH8fYECBw74bj+G968
QQUAoMQ0rxMBzMIFndRzY/k0HV8RndD6
=8n5X
-----END PGP SIGNATURE-----

--gwHyQuq5wHWsurqv--



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