Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 4 Mar 2010 05:19:46 +0000 (UTC)
From:      Lawrence Stewart <lstewart@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r204688 - in user/lstewart/alq_varlen_head/sys: kern modules modules/alq
Message-ID:  <201003040519.o245Jkst076096@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: lstewart
Date: Thu Mar  4 05:19:46 2010
New Revision: 204688
URL: http://svn.freebsd.org/changeset/base/204688

Log:
  - Import alqkld_9.x.r198700.patch
  
  Sponsored by:	FreeBSD Foundation

Added:
  user/lstewart/alq_varlen_head/sys/modules/alq/
  user/lstewart/alq_varlen_head/sys/modules/alq/Makefile   (contents, props changed)
Modified:
  user/lstewart/alq_varlen_head/sys/kern/kern_alq.c
  user/lstewart/alq_varlen_head/sys/modules/Makefile

Modified: user/lstewart/alq_varlen_head/sys/kern/kern_alq.c
==============================================================================
--- user/lstewart/alq_varlen_head/sys/kern/kern_alq.c	Thu Mar  4 04:53:05 2010	(r204687)
+++ user/lstewart/alq_varlen_head/sys/kern/kern_alq.c	Thu Mar  4 05:19:46 2010	(r204688)
@@ -1,7 +1,13 @@
 /*-
  * Copyright (c) 2002, Jeffrey Roberson <jeff@freebsd.org>
+ * Copyright (c) 2008-2009, Lawrence Stewart <lstewart@freebsd.org>
+ * Copyright (c) 2009, The FreeBSD Foundation
  * All rights reserved.
  *
+ * Portions of this software were developed at the Centre for Advanced
+ * Internet Architectures, Swinburne University of Technology, Melbourne,
+ * Australia by Lawrence Stewart under sponsorship from the FreeBSD Foundation.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -27,8 +33,13 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include "opt_mac.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/alq.h>
+#include <sys/eventhandler.h>
+#include <sys/fcntl.h>
 #include <sys/kernel.h>
 #include <sys/kthread.h>
 #include <sys/lock.h>
@@ -36,12 +47,8 @@ __FBSDID("$FreeBSD$");
 #include <sys/mutex.h>
 #include <sys/namei.h>
 #include <sys/proc.h>
-#include <sys/vnode.h>
-#include <sys/alq.h>
-#include <sys/malloc.h>
 #include <sys/unistd.h>
-#include <sys/fcntl.h>
-#include <sys/eventhandler.h>
+#include <sys/vnode.h>
 
 #include <security/mac/mac_framework.h>
 
@@ -78,7 +85,6 @@ static struct mtx ald_mtx;
 static LIST_HEAD(, alq) ald_queues;
 static LIST_HEAD(, alq) ald_active;
 static int ald_shutingdown = 0;
-struct thread *ald_thread;
 static struct proc *ald_proc;
 
 #define	ALD_LOCK()	mtx_lock(&ald_mtx)
@@ -172,16 +178,21 @@ ald_daemon(void)
 	int needwakeup;
 	struct alq *alq;
 
-	ald_thread = FIRST_THREAD_IN_PROC(ald_proc);
-
 	EVENTHANDLER_REGISTER(shutdown_pre_sync, ald_shutdown, NULL,
 	    SHUTDOWN_PRI_FIRST);
 
 	ALD_LOCK();
 
 	for (;;) {
-		while ((alq = LIST_FIRST(&ald_active)) == NULL)
-			msleep(&ald_active, &ald_mtx, PWAIT, "aldslp", 0);
+		while ((alq = LIST_FIRST(&ald_active)) == NULL &&
+		    !ald_shutingdown)
+			mtx_sleep(&ald_active, &ald_mtx, PWAIT, "aldslp", 0);
+
+		/* Don't shutdown until all active ALQs are flushed. */
+		if (ald_shutingdown && alq == NULL) {
+			ALD_UNLOCK();
+			break;
+		}
 
 		ALQ_LOCK(alq);
 		ald_deactivate(alq);
@@ -189,9 +200,11 @@ ald_daemon(void)
 		needwakeup = alq_doio(alq);
 		ALQ_UNLOCK(alq);
 		if (needwakeup)
-			wakeup(alq);
+			wakeup_one(alq);
 		ALD_LOCK();
 	}
+
+	kproc_exit(0);
 }
 
 static void
@@ -200,14 +213,29 @@ ald_shutdown(void *arg, int howto)
 	struct alq *alq;
 
 	ALD_LOCK();
+
+	/* Ensure no new queues can be created. */
 	ald_shutingdown = 1;
 
+	/* Shutdown all ALQs prior to terminating the ald_daemon. */
 	while ((alq = LIST_FIRST(&ald_queues)) != NULL) {
 		LIST_REMOVE(alq, aq_link);
 		ALD_UNLOCK();
 		alq_shutdown(alq);
 		ALD_LOCK();
 	}
+
+	/* At this point, all ALQs are flushed and shutdown. */
+
+	/*
+	 * Wake ald_daemon so that it exits. It won't be able to do
+	 * anything until we mtx_sleep because we hold the ald_mtx.
+	 */
+	wakeup(&ald_active);
+
+	/* Wait for ald_daemon to exit. */
+	mtx_sleep(ald_proc, &ald_mtx, PWAIT, "aldslp", 0);
+
 	ALD_UNLOCK();
 }
 
@@ -220,14 +248,13 @@ alq_shutdown(struct alq *alq)
 	alq->aq_flags |= AQ_SHUTDOWN;
 
 	/* Drain IO */
-	while (alq->aq_flags & (AQ_FLUSHING|AQ_ACTIVE)) {
+	while (alq->aq_flags & AQ_ACTIVE) {
 		alq->aq_flags |= AQ_WANTED;
 		msleep_spin(alq, &alq->aq_mtx, "aldclose", 0);
 	}
 	ALQ_UNLOCK(alq);
 
-	vn_close(alq->aq_vp, FWRITE, alq->aq_cred,
-	    curthread);
+	vn_close(alq->aq_vp, FWRITE, alq->aq_cred, curthread);
 	crfree(alq->aq_cred);
 }
 
@@ -317,9 +344,9 @@ alq_doio(struct alq *alq)
 }
 
 static struct kproc_desc ald_kp = {
-        "ALQ Daemon",
-        ald_daemon,
-        &ald_proc
+	"ALQ Daemon",
+	ald_daemon,
+	&ald_proc
 };
 
 SYSINIT(aldthread, SI_SUB_KTHREAD_IDLE, SI_ORDER_ANY, kproc_start, &ald_kp);
@@ -431,6 +458,15 @@ alq_get(struct alq *alq, int waitok)
 		msleep_spin(alq, &alq->aq_mtx, "alqget", 0);
 	}
 
+	/*
+	 * We need to serialise wakups to ensure records remain in order...
+	 * Therefore, wakeup the next thread in the queue waiting for
+	 * ALQ resources to be available.
+	 * (Technically this is only required if we actually entered the above
+	 * while loop.)
+	 */
+	wakeup_one(alq);
+
 	if (ale != NULL) {
 		aln = ale->ae_next;
 		if ((aln->ae_flags & AE_VALID) == 0)
@@ -484,7 +520,7 @@ alq_flush(struct alq *alq)
 	ALQ_UNLOCK(alq);
 
 	if (needwakeup)
-		wakeup(alq);
+		wakeup_one(alq);
 }
 
 /*
@@ -510,3 +546,46 @@ alq_close(struct alq *alq)
 	free(alq->aq_entbuf, M_ALD);
 	free(alq, M_ALD);
 }
+
+static int
+alq_load_handler(module_t mod, int what, void *arg)
+{
+	int ret = 0;
+
+	switch(what) {
+		case MOD_LOAD:
+		case MOD_UNLOAD:
+		case MOD_SHUTDOWN:
+			break;
+		
+		case MOD_QUIESCE:
+			ALD_LOCK();
+			/* Only allow unload if there are no open queues. */
+			if (LIST_FIRST(&ald_queues) == NULL) {
+				ald_shutingdown = 1;
+				ALD_UNLOCK();
+				ald_shutdown(NULL, 0);
+				mtx_destroy(&ald_mtx);
+			} else {
+				ALD_UNLOCK();
+				ret = EBUSY;
+			}
+			break;
+		
+		default:
+			ret = EINVAL;
+			break;
+	}
+
+	return (ret);
+}
+
+static moduledata_t alq_mod =
+{
+	"alq",
+	alq_load_handler,
+	NULL
+};
+
+DECLARE_MODULE(alq, alq_mod, SI_SUB_SMP, SI_ORDER_ANY);
+MODULE_VERSION(alq, 1);

Modified: user/lstewart/alq_varlen_head/sys/modules/Makefile
==============================================================================
--- user/lstewart/alq_varlen_head/sys/modules/Makefile	Thu Mar  4 04:53:05 2010	(r204687)
+++ user/lstewart/alq_varlen_head/sys/modules/Makefile	Thu Mar  4 05:19:46 2010	(r204688)
@@ -23,6 +23,7 @@ SUBDIR=	${_3dfx} \
 	${_amd} \
 	${_amdsbwd} \
 	${_amdtemp} \
+	alq \
 	amr \
 	${_an} \
 	${_aout} \

Added: user/lstewart/alq_varlen_head/sys/modules/alq/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/lstewart/alq_varlen_head/sys/modules/alq/Makefile	Thu Mar  4 05:19:46 2010	(r204688)
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+.include <bsd.own.mk>
+
+.PATH:  ${.CURDIR}/../../kern
+KMOD=	alq
+SRCS=	opt_mac.h vnode_if.h kern_alq.c
+
+.include <bsd.kmod.mk>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201003040519.o245Jkst076096>