Author: lstewart
Date: Wed Mar 31 03:58:57 2010
New Revision: 205959
URL: http://svn.freebsd.org/changeset/base/205959

Log:
  Add support for ALQ(9) to be compiled and loaded as a kernel module.
  
  Sponsored by: FreeBSD Foundation
  Reviewed by:  dwmalone, jeff, rpaulo, rwatson
  Approved by:  kmacy (mentor)
  MFC after:    1 month

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

Modified: head/sys/kern/kern_alq.c
==============================================================================
--- head/sys/kern/kern_alq.c    Wed Mar 31 03:20:14 2010        (r205958)
+++ head/sys/kern/kern_alq.c    Wed Mar 31 03:58:57 2010        (r205959)
@@ -1,7 +1,13 @@
 /*-
  * Copyright (c) 2002, Jeffrey Roberson <[email protected]>
+ * Copyright (c) 2008-2009, Lawrence Stewart <[email protected]>
+ * Copyright (c) 2009-2010, 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,6 +33,8 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include "opt_mac.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
@@ -180,9 +188,16 @@ ald_daemon(void)
        ALD_LOCK();
 
        for (;;) {
-               while ((alq = LIST_FIRST(&ald_active)) == NULL)
+               while ((alq = LIST_FIRST(&ald_active)) == NULL &&
+                   !ald_shutingdown)
                        msleep(&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);
                ALD_UNLOCK();
@@ -192,6 +207,8 @@ ald_daemon(void)
                        wakeup(alq);
                ALD_LOCK();
        }
+
+       kproc_exit(0);
 }
 
 static void
@@ -200,14 +217,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 msleep because we hold the ald_mtx.
+        */
+       wakeup(&ald_active);
+
+       /* Wait for ald_daemon to exit. */
+       msleep(ald_proc, &ald_mtx, PWAIT, "aldslp", 0);
+
        ALD_UNLOCK();
 }
 
@@ -510,3 +542,53 @@ 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;
+       
+       ret = 0;
+
+       switch (what) {
+       case MOD_LOAD:
+       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;
+
+       case MOD_UNLOAD:
+               /* If MOD_QUIESCE failed we must fail here too. */
+               if (ald_shutingdown == 0)
+                       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: head/sys/modules/Makefile
==============================================================================
--- head/sys/modules/Makefile   Wed Mar 31 03:20:14 2010        (r205958)
+++ head/sys/modules/Makefile   Wed Mar 31 03:58:57 2010        (r205959)
@@ -20,6 +20,7 @@ SUBDIR=       ${_3dfx} \
        aio \
        alc \
        ale \
+       alq \
        ${_amd} \
        ${_amdsbwd} \
        ${_amdtemp} \

Added: head/sys/modules/alq/Makefile
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/modules/alq/Makefile       Wed Mar 31 03:58:57 2010        
(r205959)
@@ -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>
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to