Date: Thu, 11 Jul 2002 15:34:33 -0700 (PDT) From: Matthew Dillon <dillon@apollo.backplane.com> To: John Baldwin <jhb@FreeBSD.ORG> Cc: Alfred Perlstein <bright@mu.org>, freebsd-current@FreeBSD.ORG, Peter Wemm <peter@FreeBSD.ORG>, Julian Elischer <julian@elischer.org> Subject: Proposed fix for SMP vm_zeroidle.c Message-ID: <200207112234.g6BMYXnH012160@apollo.backplane.com> References: <XFMail.20020708204655.jhb@FreeBSD.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Here is my proposed fix for the page-zeroing problem w/ SMP. It
is untested (I'm about to test it)... I'm looking for comments on
the concept. If the comments are positive and my testing succeeds I
will commit it tonight.
Basically the idea is simple. Provide a function that mi_switch() can
call when switching in a thread. The page zeroing code sets this
function to cpu_invlpg(CADDR3) on switch-in, thus dealing with any
potential switch between cpu's with virtually no overhead (no overhead
that we care about anyway).
I daresay that this mechanism could be used for a number of other
purposes as well.
What do you think?
-Matt
Index: i386/i386/pmap.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/i386/pmap.c,v
retrieving revision 1.335
diff -u -r1.335 pmap.c
--- i386/i386/pmap.c 8 Jul 2002 04:24:25 -0000 1.335
+++ i386/i386/pmap.c 11 Jul 2002 22:23:22 -0000
@@ -2687,6 +2687,21 @@
*CMAP2 = 0;
}
+#ifdef SMP
+
+/*
+ * Called with the scheduler lock held when pmap_zero_page_idle() is
+ * switched in, to ensure that we are not working with a stale TLB
+ * entry if we switch cpus.
+ */
+static void
+pmap_zpi_switchin(void)
+{
+ cpu_invlpg(CADDR3);
+}
+
+#endif
+
/*
* pmap_zero_page_idle zeros the specified hardware page by mapping
* the page into KVM and using bzero to clear its contents. This
@@ -2703,12 +2718,9 @@
*CMAP3 = PG_V | PG_RW | phys | PG_A | PG_M;
#ifdef SMP
- mtx_lock(&Giant); /* IPI sender not MPSAFE */
-#endif
- invltlb_1pg((vm_offset_t)CADDR3);
-#ifdef SMP
- mtx_unlock(&Giant);
+ curthread->td_switchin = pmap_zpi_switchin;
#endif
+ cpu_invlpg(CADDR3);
#if defined(I686_CPU)
if (cpu_class == CPUCLASS_686)
@@ -2716,6 +2728,9 @@
else
#endif
bzero(CADDR3, PAGE_SIZE);
+#ifdef SMP
+ curthread->td_switchin = NULL;
+#endif
*CMAP3 = 0;
}
Index: kern/kern_synch.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_synch.c,v
retrieving revision 1.182
diff -u -r1.182 kern_synch.c
--- kern/kern_synch.c 6 Jul 2002 08:47:24 -0000 1.182
+++ kern/kern_synch.c 11 Jul 2002 22:15:05 -0000
@@ -892,6 +892,13 @@
if (PCPU_GET(switchtime.sec) == 0)
binuptime(PCPU_PTR(switchtime));
PCPU_SET(switchticks, ticks);
+
+ /*
+ * Call the switchin function while still holding the scheduler lock
+ * (used by the idlezero code)
+ */
+ if (td->td_switchin)
+ td->td_switchin();
}
/*
Index: sys/proc.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/proc.h,v
retrieving revision 1.227
diff -u -r1.227 proc.h
--- sys/proc.h 8 Jul 2002 01:49:49 -0000 1.227
+++ sys/proc.h 11 Jul 2002 22:13:13 -0000
@@ -285,6 +285,7 @@
int td_intr_nesting_level; /* (k) Interrupt recursion. */
void *td_mailbox; /* the userland mailbox address */
struct ucred *td_ucred; /* (k) Reference to credentials. */
+ void (*td_switchin)(void); /* (k) switchin special func */
#define td_endzero td_md
#define td_startcopy td_endzero
Index: vm/vm_zeroidle.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_zeroidle.c,v
retrieving revision 1.13
diff -u -r1.13 vm_zeroidle.c
--- vm/vm_zeroidle.c 8 Jul 2002 23:12:37 -0000 1.13
+++ vm/vm_zeroidle.c 11 Jul 2002 22:11:50 -0000
@@ -30,11 +30,7 @@
SYSCTL_INT(_vm_stats_misc, OID_AUTO,
cnt_prezero, CTLFLAG_RD, &cnt_prezero, 0, "");
-#ifdef SMP
-static int idlezero_enable = 0;
-#else
static int idlezero_enable = 1;
-#endif
SYSCTL_INT(_vm, OID_AUTO, idlezero_enable, CTLFLAG_RW, &idlezero_enable, 0, "");
TUNABLE_INT("vm.idlezero_enable", &idlezero_enable);
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200207112234.g6BMYXnH012160>
