My (probably naive) understanding was that I could only get dynvar drops by allocating them, and not clearing often enough. However, with the attached script (please ignore the quality for now), I get no output but: # ./open5.d /pool/onnv-clone/ Started under /pool/onnv-clone/ dtrace: 391 dynamic variable drops dtrace: 14226 dynamic variable drops ... Given that I can''t be setting any variables, since my probe bodies are not called, why am I still getting huge numbers of drops? I double-checked no other dtrace scripts were running... I''m sure I''ve done something embarrassing. thanks, john -------------- next part -------------- #!/usr/sbin/dtrace -wCs #pragma D option quiet #pragma D option dynvarsize=300M #include <sys/fcntl.h> #include <sys/mman.h> #define _VALID_PATH(path) \ (strstr(path, $1) != 0 && \ strstr(path, ".make.state") == 0 && \ strstr(path, ".make.dependenc") == 0) #define VALID_PATH(path) _VALID_PATH(stringof(path != 0 ? path : "<none>")) #define FD_PATH(fd) stringof(fds[fd].fi_pathname != 0 ? fds[fd].fi_pathname : "<none>") #define FD_VALID_PATH(fd) VALID_PATH(FD_PATH(fd)) #define VPATH(fi) \ (fi->f_vnode->v_path != 0 ? \ stringof(fi->f_vnode->v_path) : "<none>") #define IS_OWNED(path) pidowner[path] != 0 #define FD_IS_OWNED(fd) IS_OWNED(FD_PATH(fd)) #define FD_CHECK_OWNER(fd) (IS_OWNED(FD_PATH(fd)) && pidowner[FD_PATH(fd)] != pid) #define SET_OWNER(path) \ execnameowner[path] = execname; \ pidowner[path] = pid; #define CLEAR_OWNER(path) \ execnameowner[path] = 0; \ pidowner[path] = 0; #define REPORT(path, type) \ printf("%s[%d] %s %s, owned by %s[%d]\n", \ execname, pid, type, path, execnameowner[path], pidowner[path]) /* indexed by pathname */ string execnameowner[string]; int pidowner[string]; BEGIN { printf("Started under %s\n", $1); } syscall::mmap:entry / (arg2 & PROT_WRITE) && FD_VALID_PATH(arg4) && !FD_IS_OWNED(arg4) / { printf("mmapentry %s[%d] %s\n", execname, pid, FD_PATH(arg4)); self->mmaping = 1; self->path = FD_PATH(arg4); } syscall::mmap:return /self->mmaping && errno == 0/ { printf("mmap %lx: %s[%d] %s\n", (long)arg1, execname, pid, self->path); SET_OWNER(self->path); self->mmapedowner[self->path] = 1; self->mmaped[(long)arg1, pid] = self->path; } syscall::mmap:return /self->mmaping/ { printf("mmap:return\n"); self->mmaping = 0; self->path = 0; } fbt::hat_unload_callback:entry / self->mmaped[(long)arg1, pid] != 0 / { printf("unmap %lx: %s[%d] %s\n", (long)arg1, execname, pid, self->mmaped[(long)arg1, pid]); this->path = self->mmaped[(long)arg1, pid]; self->mmaped[(long)arg1, pid] = 0; self->mmapedowner[this->path] = 0; CLEAR_OWNER(this->path); }
On Tue, Apr 11, 2006 at 10:32:16PM +0100, John Levon wrote:> > My (probably naive) understanding was that I could only get dynvar drops by > allocating them, and not clearing often enough. However, with the attached > script (please ignore the quality for now), I get no output but:You generally get "drops with non-empty dirty list" or "drops with non-empty rinsing list" if you''re allocating and freeing variables too quickly. Vanilla "dynamic variable drops" is more indicitive of allocating dynamic variables without freeeing them. That said, I''m not sure why you''re getting no output, but drops. All of your probes appear> # ./open5.d /pool/onnv-clone/ > Started under /pool/onnv-clone/ > dtrace: 391 dynamic variable drops > dtrace: 14226 dynamic variable drops > ... > > Given that I can''t be setting any variables, since my probe bodies are not > called, why am I still getting huge numbers of drops?A dynamic variable drop does cause the current probe to be aborted, which is probably why you aren''t seeing any output. But that implies that *all* of your probes are failing with dynamic variable drops. Which is very odd. What release are you running under? (uname -a) Does this happen regardless of the dynvarsize setting?> I double-checked no other dtrace scripts were running... I''m sure I''ve done > something embarrassing.Dynamic variable spaces are per-consumer; that wouldn''t effect anything. Cheers, - jonathan> thanks, > john> #!/usr/sbin/dtrace -wCs > > #pragma D option quiet > #pragma D option dynvarsize=300M> #include <sys/fcntl.h> > #include <sys/mman.h> > > #define _VALID_PATH(path) \ > (strstr(path, $1) != 0 && \ > strstr(path, ".make.state") == 0 && \ > strstr(path, ".make.dependenc") == 0) > > #define VALID_PATH(path) _VALID_PATH(stringof(path != 0 ? > path : "<none>")) > #define FD_PATH(fd) stringof(fds[fd].fi_pathname != 0 ? \ > fds[fd].fi_pathname : "<none>") > #define FD_VALID_PATH(fd) VALID_PATH(FD_PATH(fd)) > #define VPATH(fi) \ > (fi->f_vnode->v_path != 0 ? \ > stringof(fi->f_vnode->v_path) : "<none>") > #define IS_OWNED(path) pidowner[path] != 0 > #define FD_IS_OWNED(fd) IS_OWNED(FD_PATH(fd)) > #define FD_CHECK_OWNER(fd) (IS_OWNED(FD_PATH(fd)) && \ > pidowner[FD_PATH(fd)] != pid) > > #define SET_OWNER(path) \ > execnameowner[path] = execname; \ > pidowner[path] = pid; > > #define CLEAR_OWNER(path) \ > execnameowner[path] = 0; \ > pidowner[path] = 0; > > #define REPORT(path, type) \ > printf("%s[%d] %s %s, owned by %s[%d]\n", \ > execname, pid, type, path, execnameowner[path], pidowner[path]) > > /* indexed by pathname */ > string execnameowner[string]; > int pidowner[string]; > > BEGIN { > printf("Started under %s\n", $1); > } > > syscall::mmap:entry > / (arg2 & PROT_WRITE) && > FD_VALID_PATH(arg4) && !FD_IS_OWNED(arg4) / > { > printf("mmapentry %s[%d] %s\n", execname, pid, FD_PATH(arg4)); > self->mmaping = 1; > self->path = FD_PATH(arg4); > } > > syscall::mmap:return > /self->mmaping && errno == 0/ > { > printf("mmap %lx: %s[%d] %s\n", (long)arg1, execname, pid, self->path); > SET_OWNER(self->path); > self->mmapedowner[self->path] = 1; > self->mmaped[(long)arg1, pid] = self->path; > } > > syscall::mmap:return > /self->mmaping/ > { > printf("mmap:return\n"); > self->mmaping = 0; > self->path = 0; > } > > fbt::hat_unload_callback:entry > / self->mmaped[(long)arg1, pid] != 0 / > { > printf("unmap %lx: %s[%d] %s\n", (long)arg1, execname, pid, self->mmaped[(long)arg1, pid]); > this->path = self->mmaped[(long)arg1, pid]; > self->mmaped[(long)arg1, pid] = 0; > self->mmapedowner[this->path] = 0; > CLEAR_OWNER(this->path); > }> _______________________________________________ > dtrace-discuss mailing list > dtrace-discuss at opensolaris.org-- Jonathan Adams, Solaris Kernel Development
Hey John, The problem that you''re running into is that in order to evaluate the predicate we end up allocating a dynamic variable. You should be able to solve the problem by explicitly freeing the variable: fbt::hat_unload_callback:entry { self->mmaped[(long)arg1, pid] = 0; } I realize it seems a little strange to be assigning 0 to something you already know to be 0, but that should solve your problem. Please file a bug report on this. Adam On Tue, Apr 11, 2006 at 10:32:16PM +0100, John Levon wrote:> > My (probably naive) understanding was that I could only get dynvar drops by > allocating them, and not clearing often enough. However, with the attached > script (please ignore the quality for now), I get no output but: > > # ./open5.d /pool/onnv-clone/ > Started under /pool/onnv-clone/ > dtrace: 391 dynamic variable drops > dtrace: 14226 dynamic variable drops > ... > > Given that I can''t be setting any variables, since my probe bodies are not > called, why am I still getting huge numbers of drops? > > I double-checked no other dtrace scripts were running... I''m sure I''ve done > something embarrassing. > > thanks, > john> #!/usr/sbin/dtrace -wCs > > #pragma D option quiet > #pragma D option dynvarsize=300M > > #include <sys/fcntl.h> > #include <sys/mman.h> > > #define _VALID_PATH(path) \ > (strstr(path, $1) != 0 && \ > strstr(path, ".make.state") == 0 && \ > strstr(path, ".make.dependenc") == 0) > > #define VALID_PATH(path) _VALID_PATH(stringof(path != 0 ? path : "<none>")) > #define FD_PATH(fd) stringof(fds[fd].fi_pathname != 0 ? fds[fd].fi_pathname : "<none>") > #define FD_VALID_PATH(fd) VALID_PATH(FD_PATH(fd)) > #define VPATH(fi) \ > (fi->f_vnode->v_path != 0 ? \ > stringof(fi->f_vnode->v_path) : "<none>") > #define IS_OWNED(path) pidowner[path] != 0 > #define FD_IS_OWNED(fd) IS_OWNED(FD_PATH(fd)) > #define FD_CHECK_OWNER(fd) (IS_OWNED(FD_PATH(fd)) && pidowner[FD_PATH(fd)] != pid) > > #define SET_OWNER(path) \ > execnameowner[path] = execname; \ > pidowner[path] = pid; > > #define CLEAR_OWNER(path) \ > execnameowner[path] = 0; \ > pidowner[path] = 0; > > #define REPORT(path, type) \ > printf("%s[%d] %s %s, owned by %s[%d]\n", \ > execname, pid, type, path, execnameowner[path], pidowner[path]) > > /* indexed by pathname */ > string execnameowner[string]; > int pidowner[string]; > > BEGIN { > printf("Started under %s\n", $1); > } > > syscall::mmap:entry > / (arg2 & PROT_WRITE) && > FD_VALID_PATH(arg4) && !FD_IS_OWNED(arg4) / > { > printf("mmapentry %s[%d] %s\n", execname, pid, FD_PATH(arg4)); > self->mmaping = 1; > self->path = FD_PATH(arg4); > } > > syscall::mmap:return > /self->mmaping && errno == 0/ > { > printf("mmap %lx: %s[%d] %s\n", (long)arg1, execname, pid, self->path); > SET_OWNER(self->path); > self->mmapedowner[self->path] = 1; > self->mmaped[(long)arg1, pid] = self->path; > } > > syscall::mmap:return > /self->mmaping/ > { > printf("mmap:return\n"); > self->mmaping = 0; > self->path = 0; > } > > fbt::hat_unload_callback:entry > / self->mmaped[(long)arg1, pid] != 0 / > { > printf("unmap %lx: %s[%d] %s\n", (long)arg1, execname, pid, self->mmaped[(long)arg1, pid]); > this->path = self->mmaped[(long)arg1, pid]; > self->mmaped[(long)arg1, pid] = 0; > self->mmapedowner[this->path] = 0; > CLEAR_OWNER(this->path); > }> _______________________________________________ > dtrace-discuss mailing list > dtrace-discuss at opensolaris.org-- Adam Leventhal, Solaris Kernel Development http://blogs.sun.com/ahl
On Tue, Apr 11, 2006 at 03:48:16PM -0700, Jonathan Adams wrote:> You generally get "drops with non-empty dirty list" or "drops with > non-empty rinsing list" if you''re allocating and freeing variables too > quickly. Vanilla "dynamic variable drops" is more indicitive of allocating > dynamic variables without freeeing them.Right.> is probably why you aren''t seeing any output. But that implies that *all* of > your probes are failing with dynamic variable drops. Which is very odd.Odd indeed, but not as odd as the reduced case: string self mmaped[long]; fbt::hat_unload_callback:entry / self->mmaped[arg1] != 0 / { } Same happens with segvn_unmap and as_free.> What release are you running under? (uname -a)BFU''d from daily.0409 debug.> Does this happen regardless of the dynvarsize setting?Yep. I suspect there''s something nasty going on with taking the probe during some unmap in a critical part of the dtrace non-probe code, but I don''t know dtrace.c anywhere near well enough to guess what. regards john
On Tue, Apr 11, 2006 at 11:56:28PM +0100, John Levon wrote:> On Tue, Apr 11, 2006 at 03:48:16PM -0700, Jonathan Adams wrote: > > > You generally get "drops with non-empty dirty list" or "drops with > > non-empty rinsing list" if you''re allocating and freeing variables too > > quickly. Vanilla "dynamic variable drops" is more indicitive of allocating > > dynamic variables without freeeing them. > > Right. > > > is probably why you aren''t seeing any output. But that implies that *all* of > > your probes are failing with dynamic variable drops. Which is very odd. > > Odd indeed, but not as odd as the reduced case: > > string self mmaped[long]; > fbt::hat_unload_callback:entry / self->mmaped[arg1] != 0 / { } > > Same happens with segvn_unmap and as_free.Does it happen if it''s "int self mmaped[long]"?> > What release are you running under? (uname -a) > > BFU''d from daily.0409 debug.Sparc, x86, powerpc?> > Does this happen regardless of the dynvarsize setting? > > Yep. > > I suspect there''s something nasty going on with taking the probe during some > unmap in a critical part of the dtrace non-probe code, but I don''t know > dtrace.c anywhere near well enough to guess what. > > regards > john-- Jonathan Adams, Solaris Kernel Development
On Wed, Apr 12, 2006 at 12:09:39AM +0100, John Levon wrote:> On Tue, Apr 11, 2006 at 03:52:16PM -0700, Adam Leventhal wrote: > > > The problem that you''re running into is that in order to evaluate the predicate > > we end up allocating a dynamic variable. You should be able to solve the > > problem by explicitly freeing the variable: > > > > fbt::hat_unload_callback:entry > > { > > self->mmaped[(long)arg1, pid] = 0; > > } > > This doesn''t seem to help, i.e. > > string self mmaped[long]; > fbt::hat_unload_callback:entry > / self->mmaped[arg1] != 0 / > { self->mmaped[arg1] = 0; } > > still has lots of drops. (Note the original script was check != 0 not == 0).I should have been clearer: you need to do this: fbt::hat_unload_callback:entry /self->mmaped[arg1] != 0/ { ... } fbt::hat_unload_callback:entry { self->mmaped[arg1] = 0; } It''s not a problem with the probes. It''s a problem with dynamic variables. Adam -- Adam Leventhal, Solaris Kernel Development http://blogs.sun.com/ahl
On Tue, Apr 11, 2006 at 03:52:16PM -0700, Adam Leventhal wrote:> The problem that you''re running into is that in order to evaluate the predicate > we end up allocating a dynamic variable. You should be able to solve the > problem by explicitly freeing the variable: > > fbt::hat_unload_callback:entry > { > self->mmaped[(long)arg1, pid] = 0; > }This doesn''t seem to help, i.e. string self mmaped[long]; fbt::hat_unload_callback:entry / self->mmaped[arg1] != 0 / { self->mmaped[arg1] = 0; } still has lots of drops. (Note the original script was check != 0 not == 0).> Please file a bug report on this.6411979 dynamic variable drops due to probe clause I mention there that other functions such as cbe_fire() (or kmem_alloc() etc.) don''t seem to exhibit this problem. regards john