Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 22 Dec 2008 00:10:14 +0200
From:      Kostik Belousov <kostikbel@gmail.com>
To:        Ed Schouten <ed@freebsd.org>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r186382 - head/sys/kern
Message-ID:  <20081221221014.GJ2038@deviant.kiev.zoral.com.ua>
In-Reply-To: <200812212116.mBLLGvPj042566@svn.freebsd.org>
References:  <200812212116.mBLLGvPj042566@svn.freebsd.org>

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

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

On Sun, Dec 21, 2008 at 09:16:57PM +0000, Ed Schouten wrote:
> Author: ed
> Date: Sun Dec 21 21:16:57 2008
> New Revision: 186382
> URL: http://svn.freebsd.org/changeset/base/186382
>=20
> Log:
>   Set PTS_FINISHED before waking up any threads.
>  =20
>   Inside ptsdrv_{in,out}wakeup() we call KNOTE_LOCKED() to wake up any
>   kevent(2) users. Because the kqueue handlers are executed synchronously,
>   we must set PTS_FINISHED before calling ptsdrv_{in,out}wakeup().
>  =20
>   Discovered by:	nork
>=20
> Modified:
>   head/sys/kern/tty_pts.c
>=20
> Modified: head/sys/kern/tty_pts.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=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
> --- head/sys/kern/tty_pts.c	Sun Dec 21 20:30:14 2008	(r186381)
> +++ head/sys/kern/tty_pts.c	Sun Dec 21 21:16:57 2008	(r186382)
> @@ -630,10 +630,9 @@ ptsdrv_close(struct tty *tp)
>  	struct pts_softc *psc =3D tty_softc(tp);
> =20
>  	/* Wake up any blocked readers/writers. */
> +	psc->pts_flags |=3D PTS_FINISHED;
>  	ptsdrv_outwakeup(tp);
>  	ptsdrv_inwakeup(tp);
> -
> -	psc->pts_flags |=3D PTS_FINISHED;
>  }
> =20
>  static void

I was always curious whether our cv code guarantees that there is no
a spurious wakeup. If the spurious wakeup can happen, then setting
PTS_FINISHED before calling cv_broadcast() still does not solve
the possible race.

Assume that waiting thread is woken up, and ptsdrv_close() still did
not set PTS_FINISHED. The ptsdev_read() locked the mutex, rechecked
the condition (that is false still), and preempted for the
ptsdrv_close() thread. This thread sets flag and issues broadcast.
Then, the ptsdrv_read() thread is put to sleep, having lost a wakeup.

I think that mutex shall be acquired around setting flag and wakeups.
scheduled, it=20

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

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

iEYEARECAAYFAklOvsYACgkQC3+MBN1Mb4hbWACeJQqGDApaXHqwG0sJadHZQxpa
XHMAn1cDnBcINM391qHSoNY+oMr3kwio
=OvVb
-----END PGP SIGNATURE-----

--B3dAGXc5YVwcSxdz--



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