summaryrefslogtreecommitdiffstats
path: root/tapset/LKET/ioscheduler.stp
diff options
context:
space:
mode:
Diffstat (limited to 'tapset/LKET/ioscheduler.stp')
-rwxr-xr-xtapset/LKET/ioscheduler.stp182
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);
+ }
+ }
+
+%}
+
+%)