changeset 9973:7911cfe2424f

6815882 aio_cleanup_thread() can get stuck after missing to process the aio_doneq
author Surya Prakki <Surya.Prakki@Sun.COM>
date Thu, 25 Jun 2009 21:42:33 -0700
parents 20b62d0bb64b
children 206607ab68be
files usr/src/uts/common/os/aio.c usr/src/uts/common/os/aio_subr.c usr/src/uts/common/sys/aio_impl.h
diffstat 3 files changed, 31 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/os/aio.c	Fri Jun 26 10:06:56 2009 +0800
+++ b/usr/src/uts/common/os/aio.c	Thu Jun 25 21:42:33 2009 -0700
@@ -2594,15 +2594,11 @@
 				aiop->aio_rqclnup = 0;
 				rqclnup = 1;
 			}
-
-			if ((rqclnup || AS_ISUNMAPWAIT(as)) &&
-			    aiop->aio_doneq) {
+			mutex_exit(&as->a_contents);
+			if (aiop->aio_doneq) {
 				aio_req_t *doneqhead = aiop->aio_doneq;
-				mutex_exit(&as->a_contents);
 				aiop->aio_doneq = NULL;
 				aio_cleanupq_concat(aiop, doneqhead, AIO_DONEQ);
-			} else {
-				mutex_exit(&as->a_contents);
 			}
 		}
 		mutex_exit(&aiop->aio_mutex);
--- a/usr/src/uts/common/os/aio_subr.c	Fri Jun 26 10:06:56 2009 +0800
+++ b/usr/src/uts/common/os/aio_subr.c	Thu Jun 25 21:42:33 2009 -0700
@@ -20,12 +20,10 @@
  */
 
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <sys/types.h>
 #include <sys/proc.h>
 #include <sys/file.h>
@@ -60,7 +58,7 @@
 static void aio_sigev_send(proc_t *, sigqueue_t *);
 static void aio_hash_delete(aio_t *, aio_req_t *);
 static void aio_lio_free(aio_t *, aio_lio_t *);
-static void aio_cleanup_cleanupq(aio_t *, aio_req_t *, int);
+static int aio_cleanup_cleanupq(aio_t *, aio_req_t *, int);
 static int aio_cleanup_notifyq(aio_t *, aio_req_t *, int);
 static void aio_cleanup_pollq(aio_t *, aio_req_t *, int);
 static void aio_cleanup_portq(aio_t *, aio_req_t *, int);
@@ -103,11 +101,11 @@
 #endif	/* _ILP32 */
 
 	TNF_PROBE_5(aphysio_start, "kaio", /* CSTYLED */,
-		tnf_opaque, bp, bp,
-		tnf_device, device, dev,
-		tnf_offset, blkno, btodt(uio->uio_loffset),
-		tnf_size, size, uio->uio_iov->iov_len,
-		tnf_bioflags, rw, rw);
+	    tnf_opaque, bp, bp,
+	    tnf_device, device, dev,
+	    tnf_offset, blkno, btodt(uio->uio_loffset),
+	    tnf_size, size, uio->uio_iov->iov_len,
+	    tnf_bioflags, rw, rw);
 
 	if (rw == B_READ) {
 		CPU_STATS_ADD_K(sys, phread, 1);
@@ -216,11 +214,11 @@
 	fd = reqp->aio_req_fd;
 
 	TNF_PROBE_5(aphysio_end, "kaio", /* CSTYLED */,
-		tnf_opaque, bp, bp,
-		tnf_device, device, bp->b_edev,
-		tnf_offset, blkno, btodt(reqp->aio_req_uio.uio_loffset),
-		tnf_size, size, reqp->aio_req_uio.uio_iov->iov_len,
-		tnf_bioflags, rw, (bp->b_flags & (B_READ|B_WRITE)));
+	    tnf_opaque, bp, bp,
+	    tnf_device, device, bp->b_edev,
+	    tnf_offset, blkno, btodt(reqp->aio_req_uio.uio_loffset),
+	    tnf_size, size, reqp->aio_req_uio.uio_iov->iov_len,
+	    tnf_bioflags, rw, (bp->b_flags & (B_READ|B_WRITE)));
 
 	/*
 	 * mapout earlier so that more kmem is available when aio is
@@ -408,9 +406,13 @@
 		/*
 		 * Send a SIGIO signal when the process has a handler enabled.
 		 */
-		if ((func = PTOU(p)->u_signal[SIGIO - 1]) != SIG_DFL &&
-		    func != SIG_IGN)
+		if ((func = PTOU(p)->u_signal[SIGIO - 1]) !=
+		    SIG_DFL && (func != SIG_IGN)) {
 			psignal(p, SIGIO);
+			mutex_enter(&aiop->aio_mutex);
+			reqp->aio_req_flags |= AIO_SIGNALLED;
+			mutex_exit(&aiop->aio_mutex);
+		}
 	}
 	if (pkevp)
 		port_send_event(pkevp);
@@ -482,8 +484,8 @@
 	flags = (((bp->b_flags & B_READ) == B_READ) ? S_WRITE : S_READ);
 	if (reqp->aio_req_flags & AIO_PAGELOCKDONE) {
 		as_pageunlock(bp->b_proc->p_as,
-			bp->b_flags & B_SHADOW ? bp->b_shadow : NULL,
-			iov->iov_base, iov->iov_len, flags);
+		    bp->b_flags & B_SHADOW ? bp->b_shadow : NULL,
+		    iov->iov_base, iov->iov_len, flags);
 		reqp->aio_req_flags &= ~AIO_PAGELOCKDONE;
 	}
 	bp->b_flags &= ~(B_BUSY|B_WANTED|B_PHYS|B_SHADOW);
@@ -747,7 +749,7 @@
 	 * do cleanup for the various queues.
 	 */
 	if (cleanupqhead)
-		aio_cleanup_cleanupq(aiop, cleanupqhead, exitflg);
+		signalled = aio_cleanup_cleanupq(aiop, cleanupqhead, exitflg);
 	mutex_exit(&aiop->aio_cleanupq_mutex);
 	if (notifyqhead)
 		signalled = aio_cleanup_notifyq(aiop, notifyqhead, exitflg);
@@ -882,10 +884,11 @@
 /*
  * Do cleanup for every element of the cleanupq.
  */
-static void
+static int
 aio_cleanup_cleanupq(aio_t *aiop, aio_req_t *qhead, int exitflg)
 {
 	aio_req_t *reqp, *next;
+	int signalled = 0;
 
 	ASSERT(MUTEX_HELD(&aiop->aio_cleanupq_mutex));
 
@@ -897,7 +900,7 @@
 	 * loop from aio_req_done() and aio_req_find().
 	 */
 	if ((reqp = qhead) == NULL)
-		return;
+		return (0);
 	do {
 		ASSERT(reqp->aio_req_flags & AIO_CLEANUPQ);
 		ASSERT(reqp->aio_req_portkev == NULL);
@@ -908,8 +911,11 @@
 			aio_req_free(aiop, reqp);
 		else
 			aio_enq(&aiop->aio_doneq, reqp, AIO_DONEQ);
+		if (!exitflg && reqp->aio_req_flags & AIO_SIGNALLED)
+			signalled++;
 		mutex_exit(&aiop->aio_mutex);
 	} while ((reqp = next) != qhead);
+	return (signalled);
 }
 
 /*
--- a/usr/src/uts/common/sys/aio_impl.h	Fri Jun 26 10:06:56 2009 +0800
+++ b/usr/src/uts/common/sys/aio_impl.h	Thu Jun 25 21:42:33 2009 -0700
@@ -155,7 +155,8 @@
 #define	AIO_DONEQ	0x80			/* aio req is on the doneq */
 #define	AIO_ZEROLEN	0x100			/* aio req is zero length */
 #define	AIO_PAGELOCKDONE	0x200		/* aio called as_pagelock() */
-#define	AIO_CLOSE_PORT		0x400		/* port is being closed */
+#define	AIO_CLOSE_PORT	0x400		/* port is being closed */
+#define	AIO_SIGNALLED	0x800		/* process signalled by this req */
 
 /* flag argument of aio_cleanup() */