Date: Tue, 28 Nov 2017 17:04:22 +0000 (UTC) From: Alan Somers <asomers@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r326322 - in stable/11: lib/libc/sys sys/kern Message-ID: <201711281704.vASH4MCK078598@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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)) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201711281704.vASH4MCK078598>