From owner-cvs-src@FreeBSD.ORG Mon Jul 28 21:44:36 2008 Return-Path: Delivered-To: cvs-src@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id AB1891065670; Mon, 28 Jul 2008 21:44:36 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from server.baldwin.cx (bigknife-pt.tunnel.tserv9.chi1.ipv6.he.net [IPv6:2001:470:1f10:75::2]) by mx1.freebsd.org (Postfix) with ESMTP id 2D78C8FC0C; Mon, 28 Jul 2008 21:44:36 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from localhost.corp.yahoo.com (john@localhost [IPv6:::1]) (authenticated bits=0) by server.baldwin.cx (8.14.2/8.14.2) with ESMTP id m6SLhwaC004973; Mon, 28 Jul 2008 17:44:28 -0400 (EDT) (envelope-from jhb@FreeBSD.org) From: John Baldwin To: src-committers@FreeBSD.org Date: Mon, 28 Jul 2008 16:47:37 -0400 User-Agent: KMail/1.9.7 References: <200807282039.m6SKdU1T073711@repoman.freebsd.org> In-Reply-To: <200807282039.m6SKdU1T073711@repoman.freebsd.org> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-15" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200807281647.37400.jhb@freebsd.org> X-Greylist: Sender succeeded SMTP AUTH authentication, not delayed by milter-greylist-2.0.2 (server.baldwin.cx [IPv6:::1]); Mon, 28 Jul 2008 17:44:30 -0400 (EDT) X-Virus-Scanned: ClamAV 0.93.1/7868/Mon Jul 28 14:31:43 2008 on server.baldwin.cx X-Virus-Status: Clean X-Spam-Status: No, score=-2.5 required=4.2 tests=AWL,BAYES_00,NO_RELAYS autolearn=ham version=3.1.3 X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on server.baldwin.cx Cc: cvs-src@FreeBSD.org, cvs-all@FreeBSD.org Subject: Re: cvs commit: src/sys/kern sched_4bsd.c X-BeenThere: cvs-src@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: CVS commit messages for the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 28 Jul 2008 21:44:36 -0000 On Monday 28 July 2008 04:39:21 pm John Baldwin wrote: > jhb 2008-07-28 20:39:21 UTC > > FreeBSD src repository > > Modified files: > sys/kern sched_4bsd.c > Log: > SVN rev 180937 on 2008-07-28 20:39:21Z by jhb > > When choosing a CPU for a thread in a cpuset, prefer the last CPU that the > thread ran on if there are no other CPUs in the set with a shorter per-CPU > runqueue. I used the test program below. Prior to this change, the two child processes bounced between the two CPUs constantly. With this patch on an otherwise-idle box, they only switched CPUs once after starting. With ULE they switch CPUs occasionally (once every few seconds) but not nearly as bad as 4BSD before this patch (multiple switches per second). Granted, this is a very contrived test. :) Note that I ran this on a 4-CPU box and used CPUs 2 and 3. You can change which CPUs are used by changing the 'cpus[]' array. This is also quite x86 specific. :) #include #include #include #include #include #include int apic_ids[2]; int cpus[2] = { 2, 3 }; int apic_id(void) { u_int regs[4]; do_cpuid(1, regs); return (regs[1] >> 24); } void check_id(pid_t pid, int *id) { int new; new = apic_id(); if (*id == new) return; printf("%d: moved from APIC ID %d to APIC ID %d\n", pid, *id, new); *id = new; } void child(void) { int last_id; pid_t pid; int i; pid = getpid(); last_id = apic_id(); printf("%d: starting on APIC ID %d\n", pid, last_id); for (;;) { for (i = 0; i < 10000000; i++) check_id(pid, &last_id); usleep(5); check_id(pid, &last_id); } } int main(int ac, char **av) { cpuset_t set; int i; for (i = 0; i < 2; i++) { CPU_ZERO(&set); CPU_SET(cpus[i], &set); if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, sizeof(set), &set)) err(1, "cpuset_affinity(%d)", cpus[i]); apic_ids[i] = apic_id(); printf("CPU%d has APIC ID %d\n", cpus[i], apic_ids[i]); } CPU_ZERO(&set); for (i = 0; i < 2; i++) CPU_SET(cpus[i], &set); if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, sizeof(set), &set)) err(1, "cpuset_affinity"); for (i = 0; i < 2; i++) { switch (fork()) { case -1: err(1, "fork"); case 0: break; default: child(); } } for (i = 0; i < 2; i++) wait(NULL); return (0); } -- John Baldwin