Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 5 Nov 2004 19:23:17 GMT
From:      John Baldwin <jhb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 64358 for review
Message-ID:  <200411051923.iA5JNHEG024858@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=64358

Change 64358 by jhb@jhb_slimer on 2004/11/05 19:22:55

	IFC @64357 (loop back some changes).

Affected files ...

.. //depot/projects/smpng/sys/alpha/alpha/machdep.c#72 integrate
.. //depot/projects/smpng/sys/alpha/alpha/mp_machdep.c#30 integrate
.. //depot/projects/smpng/sys/alpha/include/pcpu.h#4 integrate
.. //depot/projects/smpng/sys/alpha/include/smp.h#4 integrate
.. //depot/projects/smpng/sys/amd64/amd64/busdma_machdep.c#12 integrate
.. //depot/projects/smpng/sys/amd64/amd64/mp_machdep.c#15 integrate
.. //depot/projects/smpng/sys/arm/arm/critical.c#2 integrate
.. //depot/projects/smpng/sys/dev/snp/snp.c#19 integrate
.. //depot/projects/smpng/sys/geom/mirror/g_mirror.c#11 integrate
.. //depot/projects/smpng/sys/geom/mirror/g_mirror.h#4 integrate
.. //depot/projects/smpng/sys/geom/raid3/g_raid3.c#6 integrate
.. //depot/projects/smpng/sys/geom/raid3/g_raid3.h#4 integrate
.. //depot/projects/smpng/sys/i386/acpica/acpi_asus.c#8 integrate
.. //depot/projects/smpng/sys/kern/kern_intr.c#58 integrate
.. //depot/projects/smpng/sys/kern/kern_shutdown.c#52 integrate
.. //depot/projects/smpng/sys/kern/kern_subr.c#37 integrate
.. //depot/projects/smpng/sys/kern/kern_thread.c#72 integrate
.. //depot/projects/smpng/sys/netgraph/ng_base.c#27 integrate
.. //depot/projects/smpng/sys/sys/syslog.h#5 integrate
.. //depot/projects/smpng/sys/vm/swap_pager.c#51 integrate
.. //depot/projects/smpng/sys/vm/vm_object.c#60 integrate
.. //depot/projects/smpng/sys/vm/vm_pageout.c#51 integrate
.. //depot/projects/smpng/sys/vm/vm_zeroidle.c#22 integrate

Differences ...

==== //depot/projects/smpng/sys/alpha/alpha/machdep.c#72 (text+ko) ====

@@ -88,7 +88,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/alpha/alpha/machdep.c,v 1.223 2004/09/05 02:09:51 julian Exp $");
+__FBSDID("$FreeBSD: src/sys/alpha/alpha/machdep.c,v 1.224 2004/11/05 19:16:43 jhb Exp $");
 
 #include "opt_compat.h"
 #include "opt_ddb.h"

==== //depot/projects/smpng/sys/alpha/alpha/mp_machdep.c#30 (text+ko) ====

@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/alpha/alpha/mp_machdep.c,v 1.52 2004/01/07 23:00:20 jhb Exp $");
+__FBSDID("$FreeBSD: src/sys/alpha/alpha/mp_machdep.c,v 1.53 2004/11/05 19:16:43 jhb Exp $");
 
 #include "opt_kstack_pages.h"
 

==== //depot/projects/smpng/sys/alpha/include/pcpu.h#4 (text+ko) ====

@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/alpha/include/pcpu.h,v 1.14 2001/12/11 23:33:39 jhb Exp $
+ * $FreeBSD: src/sys/alpha/include/pcpu.h,v 1.15 2004/11/05 19:16:44 jhb Exp $
  */
 
 #ifndef	_MACHINE_PCPU_H_

==== //depot/projects/smpng/sys/alpha/include/smp.h#4 (text+ko) ====

@@ -6,7 +6,7 @@
  * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
  * ----------------------------------------------------------------------------
  *
- * $FreeBSD: src/sys/alpha/include/smp.h,v 1.6 2001/08/13 22:41:15 jhb Exp $
+ * $FreeBSD: src/sys/alpha/include/smp.h,v 1.7 2004/11/05 19:16:44 jhb Exp $
  *
  */
 

==== //depot/projects/smpng/sys/amd64/amd64/busdma_machdep.c#12 (text+ko) ====

@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/busdma_machdep.c,v 1.58 2004/09/08 04:54:18 scottl Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/busdma_machdep.c,v 1.59 2004/11/05 18:24:01 peter Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -33,12 +33,14 @@
 #include <sys/bus.h>
 #include <sys/interrupt.h>
 #include <sys/kernel.h>
+#include <sys/ktr.h>
 #include <sys/lock.h>
 #include <sys/proc.h>
 #include <sys/mutex.h>
 #include <sys/mbuf.h>
 #include <sys/uio.h>
 #include <sys/sysctl.h>
+#include <sys/ktr.h>
 
 #include <vm/vm.h>
 #include <vm/vm_page.h>
@@ -218,8 +220,11 @@
 	*dmat = NULL;
 
 	newtag = (bus_dma_tag_t)malloc(sizeof(*newtag), M_DEVBUF, M_NOWAIT);
-	if (newtag == NULL)
+	if (newtag == NULL) {
+		CTR3(KTR_BUSDMA, "bus_dma_tag_create returned tag %p tag "
+		    "flags 0x%x error %d", newtag, 0, error);
 		return (ENOMEM);
+	}
 
 	newtag->parent = parent;
 	newtag->alignment = alignment;
@@ -296,16 +301,26 @@
 	} else {
 		*dmat = newtag;
 	}
+	CTR3(KTR_BUSDMA, "bus_dma_tag_create returned tag %p tag flags 0x%x "
+	    "error %d", newtag, (newtag != NULL ? newtag->flags : 0), error);
 	return (error);
 }
 
 int
 bus_dma_tag_destroy(bus_dma_tag_t dmat)
 {
+	bus_dma_tag_t dmat_copy;
+	int error;
+
+	error = 0;
+	dmat_copy = dmat;
+
 	if (dmat != NULL) {
 
-		if (dmat->map_count != 0)
-			return (EBUSY);
+		if (dmat->map_count != 0) {
+			error = EBUSY;
+			goto out;
+		}
 
 		while (dmat != NULL) {
 			bus_dma_tag_t parent;
@@ -326,7 +341,10 @@
 				dmat = NULL;
 		}
 	}
-	return (0);
+out:
+	CTR2(KTR_BUSDMA, "bus_dma_tag_destroy tag %p error %d", dmat_copy,
+	    error);
+	return (error);
 }
 
 /*
@@ -344,8 +362,11 @@
 		dmat->segments = (bus_dma_segment_t *)malloc(
 		    sizeof(bus_dma_segment_t) * dmat->nsegments, M_DEVBUF,
 		    M_NOWAIT);
-		if (dmat->segments == NULL)
+		if (dmat->segments == NULL) {
+			CTR2(KTR_BUSDMA, "bus_dmamap_create: tag %p error %d",
+			    dmat, ENOMEM);
 			return (ENOMEM);
+		}
 	}
 
 	/*
@@ -360,8 +381,11 @@
 
 		*mapp = (bus_dmamap_t)malloc(sizeof(**mapp), M_DEVBUF,
 					     M_NOWAIT | M_ZERO);
-		if (*mapp == NULL)
+		if (*mapp == NULL) {
+			CTR2(KTR_BUSDMA, "bus_dmamap_create: tag %p error %d",
+			    dmat, ENOMEM);
 			return (ENOMEM);
+		}
 
 		/* Initialize the new map */
 		STAILQ_INIT(&((*mapp)->bpages));
@@ -400,6 +424,8 @@
 	}
 	if (error == 0)
 		dmat->map_count++;
+	CTR3(KTR_BUSDMA, "bus_dmamap_create: tag %p tag flags 0x%x error %d",
+	    dmat, dmat->flags, error);
 	return (error);
 }
 
@@ -411,11 +437,15 @@
 bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map)
 {
 	if (map != NULL && map != &nobounce_dmamap) {
-		if (STAILQ_FIRST(&map->bpages) != NULL)
+		if (STAILQ_FIRST(&map->bpages) != NULL) {
+			CTR2(KTR_BUSDMA, "bus_dmamap_destroy: tag %p error %d",
+			    dmat, EBUSY);
 			return (EBUSY);
+		}
 		free(map, M_DEVBUF);
 	}
 	dmat->map_count--;
+	CTR1(KTR_BUSDMA, "bus_dmamap_destroy: tag %p error 0", dmat);
 	return (0);
 }
 
@@ -445,8 +475,11 @@
 		dmat->segments = (bus_dma_segment_t *)malloc(
 		    sizeof(bus_dma_segment_t) * dmat->nsegments, M_DEVBUF,
 		    M_NOWAIT);
-		if (dmat->segments == NULL)
+		if (dmat->segments == NULL) {
+			CTR3(KTR_BUSDMA, "bus_dmamem_alloc: tag %p tag "
+			    "flags 0x%x error %d", dmat, dmat->flags, ENOMEM);
 			return (ENOMEM);
+		}
 	}
 
 	if ((dmat->maxsize <= PAGE_SIZE) &&
@@ -463,8 +496,13 @@
 		    0ul, dmat->lowaddr, dmat->alignment? dmat->alignment : 1ul,
 		    dmat->boundary);
 	}
-	if (*vaddr == NULL)
+	if (*vaddr == NULL) {
+		CTR3(KTR_BUSDMA, "bus_dmamem_alloc: tag %p tag flags 0x%x "
+		    "error %d", dmat, dmat->flags, ENOMEM);
 		return (ENOMEM);
+	}
+	CTR3(KTR_BUSDMA, "bus_dmamem_alloc: tag %p tag flags 0x%x error %d",
+	    dmat, dmat->flags, ENOMEM);
 	return (0);
 }
 
@@ -487,6 +525,8 @@
 	else {
 		contigfree(vaddr, dmat->maxsize, M_DEVBUF);
 	}
+	CTR2(KTR_BUSDMA, "bus_dmamem_free: tag %p flags 0x%x", dmat,
+	    dmat->flags);
 }
 
 /*
@@ -495,11 +535,11 @@
  * the starting segment on entrace, and the ending segment on exit.
  * first indicates if this is the first invocation of this function.
  */
-static int
+static __inline int
 _bus_dmamap_load_buffer(bus_dma_tag_t dmat,
     			bus_dmamap_t map,
 			void *buf, bus_size_t buflen,
-			struct thread *td,
+			pmap_t pmap,
 			int flags,
 			bus_addr_t *lastaddrp,
 			int *segp,
@@ -512,23 +552,22 @@
 	bus_addr_t paddr;
 	int needbounce = 0;
 	int seg;
-	pmap_t pmap;
 
 	segs = dmat->segments;
 
 	if (map == NULL)
 		map = &nobounce_dmamap;
 
-	if (td != NULL)
-		pmap = vmspace_pmap(td->td_proc->p_vmspace);
-	else
-		pmap = NULL;
-
-	if ((dmat->lowaddr < ptoa((vm_paddr_t)Maxmem)
-	 || dmat->boundary > 0 || dmat->alignment > 1)
-	 && map != &nobounce_dmamap && map->pagesneeded == 0) {
+	if ((map != &nobounce_dmamap && map->pagesneeded == 0) 
+	 && (dmat->lowaddr < ptoa((vm_paddr_t)Maxmem)
+	 || dmat->boundary > 0 || dmat->alignment > 1)) {
 		vm_offset_t	vendaddr;
 
+		CTR4(KTR_BUSDMA, "lowaddr= %d Maxmem= %d, boundary= %d, "
+		    "alignment= %d", dmat->lowaddr, ptoa((vm_paddr_t)Maxmem),
+		    dmat->boundary, dmat->alignment);
+		CTR3(KTR_BUSDMA, "map= %p, nobouncemap= %p, pagesneeded= %d",
+		    map, &nobounce_dmamap, map->pagesneeded);
 		/*
 		 * Count the number of bounce pages
 		 * needed in order to complete this transfer
@@ -544,10 +583,9 @@
 			}
 			vaddr += PAGE_SIZE;
 		}
+		CTR1(KTR_BUSDMA, "pagesneeded= %d\n", map->pagesneeded);
 	}
 
-	vaddr = (vm_offset_t)buf;
-
 	/* Reserve Necessary Bounce Pages */
 	if (map->pagesneeded != 0) {
 		mtx_lock(&bounce_lock);
@@ -571,6 +609,7 @@
 		mtx_unlock(&bounce_lock);
 	}
 
+	vaddr = (vm_offset_t)buf;
 	lastaddr = *lastaddrp;
 	bmask = ~(dmat->boundary - 1);
 
@@ -658,14 +697,19 @@
 	error = _bus_dmamap_load_buffer(dmat, map, buf, buflen, NULL, flags,
 	     &lastaddr, &nsegs, 1);
 
-	if (error == EINPROGRESS)
+	if (error == EINPROGRESS) {
+		CTR3(KTR_BUSDMA, "bus_dmamap_load: tag %p tag flags 0x%x "
+		    "error %d", dmat, dmat->flags, error);
 		return (error);
+	}
 
 	if (error)
 		(*callback)(callback_arg, dmat->segments, 0, error);
 	else
 		(*callback)(callback_arg, dmat->segments, nsegs + 1, 0);
 
+	CTR2(KTR_BUSDMA, "bus_dmamap_load: tag %p tag flags 0x%x error 0",
+	    dmat, dmat->flags);
 	return (0);
 }
 
@@ -711,6 +755,8 @@
 		(*callback)(callback_arg, dmat->segments,
 			    nsegs+1, m0->m_pkthdr.len, error);
 	}
+	CTR3(KTR_BUSDMA, "bus_dmamap_load_mbuf: tag %p tag flags 0x%x "
+	    "error %d", dmat, dmat->flags, error);
 	return (error);
 }
 
@@ -727,17 +773,18 @@
 	int nsegs, error, first, i;
 	bus_size_t resid;
 	struct iovec *iov;
-	struct thread *td = NULL;
+	pmap_t pmap;
 
 	flags |= BUS_DMA_NOWAIT;
 	resid = uio->uio_resid;
 	iov = uio->uio_iov;
 
 	if (uio->uio_segflg == UIO_USERSPACE) {
-		td = uio->uio_td;
-		KASSERT(td != NULL,
+		KASSERT(uio->uio_td != NULL,
 			("bus_dmamap_load_uio: USERSPACE but no proc"));
-	}
+		pmap = vmspace_pmap(uio->uio_td->td_proc->p_vmspace);
+	} else
+		pmap = NULL;
 
 	nsegs = 0;
 	error = 0;
@@ -754,7 +801,7 @@
 		if (minlen > 0) {
 			error = _bus_dmamap_load_buffer(dmat, map,
 					addr, minlen,
-					td, flags, &lastaddr, &nsegs, first);
+					pmap, flags, &lastaddr, &nsegs, first);
 			first = 0;
 
 			resid -= minlen;
@@ -768,6 +815,8 @@
 		(*callback)(callback_arg, dmat->segments,
 			    nsegs+1, uio->uio_resid, error);
 	}
+	CTR3(KTR_BUSDMA, "bus_dmamap_load_uio: tag %p tag flags 0x%x "
+	    "error %d", dmat, dmat->flags, error);
 	return (error);
 }
 
@@ -797,6 +846,8 @@
 		 * the caches on broken hardware
 		 */
 		total_bounced++;
+		CTR3(KTR_BUSDMA, "_bus_dmamap_sync: tag %p tag flags 0x%x "
+		    "op 0x%x performing bounce", op, dmat, dmat->flags);
 
 		if (op & BUS_DMASYNC_PREWRITE) {
 			while (bpage != NULL) {

==== //depot/projects/smpng/sys/amd64/amd64/mp_machdep.c#15 (text+ko) ====

@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/amd64/amd64/mp_machdep.c,v 1.247 2004/09/29 01:59:10 peter Exp $");
+__FBSDID("$FreeBSD: src/sys/amd64/amd64/mp_machdep.c,v 1.248 2004/11/05 18:25:22 peter Exp $");
 
 #include "opt_cpu.h"
 #include "opt_kstack_pages.h"
@@ -127,6 +127,7 @@
 struct cpu_info {
 	int	cpu_present:1;
 	int	cpu_bsp:1;
+	int	cpu_disabled:1;
 } static cpu_info[MAXCPU];
 static int cpu_apic_ids[MAXCPU];
 
@@ -350,7 +351,11 @@
 	/* List CPUs */
 	printf(" cpu0 (BSP): APIC ID: %2d\n", boot_cpu_id);
 	for (i = 1, x = 0; x < MAXCPU; x++) {
-		if (cpu_info[x].cpu_present && !cpu_info[x].cpu_bsp) {
+		if (!cpu_info[x].cpu_present || cpu_info[x].cpu_bsp)
+			continue;
+		if (cpu_info[x].cpu_disabled)
+			printf("  cpu (AP): APIC ID: %2d (disabled)\n", x);
+		else {
 			KASSERT(i < mp_ncpus,
 			    ("mp_ncpus and actual cpus are out of whack"));
 			printf(" cpu%d (AP): APIC ID: %2d\n", i++, x);
@@ -582,9 +587,19 @@
 	/* start each AP */
 	cpu = 0;
 	for (apic_id = 0; apic_id < MAXCPU; apic_id++) {
+
+		/* Ignore non-existent CPUs and the BSP. */
 		if (!cpu_info[apic_id].cpu_present ||
 		    cpu_info[apic_id].cpu_bsp)
 			continue;
+
+		/* Don't use this CPU if it has been disabled by a tunable. */
+		if (resource_disabled("lapic", apic_id)) {
+			cpu_info[apic_id].cpu_disabled = 1;
+			mp_ncpus--;
+			continue;
+		}
+
 		cpu++;
 
 		/* save APIC ID for this logical ID */

==== //depot/projects/smpng/sys/arm/arm/critical.c#2 (text+ko) ====

@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/arm/arm/critical.c,v 1.1 2004/05/14 11:46:42 cognet Exp $");
+__FBSDID("$FreeBSD: src/sys/arm/arm/critical.c,v 1.2 2004/11/05 18:29:45 cognet Exp $");
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/signalvar.h>
@@ -46,5 +46,7 @@
 void
 cpu_critical_fork_exit(void)
 {
+
+	curthread->td_md.md_savecrit = __set_cpsr_c(0, 0) &~ I32_bit;
 }
 

==== //depot/projects/smpng/sys/dev/snp/snp.c#19 (text+ko) ====

@@ -15,7 +15,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/snp/snp.c,v 1.94 2004/09/24 08:12:41 phk Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/snp/snp.c,v 1.95 2004/11/05 18:32:14 cognet Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -119,7 +119,20 @@
 static int		snp_down(struct snoop *snp);
 static int		snp_in(struct snoop *snp, char *buf, int n);
 static int		snp_modevent(module_t mod, int what, void *arg);
+static struct snoop	*ttytosnp(struct tty *);
 
+static struct snoop *
+ttytosnp(struct tty *tp)
+{
+	struct snoop *snp;
+	
+	LIST_FOREACH(snp, &snp_sclist, snp_list) {
+		if (snp->snp_tty == tp)
+			return (snp);
+	}
+	return (NULL);
+}
+
 static int
 snplclose(tp, flag)
 	struct tty *tp;
@@ -128,7 +141,7 @@
 	struct snoop *snp;
 	int error;
 
-	snp = tp->t_sc;
+	snp = ttytosnp(tp);
 	error = snp_down(snp);
 	if (error != 0)
 		return (error);
@@ -150,7 +163,7 @@
 
 	error = 0;
 	ibuf = NULL;
-	snp = tp->t_sc;
+	snp = ttytosnp(tp);
 	while (uio->uio_resid > 0) {
 		ilen = imin(512, uio->uio_resid);
 		ibuf = malloc(ilen, M_SNP, M_WAITOK);
@@ -217,8 +230,7 @@
 	tp = snp->snp_tty;
 	if (tp == NULL)
 		return (EIO);
-	if ((tp->t_sc == snp) && (tp->t_state & TS_SNOOP) &&
-	    tp->t_line == snooplinedisc)
+	if ((tp->t_state & TS_SNOOP) && tp->t_line == snooplinedisc)
 		goto tty_input;
 
 	printf("snp%d: attempt to write to bad tty\n", snp->snp_unit);
@@ -442,9 +454,7 @@
 	if (tp == NULL)
 		goto detach_notty;
 
-	if (tp && (tp->t_sc == snp) && (tp->t_state & TS_SNOOP) &&
-	    tp->t_line == snooplinedisc) {
-		tp->t_sc = NULL;
+	if ((tp->t_state & TS_SNOOP) && tp->t_line == snooplinedisc) {
 		tp->t_state &= ~TS_SNOOP;
 		tp->t_line = snp->snp_olddisc;
 	} else
@@ -530,7 +540,6 @@
 				tpo->t_state &= ~TS_SNOOP;
 		}
 
-		tp->t_sc = (caddr_t)snp;
 		tp->t_state |= TS_SNOOP;
 		snp->snp_olddisc = tp->t_line;
 		tp->t_line = snooplinedisc;

==== //depot/projects/smpng/sys/geom/mirror/g_mirror.c#11 (text+ko) ====

@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/geom/mirror/g_mirror.c,v 1.38 2004/10/14 07:55:29 pjd Exp $");
+__FBSDID("$FreeBSD: src/sys/geom/mirror/g_mirror.c,v 1.43 2004/11/05 17:18:39 pjd Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -37,9 +37,8 @@
 #include <sys/bio.h>
 #include <sys/sysctl.h>
 #include <sys/malloc.h>
-#include <sys/bitstring.h>
+#include <sys/eventhandler.h>
 #include <vm/uma.h>
-#include <machine/atomic.h>
 #include <geom/geom.h>
 #include <sys/proc.h>
 #include <sys/kthread.h>
@@ -58,6 +57,10 @@
 TUNABLE_INT("kern.geom.mirror.timeout", &g_mirror_timeout);
 SYSCTL_UINT(_kern_geom_mirror, OID_AUTO, timeout, CTLFLAG_RW, &g_mirror_timeout,
     0, "Time to wait on all mirror components");
+static u_int g_mirror_idletime = 5;
+TUNABLE_INT("kern.geom.mirror.idletime", &g_mirror_idletime);
+SYSCTL_UINT(_kern_geom_mirror, OID_AUTO, idletime, CTLFLAG_RW,
+    &g_mirror_idletime, 0, "Mark components as clean when idling");
 static u_int g_mirror_reqs_per_sync = 5;
 SYSCTL_UINT(_kern_geom_mirror, OID_AUTO, reqs_per_sync, CTLFLAG_RW,
     &g_mirror_reqs_per_sync, 0,
@@ -73,17 +76,22 @@
 	G_MIRROR_DEBUG(4, "%s: Woken up %p.", __func__, (ident));	\
 } while (0)
 
+static eventhandler_tag g_mirror_ehtag = NULL;
 
 static int g_mirror_destroy_geom(struct gctl_req *req, struct g_class *mp,
     struct g_geom *gp);
 static g_taste_t g_mirror_taste;
+static void g_mirror_init(struct g_class *mp);
+static void g_mirror_fini(struct g_class *mp);
 
 struct g_class g_mirror_class = {
 	.name = G_MIRROR_CLASS_NAME,
 	.version = G_VERSION,
 	.ctlreq = g_mirror_config,
 	.taste = g_mirror_taste,
-	.destroy_geom = g_mirror_destroy_geom
+	.destroy_geom = g_mirror_destroy_geom,
+	.init = g_mirror_init,
+	.fini = g_mirror_fini
 };
 
 
@@ -291,7 +299,7 @@
 g_mirror_is_busy(struct g_mirror_softc *sc, struct g_consumer *cp)
 {
 
-	if (cp->nstart != cp->nend) {
+	if (cp->index > 0) {
 		G_MIRROR_DEBUG(2,
 		    "I/O requests for %s exist, can't destroy it now.",
 		    cp->provider->name);
@@ -331,6 +339,7 @@
 
 	disk->d_consumer = g_new_consumer(disk->d_softc->sc_geom);
 	disk->d_consumer->private = disk;
+	disk->d_consumer->index = 0;
 	error = g_attach(disk->d_consumer, pp);
 	if (error != 0)
 		return (error);
@@ -451,6 +460,8 @@
 		g_mirror_destroy_provider(sc);
 	for (disk = LIST_FIRST(&sc->sc_disks); disk != NULL;
 	    disk = LIST_FIRST(&sc->sc_disks)) {
+		disk->d_flags &= ~G_MIRROR_DISK_FLAG_DIRTY;
+		g_mirror_update_metadata(disk);
 		g_mirror_destroy_disk(disk);
 	}
 	while ((ep = g_mirror_event_get(sc)) != NULL) {
@@ -705,6 +716,68 @@
 	}
 }
 
+static void
+g_mirror_idle(struct g_mirror_softc *sc)
+{
+	struct g_mirror_disk *disk;
+
+	if (sc->sc_provider == NULL || sc->sc_provider->acw == 0)
+		return;
+	sc->sc_idle = 1;
+	g_topology_lock();
+	LIST_FOREACH(disk, &sc->sc_disks, d_next) {
+		if (disk->d_state != G_MIRROR_DISK_STATE_ACTIVE)
+			continue;
+		G_MIRROR_DEBUG(1, "Disk %s (device %s) marked as clean.",
+		    g_mirror_get_diskname(disk), sc->sc_name);
+		disk->d_flags &= ~G_MIRROR_DISK_FLAG_DIRTY;
+		g_mirror_update_metadata(disk);
+	}
+	g_topology_unlock();
+}
+
+static void
+g_mirror_unidle(struct g_mirror_softc *sc)
+{
+	struct g_mirror_disk *disk;
+
+	sc->sc_idle = 0;
+	g_topology_lock();
+	LIST_FOREACH(disk, &sc->sc_disks, d_next) {
+		if (disk->d_state != G_MIRROR_DISK_STATE_ACTIVE)
+			continue;
+		G_MIRROR_DEBUG(1, "Disk %s (device %s) marked as dirty.",
+		    g_mirror_get_diskname(disk), sc->sc_name);
+		disk->d_flags |= G_MIRROR_DISK_FLAG_DIRTY;
+		g_mirror_update_metadata(disk);
+	}
+	g_topology_unlock();
+}
+
+/*
+ * Return 1 if we should check if mirror is idling.
+ */
+static int
+g_mirror_check_idle(struct g_mirror_softc *sc)
+{
+	struct g_mirror_disk *disk;
+
+	if (sc->sc_idle)
+		return (0);
+	if (sc->sc_provider != NULL && sc->sc_provider->acw == 0)
+		return (0);
+	/*
+	 * Check if there are no in-flight requests.
+	 */
+	LIST_FOREACH(disk, &sc->sc_disks, d_next) {
+		if (disk->d_state != G_MIRROR_DISK_STATE_ACTIVE)
+			continue;
+		if (disk->d_consumer->index > 0)
+			return (0);
+	}
+	return (1);
+}
+
 static __inline int
 bintime_cmp(struct bintime *bt1, struct bintime *bt2)
 {
@@ -752,6 +825,7 @@
 
 	g_topology_assert_not();
 
+	bp->bio_from->index--;
 	pbp = bp->bio_parent;
 	sc = pbp->bio_to->geom->softc;
 	disk = bp->bio_from->private;
@@ -907,6 +981,7 @@
 	disk->d_sync.ds_offset += bp->bio_length;
 	bp->bio_to = sc->sc_provider;
 	G_MIRROR_LOGREQ(3, bp, "Sending synchronization request.");
+	disk->d_sync.ds_consumer->index++;
 	g_io_request(bp, disk->d_sync.ds_consumer);
 }
 
@@ -916,6 +991,7 @@
 	struct g_mirror_softc *sc;
 	struct g_mirror_disk *disk;
 
+	bp->bio_from->index--;
 	sc = bp->bio_from->geom->softc;
 	disk = bp->bio_from->private;
 	if (disk == NULL) {
@@ -941,13 +1017,15 @@
 			g_destroy_bio(bp);
 			return;
 		}
+		G_MIRROR_LOGREQ(3, bp,
+		    "Synchronization request half-finished.");
 		bp->bio_cmd = BIO_WRITE;
 		bp->bio_cflags = 0;
-		G_MIRROR_LOGREQ(3, bp, "Synchronization request finished.");
 		cp = disk->d_consumer;
 		KASSERT(cp->acr == 0 && cp->acw == 1 && cp->ace == 1,
 		    ("Consumer %s not opened (r%dw%de%d).", cp->provider->name,
 		    cp->acr, cp->acw, cp->ace));
+		cp->index++;
 		g_io_request(bp, cp);
 		return;
 	    }
@@ -1031,6 +1109,7 @@
 	KASSERT(cp->acr > 0 && cp->ace > 0,
 	    ("Consumer %s not opened (r%dw%de%d).", cp->provider->name, cp->acr,
 	    cp->acw, cp->ace));
+	cp->index++;
 	g_io_request(cbp, cp);
 }
 
@@ -1065,6 +1144,7 @@
 	KASSERT(cp->acr > 0 && cp->ace > 0,
 	    ("Consumer %s not opened (r%dw%de%d).", cp->provider->name, cp->acr,
 	    cp->acw, cp->ace));
+	cp->index++;
 	g_io_request(cbp, cp);
 }
 
@@ -1112,6 +1192,7 @@
 	KASSERT(cp->acr > 0 && cp->ace > 0,
 	    ("Consumer %s not opened (r%dw%de%d).", cp->provider->name, cp->acr,
 	    cp->acw, cp->ace));
+	cp->index++;
 	g_io_request(cbp, cp);
 }
 
@@ -1180,6 +1261,7 @@
 		KASSERT(cp->acr > 0 && cp->ace > 0,
 		    ("Consumer %s not opened (r%dw%de%d).", cp->provider->name,
 		    cp->acr, cp->acw, cp->ace));
+		disk->d_consumer->index++;
 		g_io_request(cbp, disk->d_consumer);
 	}
 }
@@ -1216,6 +1298,8 @@
 		struct g_consumer *cp;
 		struct bio *cbp;
 
+		if (sc->sc_idle)
+			g_mirror_unidle(sc);
 		/*
 		 * Allocate all bios before sending any request, so we can
 		 * return ENOMEM in nice and clean way.
@@ -1267,6 +1351,7 @@
 			G_MIRROR_LOGREQ(3, cbp, "Sending request.");
 			cp = cbp->bio_caller1;
 			cbp->bio_caller1 = NULL;
+			cp->index++;
 			g_io_request(cbp, cp);
 		}
 		/*
@@ -1445,8 +1530,29 @@
 			goto sleep;
 		}
 		if (bp == NULL) {
-			MSLEEP(sc, &sc->sc_queue_mtx, PRIBIO | PDROP, "m:w1", 0);
-			G_MIRROR_DEBUG(5, "%s: I'm here 3.", __func__);
+			if (g_mirror_check_idle(sc)) {
+				u_int idletime;
+
+				idletime = g_mirror_idletime;
+				if (idletime == 0)
+					idletime = 1;
+				idletime *= hz;
+				if (msleep(sc, &sc->sc_queue_mtx, PRIBIO | PDROP,
+				    "m:w1", idletime) == EWOULDBLOCK) {
+					G_MIRROR_DEBUG(5, "%s: I'm here 3.",
+					    __func__);
+					/*
+					 * No I/O requests in 'idletime' seconds,
+					 * so mark components as clean.
+					 */
+					g_mirror_idle(sc);
+				}
+				G_MIRROR_DEBUG(5, "%s: I'm here 4.", __func__);
+			} else {
+				MSLEEP(sc, &sc->sc_queue_mtx, PRIBIO | PDROP,
+				    "m:w2", 0);
+				G_MIRROR_DEBUG(5, "%s: I'm here 5.", __func__);
+			}
 			continue;
 		}
 		nreqs++;
@@ -1460,26 +1566,26 @@
 
 			g_mirror_sync_request(bp);
 sleep:
-			sps = atomic_load_acq_int(&g_mirror_syncs_per_sec);
+			sps = g_mirror_syncs_per_sec;
 			if (sps == 0) {
-				G_MIRROR_DEBUG(5, "%s: I'm here 5.", __func__);
+				G_MIRROR_DEBUG(5, "%s: I'm here 6.", __func__);
 				continue;
 			}
 			mtx_lock(&sc->sc_queue_mtx);
 			if (bioq_first(&sc->sc_queue) != NULL) {
 				mtx_unlock(&sc->sc_queue_mtx);
-				G_MIRROR_DEBUG(5, "%s: I'm here 4.", __func__);
+				G_MIRROR_DEBUG(5, "%s: I'm here 7.", __func__);
 				continue;
 			}
 			timeout = hz / sps;
 			if (timeout == 0)
 				timeout = 1;
-			MSLEEP(sc, &sc->sc_queue_mtx, PRIBIO | PDROP, "m:w2",
+			MSLEEP(sc, &sc->sc_queue_mtx, PRIBIO | PDROP, "m:w3",
 			    timeout);
 		} else {
 			g_mirror_register_request(bp);
 		}
-		G_MIRROR_DEBUG(5, "%s: I'm here 6.", __func__);
+		G_MIRROR_DEBUG(5, "%s: I'm here 8.", __func__);
 	}
 }
 
@@ -1565,6 +1671,7 @@
 	    sc->sc_name, g_mirror_get_diskname(disk)));
 	disk->d_sync.ds_consumer = g_new_consumer(sc->sc_sync.ds_geom);
 	disk->d_sync.ds_consumer->private = disk;
+	disk->d_sync.ds_consumer->index = 0;
 	error = g_attach(disk->d_sync.ds_consumer, disk->d_softc->sc_provider);
 	KASSERT(error == 0, ("Cannot attach to %s (error=%d).",
 	    disk->d_softc->sc_name, error));
@@ -1911,20 +2018,15 @@
 		break;
 	    }
 	case G_MIRROR_DEVICE_STATE_RUNNING:
-		if (g_mirror_ndisks(sc, -1) == 0) {
-			/*
-			 * No disks at all, we need to destroy device.
-			 */
-			sc->sc_flags |= G_MIRROR_DEVICE_FLAG_DESTROY;
-			break;
-		} else if (g_mirror_ndisks(sc,
-		    G_MIRROR_DISK_STATE_ACTIVE) == 0 &&
+		if (g_mirror_ndisks(sc, G_MIRROR_DISK_STATE_ACTIVE) == 0 &&
 		    g_mirror_ndisks(sc, G_MIRROR_DISK_STATE_NEW) == 0) {
 			/*
-			 * No active disks, destroy provider.
+			 * No active disks or no disks at all,
+			 * so destroy device.
 			 */
 			if (sc->sc_provider != NULL)
 				g_mirror_destroy_provider(sc);
+			sc->sc_flags |= G_MIRROR_DEVICE_FLAG_DESTROY;
 			break;
 		} else if (g_mirror_ndisks(sc,
 		    G_MIRROR_DISK_STATE_ACTIVE) > 0 &&
@@ -2410,6 +2512,7 @@
 	sc->sc_ndisks = md->md_all;
 	sc->sc_flags = md->md_mflags;
 	sc->sc_bump_syncid = 0;
+	sc->sc_idle = 0;
 	bioq_init(&sc->sc_queue);
 	mtx_init(&sc->sc_queue_mtx, "gmirror:queue", NULL, MTX_DEF);
 	LIST_INIT(&sc->sc_disks);
@@ -2446,8 +2549,8 @@
 	/*
 	 * Run timeout.
 	 */
-	timeout = atomic_load_acq_int(&g_mirror_timeout);
-	callout_reset(&sc->sc_callout, timeout * hz, g_mirror_go, sc);
+	timeout = g_mirror_timeout * hz;
+	callout_reset(&sc->sc_callout, timeout, g_mirror_go, sc);
 	return (sc->sc_geom);
 }
 
@@ -2694,6 +2797,44 @@
 	}
 }
 
+static void
+g_mirror_shutdown(void *arg, int howto)
+{
+	struct g_class *mp;
+	struct g_geom *gp, *gp2;
+
+	mp = arg;
+	g_topology_lock();
+	LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) {
+		if (gp->softc == NULL)
+			continue;
+		g_mirror_destroy(gp->softc, 1);
+	}
+	g_topology_unlock();
+#if 0
+	tsleep(&gp, PRIBIO, "m:shutdown", hz * 20);
+#endif
+}
+
+static void
+g_mirror_init(struct g_class *mp)
+{
+
+	g_mirror_ehtag = EVENTHANDLER_REGISTER(shutdown_post_sync,
+	    g_mirror_shutdown, mp, SHUTDOWN_PRI_FIRST);
+	if (g_mirror_ehtag == NULL)
+		G_MIRROR_DEBUG(0, "Warning! Cannot register shutdown event.");
+}
+
+static void
+g_mirror_fini(struct g_class *mp)
+{
+
+	if (g_mirror_ehtag == NULL)
+		return;
+	EVENTHANDLER_DEREGISTER(shutdown_post_sync, g_mirror_ehtag);
+}
+
 static int
 g_mirror_can_go(void)
 {

==== //depot/projects/smpng/sys/geom/mirror/g_mirror.h#4 (text+ko) ====

@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/geom/mirror/g_mirror.h,v 1.10 2004/09/28 07:33:37 pjd Exp $
+ * $FreeBSD: src/sys/geom/mirror/g_mirror.h,v 1.11 2004/11/05 09:05:15 pjd Exp $
  */
 
 #ifndef	_G_MIRROR_H_
@@ -174,6 +174,7 @@
 	u_int		sc_syncid;	/* Synchronization ID. */
 	int		sc_bump_syncid;
 	struct g_mirror_device_sync sc_sync;
+	int		sc_idle;	/* DIRTY flags removed. */
 
 	TAILQ_HEAD(, g_mirror_event) sc_events;
 	struct mtx	sc_events_mtx;

==== //depot/projects/smpng/sys/geom/raid3/g_raid3.c#6 (text+ko) ====

@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/geom/raid3/g_raid3.c,v 1.18 2004/09/28 07:33:37 pjd Exp $");
+__FBSDID("$FreeBSD: src/sys/geom/raid3/g_raid3.c,v 1.22 2004/11/05 17:18:39 pjd Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -37,7 +37,7 @@
 #include <sys/bio.h>
 #include <sys/sysctl.h>
 #include <sys/malloc.h>
-#include <sys/bitstring.h>
+#include <sys/eventhandler.h>
 #include <vm/uma.h>
 #include <machine/atomic.h>
 #include <geom/geom.h>
@@ -55,8 +55,13 @@
 SYSCTL_UINT(_kern_geom_raid3, OID_AUTO, debug, CTLFLAG_RW, &g_raid3_debug, 0,
     "Debug level");
 static u_int g_raid3_timeout = 4;
+TUNABLE_INT("kern.geom.raid3.timeout", &g_raid3_timeout);
 SYSCTL_UINT(_kern_geom_raid3, OID_AUTO, timeout, CTLFLAG_RW, &g_raid3_timeout,
     0, "Time to wait on all raid3 components");

>>> TRUNCATED FOR MAIL (1000 lines) <<<



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