From owner-freebsd-current Thu Jul 11 15:34:53 2002 Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 8283637B400; Thu, 11 Jul 2002 15:34:39 -0700 (PDT) Received: from apollo.backplane.com (apollo.backplane.com [216.240.41.2]) by mx1.FreeBSD.org (Postfix) with ESMTP id 295C443E52; Thu, 11 Jul 2002 15:34:39 -0700 (PDT) (envelope-from dillon@apollo.backplane.com) Received: from apollo.backplane.com (localhost [127.0.0.1]) by apollo.backplane.com (8.12.5/8.12.4) with ESMTP id g6BMYbLA012164; Thu, 11 Jul 2002 15:34:37 -0700 (PDT) (envelope-from dillon@apollo.backplane.com) Received: (from dillon@localhost) by apollo.backplane.com (8.12.5/8.12.4/Submit) id g6BMYXnH012160; Thu, 11 Jul 2002 15:34:33 -0700 (PDT) (envelope-from dillon) Date: Thu, 11 Jul 2002 15:34:33 -0700 (PDT) From: Matthew Dillon Message-Id: <200207112234.g6BMYXnH012160@apollo.backplane.com> To: John Baldwin Cc: Alfred Perlstein , freebsd-current@FreeBSD.ORG, Peter Wemm , Julian Elischer Subject: Proposed fix for SMP vm_zeroidle.c References: Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG 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