Home | History | Annotate | Line # | Download | only in FS
      1 #!/usr/sbin/dtrace -s
      2 /*
      3  * fspaging.d - file system read/write and paging tracing.
      4  *              Written using DTrace (Solaris 10 3/05)
      5  *
      6  * This traces file related activity: system call reads and writes,
      7  * vnode logical read and writes (fop), vnode putpage and getpage activity,
      8  * and disk I/O. It can be used to examine the behaviour of each I/O
      9  * layer, from the syscall interface to what the disk is doing. Behaviour
     10  * such as read-ahead, and max I/O size breakup can be observed.
     11  *
     12  * This is a verbose version of fsrw.d, as this also traces paging activity.
     13  *
     14  * $Id: fspaging.d,v 1.1.1.1 2015/09/30 22:01:09 christos Exp $
     15  *
     16  * USAGE:	fspaging.d
     17  *
     18  * FIELDS:
     19  *		Event		Traced event (see EVENTS below)
     20  *		Device		Device, for disk I/O
     21  *		RW		Either Read or Write
     22  *		Size		Size of I/O in bytes, if known
     23  *		Offset		Offset of I/O in kilobytes, if known
     24  *		Path		Path to file on disk
     25  *
     26  * EVENTS:
     27  *		sc-read		System call read
     28  *		sc-write	System call write
     29  *		fop_read	Logical read
     30  *		fop_write	Logical write
     31  *		fop_getpage	Logical get page
     32  *		fop_putpage	Logical put page
     33  *		disk_io		Physical disk I/O
     34  *		disk_ra		Physical disk I/O, read ahead
     35  *
     36  * The events are drawn with a level of indentation, which can sometimes
     37  * help identify related events.
     38  *
     39  * SEE ALSO: fsrw.d
     40  *
     41  * IDEA: Richard McDougall, Solaris Internals 2nd Ed, FS Chapter.
     42  *
     43  * COPYRIGHT: Copyright (c) 2006 Brendan Gregg.
     44  *
     45  * CDDL HEADER START
     46  *
     47  *  The contents of this file are subject to the terms of the
     48  *  Common Development and Distribution License, Version 1.0 only
     49  *  (the "License").  You may not use this file except in compliance
     50  *  with the License.
     51  *
     52  *  You can obtain a copy of the license at Docs/cddl1.txt
     53  *  or http://www.opensolaris.org/os/licensing.
     54  *  See the License for the specific language governing permissions
     55  *  and limitations under the License.
     56  *
     57  * CDDL HEADER END
     58  *
     59  * ToDo: readv()
     60  *
     61  * 20-Mar-2006  Brendan Gregg   Created this.
     62  * 23-Apr-2006	   "      "	Last update.
     63  */
     64 
     65 #pragma D option quiet
     66 #pragma D option switchrate=10hz
     67 
     68 dtrace:::BEGIN
     69 {
     70 	printf("%-13s %10s %2s %8s %6s %s\n",
     71 	    "Event", "Device", "RW", "Size", "Offset", "Path");
     72 }
     73 
     74 syscall::*read:entry,
     75 syscall::*write*:entry
     76 {
     77 	/*
     78 	 * starting with a file descriptior, dig out useful info
     79 	 * from the corresponding file_t and vnode_t.
     80 	 */
     81 	this->filistp = curthread->t_procp->p_user.u_finfo.fi_list;
     82 	this->ufentryp = (uf_entry_t *)((uint64_t)this->filistp +
     83 	    (uint64_t)arg0 * (uint64_t)sizeof (uf_entry_t));
     84 	this->filep = this->ufentryp->uf_file;
     85 	self->offset = this->filep->f_offset;
     86 	this->vnodep = this->filep != 0 ? this->filep->f_vnode : 0;
     87 	self->vpath = this->vnodep ? (this->vnodep->v_path != 0 ?
     88 	    cleanpath(this->vnodep->v_path) : "<unknown>") : "<unknown>";
     89 	self->sc_trace = this->vnodep ? this->vnodep->v_type == 1 ||
     90 	    this->vnodep->v_type == 2 ? 1 : 0 : 0;
     91 }
     92 
     93 syscall::*read:entry
     94 /self->sc_trace/
     95 {
     96 	printf("sc-%-10s %10s %2s %8d %6d %s\n", probefunc, ".", "R",
     97 	    (int)arg2, self->offset / 1024, self->vpath);
     98 }
     99 
    100 syscall::*write*:entry
    101 /self->sc_trace/
    102 {
    103 	printf("sc-%-10s %10s %2s %8d %6d %s\n", probefunc, ".", "W",
    104 	    (int)arg2, self->offset / 1024, self->vpath);
    105 }
    106 
    107 syscall::*read:return,
    108 syscall::*write*:return
    109 {
    110 	self->vpath = 0;
    111 	self->offset = 0;
    112 	self->sc_trace = 0;
    113 }
    114 
    115 fbt::fop_putpage:entry,
    116 fbt::fop_getpage:entry
    117 /self->sc_trace && args[0]->v_path/
    118 {
    119 	printf("  %-11s %10s %2s %8d %6d %s\n", probefunc, ".",
    120 	    probefunc == "fop_getpage" ? "R" : "W", (uint64_t)arg2,
    121 	    args[1] / 1024, cleanpath(args[0]->v_path));
    122 }
    123 
    124 
    125 fbt::fop_read:entry,
    126 fbt::fop_write:entry
    127 /self->sc_trace && args[0]->v_path/
    128 {
    129 	printf("  %-11s %10s %2s %8d %6d %s\n", probefunc, ".",
    130 	    probefunc == "fop_read" ? "R" : "W", args[1]->uio_resid,
    131 	    args[1]->_uio_offset._f / 1024, cleanpath(args[0]->v_path));
    132 }
    133 
    134 fbt:ufs:ufs_getpage_ra:entry
    135 {
    136 	/* fetch the real offset (file_t is unaware of this) */
    137 	self->offset = ((inode_t *)args[0]->v_data)->i_nextrio;
    138 	self->read_ahead = 1;
    139 }
    140 
    141 fbt:ufs:ufs_getpage_ra:return
    142 {
    143 	self->read_ahead = 0;
    144 	self->offset = 0;
    145 }
    146 
    147 io::bdev_strategy:start
    148 {
    149 	this->offset = self->read_ahead ? self->offset : args[2]->fi_offset;
    150 	printf("    %-9s %10s %2s %8d %6d %s\n",
    151 	    self->read_ahead ? "disk_ra" : "disk_io", args[1]->dev_statname,
    152 	    args[0]->b_flags & B_READ ? "R" : "W", args[0]->b_bcount,
    153 	    this->offset / 1024, args[2]->fi_pathname);
    154 }
    155