Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 23 Oct 2017 23:12:01 +0000 (UTC)
From:      Alan Somers <asomers@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r324941 - in head: lib/libc/sys sys/kern
Message-ID:  <201710232312.v9NNC1B0011025@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: asomers
Date: Mon Oct 23 23:12:01 2017
New Revision: 324941
URL: https://svnweb.freebsd.org/changeset/base/324941

Log:
  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

Modified:
  head/lib/libc/sys/aio_suspend.2
  head/lib/libc/sys/lio_listio.2
  head/sys/kern/vfs_aio.c

Modified: head/lib/libc/sys/aio_suspend.2
==============================================================================
--- head/lib/libc/sys/aio_suspend.2	Mon Oct 23 23:05:29 2017	(r324940)
+++ head/lib/libc/sys/aio_suspend.2	Mon Oct 23 23:12:01 2017	(r324941)
@@ -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: head/lib/libc/sys/lio_listio.2
==============================================================================
--- head/lib/libc/sys/lio_listio.2	Mon Oct 23 23:05:29 2017	(r324940)
+++ head/lib/libc/sys/lio_listio.2	Mon Oct 23 23:12:01 2017	(r324941)
@@ -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: head/sys/kern/vfs_aio.c
==============================================================================
--- head/sys/kern/vfs_aio.c	Mon Oct 23 23:05:29 2017	(r324940)
+++ head/sys/kern/vfs_aio.c	Mon Oct 23 23:12:01 2017	(r324941)
@@ -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_
 	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_
 	} 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 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)
@@ -2293,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)) {
@@ -2330,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)) {
@@ -2799,7 +2796,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) {
@@ -2812,7 +2809,7 @@ 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]));
@@ -2822,7 +2819,7 @@ freebsd32_aio_suspend(struct thread *td, struct freebs
 
 		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 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?201710232312.v9NNC1B0011025>