summaryrefslogtreecommitdiffstats
path: root/tapset/LKET/aio.stp
blob: d5e3625d7be44ce79a8482e71b38b9197b39d8d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
// AIO tapset
// Copyright (C) 2006 IBM Corp.
//
// This file is part of systemtap, and is free software.  You can
// redistribute it and/or modify it under the terms of the GNU General
// Public License (GPL); either version 2, or (at your option) any
// later version.

/*
 * the following aio related probes are used to probe those aio related
 * calls inside the kernel. They are: sys_io_setup, sys_io_submit, 
 * sys_io_getevents, sys_io_destroy, sys_io_cancel, io_submit_one
 */

probe addevent.aio
	= addevent.aio.entry, addevent.aio.return
{}

probe addevent.aio.entry
	=
	addevent.aio.io_setup.entry,
	addevent.aio.io_submit.entry,
	addevent.aio.io_submit_one.entry,
	addevent.aio.io_destroy.entry,
	addevent.aio.io_getevents.entry,
	addevent.aio.io_cancel.entry
{}

probe addevent.aio.return
	=
	addevent.aio.io_setup.return,
	addevent.aio.io_submit.return,
	addevent.aio.io_submit_one.return,
	addevent.aio.io_destroy.return,
	addevent.aio.io_getevents.return,
	addevent.aio.io_cancel.return
{}

/* 
 *  Fires by calling io_setup from user space. The corresponding
 *  system call is sys_io_setup, which will create an aio_context 
 *  capable of receiving at least maxevents.
 */
probe addevent.aio.io_setup.entry
	+= _addevent.aio.io_setup.entry
{
	update_record()
}

probe _addevent.aio.io_setup.entry
	= syscall.io_setup
{
	log_aio_setup(HOOKID_AIO_IO_SETUP_ENTRY, maxevents, ctxp_uaddr)
}

function log_aio_setup(hookid:long, nr_events:long, ctxp_uaddr:long)
%{
	/* nr_events|ctxp_uaddr */
	_lket_trace(_GROUP_AIO, THIS->hookid, "%4b%8b", 
		THIS->nr_events, THIS->ctxp_uaddr);
%}

probe addevent.aio.io_setup.return
        += _addevent.aio.io_setup.return
{
        update_record()
}

probe _addevent.aio.io_setup.return
        = kernel.function("sys_io_setup").return
{
        log_aio_return(HOOKID_AIO_IO_SETUP_RETURN, $return)
}

function log_aio_return(hookid:long, retval:long)
%{
	_lket_trace(_GROUP_AIO, THIS->hookid, "%8b", THIS->retval);
%}

/*
 * Fired by calling io_submit from user space. The corresponding  
 * system call is sys_io_submit which will queue the nr iocbs 
 * pointed to by iocbpp_uaddr for processing.
 */
probe addevent.aio.io_submit.entry
	+= _addevent.aio.io_submit.entry
{
	update_record()
}

probe _addevent.aio.io_submit.entry
	= syscall.io_submit
{
	log_aio_submit(HOOKID_AIO_IO_SUBMIT_ENTRY, ctx_id, nr, iocbpp_uaddr)
}

function log_aio_submit(hookid:long, ctx_id:long, nr:long, iocbpp_uaddr:long)
%{
	/* ctx_id | no_iocbs | iocbpp */
	_lket_trace(_GROUP_AIO, THIS->hookid, "%8b%4b%8b", 
		THIS->ctx_id, THIS->nr, THIS->iocbpp_uaddr);
%}

probe addevent.aio.io_submit.return
	+= _addevent.aio.io_submit.return
{
	update_record()
}

probe _addevent.aio.io_submit.return
	= syscall.io_submit.return
{
	log_aio_return(HOOKID_AIO_IO_SUBMIT_RETURN, $return)	
}

/* Called by sys_io_submit, will iterate iocbpp and process them
 * one by one
 */
probe addevent.aio.io_submit_one.entry
	+= _addevent.aio.io_submit_one.entry
{
	update_record()
}


probe _addevent.aio.io_submit_one.entry
	= kernel.function("io_submit_one")
{
	log_io_submit_one(HOOKID_AIO_IO_SUBMIT_ONE_ENTRY, $ctx, $user_iocb)	
}

function log_io_submit_one(hookid:long, ctx:long, user_iocb_uaddr:long)
%{
	struct iocb *user_iocb = (struct iocb *)((long)THIS->user_iocb_uaddr);

	/* ctx | user_iocb_addr | aio_lio_opcode | >aio_reqprio |
		aio_fildes | aio_buf | aio_nbytes | >aio_offset */
	_lket_trace(_GROUP_AIO, THIS->hookid, 
		"%8b%8b%2b%2b%4b%8b%8b%8b", 
		THIS->ctx, THIS->user_iocb_uaddr, (_FMT_)user_iocb->aio_lio_opcode, 
		(_FMT_)user_iocb->aio_reqprio, (_FMT_)user_iocb->aio_fildes, 
		(_FMT_)user_iocb->aio_buf, (_FMT_)user_iocb->aio_nbytes, 
		(_FMT_)user_iocb->aio_offset);
%}

probe addevent.aio.io_submit_one.return
	+= _addevent.aio.io_submit_one.return
{
	update_record()
}

probe _addevent.aio.io_submit_one.return
	= kernel.function("io_submit_one").return
{
	log_aio_return(HOOKID_AIO_IO_SUBMIT_ONE_RETURN, $return)
}

/*
 * Fired by calling io_destroy from user space. The corresponding 
 * system call is sys_io_destroy, which will destroy the aio_context 
 * specified.
 */
probe addevent.aio.io_destroy.entry
	+= _addevent.aio.io_destroy.entry
{
	update_record()
}

probe _addevent.aio.io_destroy.entry
	= syscall.io_destroy
{
	log_io_destroy(HOOKID_AIO_IO_DESTROY_ENTRY, ctx)
}

function log_io_destroy(hookid:long, ctx:long)
%{
	_lket_trace(_GROUP_AIO, THIS->hookid, "%8b", THIS->ctx);
%}


probe addevent.aio.io_destroy.return
        += _addevent.aio.io_destroy.return
{
        update_record()
}

probe _addevent.aio.io_destroy.return
        = syscall.io_destroy.return
{
        log_aio_return(HOOKID_AIO_IO_DESTROY_RETURN, $return)
}

/*
 * Fired by calling io_getevents from user space. The corresponding 
 * system call is sys_io_getevents, which will attempt to read at 
 * least min_nr events and up to nr events from the completion queue 
 * for the aio_context specified by ctx_id.
 */
probe addevent.aio.io_getevents.entry
        += _addevent.aio.io_getevents.entry
{
        update_record()
}

probe _addevent.aio.io_getevents.entry
        = syscall.io_getevents
{
	log_io_getevents(HOOKID_AIO_IO_GETEVENTS_ENTRY, ctx_id, 
		min_nr, nr, events_uaddr, timeout_uaddr)
}

function log_io_getevents(hookid:long, ctx_id:long, min_nr:long, nr:long, 
		events_uaddr:long, timeout:long)
%{
	struct timespec __user *timeout = (struct timespec *)((long)THIS->timeout);
	struct timespec ts;

	if (unlikely(copy_from_user(&ts, timeout, sizeof(ts))))
		return;

	_lket_trace(_GROUP_AIO, THIS->hookid,
		"%8b%4b%4b%8b%4b%4b", THIS->ctx_id, THIS->min_nr,
		THIS->nr, THIS->events_uaddr, (_FMT_)ts.tv_sec, 
		(_FMT_)ts.tv_nsec);
%}

probe addevent.aio.io_getevents.return
        += _addevent.aio.io_getevents.return
{
        update_record()
}

probe _addevent.aio.io_getevents.return
        = syscall.io_getevents.return
{
        log_aio_return(HOOKID_AIO_IO_GETEVENTS_RETURN, $return)
}

/* 
 * Fired by calling io_cancel from user space. The corresponding
 * system call is sys_io_cancel, which will attempt to cancel 
 * an iocb previously passed to io_submit.
 */
probe addevent.aio.io_cancel.entry
	+= _addevent.aio.io_cancel.entry
{
	update_record()
}

probe _addevent.aio.io_cancel.entry
	= syscall.io_cancel
{
	log_aio_cancel(HOOKID_AIO_IO_CANCEL_ENTRY, ctx_id, 
		iocb_uaddr, result_uaddr)
}

function log_aio_cancel(hookid:long, ctx_id:long, iocb_uaddr:long, result_uaddr:long)
%{
	_lket_trace(_GROUP_AIO, THIS->hookid, "%8b%8b%8b",
		THIS->ctx_id, THIS->iocb_uaddr, THIS->result_uaddr);
%}

probe addevent.aio.io_cancel.return
	+= _addevent.aio.io_cancel.return
{
	update_record()
}

probe _addevent.aio.io_cancel.return
	= syscall.io_cancel.return
{
	log_aio_return(HOOKID_AIO_IO_CANCEL_RETURN, $return)
}