diff options
author | alc <alc@FreeBSD.org> | 2005-06-04 19:16:33 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2005-06-04 19:16:33 +0000 |
commit | 369cab6800d25131e3b41b7b42d49507df962cfb (patch) | |
tree | 7bf14a2208ac4b61312d9aad3fa19a3d1ca782cd /sys/kern/vfs_aio.c | |
parent | 497a5998afc4581a2a4909ccdd39c877d8672fb8 (diff) | |
download | FreeBSD-src-369cab6800d25131e3b41b7b42d49507df962cfb.zip FreeBSD-src-369cab6800d25131e3b41b7b42d49507df962cfb.tar.gz |
Eliminate the original method of requesting notification of aio_read(2) and
aio_write(2) completion through kevent(2). This method does not work on
64-bit architectures. It was deprecated in FreeBSD 4.4. See revisions
1.87 and 1.70.2.7.
Change aio_physwakeup() to call psignal(9) directly rather than indirectly
through a timeout(9). Discussed with: bde
Correct a bug introduced in revision 1.65 that could result in premature
delivery of a signal if an lio_listio(2) consisted of a mixture of
direct/raw and queued I/O operations. Observed by: tegge
Eliminate a field from struct kaioinfo that is now unused.
Reviewed by: tegge
Diffstat (limited to 'sys/kern/vfs_aio.c')
-rw-r--r-- | sys/kern/vfs_aio.c | 72 |
1 files changed, 14 insertions, 58 deletions
diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index f94366b..481a92d 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -177,7 +177,6 @@ struct aiocblist { int jobstate; int inputcharge; int outputcharge; - struct callout_handle timeouthandle; struct buf *bp; /* Buffer pointer */ struct proc *userproc; /* User process */ /* Not td! */ struct ucred *cred; /* Active credential when created */ @@ -232,7 +231,6 @@ struct kaioinfo { int kaio_queue_finished_count; /* number of daemon jobs finished */ int kaio_buffer_count; /* number of physio buffers */ int kaio_buffer_finished_count; /* count of I/O done */ - struct proc *kaio_p; /* process that uses this kaio block */ TAILQ_HEAD(,aio_liojob) kaio_liojoblist; /* list of lio jobs */ TAILQ_HEAD(,aiocblist) kaio_jobqueue; /* job queue for process */ TAILQ_HEAD(,aiocblist) kaio_jobdone; /* done queue for process */ @@ -262,7 +260,6 @@ static int aio_qphysio(struct proc *p, struct aiocblist *iocb); static void aio_daemon(void *uproc); static void aio_swake_cb(struct socket *, struct sockbuf *); static int aio_unload(void); -static void process_signal(void *aioj); static int filt_aioattach(struct knote *kn); static void filt_aiodetach(struct knote *kn); static int filt_aio(struct knote *kn, long hint); @@ -410,7 +407,6 @@ aio_init_aioinfo(struct proc *p) ki->kaio_ballowed_count = max_buf_aio; ki->kaio_buffer_count = 0; ki->kaio_buffer_finished_count = 0; - ki->kaio_p = p; TAILQ_INIT(&ki->kaio_jobdone); TAILQ_INIT(&ki->kaio_jobqueue); TAILQ_INIT(&ki->kaio_bufdone); @@ -529,7 +525,6 @@ aio_free_entry(struct aiocblist *aiocbe) uma_zfree(aiolio_zone, lj); } aiocbe->jobstate = JOBST_NULL; - untimeout(process_signal, aiocbe, aiocbe->timeouthandle); fdrop(aiocbe->fd_file, curthread); crfree(aiocbe->cred); uma_zfree(aiocb_zone, aiocbe); @@ -1280,7 +1275,7 @@ _aio_aqueue(struct thread *td, struct aiocb *job, struct aio_liojob *lj, int typ struct socket *so; int s; int error; - int opcode, user_opcode; + int opcode; struct aiocblist *aiocbe; struct aiothreadlist *aiop; struct kaioinfo *ki; @@ -1292,7 +1287,6 @@ _aio_aqueue(struct thread *td, struct aiocb *job, struct aio_liojob *lj, int typ aiocbe = uma_zalloc(aiocb_zone, M_WAITOK); aiocbe->inputcharge = 0; aiocbe->outputcharge = 0; - callout_handle_init(&aiocbe->timeouthandle); /* XXX - need a lock */ knlist_init(&aiocbe->klist, NULL); @@ -1316,7 +1310,6 @@ _aio_aqueue(struct thread *td, struct aiocb *job, struct aio_liojob *lj, int typ aiocbe->uuaiocb = job; /* Get the opcode. */ - user_opcode = aiocbe->uaiocb.aio_lio_opcode; if (type != LIO_NOP) aiocbe->uaiocb.aio_lio_opcode = type; opcode = aiocbe->uaiocb.aio_lio_opcode; @@ -1385,23 +1378,8 @@ _aio_aqueue(struct thread *td, struct aiocb *job, struct aio_liojob *lj, int typ if (aiocbe->uaiocb.aio_sigevent.sigev_notify == SIGEV_KEVENT) { kev.ident = aiocbe->uaiocb.aio_sigevent.sigev_notify_kqueue; kev.udata = aiocbe->uaiocb.aio_sigevent.sigev_value.sigval_ptr; - } - else { - /* - * This method for requesting kevent-based notification won't - * work on the alpha, since we're passing in a pointer - * via aio_lio_opcode, which is an int. Use the SIGEV_KEVENT- - * based method instead. - */ - if (user_opcode == LIO_NOP || user_opcode == LIO_READ || - user_opcode == LIO_WRITE) - goto no_kqueue; - - error = copyin((struct kevent *)(uintptr_t)user_opcode, - &kev, sizeof(kev)); - if (error) - goto aqueue_fail; - } + } else + goto no_kqueue; if ((u_int)kev.ident >= fdp->fd_nfiles || (kq_fp = fdp->fd_ofiles[kev.ident]) == NULL || (kq_fp->f_type != DTYPE_KQUEUE)) { @@ -2118,32 +2096,6 @@ lio_listio(struct thread *td, struct lio_listio_args *uap) } /* - * This is a weird hack so that we can post a signal. It is safe to do so from - * a timeout routine, but *not* from an interrupt routine. - */ -static void -process_signal(void *aioj) -{ - struct aiocblist *aiocbe = aioj; - struct aio_liojob *lj = aiocbe->lio; - struct aiocb *cb = &aiocbe->uaiocb; - - if ((lj) && (lj->lioj_signal.sigev_notify == SIGEV_SIGNAL) && - (lj->lioj_queue_count == lj->lioj_queue_finished_count)) { - PROC_LOCK(lj->lioj_ki->kaio_p); - psignal(lj->lioj_ki->kaio_p, lj->lioj_signal.sigev_signo); - PROC_UNLOCK(lj->lioj_ki->kaio_p); - lj->lioj_flags |= LIOJ_SIGNAL_POSTED; - } - - if (cb->aio_sigevent.sigev_notify == SIGEV_SIGNAL) { - PROC_LOCK(aiocbe->userproc); - psignal(aiocbe->userproc, cb->aio_sigevent.sigev_signo); - PROC_UNLOCK(aiocbe->userproc); - } -} - -/* * Interrupt handler for physio, performs the necessary process wakeups, and * signals. */ @@ -2178,17 +2130,19 @@ aio_physwakeup(struct buf *bp) * wakeup/signal if all of the interrupt jobs are done. */ if (lj->lioj_buffer_finished_count == - lj->lioj_buffer_count) { + lj->lioj_buffer_count && + lj->lioj_queue_finished_count == + lj->lioj_queue_count) { /* * Post a signal if it is called for. */ if ((lj->lioj_flags & (LIOJ_SIGNAL|LIOJ_SIGNAL_POSTED)) == LIOJ_SIGNAL) { + PROC_LOCK(p); + psignal(p, lj->lioj_signal.sigev_signo); + PROC_UNLOCK(p); lj->lioj_flags |= LIOJ_SIGNAL_POSTED; - aiocbe->timeouthandle = - timeout(process_signal, - aiocbe, 0); } } } @@ -2207,9 +2161,11 @@ aio_physwakeup(struct buf *bp) } } - if (aiocbe->uaiocb.aio_sigevent.sigev_notify == SIGEV_SIGNAL) - aiocbe->timeouthandle = - timeout(process_signal, aiocbe, 0); + if (aiocbe->uaiocb.aio_sigevent.sigev_notify == SIGEV_SIGNAL) { + PROC_LOCK(p); + psignal(p, aiocbe->uaiocb.aio_sigevent.sigev_signo); + PROC_UNLOCK(p); + } } mtx_unlock(&Giant); } |