From owner-freebsd-current@FreeBSD.ORG Wed Jun 15 02:20:22 2011 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 367721065670; Wed, 15 Jun 2011 02:20:22 +0000 (UTC) (envelope-from davidxu@freebsd.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 1BDDC8FC21; Wed, 15 Jun 2011 02:20:22 +0000 (UTC) Received: from xyf.my.dom (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id p5F2KJFk016039; Wed, 15 Jun 2011 02:20:20 GMT (envelope-from davidxu@freebsd.org) Message-ID: <4DF816E4.1080003@freebsd.org> Date: Wed, 15 Jun 2011 10:20:20 +0800 From: David Xu User-Agent: Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.9.2.13) Gecko/20110127 Thunderbird/3.1.7 MIME-Version: 1.0 To: Sergey Kandaurov References: <201011010042.oA10gPeg016326@svn.freebsd.org> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Cc: Attilio Rao , FreeBSD Current , Bruce Evans Subject: Re: svn commit: r214611 - head/sys/kern X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 15 Jun 2011 02:20:22 -0000 On 2011/06/14 20:02, Sergey Kandaurov wrote: > On 1 November 2010 03:42, David Xu wrote: >> Author: davidxu >> Date: Mon Nov 1 00:42:25 2010 >> New Revision: 214611 >> URL: http://svn.freebsd.org/changeset/base/214611 >> >> Log: >> Use integer for size of cpuset, as it won't be bigger than INT_MAX, >> This is requested by bge. >> Also move the sysctl into file kern_cpuset.c, because it should >> always be there, it is independent of thread scheduler. > > Hi. > This breaks for me fetching a cpusetsize value with sysconf(3) interface, > as after this change sysconf(3) consumers expect a long return type, while > sysctl kern.sched.cpusetsize has switched from long to int type in kernel. > That makes for me sizeof(cpusize_t) from 8 to incorrect 34359738376. > > In particular, kvm_getpcpu(3) uses sysconf(3) to fetch cpusetsize on > live kernel. That gives me a broken result: > kvm_open: kcpusetsize: 8 > pcpu[0] = 0x801072300 > kvm_open: kcpusetsize: 34359738376 > pcpu[1] = 0xffffffffffffffff > kvm_open: kcpusetsize: 8 > pcpu[2] = 0x801072600 > kvm_open: kcpusetsize: 34359738376 > pcpu[3] = 0xffffffffffffffff > > This small test indicates that that's due to int->long type conversion: > long lvalue; > size_t len; > > len = sizeof(lvalue); > if (sysctlbyname("kern.sched.cpusetsize", &lvalue, &len, NULL, 0) < 0) > err(1, "sysctlbyname"); > printf("sysctl: %ld\n", lvalue); > printf("sysctl: %d -- explicitly casted to (int)\n", (int)lvalue); > printf("sysconf: %ld\n", sysconf(_SC_CPUSET_SIZE)); > printf("sysconf: %d -- explicitly casted to (int)\n", > (int)sysconf(_SC_CPUSET_SIZE)); > > That prints: > sysctl: 34359738376 > sysctl: 8 -- explicitly casted to (int) > sysconf: 34359738376 > sysconf: 8 -- explicitly casted to (int) > > The other way to solve this other than reverting is to "fix" all cpusetsize > consumers in userland. Now sysconf() saves long returned value to int: > > Index: lib/libkvm/kvm_pcpu.c > =================================================================== > --- lib/libkvm/kvm_pcpu.c (revision 223073) > +++ lib/libkvm/kvm_pcpu.c (working copy) > @@ -120,7 +120,7 @@ > void * > kvm_getpcpu(kvm_t *kd, int cpu) > { > - long kcpusetsize; > + int kcpusetsize; > ssize_t nbytes; > uintptr_t readptr; > char *buf; > > So, after applying the above change all is ok: > kvm_open: kcpusetsize: 8 > pcpu[0] = 0x801072300 > kvm_open: kcpusetsize: 8 > pcpu[1] = 0x801072600 > kvm_open: kcpusetsize: 8 > pcpu[2] = 0x801072900 > kvm_open: kcpusetsize: 8 > pcpu[3] = 0x801072c00 > > Try this patch, I think it should fix it. Index: lib/libc/gen/sysconf.c =================================================================== --- lib/libc/gen/sysconf.c (revision 221356) +++ lib/libc/gen/sysconf.c (working copy) @@ -599,11 +599,11 @@ #ifdef _SC_CPUSET_SIZE case _SC_CPUSET_SIZE: - len = sizeof(lvalue); - if (sysctlbyname("kern.sched.cpusetsize", &lvalue, &len, NULL, + len = sizeof(value); + if (sysctlbyname("kern.sched.cpusetsize", &value, &len, NULL, 0) == -1) return (-1); - return (lvalue); + return ((long)(value)); #endif default: