1) Merge _aio_aqueue and aio_aqueue, check quota in aio_aqueue,

so that lio_listio won't exceed the quota.
2) Remove lio_ref_count, it is no longer used.
This commit is contained in:
David Xu 2006-01-23 02:49:34 +00:00
parent bb53e2bf27
commit a9bf5e37ae

View File

@ -144,7 +144,7 @@ SYSCTL_INT(_vfs_aio, OID_AUTO, num_buf_aio, CTLFLAG_RD, &num_buf_aio, 0,
"Number of aio requests presently handled by the buf subsystem");
/* Number of async I/O thread in the process of being started */
/* XXX This should be local to _aio_aqueue() */
/* XXX This should be local to aio_aqueue() */
static int num_aio_resv_start = 0;
static int aiod_timeout;
@ -227,7 +227,6 @@ struct aioliojob {
int lioj_flags;
int lioj_count;
int lioj_finished_count;
int lioj_ref_count;
struct sigevent lioj_signal; /* signal on all I/O done */
TAILQ_ENTRY(aioliojob) lioj_list;
struct knlist klist; /* list of knotes */
@ -272,8 +271,8 @@ static void aio_onceonly(void);
static int aio_free_entry(struct aiocblist *aiocbe);
static void aio_process(struct aiocblist *aiocbe);
static int aio_newproc(int *);
static int aio_aqueue(struct thread *td, struct aiocb *job, int type,
int osigev);
static int aio_aqueue(struct thread *td, struct aiocb *job,
struct aioliojob *lio, int type, int osigev);
static void aio_physwakeup(struct buf *bp);
static void aio_proc_rundown(void *arg, struct proc *p);
static int aio_qphysio(struct proc *p, struct aiocblist *iocb);
@ -515,7 +514,7 @@ aio_free_entry(struct aiocblist *aiocbe)
lj->lioj_count--;
lj->lioj_finished_count--;
if (lj->lioj_count == 0 && lj->lioj_ref_count == 0) {
if (lj->lioj_count == 0) {
TAILQ_REMOVE(&ki->kaio_liojoblist, lj, lioj_list);
/* lio is going away, we need to destroy any knotes */
knlist_delete(&lj->klist, curthread, 1);
@ -638,15 +637,14 @@ aio_proc_rundown(void *arg, struct proc *p)
aio_free_entry(cbe);
while ((lj = TAILQ_FIRST(&ki->kaio_liojoblist)) != NULL) {
if (lj->lioj_count == 0 && lj->lioj_ref_count == 0) {
if (lj->lioj_count == 0) {
TAILQ_REMOVE(&ki->kaio_liojoblist, lj, lioj_list);
knlist_delete(&lj->klist, curthread, 1);
sigqueue_take(&lj->lioj_ksi);
uma_zfree(aiolio_zone, lj);
} else {
panic("LIO job not cleaned up: C:%d, FC:%d, RC:%d\n",
lj->lioj_count, lj->lioj_finished_count,
lj->lioj_ref_count);
panic("LIO job not cleaned up: C:%d, FC:%d\n",
lj->lioj_count, lj->lioj_finished_count);
}
}
@ -733,7 +731,7 @@ aio_process(struct aiocblist *aiocbe)
inblock_st = mycp->p_stats->p_ru.ru_inblock;
oublock_st = mycp->p_stats->p_ru.ru_oublock;
/*
* _aio_aqueue() acquires a reference to the file that is
* aio_aqueue() acquires a reference to the file that is
* released in aio_free_entry().
*/
if (cb->aio_lio_opcode == LIO_READ) {
@ -1066,7 +1064,7 @@ aio_newproc(int *start)
* VCHR devices. This method doesn't use an aio helper thread, and
* thus has very low overhead.
*
* Assumes that the caller, _aio_aqueue(), has incremented the file
* Assumes that the caller, aio_aqueue(), has incremented the file
* structure's reference count, preventing its deallocation for the
* duration of this call.
*/
@ -1247,7 +1245,7 @@ aio_swake_cb(struct socket *so, struct sockbuf *sb)
* technique is done in this code.
*/
static int
_aio_aqueue(struct thread *td, struct aiocb *job, struct aioliojob *lj,
aio_aqueue(struct thread *td, struct aiocb *job, struct aioliojob *lj,
int type, int oldsigev)
{
struct proc *p = td->td_proc;
@ -1265,17 +1263,26 @@ _aio_aqueue(struct thread *td, struct aiocb *job, struct aioliojob *lj,
int fd;
int jid;
if (p->p_aioinfo == NULL)
aio_init_aioinfo(p);
ki = p->p_aioinfo;
suword(&job->_aiocb_private.status, -1);
suword(&job->_aiocb_private.error, 0);
suword(&job->_aiocb_private.kernelinfo, -1);
if (num_queue_count >= max_queue_count ||
ki->kaio_count >= ki->kaio_qallowed_count) {
suword(&job->_aiocb_private.error, EAGAIN);
return (EAGAIN);
}
aiocbe = uma_zalloc(aiocb_zone, M_WAITOK | M_ZERO);
aiocbe->inputcharge = 0;
aiocbe->outputcharge = 0;
knlist_init(&aiocbe->klist, &p->p_mtx, NULL, NULL, NULL);
suword(&job->_aiocb_private.status, -1);
suword(&job->_aiocb_private.error, 0);
suword(&job->_aiocb_private.kernelinfo, -1);
if (oldsigev) {
bzero(&aiocbe->uaiocb, sizeof(struct aiocb));
error = copyin(job, &aiocbe->uaiocb, sizeof(struct oaiocb));
@ -1488,28 +1495,6 @@ _aio_aqueue(struct thread *td, struct aiocb *job, struct aioliojob *lj,
return (error);
}
/*
* This routine queues an AIO request, checking for quotas.
*/
static int
aio_aqueue(struct thread *td, struct aiocb *job, int type, int oldsigev)
{
struct proc *p = td->td_proc;
struct kaioinfo *ki;
if (p->p_aioinfo == NULL)
aio_init_aioinfo(p);
if (num_queue_count >= max_queue_count)
return (EAGAIN);
ki = p->p_aioinfo;
if (ki->kaio_count >= ki->kaio_qallowed_count)
return (EAGAIN);
return _aio_aqueue(td, job, NULL, type, oldsigev);
}
/*
* Support the aio_return system call, as a side-effect, kernel resources are
* released.
@ -1776,7 +1761,7 @@ aio_error(struct thread *td, struct aio_error_args *uap)
PROC_UNLOCK(p);
/*
* Hack for failure of _aio_aqueue.
* Hack for failure of aio_aqueue.
*/
status = fuword(&uap->aiocbp->_aiocb_private.status);
if (status == -1) {
@ -1793,14 +1778,14 @@ int
oaio_read(struct thread *td, struct oaio_read_args *uap)
{
return aio_aqueue(td, (struct aiocb *)uap->aiocbp, LIO_READ, 1);
return aio_aqueue(td, (struct aiocb *)uap->aiocbp, NULL, LIO_READ, 1);
}
int
aio_read(struct thread *td, struct aio_read_args *uap)
{
return aio_aqueue(td, uap->aiocbp, LIO_READ, 0);
return aio_aqueue(td, uap->aiocbp, NULL, LIO_READ, 0);
}
/* syscall - asynchronous write to a file (REALTIME) */
@ -1808,14 +1793,14 @@ int
oaio_write(struct thread *td, struct oaio_write_args *uap)
{
return aio_aqueue(td, (struct aiocb *)uap->aiocbp, LIO_WRITE, 1);
return aio_aqueue(td, (struct aiocb *)uap->aiocbp, NULL, LIO_WRITE, 1);
}
int
aio_write(struct thread *td, struct aio_write_args *uap)
{
return aio_aqueue(td, uap->aiocbp, LIO_WRITE, 0);
return aio_aqueue(td, uap->aiocbp, NULL, LIO_WRITE, 0);
}
/* syscall - list directed I/O (REALTIME) */
@ -1863,7 +1848,6 @@ do_lio_listio(struct thread *td, struct lio_listio_args *uap, int oldsigev)
lj->lioj_flags = 0;
lj->lioj_count = 0;
lj->lioj_finished_count = 0;
lj->lioj_ref_count = 0;
knlist_init(&lj->klist, &p->p_mtx, NULL, NULL, NULL);
ksiginfo_init(&lj->lioj_ksi);
@ -1935,7 +1919,7 @@ do_lio_listio(struct thread *td, struct lio_listio_args *uap, int oldsigev)
for (i = 0; i < uap->nent; i++) {
iocb = (struct aiocb *)(intptr_t)fuword(&cbptr[i]);
if (((intptr_t)iocb != -1) && ((intptr_t)iocb != 0)) {
error = _aio_aqueue(td, iocb, lj, 0, oldsigev);
error = aio_aqueue(td, iocb, lj, 0, oldsigev);
if (error != 0)
nerror++;
}