From owner-svn-src-all@FreeBSD.ORG Sun Jan 23 11:08:37 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 356E410656A3; Sun, 23 Jan 2011 11:08:37 +0000 (UTC) (envelope-from uqs@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 242D58FC14; Sun, 23 Jan 2011 11:08:37 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p0NB8buW053204; Sun, 23 Jan 2011 11:08:37 GMT (envelope-from uqs@svn.freebsd.org) Received: (from uqs@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p0NB8bl9053201; Sun, 23 Jan 2011 11:08:37 GMT (envelope-from uqs@svn.freebsd.org) Message-Id: <201101231108.p0NB8bl9053201@svn.freebsd.org> From: Ulrich Spoerlein Date: Sun, 23 Jan 2011 11:08:37 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r217745 - head/lib/libkvm X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 23 Jan 2011 11:08:37 -0000 Author: uqs Date: Sun Jan 23 11:08:36 2011 New Revision: 217745 URL: http://svn.freebsd.org/changeset/base/217745 Log: libkvm: fix process runtime calculation on crashdumps Fix a long standing bug, where the procs ticks where assumed to be in us. Instead, read cpu_tick_frequency from the kernel and use the same logic to convert runtime. This is still too optimistic in that it assumes cpu_tick_frequency is available and fixed. Since this function is only called on crashdumps, I think we can live with that. Testing has shown the values to be correct for different kern.hz inside Virtualbox. Bump WARNS. Alignment issues on some archs mean this is still at 3. Reviewed by: bde Modified: head/lib/libkvm/Makefile head/lib/libkvm/kvm_proc.c Modified: head/lib/libkvm/Makefile ============================================================================== --- head/lib/libkvm/Makefile Sun Jan 23 11:08:28 2011 (r217744) +++ head/lib/libkvm/Makefile Sun Jan 23 11:08:36 2011 (r217745) @@ -15,7 +15,7 @@ KVM_ARCH=${MACHINE_ARCH} KVM_ARCH=${MACHINE_CPUARCH} .endif -WARNS?= 0 +WARNS?= 3 SRCS= kvm.c kvm_${KVM_ARCH}.c kvm_cptime.c kvm_file.c kvm_getloadavg.c \ kvm_getswapinfo.c kvm_pcpu.c kvm_proc.c kvm_vnet.c Modified: head/lib/libkvm/kvm_proc.c ============================================================================== --- head/lib/libkvm/kvm_proc.c Sun Jan 23 11:08:28 2011 (r217744) +++ head/lib/libkvm/kvm_proc.c Sun Jan 23 11:08:36 2011 (r217745) @@ -88,6 +88,25 @@ __FBSDID("$FreeBSD$"); static int ticks; static int hz; +static uint64_t cpu_tick_frequency; + +/* + * From sys/kern/kern_tc.c. Depends on cpu_tick_frequency, which is + * read/initialized before this function is ever called. + */ +static uint64_t +cputick2usec(uint64_t tick) +{ + + if (cpu_tick_frequency == 0) + return (0); + if (tick > 18446744073709551) /* floor(2^64 / 1000) */ + return (tick / (cpu_tick_frequency / 1000000)); + else if (tick > 18446744073709) /* floor(2^64 / 1000000) */ + return ((tick * 1000) / (cpu_tick_frequency / 1000)); + else + return ((tick * 1000000) / cpu_tick_frequency); +} /* * Read proc's from memory file into buffer bp, which has space to hold @@ -113,7 +132,6 @@ kvm_proclist(kvm_t *kd, int what, int ar struct thread mtd; struct proc proc; struct proc pproc; - struct timeval tv; struct sysentvec sysent; char svname[KI_EMULNAMELEN]; @@ -367,15 +385,7 @@ nopgrp: kp->ki_lockname, LOCKNAMELEN); kp->ki_lockname[LOCKNAMELEN] = 0; } - /* - * XXX: This is plain wrong, rux_runtime has nothing - * to do with struct bintime, rux_runtime is just a 64-bit - * integer counter of cputicks. What we need here is a way - * to convert cputicks to usecs. The kernel does it in - * kern/kern_tc.c, but the function can't be just copied. - */ - bintime2timeval(&proc.p_rux.rux_runtime, &tv); - kp->ki_runtime = (u_int64_t)tv.tv_sec * 1000000 + tv.tv_usec; + kp->ki_runtime = cputick2usec(proc.p_rux.rux_runtime); kp->ki_pid = proc.p_pid; kp->ki_siglist = proc.p_siglist; SIGSETOR(kp->ki_siglist, mtd.td_siglist); @@ -542,14 +552,15 @@ kvm_getprocs(kvm_t *kd, int op, int arg, liveout: nprocs = size == 0 ? 0 : size / kd->procbase->ki_structsize; } else { - struct nlist nl[6], *p; + struct nlist nl[7], *p; nl[0].n_name = "_nprocs"; nl[1].n_name = "_allproc"; nl[2].n_name = "_zombproc"; nl[3].n_name = "_ticks"; nl[4].n_name = "_hz"; - nl[5].n_name = 0; + nl[5].n_name = "_cpu_tick_frequency"; + nl[6].n_name = 0; if (kvm_nlist(kd, nl) != 0) { for (p = nl; p->n_type != 0; ++p) @@ -570,6 +581,11 @@ liveout: _kvm_err(kd, kd->program, "can't read hz"); return (0); } + if (KREAD(kd, nl[5].n_value, &cpu_tick_frequency)) { + _kvm_err(kd, kd->program, + "can't read cpu_tick_frequency"); + return (0); + } size = nprocs * sizeof(struct kinfo_proc); kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size); if (kd->procbase == 0)