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>