Mercurial > illumos > illumos-gate
changeset 10719:203f5727fba9
6887205 program using Posix aio gets unexpected SIGPOLL (SIGIO) signals
author | Roger A. Faulkner <Roger.Faulkner@Sun.COM> |
---|---|
date | Mon, 05 Oct 2009 12:36:45 -0700 |
parents | 77613d4558c6 |
children | c45747dcac4f |
files | usr/src/uts/common/os/aio.c usr/src/uts/common/os/aio_subr.c usr/src/uts/common/sys/aio_impl.h |
diffstat | 3 files changed, 56 insertions(+), 34 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/os/aio.c Mon Oct 05 11:35:02 2009 -0700 +++ b/usr/src/uts/common/os/aio.c Mon Oct 05 12:36:45 2009 -0700 @@ -86,7 +86,7 @@ static int aio_req_find(aio_result_t *, aio_req_t **); static int aio_hash_insert(struct aio_req_t *, aio_t *); static int aio_req_setup(aio_req_t **, aio_t *, aiocb_t *, - aio_result_t *, vnode_t *); + aio_result_t *, vnode_t *, int); static int aio_cleanup_thread(aio_t *); static aio_lio_t *aio_list_get(aio_result_t *); static void lio_set_uerror(void *, int); @@ -106,7 +106,7 @@ static int alioLF(int, void *, int, void *); static int aio_req_setupLF(aio_req_t **, aio_t *, aiocb64_32_t *, - aio_result_t *, vnode_t *); + aio_result_t *, vnode_t *, int); static int alio32(int, void *, int, void *); static int driver_aio_write(vnode_t *vp, struct aio_req *aio, cred_t *cred_p); static int driver_aio_read(vnode_t *vp, struct aio_req *aio, cred_t *cred_p); @@ -1401,7 +1401,7 @@ } error = aio_req_setup(&reqp, aiop, aiocb, - &cbp->aio_resultp, vp); + &cbp->aio_resultp, vp, 0); if (error) { releasef(aiocb->aio_fildes); lio_set_uerror(&cbp->aio_resultp, error); @@ -1982,14 +1982,14 @@ aiocb.aio_nbytes = bufsize; aiocb.aio_offset = offset; aiocb.aio_sigevent.sigev_notify = 0; - error = aio_req_setup(&reqp, aiop, &aiocb, resultp, vp); + error = aio_req_setup(&reqp, aiop, &aiocb, resultp, vp, 1); #else aiocb64.aio_fildes = fdes; aiocb64.aio_buf = (caddr32_t)bufp; aiocb64.aio_nbytes = bufsize; aiocb64.aio_offset = offset; aiocb64.aio_sigevent.sigev_notify = 0; - error = aio_req_setupLF(&reqp, aiop, &aiocb64, resultp, vp); + error = aio_req_setupLF(&reqp, aiop, &aiocb64, resultp, vp, 1); #endif if (error) { releasef(fdes); @@ -2172,9 +2172,9 @@ return (EBADFD); } if (run_mode == AIO_LARGEFILE) - error = aio_req_setupLF(&reqp, aiop, &aiocb64, resultp, vp); + error = aio_req_setupLF(&reqp, aiop, &aiocb64, resultp, vp, 0); else - error = aio_req_setup(&reqp, aiop, &aiocb, resultp, vp); + error = aio_req_setup(&reqp, aiop, &aiocb, resultp, vp, 0); if (error) { releasef(fd); @@ -2393,7 +2393,8 @@ aio_t *aiop, aiocb_t *arg, aio_result_t *resultp, - vnode_t *vp) + vnode_t *vp, + int old_solaris_req) { sigqueue_t *sqp = NULL; aio_req_t *reqp; @@ -2439,6 +2440,11 @@ aiop->aio_pending++; aiop->aio_outstanding++; reqp->aio_req_flags = AIO_PENDING; + if (old_solaris_req) { + /* this is an old solaris aio request */ + reqp->aio_req_flags |= AIO_SOLARIS; + aiop->aio_flags |= AIO_SOLARIS_REQ; + } if (sigev->sigev_notify == SIGEV_THREAD || sigev->sigev_notify == SIGEV_PORT) aio_enq(&aiop->aio_portpending, reqp, 0); @@ -3106,10 +3112,10 @@ #ifdef _LP64 aiocb_LFton(aiocb, &aiocb_n); error = aio_req_setup(&reqp, aiop, &aiocb_n, - (aio_result_t *)&cbp->aio_resultp, vp); + (aio_result_t *)&cbp->aio_resultp, vp, 0); #else error = aio_req_setupLF(&reqp, aiop, aiocb, - (aio_result_t *)&cbp->aio_resultp, vp); + (aio_result_t *)&cbp->aio_resultp, vp, 0); #endif /* _LP64 */ if (error) { releasef(aiocb->aio_fildes); @@ -3284,7 +3290,8 @@ aio_t *aiop, aiocb64_32_t *arg, aio_result_t *resultp, - vnode_t *vp) + vnode_t *vp, + int old_solaris_req) { sigqueue_t *sqp = NULL; aio_req_t *reqp; @@ -3330,6 +3337,11 @@ aiop->aio_pending++; aiop->aio_outstanding++; reqp->aio_req_flags = AIO_PENDING; + if (old_solaris_req) { + /* this is an old solaris aio request */ + reqp->aio_req_flags |= AIO_SOLARIS; + aiop->aio_flags |= AIO_SOLARIS_REQ; + } if (sigev->sigev_notify == SIGEV_THREAD || sigev->sigev_notify == SIGEV_PORT) aio_enq(&aiop->aio_portpending, reqp, 0); @@ -3595,7 +3607,7 @@ } error = aio_req_setup(&reqp, aiop, aiocb, - (aio_result_t *)&cbp->aio_resultp, vp); + (aio_result_t *)&cbp->aio_resultp, vp, 0); if (error) { releasef(aiocb->aio_fildes); lio_set_uerror(&cbp->aio_resultp, error);
--- a/usr/src/uts/common/os/aio_subr.c Mon Oct 05 11:35:02 2009 -0700 +++ b/usr/src/uts/common/os/aio_subr.c Mon Oct 05 12:36:45 2009 -0700 @@ -388,9 +388,11 @@ /* * No need to set this flag for pollq, portq, lio requests. - * Send a SIGIO signal when the process has a handler enabled. + * If this is an old Solaris aio request, and the process has + * a SIGIO signal handler enabled, then send a SIGIO signal. */ if (!sigev && !use_port && head == NULL && + (reqp->aio_req_flags & AIO_SOLARIS) && (func = PTOU(p)->u_signal[SIGIO - 1]) != SIG_DFL && (func != SIG_IGN)) { send_signal = 1; @@ -774,6 +776,12 @@ */ mutex_enter(&aiop->aio_mutex); + /* + * If there has never been an old solaris aio request + * issued by this process, then do not send a SIGIO signal. + */ + if (!(aiop->aio_flags & AIO_SOLARIS_REQ)) + signalled = 1; cv_broadcast(&aiop->aio_waitcv); mutex_exit(&aiop->aio_mutex);
--- a/usr/src/uts/common/sys/aio_impl.h Mon Oct 05 11:35:02 2009 -0700 +++ b/usr/src/uts/common/sys/aio_impl.h Mon Oct 05 12:36:45 2009 -0700 @@ -135,34 +135,36 @@ /* * aio_flags for an aio_t. */ -#define AIO_CLEANUP 0x1 /* do aio cleanup processing */ -#define AIO_WAITN 0x2 /* aiowaitn in progress */ -#define AIO_WAITN_PENDING 0x4 /* aiowaitn requests pending */ -#define AIO_REQ_BLOCK 0x8 /* block new requests */ -#define AIO_CLEANUP_PORT 0x10 -#define AIO_DONE_ACTIVE 0x20 /* aio_done call in progress */ +#define AIO_CLEANUP 0x0001 /* do aio cleanup processing */ +#define AIO_WAITN 0x0002 /* aiowaitn in progress */ +#define AIO_WAITN_PENDING 0x0004 /* aiowaitn requests pending */ +#define AIO_REQ_BLOCK 0x0008 /* block new requests */ +#define AIO_CLEANUP_PORT 0x0010 +#define AIO_DONE_ACTIVE 0x0020 /* aio_done call in progress */ +#define AIO_SOLARIS_REQ 0x0040 /* an old solaris aio req was issued */ /* * aio_req_flags for an aio_req_t */ -#define AIO_POLL 0x1 /* AIO_INPROGRESS is set */ -#define AIO_PENDING 0x2 /* aio is in progress */ -#define AIO_PHYSIODONE 0x4 /* unlocked phys pages */ -#define AIO_COPYOUTDONE 0x8 /* result copied to userland */ -#define AIO_NOTIFYQ 0x10 /* aio req is on the notifyq */ -#define AIO_CLEANUPQ 0x20 /* aio req is on the cleanupq */ -#define AIO_POLLQ 0x40 /* aio req is on the pollq */ -#define AIO_DONEQ 0x80 /* aio req is on the doneq */ -#define AIO_ZEROLEN 0x100 /* aio req is zero length */ -#define AIO_PAGELOCKDONE 0x200 /* aio called as_pagelock() */ -#define AIO_CLOSE_PORT 0x400 /* port is being closed */ -#define AIO_SIGNALLED 0x800 /* process signalled by this req */ +#define AIO_POLL 0x0001 /* AIO_INPROGRESS is set */ +#define AIO_PENDING 0x0002 /* aio is in progress */ +#define AIO_PHYSIODONE 0x0004 /* unlocked phys pages */ +#define AIO_COPYOUTDONE 0x0008 /* result copied to userland */ +#define AIO_NOTIFYQ 0x0010 /* aio req is on the notifyq */ +#define AIO_CLEANUPQ 0x0020 /* aio req is on the cleanupq */ +#define AIO_POLLQ 0x0040 /* aio req is on the pollq */ +#define AIO_DONEQ 0x0080 /* aio req is on the doneq */ +#define AIO_ZEROLEN 0x0100 /* aio req is zero length */ +#define AIO_PAGELOCKDONE 0x0200 /* aio called as_pagelock() */ +#define AIO_CLOSE_PORT 0x0400 /* port is being closed */ +#define AIO_SIGNALLED 0x0800 /* process signalled by this req */ +#define AIO_SOLARIS 0x1000 /* this is an old solaris aio req */ /* flag argument of aio_cleanup() */ -#define AIO_CLEANUP_POLL 0 /* check kaio poll queue */ -#define AIO_CLEANUP_EXIT 1 /* aio_cleanup_exit() */ -#define AIO_CLEANUP_THREAD 2 /* aio_cleanup_thread() */ +#define AIO_CLEANUP_POLL 0 /* check kaio poll queue */ +#define AIO_CLEANUP_EXIT 1 /* aio_cleanup_exit() */ +#define AIO_CLEANUP_THREAD 2 /* aio_cleanup_thread() */ /* functions exported by common/os/aio_subr.c */