diff options
Diffstat (limited to 'kernel/trace/kmemtrace.c')
-rw-r--r-- | kernel/trace/kmemtrace.c | 120 |
1 files changed, 90 insertions, 30 deletions
diff --git a/kernel/trace/kmemtrace.c b/kernel/trace/kmemtrace.c index 1edaa9516e81..74903b62bcb6 100644 --- a/kernel/trace/kmemtrace.c +++ b/kernel/trace/kmemtrace.c | |||
@@ -239,12 +239,52 @@ struct kmemtrace_user_event_alloc { | |||
239 | }; | 239 | }; |
240 | 240 | ||
241 | static enum print_line_t | 241 | static enum print_line_t |
242 | kmemtrace_print_alloc_user(struct trace_iterator *iter, | 242 | kmemtrace_print_alloc_user(struct trace_iterator *iter, int flags) |
243 | struct kmemtrace_alloc_entry *entry) | 243 | { |
244 | struct trace_seq *s = &iter->seq; | ||
245 | struct kmemtrace_alloc_entry *entry; | ||
246 | int ret; | ||
247 | |||
248 | trace_assign_type(entry, iter->ent); | ||
249 | |||
250 | ret = trace_seq_printf(s, "type_id %d call_site %pF ptr %lu " | ||
251 | "bytes_req %lu bytes_alloc %lu gfp_flags %lu node %d\n", | ||
252 | entry->type_id, (void *)entry->call_site, (unsigned long)entry->ptr, | ||
253 | (unsigned long)entry->bytes_req, (unsigned long)entry->bytes_alloc, | ||
254 | (unsigned long)entry->gfp_flags, entry->node); | ||
255 | |||
256 | if (!ret) | ||
257 | return TRACE_TYPE_PARTIAL_LINE; | ||
258 | return TRACE_TYPE_HANDLED; | ||
259 | } | ||
260 | |||
261 | static enum print_line_t | ||
262 | kmemtrace_print_free_user(struct trace_iterator *iter, int flags) | ||
244 | { | 263 | { |
245 | struct kmemtrace_user_event_alloc *ev_alloc; | ||
246 | struct trace_seq *s = &iter->seq; | 264 | struct trace_seq *s = &iter->seq; |
265 | struct kmemtrace_free_entry *entry; | ||
266 | int ret; | ||
267 | |||
268 | trace_assign_type(entry, iter->ent); | ||
269 | |||
270 | ret = trace_seq_printf(s, "type_id %d call_site %pF ptr %lu\n", | ||
271 | entry->type_id, (void *)entry->call_site, | ||
272 | (unsigned long)entry->ptr); | ||
273 | |||
274 | if (!ret) | ||
275 | return TRACE_TYPE_PARTIAL_LINE; | ||
276 | return TRACE_TYPE_HANDLED; | ||
277 | } | ||
278 | |||
279 | static enum print_line_t | ||
280 | kmemtrace_print_alloc_user_bin(struct trace_iterator *iter, int flags) | ||
281 | { | ||
282 | struct trace_seq *s = &iter->seq; | ||
283 | struct kmemtrace_alloc_entry *entry; | ||
247 | struct kmemtrace_user_event *ev; | 284 | struct kmemtrace_user_event *ev; |
285 | struct kmemtrace_user_event_alloc *ev_alloc; | ||
286 | |||
287 | trace_assign_type(entry, iter->ent); | ||
248 | 288 | ||
249 | ev = trace_seq_reserve(s, sizeof(*ev)); | 289 | ev = trace_seq_reserve(s, sizeof(*ev)); |
250 | if (!ev) | 290 | if (!ev) |
@@ -271,12 +311,14 @@ kmemtrace_print_alloc_user(struct trace_iterator *iter, | |||
271 | } | 311 | } |
272 | 312 | ||
273 | static enum print_line_t | 313 | static enum print_line_t |
274 | kmemtrace_print_free_user(struct trace_iterator *iter, | 314 | kmemtrace_print_free_user_bin(struct trace_iterator *iter, int flags) |
275 | struct kmemtrace_free_entry *entry) | ||
276 | { | 315 | { |
277 | struct trace_seq *s = &iter->seq; | 316 | struct trace_seq *s = &iter->seq; |
317 | struct kmemtrace_free_entry *entry; | ||
278 | struct kmemtrace_user_event *ev; | 318 | struct kmemtrace_user_event *ev; |
279 | 319 | ||
320 | trace_assign_type(entry, iter->ent); | ||
321 | |||
280 | ev = trace_seq_reserve(s, sizeof(*ev)); | 322 | ev = trace_seq_reserve(s, sizeof(*ev)); |
281 | if (!ev) | 323 | if (!ev) |
282 | return TRACE_TYPE_PARTIAL_LINE; | 324 | return TRACE_TYPE_PARTIAL_LINE; |
@@ -294,12 +336,14 @@ kmemtrace_print_free_user(struct trace_iterator *iter, | |||
294 | 336 | ||
295 | /* The two other following provide a more minimalistic output */ | 337 | /* The two other following provide a more minimalistic output */ |
296 | static enum print_line_t | 338 | static enum print_line_t |
297 | kmemtrace_print_alloc_compress(struct trace_iterator *iter, | 339 | kmemtrace_print_alloc_compress(struct trace_iterator *iter) |
298 | struct kmemtrace_alloc_entry *entry) | ||
299 | { | 340 | { |
341 | struct kmemtrace_alloc_entry *entry; | ||
300 | struct trace_seq *s = &iter->seq; | 342 | struct trace_seq *s = &iter->seq; |
301 | int ret; | 343 | int ret; |
302 | 344 | ||
345 | trace_assign_type(entry, iter->ent); | ||
346 | |||
303 | /* Alloc entry */ | 347 | /* Alloc entry */ |
304 | ret = trace_seq_printf(s, " + "); | 348 | ret = trace_seq_printf(s, " + "); |
305 | if (!ret) | 349 | if (!ret) |
@@ -362,12 +406,14 @@ kmemtrace_print_alloc_compress(struct trace_iterator *iter, | |||
362 | } | 406 | } |
363 | 407 | ||
364 | static enum print_line_t | 408 | static enum print_line_t |
365 | kmemtrace_print_free_compress(struct trace_iterator *iter, | 409 | kmemtrace_print_free_compress(struct trace_iterator *iter) |
366 | struct kmemtrace_free_entry *entry) | ||
367 | { | 410 | { |
411 | struct kmemtrace_free_entry *entry; | ||
368 | struct trace_seq *s = &iter->seq; | 412 | struct trace_seq *s = &iter->seq; |
369 | int ret; | 413 | int ret; |
370 | 414 | ||
415 | trace_assign_type(entry, iter->ent); | ||
416 | |||
371 | /* Free entry */ | 417 | /* Free entry */ |
372 | ret = trace_seq_printf(s, " - "); | 418 | ret = trace_seq_printf(s, " - "); |
373 | if (!ret) | 419 | if (!ret) |
@@ -421,32 +467,31 @@ static enum print_line_t kmemtrace_print_line(struct trace_iterator *iter) | |||
421 | { | 467 | { |
422 | struct trace_entry *entry = iter->ent; | 468 | struct trace_entry *entry = iter->ent; |
423 | 469 | ||
424 | switch (entry->type) { | 470 | if (!(kmem_tracer_flags.val & TRACE_KMEM_OPT_MINIMAL)) |
425 | case TRACE_KMEM_ALLOC: { | 471 | return TRACE_TYPE_UNHANDLED; |
426 | struct kmemtrace_alloc_entry *field; | ||
427 | |||
428 | trace_assign_type(field, entry); | ||
429 | if (kmem_tracer_flags.val & TRACE_KMEM_OPT_MINIMAL) | ||
430 | return kmemtrace_print_alloc_compress(iter, field); | ||
431 | else | ||
432 | return kmemtrace_print_alloc_user(iter, field); | ||
433 | } | ||
434 | |||
435 | case TRACE_KMEM_FREE: { | ||
436 | struct kmemtrace_free_entry *field; | ||
437 | |||
438 | trace_assign_type(field, entry); | ||
439 | if (kmem_tracer_flags.val & TRACE_KMEM_OPT_MINIMAL) | ||
440 | return kmemtrace_print_free_compress(iter, field); | ||
441 | else | ||
442 | return kmemtrace_print_free_user(iter, field); | ||
443 | } | ||
444 | 472 | ||
473 | switch (entry->type) { | ||
474 | case TRACE_KMEM_ALLOC: | ||
475 | return kmemtrace_print_alloc_compress(iter); | ||
476 | case TRACE_KMEM_FREE: | ||
477 | return kmemtrace_print_free_compress(iter); | ||
445 | default: | 478 | default: |
446 | return TRACE_TYPE_UNHANDLED; | 479 | return TRACE_TYPE_UNHANDLED; |
447 | } | 480 | } |
448 | } | 481 | } |
449 | 482 | ||
483 | static struct trace_event kmem_trace_alloc = { | ||
484 | .type = TRACE_KMEM_ALLOC, | ||
485 | .trace = kmemtrace_print_alloc_user, | ||
486 | .binary = kmemtrace_print_alloc_user_bin, | ||
487 | }; | ||
488 | |||
489 | static struct trace_event kmem_trace_free = { | ||
490 | .type = TRACE_KMEM_FREE, | ||
491 | .trace = kmemtrace_print_free_user, | ||
492 | .binary = kmemtrace_print_free_user_bin, | ||
493 | }; | ||
494 | |||
450 | static struct tracer kmem_tracer __read_mostly = { | 495 | static struct tracer kmem_tracer __read_mostly = { |
451 | .name = "kmemtrace", | 496 | .name = "kmemtrace", |
452 | .init = kmem_trace_init, | 497 | .init = kmem_trace_init, |
@@ -463,6 +508,21 @@ void kmemtrace_init(void) | |||
463 | 508 | ||
464 | static int __init init_kmem_tracer(void) | 509 | static int __init init_kmem_tracer(void) |
465 | { | 510 | { |
466 | return register_tracer(&kmem_tracer); | 511 | if (!register_ftrace_event(&kmem_trace_alloc)) { |
512 | pr_warning("Warning: could not register kmem events\n"); | ||
513 | return 1; | ||
514 | } | ||
515 | |||
516 | if (!register_ftrace_event(&kmem_trace_free)) { | ||
517 | pr_warning("Warning: could not register kmem events\n"); | ||
518 | return 1; | ||
519 | } | ||
520 | |||
521 | if (!register_tracer(&kmem_tracer)) { | ||
522 | pr_warning("Warning: could not register the kmem tracer\n"); | ||
523 | return 1; | ||
524 | } | ||
525 | |||
526 | return 0; | ||
467 | } | 527 | } |
468 | device_initcall(init_kmem_tracer); | 528 | device_initcall(init_kmem_tracer); |