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 [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to