From owner-freebsd-current@FreeBSD.ORG Tue Jun 29 23:52:23 2004 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from green.homeunix.org (freefall.freebsd.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 43C6816A4CE; Tue, 29 Jun 2004 23:52:23 +0000 (GMT) Received: from green.homeunix.org (green@localhost [127.0.0.1]) by green.homeunix.org (8.12.11/8.12.11) with ESMTP id i5TNqMYR004809; Tue, 29 Jun 2004 19:52:22 -0400 (EDT) (envelope-from green@green.homeunix.org) Received: (from green@localhost) by green.homeunix.org (8.12.11/8.12.11/Submit) id i5TNqMG8004808; Tue, 29 Jun 2004 19:52:22 -0400 (EDT) (envelope-from green) Date: Tue, 29 Jun 2004 19:52:21 -0400 From: Brian Fundakowski Feldman To: Ronald Klop Message-ID: <20040629235221.GF1144@green.homeunix.org> References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="Kj7319i9nmIyA2yE" Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.6i cc: freebsd-current@freebsd.org Subject: Re: panic with heavy writing on md device X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 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: Tue, 29 Jun 2004 23:52:23 -0000 --Kj7319i9nmIyA2yE Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Tue, Jun 29, 2004 at 11:11:51PM +0200, Ronald Klop wrote: > Hello, > > I got a panic while doing a lot of IO on a md device. > I attached a gdb backtrace of the kernelcore and a dmesg output. > > It happened while untarring a 30 MB tar on the background (&) and > traversing this new directory in the meantime. > > uname -a > FreeBSD guido.thuis.klop.ws 5.2-CURRENT FreeBSD 5.2-CURRENT #1: Fri Jun 25 > 04:03:35 CEST 2004 > root@guido.thuis.klop.ws:/usr/obj/usr/src/sys/GUIDO i386 > > On the same time I was playing music with mpg123, but that doesn't make > use of the md device. > > I have had this more and always while doing a lot of IO on the md device. > > Is there more info you need? It looks like there is a memory leak -- in general, you are not supposed to run out of kernel virtual memory address space unless you have a dire misconfiguration somewhere. Unfortunately, I think the most useful pieces of information (zone and malloc allocation) are not fetchable via kvm anymore. Here's a fix for vmstat so that you can provide vmstat -m output using the -M and -N args again. I think vmstat -c output would also be useful. -- Brian Fundakowski Feldman \'[ FreeBSD ]''''''''''\ <> green@FreeBSD.org \ The Power to Serve! \ Opinions expressed are my own. \,,,,,,,,,,,,,,,,,,,,,,\ --Kj7319i9nmIyA2yE Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="vmstat-mM.patch" Index: vmstat.c =================================================================== RCS file: /usr/ncvs/src/usr.bin/vmstat/vmstat.c,v retrieving revision 1.82 diff -u -r1.82 vmstat.c --- vmstat.c 23 Apr 2004 13:10:29 -0000 1.82 +++ vmstat.c 29 Jun 2004 23:36:57 -0000 @@ -99,18 +99,22 @@ { "_intrcnt" }, #define X_EINTRCNT 9 { "_eintrcnt" }, +#define X_KMEMSTATS 10 + { "_kmemstatistics" }, +#define X_KMEMZONES 11 + { "_kmemzones" }, #ifdef notyet -#define X_DEFICIT 10 +#define X_DEFICIT XXX { "_deficit" }, -#define X_REC 11 +#define X_REC XXX { "_rectime" }, -#define X_PGIN 12 +#define X_PGIN XXX { "_pgintime" }, -#define X_XSTATS 13 +#define X_XSTATS XXX { "_xstats" }, -#define X_END 14 +#define X_END XXX #else -#define X_END 10 +#define X_END 12 #endif { "" }, }; @@ -153,6 +157,8 @@ static void dovmstat(unsigned int, int); static void dozmem(void); static void kread(int, void *, size_t); +static void kreado(int, void *, size_t, size_t); +static char *kgetstr(const char *); static void needhdr(int); static void printhdr(void); static void usage(void); @@ -894,9 +900,59 @@ static void domem(void) { - if (kd != NULL) - errx(1, "not implemented"); - dosysctl("kern.malloc"); + struct malloc_type type; + + if (kd == NULL) { + dosysctl("kern.malloc"); + return; + } + kread(X_KMEMSTATS, &type.ks_next, sizeof(type.ks_next)); + (void)printf("\n Type InUse MemUse HighUse Requests" + " Size(s)\n"); + do { + /* XXX this should be exported in sys/malloc.h */ + struct { + int kz_size; + char *kz_name; + /* uma_zone_t */ void *kz_zone; + } kz; + size_t kmemzonenum; + char *str; + int first; + + if (kvm_read(kd, (u_long)type.ks_next, &type, sizeof(type)) != + sizeof(type)) + errx(1, "%s: %p: %s", __func__, type.ks_next, + kvm_geterr(kd)); + if (type.ks_calls == 0) + continue; + str = kgetstr(type.ks_shortdesc); + (void)printf("%13s%6lu%6luK%7luK%9llu", + str, + type.ks_inuse, + (type.ks_memuse + 1023) / 1024, + (type.ks_maxused + 1023) / 1024, + (long long unsigned)type.ks_calls); + free(str); + for (kmemzonenum = 0, first = 1; ; kmemzonenum++) { + kreado(X_KMEMZONES, &kz, sizeof(kz), + kmemzonenum * sizeof(kz)); + if (kz.kz_name == NULL) { + (void)printf("\n"); + break; + } + if (!(type.ks_size & (1 << kmemzonenum))) + continue; + if (first) + (void)printf(" "); + else + (void)printf(","); + first = 0; + str = kgetstr(kz.kz_name); + (void)printf("%s", str); + free(str); + } + } while (type.ks_next != NULL); } static void @@ -929,7 +985,7 @@ * kread reads something from the kernel, given its nlist index. */ static void -kread(int nlx, void *addr, size_t size) +kreado(int nlx, void *addr, size_t size, size_t offset) { const char *sym; @@ -939,12 +995,38 @@ ++sym; errx(1, "symbol %s not defined", sym); } - if ((size_t)kvm_read(kd, namelist[nlx].n_value, addr, size) != size) { + if ((size_t)kvm_read(kd, namelist[nlx].n_value + offset, addr, + size) != size) { sym = namelist[nlx].n_name; if (*sym == '_') ++sym; errx(1, "%s: %s", sym, kvm_geterr(kd)); } +} + +static void +kread(int nlx, void *addr, size_t size) +{ + kreado(nlx, addr, size, 0); +} + +static char * +kgetstr(const char *strp) +{ + int n = 0, size = 1; + char *ret = NULL; + + do { + if (size == n + 1) { + ret = realloc(ret, size); + if (ret == NULL) + err(1, "%s: realloc", __func__); + size *= 2; + } + if (kvm_read(kd, (u_long)strp + n, &ret[n], 1) != 1) + errx(1, "%s: %s", __func__, kvm_geterr(kd)); + } while (ret[n++] != '\0'); + return (ret); } static void --Kj7319i9nmIyA2yE--