svn commit: r326322 - in stable/11: lib/libc/sys sys/kern
Alan Somers
asomers at FreeBSD.org
Tue Nov 28 17:04:24 UTC 2017
Author: asomers
Date: Tue Nov 28 17:04:22 2017
New Revision: 326322
URL: https://svnweb.freebsd.org/changeset/base/326322
Log:
MFC r322258, r324941, r324956, r325018
r322258:
Make p1003_1b.aio_listio_max a tunable
p1003_1b.aio_listio_max is now a tunable. Its value is reflected in the
sysctl of the same name, and the sysconf(3) variable _SC_AIO_LISTIO_MAX.
Its value will be bounded from below by the compile-time constant
AIO_LISTIO_MAX and from above by the compile-time constant
MAX_AIO_QUEUE_PER_PROC and the tunable vfs.aio.max_aio_queue.
Reviewed by: jhb, kib
Relnotes: yes
Sponsored by: Spectra Logic Corp
Differential Revision: https://reviews.freebsd.org/D11601
r324941:
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
Sponsored by: Spectra Logic Corp
Differential Revision: https://reviews.freebsd.org/D12120
r324956:
Bump man page revision dates for r324941
Reported by: jhb
X-MFC-with: 324941
Sponsored by: Spectra Logic Corp
r325018:
Fix aio_suspend in 32-bit emulation
An off-by-one error has been present since the system call was first present
in 185878. It additionally became a memory corruption bug after change
324941. The failure is actually revealed by our existing AIO tests.
However, apparently nobody's been running those in 32-bit emulation mode.
Reported by: Coverity, cem
CID: 1382114
X-MFC-With: 324941
Sponsored by: Spectra Logic Corp
Modified:
stable/11/lib/libc/sys/aio_suspend.2
stable/11/lib/libc/sys/lio_listio.2
stable/11/sys/kern/posix4_mib.c
stable/11/sys/kern/vfs_aio.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/lib/libc/sys/aio_suspend.2
==============================================================================
--- stable/11/lib/libc/sys/aio_suspend.2 Tue Nov 28 16:52:38 2017 (r326321)
+++ stable/11/lib/libc/sys/aio_suspend.2 Tue Nov 28 17:04:22 2017 (r326322)
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd June 2, 1999
+.Dd Oct 23, 2017
.Dt AIO_SUSPEND 2
.Os
.Sh NAME
@@ -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
Modified: stable/11/lib/libc/sys/lio_listio.2
==============================================================================
--- stable/11/lib/libc/sys/lio_listio.2 Tue Nov 28 16:52:38 2017 (r326321)
+++ stable/11/lib/libc/sys/lio_listio.2 Tue Nov 28 17:04:22 2017 (r326322)
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 15, 2016
+.Dd Oct 23, 2017
.Dt LIO_LISTIO 2
.Os
.Sh NAME
@@ -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
Modified: stable/11/sys/kern/posix4_mib.c
==============================================================================
--- stable/11/sys/kern/posix4_mib.c Tue Nov 28 16:52:38 2017 (r326321)
+++ stable/11/sys/kern/posix4_mib.c Tue Nov 28 17:04:22 2017 (r326322)
@@ -91,7 +91,6 @@ P1B_SYSCTL(CTL_P1003_1B_FSYNC, fsync);
P1B_SYSCTL(CTL_P1003_1B_SHARED_MEMORY_OBJECTS, shared_memory_objects);
P1B_SYSCTL(CTL_P1003_1B_SYNCHRONIZED_IO, synchronized_io);
P1B_SYSCTL(CTL_P1003_1B_TIMERS, timers);
-P1B_SYSCTL(CTL_P1003_1B_AIO_LISTIO_MAX, aio_listio_max);
P1B_SYSCTL(CTL_P1003_1B_AIO_MAX, aio_max);
P1B_SYSCTL(CTL_P1003_1B_AIO_PRIO_DELTA_MAX, aio_prio_delta_max);
P1B_SYSCTL(CTL_P1003_1B_DELAYTIMER_MAX, delaytimer_max);
Modified: stable/11/sys/kern/vfs_aio.c
==============================================================================
--- stable/11/sys/kern/vfs_aio.c Tue Nov 28 16:52:38 2017 (r326321)
+++ stable/11/sys/kern/vfs_aio.c Tue Nov 28 17:04:22 2017 (r326322)
@@ -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
@@ -102,8 +102,10 @@ static uint64_t jobseqno;
#endif
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");
@@ -168,6 +170,15 @@ 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)");
+/*
+ * 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_RD | CTLFLAG_CAPRD, &max_aio_queue_per_proc,
+ 0, "Maximum aio requests for a single lio_listio call");
+
#ifdef COMPAT_FREEBSD6
typedef struct oaiocb {
int aio_fildes; /* File descriptor */
@@ -328,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 = {
@@ -405,14 +415,11 @@ 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;
jobrefid = 1;
p31b_setcfg(CTL_P1003_1B_ASYNCHRONOUS_IO, _POSIX_ASYNCHRONOUS_IO);
- p31b_setcfg(CTL_P1003_1B_AIO_LISTIO_MAX, AIO_LISTIO_MAX);
p31b_setcfg(CTL_P1003_1B_AIO_MAX, MAX_AIO_QUEUE);
p31b_setcfg(CTL_P1003_1B_AIO_PRIO_DELTA_MAX, 0);
@@ -1943,7 +1950,7 @@ sys_aio_suspend(struct thread *td, struct aio_suspend_
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) {
@@ -1954,11 +1961,11 @@ sys_aio_suspend(struct thread *td, struct aio_suspend_
} 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);
}
@@ -2151,7 +2158,7 @@ kern_lio_listio(struct thread *td, int mode, struct ai
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)
@@ -2283,7 +2290,7 @@ freebsd6_lio_listio(struct thread *td, struct freebsd6
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)) {
@@ -2320,7 +2327,7 @@ sys_lio_listio(struct thread *td, struct lio_listio_ar
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)) {
@@ -2785,7 +2792,7 @@ freebsd32_aio_suspend(struct thread *td, struct freebs
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) {
@@ -2798,17 +2805,17 @@ freebsd32_aio_suspend(struct thread *td, struct freebs
} 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]));
if (error == 0) {
- for (i = uap->nent; i > 0; i--)
+ for (i = uap->nent - 1; i >= 0; i--)
ujoblist[i] = PTRIN(ujoblist32[i]);
error = kern_aio_suspend(td, uap->nent, ujoblist, tsp);
}
- uma_zfree(aiol_zone, ujoblist);
+ free(ujoblist, M_AIOS);
return (error);
}
@@ -2911,7 +2918,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)) {
@@ -2957,7 +2964,7 @@ freebsd32_lio_listio(struct thread *td, struct freebsd
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)) {
More information about the svn-src-stable-11
mailing list