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); |
