Subject: Re: CVS commit: src
To: Andrew Doran <ad@netbsd.org>
From: Bill Stouder-Studenmund <wrstuden@netbsd.org>
List: tech-kern
Date: 04/30/2007 15:25:08
--AbQceqfdZEv+FvjW
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
On Mon, Apr 30, 2007 at 11:13:18PM +0100, Andrew Doran wrote:
> Hi,
>=20
> > Log Message:
> > Import of POSIX Asynchronous I/O.
> > Seems to be quite stable. Some work still left to do.
>=20
> Cool! I have some more comments & suggestions now that this is in the tre=
e.
>=20
> o It belongs in sys_aio.c for a couple of reasons. The file implements on=
ly
> syscalls and direct support for them, and it's not a VFS component as
> such. It should be possible to do AIO on other types of file descriptor.
Agreed.
> o Holding p->p_mutex across mutex_init and pool_init is dicey since they =
can
> sleep in order to allocate memory. There are number of other things th=
at
> depend on p_mutex, so if an LWP sleeps here it could tie other LWPs up =
in
> knots waiting. What I suggest to fix that is a flag in p_flag and perha=
ps
> another condvar that says "AIO is being initialized". Other threads that
> end up in aio_init would wait for that flag to clear, then return when =
it
> has cleared:
>=20
> mutex_enter(&p->p_mutex);
> if ((p->p_flag & PK_AIOINIT) !=3D 0 || p->p_aio !=3D NULL) {
> /* Already initializing or initialized. */
> while ((p->p_flag & PK_AIOINIT) !=3D 0)
> cv_wait(&p->p_mutex, &p->p_somecv);
> if (p->p_aio !=3D NULL) {
> mutex_exit(&p->p_mutex);
> return;
> } else {
> /*
> * Another thread's initialization attempt
> * may have failed: retry.
> */
> }
> }
Layered file systems deal with this. You grab the mutex & look to see if=20
it's been inited. If not, you drop the mutex, do the allocation, grab the=
=20
mutex, & see if it's still uninitialized. If uninitialized, store your=20
allocation & proceed. If it's been allocated by someone else, error out=20
and release what you allocated.
> o Testing for p->p_aio to be non-null appears to be unsafe as it can
> currently be non-null while AIO is not fully initialized. To fix that
> the worker thread could also check for the "AIO is initializing" flag in
> p_flag, and wait until it clears. Then, we could set p_aio as the last
> action in aio_init, like this:
>=20
> /* No longer initializing. */
> mutex_enter(&p->p_mutex);
> p->p_aio =3D aio;
> p->p_flag &=3D ~PK_AIOINIT;
> cv_broadcast(&p->p_somecv);
> mutex_exit(&p->p_mutex);
How much is involved in cleaning up a failed initialization? Another=20
option is to fill in the aio structure before storing it in the process=20
structure.
Take care,
Bill
--AbQceqfdZEv+FvjW
Content-Type: application/pgp-signature
Content-Disposition: inline
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (NetBSD)
iD8DBQFGNmzEWz+3JHUci9cRAg8wAKCMx6wKQuiHQb7WchBwdlTBLweuEACfTt7b
kDdcT2k+QR33pbDUk4ZszYI=
=9sPY
-----END PGP SIGNATURE-----
--AbQceqfdZEv+FvjW--