This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

ideas of filter in Linux Kernel Event Trace tool


Hi folks,
As discussed in the topic "per-entity statistics", I think it's better for this trace tool to have a flexible filter facility. So that the user could filter out those events he doesn't care about, and at the same time, it also helps reduce the overhead of this trace tool.
But an easy-to-use and flexible filter facility is not so easy to design. After thinking about this, I come up with a priliminary idea. And I hope to hear more ideas and suggestions about the filter facility in this trace tool.
the filter codes make use of macros passed by -D options of stap.
I inline the modified scsi.stp to demonstrate thisidea. To make it simple, I deleted some probes & functions from scsi.stp.


To use the filter functionalities of scsi event hook, you could just:

stap sample.stp -D FILTER_SCSI_HOST=0 -D FILTER_SCSI_CHANNEL=1 -I tapsets/

then systemtap will only probe those scsi event whose host no is 0 and channel no is 1

---------sample.stp-------

probe addevent.scsi.iocompleted { }

---------tapsets/scsi.stp---------
%{
#include <linux/types.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <linux/timer.h>
#include <linux/blkdev.h>
%}

/* mid-layer processes the completed IO */
probe addevent.scsi.iocompleted
= module("scsi_mod").function("scsi_io_completion")
{
if( filter_by_scsi_host($cmd->device->host->host_no)
  && filter_by_scsi_channel($cmd->device->channel)
  && filter_by_scsi_lun($cmd->device->lun) )
{
     log_tracedata_common(HOOKID_SCSI_IOCOMP_BY_MIDLEVEL)
     log_scsi_iocompleted_extra($cmd, $good_bytes)
}
/* for demo, should be deleted */
else
{
     log("scsi skipped")
}
}

function filter_by_scsi_host:long(var:long)
%{
#ifdef FILTER_SCSI_HOST
     if( (long)(THIS->var) == FILTER_SCSI_HOST)
           THIS->__retvalue = 1;
     else
           THIS->__retvalue = 0;
#else
     THIS->__retvalue = 1;
#endif
%}

function filter_by_scsi_channel:long(var:long)
%{
#ifdef FILTER_SCSI_CHANNEL
       if( (long)(THIS->var) == FILTER_SCSI_CHANNEL)
               THIS->__retvalue = 1;
       else
               THIS->__retvalue = 0;

#else
        THIS->__retvalue = 1;
#endif
%}

function filter_by_scsi_lun:long(var:long)
%{
#ifdef FILTER_SCSI_LUN
       if( (long)(THIS->var) == FILTER_SCSI_LUN)
               THIS->__retvalue = 1;
       else
               THIS->__retvalue = 0;
#else
THIS->__retvalue = 1;
#endif
%}

/* log the info about scsi_dispatching_cmd */
function log_scsi_iocompleted_extra(var_cmd:long, var_goodbytes:long)
%{
struct scsi_cmnd *cmd = (struct scsi_cmnd *)((long)THIS->var_cmd);
long long scsi_info;
unsigned long goodbytes = (unsigned long)(THIS->var_goodbytes);

scsi_info = ((cmd->device->host->host_no & 0xFF) << 24) |
 ((cmd->device->channel & 0xFF) << 16) |
 ((cmd->device->lun & 0xFF) <<  8) |
 (cmd->device->id & 0xFF);

/* scsi_info|data_direction|cmd_identifier|goodbytes */
_stp_printf("%lld|%d|%d|%u", scsi_info, cmd->sc_data_direction, cmd->pid, goodbytes);
%}



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]