From owner-freebsd-bugs@FreeBSD.ORG Tue Mar 9 17:50:02 2010 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A3788106566B for ; Tue, 9 Mar 2010 17:50:02 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 66DEA8FC19 for ; Tue, 9 Mar 2010 17:50:02 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id o29Ho2Pd093348 for ; Tue, 9 Mar 2010 17:50:02 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id o29Ho2Js093347; Tue, 9 Mar 2010 17:50:02 GMT (envelope-from gnats) Resent-Date: Tue, 9 Mar 2010 17:50:02 GMT Resent-Message-Id: <201003091750.o29Ho2Js093347@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Petr Salinger Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 22885106566B for ; Tue, 9 Mar 2010 17:44:10 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21]) by mx1.freebsd.org (Postfix) with ESMTP id 121F48FC13 for ; Tue, 9 Mar 2010 17:44:10 +0000 (UTC) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.14.3/8.14.3) with ESMTP id o29Hi9I5027930 for ; Tue, 9 Mar 2010 17:44:09 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.14.3/8.14.3/Submit) id o29Hi9G9027929; Tue, 9 Mar 2010 17:44:09 GMT (envelope-from nobody) Message-Id: <201003091744.o29Hi9G9027929@www.freebsd.org> Date: Tue, 9 Mar 2010 17:44:09 GMT From: Petr Salinger To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: kern/144584: bogus values in linprocfs X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 09 Mar 2010 17:50:02 -0000 >Number: 144584 >Category: kern >Synopsis: bogus values in linprocfs >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Mar 09 17:50:01 UTC 2010 >Closed-Date: >Last-Modified: >Originator: Petr Salinger >Release: >Organization: >Environment: GNU/kFreeBSD debian 8.0-1-686 >Description: The current linprocfs output wrong values, mainly tick related ones. The attached is patch that we are using to improve situation. >How-To-Repeat: >Fix: Patch attached with submission follows: Improve linprocfs, see #344546, #521304, #460331 for other/related problems. --- a/sys/compat/linprocfs/linprocfs.c +++ b/sys/compat/linprocfs/linprocfs.c @@ -110,13 +110,36 @@ /* * Various conversion macros */ + +/* The LINUX_USER_HZ is assumed 100 for now */ + +#if defined(__i386__) +/* we need intermediate result as 64 bit, otherwise it overflows too early */ +#define DO64_MULDIV(v,m,d) \ +({ \ + unsigned long rv0; \ + unsigned long rv1; \ + __asm__ __volatile__( \ + "mull %1\n\t" \ + "divl %2\n\t" \ + :"=a" (rv0), "=d" (rv1) \ + :"r" (d), "0" (v), "1" (m) \ + :"cc" ); \ + rv0; \ +}) + +#define T2J(x) DO64_MULDIV((x), 100UL, (stathz ? stathz : hz)) /* ticks to jiffies */ +#else #define T2J(x) (((x) * 100UL) / (stathz ? stathz : hz)) /* ticks to jiffies */ +#endif #define T2S(x) ((x) / (stathz ? stathz : hz)) /* ticks to seconds */ #define B2K(x) ((x) >> 10) /* bytes to kbytes */ #define B2P(x) ((x) >> PAGE_SHIFT) /* bytes to pages */ #define P2B(x) ((x) << PAGE_SHIFT) /* pages to bytes */ #define P2K(x) ((x) << (PAGE_SHIFT - 10)) /* pages to kbytes */ +#define TV2J(x) (((x)->tv_sec) * 100UL + ((x)->tv_usec) / 10000) + /** * @brief Mapping of ki_stat in struct kinfo_proc to the linux state * @@ -502,12 +525,24 @@ { long cp_time[CPUSTATES]; struct timeval tv; + int cnt, i; getmicrouptime(&tv); read_cpu_time(cp_time); + + for (cnt = 0, i = 0; i <= mp_maxid; ++i) + if (!(CPU_ABSENT(i))) + cnt++; + + if (!cnt) + cnt = 1; + + i = ((cp_time[CP_IDLE])/cnt) % (stathz ? stathz : hz); + i = (i * 100) / (stathz ? stathz : hz); + sbuf_printf(sb, "%lld.%02ld %ld.%02ld\n", (long long)tv.tv_sec, tv.tv_usec / 10000, - T2S(cp_time[CP_IDLE]), T2J(cp_time[CP_IDLE]) % 100); + T2S((cp_time[CP_IDLE]/cnt)), i); return (0); } @@ -613,9 +648,17 @@ struct kinfo_proc kp; char state; static int ratelimit = 0; + unsigned long startcode, startdata; PROC_LOCK(p); fill_kinfo_proc(p, &kp); + if (p->p_vmspace) { + startcode = (unsigned long) p->p_vmspace->vm_taddr; + startdata = (unsigned long) p->p_vmspace->vm_daddr; + } else { + startcode = 0; + startdata = 0; + }; sbuf_printf(sb, "%d", p->p_pid); #define PS_ADD(name, fmt, arg) sbuf_printf(sb, " " fmt, arg) PS_ADD("comm", "(%s)", p->p_comm); @@ -634,30 +677,27 @@ PS_ADD("pgrp", "%d", p->p_pgid); PS_ADD("session", "%d", p->p_session->s_sid); PROC_UNLOCK(p); - PS_ADD("tty", "%d", 0); /* XXX */ + PS_ADD("tty", "%d", kp.ki_tdev); PS_ADD("tpgid", "%d", kp.ki_tpgid); PS_ADD("flags", "%u", 0); /* XXX */ PS_ADD("minflt", "%lu", kp.ki_rusage.ru_minflt); PS_ADD("cminflt", "%lu", kp.ki_rusage_ch.ru_minflt); PS_ADD("majflt", "%lu", kp.ki_rusage.ru_majflt); PS_ADD("cmajflt", "%lu", kp.ki_rusage_ch.ru_majflt); - PS_ADD("utime", "%ld", T2J(tvtohz(&kp.ki_rusage.ru_utime))); - PS_ADD("stime", "%ld", T2J(tvtohz(&kp.ki_rusage.ru_stime))); - PS_ADD("cutime", "%ld", T2J(tvtohz(&kp.ki_rusage_ch.ru_utime))); - PS_ADD("cstime", "%ld", T2J(tvtohz(&kp.ki_rusage_ch.ru_stime))); + PS_ADD("utime", "%ld", TV2J((&kp.ki_rusage.ru_utime))); + PS_ADD("stime", "%ld", TV2J((&kp.ki_rusage.ru_stime))); + PS_ADD("cutime", "%ld", TV2J((&kp.ki_rusage_ch.ru_utime))); + PS_ADD("cstime", "%ld", TV2J((&kp.ki_rusage_ch.ru_stime))); PS_ADD("priority", "%d", kp.ki_pri.pri_user); PS_ADD("nice", "%d", kp.ki_nice); /* 19 (nicest) to -19 */ PS_ADD("0", "%d", 0); /* removed field */ PS_ADD("itrealvalue", "%d", 0); /* XXX */ - /* XXX: starttime is not right, it is the _same_ for _every_ process. - It should be the number of jiffies between system boot and process - start. */ - PS_ADD("starttime", "%lu", T2J(tvtohz(&kp.ki_start))); + PS_ADD("starttime", "%lu", TV2J((&kp.ki_start)) - TV2J((&boottime))); PS_ADD("vsize", "%ju", P2K((uintmax_t)kp.ki_size)); PS_ADD("rss", "%ju", (uintmax_t)kp.ki_rssize); PS_ADD("rlim", "%lu", kp.ki_rusage.ru_maxrss); - PS_ADD("startcode", "%u", (unsigned)0); - PS_ADD("endcode", "%u", 0); /* XXX */ + PS_ADD("startcode", "%lu", startcode); + PS_ADD("endcode", "%lu", startdata); PS_ADD("startstack", "%u", 0); /* XXX */ PS_ADD("kstkesp", "%u", 0); /* XXX */ PS_ADD("kstkeip", "%u", 0); /* XXX */ @@ -800,7 +840,7 @@ */ sbuf_printf(sb, "VmSize:\t%8ju kB\n", B2K((uintmax_t)kp.ki_size)); sbuf_printf(sb, "VmLck:\t%8u kB\n", P2K(0)); /* XXX */ - sbuf_printf(sb, "VmRss:\t%8ju kB\n", P2K((uintmax_t)kp.ki_rssize)); + sbuf_printf(sb, "VmRSS:\t%8ju kB\n", P2K((uintmax_t)kp.ki_rssize)); sbuf_printf(sb, "VmData:\t%8ju kB\n", P2K((uintmax_t)kp.ki_dsize)); sbuf_printf(sb, "VmStk:\t%8ju kB\n", P2K((uintmax_t)kp.ki_ssize)); sbuf_printf(sb, "VmExe:\t%8ju kB\n", P2K((uintmax_t)kp.ki_tsize)); >Release-Note: >Audit-Trail: >Unformatted: