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>