Synchronize access to aio_freeproc with a mutex. Eliminate related spl

calls.

Reduce the scope of Giant in aio_daemon().
This commit is contained in:
Alan Cox 2005-05-30 22:26:34 +00:00
parent c64e9e6833
commit 3148c2c96a

View File

@ -245,6 +245,8 @@ struct kaioinfo {
#define KAIO_WAKEUP 0x2 /* wakeup process when there is a significant event */ #define KAIO_WAKEUP 0x2 /* wakeup process when there is a significant event */
static TAILQ_HEAD(,aiothreadlist) aio_freeproc; /* Idle daemons */ static TAILQ_HEAD(,aiothreadlist) aio_freeproc; /* Idle daemons */
static struct mtx aio_freeproc_mtx;
static TAILQ_HEAD(,aiocblist) aio_jobs; /* Async job list */ static TAILQ_HEAD(,aiocblist) aio_jobs; /* Async job list */
static void aio_init_aioinfo(struct proc *p); static void aio_init_aioinfo(struct proc *p);
@ -339,6 +341,7 @@ aio_onceonly(void)
EVENTHANDLER_PRI_ANY); EVENTHANDLER_PRI_ANY);
kqueue_add_filteropts(EVFILT_AIO, &aio_filtops); kqueue_add_filteropts(EVFILT_AIO, &aio_filtops);
TAILQ_INIT(&aio_freeproc); TAILQ_INIT(&aio_freeproc);
mtx_init(&aio_freeproc_mtx, "aio_freeproc", NULL, MTX_DEF);
TAILQ_INIT(&aio_jobs); TAILQ_INIT(&aio_jobs);
kaio_zone = uma_zcreate("AIO", sizeof(struct kaioinfo), NULL, NULL, kaio_zone = uma_zcreate("AIO", sizeof(struct kaioinfo), NULL, NULL,
NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
@ -779,7 +782,6 @@ aio_daemon(void *uproc)
struct pgrp *newpgrp; struct pgrp *newpgrp;
struct session *newsess; struct session *newsess;
mtx_lock(&Giant);
/* /*
* Local copies of curproc (cp) and vmspace (myvm) * Local copies of curproc (cp) and vmspace (myvm)
*/ */
@ -796,19 +798,18 @@ aio_daemon(void *uproc)
aiop->aiothread = td; aiop->aiothread = td;
aiop->aiothreadflags |= AIOP_FREE; aiop->aiothreadflags |= AIOP_FREE;
s = splnet();
/* /*
* Place thread (lightweight process) onto the AIO free thread list. * Place thread (lightweight process) onto the AIO free thread list.
*/ */
mtx_lock(&aio_freeproc_mtx);
TAILQ_INSERT_HEAD(&aio_freeproc, aiop, list); TAILQ_INSERT_HEAD(&aio_freeproc, aiop, list);
mtx_unlock(&aio_freeproc_mtx);
splx(s);
/* /*
* Get rid of our current filedescriptors. AIOD's don't need any * Get rid of our current filedescriptors. AIOD's don't need any
* filedescriptors, except as temporarily inherited from the client. * filedescriptors, except as temporarily inherited from the client.
*/ */
mtx_lock(&Giant);
fdfree(td); fdfree(td);
mtx_unlock(&Giant); mtx_unlock(&Giant);
@ -839,12 +840,12 @@ aio_daemon(void *uproc)
/* /*
* Take daemon off of free queue * Take daemon off of free queue
*/ */
mtx_lock(&aio_freeproc_mtx);
if (aiop->aiothreadflags & AIOP_FREE) { if (aiop->aiothreadflags & AIOP_FREE) {
s = splnet();
TAILQ_REMOVE(&aio_freeproc, aiop, list); TAILQ_REMOVE(&aio_freeproc, aiop, list);
aiop->aiothreadflags &= ~AIOP_FREE; aiop->aiothreadflags &= ~AIOP_FREE;
splx(s);
} }
mtx_unlock(&aio_freeproc_mtx);
/* /*
* Check for jobs. * Check for jobs.
@ -973,21 +974,23 @@ aio_daemon(void *uproc)
curcp = mycp; curcp = mycp;
} }
s = splnet(); mtx_lock(&aio_freeproc_mtx);
TAILQ_INSERT_HEAD(&aio_freeproc, aiop, list); TAILQ_INSERT_HEAD(&aio_freeproc, aiop, list);
aiop->aiothreadflags |= AIOP_FREE; aiop->aiothreadflags |= AIOP_FREE;
splx(s);
/* /*
* If daemon is inactive for a long time, allow it to exit, * If daemon is inactive for a long time, allow it to exit,
* thereby freeing resources. * thereby freeing resources.
*/ */
if (tsleep(aiop->aiothread, PRIBIO, "aiordy", aiod_lifetime)) { if (msleep(aiop->aiothread, &aio_freeproc_mtx, PDROP | PRIBIO,
"aiordy", aiod_lifetime)) {
s = splnet(); s = splnet();
if (TAILQ_EMPTY(&aio_jobs)) { if (TAILQ_EMPTY(&aio_jobs)) {
mtx_lock(&aio_freeproc_mtx);
if ((aiop->aiothreadflags & AIOP_FREE) && if ((aiop->aiothreadflags & AIOP_FREE) &&
(num_aio_procs > target_aio_procs)) { (num_aio_procs > target_aio_procs)) {
TAILQ_REMOVE(&aio_freeproc, aiop, list); TAILQ_REMOVE(&aio_freeproc, aiop, list);
mtx_unlock(&aio_freeproc_mtx);
splx(s); splx(s);
uma_zfree(aiop_zone, aiop); uma_zfree(aiop_zone, aiop);
num_aio_procs--; num_aio_procs--;
@ -1000,6 +1003,7 @@ aio_daemon(void *uproc)
#endif #endif
kthread_exit(0); kthread_exit(0);
} }
mtx_unlock(&aio_freeproc_mtx);
} }
splx(s); splx(s);
} }
@ -1252,11 +1256,13 @@ aio_swake_cb(struct socket *so, struct sockbuf *sb)
} }
while (wakecount--) { while (wakecount--) {
mtx_lock(&aio_freeproc_mtx);
if ((aiop = TAILQ_FIRST(&aio_freeproc)) != 0) { if ((aiop = TAILQ_FIRST(&aio_freeproc)) != 0) {
TAILQ_REMOVE(&aio_freeproc, aiop, list); TAILQ_REMOVE(&aio_freeproc, aiop, list);
aiop->aiothreadflags &= ~AIOP_FREE; aiop->aiothreadflags &= ~AIOP_FREE;
wakeup(aiop->aiothread); wakeup(aiop->aiothread);
} }
mtx_unlock(&aio_freeproc_mtx);
} }
} }
@ -1492,7 +1498,7 @@ no_kqueue:
* (thread) due to resource issues, we return an error for now (EAGAIN), * (thread) due to resource issues, we return an error for now (EAGAIN),
* which is likely not the correct thing to do. * which is likely not the correct thing to do.
*/ */
s = splnet(); mtx_lock(&aio_freeproc_mtx);
retryproc: retryproc:
if ((aiop = TAILQ_FIRST(&aio_freeproc)) != NULL) { if ((aiop = TAILQ_FIRST(&aio_freeproc)) != NULL) {
TAILQ_REMOVE(&aio_freeproc, aiop, list); TAILQ_REMOVE(&aio_freeproc, aiop, list);
@ -1502,13 +1508,16 @@ retryproc:
((ki->kaio_active_count + num_aio_resv_start) < ((ki->kaio_active_count + num_aio_resv_start) <
ki->kaio_maxactive_count)) { ki->kaio_maxactive_count)) {
num_aio_resv_start++; num_aio_resv_start++;
mtx_unlock(&aio_freeproc_mtx);
if ((error = aio_newproc()) == 0) { if ((error = aio_newproc()) == 0) {
mtx_lock(&aio_freeproc_mtx);
num_aio_resv_start--; num_aio_resv_start--;
goto retryproc; goto retryproc;
} }
mtx_lock(&aio_freeproc_mtx);
num_aio_resv_start--; num_aio_resv_start--;
} }
splx(s); mtx_unlock(&aio_freeproc_mtx);
done: done:
return (error); return (error);
} }