Remove artificial restriction on lio_listio's operation count
In r322258 I made p1003_1b.aio_listio_max a tunable. However, further investigation shows that there was never any good reason for that limit to exist in the first place. It's used in two completely different ways: * To size a UMA zone, which globally limits the number of concurrent aio_suspend calls. * To artifically limit the number of operations in a single lio_listio call. There doesn't seem to be any memory allocation associated with this limit. This change does two things: * Properly names aio_suspend's UMA zone, and sizes it based on a new constant. * Eliminates the artifical restriction on lio_listio. Instead, lio_listio calls will now be limited by the more generous max_aio_queue_per_proc. The old p1003_1b.aio_listio_max is now an alias for vfs.aio.max_aio_queue_per_proc, so sysconf(3) will still work with _SC_AIO_LISTIO_MAX. Reported by: bde Reviewed by: jhb MFC after: 3 weeks Sponsored by: Spectra Logic Corp Differential Revision: https://reviews.freebsd.org/D12120
This commit is contained in:
parent
010bb3a477
commit
d4f614fd9c
@ -85,10 +85,10 @@ expired before any I/O requests completed.
|
||||
The
|
||||
.Fa iocbs
|
||||
argument
|
||||
contains more than
|
||||
.Dv AIO_LISTIO_MAX
|
||||
asynchronous I/O requests, or at least one of the requests is not
|
||||
valid.
|
||||
contains more asynchronous I/O requests than the
|
||||
.Va vfs.aio.max_aio_queue_per_proc
|
||||
.Xr sysctl 8
|
||||
variable, or at least one of the requests is not valid.
|
||||
.It Bq Er EINTR
|
||||
the suspend was interrupted by a signal.
|
||||
.El
|
||||
|
@ -161,7 +161,7 @@ function will fail if:
|
||||
There are not enough resources to enqueue the requests.
|
||||
.It Bq Er EAGAIN
|
||||
The request would cause the system-wide limit
|
||||
.Dv AIO_MAX
|
||||
.Dv {AIO_MAX}
|
||||
to be exceeded.
|
||||
.It Bq Er EINVAL
|
||||
The
|
||||
@ -173,7 +173,7 @@ nor
|
||||
or
|
||||
.Fa nent
|
||||
is greater than
|
||||
.Dv AIO_LISTIO_MAX .
|
||||
.Dv {AIO_LISTIO_MAX} .
|
||||
.It Bq Er EINVAL
|
||||
The asynchronous notification method in
|
||||
.Fa sig->sigev_notify
|
||||
|
@ -90,11 +90,11 @@ static uint64_t jobseqno;
|
||||
#endif
|
||||
|
||||
#ifndef MAX_AIO_QUEUE_PER_PROC
|
||||
#define MAX_AIO_QUEUE_PER_PROC 256 /* Bigger than AIO_LISTIO_MAX */
|
||||
#define MAX_AIO_QUEUE_PER_PROC 256
|
||||
#endif
|
||||
|
||||
#ifndef MAX_AIO_QUEUE
|
||||
#define MAX_AIO_QUEUE 1024 /* Bigger than AIO_LISTIO_MAX */
|
||||
#define MAX_AIO_QUEUE 1024 /* Bigger than MAX_AIO_QUEUE_PER_PROC */
|
||||
#endif
|
||||
|
||||
#ifndef MAX_BUF_AIO
|
||||
@ -105,6 +105,7 @@ FEATURE(aio, "Asynchronous I/O");
|
||||
SYSCTL_DECL(_p1003_1b);
|
||||
|
||||
static MALLOC_DEFINE(M_LIO, "lio", "listio aio control block list");
|
||||
static MALLOC_DEFINE(M_AIOS, "aios", "aio_suspend aio control block list");
|
||||
|
||||
static SYSCTL_NODE(_vfs, OID_AUTO, aio, CTLFLAG_RW, 0,
|
||||
"Async IO management");
|
||||
@ -169,10 +170,14 @@ static int max_buf_aio = MAX_BUF_AIO;
|
||||
SYSCTL_INT(_vfs_aio, OID_AUTO, max_buf_aio, CTLFLAG_RW, &max_buf_aio, 0,
|
||||
"Maximum buf aio requests per process (stored in the process)");
|
||||
|
||||
static int aio_listio_max = AIO_LISTIO_MAX;
|
||||
/*
|
||||
* Though redundant with vfs.aio.max_aio_queue_per_proc, POSIX requires
|
||||
* sysconf(3) to support AIO_LISTIO_MAX, and we implement that with
|
||||
* vfs.aio.aio_listio_max.
|
||||
*/
|
||||
SYSCTL_INT(_p1003_1b, CTL_P1003_1B_AIO_LISTIO_MAX, aio_listio_max,
|
||||
CTLFLAG_RDTUN | CTLFLAG_CAPRD, &aio_listio_max, 0,
|
||||
"Maximum aio requests for a single lio_listio call");
|
||||
CTLFLAG_RD | CTLFLAG_CAPRD, &max_aio_queue_per_proc,
|
||||
0, "Maximum aio requests for a single lio_listio call");
|
||||
|
||||
#ifdef COMPAT_FREEBSD6
|
||||
typedef struct oaiocb {
|
||||
@ -334,10 +339,9 @@ static int filt_lio(struct knote *kn, long hint);
|
||||
* kaio Per process async io info
|
||||
* aiop async io process data
|
||||
* aiocb async io jobs
|
||||
* aiol list io job pointer - internal to aio_suspend XXX
|
||||
* aiolio list io jobs
|
||||
*/
|
||||
static uma_zone_t kaio_zone, aiop_zone, aiocb_zone, aiol_zone, aiolio_zone;
|
||||
static uma_zone_t kaio_zone, aiop_zone, aiocb_zone, aiolio_zone;
|
||||
|
||||
/* kqueue filters for aio */
|
||||
static struct filterops aio_filtops = {
|
||||
@ -394,11 +398,6 @@ static int
|
||||
aio_onceonly(void)
|
||||
{
|
||||
|
||||
if (aio_listio_max < AIO_LISTIO_MAX)
|
||||
aio_listio_max = AIO_LISTIO_MAX;
|
||||
if (aio_listio_max > MIN(MAX_AIO_QUEUE_PER_PROC, max_queue_count))
|
||||
aio_listio_max = MIN(MAX_AIO_QUEUE_PER_PROC, max_queue_count);
|
||||
|
||||
exit_tag = EVENTHANDLER_REGISTER(process_exit, aio_proc_rundown, NULL,
|
||||
EVENTHANDLER_PRI_ANY);
|
||||
exec_tag = EVENTHANDLER_REGISTER(process_exec, aio_proc_rundown_exec,
|
||||
@ -416,8 +415,6 @@ aio_onceonly(void)
|
||||
NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
|
||||
aiocb_zone = uma_zcreate("AIOCB", sizeof(struct kaiocb), NULL, NULL,
|
||||
NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
|
||||
aiol_zone = uma_zcreate("AIOL", aio_listio_max * sizeof(intptr_t) ,
|
||||
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
|
||||
aiolio_zone = uma_zcreate("AIOLIO", sizeof(struct aioliojob), NULL,
|
||||
NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
|
||||
aiod_lifetime = AIOD_LIFETIME_DEFAULT;
|
||||
@ -1953,7 +1950,7 @@ sys_aio_suspend(struct thread *td, struct aio_suspend_args *uap)
|
||||
struct aiocb **ujoblist;
|
||||
int error;
|
||||
|
||||
if (uap->nent < 0 || uap->nent > aio_listio_max)
|
||||
if (uap->nent < 0 || uap->nent > max_aio_queue_per_proc)
|
||||
return (EINVAL);
|
||||
|
||||
if (uap->timeout) {
|
||||
@ -1964,11 +1961,11 @@ sys_aio_suspend(struct thread *td, struct aio_suspend_args *uap)
|
||||
} else
|
||||
tsp = NULL;
|
||||
|
||||
ujoblist = uma_zalloc(aiol_zone, M_WAITOK);
|
||||
ujoblist = malloc(uap->nent * sizeof(ujoblist[0]), M_AIOS, M_WAITOK);
|
||||
error = copyin(uap->aiocbp, ujoblist, uap->nent * sizeof(ujoblist[0]));
|
||||
if (error == 0)
|
||||
error = kern_aio_suspend(td, uap->nent, ujoblist, tsp);
|
||||
uma_zfree(aiol_zone, ujoblist);
|
||||
free(ujoblist, M_AIOS);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -2161,7 +2158,7 @@ kern_lio_listio(struct thread *td, int mode, struct aiocb * const *uacb_list,
|
||||
if ((mode != LIO_NOWAIT) && (mode != LIO_WAIT))
|
||||
return (EINVAL);
|
||||
|
||||
if (nent < 0 || nent > aio_listio_max)
|
||||
if (nent < 0 || nent > max_aio_queue_per_proc)
|
||||
return (EINVAL);
|
||||
|
||||
if (p->p_aioinfo == NULL)
|
||||
@ -2293,7 +2290,7 @@ freebsd6_lio_listio(struct thread *td, struct freebsd6_lio_listio_args *uap)
|
||||
return (EINVAL);
|
||||
|
||||
nent = uap->nent;
|
||||
if (nent < 0 || nent > aio_listio_max)
|
||||
if (nent < 0 || nent > max_aio_queue_per_proc)
|
||||
return (EINVAL);
|
||||
|
||||
if (uap->sig && (uap->mode == LIO_NOWAIT)) {
|
||||
@ -2330,7 +2327,7 @@ sys_lio_listio(struct thread *td, struct lio_listio_args *uap)
|
||||
return (EINVAL);
|
||||
|
||||
nent = uap->nent;
|
||||
if (nent < 0 || nent > aio_listio_max)
|
||||
if (nent < 0 || nent > max_aio_queue_per_proc)
|
||||
return (EINVAL);
|
||||
|
||||
if (uap->sig && (uap->mode == LIO_NOWAIT)) {
|
||||
@ -2799,7 +2796,7 @@ freebsd32_aio_suspend(struct thread *td, struct freebsd32_aio_suspend_args *uap)
|
||||
uint32_t *ujoblist32;
|
||||
int error, i;
|
||||
|
||||
if (uap->nent < 0 || uap->nent > aio_listio_max)
|
||||
if (uap->nent < 0 || uap->nent > max_aio_queue_per_proc)
|
||||
return (EINVAL);
|
||||
|
||||
if (uap->timeout) {
|
||||
@ -2812,7 +2809,7 @@ freebsd32_aio_suspend(struct thread *td, struct freebsd32_aio_suspend_args *uap)
|
||||
} else
|
||||
tsp = NULL;
|
||||
|
||||
ujoblist = uma_zalloc(aiol_zone, M_WAITOK);
|
||||
ujoblist = malloc(uap->nent * sizeof(ujoblist[0]), M_AIOS, M_WAITOK);
|
||||
ujoblist32 = (uint32_t *)ujoblist;
|
||||
error = copyin(uap->aiocbp, ujoblist32, uap->nent *
|
||||
sizeof(ujoblist32[0]));
|
||||
@ -2822,7 +2819,7 @@ freebsd32_aio_suspend(struct thread *td, struct freebsd32_aio_suspend_args *uap)
|
||||
|
||||
error = kern_aio_suspend(td, uap->nent, ujoblist, tsp);
|
||||
}
|
||||
uma_zfree(aiol_zone, ujoblist);
|
||||
free(ujoblist, M_AIOS);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -2925,7 +2922,7 @@ freebsd6_freebsd32_lio_listio(struct thread *td,
|
||||
return (EINVAL);
|
||||
|
||||
nent = uap->nent;
|
||||
if (nent < 0 || nent > aio_listio_max)
|
||||
if (nent < 0 || nent > max_aio_queue_per_proc)
|
||||
return (EINVAL);
|
||||
|
||||
if (uap->sig && (uap->mode == LIO_NOWAIT)) {
|
||||
@ -2971,7 +2968,7 @@ freebsd32_lio_listio(struct thread *td, struct freebsd32_lio_listio_args *uap)
|
||||
return (EINVAL);
|
||||
|
||||
nent = uap->nent;
|
||||
if (nent < 0 || nent > aio_listio_max)
|
||||
if (nent < 0 || nent > max_aio_queue_per_proc)
|
||||
return (EINVAL);
|
||||
|
||||
if (uap->sig && (uap->mode == LIO_NOWAIT)) {
|
||||
|
Loading…
Reference in New Issue
Block a user