diff options
Diffstat (limited to 'tapset/LKET/ioscheduler.stp')
-rwxr-xr-x | tapset/LKET/ioscheduler.stp | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/tapset/LKET/ioscheduler.stp b/tapset/LKET/ioscheduler.stp new file mode 100755 index 00000000..8e238a8d --- /dev/null +++ b/tapset/LKET/ioscheduler.stp @@ -0,0 +1,182 @@ +// Copyright (C) 2005, 2006 IBM Corp. +// +// This file is part of systemtap, and is free software. You can +// redistribute it and/or modify it under the terms of the GNU General +// Public License (GPL); either version 2, or (at your option) any +// later version. + +/* only print backtrace for elv_add_request & elv_next_request*/ +probe addevent.ioscheduler + = addevent.ioscheduler.elv_next_request, + addevent.ioscheduler.elv_completed_request, + addevent.ioscheduler.elv_add_request +{ +} + +/* when a request is retrieved from request queue */ +probe addevent.ioscheduler.elv_next_request + += ioscheduler.elv_next_request +{ + if(filter_by_pid() == 1 ) { + log_ioscheduler_tracedata_elv_next(HOOKID_IOSCHED_NEXT_REQ, $q, backtrace) + } +} + + +/* when a request is added to the request queue */ +probe addevent.ioscheduler.elv_add_request + += ioscheduler.elv_add_request +{ + if(filter_by_pid() == 1 ) { + log_ioscheduler_tracedata_others(HOOKID_IOSCHED_ADD_REQ, $q, $rq, backtrace) + } +} + +/* when a request is completed */ +probe addevent.ioscheduler.elv_completed_request + = ioscheduler.elv_completed_request +{ + if(filter_by_pid() == 1 ) { + log_ioscheduler_tracedata_others(HOOKID_IOSCHED_REMOVE_REQ, $q, $rq, backtrace) + } +} + + +%{ +#include <linux/blkdev.h> +#include <linux/elevator.h> +%} + +/* log the data specific to __elv_add_request and elv_remove_request */ +%( kernel_v >= "2.6.10" %? + +function log_ioscheduler_tracedata_others(var_id:long, var_q:long, var_rq:long, backtrace:long) +%{ + struct request *rq = (struct request *)((long)THIS->var_rq); + struct request_queue *q = (struct request_queue *)((long)THIS->var_q); + + /* elevator name|major|minor| */ + + /* only print backtrace for elv_add_request */ + if(THIS->backtrace == 1) { + String str = _stp_string_init (0); + _stp_stack_sprint (str, CONTEXT->regs, 0); + + _lket_trace(_GROUP_IOSCHED, THIS->var_id, "%0s%1b%1b%0s", q->elevator->elevator_type->elevator_name, + rq->rq_disk->major, rq->rq_disk->first_minor, _stp_string_ptr(str)); + } else { + _lket_trace(_GROUP_IOSCHED, THIS->var_id, "%0s%1b%1b", q->elevator->elevator_type->elevator_name, + rq->rq_disk->major, rq->rq_disk->first_minor); + } +%} + +%: + +function log_ioscheduler_tracedata_others(var_id:long, var_q:long, var_rq:long, backtrace:long) +%{ + struct request *rq = (struct request *)((long)THIS->var_rq); + struct request_queue *q = (struct request_queue *)((long)THIS->var_q); + + /* elevator name|major|minor| */ + + /* only print backtrace for elv_add_request */ + if(THIS->backtrace == 1) { + String str = _stp_string_init (0); + _stp_stack_sprint (str, CONTEXT->regs, 0); + + _lket_trace(_GROUP_IOSCHED, THIS->var_id, "%0s%1b%1b%0s", q->elevator.elevator_name, + rq->rq_disk->major, rq->rq_disk->first_minor, _stp_string_ptr(str)); + } else { + _lket_trace(_GROUP_IOSCHED, THIS->var_id, "%0s%1b%1b", q->elevator.elevator_name, + rq->rq_disk->major, rq->rq_disk->first_minor); + } +%} + +%) + +/* log the data specific to elv_next_request, for kernel == 2.6.9 */ +%( kernel_v >= "2.6.10" %? + +/* log the data specific to elv_next_request , for kernel > 2.6.9*/ +function log_ioscheduler_tracedata_elv_next(var_id:long, var:long, backtrace:long) +%{ + + struct request_queue *q; + struct request *rq; + + q = (struct request_queue *)((long)THIS->var); + + /* If there is a request in the request queue: + elevator name|major|minor| + if there is no request in the request queue: + elevator name|empty| + */ + + if(THIS->backtrace == 1) { + String str = _stp_string_init (0); + _stp_stack_sprint (str, CONTEXT->regs, 0); + + if(list_empty(&(q->queue_head))) { + _lket_trace(_GROUP_IOSCHED, THIS->var_id, "%0s%1b%1b%0s", + q->elevator->elevator_type->elevator_name, -1, -1, _stp_string_ptr(str)); + } else { + rq = list_entry_rq(q->queue_head.next); + _lket_trace(_GROUP_IOSCHED, THIS->var_id, "%0s%1b%1b%0s", + q->elevator->elevator_type->elevator_name, rq->rq_disk->major, + rq->rq_disk->first_minor, _stp_string_ptr(str)); + } + } else { + if(list_empty(&(q->queue_head))) { + _lket_trace(_GROUP_IOSCHED, THIS->var_id, "%0s%1b%1b", + q->elevator->elevator_type->elevator_name, -1, -1); + } else { + rq = list_entry_rq(q->queue_head.next); + _lket_trace(_GROUP_IOSCHED, THIS->var_id, "%0s%1b%1b", + q->elevator->elevator_type->elevator_name, rq->rq_disk->major, + rq->rq_disk->first_minor); + } + + } +%} + +%: + +function log_ioscheduler_tracedata_elv_next(var_id:long, var:long, backtrace:long) +%{ + + struct request_queue *q; + struct request *rq; + + q = (struct request_queue *)((long)THIS->var); + + /* If there is a request in the request queue: + elevator name|major|minor| + if there is no request in the request queue: + elevator name|empty| + */ + if(THIS->backtrace == 1) { + String str = _stp_string_init (0); + _stp_stack_sprint (str, CONTEXT->regs, 0); + + if(list_empty(&(q->queue_head))) { + _lket_trace(_GROUP_IOSCHED, THIS->var_id, "%0s%1b%1b%0s", + q->elevator.elevator_name, -1, -1, _stp_string_ptr(str)); + } else { + rq = list_entry_rq(q->queue_head.next); + _lket_trace(_GROUP_IOSCHED, THIS->var_id, "%0s%1b%1b%0s", q->elevator.elevator_name, + rq->rq_disk->major, rq->rq_disk->first_minor, _stp_string_ptr(str)); + } + } else { + if(list_empty(&(q->queue_head))) { + _lket_trace(_GROUP_IOSCHED, THIS->var_id, "%0s%1b%1b", + q->elevator.elevator_name, -1, -1); + } else { + rq = list_entry_rq(q->queue_head.next); + _lket_trace(_GROUP_IOSCHED, THIS->var_id, "%0s%1b%1b", q->elevator.elevator_name, + rq->rq_disk->major, rq->rq_disk->first_minor); + } + } + +%} + +%) |