PERFORCE change 64358 for review
John Baldwin
jhb at FreeBSD.org
Fri Nov 5 11:23:19 PST 2004
http://perforce.freebsd.org/chv.cgi?CH=64358
Change 64358 by jhb at 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) <<<
More information about the p4-projects
mailing list