forked from hatem-mahmoud/scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathschedtimes_wsi.stp
188 lines (153 loc) · 4.95 KB
/
schedtimes_wsi.stp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#! /usr/bin/env stap
############################################################
# Schedtimes.stp
#
# Copyright (C) 2009, 2014 Red Hat, Inc.
#
# This program is free software you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
# Authors: Jason Baron <[email protected]>
# Josh Stone <[email protected]>
# profiles threads and displays their run times, queued times,
# wait times, including i/o wait times.
# Has two modes. When no arguments are given it profiles all
# threads. Alternatively, you can pass -c "program name"
#
# 06/02/2017 added oracle session information by Hatem Mahmoud
############################################################
global KSUSENUM = 5920
global KSUSESQH = 6084
global KSUSECLI = 6488
global ksupga_address=202316608
global ksupga_offset=24
//constants
global DEAD=-1, RUNNING=1, QUEUED=2, SLEEPING=3
global run_time, queued_time, sleep_time, iowait_time
global pid_state, pid_names,pid_sid,pid_hash,pid_cli_info
// For new enough kernels, roughly 2.6.32+, the @defined(@task->in_iowait)
// tests will succeed and reduce these macros to nothing, including these
// pid-iowait arrays. For older kernels, the rq fallback will remain.
global pid_in_iowait
global pid_iowait_count
@define in_iowait(task) %(
@choose_defined(@task->in_iowait,
(pid_in_iowait[@task->pid] ? pid_in_iowait[@task->pid]-- : 0))
%)
@define clear_iowait(rq, task) %(
if (!@defined(@task->in_iowait))
pid_iowait_count[@task->pid] = @nr_iowait(@rq)
%)
@define set_iowait(rq, task) %(
if (!@defined(@task->in_iowait))
pid_in_iowait[@task->pid] = (@nr_iowait(@rq) > pid_iowait_count[@task->pid])
%)
@define nr_iowait(rq) %(
atomic_read(&@cast(@rq, "rq")->nr_iowait)
%)
global previous_timestamp
function timestamp()
{
return cpu_clock_us(0)
}
function update_times(pid, now)
{
delta = now - previous_timestamp[pid]
previous_timestamp[pid] = now
if ((state = pid_state[pid]) > 0) {
if (state == SLEEPING)
sleep_time[pid] += delta
else if (state == QUEUED)
queued_time[pid] += delta
else if (state == RUNNING)
run_time[pid] += delta
}
return delta
}
function task_targeted(task)
{
pid = task_pid(task)
if (pid && (!target() || target_set_pid(pid))) {
pid_names[task_tid(task)] = task_execname(task)
if (( isinstr(task_execname(task) , "ora_" ) == 1 || isinstr(task_execname(task) , "oracle" ) == 1 ) && user_uint16(user_uint64(ksupga_address+ksupga_offset)+KSUSENUM) > 0 ) {
pid_sid[task_tid(task)] = user_uint16(user_uint64(ksupga_address+ksupga_offset)+KSUSENUM);
pid_hash[task_tid(task)] = user_uint32(user_uint64(ksupga_address+ksupga_offset)+KSUSESQH);
pid_cli_info[task_tid(task)] = user_string2(user_uint64(ksupga_address+ksupga_offset)+KSUSECLI,"error");
}
return 1
}
return 0
}
// Update the task name after exec
probe kernel.trace("sched_process_exec")!,
kprocess.exec_complete
{
if (tid() in pid_names)
pid_names[tid()] = execname()
}
probe kernel.trace("sched_switch")
{
// Task $prev is scheduled off this cpu
if (task_targeted($prev)) {
pid = $prev->pid
state = $prev->state
update_times(pid, timestamp())
if (state > 0) {
@set_iowait($rq, $prev)
pid_state[pid] = SLEEPING
} else if (state == 0) {
pid_state[pid] = QUEUED
} else {
pid_state[pid] = DEAD
}
}
// Task $next is scheduled onto this cpu
if (task_targeted($next)) {
pid = $next->pid
update_times(pid, timestamp())
@clear_iowait($rq, $next)
pid_state[pid] = RUNNING
}
}
probe kernel.trace("sched_wakeup")
{
// Task $p is awakened
if (@choose_defined($success, 1) && task_targeted($p)) {
pid = $p->pid
delta = update_times(pid, timestamp())
if (pid_state[pid] == SLEEPING && @in_iowait($p)) {
iowait_time[pid] += delta
}
pid_state[pid] = QUEUED
}
}
// Give task $p a final accounting
probe kernel.trace("sched_process_exit")
{
if (task_targeted($p)) {
pid = $p->pid
update_times(pid, timestamp())
pid_state[pid] = DEAD
}
}
probe end
{
t = timestamp()
printf ("\n%16s: %6s %10s %10s %10s %10s %10s %10s %10s %10s\n\n",
"execname", "pid", "run(us)", "sleep(us)", "iowait(us)",
"queued(us)", "total(us)", "[ sid", "sql_hash"," client_info ]")
foreach (pid+ in pid_state) {
update_times(pid, t)
}
foreach ([pid] in run_time- limit 10) {
if(pid_sid[pid]) {
printf("%16s: %6d %10d %10d %10d %10d %10d %10d %12d %10s\n", pid_names[pid], pid,
run_time[pid], sleep_time[pid], iowait_time[pid], queued_time[pid],
(run_time[pid] + sleep_time[pid] + queued_time[pid]),pid_sid[pid],pid_hash[pid],pid_cli_info[pid] )
} else {
printf("%16s: %6d %10d %10d %10d %10d %10d\n", pid_names[pid], pid,
run_time[pid], sleep_time[pid], iowait_time[pid], queued_time[pid],
(run_time[pid] + sleep_time[pid] + queued_time[pid]))
}
}
}