Merge lp:~f-turgis/ubuntu/natty/systemtap/systemtap.2.6.38 into lp:ubuntu/natty/systemtap
- Natty (11.04)
- systemtap.2.6.38
- Merge into natty
Proposed by
Frederic Turgis
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 19 | ||||
Proposed branch: | lp:~f-turgis/ubuntu/natty/systemtap/systemtap.2.6.38 | ||||
Merge into: | lp:ubuntu/natty/systemtap | ||||
Diff against target: |
10383 lines (+9776/-122) 47 files modified
.pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch/doc/SystemTap_Tapset_Reference/tapsets.tmpl (+286/-0) .pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch/tapset/irq.stp (+172/-0) .pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch/tapset/irq.stp (+152/-0) .pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch/testsuite/buildok/irq-detailed.stp (+46/-0) .pc/Fix-for-undefined-STAPCONF_PERF_STRUCTPID.patch/runtime/perf.c (+86/-0) .pc/Fixed-PR11940-by-getting-scripts-w-global-variables-.patch/runtime/runtime.h (+204/-0) .pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/tapset/ip.stp (+86/-0) .pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/testsuite/systemtap.examples/process/pfiles.stp (+612/-0) .pc/Updated-__ip_sock_daddr-for-2.6.38-kernels.patch/tapset/ip.stp (+96/-0) .pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/memory.stp (+635/-0) .pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/rpc.stp (+1185/-0) .pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/task.stp (+384/-0) .pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/vfs.stp (+1018/-0) .pc/Use-linux-blk_types.h-and-REQ_WRITE-for-2.6.36-and-n.patch/buildrun.cxx (+650/-0) .pc/Use-linux-blk_types.h-and-REQ_WRITE-for-2.6.36-and-n.patch/tapset/ioblock.stp (+316/-0) .pc/adding-ifdef-CLONE_STOPPED-to-stop-module-compilatio.patch/tapset/aux_syscalls.stp (+2048/-0) .pc/applied-patches (+10/-0) .pc/compatibility-perf_event.h-updates-for-kernel-2.6.37.patch/buildrun.cxx (+651/-0) .pc/compatibility-perf_event.h-updates-for-kernel-2.6.37.patch/runtime/perf.c (+81/-0) buildrun.cxx (+2/-0) debian/changelog (+8/-0) debian/patches/01-Add-irq.stp-to-Tapset-Reference-manual.patch (+210/-0) debian/patches/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch (+72/-0) debian/patches/Fix-for-undefined-STAPCONF_PERF_STRUCTPID.patch (+25/-0) debian/patches/Fixed-PR11940-by-getting-scripts-w-global-variables-.patch (+57/-0) debian/patches/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch (+60/-0) debian/patches/Updated-__ip_sock_daddr-for-2.6.38-kernels.patch (+37/-0) debian/patches/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch (+214/-0) debian/patches/Use-linux-blk_types.h-and-REQ_WRITE-for-2.6.36-and-n.patch (+60/-0) debian/patches/adding-ifdef-CLONE_STOPPED-to-stop-module-compilatio.patch (+26/-0) debian/patches/compatibility-perf_event.h-updates-for-kernel-2.6.37.patch (+68/-0) debian/patches/series (+10/-0) doc/SystemTap_Tapset_Reference/tapsets.tmpl (+10/-0) runtime/autoconf-blk-types.c (+2/-0) runtime/autoconf-perf-structpid.c (+14/-0) runtime/perf.c (+6/-1) runtime/runtime.h (+14/-3) tapset/aux_syscalls.stp (+2/-0) tapset/ioblock.stp (+6/-1) tapset/ip.stp (+18/-5) tapset/irq.stp (+62/-74) tapset/memory.stp (+2/-1) tapset/rpc.stp (+8/-6) tapset/task.stp (+10/-12) tapset/vfs.stp (+41/-18) testsuite/buildok/irq-detailed.stp (+1/-1) testsuite/systemtap.examples/process/pfiles.stp (+13/-0) |
||||
To merge this branch: | bzr merge lp:~f-turgis/ubuntu/natty/systemtap/systemtap.2.6.38 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu branches | Pending | ||
Review via email:
|
Commit message
Description of the change
Backporting of Redhat patches to get systemtap working on 2.6.38 (Redhat has currently ported to 2.6.37 but fixing 2.6.38 issues mentioned to them). Patches identified by running systemtap testsuite
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added directory '.pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch' |
2 | === added directory '.pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch/doc' |
3 | === added directory '.pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch/doc/SystemTap_Tapset_Reference' |
4 | === added file '.pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch/doc/SystemTap_Tapset_Reference/tapsets.tmpl' |
5 | --- .pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch/doc/SystemTap_Tapset_Reference/tapsets.tmpl 1970-01-01 00:00:00 +0000 |
6 | +++ .pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch/doc/SystemTap_Tapset_Reference/tapsets.tmpl 2011-03-22 12:11:00 +0000 |
7 | @@ -0,0 +1,286 @@ |
8 | +<?xml version="1.0" encoding="UTF-8"?> |
9 | +<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" |
10 | + "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []> |
11 | + |
12 | +<book id="TapsetRef"> |
13 | + <bookinfo> |
14 | + <title>SystemTap Tapset Reference Manual</title> |
15 | +<!--starthere--> |
16 | + <copyright> |
17 | + <year>2008-2009</year> |
18 | + <holder>Red Hat, Inc. and others</holder> |
19 | + </copyright> |
20 | + |
21 | + <authorgroup> |
22 | + <author> |
23 | + <othername>SystemTap</othername> |
24 | + <contrib>Hackers</contrib> |
25 | + </author> |
26 | + </authorgroup> |
27 | + |
28 | + |
29 | + <legalnotice> |
30 | + <para> |
31 | + This documentation is free software; you can redistribute |
32 | + it and/or modify it under the terms of the GNU General Public |
33 | + License version 2 as published by the Free Software Foundation. |
34 | + </para> |
35 | + |
36 | + <para> |
37 | + This program is distributed in the hope that it will be |
38 | + useful, but WITHOUT ANY WARRANTY; without even the implied |
39 | + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
40 | + See the GNU General Public License for more details. |
41 | + </para> |
42 | + |
43 | + <para> |
44 | + You should have received a copy of the GNU General Public |
45 | + License along with this program; if not, write to the Free |
46 | + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
47 | + MA 02111-1307 USA |
48 | + </para> |
49 | + |
50 | + <para> |
51 | + For more details see the file COPYING in the source |
52 | + distribution of Linux. |
53 | + </para> |
54 | + </legalnotice> |
55 | + </bookinfo> |
56 | +<!-- pls dont remove marker comments, as they are used in publican conversion--> |
57 | +<toc></toc> |
58 | +<chapter id="introduction"> |
59 | + <title>Introduction</title> |
60 | + <para> |
61 | + SystemTap provides free software (GPL) infrastructure to simplify the |
62 | + gathering of information about the running Linux system. This assists |
63 | + diagnosis of a performance or functional problem. SystemTap eliminates the |
64 | + need for the developer to go through the tedious and disruptive instrument, |
65 | + recompile, install, and reboot sequence that may be otherwise required to |
66 | + collect data. |
67 | + </para> |
68 | + |
69 | + <para> |
70 | + SystemTap provides a simple command line interface and scripting language |
71 | + for writing instrumentation for a live running kernel. The instrumentation |
72 | + makes extensive use of the probe points and functions provided in the |
73 | + <firstterm>tapset</firstterm> library. This document describes the various |
74 | + probe points and functions. |
75 | + </para> |
76 | + |
77 | + <section id="format"> |
78 | + <title>Tapset Name Format</title> |
79 | + |
80 | + <para>In this guide, tapset definitions appear in the following format:</para> |
81 | + |
82 | + <screen> |
83 | + name:return (parameters) |
84 | + definition |
85 | + </screen> |
86 | + |
87 | + <para> |
88 | + The <replaceable>return</replaceable> field specifies what data type the |
89 | + tapset extracts and returns from the kernel during a probe (and thus, |
90 | + returns). Tapsets use 2 data types for |
91 | + <replaceable>return</replaceable>: <literal>long</literal> (tapset |
92 | + extracts and returns an integer) and <literal>string</literal> (tapset |
93 | + extracts and returns a string). |
94 | + </para> |
95 | + |
96 | + <para> |
97 | + In some cases, tapsets do not have a <replaceable>return</replaceable> |
98 | + value. This simply means that the tapset does not extract anything from |
99 | + the kernel. This is common among asynchronous events such as timers, |
100 | + exit functions, and print functions. |
101 | + </para> |
102 | +<!-- |
103 | +<varlistentry> |
104 | +<term></term> |
105 | +<listitem> |
106 | + <para></para> |
107 | +</listitem> |
108 | +</varlistentry> |
109 | +--> |
110 | + |
111 | + </section> |
112 | + |
113 | + </chapter> |
114 | +<!--endhere--> |
115 | +<!--markerforxi--> |
116 | +<!-- pls dont remove marker comments, as they are used in publican conversion--> |
117 | + <chapter id="context_stp"> |
118 | + <title>Context Functions</title> |
119 | + <para> |
120 | + The context functions provide additional information about where |
121 | + an event occurred. |
122 | + These functions can provide information such as a backtrace to |
123 | + where the event occurred |
124 | + and the current register values for the processor. |
125 | + </para> |
126 | +!Itapset/context.stp |
127 | +!Itapset/context-symbols.stp |
128 | +!Itapset/ucontext-symbols.stp |
129 | +!Itapset/context-unwind.stp |
130 | +!Itapset/ucontext-unwind.stp |
131 | +!Itapset/task.stp |
132 | +!Itapset/pn.stp |
133 | + </chapter> |
134 | + |
135 | + <chapter id="timestamp_stp"> |
136 | + <title>Timestamp Functions</title> |
137 | + <para> |
138 | + Each timestamp function returns a value to indicate when |
139 | + a function is executed. |
140 | + These returned values can then be used to indicate |
141 | + when an event occurred, provide an ordering for events, or compute |
142 | + the amount of time elapsed between two time stamps. |
143 | + </para> |
144 | +!Itapset/timestamp.stp |
145 | +!Itapset/timestamp_gtod.stp |
146 | + </chapter> |
147 | + |
148 | + <chapter id="ctime.stp"> |
149 | + <title>Time string utility function</title> |
150 | + <para> |
151 | + Utility function to turn seconds since the epoch (as returned by |
152 | + the timestamp function gettimeofday_s()) into a human readable |
153 | + date/time string. |
154 | + </para> |
155 | +!Itapset/ctime.stp |
156 | + </chapter> |
157 | + |
158 | + <chapter id="memory_stp"> |
159 | + <title>Memory Tapset</title> |
160 | + <para> |
161 | + This family of probe points is used to probe memory-related events |
162 | + or query the memory usage of the current process. |
163 | + It contains the following probe points: |
164 | + </para> |
165 | +!Itapset/memory.stp |
166 | +!Itapset/proc_mem.stp |
167 | + </chapter> |
168 | + |
169 | + <chapter id="task_time_stp"> |
170 | + <title>Task Time Tapset</title> |
171 | + <para> |
172 | + This tapset defines utility functions to query time related |
173 | + properties of the current tasks, translate those in miliseconds |
174 | + and human readable strings. |
175 | + </para> |
176 | +!Itapset/task_time.stp |
177 | + </chapter> |
178 | + |
179 | + <chapter id="iosched.stp"> |
180 | + <title>IO Scheduler and block IO Tapset</title> |
181 | + <para> |
182 | + This family of probe points is used to probe block IO layer and IO scheduler activities. |
183 | + It contains the following probe points: |
184 | + </para> |
185 | +!Itapset/ioscheduler.stp |
186 | +!Itapset/ioblock.stp |
187 | + </chapter> |
188 | + |
189 | + <chapter id="scsi.stp"> |
190 | + <title>SCSI Tapset</title> |
191 | + <para> |
192 | + This family of probe points is used to probe SCSI activities. |
193 | + It contains the following probe points: |
194 | + </para> |
195 | +!Itapset/scsi.stp |
196 | + </chapter> |
197 | + |
198 | + <chapter id="tty.stp"> |
199 | + <title>TTY Tapset</title> |
200 | + <para> |
201 | + This family of probe points is used to probe TTY (Teletype) activities. |
202 | + It contains the following probe points: |
203 | + </para> |
204 | +!Itapset/tty.stp |
205 | + </chapter> |
206 | + |
207 | + <chapter id="networking.stp"> |
208 | + <title>Networking Tapset</title> |
209 | + <para> |
210 | + This family of probe points is used to probe the activities of |
211 | + the network device and protocol layers. |
212 | + </para> |
213 | +!Itapset/networking.stp |
214 | +!Itapset/tcp.stp |
215 | +!Itapset/udp.stp |
216 | +!Itapset/ip.stp |
217 | + </chapter> |
218 | + |
219 | + <chapter id="socket.stp"> |
220 | + <title>Socket Tapset</title> |
221 | + <para> |
222 | + This family of probe points is used to probe socket activities. |
223 | + It contains the following probe points: |
224 | + </para> |
225 | +!Itapset/socket.stp |
226 | + </chapter> |
227 | + <chapter id="kprocess.stp"> |
228 | + <title>Kernel Process Tapset</title> |
229 | + <para> |
230 | + This family of probe points is used to probe process-related activities. |
231 | + It contains the following probe points: |
232 | + </para> |
233 | +!Itapset/kprocess.stp |
234 | + </chapter> |
235 | + <chapter id="signal.stp"> |
236 | + <title>Signal Tapset</title> |
237 | + <para> |
238 | + This family of probe points is used to probe signal activities. |
239 | + It contains the following probe points: |
240 | + </para> |
241 | +!Itapset/signal.stp |
242 | + </chapter> |
243 | + <chapter id="dentry.stp"> |
244 | + <title>Directory-entry (dentry) Tapset</title> |
245 | + <para> |
246 | + This family of functions is used to map kernel VFS |
247 | + directory entry pointers to file or full path names. |
248 | + </para> |
249 | +!Itapset/dentry.stp |
250 | + </chapter> |
251 | + <chapter id="logging.stp"> |
252 | + <title>Logging Tapset</title> |
253 | + <para> |
254 | + This family of functions is used to send simple |
255 | + message strings to various destinations. |
256 | + </para> |
257 | +!Itapset/logging.stp |
258 | + </chapter> |
259 | + <chapter id="random.stp"> |
260 | + <title>Random functions Tapset</title> |
261 | + <para> |
262 | + These functions deal with random number generation. |
263 | + </para> |
264 | +!Itapset/random.stp |
265 | + </chapter> |
266 | + <chapter id="conversions.stp"> |
267 | + <title>String and data retrieving functions Tapset</title> |
268 | + <para> |
269 | + Functions to retrieve strings and other primitive types from |
270 | + the kernel or a user space programs based on addresses. All |
271 | + strings are of a maximum length given by MAXSTRINGLEN. |
272 | + </para> |
273 | +!Itapset/conversions.stp |
274 | + </chapter> |
275 | + <chapter id="string.stp"> |
276 | + <title>A collection of standard string functions</title> |
277 | + <para> |
278 | + Functions to get the length, a substring, getting at individual |
279 | + characters, string seaching, escaping, tokenizing, and converting |
280 | + strings to longs. |
281 | + </para> |
282 | +!Itapset/string.stp |
283 | + </chapter> |
284 | + <chapter id="ansi.stp"> |
285 | + <title>Utility functions for using ansi control chars in logs</title> |
286 | + <para> |
287 | + Utility functions for logging using ansi control characters. This |
288 | + lets you manipulate the cursor position and character color output |
289 | + and attributes of log messages. |
290 | + </para> |
291 | +!Itapset/ansi.stp |
292 | + </chapter> |
293 | +</book> |
294 | |
295 | === added directory '.pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch/tapset' |
296 | === added file '.pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch/tapset/irq.stp' |
297 | --- .pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch/tapset/irq.stp 1970-01-01 00:00:00 +0000 |
298 | +++ .pc/01-Add-irq.stp-to-Tapset-Reference-manual.patch/tapset/irq.stp 2011-03-22 12:11:00 +0000 |
299 | @@ -0,0 +1,172 @@ |
300 | +/* |
301 | + * Copyright (C) 2009 IBM Corp. |
302 | + * This file is part of systemtap, and is free software. You can |
303 | + * redistribute it and/or modify it under the terms of the GNU General |
304 | + * Public License (GPL); either version 2, or (at your option) any |
305 | + * later version. |
306 | + * |
307 | + * Version 1.0 prerna@linux.vnet.ibm.com 2009-10-28 |
308 | + * |
309 | + * Tracepoint based tapset for IRQs, Workqueues, etc |
310 | + * |
311 | + */ |
312 | +// Probes for workqueues. |
313 | + |
314 | +/** |
315 | + * probe workqueue.create : probes creation of a new workqueue |
316 | + * @wq_thread : task_struct of the workqueue thread. |
317 | + * @cpu : cpu for which the worker thread is created. |
318 | + */ |
319 | +probe workqueue.create = kernel.trace("workqueue_creation") ? |
320 | +{ |
321 | + wq_thread = $wq_thread |
322 | + cpu = $cpu |
323 | +} |
324 | + |
325 | +/** |
326 | + * probe workqueue.insert : probes queuing of work on a workqueue |
327 | + * @wq_thread : task_struct of the workqueue thread. |
328 | + * @work : work_struct* being queued. |
329 | + * @work_func : pointer to handler func. |
330 | + */ |
331 | +probe workqueue.insert = kernel.trace("workqueue_insertion") ? |
332 | +{ |
333 | + wq_thread = $wq_thread |
334 | + work = $work |
335 | + work_func = $work->func |
336 | +} |
337 | + |
338 | +/** |
339 | + * probe workqueue.execute : probes execution of deferred work. |
340 | + * @wq_thread : task_struct of the workqueue thread. |
341 | + * @work : work_struct* being executed. |
342 | + * @work_func : pointer to handler func. |
343 | + */ |
344 | +probe workqueue.execute = kernel.trace("workqueue_execution") ? |
345 | +{ |
346 | + wq_thread = $wq_thread |
347 | + work = $work |
348 | + work_func = $work->func |
349 | +} |
350 | + |
351 | +/** |
352 | + * probe workqueue.destroy : probes destruction of each worker thread of each cpu for a workqueue. |
353 | + * @wq_thread : task_struct of the workqueue thread. |
354 | + */ |
355 | +probe workqueue.destroy = kernel.trace("workqueue_destruction") ? |
356 | +{ |
357 | + wq_thread = $wq_thread |
358 | +} |
359 | + |
360 | +// Probes for IRQ handlers. |
361 | + |
362 | +/** |
363 | + * probe irq_handler.entry : Fires prior to execution of interrupt handler. |
364 | + * @irq : irq number. |
365 | + * @action : struct irqaction* for this interrupt num. |
366 | + * @handler : interrupt handler function. |
367 | + * @flags : Flags for IRQ handler |
368 | + * IRQF_DISABLED [0x00000020] : keep irqs disabled when calling action handler. |
369 | + * IRQF_SAMPLE_RANDOM [0x00000040] : irq is used to feed the random generator |
370 | + * IRQF_SHARED [0x00000080] : allow sharing the irq among several devices |
371 | + * IRQF_PROBE_SHARED [0x00000100] : set by callers when they expect sharing mismatches to occur |
372 | + * IRQF_TIMER [0x00000200] : Flag to mark this interrupt as timer interrupt |
373 | + * IRQF_PERCPU [0x00000400] : Interrupt is per cpu. |
374 | + * IRQF_NOBALANCING [0x00000800] : Flag to exclude this interrupt from irq balancing |
375 | + * IRQF_IRQPOLL [0x00001000] : Interrupt is used for polling. |
376 | + * IRQF_ONESHOT [0x00002000] : Interrupt is not reenabled after the hardirq handler finished. |
377 | + * @flags_str : symbolic string representation of IRQ flags. |
378 | + * @dev_name : name of device. |
379 | + * @dev_id : Cookie to identify device. |
380 | + * @next_irqaction : pointer to next irqaction for shared interrupts. |
381 | + * @dir : pointer to the proc/irq/NN/name entry |
382 | + * @thread_fn : interupt handler function for threaded interrupts. |
383 | + * @thread : thread pointer for threaded interrupts. |
384 | + * @thread_flags : Flags related to thread. |
385 | + */ |
386 | +probe irq_handler.entry = kernel.trace("irq_handler_entry") ? |
387 | +{ |
388 | + irq = $irq |
389 | + action = $action |
390 | + handler = $action->handler |
391 | + flags = $action->flags |
392 | + flags_str = irqflags_str(flags) |
393 | + dev_name = $action->name |
394 | + dev_id = $action->dev_id |
395 | + next_irqaction = $action->next |
396 | + dir = $action->dir |
397 | + thread_fn = $action->thread_fn |
398 | + thread = $action->thread |
399 | + thread_flags = $action->thread_flags |
400 | +} |
401 | + |
402 | +/** |
403 | + * probe irq_handler.exit : Fires just after execution of interrupt handler. |
404 | + * @irq : interrupt number |
405 | + * @action : struct irqaction* |
406 | + * @ret : return value of the handler |
407 | + * @handler : interrupt handler function that was executed. |
408 | + * @flags : flags for IRQ handler |
409 | + * IRQF_DISABLED [0x00000020] : keep irqs disabled when calling action handler. |
410 | + * IRQF_SAMPLE_RANDOM [0x00000040] : irq is used to feed the random generator |
411 | + * IRQF_SHARED [0x00000080] : allow sharing the irq among several devices |
412 | + * IRQF_PROBE_SHARED [0x00000100] : set by callers when they expect sharing mismatches to occur |
413 | + * IRQF_TIMER [0x00000200] : Flag to mark this interrupt as timer interrupt |
414 | + * IRQF_PERCPU [0x00000400] : Interrupt is per cpu. |
415 | + * IRQF_NOBALANCING [0x00000800] : Flag to exclude this interrupt from irq balancing |
416 | + * IRQF_IRQPOLL [0x00001000] : Interrupt is used for polling. |
417 | + * IRQF_ONESHOT [0x00002000] : Interrupt is not reenabled after the hardirq handler finished. |
418 | + * @flags_str : symbolic string representation of IRQ flags. |
419 | + * @dev_name : name of device. |
420 | + * @dev_id : Cookie to identify device. |
421 | + * @next_irqaction : pointer to next irqaction for shared interrupts. |
422 | + * @dir : pointer to the proc/irq/NN/name entry |
423 | + * @thread_fn : interupt handler function for threaded interrupts. |
424 | + * @thread : thread pointer for threaded interrupts. |
425 | + * @thread_flags : Flags related to thread. |
426 | + */ |
427 | +probe irq_handler.exit = kernel.trace("irq_handler_exit") ? |
428 | +{ |
429 | + irq = $irq |
430 | + action = $action |
431 | + ret = $ret |
432 | + handler = $action->handler |
433 | + flags = $action->flags |
434 | + flags_str = irqflags_str(flags) |
435 | + dev_name = $action->name |
436 | + dev_id = $action->dev_id |
437 | + next_irqaction = $action->next |
438 | + dir = $action->dir |
439 | + thread_fn = $action->thread_fn |
440 | + thread = $action->thread |
441 | + thread_flags = $action->thread_flags |
442 | +} |
443 | + |
444 | +// Softirq based probes. |
445 | +/** |
446 | + * probe softirq.entry : triggered just before executing handler |
447 | + * for a pending softirq. |
448 | + * @h : struct softirq_action* for current pending softirq. |
449 | + * @vec : softirq_action vector. |
450 | + * @action : pointer to softirq handler just about to execute. |
451 | + */ |
452 | +probe softirq.entry = kernel.trace("softirq_entry") ? |
453 | +{ |
454 | + h = $h |
455 | + vec = $vec |
456 | + action = $h->action |
457 | +} |
458 | + |
459 | +/** |
460 | + * probe softirq.exit : triggered just after executing handler for a pending |
461 | + * softirq. |
462 | + * @h : struct softirq_action* for just executed softirq. |
463 | + * @vec : softirq_action vector. |
464 | + * @action : pointer to softirq handler that just finished execution. |
465 | + */ |
466 | +probe softirq.exit = kernel.trace("softirq_exit") ? |
467 | +{ |
468 | + h = $h |
469 | + vec = $vec |
470 | + action = $h->action |
471 | +} |
472 | |
473 | === added directory '.pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch' |
474 | === added directory '.pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch/tapset' |
475 | === added file '.pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch/tapset/irq.stp' |
476 | --- .pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch/tapset/irq.stp 1970-01-01 00:00:00 +0000 |
477 | +++ .pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch/tapset/irq.stp 2011-03-22 12:11:00 +0000 |
478 | @@ -0,0 +1,152 @@ |
479 | +/* |
480 | + * Copyright (C) 2009 IBM Corp. |
481 | + * This file is part of systemtap, and is free software. You can |
482 | + * redistribute it and/or modify it under the terms of the GNU General |
483 | + * Public License (GPL); either version 2, or (at your option) any |
484 | + * later version. |
485 | + * |
486 | + * Version 1.0 prerna@linux.vnet.ibm.com 2009-10-28 |
487 | + * |
488 | + * Tracepoint based tapset for IRQs, Workqueues, etc |
489 | + * |
490 | + */ |
491 | +// Probes for workqueues. |
492 | + |
493 | +/** |
494 | + * probe workqueue.create - Creating a new workqueue |
495 | + * @wq_thread: task_struct of the workqueue thread |
496 | + * @cpu: cpu for which the worker thread is created |
497 | + */ |
498 | +probe workqueue.create = kernel.trace("workqueue_creation") ? |
499 | +{ |
500 | + wq_thread = $wq_thread |
501 | + cpu = $cpu |
502 | +} |
503 | + |
504 | +/** |
505 | + * probe workqueue.insert - Queuing work on a workqueue |
506 | + * @wq_thread: task_struct of the workqueue thread |
507 | + * @work: work_struct* being queued |
508 | + * @work_func: pointer to handler function |
509 | + */ |
510 | +probe workqueue.insert = kernel.trace("workqueue_insertion") ? |
511 | +{ |
512 | + wq_thread = $wq_thread |
513 | + work = $work |
514 | + work_func = $work->func |
515 | +} |
516 | + |
517 | +/** |
518 | + * probe workqueue.execute - Executing deferred work |
519 | + * @wq_thread: task_struct of the workqueue thread |
520 | + * @work: work_struct* being executed |
521 | + * @work_func: pointer to handler function |
522 | + */ |
523 | +probe workqueue.execute = kernel.trace("workqueue_execution") ? |
524 | +{ |
525 | + wq_thread = $wq_thread |
526 | + work = $work |
527 | + work_func = $work->func |
528 | +} |
529 | + |
530 | +/** |
531 | + * probe workqueue.destroy - Destroying workqueue |
532 | + * @wq_thread: task_struct of the workqueue thread |
533 | + */ |
534 | +probe workqueue.destroy = kernel.trace("workqueue_destruction") ? |
535 | +{ |
536 | + wq_thread = $wq_thread |
537 | +} |
538 | + |
539 | +// Probes for IRQ handlers. |
540 | + |
541 | +/** |
542 | + * probe irq_handler.entry - Execution of interrupt handler starting |
543 | + * @irq: irq number |
544 | + * @action: struct irqaction* for this interrupt num |
545 | + * @handler: interrupt handler function |
546 | + * @flags: Flags for IRQ handler |
547 | + * @flags_str: symbolic string representation of IRQ flags |
548 | + * @dev_name: name of device |
549 | + * @dev_id: Cookie to identify device |
550 | + * @next_irqaction: pointer to next irqaction for shared interrupts |
551 | + * @dir: pointer to the proc/irq/NN/name entry |
552 | + * @thread_fn: interrupt handler function for threaded interrupts |
553 | + * @thread: thread pointer for threaded interrupts |
554 | + * @thread_flags: Flags related to thread |
555 | + */ |
556 | +probe irq_handler.entry = kernel.trace("irq_handler_entry") ? |
557 | +{ |
558 | + irq = $irq |
559 | + action = $action |
560 | + handler = $action->handler |
561 | + flags = $action->flags |
562 | + flags_str = irqflags_str(flags) |
563 | + dev_name = $action->name |
564 | + dev_id = $action->dev_id |
565 | + next_irqaction = $action->next |
566 | + dir = $action->dir |
567 | + thread_fn = $action->thread_fn |
568 | + thread = $action->thread |
569 | + thread_flags = $action->thread_flags |
570 | +} |
571 | + |
572 | +/** |
573 | + * probe irq_handler.exit - Execution of interrupt handler completed |
574 | + * @irq: interrupt number |
575 | + * @action: struct irqaction* |
576 | + * @ret: return value of the handler |
577 | + * @handler: interrupt handler function that was executed |
578 | + * @flags: flags for IRQ handler |
579 | + * @flags_str: symbolic string representation of IRQ flags |
580 | + * @dev_name: name of device |
581 | + * @dev_id: Cookie to identify device |
582 | + * @next_irqaction: pointer to next irqaction for shared interrupts |
583 | + * @dir: pointer to the proc/irq/NN/name entry |
584 | + * @thread_fn: interrupt handler function for threaded interrupts |
585 | + * @thread: thread pointer for threaded interrupts |
586 | + * @thread_flags: Flags related to thread |
587 | + */ |
588 | +probe irq_handler.exit = kernel.trace("irq_handler_exit") ? |
589 | +{ |
590 | + irq = $irq |
591 | + action = $action |
592 | + ret = $ret |
593 | + handler = $action->handler |
594 | + flags = $action->flags |
595 | + flags_str = irqflags_str(flags) |
596 | + dev_name = $action->name |
597 | + dev_id = $action->dev_id |
598 | + next_irqaction = $action->next |
599 | + dir = $action->dir |
600 | + thread_fn = $action->thread_fn |
601 | + thread = $action->thread |
602 | + thread_flags = $action->thread_flags |
603 | +} |
604 | + |
605 | +// Softirq based probes. |
606 | +/** |
607 | + * probe softirq.entry - Execution of handler for a pending softirq starting |
608 | + * @h: struct softirq_action* for current pending softirq |
609 | + * @vec: softirq_action vector |
610 | + * @action: pointer to softirq handler just about to execute |
611 | + */ |
612 | +probe softirq.entry = kernel.trace("softirq_entry") ? |
613 | +{ |
614 | + h = $h |
615 | + vec = $vec |
616 | + action = $h->action |
617 | +} |
618 | + |
619 | +/** |
620 | + * probe softirq.exit - Execution of handler for a pending softirq completed |
621 | + * @h: struct softirq_action* for just executed softirq |
622 | + * @vec: softirq_action vector |
623 | + * @action: pointer to softirq handler that just finished execution |
624 | + */ |
625 | +probe softirq.exit = kernel.trace("softirq_exit") ? |
626 | +{ |
627 | + h = $h |
628 | + vec = $vec |
629 | + action = $h->action |
630 | +} |
631 | |
632 | === added directory '.pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch/testsuite' |
633 | === added directory '.pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch/testsuite/buildok' |
634 | === added file '.pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch/testsuite/buildok/irq-detailed.stp' |
635 | --- .pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch/testsuite/buildok/irq-detailed.stp 1970-01-01 00:00:00 +0000 |
636 | +++ .pc/02-Fixed-PR12338-by-updating-softirq.entry-softirq.exit.patch/testsuite/buildok/irq-detailed.stp 2011-03-22 12:11:00 +0000 |
637 | @@ -0,0 +1,46 @@ |
638 | +#! stap -p4 |
639 | + |
640 | +# |
641 | +# workqueue probes |
642 | +# |
643 | + |
644 | +probe workqueue.create ? |
645 | +{ |
646 | + printf("%p %d\n", wq_thread, cpu) |
647 | +} |
648 | + |
649 | +probe workqueue.insert ?, workqueue.execute ? |
650 | +{ |
651 | + printf("%p %p %p\n", wq_thread, work, work_func) |
652 | +} |
653 | + |
654 | +probe workqueue.destroy ? |
655 | +{ |
656 | + printf("%p\n", wq_thread) |
657 | +} |
658 | + |
659 | +# |
660 | +# irq_handler probes |
661 | +# |
662 | + |
663 | +probe irq_handler.entry ?, irq_handler.exit ? |
664 | +{ |
665 | + printf("%d %p %p %d(%s)\n", irq, action, handler, flags, flags_str) |
666 | + printf("%d %d %p %p\n", dev_name, dev_id, next_irqaction, dir) |
667 | + printf("%p %p %d\n", thread_fn, thread, thread_flags) |
668 | +} |
669 | + |
670 | +# |
671 | +# softirq probes |
672 | +# |
673 | + |
674 | +probe softirq.entry ?, softirq.exit ? |
675 | +{ |
676 | + printf("%p %p %p\n", h, vec, action) |
677 | +} |
678 | + |
679 | +# Make sure we've got at least one probe. |
680 | +probe never |
681 | +{ |
682 | + printf("never\n") |
683 | +} |
684 | |
685 | === added directory '.pc/Fix-for-undefined-STAPCONF_PERF_STRUCTPID.patch' |
686 | === added directory '.pc/Fix-for-undefined-STAPCONF_PERF_STRUCTPID.patch/runtime' |
687 | === added file '.pc/Fix-for-undefined-STAPCONF_PERF_STRUCTPID.patch/runtime/perf.c' |
688 | --- .pc/Fix-for-undefined-STAPCONF_PERF_STRUCTPID.patch/runtime/perf.c 1970-01-01 00:00:00 +0000 |
689 | +++ .pc/Fix-for-undefined-STAPCONF_PERF_STRUCTPID.patch/runtime/perf.c 2011-03-22 12:11:00 +0000 |
690 | @@ -0,0 +1,86 @@ |
691 | +/* -*- linux-c -*- |
692 | + * Perf Functions |
693 | + * Copyright (C) 2006 Red Hat Inc. |
694 | + * Copyright (C) 2010 Red Hat Inc. |
695 | + * |
696 | + * This file is part of systemtap, and is free software. You can |
697 | + * redistribute it and/or modify it under the terms of the GNU General |
698 | + * Public License (GPL); either version 2, or (at your option) any |
699 | + * later version. |
700 | + */ |
701 | + |
702 | +#ifndef _PERF_C_ |
703 | +#define _PERF_C_ |
704 | + |
705 | +#include <linux/perf_event.h> |
706 | + |
707 | +#include "perf.h" |
708 | + |
709 | +/** @file perf.c |
710 | + * @brief Implements performance monitoring hardware support |
711 | + */ |
712 | + |
713 | +/** Initialize performance sampling |
714 | + * Call this during probe initialization to set up performance event sampling |
715 | + * for all online cpus. Returns non-zero on error. |
716 | + * |
717 | + * @param stp Handle for the event to be registered. |
718 | + */ |
719 | +static long _stp_perf_init (struct stap_perf_probe *stp) |
720 | +{ |
721 | + int cpu; |
722 | + |
723 | + /* allocate space for the event descriptor for each cpu */ |
724 | + stp->events = _stp_alloc_percpu (sizeof(struct perf_event*)); |
725 | + if (stp->events == NULL) { |
726 | + return -ENOMEM; |
727 | + } |
728 | + |
729 | + /* initialize event on each processor */ |
730 | + stp_for_each_cpu(cpu) { |
731 | + struct perf_event **event = per_cpu_ptr (stp->events, cpu); |
732 | + if (cpu_is_offline(cpu)) { |
733 | + *event = NULL; |
734 | + continue; |
735 | + } |
736 | + *event = perf_event_create_kernel_counter(&stp->attr, |
737 | + cpu, |
738 | +#if STAPCONF_PERF_STRUCTPID |
739 | + NULL, |
740 | +#else |
741 | + -1, |
742 | +#endif |
743 | + stp->callback); |
744 | + |
745 | + if (IS_ERR(*event)) { |
746 | + long rc = PTR_ERR(*event); |
747 | + *event = NULL; |
748 | + _stp_perf_del(stp); |
749 | + return rc; |
750 | + } |
751 | + } |
752 | + return 0; |
753 | +} |
754 | + |
755 | +/** Delete performance event. |
756 | + * Call this to shutdown performance event sampling |
757 | + * |
758 | + * @param stp Handle for the event to be unregistered. |
759 | + */ |
760 | +static void _stp_perf_del (struct stap_perf_probe *stp) |
761 | +{ |
762 | + if (stp && stp->events) { |
763 | + int cpu; |
764 | + /* shut down performance event sampling */ |
765 | + stp_for_each_cpu(cpu) { |
766 | + struct perf_event **event = per_cpu_ptr (stp->events, cpu); |
767 | + if (*event) { |
768 | + perf_event_release_kernel(*event); |
769 | + } |
770 | + } |
771 | + _stp_free_percpu (stp->events); |
772 | + stp->events = NULL; |
773 | + } |
774 | +} |
775 | + |
776 | +#endif /* _PERF_C_ */ |
777 | |
778 | === added directory '.pc/Fixed-PR11940-by-getting-scripts-w-global-variables-.patch' |
779 | === added directory '.pc/Fixed-PR11940-by-getting-scripts-w-global-variables-.patch/runtime' |
780 | === added file '.pc/Fixed-PR11940-by-getting-scripts-w-global-variables-.patch/runtime/runtime.h' |
781 | --- .pc/Fixed-PR11940-by-getting-scripts-w-global-variables-.patch/runtime/runtime.h 1970-01-01 00:00:00 +0000 |
782 | +++ .pc/Fixed-PR11940-by-getting-scripts-w-global-variables-.patch/runtime/runtime.h 2011-03-22 12:11:00 +0000 |
783 | @@ -0,0 +1,204 @@ |
784 | +/* main header file |
785 | + * Copyright (C) 2005-2008 Red Hat Inc. |
786 | + * Copyright (C) 2005, 2006 Intel Corporation. |
787 | + * |
788 | + * This file is part of systemtap, and is free software. You can |
789 | + * redistribute it and/or modify it under the terms of the GNU General |
790 | + * Public License (GPL); either version 2, or (at your option) any |
791 | + * later version. |
792 | + */ |
793 | + |
794 | +#ifndef _RUNTIME_H_ |
795 | +#define _RUNTIME_H_ |
796 | + |
797 | +#include <linux/module.h> |
798 | +#include <linux/ctype.h> |
799 | +#include <linux/kernel.h> |
800 | +#include <linux/miscdevice.h> |
801 | +#include <linux/init.h> |
802 | +#include <linux/hash.h> |
803 | +#include <linux/string.h> |
804 | +#include <linux/kprobes.h> |
805 | +#include <linux/proc_fs.h> |
806 | +#include <linux/vmalloc.h> |
807 | +#include <linux/time.h> |
808 | +#include <linux/spinlock.h> |
809 | +#include <linux/hardirq.h> |
810 | +#include <asm/uaccess.h> |
811 | +#include <linux/kallsyms.h> |
812 | +#include <linux/version.h> |
813 | +#include <linux/compat.h> |
814 | +#include <linux/sched.h> |
815 | +#include <linux/mm.h> |
816 | + |
817 | + |
818 | +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15) |
819 | +#if !defined (CONFIG_DEBUG_FS) && !defined (CONFIG_DEBUG_FS_MODULE) |
820 | +#error "DebugFS is required and was not found in the kernel." |
821 | +#endif |
822 | +#ifdef CONFIG_RING_BUFFER |
823 | +#define STP_TRANSPORT_VERSION 3 |
824 | +#else |
825 | +#define STP_TRANSPORT_VERSION 2 |
826 | +#endif |
827 | +#else |
828 | +/* older kernels have no debugfs and older version of relayfs. */ |
829 | +#define STP_TRANSPORT_VERSION 1 |
830 | +#endif |
831 | + |
832 | +#ifndef stp_for_each_cpu |
833 | +#define stp_for_each_cpu(cpu) for_each_cpu_mask((cpu), cpu_possible_map) |
834 | +#endif |
835 | + |
836 | +#ifndef clamp |
837 | +#define clamp(val, low, high) min(max(low, val), high) |
838 | +#endif |
839 | + |
840 | +#ifndef clamp_t |
841 | +#define clamp_t(type, val, low, high) min_t(type, max_t(type, low, val), high) |
842 | +#endif |
843 | + |
844 | +static void _stp_dbug (const char *func, int line, const char *fmt, ...) __attribute__ ((format (printf, 3, 4))); |
845 | +static void _stp_error (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); |
846 | +static void _stp_warn (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); |
847 | + |
848 | +static void _stp_exit(void); |
849 | + |
850 | + |
851 | + |
852 | +/* unprivileged user support */ |
853 | + |
854 | +#ifdef STAPCONF_TASK_UID |
855 | +#define STP_CURRENT_EUID (current->euid) |
856 | +#else |
857 | +#define STP_CURRENT_EUID (task_euid(current)) |
858 | +#endif |
859 | + |
860 | +#define is_myproc() (STP_CURRENT_EUID == _stp_uid) |
861 | + |
862 | +#ifndef STP_PRIVILEGED |
863 | +#define assert_is_myproc() do { \ |
864 | + if (! is_myproc()) { \ |
865 | + snprintf (CONTEXT->error_buffer, MAXSTRINGLEN, "semi-privileged tapset function called without is_myproc checking for pid %d (euid %d)", \ |
866 | + current->tgid, STP_CURRENT_EUID); \ |
867 | + CONTEXT->last_error = CONTEXT->error_buffer; \ |
868 | + goto out; \ |
869 | + } } while (0) |
870 | +#else |
871 | +#define assert_is_myproc() do {} while (0) |
872 | +#endif |
873 | + |
874 | + |
875 | + |
876 | +#include "debug.h" |
877 | + |
878 | +/* atomic globals */ |
879 | +static atomic_t _stp_transport_failures = ATOMIC_INIT (0); |
880 | + |
881 | +static struct |
882 | +{ |
883 | + atomic_t ____cacheline_aligned_in_smp seq; |
884 | +} _stp_seq = { ATOMIC_INIT (0) }; |
885 | + |
886 | +#define _stp_seq_inc() (atomic_inc_return(&_stp_seq.seq)) |
887 | + |
888 | +#ifndef MAXSTRINGLEN |
889 | +#define MAXSTRINGLEN 128 |
890 | +#endif |
891 | + |
892 | +#ifndef MAXTRACE |
893 | +#define MAXTRACE 20 |
894 | +#endif |
895 | + |
896 | +/* dwarf unwinder only tested so far on i386 and x86_64. */ |
897 | +#if (defined(__i386__) || defined(__x86_64__)) |
898 | +#ifndef STP_USE_DWARF_UNWINDER |
899 | +#define STP_USE_DWARF_UNWINDER |
900 | +#endif |
901 | +#endif |
902 | + |
903 | +#ifdef CONFIG_FRAME_POINTER |
904 | +/* Just because frame pointers are available does not mean we can trust them. */ |
905 | +#ifndef STP_USE_DWARF_UNWINDER |
906 | +#define STP_USE_FRAME_POINTER |
907 | +#endif |
908 | +#endif |
909 | + |
910 | +#include "alloc.c" |
911 | +#include "print.c" |
912 | +#include "string.c" |
913 | +#include "io.c" |
914 | +#include "arith.c" |
915 | +#include "copy.c" |
916 | +#include "regs.c" |
917 | +#include "regs-ia64.c" |
918 | +#include "time.c" |
919 | + |
920 | +#include "task_finder.c" |
921 | + |
922 | +#include "sym.c" |
923 | +#ifdef STP_PERFMON |
924 | +#include "perf.c" |
925 | +#endif |
926 | +#include "addr-map.c" |
927 | + |
928 | + |
929 | + |
930 | +/* Support functions for int64_t module parameters. */ |
931 | +static int param_set_int64_t(const char *val, struct kernel_param *kp) |
932 | +{ |
933 | + char *endp; |
934 | + long long ll; |
935 | + |
936 | + if (!val) |
937 | + return -EINVAL; |
938 | + |
939 | + /* simple_strtoll isn't exported... */ |
940 | + if (*val == '-') |
941 | + ll = -simple_strtoull(val+1, &endp, 0); |
942 | + else |
943 | + ll = simple_strtoull(val, &endp, 0); |
944 | + |
945 | + if ((endp == val) || ((int64_t)ll != ll)) |
946 | + return -EINVAL; |
947 | + |
948 | + *((int64_t *)kp->arg) = ll; |
949 | + return 0; |
950 | +} |
951 | + |
952 | +static int param_get_int64_t(char *buffer, struct kernel_param *kp) |
953 | +{ |
954 | + return sprintf(buffer, "%lli", (long long)*((int64_t *)kp->arg)); |
955 | +} |
956 | + |
957 | +#define param_check_int64_t(name, p) __param_check(name, p, int64_t) |
958 | + |
959 | + |
960 | +/************* Module Stuff ********************/ |
961 | + |
962 | +int init_module (void) |
963 | +{ |
964 | + return _stp_transport_init(); |
965 | +} |
966 | + |
967 | +static int probe_start(void); |
968 | + |
969 | +void cleanup_module(void) |
970 | +{ |
971 | + _stp_transport_close(); |
972 | +} |
973 | + |
974 | +#define pseudo_atomic_cmpxchg(v, old, new) ({\ |
975 | + int ret;\ |
976 | + unsigned long flags;\ |
977 | + local_irq_save(flags);\ |
978 | + ret = atomic_read(v);\ |
979 | + if (likely(ret == old))\ |
980 | + atomic_set(v, new);\ |
981 | + local_irq_restore(flags);\ |
982 | + ret; }) |
983 | + |
984 | + |
985 | +MODULE_LICENSE("GPL"); |
986 | + |
987 | +#endif /* _RUNTIME_H_ */ |
988 | |
989 | === added directory '.pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch' |
990 | === added directory '.pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/tapset' |
991 | === added file '.pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/tapset/ip.stp' |
992 | --- .pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/tapset/ip.stp 1970-01-01 00:00:00 +0000 |
993 | +++ .pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/tapset/ip.stp 2011-03-22 12:11:00 +0000 |
994 | @@ -0,0 +1,86 @@ |
995 | +// IP tapset |
996 | +// |
997 | +// Copyright (C) 2009, IBM Inc. |
998 | +// Copyright (C) 2010, Red Hat Inc. |
999 | +// |
1000 | +// Author : Breno Leitao <leitao@linux.vnet.ibm.com> |
1001 | +// |
1002 | +// This file is free software. You can redistribute it and/or modify it under |
1003 | +// the terms of the GNU General Public License (GPL), version 2. |
1004 | +// |
1005 | +// Based on previous work done by Arnaldo Carvalho de Melo <acme@redhat.com> |
1006 | + |
1007 | +%{ |
1008 | +#include <linux/skbuff.h> |
1009 | +%} |
1010 | + |
1011 | +/** |
1012 | + * sfunction ip_ntop - returns a string representation from an integer IP number |
1013 | + * @addr: the ip represented as an integer |
1014 | + */ |
1015 | +function ip_ntop:string (addr:long) |
1016 | +%{ |
1017 | + __be32 ip; |
1018 | + |
1019 | + ip = THIS->addr; |
1020 | + snprintf(THIS->__retvalue, MAXSTRINGLEN, NIPQUAD_FMT, NIPQUAD(ip)); |
1021 | +%} |
1022 | + |
1023 | +/* return the source IP address for a given sock */ |
1024 | +function __ip_sock_saddr:long (sock:long) |
1025 | +{ |
1026 | + return (@defined(@cast(sock, "inet_sock")->inet_saddr) |
1027 | + ? @cast(sock, "inet_sock")->inet_saddr # kernel >= 2.6.33 |
1028 | + : (@defined(@cast(sock, "inet_sock")->saddr) |
1029 | + ? @cast(sock, "inet_sock", "kernel")->saddr # kernel >= 2.6.11 |
1030 | + : @cast(sock, "inet_sock", "kernel<net/ip.h>")->inet->saddr)) |
1031 | +} |
1032 | + |
1033 | +/* return the destination IP address for a given sock */ |
1034 | +function __ip_sock_daddr:long (sock:long) |
1035 | +{ |
1036 | + return (@defined(@cast(sock, "inet_sock")->inet_daddr) |
1037 | + ? @cast(sock, "inet_sock")->inet_daddr # kernel >= 2.6.33 |
1038 | + : (@defined(@cast(sock, "inet_sock")->daddr) |
1039 | + ? @cast(sock, "inet_sock", "kernel")->daddr # kernel >= 2.6.11 |
1040 | + : @cast(sock, "inet_sock", "kernel<net/ip.h>")->inet->daddr)) |
1041 | +} |
1042 | + |
1043 | +/* Get the IP header from a sk_buff struct */ |
1044 | +function __get_skb_iphdr:long(skb:long) |
1045 | +%( kernel_v < "2.6.21" %? |
1046 | +{ |
1047 | + iphdr = @cast(skb, "sk_buff")->nh->raw |
1048 | + return iphdr |
1049 | +} |
1050 | +%: |
1051 | +%{ /* pure */ |
1052 | + struct sk_buff *skb; |
1053 | + skb = (struct sk_buff *)(long)THIS->skb; |
1054 | + /* as done by skb_network_header() */ |
1055 | + #ifdef NET_SKBUFF_DATA_USES_OFFSET |
1056 | + THIS->__retvalue = (long)(kread(&(skb->head)) + kread(&(skb->network_header))); |
1057 | + #else |
1058 | + THIS->__retvalue = (long)kread(&(skb->network_header)); |
1059 | + #endif |
1060 | + CATCH_DEREF_FAULT(); |
1061 | +%} |
1062 | +%) |
1063 | + |
1064 | +/* return the source next layer protocol for a given sk_buff structure */ |
1065 | +function __ip_skb_proto:long (iphdr) |
1066 | +{ |
1067 | + return @cast(iphdr, "iphdr")->protocol |
1068 | +} |
1069 | + |
1070 | +/* return the source IP address for a given sk_buff structure */ |
1071 | +function __ip_skb_saddr:long (iphdr) |
1072 | +{ |
1073 | + return @cast(iphdr, "iphdr")->saddr |
1074 | +} |
1075 | + |
1076 | +/* return the destination IP address for a given skb */ |
1077 | +function __ip_skb_daddr:long (iphdr) |
1078 | +{ |
1079 | + return @cast(iphdr, "iphdr")->daddr |
1080 | +} |
1081 | |
1082 | === added directory '.pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/testsuite' |
1083 | === added directory '.pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/testsuite/systemtap.examples' |
1084 | === added directory '.pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/testsuite/systemtap.examples/process' |
1085 | === added file '.pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/testsuite/systemtap.examples/process/pfiles.stp' |
1086 | --- .pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/testsuite/systemtap.examples/process/pfiles.stp 1970-01-01 00:00:00 +0000 |
1087 | +++ .pc/Local-definitions-of-NIPQUAD-and-NIPQUAD_FMT-when-re.patch/testsuite/systemtap.examples/process/pfiles.stp 2011-03-22 12:11:00 +0000 |
1088 | @@ -0,0 +1,612 @@ |
1089 | +#! /bin/sh |
1090 | + |
1091 | +//bin/true && exec stap -g $0 ${1+"$@"} |
1092 | + |
1093 | +# pfiles |
1094 | +# Copyright (C) 2007-2010 Red Hat, Inc., Eugene Teo <eteo@redhat.com> |
1095 | +# |
1096 | +# This program is free software; you can redistribute it and/or modify |
1097 | +# it under the terms of the GNU General Public License version 2 as |
1098 | +# published by the Free Software Foundation. |
1099 | +# |
1100 | +# pfiles report information for all open files by the process id. |
1101 | +# |
1102 | +# pfiles is not a port of Solaris' pfiles tool. It was written based on the |
1103 | +# example outputs in: |
1104 | +# - https://bugzilla.redhat.com/show_bug.cgi?id=223489 |
1105 | +# - http://blogs.sun.com/peteh/entry/pfiles_1_locked_files_and |
1106 | +# - http://lists.samba.org/archive/samba-technical/2001-May/014293.html |
1107 | +# - http://mail.gnome.org/archives/gconf-list/2004-December/msg00005.html |
1108 | +# |
1109 | +# systemtap SNAPSHOT c9116e9980ad6e417697737f8d54a4a625811245 |
1110 | +# on kernel 2.6.18-128.1.13.el5 |
1111 | +# and on kernel 2.6.27.21-170.2.56.fc10.i686.PAE |
1112 | +# |
1113 | +# Last updated: Thu May 28 20:37:57 SGT 2009 |
1114 | +# |
1115 | +# pfiles is able to: |
1116 | +# - report locked open files |
1117 | +# - report pathname information |
1118 | +# - report socket information (thanks Luis Henriques) |
1119 | +# - report sk_userlocks (thanks Arnaldo Carvalho de Melo) |
1120 | +# - report socket options |
1121 | +# |
1122 | +# Example: |
1123 | +# $ ./pfiles.stp `pgrep udevd` |
1124 | +# 787: udevd |
1125 | +# Current rlimit: 32 file descriptors |
1126 | +# 0: S_IFCHR mode:0666 dev:0,15 ino:396 uid:0 gid:0 rdev:1,3 |
1127 | +# O_RDWR|O_LARGEFILE |
1128 | +# /dev/null |
1129 | +# 1: S_IFCHR mode:0666 dev:0,15 ino:396 uid:0 gid:0 rdev:1,3 |
1130 | +# O_RDWR|O_LARGEFILE |
1131 | +# /dev/null |
1132 | +# 2: S_IFCHR mode:0666 dev:0,15 ino:396 uid:0 gid:0 rdev:1,3 |
1133 | +# O_RDWR|O_LARGEFILE |
1134 | +# /dev/null |
1135 | +# 3: S_IFDIR mode:0600 dev:0,9 ino:1 uid:0 gid:0 rdev:0,0 |
1136 | +# O_RDONLY |
1137 | +# inotify |
1138 | +# 4: S_IFSOCK mode:0777 dev:0,4 ino:2353 uid:0 gid:0 rdev:0,0 |
1139 | +# O_RDWR |
1140 | +# socket:[2353] |
1141 | +# SO_PASSCRED,SO_TYPE(2),SO_SNDBUF(111616),SO_RCVBUF(111616) |
1142 | +# sockname: AF_UNIX |
1143 | +# 5: S_IFSOCK mode:0777 dev:0,4 ino:2354 uid:0 gid:0 rdev:0,0 |
1144 | +# O_RDWR |
1145 | +# socket:[2354] |
1146 | +# SO_TYPE(2),SO_SNDBUF(111616),SO_RCVBUF(33554432) |
1147 | +# ulocks: rcv |
1148 | +# 6: S_IFIFO mode:0600 dev:0,6 ino:2355 uid:0 gid:0 rdev:0,0 |
1149 | +# O_RDONLY|O_NONBLOCK |
1150 | +# pipe:[2355] |
1151 | +# 7: S_IFIFO mode:0600 dev:0,6 ino:2355 uid:0 gid:0 rdev:0,0 |
1152 | +# O_WRONLY|O_NONBLOCK |
1153 | +# pipe:[2355] |
1154 | +# |
1155 | +# I used Andrew Tridgell's locktst.c to test the advisory lock code. |
1156 | +# You can download it at http://samba.org/ftp/unpacked/junkcode/locktst.c |
1157 | +# |
1158 | +# $ ./locktst file & |
1159 | +# fcntl_lock 3 6 1 1 1 |
1160 | +# $ pfiles 10126 | grep advisory -A1 -B2 |
1161 | +# 3: S_IFREG mode:0644 dev:253,0 ino:15237159 uid:500 gid:500 rdev:0,0 |
1162 | +# O_RDWR |
1163 | +# advisory write lock set by process 10126 |
1164 | +# /home/eteo/pfiles/file |
1165 | +# |
1166 | + |
1167 | +%{ |
1168 | +#include <linux/file.h> |
1169 | +#include <net/sock.h> |
1170 | +#include <linux/un.h> |
1171 | +#include <linux/tcp.h> |
1172 | +%} |
1173 | + |
1174 | +function task_valid_file_handle:long (task:long, fd:long) %{ /* pure */ |
1175 | + struct task_struct *p = (struct task_struct *)((long)THIS->task); |
1176 | + struct files_struct *files = kread(&p->files); |
1177 | + struct file *filp; |
1178 | + |
1179 | + rcu_read_lock(); |
1180 | + filp = fcheck_files(files, THIS->fd); |
1181 | + if (!filp) { |
1182 | + THIS->__retvalue = 0; |
1183 | + rcu_read_unlock(); |
1184 | + return; |
1185 | + } |
1186 | + THIS->__retvalue = (long)filp; |
1187 | + rcu_read_unlock(); |
1188 | + |
1189 | + CATCH_DEREF_FAULT(); |
1190 | +%} |
1191 | + |
1192 | +function i_mode2str:string (i_mode:long) %{ /* pure */ |
1193 | + snprintf(THIS->__retvalue, MAXSTRINGLEN, "%d", (int)THIS->i_mode); |
1194 | + THIS->i_mode = simple_strtol(THIS->__retvalue, NULL, 10); |
1195 | + |
1196 | + if (S_ISLNK(THIS->i_mode)) strlcpy (THIS->__retvalue, "S_IFLNK", MAXSTRINGLEN); |
1197 | + else if (S_ISREG(THIS->i_mode)) strlcpy (THIS->__retvalue, "S_IFREG", MAXSTRINGLEN); |
1198 | + else if (S_ISDIR(THIS->i_mode)) strlcpy (THIS->__retvalue, "S_IFDIR", MAXSTRINGLEN); |
1199 | + else if (S_ISCHR(THIS->i_mode)) strlcpy (THIS->__retvalue, "S_IFCHR", MAXSTRINGLEN); |
1200 | + else if (S_ISBLK(THIS->i_mode)) strlcpy (THIS->__retvalue, "S_IFBLK", MAXSTRINGLEN); |
1201 | + else if (S_ISFIFO(THIS->i_mode)) strlcpy (THIS->__retvalue, "S_IFIFO", MAXSTRINGLEN); |
1202 | + else if (S_ISSOCK(THIS->i_mode)) strlcpy (THIS->__retvalue, "S_IFSOCK", MAXSTRINGLEN); |
1203 | +%} |
1204 | + |
1205 | +function task_file_handle_i_mode:long (task:long, fd:long) %{ /* pure */ |
1206 | + struct task_struct *p = (struct task_struct *)((long)THIS->task); |
1207 | + struct files_struct *files = kread(&p->files); |
1208 | + struct file *filp; |
1209 | + |
1210 | + rcu_read_lock(); |
1211 | + filp = fcheck_files(files, THIS->fd); |
1212 | + THIS->__retvalue = kread(&filp->f_dentry->d_inode->i_mode); |
1213 | + rcu_read_unlock(); |
1214 | + |
1215 | + CATCH_DEREF_FAULT(); |
1216 | +%} |
1217 | + |
1218 | +function task_file_handle_majmin_dev:string (task:long, fd:long) %{ /* pure */ |
1219 | + struct task_struct *p = (struct task_struct *)((long)THIS->task); |
1220 | + struct files_struct *files = kread(&p->files); |
1221 | + struct file *filp; |
1222 | + int dev_nr; |
1223 | + |
1224 | + rcu_read_lock(); |
1225 | + filp = fcheck_files(files, THIS->fd); |
1226 | + dev_nr = kread(&filp->f_dentry->d_inode->i_sb->s_dev); |
1227 | + snprintf(THIS->__retvalue, MAXSTRINGLEN, |
1228 | + "%d,%d", MAJOR(dev_nr), MINOR(dev_nr)); |
1229 | + rcu_read_unlock(); |
1230 | + |
1231 | + CATCH_DEREF_FAULT(); |
1232 | +%} |
1233 | + |
1234 | +function task_file_handle_majmin_rdev:string (task:long, fd:long) %{ /* pure */ |
1235 | + struct task_struct *p = (struct task_struct *)((long)THIS->task); |
1236 | + struct files_struct *files = kread(&p->files); |
1237 | + struct file *filp; |
1238 | + int rdev_nr; |
1239 | + |
1240 | + rcu_read_lock(); |
1241 | + filp = fcheck_files(files, THIS->fd); |
1242 | + rdev_nr = kread(&filp->f_dentry->d_inode->i_rdev); |
1243 | + snprintf(THIS->__retvalue, MAXSTRINGLEN, |
1244 | + "%d,%d", MAJOR(rdev_nr), MINOR(rdev_nr)); |
1245 | + rcu_read_unlock(); |
1246 | + |
1247 | + CATCH_DEREF_FAULT(); |
1248 | +%} |
1249 | + |
1250 | +function task_file_handle_i_node:long (task:long, fd:long) %{ /* pure */ |
1251 | + struct task_struct *p = (struct task_struct *)((long)THIS->task); |
1252 | + struct files_struct *files = kread(&p->files); |
1253 | + struct file *filp; |
1254 | + |
1255 | + rcu_read_lock(); |
1256 | + filp = fcheck_files(files, THIS->fd); |
1257 | + THIS->__retvalue = kread(&filp->f_dentry->d_inode->i_ino); |
1258 | + rcu_read_unlock(); |
1259 | + |
1260 | + CATCH_DEREF_FAULT(); |
1261 | +%} |
1262 | + |
1263 | +function task_file_handle_uid:long (task:long, fd:long) %{ /* pure */ |
1264 | + struct task_struct *p = (struct task_struct *)((long)THIS->task); |
1265 | + struct files_struct *files = kread(&p->files); |
1266 | + struct file *filp; |
1267 | + |
1268 | + rcu_read_lock(); |
1269 | + filp = fcheck_files(files, THIS->fd); |
1270 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) |
1271 | + /* git commit d76b0d9b */ |
1272 | + THIS->__retvalue = kread(&filp->f_cred->fsuid); |
1273 | +#else |
1274 | + THIS->__retvalue = kread(&filp->f_uid); |
1275 | +#endif |
1276 | + rcu_read_unlock(); |
1277 | + |
1278 | + CATCH_DEREF_FAULT(); |
1279 | +%} |
1280 | + |
1281 | +function task_file_handle_gid:long (task:long, fd:long) %{ /* pure */ |
1282 | + struct task_struct *p = (struct task_struct *)((long)THIS->task); |
1283 | + struct files_struct *files = kread(&p->files); |
1284 | + struct file *filp; |
1285 | + |
1286 | + rcu_read_lock(); |
1287 | + filp = fcheck_files(files, THIS->fd); |
1288 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) |
1289 | + /* git commit d76b0d9b */ |
1290 | + THIS->__retvalue = kread(&filp->f_cred->fsgid); |
1291 | +#else |
1292 | + THIS->__retvalue = kread(&filp->f_gid); |
1293 | +#endif |
1294 | + rcu_read_unlock(); |
1295 | + |
1296 | + CATCH_DEREF_FAULT(); |
1297 | +%} |
1298 | + |
1299 | +function task_file_handle_f_flags:long (task:long, fd:long) %{ /* pure */ |
1300 | + struct task_struct *p = (struct task_struct *)((long)THIS->task); |
1301 | + struct files_struct *files = kread(&p->files); |
1302 | + struct file *filp; |
1303 | + |
1304 | + rcu_read_lock(); |
1305 | + filp = fcheck_files(files, THIS->fd); |
1306 | + THIS->__retvalue = kread(&filp->f_flags); |
1307 | + rcu_read_unlock(); |
1308 | + |
1309 | + CATCH_DEREF_FAULT(); |
1310 | +%} |
1311 | + |
1312 | +function task_file_handle_fd_flags:string (task:long, fd:long) %{ /* pure */ |
1313 | + struct task_struct *p = (struct task_struct *)((long)THIS->task); |
1314 | + struct files_struct *files = kread(&p->files); |
1315 | + struct fdtable *fdt; |
1316 | + int gcoe; |
1317 | + |
1318 | + rcu_read_lock(); |
1319 | + fdt = files_fdtable(files); |
1320 | + gcoe = FD_ISSET(THIS->fd, kread(&fdt->close_on_exec)); |
1321 | + snprintf(THIS->__retvalue, MAXSTRINGLEN, |
1322 | + "%s", gcoe ? "FD_CLOEXEC" : ""); |
1323 | + rcu_read_unlock(); |
1324 | + |
1325 | + CATCH_DEREF_FAULT(); |
1326 | +%} |
1327 | + |
1328 | +function task_file_handle_flock:string (task:long, fd:long) %{ /* pure */ |
1329 | + struct task_struct *p = (struct task_struct *)((long)THIS->task); |
1330 | + struct files_struct *files = kread(&p->files); |
1331 | + struct file_lock *flock; |
1332 | + int fl_type, fl_pid; |
1333 | + struct file *filp; |
1334 | + |
1335 | + rcu_read_lock(); |
1336 | + filp = fcheck_files(files, THIS->fd); |
1337 | + flock = kread(&filp->f_dentry->d_inode->i_flock); |
1338 | + fl_type = fl_pid = -1; |
1339 | + if (flock) { |
1340 | + fl_type = kread(&flock->fl_type); |
1341 | + fl_pid = kread(&flock->fl_pid); |
1342 | + } |
1343 | + |
1344 | + if (fl_type != -1) /* !flock */ |
1345 | + snprintf(THIS->__retvalue, MAXSTRINGLEN, |
1346 | + " advisory %s lock set by process %d", |
1347 | + fl_type ? "write" : "read", fl_pid); |
1348 | + else |
1349 | + snprintf(THIS->__retvalue, MAXSTRINGLEN, "NULL"); |
1350 | + rcu_read_unlock(); |
1351 | + |
1352 | + CATCH_DEREF_FAULT(); |
1353 | +%} |
1354 | + |
1355 | +function task_file_handle_d_path:string (task:long, fd:long) %{ /* pure */ |
1356 | + struct task_struct *p = (struct task_struct *)((long)THIS->task); |
1357 | + struct files_struct *files = kread(&p->files); |
1358 | + char *page = (char *)__get_free_page(GFP_KERNEL); |
1359 | + struct file *filp; |
1360 | + struct dentry *dentry; |
1361 | + struct vfsmount *vfsmnt; |
1362 | + |
1363 | + /* TODO: handle !page */ |
1364 | + if (!page) |
1365 | + return; |
1366 | + |
1367 | + rcu_read_lock(); |
1368 | + filp = fcheck_files(files, THIS->fd); |
1369 | + dentry = kread(&filp->f_dentry); |
1370 | + vfsmnt = kread(&filp->f_vfsmnt); |
1371 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) |
1372 | + /* git commit 9d1bc601 */ |
1373 | + snprintf(THIS->__retvalue, MAXSTRINGLEN, "%s", |
1374 | + d_path(&filp->f_path, page, PAGE_SIZE)); |
1375 | +#else |
1376 | + snprintf(THIS->__retvalue, MAXSTRINGLEN, "%s", |
1377 | + d_path(dentry, vfsmnt, page, PAGE_SIZE)); |
1378 | +#endif |
1379 | + free_page((unsigned long)page); |
1380 | + rcu_read_unlock(); |
1381 | + |
1382 | + CATCH_DEREF_FAULT(); |
1383 | +%} |
1384 | + |
1385 | +function task_file_handle_socket:long (task:long, fd:long) %{ /* pure */ |
1386 | + struct task_struct *p = (struct task_struct *)((long)THIS->task); |
1387 | + struct files_struct *files = kread(&p->files); |
1388 | + struct inode *inode; |
1389 | + struct file *filp; |
1390 | + |
1391 | + rcu_read_lock(); |
1392 | + filp = fcheck_files(files, THIS->fd); |
1393 | + if (!filp) { |
1394 | + THIS->__retvalue = 0; |
1395 | + rcu_read_unlock(); |
1396 | + return; |
1397 | + } |
1398 | + inode = kread(&filp->f_dentry->d_inode); |
1399 | + if (S_ISSOCK(kread(&inode->i_mode))) |
1400 | + THIS->__retvalue = (long)SOCKET_I(inode); |
1401 | + rcu_read_unlock(); |
1402 | + |
1403 | + CATCH_DEREF_FAULT(); |
1404 | +%} |
1405 | + |
1406 | +function socket_userlocks:string (sock:long) %{ /* pure */ |
1407 | + struct socket *sock = (struct socket *)((long)THIS->sock); |
1408 | + struct sock *sk = (struct sock *)kread(&sock->sk); |
1409 | + unsigned char locks = sk->sk_userlocks; |
1410 | + int printed = 0; |
1411 | + |
1412 | + THIS->__retvalue[0] = '\0'; |
1413 | + |
1414 | + if (locks & SOCK_RCVBUF_LOCK) |
1415 | + printed = snprintf(THIS->__retvalue, MAXSTRINGLEN, |
1416 | + "ulocks: rcv"); |
1417 | + |
1418 | + if (locks & SOCK_SNDBUF_LOCK) |
1419 | + snprintf(THIS->__retvalue, MAXSTRINGLEN, |
1420 | + "ulocks: %ssnd", |
1421 | + printed ? "rcv, " : ""); |
1422 | + |
1423 | + CATCH_DEREF_FAULT(); |
1424 | +%} |
1425 | + |
1426 | +function socket_optname:string (sock:long) %{ /* pure */ |
1427 | + struct socket *sock = (struct socket *)((long)THIS->sock); |
1428 | + int optval; |
1429 | + int optlen; |
1430 | + int ret, a; |
1431 | + char str[30]; |
1432 | + struct linger ling; |
1433 | + struct optname_item { |
1434 | + int optfam; |
1435 | + int optnum; |
1436 | + const char *optname; |
1437 | + int show_val; |
1438 | + } *p; |
1439 | + struct optname_item optname_entries[] = { |
1440 | + { SOL_SOCKET, SO_DEBUG, "SO_DEBUG", 0 }, |
1441 | + { SOL_SOCKET, SO_REUSEADDR, "SO_REUSEADDR", 0 }, |
1442 | + { SOL_SOCKET, SO_DONTROUTE, "SO_DONTROUTE", 0 }, |
1443 | + { SOL_SOCKET, SO_BROADCAST, "SO_BROADCAST", 0 }, |
1444 | + { SOL_SOCKET, SO_KEEPALIVE, "SO_KEEPALIVE", 0 }, |
1445 | + { SOL_SOCKET, SO_OOBINLINE, "SO_OOBINLINE", 0 }, |
1446 | + { SOL_SOCKET, SO_PASSCRED, "SO_PASSCRED", 0 }, |
1447 | +/* { SOL_SOCKET, SO_SNDLOWAT, "SO_SNDLOWAT", 0 },*/ |
1448 | + { SOL_SOCKET, SO_TYPE, "SO_TYPE", 1 }, |
1449 | + { SOL_SOCKET, SO_ERROR, "SO_ERROR", 1 }, |
1450 | + { SOL_SOCKET, SO_SNDBUF, "SO_SNDBUF", 1 }, |
1451 | + { SOL_SOCKET, SO_RCVBUF, "SO_RCVBUF", 1 }, |
1452 | + { SOL_SOCKET, SO_NO_CHECK, "SO_NO_CHECK", 1 }, |
1453 | + { SOL_TCP, TCP_NODELAY, "TCP_NODELAY", 0 }, |
1454 | + { 0, 0, NULL, 0 }, |
1455 | + }; |
1456 | + |
1457 | + for (p = optname_entries; p->optname; ++p) { |
1458 | + optlen = sizeof(optval); |
1459 | + ret = kernel_getsockopt(sock, p->optfam, p->optnum, (char *)&optval, &optlen); |
1460 | + if (ret == 0 && optval != 0) { |
1461 | + if (!p->show_val) |
1462 | + snprintf(str, MAXSTRINGLEN, "%s,", p->optname); |
1463 | + else |
1464 | + snprintf(str, MAXSTRINGLEN, "%s(%d),", p->optname, optval); |
1465 | + strcat(THIS->__retvalue, str); |
1466 | + } |
1467 | + } |
1468 | + |
1469 | + optlen = sizeof(ling); |
1470 | + ret = kernel_getsockopt(sock, SOL_SOCKET, SO_LINGER, (void *)&ling, &optlen); |
1471 | + if (ret == 0 && ling.l_onoff != 0) { |
1472 | + snprintf(str, MAXSTRINGLEN, "SO_LINGER(%d),", ling.l_linger); |
1473 | + strcat(THIS->__retvalue, str); |
1474 | + } |
1475 | + |
1476 | + THIS->__retvalue[strlen(THIS->__retvalue) - 1] = '\0'; |
1477 | + CATCH_DEREF_FAULT(); |
1478 | +%} |
1479 | + |
1480 | +function socket_family:long (sock:long) %{ /* pure */ |
1481 | + struct socket *sock = (struct socket *)((long)THIS->sock); |
1482 | + THIS->__retvalue = (long)kread(&sock->ops->family); |
1483 | + CATCH_DEREF_FAULT(); |
1484 | +%} |
1485 | + |
1486 | +function socket_unix_sockname:string (sock:long) %{ /* pure */ |
1487 | + struct socket *sock = (struct socket *)((long)THIS->sock); |
1488 | + struct sockaddr_un un_addr; |
1489 | + int err, len; |
1490 | + |
1491 | + err = sock->ops->getname(sock, (struct sockaddr *)(&un_addr), &len, 0); |
1492 | +// err = kernel_getsockname(kread(&sock), (struct sockaddr *)(&un_addr), &len); |
1493 | + if (!err) { |
1494 | + if (kread(&un_addr.sun_path[0]) != 0) |
1495 | + snprintf(THIS->__retvalue, MAXSTRINGLEN, |
1496 | + " sockname: AF_UNIX %s", un_addr.sun_path); |
1497 | + else |
1498 | + snprintf(THIS->__retvalue, MAXSTRINGLEN, " sockname: AF_UNIX"); |
1499 | + } |
1500 | + CATCH_DEREF_FAULT(); |
1501 | +%} |
1502 | + |
1503 | +function socket_unix_peername:string (sock:long) %{ /* pure */ |
1504 | + struct socket *sock = (struct socket *)((long)THIS->sock); |
1505 | + struct sockaddr_un un_addr; |
1506 | + int err, len; |
1507 | + |
1508 | + err = sock->ops->getname(sock, (struct sockaddr *)(&un_addr), &len, 1); |
1509 | +// err = kernel_getpeername(kread(&sock), (struct sockaddr *)(&un_addr), &len); |
1510 | + if (!err) { |
1511 | + if (kread(&un_addr.sun_path[0]) != 0) |
1512 | + snprintf(THIS->__retvalue, MAXSTRINGLEN, |
1513 | + " peername: AF_UNIX %s", un_addr.sun_path); |
1514 | + else |
1515 | + snprintf(THIS->__retvalue, MAXSTRINGLEN, " peername: AF_UNIX"); |
1516 | + } |
1517 | + CATCH_DEREF_FAULT(); |
1518 | +%} |
1519 | + |
1520 | +function socket_ipv4_sockname:string (sock:long) %{ /* pure */ |
1521 | + struct socket *sock = (struct socket *)((long)THIS->sock); |
1522 | + struct sockaddr_in in_addr; |
1523 | + __be32 addr, port; |
1524 | + int err, len; |
1525 | + |
1526 | + err = sock->ops->getname (sock, (struct sockaddr*)(&in_addr), &len, 0); |
1527 | + if (!err) { |
1528 | + addr = kread(&in_addr.sin_addr.s_addr); |
1529 | + port = htons(kread(&in_addr.sin_port)); |
1530 | + snprintf(THIS->__retvalue, MAXSTRINGLEN, |
1531 | + " sockname: AF_INET " NIPQUAD_FMT " port: %d", |
1532 | + NIPQUAD(addr), port); |
1533 | + } |
1534 | + CATCH_DEREF_FAULT(); |
1535 | +%} |
1536 | + |
1537 | +function socket_ipv4_peername:string (sock:long) %{ /* pure */ |
1538 | + struct socket *sock = (struct socket *)((long)THIS->sock); |
1539 | + struct sockaddr_in in_addr; |
1540 | + __be32 addr, port; |
1541 | + int err, len; |
1542 | + |
1543 | + err = sock->ops->getname (sock, (struct sockaddr*)(&in_addr), &len, 1); |
1544 | + if (!err) { |
1545 | + addr = kread(&in_addr.sin_addr.s_addr); |
1546 | + port = htons(kread(&in_addr.sin_port)); |
1547 | + snprintf(THIS->__retvalue, MAXSTRINGLEN, |
1548 | + " peername: AF_INET " NIPQUAD_FMT " port: %d", |
1549 | + NIPQUAD(addr), port); |
1550 | + } |
1551 | + CATCH_DEREF_FAULT(); |
1552 | +%} |
1553 | + |
1554 | +%{ |
1555 | +#ifndef NIP6_FMT |
1556 | +#define NIP6_FMT "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x" |
1557 | +#endif |
1558 | +#ifndef NIP6 |
1559 | +#define NIP6(addr) \ |
1560 | + ntohs((addr).s6_addr16[0]), \ |
1561 | + ntohs((addr).s6_addr16[1]), \ |
1562 | + ntohs((addr).s6_addr16[2]), \ |
1563 | + ntohs((addr).s6_addr16[3]), \ |
1564 | + ntohs((addr).s6_addr16[4]), \ |
1565 | + ntohs((addr).s6_addr16[5]), \ |
1566 | + ntohs((addr).s6_addr16[6]), \ |
1567 | + ntohs((addr).s6_addr16[7]) |
1568 | +#endif |
1569 | + |
1570 | +%} |
1571 | + |
1572 | +function socket_ipv6_sockname:string (sock:long) %{ /* pure */ |
1573 | + struct socket *sock = (struct socket *)((long)THIS->sock); |
1574 | + struct sockaddr_in6 in_addr; |
1575 | + __be32 port; |
1576 | + int err, len; |
1577 | + |
1578 | + err = sock->ops->getname (sock, (struct sockaddr*)(&in_addr), &len, 0); |
1579 | + if (!err) { |
1580 | + port = htons(kread(&in_addr.sin6_port)); |
1581 | + snprintf(THIS->__retvalue, MAXSTRINGLEN, |
1582 | + " sockname: AF_INET6 " NIP6_FMT " port: %d", |
1583 | + NIP6(in_addr.sin6_addr), port); |
1584 | + } |
1585 | + CATCH_DEREF_FAULT(); |
1586 | +%} |
1587 | + |
1588 | +function socket_ipv6_peername:string (sock:long) %{ /* pure */ |
1589 | + struct socket *sock = (struct socket *)((long)THIS->sock); |
1590 | + struct sockaddr_in6 in_addr; |
1591 | + __be32 port; |
1592 | + int err, len; |
1593 | + |
1594 | + err = sock->ops->getname (sock, (struct sockaddr*)(&in_addr), &len, 1); |
1595 | + if (!err) { |
1596 | + port = htons(kread(&in_addr.sin6_port)); |
1597 | + snprintf(THIS->__retvalue, MAXSTRINGLEN, |
1598 | + " peername: AF_INET6 " NIP6_FMT " port: %d", |
1599 | + NIP6(in_addr.sin6_addr), port); |
1600 | + } |
1601 | + CATCH_DEREF_FAULT(); |
1602 | +%} |
1603 | + |
1604 | +function print_file_handle_general(task, fd) { |
1605 | + printf("%4d: %s mode:%04o dev:%s ino:%d uid:%d gid:%d rdev:%s\n", |
1606 | + fd, i_mode2str(task_file_handle_i_mode(task, fd)), |
1607 | + task_file_handle_i_mode(task, fd) & 0777, |
1608 | + task_file_handle_majmin_dev(task, fd), |
1609 | + task_file_handle_i_node(task, fd), |
1610 | + task_file_handle_uid(task, fd), |
1611 | + task_file_handle_gid(task, fd), |
1612 | + task_file_handle_majmin_rdev(task, fd)); |
1613 | +} |
1614 | + |
1615 | +function print_file_handle_flags(task, fd) { |
1616 | + printf(" %s %s\n", |
1617 | + _sys_open_flag_str(task_file_handle_f_flags(task, fd)), |
1618 | + task_file_handle_fd_flags(task, fd)); |
1619 | +} |
1620 | + |
1621 | +function print_file_handle_flock(task, fd) { |
1622 | + flock = task_file_handle_flock(task, fd) |
1623 | + if (!isinstr(flock, "NULL")) |
1624 | + printf("%s\n", flock) |
1625 | +} |
1626 | + |
1627 | +function print_file_handle_d_path(task, fd) { |
1628 | + printf(" %s\n", task_file_handle_d_path(task, fd)) |
1629 | +} |
1630 | + |
1631 | +function print_socket_userlocks(sock) { |
1632 | + slocks = socket_userlocks(sock) |
1633 | + if (strlen(slocks) > 0) |
1634 | + printf(" %s\n", slocks) |
1635 | +} |
1636 | + |
1637 | +function print_unix_socket(sock) { |
1638 | + sockname = socket_unix_sockname(sock) |
1639 | + peername = socket_unix_peername(sock) |
1640 | + printf("%s%s", strlen(sockname) > 0 ? sockname . "\n" : "", |
1641 | + strlen(peername) > 0 ? peername . "\n" : "") |
1642 | +} |
1643 | + |
1644 | +function print_ipv4_socket(sock) { |
1645 | + sockname = socket_ipv4_sockname(sock) |
1646 | + peername = socket_ipv4_peername(sock) |
1647 | + printf("%s%s", strlen(sockname) > 0 ? sockname . "\n" : "", |
1648 | + strlen(peername) > 0 ? peername . "\n" : "") |
1649 | +} |
1650 | + |
1651 | +function print_ipv6_socket(sock) { |
1652 | + sockname = socket_ipv6_sockname(sock) |
1653 | + peername = socket_ipv6_peername(sock) |
1654 | + printf("%s%s", strlen(sockname) > 0 ? sockname . "\n" : "", |
1655 | + strlen(peername) > 0 ? peername . "\n" : "") |
1656 | +} |
1657 | + |
1658 | +function print_socket_optname(sock) { |
1659 | + str = socket_optname(sock) |
1660 | + printf(" %s", strlen(str) > 0 ? str . "\n" : "") |
1661 | +} |
1662 | + |
1663 | +probe begin { |
1664 | +%( $# < 1 |
1665 | + %? pid = target() |
1666 | + %: pid = $1 |
1667 | +%) |
1668 | + # if (pid == 0) error ("Please provide valid target process-id as $1 or -x PID"); |
1669 | + task = pid2task(pid) |
1670 | + if (task == 0) error (sprintf("Process-id %d is invalid, please provide valid PID as $1 or -x PID", pid)) |
1671 | + |
1672 | + max_fds = task_max_file_handles(task) |
1673 | + |
1674 | + printf("%6d: %s\n", pid, pid2execname(pid)) |
1675 | + printf(" Current rlimit: %d file descriptors\n", max_fds) |
1676 | + |
1677 | + for (fd = 0; fd < max_fds; fd++) { |
1678 | + if (task_valid_file_handle(task, fd)) { |
1679 | + print_file_handle_general(task, fd) |
1680 | + print_file_handle_flags(task, fd) |
1681 | + print_file_handle_flock(task, fd) |
1682 | + print_file_handle_d_path(task, fd) |
1683 | + sock = task_file_handle_socket(task, fd) |
1684 | + if (sock) { |
1685 | + print_socket_optname(sock) |
1686 | + fam = socket_family(sock) |
1687 | + if (fam == 1) { /* AF_UNIX */ |
1688 | + print_unix_socket(sock) |
1689 | + } else if (fam == 2) { /* AF_INET */ |
1690 | + print_ipv4_socket(sock) |
1691 | + } else if (fam == 10) { /* AF_INET6 */ |
1692 | + print_ipv6_socket(sock) |
1693 | + } |
1694 | + print_socket_userlocks(sock) |
1695 | + } |
1696 | + } |
1697 | + } |
1698 | + |
1699 | + exit() |
1700 | +} |
1701 | |
1702 | === added directory '.pc/Updated-__ip_sock_daddr-for-2.6.38-kernels.patch' |
1703 | === added directory '.pc/Updated-__ip_sock_daddr-for-2.6.38-kernels.patch/tapset' |
1704 | === added file '.pc/Updated-__ip_sock_daddr-for-2.6.38-kernels.patch/tapset/ip.stp' |
1705 | --- .pc/Updated-__ip_sock_daddr-for-2.6.38-kernels.patch/tapset/ip.stp 1970-01-01 00:00:00 +0000 |
1706 | +++ .pc/Updated-__ip_sock_daddr-for-2.6.38-kernels.patch/tapset/ip.stp 2011-03-22 12:11:00 +0000 |
1707 | @@ -0,0 +1,96 @@ |
1708 | +// IP tapset |
1709 | +// |
1710 | +// Copyright (C) 2009, IBM Inc. |
1711 | +// Copyright (C) 2010, Red Hat Inc. |
1712 | +// |
1713 | +// Author : Breno Leitao <leitao@linux.vnet.ibm.com> |
1714 | +// |
1715 | +// This file is free software. You can redistribute it and/or modify it under |
1716 | +// the terms of the GNU General Public License (GPL), version 2. |
1717 | +// |
1718 | +// Based on previous work done by Arnaldo Carvalho de Melo <acme@redhat.com> |
1719 | + |
1720 | +%{ |
1721 | +#include <linux/skbuff.h> |
1722 | +#ifndef NIPQUAD |
1723 | +#define NIPQUAD(addr) \ |
1724 | + ((unsigned char *)&addr)[0], \ |
1725 | + ((unsigned char *)&addr)[1], \ |
1726 | + ((unsigned char *)&addr)[2], \ |
1727 | + ((unsigned char *)&addr)[3] |
1728 | +#endif |
1729 | +#ifndef NIPQUAD_FMT |
1730 | +#define NIPQUAD_FMT "%u.%u.%u.%u" |
1731 | +#endif |
1732 | +%} |
1733 | + |
1734 | +/** |
1735 | + * sfunction ip_ntop - returns a string representation from an integer IP number |
1736 | + * @addr: the ip represented as an integer |
1737 | + */ |
1738 | +function ip_ntop:string (addr:long) |
1739 | +%{ |
1740 | + __be32 ip; |
1741 | + |
1742 | + ip = THIS->addr; |
1743 | + snprintf(THIS->__retvalue, MAXSTRINGLEN, NIPQUAD_FMT, NIPQUAD(ip)); |
1744 | +%} |
1745 | + |
1746 | +/* return the source IP address for a given sock */ |
1747 | +function __ip_sock_saddr:long (sock:long) |
1748 | +{ |
1749 | + return (@defined(@cast(sock, "inet_sock")->inet_saddr) |
1750 | + ? @cast(sock, "inet_sock")->inet_saddr # kernel >= 2.6.33 |
1751 | + : (@defined(@cast(sock, "inet_sock")->saddr) |
1752 | + ? @cast(sock, "inet_sock", "kernel")->saddr # kernel >= 2.6.11 |
1753 | + : @cast(sock, "inet_sock", "kernel<net/ip.h>")->inet->saddr)) |
1754 | +} |
1755 | + |
1756 | +/* return the destination IP address for a given sock */ |
1757 | +function __ip_sock_daddr:long (sock:long) |
1758 | +{ |
1759 | + return (@defined(@cast(sock, "inet_sock")->inet_daddr) |
1760 | + ? @cast(sock, "inet_sock")->inet_daddr # kernel >= 2.6.33 |
1761 | + : (@defined(@cast(sock, "inet_sock")->daddr) |
1762 | + ? @cast(sock, "inet_sock", "kernel")->daddr # kernel >= 2.6.11 |
1763 | + : @cast(sock, "inet_sock", "kernel<net/ip.h>")->inet->daddr)) |
1764 | +} |
1765 | + |
1766 | +/* Get the IP header from a sk_buff struct */ |
1767 | +function __get_skb_iphdr:long(skb:long) |
1768 | +%( kernel_v < "2.6.21" %? |
1769 | +{ |
1770 | + iphdr = @cast(skb, "sk_buff")->nh->raw |
1771 | + return iphdr |
1772 | +} |
1773 | +%: |
1774 | +%{ /* pure */ |
1775 | + struct sk_buff *skb; |
1776 | + skb = (struct sk_buff *)(long)THIS->skb; |
1777 | + /* as done by skb_network_header() */ |
1778 | + #ifdef NET_SKBUFF_DATA_USES_OFFSET |
1779 | + THIS->__retvalue = (long)(kread(&(skb->head)) + kread(&(skb->network_header))); |
1780 | + #else |
1781 | + THIS->__retvalue = (long)kread(&(skb->network_header)); |
1782 | + #endif |
1783 | + CATCH_DEREF_FAULT(); |
1784 | +%} |
1785 | +%) |
1786 | + |
1787 | +/* return the source next layer protocol for a given sk_buff structure */ |
1788 | +function __ip_skb_proto:long (iphdr) |
1789 | +{ |
1790 | + return @cast(iphdr, "iphdr")->protocol |
1791 | +} |
1792 | + |
1793 | +/* return the source IP address for a given sk_buff structure */ |
1794 | +function __ip_skb_saddr:long (iphdr) |
1795 | +{ |
1796 | + return @cast(iphdr, "iphdr")->saddr |
1797 | +} |
1798 | + |
1799 | +/* return the destination IP address for a given skb */ |
1800 | +function __ip_skb_daddr:long (iphdr) |
1801 | +{ |
1802 | + return @cast(iphdr, "iphdr")->daddr |
1803 | +} |
1804 | |
1805 | === added directory '.pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch' |
1806 | === added directory '.pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset' |
1807 | === added file '.pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/memory.stp' |
1808 | --- .pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/memory.stp 1970-01-01 00:00:00 +0000 |
1809 | +++ .pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/memory.stp 2011-03-22 12:11:00 +0000 |
1810 | @@ -0,0 +1,635 @@ |
1811 | +// memory/vm related tapset |
1812 | +// Copyright (C) 2005, 2006 IBM Corp. |
1813 | +// Copyright (C) 2006 Intel Corporation. |
1814 | +// Copyright (C) 2010 Red Hat Inc. |
1815 | +// |
1816 | +// This file is part of systemtap, and is free software. You can |
1817 | +// redistribute it and/or modify it under the terms of the GNU General |
1818 | +// Public License (GPL); either version 2, or (at your option) any |
1819 | +// later version. |
1820 | +// <tapsetdescription> |
1821 | +// This family of probe points is used to probe memory-related events. |
1822 | +// </tapsetdescription> |
1823 | +%{ |
1824 | +#include <linux/mm.h> |
1825 | +%} |
1826 | + |
1827 | +global VM_FAULT_OOM=0, VM_FAULT_SIGBUS=1, VM_FAULT_MINOR=2, VM_FAULT_MAJOR=3 |
1828 | +global VM_FAULT_NOPAGE=4, VM_FAULT_LOCKED=5, VM_FAULT_ERROR=6 |
1829 | +global FAULT_FLAG_WRITE=1 |
1830 | + |
1831 | +/** |
1832 | + * sfunction vm_fault_contains - Test return value for page fault reason |
1833 | + * @value: The fault_type returned by vm.page_fault.return |
1834 | + * @test: The type of fault to test for (VM_FAULT_OOM or similar) |
1835 | + */ |
1836 | +function vm_fault_contains:long (value:long, test:long) |
1837 | +%{ |
1838 | + int res; |
1839 | + switch (THIS->test){ |
1840 | + case 0: res = THIS->value & VM_FAULT_OOM; break; |
1841 | + case 1: res = THIS->value & VM_FAULT_SIGBUS; break; |
1842 | +#if defined(VM_FAULT_MINOR) && VM_FAULT_MINOR != 0 |
1843 | + case 2: /* VM_FAULT_MINOR infered by that flags off */ |
1844 | + res = !((VM_FAULT_OOM | VM_FAULT_SIGBUS | VM_FAULT_MAJOR) & |
1845 | + THIS->value); |
1846 | + break; |
1847 | +#else |
1848 | + case 2: res = THIS->value == VM_FAULT_MINOR; break; |
1849 | +#endif |
1850 | + case 3: res = THIS->value & VM_FAULT_MAJOR; break; |
1851 | +#ifdef VM_FAULT_NOPAGE |
1852 | + case 4: res = THIS->value & VM_FAULT_NOPAGE; break; |
1853 | +#endif |
1854 | +#ifdef VM_FAULT_LOCKED |
1855 | + case 5: res = THIS->value & VM_FAULT_LOCKED; break; |
1856 | +#endif |
1857 | +#ifdef VM_FAULT_ERROR |
1858 | + case 6: res = THIS->value & VM_FAULT_ERROR; break; |
1859 | +#endif |
1860 | + default: res = 0; break; |
1861 | + } |
1862 | + THIS->__retvalue = (res != 0); |
1863 | + return; |
1864 | +%} |
1865 | + |
1866 | +/** |
1867 | + * probe vm.pagefault - Records that a page fault occurred. |
1868 | + * @name: Name of the probe point |
1869 | + * @address: The address of the faulting memory access; i.e. the address that caused the page fault. |
1870 | + * @write_access: Indicates whether this was a write or read access; 1 indicates a write, |
1871 | + * while 0 indicates a read. |
1872 | + * |
1873 | + * Context: The process which triggered the fault |
1874 | + */ |
1875 | +probe vm.pagefault = kernel.function("__handle_mm_fault@mm/memory.c") ?, |
1876 | + kernel.function("handle_mm_fault@mm/memory.c") ? |
1877 | +{ |
1878 | + name = "pagefault" |
1879 | + write_access = (@defined($flags) |
1880 | + ? $flags & FAULT_FLAG_WRITE : $write_access) |
1881 | + address = $address |
1882 | +} |
1883 | + |
1884 | +/** |
1885 | + * probe vm.pagefault.return - Indicates what type of fault occurred. |
1886 | + * @name: Name of the probe point |
1887 | + * @fault_type: Returns either |
1888 | + * 0 (VM_FAULT_OOM) for out of memory faults, |
1889 | + * 2 (VM_FAULT_MINOR) for minor faults, 3 (VM_FAULT_MAJOR) for |
1890 | + * major faults, or 1 (VM_FAULT_SIGBUS) if the fault was neither OOM, minor fault, |
1891 | + * nor major fault. |
1892 | + */ |
1893 | +probe vm.pagefault.return = |
1894 | + kernel.function("__handle_mm_fault@mm/memory.c").return ?, |
1895 | + kernel.function("handle_mm_fault@mm/memory.c").return ? |
1896 | +{ |
1897 | + name = "pagefault" |
1898 | + fault_type = $return |
1899 | +} |
1900 | + |
1901 | +/** |
1902 | + * sfunction addr_to_node - Returns which node a given address belongs to within a NUMA system. |
1903 | + * |
1904 | + * General Syntax: addr_to_node:long(addr:long) |
1905 | + * |
1906 | + * @addr: The address of the faulting memory access. |
1907 | + * |
1908 | + * Description: This function accepts an address, and returns the |
1909 | + * node that the given address belongs to in a NUMA system. |
1910 | + */ |
1911 | +function addr_to_node:long(addr:long) %{ /* pure */ |
1912 | + int pfn = __pa(THIS->addr) >> PAGE_SHIFT; |
1913 | + int nid; |
1914 | +#ifdef for_each_online_node |
1915 | + for_each_online_node(nid) |
1916 | +#else |
1917 | + for (nid=0; nid<MAX_NUMNODES; nid++) /* if (node_online(nid)) */ |
1918 | +#endif |
1919 | + if ( NODE_DATA(nid)->node_start_pfn <= pfn && |
1920 | + pfn < (NODE_DATA(nid)->node_start_pfn + |
1921 | + NODE_DATA(nid)->node_spanned_pages) ) |
1922 | + { |
1923 | + THIS->__retvalue = nid; |
1924 | + break; |
1925 | + } |
1926 | +%} |
1927 | + |
1928 | +// Return whether a page to be copied is a zero page. |
1929 | +function _IS_ZERO_PAGE:long(from:long, vaddr:long) %{ /* pure */ |
1930 | + THIS->__retvalue = (THIS->from == (long) ZERO_PAGE(THIS->vaddr)); |
1931 | +%} |
1932 | + |
1933 | + |
1934 | +/** |
1935 | + * probe vm.write_shared - Attempts at writing to a shared page. |
1936 | + * @name: Name of the probe point |
1937 | + * @address: The address of the shared write. |
1938 | + * |
1939 | + * Context: |
1940 | + * The context is the process attempting the write. |
1941 | + * |
1942 | + * Fires when a process attempts to write to a shared page. |
1943 | + * If a copy is necessary, this will be followed by a |
1944 | + * vm.write_shared_copy. |
1945 | + */ |
1946 | +probe vm.write_shared = kernel.function("do_wp_page") { |
1947 | + name = "write_shared" |
1948 | + address = $address |
1949 | +} |
1950 | + |
1951 | +/** |
1952 | + * probe vm.write_shared_copy - Page copy for shared page write. |
1953 | + * @name: Name of the probe point |
1954 | + * @address: The address of the shared write. |
1955 | + * @zero: Boolean indicating whether it is a zero page |
1956 | + * (can do a clear instead of a copy). |
1957 | + * |
1958 | + * Context: |
1959 | + * The process attempting the write. |
1960 | + * |
1961 | + * Fires when a write to a shared page requires a page copy. This is |
1962 | + * always preceded by a vm.shared_write. |
1963 | + */ |
1964 | +probe vm.write_shared_copy = kernel.function("copy_cow_page") ? |
1965 | +{ |
1966 | + name = "write_shared_copy" |
1967 | + address = $address |
1968 | + zero = _IS_ZERO_PAGE($from, $address); |
1969 | +} |
1970 | + |
1971 | + |
1972 | +/** |
1973 | + * probe vm.mmap - Fires when an mmap is requested. |
1974 | + * @name: Name of the probe point |
1975 | + * @address: The requested address |
1976 | + * @length: The length of the memory segment |
1977 | + * |
1978 | + * Context: |
1979 | + * The process calling mmap. |
1980 | + */ |
1981 | +probe vm.mmap = kernel.function("do_mmap"), kernel.function("do_mmap2") ? |
1982 | +{ |
1983 | + name = "mmap" |
1984 | + address = $addr |
1985 | + length = $len |
1986 | +} |
1987 | + |
1988 | + |
1989 | +/** |
1990 | + * probe vm.munmap - Fires when an munmap is requested. |
1991 | + * @name: Name of the probe point |
1992 | + * @address: The requested address |
1993 | + * @length: The length of the memory segment |
1994 | + * |
1995 | + * Context: |
1996 | + * The process calling munmap. |
1997 | + */ |
1998 | +probe vm.munmap = kernel.function("do_munmap") { |
1999 | + name = "munmap" |
2000 | + address = $start |
2001 | + length = $len |
2002 | +} |
2003 | + |
2004 | +/** |
2005 | + * probe vm.brk - Fires when a brk is requested (i.e. the heap will be resized). |
2006 | + * @name: Name of the probe point |
2007 | + * @address: The requested address |
2008 | + * @length: The length of the memory segment |
2009 | + * |
2010 | + * Context: |
2011 | + * The process calling brk. |
2012 | + */ |
2013 | +probe vm.brk = kernel.function("do_brk") { |
2014 | + name = "brk" |
2015 | + address = $addr |
2016 | + length = $len |
2017 | +} |
2018 | + |
2019 | +/** |
2020 | + * probe vm.oom_kill - Fires when a thread is selected for termination by the OOM killer. |
2021 | + * @name: Name of the probe point |
2022 | + * @task: The task being killed |
2023 | + * |
2024 | + * Context: |
2025 | + * The process that tried to consume excessive memory, and thus |
2026 | + * triggered the OOM. |
2027 | + */ |
2028 | +probe vm.oom_kill = kernel.function("__oom_kill_task") |
2029 | +{ |
2030 | + name = "oom_kill" |
2031 | + task = $p |
2032 | +} |
2033 | + |
2034 | +function GFP_KERNEL:long() |
2035 | +%{ /* pure */ /* unprivileged */ |
2036 | + THIS->__retvalue = GFP_KERNEL; |
2037 | +%} |
2038 | + |
2039 | +function __gfp_flag_str:string(gfp_flag:long) |
2040 | +%{ |
2041 | + long gfp_flag = THIS->gfp_flag; |
2042 | + THIS->__retvalue[0] = '\0'; |
2043 | + |
2044 | +/* Older kernels < 2.6.32 didn't have some of these GFP defines yet. */ |
2045 | +#ifndef __GFP_DMA32 |
2046 | +#define __GFP_DMA32 ((__force gfp_t)0x04u) |
2047 | +#endif |
2048 | +#ifndef GFP_DMA32 |
2049 | +#define GFP_DMA32 __GFP_DMA32 |
2050 | +#endif |
2051 | + |
2052 | +#ifndef __GFP_MOVABLE |
2053 | +#define __GFP_MOVABLE ((__force gfp_t)0x08u) /* Page is movable */ |
2054 | +#endif |
2055 | + |
2056 | +#ifndef GFP_ZONEMASK |
2057 | +#define GFP_ZONEMASK (__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE) |
2058 | +#endif |
2059 | + |
2060 | +#ifndef __GFP_NOTRACK |
2061 | +#ifdef CONFIG_KMEMCHECK |
2062 | +#define __GFP_NOTRACK ((__force gfp_t)0x200000u) /* Don't track with kmemcheck */ |
2063 | +#else |
2064 | +#define __GFP_NOTRACK ((__force gfp_t)0) |
2065 | +#endif |
2066 | +#endif |
2067 | + |
2068 | +#ifndef __GFP_THISNODE |
2069 | +#define __GFP_THISNODE ((__force gfp_t)0x40000u) |
2070 | +#endif |
2071 | + |
2072 | +#ifndef __GFP_RECLAIMABLE |
2073 | +#define __GFP_RECLAIMABLE ((__force gfp_t)0x80000u) |
2074 | +#endif |
2075 | + |
2076 | +#ifndef __GFP_ZERO |
2077 | +#define __GFP_ZERO ((__force gfp_t)0x8000u) |
2078 | +#endif |
2079 | + |
2080 | +#ifndef __GFP_NOMEMALLOC |
2081 | +#define __GFP_NOMEMALLOC ((__force gfp_t)0x10000u) |
2082 | +#endif |
2083 | + |
2084 | +#ifndef __GFP_HARDWALL |
2085 | +#define __GFP_HARDWALL ((__force gfp_t)0x20000u) |
2086 | +#endif |
2087 | + |
2088 | +#ifndef GFP_TEMPORARY |
2089 | +#define GFP_TEMPORARY (__GFP_WAIT | __GFP_IO | __GFP_FS | \ |
2090 | + __GFP_RECLAIMABLE) |
2091 | +#endif |
2092 | + |
2093 | +#ifndef GFP_HIGHUSER_MOVABLE |
2094 | +#define GFP_HIGHUSER_MOVABLE (__GFP_WAIT | __GFP_IO | __GFP_FS | \ |
2095 | + __GFP_HARDWALL | __GFP_HIGHMEM | \ |
2096 | + __GFP_MOVABLE) |
2097 | +#endif |
2098 | + |
2099 | +#ifndef GFP_THISNODE |
2100 | +#ifdef CONFIG_NUMA |
2101 | +#define GFP_THISNODE (__GFP_THISNODE | __GFP_NOWARN | __GFP_NORETRY) |
2102 | +#else |
2103 | +#define GFP_THISNODE ((__force gfp_t)0) |
2104 | +#endif |
2105 | +#endif |
2106 | + |
2107 | +/* Macro for GFP Bitmasks. */ |
2108 | +/* The resulted GFP_FLAGS may be either single or concatenation of the multiple bitmasks. */ |
2109 | + |
2110 | + |
2111 | +#define __GFP_BITMASKS(FLAG) if(gfp_flag & FLAG) { if(THIS->__retvalue[0] != '\0') \ |
2112 | + strlcat(THIS->__retvalue, " | "#FLAG, MAXSTRINGLEN); \ |
2113 | + else strlcat(THIS->__retvalue, #FLAG, MAXSTRINGLEN); } |
2114 | + |
2115 | + |
2116 | +/* Macro for Composite Flags. */ |
2117 | +/* Each Composite GFP_FLAG is the combination of multiple bitmasks. */ |
2118 | + |
2119 | + |
2120 | +#define __GFP_COMPOSITE_FLAG(FLAG) if(gfp_flag == FLAG) { \ |
2121 | + strlcat(THIS->__retvalue, #FLAG, MAXSTRINGLEN); return; } |
2122 | + |
2123 | + |
2124 | +/* Composite GFP FLAGS of the BitMasks. */ |
2125 | + |
2126 | + __GFP_COMPOSITE_FLAG(GFP_ZONEMASK) |
2127 | + __GFP_COMPOSITE_FLAG(GFP_ATOMIC) |
2128 | + __GFP_COMPOSITE_FLAG(GFP_NOIO) |
2129 | + __GFP_COMPOSITE_FLAG(GFP_NOFS) |
2130 | + __GFP_COMPOSITE_FLAG(GFP_KERNEL) |
2131 | + __GFP_COMPOSITE_FLAG(GFP_TEMPORARY) |
2132 | + __GFP_COMPOSITE_FLAG(GFP_USER) |
2133 | + __GFP_COMPOSITE_FLAG(GFP_HIGHUSER) |
2134 | + __GFP_COMPOSITE_FLAG(GFP_HIGHUSER_MOVABLE) |
2135 | + __GFP_COMPOSITE_FLAG(GFP_THISNODE) |
2136 | + __GFP_COMPOSITE_FLAG(GFP_DMA) |
2137 | + __GFP_COMPOSITE_FLAG(GFP_DMA32) |
2138 | + |
2139 | +/* GFP BitMasks */ |
2140 | + |
2141 | + __GFP_BITMASKS(__GFP_DMA) |
2142 | + __GFP_BITMASKS(__GFP_HIGHMEM) |
2143 | + __GFP_BITMASKS(__GFP_MOVABLE) |
2144 | + __GFP_BITMASKS(__GFP_WAIT) |
2145 | + __GFP_BITMASKS(__GFP_HIGH) |
2146 | + __GFP_BITMASKS(__GFP_IO) |
2147 | + __GFP_BITMASKS(__GFP_FS) |
2148 | + __GFP_BITMASKS(__GFP_COLD) |
2149 | + __GFP_BITMASKS(__GFP_NOWARN) |
2150 | + __GFP_BITMASKS(__GFP_REPEAT) |
2151 | + __GFP_BITMASKS(__GFP_NOFAIL) |
2152 | + __GFP_BITMASKS(__GFP_COMP) |
2153 | + __GFP_BITMASKS(__GFP_ZERO) |
2154 | + __GFP_BITMASKS(__GFP_NOMEMALLOC) |
2155 | + __GFP_BITMASKS(__GFP_HARDWALL) |
2156 | + __GFP_BITMASKS(__GFP_THISNODE) |
2157 | + __GFP_BITMASKS(__GFP_RECLAIMABLE) |
2158 | + __GFP_BITMASKS(__GFP_NOTRACK) |
2159 | + |
2160 | + |
2161 | +#undef __GFP_BITMASKS |
2162 | +#undef __GFP_COMPOSITE_FLAG |
2163 | +%} |
2164 | + |
2165 | +/* The Formal Parameters will be displayed if available, otherwise \ |
2166 | + "0" or "unknown" will be displayed */ |
2167 | + |
2168 | +probe __vm.kmalloc.tp = kernel.trace("kmalloc") |
2169 | +{ |
2170 | + call_site = $call_site |
2171 | + caller_function = symname(call_site) |
2172 | + bytes_req = $bytes_req |
2173 | + bytes_alloc = $bytes_alloc |
2174 | + gfp_flags = $gfp_flags |
2175 | + gfp_flag_name = __gfp_flag_str($gfp_flags) |
2176 | + ptr = $ptr |
2177 | +} |
2178 | + |
2179 | +/* |
2180 | + * It is unsafe to invoke __builtin_return_address() presently (to get |
2181 | + * call_site for kprobe based probes) and that it can be improved |
2182 | + * later when fix for bugs bz#6961 and bz#6580 is available. |
2183 | + */ |
2184 | + |
2185 | +probe __vm.kmalloc.kp = kernel.function("kmem_cache_alloc_notrace").return !, |
2186 | + kernel.function("kmem_cache_alloc").return |
2187 | +{ |
2188 | + call_site = 0 |
2189 | + caller_function = "unknown" |
2190 | + // Note that 'bytes_req' could be wrong. By the time |
2191 | + // kmem_cache_alloc* gets called the requested size could have |
2192 | + // rounded up to the nearest cache alloc size. |
2193 | + if (@defined($s)) { |
2194 | + bytes_req = $s->size |
2195 | + bytes_alloc = $s->size |
2196 | + } |
2197 | + else if (@defined($cachep->buffer_size)) { |
2198 | + bytes_req = $cachep->buffer_size |
2199 | + bytes_alloc = $cachep->buffer_size |
2200 | + } |
2201 | + else { |
2202 | + bytes_req = $cachep->objsize |
2203 | + bytes_alloc = $cachep->objsize |
2204 | + } |
2205 | + if (@defined($gfpflags)) { |
2206 | + gfp_flags = $gfpflags |
2207 | + gfp_flag_name = __gfp_flag_str($gfpflags) |
2208 | + } |
2209 | + else { |
2210 | + gfp_flags = $flags |
2211 | + gfp_flag_name = __gfp_flag_str($flags) |
2212 | + } |
2213 | + ptr = $return |
2214 | +} |
2215 | + |
2216 | +/** |
2217 | + * probe vm.kmalloc - Fires when kmalloc is requested. |
2218 | + * @name: Name of the probe point |
2219 | + * @call_site: Address of the kmemory function. |
2220 | + * @caller_function: Name of the caller function. |
2221 | + * @bytes_req: Requested Bytes |
2222 | + * @bytes_alloc: Allocated Bytes |
2223 | + * @gfp_flags: type of kmemory to allocate |
2224 | + * @gfp_flag_name: type of kmemory to allocate (in String format) |
2225 | + * @ptr: Pointer to the kmemory allocated |
2226 | + */ |
2227 | +probe vm.kmalloc = __vm.kmalloc.tp !, __vm.kmalloc.kp |
2228 | +{ |
2229 | + name = "kmalloc" |
2230 | +} |
2231 | + |
2232 | + |
2233 | +probe __vm.kmem_cache_alloc.tp = kernel.trace("kmem_cache_alloc") |
2234 | +{ |
2235 | + call_site = $call_site |
2236 | + caller_function = symname(call_site) |
2237 | + bytes_req = $bytes_req |
2238 | + bytes_alloc = $bytes_alloc |
2239 | + gfp_flags = $gfp_flags |
2240 | + gfp_flag_name = __gfp_flag_str($gfp_flags) |
2241 | + ptr = $ptr |
2242 | +} |
2243 | + |
2244 | +probe __vm.kmem_cache_alloc.kp = kernel.function("kmem_cache_alloc").return |
2245 | +{ |
2246 | + call_site = 0 |
2247 | + caller_function = "unknown" |
2248 | + // Note that 'bytes_req' could be wrong. By the time |
2249 | + // kmem_cache_alloc* gets called the requested size could have |
2250 | + // rounded up to the nearest cache alloc size. |
2251 | + if (@defined($s)) { |
2252 | + bytes_req = $s->size |
2253 | + bytes_alloc = $s->size |
2254 | + } |
2255 | + else if (@defined($cachep->buffer_size)) { |
2256 | + bytes_req = $cachep->buffer_size |
2257 | + bytes_alloc = $cachep->buffer_size |
2258 | + } |
2259 | + else { |
2260 | + bytes_req = $cachep->objsize |
2261 | + bytes_alloc = $cachep->objsize |
2262 | + } |
2263 | + if (@defined($gfpflags)) { |
2264 | + gfp_flags = $gfpflags |
2265 | + gfp_flag_name = __gfp_flag_str($gfpflags) |
2266 | + } |
2267 | + else { |
2268 | + gfp_flags = $flags |
2269 | + gfp_flag_name = __gfp_flag_str($flags) |
2270 | + } |
2271 | + ptr = $return |
2272 | +} |
2273 | + |
2274 | +/** |
2275 | + * probe vm.kmem_cache_alloc - Fires when \ |
2276 | + * kmem_cache_alloc is requested. |
2277 | + * @name: Name of the probe point |
2278 | + * @call_site: Address of the function calling this kmemory function. |
2279 | + * @caller_function: Name of the caller function. |
2280 | + * @bytes_req: Requested Bytes |
2281 | + * @bytes_alloc: Allocated Bytes |
2282 | + * @gfp_flags: type of kmemory to allocate |
2283 | + * @gfp_flag_name: Type of kmemory to allocate(in string format) |
2284 | + * @ptr: Pointer to the kmemory allocated |
2285 | + */ |
2286 | + |
2287 | +probe vm.kmem_cache_alloc = __vm.kmem_cache_alloc.tp !, |
2288 | + __vm.kmem_cache_alloc.kp |
2289 | +{ |
2290 | + name = "kmem_cache_alloc" |
2291 | +} |
2292 | + |
2293 | +probe __vm.kmalloc_node.tp = kernel.trace("kmalloc_node") ? |
2294 | +{ |
2295 | + call_site = $call_site |
2296 | + caller_function = symname(call_site) |
2297 | + bytes_req = $bytes_req |
2298 | + bytes_alloc = $bytes_alloc |
2299 | + gfp_flags = $gfp_flags |
2300 | + gfp_flag_name = __gfp_flag_str($gfp_flags) |
2301 | + ptr = $ptr |
2302 | +} |
2303 | + |
2304 | +probe __vm.kmalloc_node.kp = kernel.function("kmalloc_node").return ? |
2305 | +{ |
2306 | + call_site = 0 |
2307 | + caller_function = "unknown" |
2308 | + bytes_req = $size |
2309 | + bytes_alloc = bytes_req // pretend they are always the same |
2310 | + |
2311 | + # Unfortunately, on i686 f11 (2.6.29.4-167.fc11.i686.PAE), we |
2312 | + # can't see the '$flags' argument (even though we can see the |
2313 | + # '$size' argument above). Note that we can see the '$flags' |
2314 | + # argument on x86_64 f11 (2.6.29.4-167.fc11.x86_64). So, the |
2315 | + # best we can do here is just use 0 when $flags isn't defined. |
2316 | + gfp_flags = (@defined($flags) ? $flags : 0) |
2317 | + gfp_flag_name = __gfp_flag_str(@defined($flags) ? $flags : 0) |
2318 | + |
2319 | + ptr = $return |
2320 | +} |
2321 | + |
2322 | +/** |
2323 | + * probe vm.kmalloc_node - Fires when kmalloc_node is requested. |
2324 | + * @name: Name of the probe point |
2325 | + * @call_site: Address of the function caling this kmemory function. |
2326 | + * @caller_function: Name of the caller function. |
2327 | + * @bytes_req: Requested Bytes |
2328 | + * @bytes_alloc: Allocated Bytes |
2329 | + * @gfp_flags: type of kmemory to allocate |
2330 | + * @gfp_flag_name: Type of kmemory to allocate(in string format) |
2331 | + * @ptr: Pointer to the kmemory allocated |
2332 | + */ |
2333 | +probe vm.kmalloc_node = __vm.kmalloc_node.tp !, __vm.kmalloc_node.kp ? |
2334 | +{ |
2335 | + name = "kmalloc_node" |
2336 | +} |
2337 | + |
2338 | +probe __vm.kmem_cache_alloc_node.tp = kernel.trace("kmem_cache_alloc_node") ? |
2339 | +{ |
2340 | + call_site = $call_site |
2341 | + caller_function = symname(call_site) |
2342 | + bytes_req = $bytes_req |
2343 | + bytes_alloc = $bytes_alloc |
2344 | + gfp_flags = $gfp_flags |
2345 | + gfp_flag_name = __gfp_flag_str($gfp_flags) |
2346 | + ptr = $ptr |
2347 | +} |
2348 | + |
2349 | +probe __vm.kmem_cache_alloc_node.kp = |
2350 | + kernel.function("kmem_cache_alloc_node").return ? |
2351 | +{ |
2352 | + call_site = 0 |
2353 | + caller_function = "unknown" |
2354 | + // Note that 'bytes_req' could be wrong. By the time |
2355 | + // kmem_cache_alloc* gets called the requested size could have |
2356 | + // rounded up to the nearest cache alloc size. |
2357 | + if (@defined($s)) { |
2358 | + bytes_req = $s->size |
2359 | + bytes_alloc = $s->size |
2360 | + } |
2361 | + else if (@defined($cachep->buffer_size)) { |
2362 | + bytes_req = $cachep->buffer_size |
2363 | + bytes_alloc = $cachep->buffer_size |
2364 | + } |
2365 | + else { |
2366 | + bytes_req = $cachep->objsize |
2367 | + bytes_alloc = $cachep->objsize |
2368 | + } |
2369 | + |
2370 | + // kmem_cache_alloc_node() doesn't get a flags argument. But, |
2371 | + // internally it uses GFP_KERNEL(). |
2372 | + gfp_flags = GFP_KERNEL() |
2373 | + gfp_flag_name = __gfp_flag_str(gfp_flags) |
2374 | + ptr = $return |
2375 | +} |
2376 | + |
2377 | +/** |
2378 | + * probe vm.kmem_cache_alloc_node - Fires when \ |
2379 | + * kmem_cache_alloc_node is requested. |
2380 | + * @name: Name of the probe point |
2381 | + * @call_site: Address of the function calling this kmemory function. |
2382 | + * @caller_function: Name of the caller function. |
2383 | + * @bytes_req: Requested Bytes |
2384 | + * @bytes_alloc: Allocated Bytes |
2385 | + * @gfp_flags: type of kmemory to allocate |
2386 | + * @gfp_flag_name: Type of kmemory to allocate(in string format) |
2387 | + * @ptr: Pointer to the kmemory allocated |
2388 | + */ |
2389 | +probe vm.kmem_cache_alloc_node = __vm.kmem_cache_alloc_node.tp !, |
2390 | + __vm.kmem_cache_alloc_node.kp ? |
2391 | +{ |
2392 | + name = "kmem_cache_alloc_node" |
2393 | +} |
2394 | + |
2395 | +probe __vm.kfree.tp = kernel.trace("kfree") |
2396 | +{ |
2397 | + call_site = $call_site |
2398 | + caller_function = symname(call_site) |
2399 | + ptr = $ptr |
2400 | +} |
2401 | + |
2402 | +probe __vm.kfree.kp = kernel.function("kfree").return |
2403 | +{ |
2404 | + call_site = 0 |
2405 | + caller_function = "unknown" |
2406 | + ptr = (@defined($x) ? $x : $objp) |
2407 | +} |
2408 | + |
2409 | +/** |
2410 | + * probe vm.kfree - Fires when kfree is requested. |
2411 | + * @name: Name of the probe point |
2412 | + * @call_site: Address of the function calling this kmemory function. |
2413 | + * @caller_function: Name of the caller function. |
2414 | + * @ptr: Pointer to the kmemory allocated which is returned by kmalloc |
2415 | + */ |
2416 | +probe vm.kfree = __vm.kfree.tp !, __vm.kfree.kp |
2417 | +{ |
2418 | + name = "kfree" |
2419 | +} |
2420 | + |
2421 | +probe __vm.kmem_cache_free.tp = kernel.trace("kmem_cache_free") |
2422 | +{ |
2423 | + call_site = $call_site |
2424 | + caller_function = symname(call_site) |
2425 | + ptr = $ptr |
2426 | +} |
2427 | +probe __vm.kmem_cache_free.kp = kernel.function("kmem_cache_free").return |
2428 | +{ |
2429 | + call_site = 0 |
2430 | + caller_function = "unknown" |
2431 | + ptr = (@defined($x) ? $x : $objp) |
2432 | +} |
2433 | + |
2434 | +/** |
2435 | + * probe vm.kmem_cache_free - Fires when \ |
2436 | + * kmem_cache_free is requested. |
2437 | + * @name: Name of the probe point |
2438 | + * @call_site: Address of the function calling this kmemory function. |
2439 | + * @caller_function: Name of the caller function. |
2440 | + * @ptr: Pointer to the kmemory allocated which is returned by kmem_cache |
2441 | + */ |
2442 | +probe vm.kmem_cache_free = __vm.kmem_cache_free.tp !, __vm.kmem_cache_free.kp |
2443 | +{ |
2444 | + name = "kmem_cache_free" |
2445 | +} |
2446 | |
2447 | === added file '.pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/rpc.stp' |
2448 | --- .pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/rpc.stp 1970-01-01 00:00:00 +0000 |
2449 | +++ .pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/rpc.stp 2011-03-22 12:11:00 +0000 |
2450 | @@ -0,0 +1,1185 @@ |
2451 | +// rpc tapset |
2452 | +// Copyright (C) 2006 IBM Corp. |
2453 | +// Copyright (C) 2007 Bull S.A.S |
2454 | +// Copyright (C) 2008, 2010 Red Hat |
2455 | +// |
2456 | +// This file is part of systemtap, and is free software. You can |
2457 | +// redistribute it and/or modify it under the terms of the GNU General |
2458 | +// Public License (GPL); either version 2, or (at your option) any |
2459 | +// later version. |
2460 | + |
2461 | +%{ |
2462 | +// Includes everything needed for __rpc_prot_from_protocol(). |
2463 | +#include <linux/sunrpc/clnt.h> |
2464 | +%} |
2465 | + |
2466 | +probe sunrpc.entry = |
2467 | + sunrpc.clnt.entry, |
2468 | + sunrpc.svc.entry, |
2469 | + sunrpc.sched.entry |
2470 | +{} |
2471 | + |
2472 | +probe sunrpc.return = |
2473 | + sunrpc.clnt.return, |
2474 | + sunrpc.svc.return, |
2475 | + sunrpc.sched.return |
2476 | +{} |
2477 | + |
2478 | +/****************************************************************** |
2479 | + * Probe points on RPC client functions * |
2480 | + ******************************************************************/ |
2481 | + |
2482 | +probe sunrpc.clnt.entry = |
2483 | + sunrpc.clnt.create_client, |
2484 | + sunrpc.clnt.clone_client, |
2485 | + sunrpc.clnt.bind_new_program, |
2486 | + sunrpc.clnt.shutdown_client, |
2487 | + sunrpc.clnt.call_sync, |
2488 | + sunrpc.clnt.call_async, |
2489 | + sunrpc.clnt.restart_call |
2490 | +{} |
2491 | + |
2492 | +probe sunrpc.clnt.return = |
2493 | + sunrpc.clnt.create_client.return, |
2494 | + sunrpc.clnt.clone_client.return, |
2495 | + sunrpc.clnt.bind_new_program.return, |
2496 | + sunrpc.clnt.shutdown_client.return, |
2497 | + sunrpc.clnt.call_sync.return, |
2498 | + sunrpc.clnt.call_async.return, |
2499 | + sunrpc.clnt.restart_call.return |
2500 | +{} |
2501 | + |
2502 | +/* |
2503 | + * Fires when an RPC client is to be created |
2504 | + * |
2505 | + * kernels > 2.6.18 |
2506 | + * |
2507 | + * struct rpc_clnt * |
2508 | + * rpc_create(struct rpc_create_args *args) |
2509 | + * The rpc_create() function is used to create an RPC client. It |
2510 | + * calculates some arguments (such as args->servername), then |
2511 | + * calls rpc_new_client(). We need the calculated arguments, so |
2512 | + * we'll probe rpc_new_client(). But, see discussion of |
2513 | + * sunrpc.clnt.create_client.return below. |
2514 | + * |
2515 | + * static struct rpc_clnt * |
2516 | + * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt) |
2517 | + * |
2518 | + * kernels <= 2.6.18 |
2519 | + * |
2520 | + * static struct rpc_clnt * |
2521 | + * rpc_new_client(struct rpc_xprt *xprt, char *servname, |
2522 | + * struct rpc_program *program, u32 vers, |
2523 | + * rpc_authflavor_t flavor) |
2524 | + * |
2525 | + * struct rpc_clnt * |
2526 | + * rpc_create_client(struct rpc_xprt *xprt, char *servname, |
2527 | + * struct rpc_program *info, u32 version, |
2528 | + * rpc_authflavor_t authflavor) |
2529 | + * |
2530 | + * @servername: the server machine name |
2531 | + * @progname: the RPC program name |
2532 | + * @prog: the RPC program number |
2533 | + * @vers: the RPC program version number |
2534 | + * @prot: the IP protocol number |
2535 | + * @port: the port number |
2536 | + * @authflavor: the authentication flavor |
2537 | + */ |
2538 | +probe sunrpc.clnt.create_client = |
2539 | + _sunrpc.clnt.create_client.rpc_new_client_inline !, |
2540 | + _sunrpc.clnt.create_client.rpc_new_client ?, |
2541 | + _sunrpc.clnt.create_client.rpc_create_client ? |
2542 | +{ |
2543 | + name = "sunrpc.clnt.create_client" |
2544 | + argstr = sprintf("%s %s %d %d %d %d %d", servername, progname, |
2545 | + prog, vers, prot, port, authflavor) |
2546 | +} |
2547 | + |
2548 | +/* |
2549 | + * Newer kernels (> 2.6.18) compiled with gcc less than version |
2550 | + * 4.4.3-16, tend to have debuginfo that doesn't include location |
2551 | + * information for inline function arguments. This is a problem, since |
2552 | + * we need the arguments to rpc_new_client(), which is inline. Since |
2553 | + * we can't get them for those kernels, we stash (and delete) the value |
2554 | + * of the 'args' parameter of rpc_create(). We then use this value |
2555 | + * when probing the inline version of rpc_new_client() (if we don't |
2556 | + * have the real arguments to that inline function). |
2557 | + */ |
2558 | + |
2559 | +global __rpc_create_args |
2560 | + |
2561 | +probe kernel.function("rpc_create") !, |
2562 | + module("sunrpc").function("rpc_create") ? |
2563 | +{ |
2564 | + __rpc_create_args[tid()] = $args |
2565 | +} |
2566 | + |
2567 | +probe kernel.function("rpc_create").return !, |
2568 | + module("sunrpc").function("rpc_create").return ? |
2569 | +{ |
2570 | + delete __rpc_create_args[tid()] |
2571 | +} |
2572 | + |
2573 | + |
2574 | +/* |
2575 | + * This function could be written in script language, but we'd need |
2576 | + * embedded-C functions for XPRT_TRANSPORT_{UDP,TCP,BC_TCP} and |
2577 | + * IPPROTO_{UDP,TCP}. So, do it all in embedded-C. |
2578 | + */ |
2579 | + |
2580 | +function __rpc_prot_from_protocol:long(protocol:long) |
2581 | +%{ |
2582 | + switch (THIS->protocol) { |
2583 | +#ifdef XPRT_TRANSPORT_BC |
2584 | + case XPRT_TRANSPORT_UDP: |
2585 | + THIS->__retvalue = IPPROTO_UDP; |
2586 | + break; |
2587 | + case XPRT_TRANSPORT_TCP: |
2588 | + case XPRT_TRANSPORT_BC_TCP: |
2589 | + THIS->__retvalue = IPPROTO_TCP; |
2590 | + break; |
2591 | +#endif |
2592 | + default: |
2593 | + THIS->__retvalue = -1; |
2594 | + break; |
2595 | + } |
2596 | +%} |
2597 | + |
2598 | +/* |
2599 | + * The probe for the inline version of "rpc_new_client" (kernels > |
2600 | + * 2.6.18) and the non-inline version of "rpc_new_client" (kernels <= |
2601 | + * 2.6.18) could be combined. However, the optimizer isn't smart |
2602 | + * enough to optimize away the '__rpc_create_args' global then. |
2603 | + */ |
2604 | + |
2605 | +probe _sunrpc.clnt.create_client.rpc_new_client_inline = |
2606 | + kernel.function("rpc_new_client").inline !, |
2607 | + module("sunrpc").function("rpc_new_client").inline |
2608 | +{ |
2609 | + if (@defined($args)) { # kernel > 2.6.18 (with good debuginfo) |
2610 | + servername = kernel_string($args->servername) |
2611 | + progname = kernel_string($args->program->name) |
2612 | + prog = $args->prognumber |
2613 | + vers = vers_from_prog($args->program, $args->version) |
2614 | + authflavor = $args->authflavor |
2615 | + |
2616 | + prot = $xprt->prot |
2617 | + port = (@defined($xprt->port) |
2618 | + ? $xprt->port : port_from_xprt($xprt)) |
2619 | + } |
2620 | + else { # kernel > 2.6.18 (with bad debuginfo) |
2621 | + args = __rpc_create_args[tid()] |
2622 | + servername = kernel_string(@cast(args, "rpc_create_args", "kernel:sunrpc")->servername) |
2623 | + progname = kernel_string(@cast(args, "rpc_create_args", "kernel:sunrpc")->program->name) |
2624 | + prog = @cast(args, "rpc_create_args", "kernel:sunrpc")->prognumber |
2625 | + vers = vers_from_prog(@cast(args, "rpc_create_args", "kernel:sunrpc")->program, @cast(args, "rpc_create_args", "kernel:sunrpc")->version) |
2626 | + authflavor = @cast(args, "rpc_create_args", "kernel:sunrpc")->authflavor |
2627 | + |
2628 | + prot = __rpc_prot_from_protocol(@cast(args, "rpc_create_args", "kernel:sunrpc")->protocol) |
2629 | + # Since we can't find $xprt, we can't know the port |
2630 | + port = -1 |
2631 | + } |
2632 | +} |
2633 | + |
2634 | +probe _sunrpc.clnt.create_client.rpc_new_client = |
2635 | + kernel.function("rpc_new_client").call !, |
2636 | + module("sunrpc").function("rpc_new_client").call |
2637 | +{ |
2638 | + # kernel <= 2.6.18 |
2639 | + servername = kernel_string($servname) |
2640 | + progname = kernel_string($program->name) |
2641 | + prog = $program->number |
2642 | + vers = vers = vers_from_prog($program, $vers) |
2643 | + authflavor = $flavor |
2644 | + |
2645 | + prot = $xprt->prot |
2646 | + port = (@defined($xprt->port) |
2647 | + ? $xprt->port : port_from_xprt($xprt)) |
2648 | +} |
2649 | + |
2650 | +probe _sunrpc.clnt.create_client.rpc_create_client = |
2651 | + kernel.function("rpc_create_client") !, |
2652 | + module("sunrpc").function("rpc_create_client") |
2653 | +{ |
2654 | + servername = kernel_string($servname) |
2655 | + if (@defined($info)) { |
2656 | + progname = kernel_string($info->name) |
2657 | + prog = $info->number |
2658 | + vers = vers_from_prog($info, $version) |
2659 | + authflavor = $authflavor |
2660 | + } |
2661 | + else { |
2662 | + progname = kernel_string($program->name) |
2663 | + prog = $program->number |
2664 | + vers = vers_from_prog($program, $vers) |
2665 | + authflavor = $flavor |
2666 | + } |
2667 | + |
2668 | + prot = $xprt->prot |
2669 | + port = (@defined($xprt->port) |
2670 | + ? $xprt->port : port_from_xprt($xprt)) |
2671 | +} |
2672 | + |
2673 | +/* |
2674 | + * On newer kernels, we want to probe the return of rpc_new_client() |
2675 | + * here. But because of problems with return probes on inline |
2676 | + * functions (PR 4413), we have to probe the return of rpc_create() |
2677 | + * instead. So, if we find the return of rpc_create() (the only |
2678 | + * caller of rpc_new_client()), we're done. |
2679 | + */ |
2680 | +probe sunrpc.clnt.create_client.return = |
2681 | + _sunrpc.clnt.create_client.return.rpc_create !, |
2682 | + _sunrpc.clnt.create_client.return.rpc_new_client ?, |
2683 | + _sunrpc.clnt.create_client.return.rpc_create_client ? |
2684 | +{ |
2685 | + name = "sunrpc.clnt.create_client.return" |
2686 | + retstr = returnstr(2) |
2687 | +} |
2688 | + |
2689 | +probe _sunrpc.clnt.create_client.return.rpc_create = |
2690 | + kernel.function("rpc_create").return !, |
2691 | + module("sunrpc").function("rpc_create").return |
2692 | +{ |
2693 | +} |
2694 | + |
2695 | +probe _sunrpc.clnt.create_client.return.rpc_new_client = |
2696 | + kernel.function("rpc_new_client").return !, |
2697 | + module("sunrpc").function("rpc_new_client").return |
2698 | +{ |
2699 | +} |
2700 | + |
2701 | +probe _sunrpc.clnt.create_client.return.rpc_create_client = |
2702 | + kernel.function("rpc_create_client").return !, |
2703 | + module("sunrpc").function("rpc_create_client").return |
2704 | +{ |
2705 | +} |
2706 | + |
2707 | +/* |
2708 | + * Fires when the RPC client structure is to be cloned |
2709 | + * |
2710 | + * struct rpc_clnt * rpc_clone_client(struct rpc_clnt *clnt) |
2711 | + * |
2712 | + * @servername: the server machine name |
2713 | + * @progname: the RPC program name |
2714 | + * @prog: the RPC program number |
2715 | + * @vers: the RPC program version number |
2716 | + * @prot: the IP protocol number |
2717 | + * @port: the port number |
2718 | + * @authflavor: the authentication flavor |
2719 | + */ |
2720 | +probe sunrpc.clnt.clone_client = kernel.function("rpc_clone_client") !, |
2721 | + module("sunrpc").function("rpc_clone_client") |
2722 | +{ |
2723 | + servername = kernel_string($clnt->cl_server) |
2724 | + progname = kernel_string($clnt->cl_protname) |
2725 | + prog = prog_from_clnt($clnt) |
2726 | + vers = vers_from_clnt($clnt) |
2727 | + prot = prot_from_clnt($clnt) |
2728 | + port = port_from_clnt($clnt) |
2729 | + authflavor = $clnt->cl_auth->au_flavor |
2730 | + |
2731 | + name = "sunrpc.clnt.clone_client" |
2732 | + argstr = sprintf("%s %s %d %d %d %d %d", servername, progname, |
2733 | + prog, vers, prot, port, authflavor) |
2734 | +} |
2735 | + |
2736 | +probe sunrpc.clnt.clone_client.return = |
2737 | + kernel.function("rpc_clone_client").return !, |
2738 | + module("sunrpc").function("rpc_clone_client").return |
2739 | +{ |
2740 | + name = "sunrpc.clnt.clone_client.return" |
2741 | + retstr = returnstr(2) |
2742 | +} |
2743 | + |
2744 | +/* |
2745 | + * Fires when an RPC client is to be shut down. |
2746 | + * |
2747 | + * int rpc_shutdown_client(struct rpc_clnt *clnt) |
2748 | + * |
2749 | + * @servername: the server machine name |
2750 | + * @progname: the RPC program name |
2751 | + * @prog: the RPC program number |
2752 | + * @vers: the RPC program version number |
2753 | + * @prot: the IP protocol number |
2754 | + * @port: the port number |
2755 | + * @authflavor: the authentication flavor |
2756 | + * |
2757 | + * @clones: the number of clones |
2758 | + * @tasks: the number of references |
2759 | + * |
2760 | + * @netreconn: the count of reconnections |
2761 | + * @rpccnt: the count of RPC calls |
2762 | + * @om_ops: the count of operations |
2763 | + * @om_ntrans: the count of RPC transmissions |
2764 | + * @om_bytes_sent: the count of bytes out |
2765 | + * @om_bytes_recv: the count of bytes in |
2766 | + * @om_queue: the jiffies queued for xmit |
2767 | + * @om_rtt: the RPC RTT jiffies |
2768 | + * @om_execute: the RPC execution jiffies |
2769 | + */ |
2770 | +probe sunrpc.clnt.shutdown_client = kernel.function("rpc_shutdown_client") !, |
2771 | + module("sunrpc").function("rpc_shutdown_client") |
2772 | +{ |
2773 | + servername = kernel_string($clnt->cl_server) |
2774 | + progname = kernel_string($clnt->cl_protname) |
2775 | + prog = prog_from_clnt($clnt) |
2776 | + vers = vers_from_clnt($clnt) |
2777 | + prot = prot_from_clnt($clnt) |
2778 | + port = port_from_clnt($clnt) |
2779 | + authflavor = $clnt->cl_auth->au_flavor |
2780 | + clones = clones_from_clnt($clnt) |
2781 | + tasks = tasks_from_clnt($clnt) |
2782 | + |
2783 | + /* per-program statistics */ |
2784 | + netreconn = $clnt->cl_stats->netreconn |
2785 | + rpccnt = $clnt->cl_stats->rpccnt |
2786 | + |
2787 | + /* per-client statistics */ |
2788 | + if (@defined($clnt->cl_metrics)) { |
2789 | + om_ops = $clnt->cl_metrics->om_ops |
2790 | + om_ntrans = $clnt->cl_metrics->om_ntrans |
2791 | + om_bytes_sent = $clnt->cl_metrics->om_bytes_sent |
2792 | + om_bytes_recv = $clnt->cl_metrics->om_bytes_recv |
2793 | + if (@defined($clnt->cl_metrics->om_queue->tv64)) { |
2794 | + om_queue = $clnt->cl_metrics->om_queue->tv64 |
2795 | + om_rtt = $clnt->cl_metrics->om_rtt->tv64 |
2796 | + om_execute = $clnt->cl_metrics->om_execute->tv64 |
2797 | + } |
2798 | + else |
2799 | + { |
2800 | + om_queue = $clnt->cl_metrics->om_queue |
2801 | + om_rtt = $clnt->cl_metrics->om_rtt |
2802 | + om_execute = $clnt->cl_metrics->om_execute |
2803 | + } |
2804 | + } |
2805 | + else { |
2806 | + om_ops = -1 |
2807 | + om_ntrans = -1 |
2808 | + om_bytes_sent = -1 |
2809 | + om_bytes_recv = -1 |
2810 | + om_queue = -1 |
2811 | + om_rtt = -1 |
2812 | + om_execute = -1 |
2813 | + } |
2814 | + |
2815 | + name = "sunrpc.clnt.shutdown_client" |
2816 | + argstr = sprintf("%s %s %d %d %d %d %d %d %d", servername, progname, |
2817 | + prog, vers, prot, port, authflavor, clones, tasks) |
2818 | +} |
2819 | + |
2820 | +probe sunrpc.clnt.shutdown_client.return = |
2821 | + kernel.function("rpc_shutdown_client").return !, |
2822 | + module("sunrpc").function("rpc_shutdown_client").return |
2823 | +{ |
2824 | + name = "sunrpc.clnt.shutdown_client.return" |
2825 | + retstr = returnstr(1) |
2826 | +} |
2827 | + |
2828 | +/* |
2829 | + * Fires when a new RPC program is to be bound an existing client |
2830 | + * |
2831 | + * struct rpc_clnt * rpc_bind_new_program(struct rpc_clnt *old, |
2832 | + * struct rpc_program *program, int vers) |
2833 | + * |
2834 | + * @servername: the server machine name |
2835 | + * @old_progname: the name of old RPC program |
2836 | + * @old_prog: the number of old RPC program |
2837 | + * @old_vers: the version of old RPC program |
2838 | + * @progname: the name of new RPC program |
2839 | + * @prog: the number of new RPC program |
2840 | + * @vers: the version of new RPC program |
2841 | + */ |
2842 | +probe sunrpc.clnt.bind_new_program = |
2843 | + kernel.function("rpc_bind_new_program") !, |
2844 | + module("sunrpc").function("rpc_bind_new_program") |
2845 | +{ |
2846 | + servername = kernel_string($old->cl_server) |
2847 | + old_progname = kernel_string($old->cl_protname) |
2848 | + old_prog = prog_from_clnt($old) |
2849 | + old_vers = vers_from_clnt($old) |
2850 | + progname = kernel_string($program->name) |
2851 | + prog = $program->number |
2852 | + vers = vers_from_prog($program, $vers) |
2853 | + |
2854 | + name = "sunrpc.clnt.bind_new_program" |
2855 | + argstr = sprintf("%s %s %d %s %d", servername, old_progname, |
2856 | + old_vers, progname, vers) |
2857 | +} |
2858 | + |
2859 | +probe sunrpc.clnt.bind_new_program.return = |
2860 | + kernel.function("rpc_bind_new_program").return !, |
2861 | + module("sunrpc").function("rpc_bind_new_program").return |
2862 | +{ |
2863 | + name = "sunrpc.clnt.bind_new_program.return" |
2864 | + retstr = returnstr(2) |
2865 | +} |
2866 | + |
2867 | +/* |
2868 | + * int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, |
2869 | + * int flags) |
2870 | + * |
2871 | + * @servername: the server machine name |
2872 | + * @progname: the RPC program name |
2873 | + * @prog: the RPC program number |
2874 | + * @vers: the RPC program version number |
2875 | + * @prot: the IP protocol number |
2876 | + * @port: the port number |
2877 | + * @xid: current transmission id |
2878 | + * @dead: whether this client is abandoned |
2879 | + * @procname: the procedure name in this RPC call |
2880 | + * @proc: the procedure number in this RPC call |
2881 | + * @flags: flags |
2882 | + */ |
2883 | +probe sunrpc.clnt.call_sync = kernel.function("rpc_call_sync") !, |
2884 | + module("sunrpc").function("rpc_call_sync") |
2885 | +{ |
2886 | + servername = kernel_string($clnt->cl_server) |
2887 | + progname = kernel_string($clnt->cl_protname) |
2888 | + prog = prog_from_clnt($clnt) |
2889 | + vers = vers_from_clnt($clnt) |
2890 | + prot = prot_from_clnt($clnt) |
2891 | + port = port_from_clnt($clnt) |
2892 | + xid = xid_from_clnt($clnt) |
2893 | + dead = (! @defined($clnt->cl_dead) |
2894 | + ? (atomic_read(&$clnt->cl_kref->refcount) == 0) |
2895 | + : $clnt->cl_dead) |
2896 | + |
2897 | + proc = proc_from_msg($msg) |
2898 | + procname = (@defined($msg->rpc_proc->p_name) |
2899 | + ? ($msg->rpc_proc->p_name |
2900 | + ? kernel_string($msg->rpc_proc->p_name) : "NULL") |
2901 | + : "NULL") |
2902 | + flags = $flags |
2903 | + |
2904 | + name = "sunrpc.clnt.call_sync" |
2905 | + argstr = sprintf("%s %d %s %d %s %d", servername, xid, progname, |
2906 | + vers, procname, flags) |
2907 | +} |
2908 | + |
2909 | +probe sunrpc.clnt.call_sync.return = kernel.function("rpc_call_sync").return !, |
2910 | + module("sunrpc").function("rpc_call_sync").return |
2911 | +{ |
2912 | + name = "sunrpc.clnt.call_sync.return" |
2913 | + retstr = returnstr(1) |
2914 | +} |
2915 | + |
2916 | +/* |
2917 | + * int rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, |
2918 | + * int flags, const struct rpc_call_ops *tk_ops, void *data) |
2919 | + * |
2920 | + * @servername: the server machine name |
2921 | + * @progname: the RPC program name |
2922 | + * @prog: the RPC program number |
2923 | + * @vers: the RPC program version number |
2924 | + * @prot: the IP protocol number |
2925 | + * @port: the port number |
2926 | + * @xid: current transmission id |
2927 | + * @dead: whether this client is abandoned |
2928 | + * @procname: the procedure name in this RPC call |
2929 | + * @proc: the procedure number in this RPC call |
2930 | + * @flags: flags |
2931 | + */ |
2932 | +probe sunrpc.clnt.call_async = kernel.function("rpc_call_async") !, |
2933 | + module("sunrpc").function("rpc_call_async") |
2934 | +{ |
2935 | + servername = kernel_string($clnt->cl_server) |
2936 | + progname = kernel_string($clnt->cl_protname) |
2937 | + prog = prog_from_clnt($clnt) |
2938 | + vers = vers_from_clnt($clnt) |
2939 | + prot = prot_from_clnt($clnt) |
2940 | + port = port_from_clnt($clnt) |
2941 | + xid = xid_from_clnt($clnt) |
2942 | + dead = (! @defined($clnt->cl_dead) |
2943 | + ? (atomic_read(&$clnt->cl_kref->refcount) == 0) |
2944 | + : $clnt->cl_dead) |
2945 | + |
2946 | + proc = proc_from_msg($msg) |
2947 | + procname = (@defined($msg->rpc_proc->p_name) |
2948 | + ? ($msg->rpc_proc->p_name |
2949 | + ? kernel_string($msg->rpc_proc->p_name) : "NULL") |
2950 | + : "NULL") |
2951 | + flags = $flags |
2952 | + |
2953 | + name = "sunrpc.clnt.call_async" |
2954 | + argstr = sprintf("%s %d %s %d %s %d", servername, xid, progname, |
2955 | + vers, procname, flags) |
2956 | +} |
2957 | + |
2958 | +probe sunrpc.clnt.call_async.return = |
2959 | + kernel.function("rpc_call_async").return !, |
2960 | + module("sunrpc").function("rpc_call_async").return |
2961 | +{ |
2962 | + name = "sunrpc.clnt.call_async.return" |
2963 | + retstr = returnstr(1) |
2964 | +} |
2965 | + |
2966 | +/* |
2967 | + * Fires when an (async) RPC call is to be restarted |
2968 | + * |
2969 | + * void rpc_restart_call(struct rpc_task *task) |
2970 | + * |
2971 | + * @servername: the server machine name |
2972 | + * @prog: the RPC program number |
2973 | + * @xid: the transmission id |
2974 | + * @tk_pid: the debugging aid of task |
2975 | + * @tk_flags: the task flags |
2976 | + * @tk_priority: the task priority |
2977 | + * @tk_runstate: the task run status |
2978 | + */ |
2979 | +probe sunrpc.clnt.restart_call = kernel.function("rpc_restart_call") !, |
2980 | + module("sunrpc").function("rpc_restart_call") |
2981 | +{ |
2982 | + servername = kernel_string($task->tk_client->cl_server) |
2983 | + prog = prog_from_clnt($task->tk_client) |
2984 | + xid = $task->tk_rqstp->rq_xid |
2985 | + tk_pid = $task->tk_pid |
2986 | + tk_flags = $task->tk_flags |
2987 | + tk_priority = $task->tk_priority |
2988 | + tk_runstate = $task->tk_runstate |
2989 | + |
2990 | + name = "sunrpc.clnt.restart_call" |
2991 | + argstr = sprintf("%s %d %d %d %d %d %d", servername, prog, xid, tk_pid, |
2992 | + tk_flags, tk_priority, tk_runstate) |
2993 | +} |
2994 | + |
2995 | +probe sunrpc.clnt.restart_call.return = |
2996 | + kernel.function("rpc_restart_call").return !, |
2997 | + module("sunrpc").function("rpc_restart_call").return |
2998 | +{ |
2999 | + name = "sunrpc.clnt.restart_call.return" |
3000 | + retstr = "N/A" |
3001 | +} |
3002 | + |
3003 | +/********************************************* |
3004 | + * Probe points on RPC server interface * |
3005 | + ********************************************/ |
3006 | +probe sunrpc.svc.entry = |
3007 | + sunrpc.svc.register, |
3008 | + sunrpc.svc.create, |
3009 | + sunrpc.svc.destroy, |
3010 | + sunrpc.svc.process, |
3011 | + sunrpc.svc.authorise, |
3012 | + sunrpc.svc.recv, |
3013 | + sunrpc.svc.send, |
3014 | + sunrpc.svc.drop |
3015 | +{} |
3016 | + |
3017 | +probe sunrpc.svc.return = |
3018 | + sunrpc.svc.register.return, |
3019 | + sunrpc.svc.create.return, |
3020 | + sunrpc.svc.destroy.return, |
3021 | + sunrpc.svc.process.return, |
3022 | + sunrpc.svc.authorise.return, |
3023 | + sunrpc.svc.recv.return, |
3024 | + sunrpc.svc.send.return, |
3025 | + sunrpc.svc.drop.return |
3026 | +{} |
3027 | + |
3028 | +/* |
3029 | + * Fires when an RPC service is to be registered with the local portmapper. |
3030 | + * If proto and port == 0, it means to unregister a service. |
3031 | + * |
3032 | + * int svc_register(struct svc_serv *serv, int proto, unsigned short port) |
3033 | + * |
3034 | + * @sv_name: the service name |
3035 | + * @progname: the name of the program |
3036 | + * @prog: the number of the program |
3037 | + * @prot: the IP protocol number |
3038 | + * @port: the port number |
3039 | + */ |
3040 | +probe sunrpc.svc.register = kernel.function("svc_register") !, |
3041 | + module("sunrpc").function("svc_register") |
3042 | +{ |
3043 | + sv_name = kernel_string($serv->sv_name) |
3044 | + progname = kernel_string($serv->sv_program->pg_name) |
3045 | + prog = $serv->sv_program->pg_prog |
3046 | + prot = $proto |
3047 | + port = $port |
3048 | + |
3049 | + name = "sunrpc.svc.register" |
3050 | + argstr = sprintf("%s %s %d %d", sv_name, progname, prot, port) |
3051 | +} |
3052 | + |
3053 | +probe sunrpc.svc.register.return = kernel.function("svc_register").return !, |
3054 | + module("sunrpc").function("svc_register").return |
3055 | +{ |
3056 | + name = "sunrpc.svc.register.return" |
3057 | + retstr = returnstr(1) |
3058 | +} |
3059 | + |
3060 | +/* |
3061 | + * Fires when an RPC service is to be created |
3062 | + * |
3063 | + * struct svc_serv * |
3064 | + * svc_create(struct svc_program *prog, unsigned int bufsize) |
3065 | + * |
3066 | + * @progname: the name of the program |
3067 | + * @prog: the number of the program |
3068 | + * @pg_nvers: the number of supported versions |
3069 | + * @bufsize: the buffer size |
3070 | + */ |
3071 | +probe sunrpc.svc.create = kernel.function("svc_create") !, |
3072 | + module("sunrpc").function("svc_create") |
3073 | +{ |
3074 | + progname = kernel_string($prog->pg_name) |
3075 | + prog = $prog->pg_prog |
3076 | + pg_nvers = $prog->pg_nvers |
3077 | + bufsize = $bufsize |
3078 | + |
3079 | + name = "sunrpc.svc.create" |
3080 | + argstr = sprintf("%s %d %d %d", progname, prog, pg_nvers, bufsize) |
3081 | +} |
3082 | + |
3083 | +probe sunrpc.svc.create.return = kernel.function("svc_create").return !, |
3084 | + module("sunrpc").function("svc_create").return |
3085 | +{ |
3086 | + name = "sunrpc.svc.create.return" |
3087 | + retstr = returnstr(2) |
3088 | +} |
3089 | + |
3090 | +/* |
3091 | + * Fires when an RPC service is to be destroyed |
3092 | + * |
3093 | + * void svc_destroy(struct svc_serv *serv) |
3094 | + * |
3095 | + * @sv_name: the service name |
3096 | + * @sv_progname: the name of the program |
3097 | + * @sv_prog: the number of the program |
3098 | + * @sv_nrthreads:the number of concurrent threads |
3099 | + * @netcnt: the count of received RPC requests |
3100 | + * @nettcpconn: the count of accepted TCP connections |
3101 | + * @rpccnt: the count of valid RPC requests |
3102 | + * @rpcbadfmt: the count of requests dropped for bad formats |
3103 | + * @rpcbadauth: the count of requests drooped for authentication failure |
3104 | + */ |
3105 | +probe sunrpc.svc.destroy = kernel.function("svc_destroy") !, |
3106 | + module("sunrpc").function("svc_destroy") |
3107 | +{ |
3108 | + sv_name = kernel_string($serv->sv_name) /* service name */ |
3109 | + sv_progname = kernel_string($serv->sv_program->pg_name) |
3110 | + sv_prog = $serv->sv_program->pg_prog |
3111 | + sv_nrthreads = $serv->sv_nrthreads |
3112 | + |
3113 | + /* RPC statistics */ |
3114 | + netcnt = $serv->sv_stats->netcnt |
3115 | + netcpconn = $serv->sv_stats->nettcpconn |
3116 | + rpccnt = $serv->sv_stats->rpccnt |
3117 | + rpcbadfmt = $serv->sv_stats->rpcbadfmt |
3118 | + rpcbadauth = $serv->sv_stats->rpcbadauth |
3119 | + |
3120 | + name = "sunrpc.svc.destroy" |
3121 | + argstr = sprintf("%s %d %d", sv_name, sv_prog, sv_nrthreads) |
3122 | +} |
3123 | + |
3124 | +probe sunrpc.svc.destroy.return = kernel.function("svc_destroy").return !, |
3125 | + module("sunrpc").function("svc_destroy").return |
3126 | +{ |
3127 | + name = "sunrpc.svc.destroy.return" |
3128 | + retstr = "N/A" |
3129 | +} |
3130 | + |
3131 | +/* |
3132 | + * Fires when an RPC request is to be processed |
3133 | + * |
3134 | + * int svc_process(struct svc_serv *serv, struct svc_rqst *rqstp) |
3135 | + * |
3136 | + * @sv_name: the service name |
3137 | + * @sv_prog: the number of the program |
3138 | + * @sv_nrthreads:the number of concurrent threads |
3139 | + * @peer_ip: the peer address where the request is from |
3140 | + * @rq_xid: the transmission id in the request |
3141 | + * @rq_prog: the program number in the request |
3142 | + * @rq_vers: the program version in the request |
3143 | + * @rq_proc: the procedure number in the request |
3144 | + * @rq_prot: the IP protocol of the reqeust |
3145 | + */ |
3146 | +probe sunrpc.svc.process = kernel.function("svc_process") !, |
3147 | + module("sunrpc").function("svc_process") |
3148 | +{ |
3149 | + if (! @defined($serv)) { |
3150 | + sv_name = kernel_string($rqstp->rq_server->sv_name) |
3151 | + sv_prog = $rqstp->rq_server->sv_program->pg_prog |
3152 | + sv_nrthreads = $rqstp->rq_server->sv_nrthreads |
3153 | + } |
3154 | + else { |
3155 | + sv_name = kernel_string($serv->sv_name) /* service name */ |
3156 | + sv_prog = $serv->sv_program->pg_prog |
3157 | + sv_nrthreads = $serv->sv_nrthreads |
3158 | + } |
3159 | + peer_ip = addr_from_rqst($rqstp) |
3160 | + rq_xid = $rqstp->rq_xid |
3161 | + rq_prog = $rqstp->rq_prog |
3162 | + rq_vers = $rqstp->rq_vers |
3163 | + rq_proc = $rqstp->rq_proc |
3164 | + rq_prot = $rqstp->rq_prot |
3165 | + |
3166 | + name = "sunrpc.svc.process" |
3167 | + argstr = sprintf("%s %d %d %d %d %d %d", sv_name, sv_prog, peer_ip, |
3168 | + rq_xid, rq_prog, rq_vers, rq_proc) |
3169 | +} |
3170 | + |
3171 | +probe sunrpc.svc.process.return = kernel.function("svc_process").return !, |
3172 | + module("sunrpc").function("svc_process").return |
3173 | +{ |
3174 | + name = "sunrpc.svc.process.return" |
3175 | + retstr = returnstr(1) |
3176 | +} |
3177 | + |
3178 | +/* |
3179 | + * Fires when an RPC request is to be authorised |
3180 | + * |
3181 | + * int svc_authorise(struct svc_rqst *rqstp) |
3182 | + * |
3183 | + * @sv_name: the service name |
3184 | + * @peer_ip: the peer address where the request is from |
3185 | + * @rq_xid: the transmission id in the request |
3186 | + * @rq_prog: the program number in the request |
3187 | + * @rq_vers: the program version in the request |
3188 | + * @rq_proc: the procedure number in the request |
3189 | + * @rq_prot: the IP protocol of the reqeust |
3190 | + */ |
3191 | +probe sunrpc.svc.authorise = kernel.function("svc_authorise") !, |
3192 | + module("sunrpc").function("svc_authorise") |
3193 | +{ |
3194 | + sv_name = kernel_string($rqstp->rq_server->sv_name) |
3195 | + peer_ip = addr_from_rqst($rqstp) |
3196 | + rq_xid = $rqstp->rq_xid |
3197 | + rq_prog = $rqstp->rq_prog |
3198 | + rq_vers = $rqstp->rq_vers |
3199 | + rq_proc = $rqstp->rq_proc |
3200 | + rq_prot = $rqstp->rq_prot |
3201 | + |
3202 | + name = "sunrpc.svc.authorise" |
3203 | + argstr = sprintf("%d %d %d %d %d %d", peer_ip, rq_xid, rq_prog, |
3204 | + rq_vers, rq_proc, rq_prot) |
3205 | +} |
3206 | + |
3207 | +probe sunrpc.svc.authorise.return = kernel.function("svc_authorise").return !, |
3208 | + module("sunrpc").function("svc_authorise").return |
3209 | +{ |
3210 | + name = "sunrpc.svc.authorise.return" |
3211 | + retstr = returnstr(1) |
3212 | +} |
3213 | + |
3214 | +/* |
3215 | + * Fires when the server is to receive the next request on any socket. |
3216 | + * |
3217 | + * int svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout) |
3218 | + * |
3219 | + * @sv_name: the service name |
3220 | + * @sv_prog: the number of the program |
3221 | + * @sv_nrthreads:the number of concurrent threads |
3222 | + * @timeout: the timeout of waiting for data |
3223 | + */ |
3224 | +probe sunrpc.svc.recv = kernel.function("svc_recv") !, |
3225 | + module("sunrpc").function("svc_recv") |
3226 | +{ |
3227 | + if (! @defined($serv)) { |
3228 | + sv_name = kernel_string($rqstp->rq_server->sv_name) |
3229 | + sv_prog = $rqstp->rq_server->sv_program->pg_prog |
3230 | + sv_nrthreads = $rqstp->rq_server->sv_nrthreads |
3231 | + } |
3232 | + else { |
3233 | + sv_name = kernel_string($serv->sv_name) |
3234 | + sv_prog = $serv->sv_program->pg_prog |
3235 | + sv_nrthreads = $serv->sv_nrthreads |
3236 | + } |
3237 | + timeout = $timeout |
3238 | + |
3239 | + name = "sunrpc.svc.recv" |
3240 | + argstr = sprintf("%s %d", sv_name, timeout) |
3241 | +} |
3242 | + |
3243 | +probe sunrpc.svc.recv.return = kernel.function("svc_recv").return !, |
3244 | + module("sunrpc").function("svc_recv").return |
3245 | +{ |
3246 | + name = "sunrpc.svc.recv.return" |
3247 | + retstr = returnstr(1) |
3248 | +} |
3249 | + |
3250 | +/* |
3251 | + * Fires when want to return reply to client. |
3252 | + * |
3253 | + * int svc_send(struct svc_rqst *rqstp) |
3254 | + * |
3255 | + * @sv_name: the service name |
3256 | + * @peer_ip: the peer address where the request is from |
3257 | + * @rq_xid: the transmission id in the request |
3258 | + * @rq_prog: the program number in the request |
3259 | + * @rq_vers: the program version in the request |
3260 | + * @rq_proc: the procedure number in the request |
3261 | + * @rq_prot: the IP protocol of the reqeust |
3262 | + */ |
3263 | +probe sunrpc.svc.send = kernel.function("svc_send") !, |
3264 | + module("sunrpc").function("svc_send") |
3265 | +{ |
3266 | + sv_name = kernel_string($rqstp->rq_server->sv_name) |
3267 | + peer_ip = addr_from_rqst($rqstp) |
3268 | + rq_xid = $rqstp->rq_xid |
3269 | + rq_prog = $rqstp->rq_prog |
3270 | + rq_vers = $rqstp->rq_vers |
3271 | + rq_proc = $rqstp->rq_proc |
3272 | + rq_prot = $rqstp->rq_prot |
3273 | + |
3274 | + name = "sunrpc.svc.send" |
3275 | + argstr = sprintf("%s %d %d %d %d %d %d", sv_name, peer_ip, |
3276 | + rq_xid, rq_prog, rq_vers, rq_proc, rq_prot) |
3277 | +} |
3278 | + |
3279 | +probe sunrpc.svc.send.return = kernel.function("svc_send").return !, |
3280 | + module("sunrpc").function("svc_send").return |
3281 | +{ |
3282 | + name = "sunrpc.svc.send.return" |
3283 | + retstr = returnstr(1) |
3284 | +} |
3285 | + |
3286 | +/* |
3287 | + * Fires when a request is to be dropped |
3288 | + * |
3289 | + * void svc_drop(struct svc_rqst *rqstp) |
3290 | + * |
3291 | + * @sv_name: the service name |
3292 | + * @peer_ip: the peer address where the request is from |
3293 | + * @rq_xid: the transmission id in the request |
3294 | + * @rq_prog: the program number in the request |
3295 | + * @rq_vers: the program version in the request |
3296 | + * @rq_proc: the procedure number in the request |
3297 | + * @rq_prot: the IP protocol of the reqeust |
3298 | + */ |
3299 | +probe sunrpc.svc.drop = kernel.function("svc_drop") !, |
3300 | + module("sunrpc").function("svc_drop") |
3301 | +{ |
3302 | + sv_name = kernel_string($rqstp->rq_server->sv_name) |
3303 | + peer_ip = addr_from_rqst($rqstp) |
3304 | + rq_xid = $rqstp->rq_xid |
3305 | + rq_prog = $rqstp->rq_prog |
3306 | + rq_vers = $rqstp->rq_vers |
3307 | + rq_proc = $rqstp->rq_proc |
3308 | + rq_prot = $rqstp->rq_prot |
3309 | + |
3310 | + name = "sunrpc.svc.drop" |
3311 | + argstr = sprintf("%s %d %d %d %d %d %d", sv_name, peer_ip, |
3312 | + rq_xid, rq_prog, rq_vers, rq_proc, rq_prot) |
3313 | +} |
3314 | + |
3315 | +probe sunrpc.svc.drop.return = kernel.function("svc_drop").return !, |
3316 | + module("sunrpc").function("svc_drop").return |
3317 | +{ |
3318 | + name = "sunrpc.svc.drop.return" |
3319 | + retstr = "N/A" |
3320 | +} |
3321 | + |
3322 | +/******************************************************************* |
3323 | + * Probe points on RPC scheduler * |
3324 | + ******************************************************************/ |
3325 | +probe sunrpc.sched.entry = |
3326 | + sunrpc.sched.new_task, |
3327 | + sunrpc.sched.release_task ?, |
3328 | + sunrpc.sched.execute, |
3329 | + sunrpc.sched.delay |
3330 | +{} |
3331 | + |
3332 | +probe sunrpc.sched.return = |
3333 | + sunrpc.sched.new_task.return, |
3334 | + sunrpc.sched.release_task.return ?, |
3335 | + sunrpc.sched.execute.return, |
3336 | + sunrpc.sched.delay.return |
3337 | +{} |
3338 | + |
3339 | +/* |
3340 | + * Fires when a new task is to be created for the specified client. |
3341 | + * |
3342 | + * struct rpc_task * rpc_new_task(struct rpc_clnt *clnt, int flags, |
3343 | + * const struct rpc_call_ops *tk_ops, void *calldata) |
3344 | + * |
3345 | + * @xid: the transmission id in the RPC call |
3346 | + * @prog: the program number in the RPC call |
3347 | + * @vers: the program version in the RPC call |
3348 | + * @prot: the IP protocol in the RPC call |
3349 | + * @tk_flags: the flags of the task |
3350 | + */ |
3351 | +probe sunrpc.sched.new_task = kernel.function("rpc_new_task") !, |
3352 | + module("sunrpc").function("rpc_new_task") |
3353 | +{ |
3354 | + if (@defined($setup_data)) { |
3355 | + xid = xid_from_clnt($setup_data->rpc_client) |
3356 | + prog = prog_from_clnt($setup_data->rpc_client) |
3357 | + vers = vers_from_clnt($setup_data->rpc_client) |
3358 | + prot = prot_from_clnt($setup_data->rpc_client) |
3359 | + flags = $setup_data->flags |
3360 | + } |
3361 | + else { |
3362 | + xid = xid_from_clnt($clnt) |
3363 | + prog = prog_from_clnt($clnt) |
3364 | + vers = vers_from_clnt($clnt) |
3365 | + prot = prot_from_clnt($clnt) |
3366 | + flags = $flags |
3367 | + } |
3368 | + |
3369 | + name = "sunrpc.sched.new_task" |
3370 | + argstr = sprintf("%d %d %d %d %d", xid, prog, vers, prot, flags) |
3371 | +} |
3372 | + |
3373 | +probe sunrpc.sched.new_task.return = kernel.function("rpc_new_task").return !, |
3374 | + module("sunrpc").function("rpc_new_task").return |
3375 | +{ |
3376 | + name = "sunrpc.sched.new_task.return" |
3377 | + retstr = returnstr(2) |
3378 | +} |
3379 | + |
3380 | +/* |
3381 | + * Fires when all resources associated with a task are to be released |
3382 | + * |
3383 | + * void rpc_release_task(struct rpc_task *task) |
3384 | + * |
3385 | + * @xid: the transmission id in the RPC call |
3386 | + * @prog: the program number in the RPC call |
3387 | + * @vers: the program version in the RPC call |
3388 | + * @prot: the IP protocol in the RPC call |
3389 | + * @tk_flags: the flags of the task |
3390 | + * |
3391 | + * rpc_release_task() might not be found for a particular kernel. So, |
3392 | + * if we can't find it, just return '-1' for everything. |
3393 | + * |
3394 | + * The '.call' here is so that we're sure to grab the non-inline |
3395 | + * version of rpc_release_task() (assuming it exists). We can't find |
3396 | + * the return of rpc_release_task() if it is inline (PR 4413). |
3397 | + */ |
3398 | + |
3399 | +probe sunrpc.sched.release_task = kernel.function("rpc_release_task").call !, |
3400 | + module("sunrpc").function("rpc_release_task").call !, |
3401 | + never |
3402 | +{ |
3403 | + if (@defined($task)) { |
3404 | + xid = xid_from_clnt($task->tk_client) |
3405 | + prog = prog_from_clnt($task->tk_client) |
3406 | + vers = vers_from_clnt($task->tk_client) |
3407 | + prot = prot_from_clnt($task->tk_client) |
3408 | + tk_flags = $task->tk_flags |
3409 | + } |
3410 | + else { |
3411 | + xid = -1 |
3412 | + prog = -1 |
3413 | + vers = -1 |
3414 | + prot = -1 |
3415 | + tk_flags = -1 |
3416 | + } |
3417 | + name = "sunrpc.sched.release_task" |
3418 | + argstr = sprintf("%d %d %d %d %d", xid, prog, vers, prot, tk_flags) |
3419 | +} |
3420 | + |
3421 | +probe sunrpc.sched.release_task.return = |
3422 | + kernel.function("rpc_release_task").return !, |
3423 | + module("sunrpc").function("rpc_release_task").return ? |
3424 | +{ |
3425 | + name = "sunrpc.sched.release_task.return" |
3426 | + retstr = "N/A" |
3427 | +} |
3428 | + |
3429 | +/* |
3430 | + * Fires when the RPC `scheduler'(or rather, the finite state machine) |
3431 | + * is to be executed |
3432 | + * |
3433 | + * static int __rpc_execute(struct rpc_task *task) |
3434 | + * |
3435 | + * @xid: the transmission id in the RPC call |
3436 | + * @prog: the program number in the RPC call |
3437 | + * @vers: the program version in the RPC call |
3438 | + * @prot: the IP protocol in the RPC call |
3439 | + * @tk_pid: the debugging id of the task |
3440 | + * @tk_flags: the flags of the task |
3441 | + */ |
3442 | +probe sunrpc.sched.execute = kernel.function("__rpc_execute") !, |
3443 | + module("sunrpc").function("__rpc_execute") |
3444 | +{ |
3445 | + xid = xid_from_clnt($task->tk_client) |
3446 | + prog = prog_from_clnt($task->tk_client) |
3447 | + vers = vers_from_clnt($task->tk_client) |
3448 | + prot = prot_from_clnt($task->tk_client) |
3449 | + tk_pid = $task->tk_pid |
3450 | + tk_flags = $task->tk_flags |
3451 | + |
3452 | + name = "sunrpc.sched.execute" |
3453 | + argstr = sprintf("%d %d %d %d %d %d", xid, prog, vers, prot, |
3454 | + tk_pid, tk_flags) |
3455 | +} |
3456 | + |
3457 | +probe sunrpc.sched.execute.return = kernel.function("__rpc_execute").return !, |
3458 | + module("sunrpc").function("__rpc_execute").return |
3459 | +{ |
3460 | + name = "sunrpc.sched.execute.return" |
3461 | + |
3462 | + # On kernels > 2.6.20, __rpc_execute() is a void function. |
3463 | + if (@defined($return)) { |
3464 | + retstr = returnstr(1) |
3465 | + } |
3466 | + else { |
3467 | + retstr = "N/A" |
3468 | + } |
3469 | +} |
3470 | + |
3471 | +/* |
3472 | + * Fires when a task is to be delayed |
3473 | + * |
3474 | + * void rpc_delay(struct rpc_task *task, unsigned long delay) |
3475 | + * |
3476 | + * @xid: the transmission id in the RPC call |
3477 | + * @prog: the program number in the RPC call |
3478 | + * @vers: the program version in the RPC call |
3479 | + * @prot: the IP protocol in the RPC call |
3480 | + * @tk_pid: the debugging id of the task |
3481 | + * @tk_flags: the flags of the task |
3482 | + * @delay: the time delayed |
3483 | + */ |
3484 | +probe sunrpc.sched.delay = kernel.function("rpc_delay") !, |
3485 | + module("sunrpc").function("rpc_delay") |
3486 | +{ |
3487 | + xid = xid_from_clnt($task->tk_client) |
3488 | + prog = prog_from_clnt($task->tk_client) |
3489 | + vers = vers_from_clnt($task->tk_client) |
3490 | + prot = prot_from_clnt($task->tk_client) |
3491 | + tk_pid = $task->tk_pid |
3492 | + tk_flags = $task->tk_flags |
3493 | + delay = $delay |
3494 | + |
3495 | + name = "sunrpc.sched.delay" |
3496 | + argstr = sprintf("%d %d %d %d %d %d %d", xid, prog, vers, |
3497 | + prot, tk_pid, tk_flags, delay) |
3498 | +} |
3499 | + |
3500 | +probe sunrpc.sched.delay.return = kernel.function("rpc_delay").return !, |
3501 | + module("sunrpc").function("rpc_delay").return |
3502 | +{ |
3503 | + name = "sunrpc.sched.delay.return" |
3504 | + retstr = "N/A" |
3505 | +} |
3506 | + |
3507 | +/****************************************************************** |
3508 | + * Helper functions * |
3509 | + *****************************************************************/ |
3510 | + |
3511 | +function xid_from_clnt:long(clnt:long) |
3512 | +{ |
3513 | + if (clnt == 0) |
3514 | + return 0 |
3515 | + return @cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_xprt->xid |
3516 | +} |
3517 | + |
3518 | +function prog_from_clnt:long(clnt:long) |
3519 | +{ |
3520 | + if (clnt == 0) |
3521 | + return 0 |
3522 | + if (@defined(@cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_prog)) |
3523 | + return @cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_prog |
3524 | + else |
3525 | + return @cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_pmap->pm_prog |
3526 | +} |
3527 | + |
3528 | +function vers_from_clnt:long(clnt:long) |
3529 | +{ |
3530 | + if (clnt == 0) |
3531 | + return 0 |
3532 | + if (@defined(@cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_vers)) |
3533 | + return @cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_vers |
3534 | + else |
3535 | + return @cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_pmap->pm_vers |
3536 | +} |
3537 | + |
3538 | +function prot_from_clnt:long(clnt:long) |
3539 | +{ |
3540 | + if (clnt == 0) |
3541 | + return 0 |
3542 | + return @cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_xprt->prot |
3543 | +} |
3544 | + |
3545 | +function port_from_xprt:long(cl_xprt:long) |
3546 | +{ |
3547 | + if (cl_xprt == 0) |
3548 | + return 0 |
3549 | + |
3550 | + addr = &@cast(cl_xprt, "rpc_xprt", "kernel:sunrpc")->addr |
3551 | + if (addr == 0) |
3552 | + return 0 |
3553 | + |
3554 | + /* In reality, 'cl_xprt->addr' is of 'sockaddr_storage' type |
3555 | + * (since 2.6.19). But when used, you cast it to what is |
3556 | + * inside that buffer. */ |
3557 | + if (@cast(addr, "sockaddr_in")->sin_family == AF_INET()) { |
3558 | + /* Now consider ipv4 only */ |
3559 | + return ntohs(@cast(addr, "sockaddr_in")->sin_port) |
3560 | + } |
3561 | + return 0 |
3562 | +} |
3563 | + |
3564 | +function port_from_clnt:long(clnt:long) |
3565 | +{ |
3566 | + if (clnt == 0) |
3567 | + return 0 |
3568 | + |
3569 | + cl_xprt = @cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_xprt |
3570 | + return port_from_xprt(cl_xprt) |
3571 | +} |
3572 | + |
3573 | +function clones_from_clnt:long(clnt:long) |
3574 | +{ |
3575 | + return (@defined(@cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_count) |
3576 | + ? atomic_read(&@cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_count) |
3577 | + : -1) |
3578 | +} |
3579 | + |
3580 | +function tasks_from_clnt:long(clnt:long) |
3581 | +{ |
3582 | + return (@defined(@cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_users) |
3583 | + ? atomic_read(&@cast(clnt, "rpc_clnt", "kernel:sunrpc")->cl_users) |
3584 | + : -1) |
3585 | +} |
3586 | + |
3587 | +function proc_from_msg:long(msg:long) |
3588 | +{ |
3589 | + if (msg == 0) |
3590 | + return 0 |
3591 | + return @cast(msg, "rpc_message", "kernel:sunrpc")->rpc_proc->p_proc |
3592 | +} |
3593 | + |
3594 | +function vers_from_prog:long(program:long, vers:long) |
3595 | +{ |
3596 | + if (program |
3597 | + && vers < @cast(program, "rpc_program", "kernel:sunrpc")->nrvers) |
3598 | + return @cast(program, "rpc_program", "kernel:sunrpc")->version[vers]->number |
3599 | + return 0 |
3600 | +} |
3601 | + |
3602 | +function addr_from_rqst:long(rqstp:long) |
3603 | +{ |
3604 | + if (rqstp) { |
3605 | + addr = &@cast(rqstp, "svc_rqst", "kernel:nfs")->rq_addr |
3606 | + if (addr == 0) |
3607 | + return 0 |
3608 | + |
3609 | + /* In reality, 'rq_addr' is of 'sockaddr_storage' type |
3610 | + * (since 2.6.19). But when used, you cast it to what is |
3611 | + * inside that buffer. */ |
3612 | + if (@cast(addr, "sockaddr_in")->sin_family == AF_INET()) { |
3613 | + /* Now consider ipv4 only */ |
3614 | + return @cast(addr, "sockaddr_in")->sin_addr->s_addr |
3615 | + } |
3616 | + } |
3617 | + return 0 |
3618 | +} |
3619 | + |
3620 | +function addr_from_rqst_str:string(rqstp:long) |
3621 | +{ |
3622 | + if (rqstp == 0) |
3623 | + return "Null" |
3624 | + |
3625 | + addr = &@cast(rqstp, "svc_rqst", "kernel:nfs")->rq_addr |
3626 | + if (addr == 0) |
3627 | + return "Null" |
3628 | + |
3629 | + s_addr = addr_from_rqst(rqstp) |
3630 | + if (s_addr == 0) |
3631 | + return "Unsupported Address Family" |
3632 | + return sprintf("%s:%d", daddr_to_string(s_addr), |
3633 | + @cast(addr, "sockaddr_in")->sin_port) |
3634 | +} |
3635 | + |
3636 | |
3637 | === added file '.pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/task.stp' |
3638 | --- .pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/task.stp 1970-01-01 00:00:00 +0000 |
3639 | +++ .pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/task.stp 2011-03-22 12:11:00 +0000 |
3640 | @@ -0,0 +1,384 @@ |
3641 | +// task information tapset |
3642 | +// Copyright (C) 2006 Intel Corporation. |
3643 | +// Copyright (C) 2010 Red Hat Inc. |
3644 | +// |
3645 | +// This file is part of systemtap, and is free software. You can |
3646 | +// redistribute it and/or modify it under the terms of the GNU General |
3647 | +// Public License (GPL); either version 2, or (at your option) any |
3648 | +// later version. |
3649 | + |
3650 | +%{ |
3651 | +#include <linux/version.h> |
3652 | +#include <linux/file.h> |
3653 | +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,25) |
3654 | +#include <linux/fdtable.h> |
3655 | +#endif |
3656 | +#ifndef STAPCONF_TASK_UID |
3657 | +#include <linux/cred.h> |
3658 | +#endif |
3659 | +%} |
3660 | + |
3661 | +/** |
3662 | + * sfunction task_current - The current task_struct of the current task. |
3663 | + * |
3664 | + * General Syntax: task_current:long() |
3665 | + * |
3666 | + * Description: This function returns the task_struct representing the current process. |
3667 | + * This address can be passed to the various task_*() functions to extract |
3668 | + * more task-specific data. |
3669 | + */ |
3670 | +function task_current:long () %{ /* pure */ |
3671 | + THIS->__retvalue = (long)current; |
3672 | +%} |
3673 | + |
3674 | +/** |
3675 | + * sfunction task_parent - The task_struct of the parent task. |
3676 | + * |
3677 | + * General Syntax: task_parent:long(task:long) |
3678 | + * |
3679 | + * @task: task_struct pointer. |
3680 | + * |
3681 | + * Description: This function returns the parent task_struct of |
3682 | + * the given task. This address can be passed to the various |
3683 | + * task_*() functions to extract more task-specific data. |
3684 | + */ |
3685 | +function task_parent:long(task:long) |
3686 | +{ |
3687 | + return (@defined(@cast(task, "task_struct", |
3688 | + "kernel<linux/sched.h>")->real_parent) |
3689 | + ? @cast(task, "task_struct", "kernel<linux/sched.h>")->real_parent |
3690 | + : @cast(task, "task_struct", "kernel<linux/sched.h>")->parent) |
3691 | +} |
3692 | + |
3693 | +/** |
3694 | + * sfunction task_state - The state of the task. |
3695 | + * |
3696 | + * General Syntax: task_state:long(task:long) |
3697 | + * |
3698 | + * @task: task_struct pointer. |
3699 | + * |
3700 | + * Description: Return the state of the given task, one of: |
3701 | + * TASK_RUNNING (0), TASK_INTERRUPTIBLE (1), TASK_UNINTERRUPTIBLE (2), |
3702 | + * TASK_STOPPED (4), TASK_TRACED (8), EXIT_ZOMBIE (16), EXIT_DEAD (32). |
3703 | + */ |
3704 | +function task_state:long (task:long) |
3705 | +{ |
3706 | + return @cast(task, "task_struct", "kernel<linux/sched.h>")->state |
3707 | +} |
3708 | + |
3709 | +/** |
3710 | + * sfunction task_execname - The name of the task. |
3711 | + * |
3712 | + * General Syntax: task_execname:string(task:long) |
3713 | + * |
3714 | + * @task: task_struct pointer. |
3715 | + * |
3716 | + * Description: Return the name of the given task. |
3717 | + */ |
3718 | +function task_execname:string (task:long) |
3719 | +{ |
3720 | + return kernel_string(@cast(task, "task_struct", "kernel<linux/sched.h>")->comm) |
3721 | +} |
3722 | + |
3723 | +/** |
3724 | + * sfunction task_pid - The process identifier of the task. |
3725 | + * |
3726 | + * General Syntax: task_pid:long (task:long) |
3727 | + * |
3728 | + * @task: task_struct pointer. |
3729 | + * |
3730 | + * Description: This fucntion returns the process id of the given task. |
3731 | + */ |
3732 | +function task_pid:long (task:long) |
3733 | +{ |
3734 | + return @cast(task, "task_struct", "kernel<linux/sched.h>")->tgid |
3735 | +} |
3736 | + |
3737 | +/** |
3738 | + * sfunction pid2task - The task_struct of the given process identifier. |
3739 | + * @pid: Process identifier. |
3740 | + * |
3741 | + * Description: Return the task struct of the given process id. |
3742 | + */ |
3743 | +function pid2task:long (pid:long) %{ /* pure */ |
3744 | + struct task_struct *t = NULL; |
3745 | + pid_t t_pid = (pid_t)(long)THIS->pid; |
3746 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) |
3747 | + struct pid *p_pid = find_get_pid(t_pid); |
3748 | + t = pid_task(p_pid, PIDTYPE_PID); |
3749 | + put_pid(p_pid); |
3750 | +#else |
3751 | + rcu_read_lock(); |
3752 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) |
3753 | + t = find_task_by_vpid (t_pid); |
3754 | +#else |
3755 | + t = find_task_by_pid (t_pid); |
3756 | +#endif /* 2.6.24 */ |
3757 | + rcu_read_unlock(); |
3758 | +#endif /* 2.6.31 */ |
3759 | + THIS->__retvalue = (long)t; |
3760 | +%} |
3761 | + |
3762 | +/** |
3763 | + * sfunction pid2execname - The name of the given process identifier. |
3764 | + * @pid: Process identifier. |
3765 | + * |
3766 | + * Description: Return the name of the given process id. |
3767 | + */ |
3768 | +function pid2execname:string (pid:long) { |
3769 | + tsk = pid2task(pid) |
3770 | + if (tsk) |
3771 | + return task_execname(tsk) |
3772 | + return "" |
3773 | +} |
3774 | + |
3775 | +/** |
3776 | + * sfunction task_tid - The thread identifier of the task. |
3777 | + * |
3778 | + * General Syntax: task_tid:long(task:long) |
3779 | + * |
3780 | + * @task: task_struct pointer. |
3781 | + * |
3782 | + * Description: This function returns the thread id of the given task. |
3783 | + */ |
3784 | +function task_tid:long (task:long) |
3785 | +{ |
3786 | + return @cast(task, "task_struct", "kernel<linux/sched.h>")->pid |
3787 | +} |
3788 | + |
3789 | + |
3790 | +/** |
3791 | + * sfunction task_gid - The group identifier of the task. |
3792 | + * |
3793 | + * General Syntax: task_gid:long(task:long) |
3794 | + * |
3795 | + * @task: task_struct pointer. |
3796 | + * |
3797 | + * Description: This function returns the group id of the given task. |
3798 | + */ |
3799 | +function task_gid:long (task:long) %{ /* pure */ |
3800 | + struct task_struct *t = (struct task_struct *)(long)THIS->task; |
3801 | +#ifdef STAPCONF_TASK_UID |
3802 | + THIS->__retvalue = kread(&(t->gid)); |
3803 | + CATCH_DEREF_FAULT(); |
3804 | +#else |
3805 | + /* XXX: We can't easily kread this rcu-protected field. */ |
3806 | + /* XXX: no task_gid() in 2.6.28 */ |
3807 | + struct cred *cred; |
3808 | + rcu_read_lock(); |
3809 | + cred = get_task_cred (t); |
3810 | + rcu_read_unlock(); |
3811 | + THIS->__retvalue = cred->gid; |
3812 | +#endif |
3813 | +%} |
3814 | + |
3815 | + |
3816 | +/** |
3817 | + * sfunction task_egid - The effective group identifier of the task. |
3818 | + * |
3819 | + * General Syntax: task_egid:long(task:long) |
3820 | + * |
3821 | + * @task: task_struct pointer. |
3822 | + * |
3823 | + * Description: This function returns the effective group id of the given task. |
3824 | + */ |
3825 | +function task_egid:long (task:long) %{ /* pure */ |
3826 | + struct task_struct *t = (struct task_struct *)(long)THIS->task; |
3827 | +#ifdef STAPCONF_TASK_UID |
3828 | + THIS->__retvalue = kread(&(t->egid)); |
3829 | + CATCH_DEREF_FAULT(); |
3830 | +#else |
3831 | + /* XXX: We can't easily kread this rcu-protected field. */ |
3832 | + /* XXX: no task_egid() in 2.6.28 */ |
3833 | + struct cred *cred; |
3834 | + rcu_read_lock(); |
3835 | + cred = get_task_cred (t); |
3836 | + rcu_read_unlock(); |
3837 | + THIS->__retvalue = cred->egid; |
3838 | +#endif |
3839 | +%} |
3840 | + |
3841 | +/** |
3842 | + * sfunction task_uid - The user identifier of the task. |
3843 | + * |
3844 | + * General Syntax: task_uid:long(task:long) |
3845 | + * |
3846 | + * @task: task_struct pointer. |
3847 | + * |
3848 | + * Description: This function returns the user id of the given task. |
3849 | + */ |
3850 | +function task_uid:long (task:long) %{ /* pure */ |
3851 | + struct task_struct *t = (struct task_struct *)(long)THIS->task; |
3852 | +#ifdef STAPCONF_TASK_UID |
3853 | + THIS->__retvalue = kread(&(t->uid)); |
3854 | + CATCH_DEREF_FAULT(); |
3855 | +#else |
3856 | + /* XXX: We can't easily kread this rcu-protected field. */ |
3857 | + THIS->__retvalue = task_uid (t); |
3858 | +#endif |
3859 | +%} |
3860 | + |
3861 | +/** |
3862 | + * sfunction task_euid - The effective user identifier of the task. |
3863 | + * |
3864 | + * General Syntax: task_euid:long(task:long) |
3865 | + * |
3866 | + * @task: task_struct pointer. |
3867 | + * |
3868 | + * Description: This function returns the effective user id of the given task. |
3869 | + */ |
3870 | +function task_euid:long (task:long) %{ /* pure */ |
3871 | + struct task_struct *t = (struct task_struct *)(long)THIS->task; |
3872 | +#ifdef STAPCONF_TASK_UID |
3873 | + THIS->__retvalue = kread(&(t->euid)); |
3874 | + CATCH_DEREF_FAULT(); |
3875 | +#else |
3876 | + /* XXX: We can't easily kread this rcu-protected field. */ |
3877 | + THIS->__retvalue = task_euid (t); |
3878 | +#endif |
3879 | +%} |
3880 | + |
3881 | + |
3882 | +/** |
3883 | + * sfunction task_prio - The priority value of the task. |
3884 | + * |
3885 | + * General Syntax: task_prio:long(task:long) |
3886 | + * |
3887 | + * @task: task_struct pointer. |
3888 | + * |
3889 | + * Description: This function returns the priority value of the given task. |
3890 | + */ |
3891 | +function task_prio:long (task:long) %{ /* pure */ |
3892 | + struct task_struct *t = (struct task_struct *)(long)THIS->task; |
3893 | + THIS->__retvalue = kread(&(t->prio)) - MAX_RT_PRIO; |
3894 | + CATCH_DEREF_FAULT(); |
3895 | +%} |
3896 | + |
3897 | + |
3898 | +/** |
3899 | + * sfunction task_nice - The nice value of the task. |
3900 | + * |
3901 | + * General Syntax: task_nice:long(task:long) |
3902 | + * |
3903 | + * @task: task_struct pointer. |
3904 | + * |
3905 | + * Description: This function returns the nice value of the given task. |
3906 | + */ |
3907 | +function task_nice:long (task:long) %{ /* pure */ |
3908 | + struct task_struct *t = (struct task_struct *)(long)THIS->task; |
3909 | + THIS->__retvalue = kread(&(t->static_prio)) - MAX_RT_PRIO - 20; |
3910 | + CATCH_DEREF_FAULT(); |
3911 | +%} |
3912 | + |
3913 | +/** |
3914 | + * sfunction task_cpu - The scheduled cpu of the task. |
3915 | + * |
3916 | + * General Syntax: task_cpu:long(task:long) |
3917 | + * |
3918 | + * @task: task_struct pointer. |
3919 | + * |
3920 | + * Description: This function returns the scheduled cpu for the given task. |
3921 | + */ |
3922 | +function task_cpu:long (task:long) |
3923 | +{ |
3924 | + ti = (@defined(@cast(task, "task_struct", "kernel<linux/sched.h>")->stack) |
3925 | + ? @cast(task, "task_struct", "kernel<linux/sched.h>")->stack |
3926 | + : @cast(task, "task_struct", "kernel<linux/sched.h>")->thread_info); |
3927 | + return @cast(ti, "thread_info", "kernel<linux/sched.h>")->cpu |
3928 | +} |
3929 | + |
3930 | +/** |
3931 | + * sfunction task_open_file_handles - The number of open files of the task. |
3932 | + * |
3933 | + * General Syntax: task_open_file_handles:long(task:long) |
3934 | + * |
3935 | + * @task: task_struct pointer. |
3936 | + * |
3937 | + * Description: This function returns the number of open file handlers for the given task. |
3938 | + */ |
3939 | +function task_open_file_handles:long (task:long) |
3940 | +%( kernel_v >= "2.6.15" %? |
3941 | +%{ /* pure */ |
3942 | + int locked = 0; |
3943 | + unsigned int count=0, fd, max; |
3944 | + struct task_struct *t; |
3945 | + struct files_struct *fs; |
3946 | + struct fdtable *f; |
3947 | + t = (struct task_struct *)(long)THIS->task; |
3948 | + fs = kread(&(t->files)); |
3949 | + f = kread(&(fs->fdt)); |
3950 | + rcu_read_lock(); |
3951 | + locked = 1; |
3952 | + max = kread(&(f->max_fds)); |
3953 | + for (fd = 0; fd < max; fd++) { |
3954 | + if ( kread(&(f->fd[fd])) != NULL) |
3955 | + count ++; |
3956 | + } |
3957 | + THIS->__retvalue = count; |
3958 | + CATCH_DEREF_FAULT(); |
3959 | + if (locked) |
3960 | + rcu_read_unlock(); |
3961 | +%} |
3962 | +%: |
3963 | +%{ /* pure */ |
3964 | + int locked = 0; |
3965 | + unsigned int count=0, fd, max; |
3966 | + struct task_struct *t; |
3967 | + struct files_struct *f; |
3968 | + t = (struct task_struct *)(long)THIS->task; |
3969 | + f = kread(&(t->files)); |
3970 | + rcu_read_lock(); |
3971 | + locked = 1; |
3972 | + max = kread(&(f->max_fds)); |
3973 | + for (fd = 0; fd < max; fd++) { |
3974 | + if ( kread(&(f->fd[fd])) != NULL) |
3975 | + count ++; |
3976 | + } |
3977 | + THIS->__retvalue = count; |
3978 | + CATCH_DEREF_FAULT(); |
3979 | + if (locked) |
3980 | + rcu_read_unlock(); |
3981 | +%} |
3982 | +%) |
3983 | + |
3984 | +/** |
3985 | + * sfunction task_max_file_handles - The max number of open files for the task. |
3986 | + * |
3987 | + * General Syntax: task_max_file_handles:long(task:long) |
3988 | + * |
3989 | + * @task: task_struct pointer. |
3990 | + * |
3991 | + * Description: This function returns the maximum number of file handlers for the given task. |
3992 | + */ |
3993 | +function task_max_file_handles:long (task:long) |
3994 | +%( kernel_v >= "2.6.15" %? |
3995 | +%{ /* pure */ |
3996 | + int locked = 0; |
3997 | + struct task_struct *t; |
3998 | + struct files_struct *fs; |
3999 | + struct fdtable *f; |
4000 | + t = (struct task_struct *)(long)THIS->task; |
4001 | + fs = kread (&(t->files)); |
4002 | + f = kread(&(fs->fdt)); |
4003 | + rcu_read_lock(); |
4004 | + locked = 1; |
4005 | + THIS->__retvalue = kread(&(f->max_fds)); |
4006 | + CATCH_DEREF_FAULT(); |
4007 | + if (locked) |
4008 | + rcu_read_unlock(); |
4009 | +%} |
4010 | +%: |
4011 | +%{ /* pure */ |
4012 | + int locked = 0; |
4013 | + struct task_struct *t; |
4014 | + struct files_struct *f; |
4015 | + t = (struct task_struct *)(long)THIS->task; |
4016 | + f = kread(&(t->files)); |
4017 | + rcu_read_lock(); |
4018 | + locked = 1; |
4019 | + THIS->__retvalue = kread(&(f->max_fds)); |
4020 | + CATCH_DEREF_FAULT(); |
4021 | + if (locked) |
4022 | + rcu_read_unlock(); |
4023 | +%} |
4024 | +%) |
4025 | |
4026 | === added file '.pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/vfs.stp' |
4027 | --- .pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/vfs.stp 1970-01-01 00:00:00 +0000 |
4028 | +++ .pc/Updated-memory.stp-rpc.stp-task.stp-and-vfs.stp-for-.patch/tapset/vfs.stp 2011-03-22 12:11:00 +0000 |
4029 | @@ -0,0 +1,1018 @@ |
4030 | +// vfs tapset |
4031 | +// Copyright (C) 2006-2007 IBM Corp. |
4032 | +// Copyright (C) 2007 Intel Corporation. |
4033 | +// Copyright (C) 2007 Bull S.A.S |
4034 | +// Copyright (c) 2008, 2010 Red Hat Inc. |
4035 | +// |
4036 | +// This file is part of systemtap, and is free software. You can |
4037 | +// redistribute it and/or modify it under the terms of the GNU General |
4038 | +// Public License (GPL); either version 2, or (at your option) any |
4039 | +// later version. |
4040 | + |
4041 | +/* generic vfs probes */ |
4042 | + |
4043 | +/* |
4044 | + We don't want to have to do a bdevname() call every time |
4045 | + we want a devname, so we'll hash them here. |
4046 | +*/ |
4047 | +/* XXX: Is this hashing really that helpful? The call to bdevname() |
4048 | + * isn't very involved... */ |
4049 | +global __devnames |
4050 | +function __find_bdevname:string(dev:long, bdev:long) |
4051 | +{ |
4052 | + if (dev in __devnames) |
4053 | + return __devnames[dev] |
4054 | + else |
4055 | + return __devnames[dev] = bdevname(bdev) |
4056 | +} |
4057 | + |
4058 | +/* deprecated */ |
4059 | +function ppos_pos:long (ppos:long) |
4060 | +{ |
4061 | + return kernel_pointer(ppos) |
4062 | +} |
4063 | + |
4064 | +function __address_inode:long (page:long) |
4065 | +{ |
4066 | + mapping = page? @cast(page, "page", "kernel")->mapping : 0 |
4067 | + if (mapping == 0) |
4068 | + return -1 |
4069 | + else |
4070 | + return @cast(mapping, "address_space", "kernel")->host |
4071 | +} |
4072 | + |
4073 | +function __page_ino:long (page:long) |
4074 | +{ |
4075 | + host = __address_inode(page) |
4076 | + if (host == -1) |
4077 | + return -1 |
4078 | + else |
4079 | + return @cast(host, "inode", "kernel")->i_ino |
4080 | +} |
4081 | + |
4082 | +function __page_dev:long (page:long) |
4083 | +{ |
4084 | + host = __address_inode(page) |
4085 | + if (host == -1) |
4086 | + return -1 |
4087 | + return @cast(host, "inode", "kernel")->i_sb->s_dev |
4088 | +} |
4089 | + |
4090 | +function __page_bdev:long (page:long) |
4091 | +{ |
4092 | + host = __address_inode(page) |
4093 | + if (host == -1) |
4094 | + return 0 |
4095 | + return @cast(host, "inode", "kernel")->i_sb->s_bdev |
4096 | +} |
4097 | + |
4098 | +function __page_index:long (page:long) |
4099 | +{ |
4100 | + return @cast(page, "page", "kernel")->index |
4101 | +} |
4102 | + |
4103 | +function __file_dev:long (file:long) |
4104 | +{ |
4105 | + d_inode = __file_inode(file) |
4106 | + if (d_inode == 0) |
4107 | + return 0 |
4108 | + return @cast(d_inode, "inode", "kernel")->i_sb->s_dev |
4109 | +} |
4110 | + |
4111 | +function __file_bdev:long (file:long) |
4112 | +{ |
4113 | + d_inode = __file_inode(file) |
4114 | + if (d_inode == 0) |
4115 | + return 0 |
4116 | + return @cast(d_inode, "inode", "kernel")->i_sb->s_bdev |
4117 | +} |
4118 | + |
4119 | +function __file_ino:long (file:long) |
4120 | +{ |
4121 | + d_inode = __file_inode(file) |
4122 | + if (d_inode == 0) |
4123 | + return 0 |
4124 | + return @cast(d_inode, "inode", "kernel")->i_ino |
4125 | +} |
4126 | + |
4127 | +function __file_maxbytes:long (file:long) |
4128 | +{ |
4129 | + d_inode = __file_inode(file) |
4130 | + if (d_inode == 0) |
4131 | + return 0 |
4132 | + return @cast(d_inode, "inode", "kernel")->i_sb->s_maxbytes |
4133 | +} |
4134 | + |
4135 | +function __file_filename:string (file:long) |
4136 | +{ |
4137 | + dentry = file |
4138 | + ? (@defined(@cast(file, "file", "kernel")->f_path->dentry) |
4139 | + ? @cast(file, "file", "kernel")->f_path->dentry |
4140 | + : @cast(file, "file", "kernel")->f_dentry) |
4141 | + : 0 |
4142 | + name = dentry? @cast(dentry, "dentry", "kernel")->d_name->name : 0 |
4143 | + if (name == 0) |
4144 | + return "NULL" |
4145 | + else |
4146 | + return kernel_string(name) |
4147 | +} |
4148 | + |
4149 | +function _get_fopv_size:long (iovp:long, nr_segs:long) |
4150 | +{ |
4151 | + if (iovp) { |
4152 | + val = 0 |
4153 | + for (i = 0; i < nr_segs; i++) |
4154 | + val += @cast(iovp, "iovec")[i]->iov_len |
4155 | + return val |
4156 | + } |
4157 | + return -1 |
4158 | +} |
4159 | + |
4160 | +/* deprecated */ |
4161 | +function _dev_minor:long (dev:long) |
4162 | +{ |
4163 | + return MINOR(dev) |
4164 | +} |
4165 | + |
4166 | +/* deprecated */ |
4167 | +function _dev_major:long (dev:long) |
4168 | +{ |
4169 | + return MAJOR(dev) |
4170 | +} |
4171 | + |
4172 | +probe generic.fop.llseek = kernel.function("generic_file_llseek") |
4173 | +{ |
4174 | + dev = __file_dev($file) |
4175 | + devname = __find_bdevname(dev, __file_bdev($file)) |
4176 | + ino = __file_ino($file) |
4177 | + file = $file |
4178 | + |
4179 | + offset = $offset |
4180 | + origin = $origin |
4181 | + maxbyte = __file_maxbytes($file) |
4182 | + |
4183 | + name = "generic_file_llseek" |
4184 | + argstr = sprintf("%d, %d", $offset, $origin) |
4185 | +} |
4186 | +probe generic.fop.llseek.return = kernel.function("generic_file_llseek").return |
4187 | +{ |
4188 | + name = "generic_file_llseek" |
4189 | + retstr = sprintf("%d", $return) |
4190 | + file = $file |
4191 | + offset = $offset |
4192 | + origin = $origin |
4193 | + |
4194 | + error = $return < 0 ? $return : 0 |
4195 | + error_str = error ? errno_str(error) : "" |
4196 | +} |
4197 | + |
4198 | +probe generic.fop.aio_read = |
4199 | + kernel.function("__generic_file_aio_read") !, |
4200 | + kernel.function("generic_file_aio_read") |
4201 | +{ |
4202 | + file = $iocb->ki_filp |
4203 | + dev = __file_dev($iocb->ki_filp) |
4204 | + devname = __find_bdevname(dev, __file_bdev($iocb->ki_filp)) |
4205 | + ino = __file_ino($iocb->ki_filp) |
4206 | + |
4207 | + pos = (@defined($pos) ? $pos : kernel_pointer($ppos)) |
4208 | + buf = $iov->iov_base |
4209 | + count = __iov_length($iov,$nr_segs,1,1) /*FIX ME: should be VERIFY_WRITE instead of 1*/ |
4210 | + name = "generic_file_aio_read" |
4211 | + argstr = sprintf("%d, %d, %p", count, pos, buf) |
4212 | + |
4213 | + size = count |
4214 | + units = "bytes" |
4215 | +} |
4216 | + |
4217 | +probe generic.fop.aio_read.return = |
4218 | + kernel.function("__generic_file_aio_read").return !, |
4219 | + kernel.function("generic_file_aio_read").return |
4220 | +{ |
4221 | + file = $iocb->ki_filp |
4222 | + nr_segs = $nr_segs |
4223 | + name = "generic_file_aio_read" |
4224 | + retstr = sprintf("%d", $return) |
4225 | + |
4226 | + bytes_read = $return > 0 ? $return : 0 |
4227 | + error = $return < 0 ? $return : 0 |
4228 | + error_str = error ? errno_str(error) : "" |
4229 | + |
4230 | + if ($return > 0) { |
4231 | + size = $return |
4232 | + units = "bytes" |
4233 | + } |
4234 | +} |
4235 | + |
4236 | +probe generic.fop.aio_write = kernel.function("generic_file_aio_write") |
4237 | +{ |
4238 | + file = $iocb->ki_filp |
4239 | + dev = __file_dev($iocb->ki_filp) |
4240 | + devname = __find_bdevname(dev, __file_bdev($iocb->ki_filp)) |
4241 | + ino = __file_ino($iocb->ki_filp) |
4242 | + |
4243 | + pos = $pos |
4244 | + |
4245 | + count = (@defined($iov) |
4246 | + ? __iov_length($iov,$nr_segs,1,0) /*FIX ME: should be VERIFY_READ instead of 0*/ |
4247 | + : $count) |
4248 | + buf = (@defined($iov->iov_base) ? $iov->iov_base : $buf) |
4249 | + name = "generic_file_aio_write" |
4250 | + argstr = sprintf("%d, %d, %p", count, pos, buf) |
4251 | + |
4252 | + size = count |
4253 | + units = "bytes" |
4254 | +} |
4255 | +probe generic.fop.aio_write.return = |
4256 | + kernel.function("generic_file_aio_write").return |
4257 | +{ |
4258 | + file = $iocb->ki_filp |
4259 | + name = "generic_file_aio_write" |
4260 | + retstr = sprintf("%d", $return) |
4261 | + |
4262 | + if ($return > 0) { |
4263 | + size = $return |
4264 | + units = "bytes" |
4265 | + } |
4266 | +} |
4267 | + |
4268 | +probe generic.fop.readv = kernel.function("generic_file_readv") ? |
4269 | +{ |
4270 | + dev = __file_dev($filp) |
4271 | + devname = __find_bdevname(dev, __file_bdev($filp)) |
4272 | + ino = __file_ino($filp) |
4273 | + file = $filp |
4274 | + |
4275 | + nr_segs = $nr_segs |
4276 | + pos = kernel_pointer($ppos) |
4277 | + |
4278 | + name = "generic_file_readv" |
4279 | + argstr = sprintf("%d, %d", $nr_segs, pos) |
4280 | + |
4281 | + size = nr_segs |
4282 | + units = "segs" |
4283 | +} |
4284 | +probe generic.fop.readv.return = kernel.function("generic_file_readv").return ? |
4285 | +{ |
4286 | + file = $filp |
4287 | + name = "generic_file_readv" |
4288 | + retstr = sprintf("%d", $return) |
4289 | + |
4290 | + bytes_read = $return > 0 ? $return : 0 |
4291 | + error = $return < 0 ? $return : 0 |
4292 | + error_str = error ? errno_str(error) : "" |
4293 | + |
4294 | + if ($return > 0) { |
4295 | + size = $return |
4296 | + units = "bytes" |
4297 | + } |
4298 | +} |
4299 | + |
4300 | +/* calls __generic_file_write_nolock */ |
4301 | +probe generic.fop.writev = kernel.function("generic_file_writev") ? |
4302 | +{ |
4303 | + dev = __file_dev($file) |
4304 | + devname = __find_bdevname(dev, __file_bdev($file)) |
4305 | + ino = __file_ino($file) |
4306 | + file = $file |
4307 | + |
4308 | + nr_segs = $nr_segs |
4309 | + pos = kernel_pointer($ppos) |
4310 | + |
4311 | + name = "generic_file_writev" |
4312 | + argstr = sprintf("%d, %d", $nr_segs, pos) |
4313 | + |
4314 | + size = nr_segs |
4315 | + units = "segs" |
4316 | +} |
4317 | +probe generic.fop.writev.return = |
4318 | + kernel.function("generic_file_writev").return ? |
4319 | +{ |
4320 | + file = $file |
4321 | + name = "generic_file_writev" |
4322 | + retstr = sprintf("%d", $return) |
4323 | + |
4324 | + bytes_written = $return > 0 ? $return : 0 |
4325 | + error = $return < 0 ? $return : 0 |
4326 | + error_str = error ? errno_str(error) : "" |
4327 | + |
4328 | + if ($return > 0) { |
4329 | + size = $return |
4330 | + units = "bytes" |
4331 | + } |
4332 | +} |
4333 | + |
4334 | +/* checks for aops->readpage, if not defined, return -ENOEXEC |
4335 | + else assigns generic_file_vm_ops to vma |
4336 | + add filemap_nopage, filemap_populate */ |
4337 | +probe generic.fop.mmap = kernel.function("generic_file_mmap") |
4338 | +{ |
4339 | + file = $file |
4340 | + dev = __file_dev($file) |
4341 | + devname = __find_bdevname(dev, __file_bdev($file)) |
4342 | + ino = __file_ino($file) |
4343 | + |
4344 | + vm_start = $vma->vm_start |
4345 | + vm_end = $vma->vm_end |
4346 | + vm_flags = $vma->vm_flags |
4347 | + |
4348 | + name = "generic_file_mmap" |
4349 | + argstr = sprintf("0x%x, 0x%x, 0x%x", $vma->vm_start, |
4350 | + $vma->vm_end, $vma->vm_flags) |
4351 | +} |
4352 | +probe generic.fop.mmap.return = kernel.function("generic_file_mmap").return |
4353 | +{ |
4354 | + file = $file |
4355 | + name = "generic_file_mmap" |
4356 | + retstr = sprintf("%d", $return) |
4357 | + |
4358 | + error = $return < 0 ? $return : 0 |
4359 | + error_str = error ? errno_str(error) : "" |
4360 | +} |
4361 | + |
4362 | +probe generic.fop.open = kernel.function("generic_file_open") |
4363 | +{ |
4364 | + dev = __file_dev($filp) |
4365 | + devname = __find_bdevname(dev, __file_bdev($filp)) |
4366 | + ino = $inode->i_ino |
4367 | + file = $filp |
4368 | + |
4369 | + filename = __file_filename($filp) |
4370 | + flag = $filp->f_flags |
4371 | + size = $inode->i_size |
4372 | + |
4373 | + name = "generic_file_open" |
4374 | + argstr = sprintf("%d, %d, %s", $inode->i_ino, $filp->f_flags, filename) |
4375 | +} |
4376 | +probe generic.fop.open.return = kernel.function("generic_file_open").return |
4377 | +{ |
4378 | + name = "generic_file_open" |
4379 | + retstr = sprintf("%d", $return) |
4380 | +} |
4381 | + |
4382 | +probe generic.fop.sendfile = kernel.function("generic_file_sendfile") ? |
4383 | +{ |
4384 | + dev = __file_dev($in_file) |
4385 | + devname = __find_bdevname($in_file, __file_bdev($in_file)) |
4386 | + ino = __file_ino($in_file) |
4387 | + file = $in_file |
4388 | + |
4389 | + count = $count |
4390 | + ppos = $ppos |
4391 | + |
4392 | + name = "generic_file_sendfile" |
4393 | + argstr = sprintf("%d", $count) |
4394 | + |
4395 | + size = $count |
4396 | + units = "bytes" |
4397 | +} |
4398 | +probe generic.fop.sendfile.return = |
4399 | + kernel.function("generic_file_sendfile").return ? |
4400 | +{ |
4401 | + name = "generic_file_sendfile" |
4402 | + retstr = sprintf("%d", $return) |
4403 | + |
4404 | + if ($return > 0) { |
4405 | + size = $return |
4406 | + units = "bytes" |
4407 | + } |
4408 | +} |
4409 | + |
4410 | +probe generic.fop.splice_read = kernel.function("generic_file_splice_read") ? |
4411 | +{ |
4412 | + dev = __file_dev($in) |
4413 | + devname = __find_bdevname(dev, __file_bdev($in)) |
4414 | + ino = __file_ino($in) |
4415 | + file = $in |
4416 | + dev_major = MAJOR(dev) |
4417 | + dev_minor = MINOR(dev) |
4418 | + |
4419 | + len = $len |
4420 | + flags = $flags |
4421 | + |
4422 | + name = "generic_file_splice_read" |
4423 | + argstr = sprintf("%d, %x", $len, $flags) |
4424 | + |
4425 | + size = $len |
4426 | + units = "bytes" |
4427 | +} |
4428 | +probe generic.fop.splice_read.return = |
4429 | + kernel.function("generic_file_splice_read").return ? |
4430 | +{ |
4431 | + name = "generic_file_splice_read" |
4432 | + retstr = sprintf("%d", $return) |
4433 | + file = $in |
4434 | + ino = __file_ino($in) |
4435 | + dev = __file_dev($in) |
4436 | + dev_major = MAJOR(dev) |
4437 | + dev_minor = MINOR(dev) |
4438 | + |
4439 | + ret = $return |
4440 | + error = $return < 0 ? $return : 0 |
4441 | + error_str = error ? errno_str(error) : "" |
4442 | + |
4443 | + if ($return > 0) { |
4444 | + size = $return |
4445 | + units = "bytes" |
4446 | + } |
4447 | +} |
4448 | + |
4449 | +probe generic.fop.splice_write = kernel.function("generic_file_splice_write") ? |
4450 | +{ |
4451 | + dev = __file_dev($out) |
4452 | + devname = __find_bdevname(dev, __file_bdev($out)) |
4453 | + ino = __file_ino($out) |
4454 | + file = $out |
4455 | + |
4456 | + len = $len |
4457 | + flags = $flags |
4458 | + |
4459 | + name = "generic_file_splice_write" |
4460 | + argstr = sprintf("%d, %x", $len, $flags) |
4461 | + |
4462 | + size = $len |
4463 | + units = "bytes" |
4464 | +} |
4465 | +probe generic.fop.splice_write.return = |
4466 | + kernel.function("generic_file_splice_write").return ? |
4467 | +{ |
4468 | + name = "generic_file_splice_write" |
4469 | + retstr = sprintf("%d", $return) |
4470 | + |
4471 | + file = $out |
4472 | + |
4473 | + error = $return < 0 ? $return : 0 |
4474 | + error_str = error ? errno_str(error) : "" |
4475 | + |
4476 | + if (error) { |
4477 | + size = $return |
4478 | + units = "bytes" |
4479 | + } |
4480 | +} |
4481 | + |
4482 | +probe generic.fop.read = kernel.function("generic_file_read") ? |
4483 | +{ |
4484 | + dev = __file_dev($filp) |
4485 | + devname = __find_bdevname(dev, __file_bdev($filp)) |
4486 | + ino = __file_ino($filp) |
4487 | + file = $filp |
4488 | + |
4489 | + count = $count |
4490 | + |
4491 | + name = "generic_file_read" |
4492 | + argstr = sprintf("%d", $count) |
4493 | + |
4494 | + size = $count |
4495 | + units = "bytes" |
4496 | +} |
4497 | +probe generic.fop.read.return = kernel.function("generic_file_read").return ? |
4498 | +{ |
4499 | + name = "generic_file_read" |
4500 | + retstr = sprintf("%d", $return) |
4501 | + |
4502 | + if ($return > 0) { |
4503 | + size = $return |
4504 | + units = "bytes" |
4505 | + } |
4506 | +} |
4507 | + |
4508 | +probe generic.fop.write = kernel.function("generic_file_write") ? |
4509 | +{ |
4510 | + dev = __file_dev($file) |
4511 | + devname = __find_bdevname(dev, __file_bdev($file)) |
4512 | + ino = __file_ino($file) |
4513 | + file = $file |
4514 | + |
4515 | + count = $count |
4516 | + |
4517 | + name = "generic_file_write" |
4518 | + argstr = sprintf("%d", $count) |
4519 | + |
4520 | + size = $count |
4521 | + units = "bytes" |
4522 | +} |
4523 | +probe generic.fop.write.return = kernel.function("generic_file_write").return ? |
4524 | +{ |
4525 | + name = "generic_file_write" |
4526 | + retstr = sprintf("%d", $return) |
4527 | + |
4528 | + if ($return > 0) { |
4529 | + size = $return |
4530 | + units = "bytes" |
4531 | + } |
4532 | +} |
4533 | + |
4534 | +/* generic_writepages calls mpage_writepages(mapping, wbc, NULL) */ |
4535 | +probe generic.aop.writepages = kernel.function("mpage_writepages") |
4536 | +{ |
4537 | + dev = $mapping->host->i_sb->s_dev |
4538 | + devname = __find_bdevname(dev, $mapping->host->i_sb->s_bdev) |
4539 | + ino = $mapping->host->i_ino |
4540 | + |
4541 | + nr_to_write = $wbc->nr_to_write |
4542 | + |
4543 | + name = "generic_writepages" |
4544 | + argstr = sprintf("%d", $wbc->nr_to_write) |
4545 | + |
4546 | + size = $wbc->nr_to_write |
4547 | + units = "pages" |
4548 | +} |
4549 | +probe generic.aop.writepages.return = kernel.function("mpage_writepages").return |
4550 | +{ |
4551 | + name = "generic_writepages" |
4552 | + retstr = sprintf("%d", $return) |
4553 | +} |
4554 | + |
4555 | +probe vfs.do_sync_read = kernel.function("do_sync_read") |
4556 | +{ |
4557 | + dev = __file_dev($filp) |
4558 | + devname = __find_bdevname(dev, __file_bdev($filp)) |
4559 | + ino = __file_ino($filp) |
4560 | + file = $filp |
4561 | + |
4562 | + len = $len |
4563 | + pos = kernel_pointer($ppos) |
4564 | + buf = $buf |
4565 | + |
4566 | + name = "do_sync_read" |
4567 | + argstr = sprintf("%d, %d, %p", $len, pos, $buf) |
4568 | + |
4569 | + size = $len |
4570 | + units = "bytes" |
4571 | + bytes_to_read = $len |
4572 | +} |
4573 | +probe vfs.do_sync_read.return = kernel.function("do_sync_read").return |
4574 | +{ |
4575 | + name = "do_sync_read" |
4576 | + retstr = sprintf("%d", $return) |
4577 | + |
4578 | + bytes_to_read = $len |
4579 | + ret = $return |
4580 | + bytes_read = $return > 0 ? $return : 0 |
4581 | + error = $return < 0 ? $return : 0 |
4582 | + error_str = error ? errno_str(error) : "" |
4583 | + |
4584 | + if ($return > 0) { |
4585 | + size = $return |
4586 | + units = "bytes" |
4587 | + } |
4588 | +} |
4589 | + |
4590 | +probe vfs.do_sync_write = kernel.function("do_sync_write") |
4591 | +{ |
4592 | + dev = __file_dev($filp) |
4593 | + devname = __find_bdevname(dev, __file_bdev($filp)) |
4594 | + ino = __file_ino($filp) |
4595 | + file = $filp |
4596 | + |
4597 | + len = $len |
4598 | + pos = kernel_pointer($ppos) |
4599 | + buf = $buf |
4600 | + bytes_to_write = $len |
4601 | + |
4602 | + name = "do_sync_write" |
4603 | + argstr = sprintf("%d, %d , %p", $len, pos, $buf) |
4604 | + |
4605 | + size = $len |
4606 | + units = "bytes" |
4607 | +} |
4608 | +probe vfs.do_sync_write.return = kernel.function("do_sync_write").return |
4609 | +{ |
4610 | + name = "do_sync_write" |
4611 | + retstr = sprintf("%d", $return) |
4612 | + |
4613 | + bytes_to_write = $len |
4614 | + pos = kernel_pointer($ppos) |
4615 | + ret = $return |
4616 | + bytes_written = $return > 0 ? $return : 0 |
4617 | + error = $return < 0 ? $return : 0 |
4618 | + error_str = error ? errno_str(error) : "" |
4619 | + |
4620 | + if (error) { |
4621 | + size = $return |
4622 | + units = "bytes" |
4623 | + } |
4624 | +} |
4625 | + |
4626 | +probe vfs.block_sync_page = kernel.function("block_sync_page") |
4627 | +{ |
4628 | + dev = __page_dev($page) |
4629 | + devname = __find_bdevname(dev, __page_bdev($page)) |
4630 | + ino = __page_ino($page) |
4631 | + |
4632 | + # 'page_index' is deprecated |
4633 | + page_index = __page_index($page) |
4634 | + index = __page_index($page) |
4635 | + |
4636 | + name = "block_sync_page" |
4637 | + argstr = sprintf("%d", index) |
4638 | + |
4639 | + size = 1 |
4640 | + units = "pages" |
4641 | +} |
4642 | +probe vfs.block_sync_page.return = kernel.function("block_sync_page").return |
4643 | +{ |
4644 | + name = "block_sync_page" |
4645 | + retstr = sprintf("N/A") |
4646 | +} |
4647 | + |
4648 | +probe vfs.buffer_migrate_page = kernel.function("buffer_migrate_page") ? |
4649 | +{ |
4650 | + dev = __page_dev($page) |
4651 | + ino = __page_ino($page) |
4652 | + devname = __find_bdevname(dev,__page_bdev($page)) |
4653 | + |
4654 | + # 'page_index' is deprecated |
4655 | + page_index = __page_index($page) |
4656 | + index = __page_index($page) |
4657 | + |
4658 | + name = "buffer_migrate_page" |
4659 | + argstr = sprintf("%d", index) |
4660 | + |
4661 | + size = 1 |
4662 | + units = "pages" |
4663 | +} |
4664 | +probe vfs.buffer_migrate_page.return = |
4665 | + kernel.function("buffer_migrate_page").return ? |
4666 | +{ |
4667 | + name = "buffer_migrate_page" |
4668 | + retstr = sprintf("%d", $return) |
4669 | + |
4670 | + if ($return == 0) { |
4671 | + size = 1 |
4672 | + units = "pages" |
4673 | + } |
4674 | +} |
4675 | + |
4676 | +/* default if aop not set, __set_page_dirty_nobuffers usually used if set */ |
4677 | +probe vfs.__set_page_dirty_buffers = kernel.function("__set_page_dirty_buffers") |
4678 | +{ |
4679 | + dev = __page_dev($page) |
4680 | + devname = __find_bdevname(dev, __page_bdev($page)) |
4681 | + ino = __page_ino($page) |
4682 | + |
4683 | + index = __page_index($page) |
4684 | + |
4685 | + name = "__set_page_dirty_buffers" |
4686 | + argstr = sprintf("%d", index) |
4687 | + |
4688 | + size = 1 |
4689 | + units = "pages" |
4690 | +} |
4691 | +probe vfs.__set_page_dirty_buffers.return = |
4692 | + kernel.function("__set_page_dirty_buffers").return |
4693 | +{ |
4694 | + name = "__set_page_dirty_buffers" |
4695 | + retstr = sprintf("%d", $return) |
4696 | + |
4697 | +%( kernel_v >= "2.6.17" %? |
4698 | + if ($return == 1) |
4699 | +%: |
4700 | + if ($return == 0) |
4701 | +%) |
4702 | + { |
4703 | + size = 1 |
4704 | + units = "pages" |
4705 | + } |
4706 | +} |
4707 | + |
4708 | +probe vfs.do_mpage_readpage = kernel.function("do_mpage_readpage") |
4709 | +{ |
4710 | + dev = __page_dev($page) |
4711 | + devname = __find_bdevname(dev, __page_bdev($page)) |
4712 | + ino = __page_ino($page) |
4713 | + |
4714 | + index = __page_index($page) |
4715 | + |
4716 | + name = "do_mpage_readpage" |
4717 | + argstr = sprintf("%d", index) |
4718 | + |
4719 | + size = 1 |
4720 | + units = "pages" |
4721 | +} |
4722 | +probe vfs.do_mpage_readpage.return = kernel.function("do_mpage_readpage").return |
4723 | +{ |
4724 | + name = "do_mpage_readpage" |
4725 | + retstr = sprintf("0x%x", $return) |
4726 | + |
4727 | + size = 1 |
4728 | + units = "pages" |
4729 | +} |
4730 | + |
4731 | +probe vfs.add_to_page_cache = |
4732 | + kernel.function("add_to_page_cache_locked") !, |
4733 | + kernel.function("add_to_page_cache") |
4734 | +{ |
4735 | + dev = $mapping->host->i_sb->s_dev |
4736 | + devname = __find_bdevname(dev, $mapping->host->i_sb->s_bdev) |
4737 | + ino = $mapping->host->i_ino |
4738 | + |
4739 | + index = $offset |
4740 | + nrpages = $mapping->nrpages |
4741 | + size = $mapping->nrpages |
4742 | + units = "pages" |
4743 | + |
4744 | + name = "vfs.add_to_page_cache" |
4745 | + argstr = sprintf("%d, %d", ino, $offset) |
4746 | +} |
4747 | + |
4748 | +probe vfs.add_to_page_cache.return = |
4749 | + kernel.function("add_to_page_cache_locked").return !, |
4750 | + kernel.function("add_to_page_cache").return |
4751 | +{ |
4752 | + name = "vfs.add_to_page_cache" |
4753 | + retstr = sprintf("%d", $return) |
4754 | + |
4755 | + if ($return == 0) { |
4756 | + size = 1 |
4757 | + units = "pages" |
4758 | + } |
4759 | +} |
4760 | + |
4761 | +probe vfs.remove_from_page_cache = kernel.function("__remove_from_page_cache") |
4762 | +{ |
4763 | + dev = __page_dev($page) |
4764 | + devname = __find_bdevname(dev, __page_bdev($page)) |
4765 | + ino = __page_ino($page) |
4766 | + |
4767 | + index = __page_index($page) |
4768 | + |
4769 | + name = "vfs.remove_from_page_cache" |
4770 | + argstr = sprintf("%d", ino) |
4771 | +} |
4772 | +probe vfs.remove_from_page_cache.return = |
4773 | + kernel.function("__remove_from_page_cache").return |
4774 | +{ |
4775 | + name = "vfs.remove_from_page_cache" |
4776 | + retstr = sprintf("N/A") |
4777 | +} |
4778 | + |
4779 | +probe vfs.read = kernel.function("vfs_read") |
4780 | +{ |
4781 | + file = $file |
4782 | + pos = $pos |
4783 | + buf = $buf |
4784 | + bytes_to_read = $count |
4785 | + dev = __file_dev($file) |
4786 | + devname = __find_bdevname(dev, __file_bdev($file)) |
4787 | + ino = __file_ino($file) |
4788 | + |
4789 | + name = "vfs.read" |
4790 | + argstr = sprintf("%d, %d, %p", $count, $pos, $buf) |
4791 | +} |
4792 | + |
4793 | +probe vfs.read.return = kernel.function("vfs_read").return |
4794 | +{ |
4795 | + name = "vfs.read" |
4796 | + retstr = sprintf("%d", $return) |
4797 | + |
4798 | + file = $file |
4799 | + pos = $pos |
4800 | + buf = $buf |
4801 | + bytes_to_read = $count |
4802 | + dev = __file_dev($file) |
4803 | + devname = __find_bdevname(dev, __file_bdev($file)) |
4804 | + ino = __file_ino($file) |
4805 | + |
4806 | + ret = $return |
4807 | + bytes_read = $return > 0 ? $return : 0 |
4808 | + error = $return < 0 ? $return : 0 |
4809 | + error_str = error ? errno_str(error) : "" |
4810 | +} |
4811 | + |
4812 | +probe vfs.readv = kernel.function("vfs_readv") |
4813 | +{ |
4814 | + file = $file |
4815 | + dev = __file_dev($file) |
4816 | + devname = __find_bdevname(dev, __file_bdev($file)) |
4817 | + ino = __file_ino($file) |
4818 | + pos = $pos |
4819 | + vec = $vec |
4820 | + vlen = $vlen |
4821 | + bytes_to_read = _get_fopv_size($vec, $vlen) |
4822 | + |
4823 | + name = "vfs.read" |
4824 | + argstr = sprintf("%d, %d, %p", bytes_to_read, $pos, $vec) |
4825 | +} |
4826 | + |
4827 | +probe vfs.readv.return = kernel.function("vfs_readv").return |
4828 | +{ |
4829 | + name = "vfs.readv" |
4830 | + retstr = sprintf("%d", $return) |
4831 | + |
4832 | + file = $file |
4833 | + dev = __file_dev($file) |
4834 | + devname = __find_bdevname(dev, __file_bdev($file)) |
4835 | + ino = __file_ino($file) |
4836 | + pos = $pos |
4837 | + vec = $vec |
4838 | + vlen = $vlen |
4839 | + bytes_to_read = _get_fopv_size($vec, $vlen) |
4840 | + |
4841 | + ret = $return |
4842 | + bytes_read = $return > 0 ? $return : 0 |
4843 | + error = $return < 0 ? $return : 0 |
4844 | + error_str = error ? errno_str(error) : "" |
4845 | +} |
4846 | + |
4847 | +probe vfs.write = kernel.function("vfs_write") |
4848 | +{ |
4849 | + file = $file |
4850 | + pos = $pos |
4851 | + buf = $buf |
4852 | + bytes_to_write = $count |
4853 | + dev = __file_dev($file) |
4854 | + devname = __find_bdevname(dev, __file_bdev($file)) |
4855 | + ino = __file_ino($file) |
4856 | + |
4857 | + name = "vfs.write" |
4858 | + argstr = sprintf("%d, %d, %p", $count, $pos, $buf) |
4859 | +} |
4860 | + |
4861 | +probe vfs.write.return = kernel.function("vfs_write").return |
4862 | +{ |
4863 | + name = "vfs.write" |
4864 | + retstr = sprintf("%d", $return) |
4865 | + |
4866 | + file = $file |
4867 | + pos = $pos |
4868 | + buf = $buf |
4869 | + bytes_to_write = $count |
4870 | + dev = __file_dev($file) |
4871 | + devname = __find_bdevname(dev, __file_bdev($file)) |
4872 | + ino = __file_ino($file) |
4873 | + |
4874 | + ret = $return |
4875 | + bytes_written = $return > 0 ? $return : 0 |
4876 | + error = $return < 0 ? $return : 0 |
4877 | + error_str = error ? errno_str(error) : "" |
4878 | +} |
4879 | + |
4880 | +probe vfs.writev = kernel.function("vfs_writev") |
4881 | +{ |
4882 | + file = $file |
4883 | + dev = __file_dev($file) |
4884 | + devname = __find_bdevname(dev, __file_bdev($file)) |
4885 | + ino = __file_ino($file) |
4886 | + pos = $pos |
4887 | + vlen = $vlen |
4888 | + vec = $vec |
4889 | + bytes_to_write = _get_fopv_size($vec, $vlen) |
4890 | + |
4891 | + name = "vfs.writev" |
4892 | + argstr = sprintf("%d, %d, %p", bytes_to_write, $pos, $vec) |
4893 | +} |
4894 | + |
4895 | +probe vfs.writev.return = kernel.function("vfs_writev").return |
4896 | +{ |
4897 | + name = "vfs.writev" |
4898 | + retstr = sprintf("%d", $return) |
4899 | + |
4900 | + file = $file |
4901 | + dev = __file_dev($file) |
4902 | + devname = __find_bdevname(dev, __file_bdev($file)) |
4903 | + ino = __file_ino($file) |
4904 | + pos = $pos |
4905 | + vlen = $vlen |
4906 | + vec = $vec |
4907 | + bytes_to_write = _get_fopv_size($vec, $vlen) |
4908 | + |
4909 | + ret = $return |
4910 | + bytes_written = $return > 0 ? $return : 0 |
4911 | + error = $return < 0 ? $return : 0 |
4912 | + error_str = error ? errno_str(error) : "" |
4913 | +} |
4914 | + |
4915 | +probe _vfs.generic_file_readonly_mmap = |
4916 | + kernel.function("generic_file_readonly_mmap") |
4917 | +{ |
4918 | + file = $file |
4919 | + vma = $vma |
4920 | + |
4921 | + name = "_vfs.generic_file_readonly_mmap" |
4922 | + argstr = sprintf("%p, %p", $file, $vma) |
4923 | +} |
4924 | + |
4925 | +probe _vfs.generic_file_readonly_mmap.return = |
4926 | + kernel.function("generic_file_readonly_mmap").return |
4927 | +{ |
4928 | + name = "_vfs.generic_file_readonly_mmap" |
4929 | + retstr = sprintf("%d", $return) |
4930 | + |
4931 | + file = $file |
4932 | + vma = $vma |
4933 | + |
4934 | + ret = $return |
4935 | + error = $return < 0 ? $return : 0 |
4936 | + error_str = error ? errno_str(error) : "" |
4937 | +} |
4938 | + |
4939 | +probe _vfs.generic_block_bmap = kernel.function("generic_block_bmap") |
4940 | +{ |
4941 | + mapping = $mapping |
4942 | + block = $block |
4943 | + get_block = $get_block |
4944 | + |
4945 | + name = "_vfs.generic_block_bmap" |
4946 | + argstr = sprintf("%p, %p, %p", $mapping, $block, $get_block) |
4947 | +} |
4948 | + |
4949 | +probe _vfs.generic_commit_write = kernel.function("generic_commit_write") ? |
4950 | +{ |
4951 | + file = $file |
4952 | + page = $page |
4953 | + from = $from |
4954 | + to = $to |
4955 | + |
4956 | + name = "_vfs.generic_commit_write" |
4957 | + argstr = sprintf("%p, %p, %d, %d", $file, $page, $from, $to) |
4958 | +} |
4959 | + |
4960 | +probe _vfs.block_prepare_write = kernel.function("__block_prepare_write") |
4961 | +{ |
4962 | + _inode = $inode |
4963 | + page = $page |
4964 | + # write_from and write_upto are deprecated |
4965 | + write_from = $from |
4966 | + write_upto = $to |
4967 | + from = $from |
4968 | + to = $to |
4969 | + |
4970 | + name = "_vfs.generic_commit_write" |
4971 | + argstr = sprintf("%p, %d, %d", $page, $from, $to) |
4972 | +} |
4973 | + |
4974 | +probe _vfs.block_prepare_write.return = |
4975 | + kernel.function("__block_prepare_write").return |
4976 | +{ |
4977 | + name = "_vfs.block_prepare_write" |
4978 | + retstr = sprintf("%d", $return) |
4979 | + |
4980 | + _inode = $inode |
4981 | + page = $page |
4982 | + # write_from and write_upto are deprecated |
4983 | + write_from = $from |
4984 | + write_upto = $to |
4985 | + from = $from |
4986 | + to = $to |
4987 | + |
4988 | + ret = $return |
4989 | + error = ret < 0 ? ret : 0 |
4990 | + error_str = error ? errno_str(error) : "" |
4991 | +} |
4992 | + |
4993 | +probe _vfs.block_write_begin = kernel.function("block_write_begin") ? |
4994 | +{ |
4995 | + file = $file |
4996 | + pos = $pos |
4997 | + len = $len |
4998 | + flags = $flags |
4999 | + |
5000 | + _inode = __address_inode($mapping) |
The diff has been truncated for viewing.