aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/ftrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r--kernel/trace/ftrace.c113
1 files changed, 54 insertions, 59 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index e60205722d0c..78db083390f0 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -326,96 +326,89 @@ ftrace_record_ip(unsigned long ip)
326 326
327static int 327static int
328__ftrace_replace_code(struct dyn_ftrace *rec, 328__ftrace_replace_code(struct dyn_ftrace *rec,
329 unsigned char *old, unsigned char *new, int enable) 329 unsigned char *nop, int enable)
330{ 330{
331 unsigned long ip, fl; 331 unsigned long ip, fl;
332 unsigned char *call, *old, *new;
332 333
333 ip = rec->ip; 334 ip = rec->ip;
334 335
335 if (ftrace_filtered && enable) { 336 /*
337 * If this record is not to be traced and
338 * it is not enabled then do nothing.
339 *
340 * If this record is not to be traced and
341 * it is enabled then disabled it.
342 *
343 */
344 if (rec->flags & FTRACE_FL_NOTRACE) {
345 if (rec->flags & FTRACE_FL_ENABLED)
346 rec->flags &= ~FTRACE_FL_ENABLED;
347 else
348 return 0;
349
350 } else if (ftrace_filtered && enable) {
336 /* 351 /*
337 * If filtering is on: 352 * Filtering is on:
338 *
339 * If this record is set to be filtered and
340 * is enabled then do nothing.
341 *
342 * If this record is set to be filtered and
343 * it is not enabled, enable it.
344 *
345 * If this record is not set to be filtered
346 * and it is not enabled do nothing.
347 *
348 * If this record is set not to trace then
349 * do nothing.
350 *
351 * If this record is set not to trace and
352 * it is enabled then disable it.
353 *
354 * If this record is not set to be filtered and
355 * it is enabled, disable it.
356 */ 353 */
357 354
358 fl = rec->flags & (FTRACE_FL_FILTER | FTRACE_FL_NOTRACE | 355 fl = rec->flags & (FTRACE_FL_FILTER | FTRACE_FL_ENABLED);
359 FTRACE_FL_ENABLED);
360 356
361 if ((fl == (FTRACE_FL_FILTER | FTRACE_FL_ENABLED)) || 357 /* Record is filtered and enabled, do nothing */
362 (fl == (FTRACE_FL_FILTER | FTRACE_FL_NOTRACE)) || 358 if (fl == (FTRACE_FL_FILTER | FTRACE_FL_ENABLED))
363 !fl || (fl == FTRACE_FL_NOTRACE))
364 return 0; 359 return 0;
365 360
366 /* 361 /* Record is not filtered and is not enabled do nothing */
367 * If it is enabled disable it, 362 if (!fl)
368 * otherwise enable it! 363 return 0;
369 */ 364
370 if (fl & FTRACE_FL_ENABLED) { 365 /* Record is not filtered but enabled, disable it */
371 /* swap new and old */ 366 if (fl == FTRACE_FL_ENABLED)
372 new = old;
373 old = ftrace_call_replace(ip, FTRACE_ADDR);
374 rec->flags &= ~FTRACE_FL_ENABLED; 367 rec->flags &= ~FTRACE_FL_ENABLED;
375 } else { 368 else
376 new = ftrace_call_replace(ip, FTRACE_ADDR); 369 /* Otherwise record is filtered but not enabled, enable it */
377 rec->flags |= FTRACE_FL_ENABLED; 370 rec->flags |= FTRACE_FL_ENABLED;
378 }
379 } else { 371 } else {
372 /* Disable or not filtered */
380 373
381 if (enable) { 374 if (enable) {
382 /* 375 /* if record is enabled, do nothing */
383 * If this record is set not to trace and is
384 * not enabled, do nothing.
385 */
386 fl = rec->flags & (FTRACE_FL_NOTRACE | FTRACE_FL_ENABLED);
387 if (fl == FTRACE_FL_NOTRACE)
388 return 0;
389
390 new = ftrace_call_replace(ip, FTRACE_ADDR);
391 } else
392 old = ftrace_call_replace(ip, FTRACE_ADDR);
393
394 if (enable) {
395 if (rec->flags & FTRACE_FL_ENABLED) 376 if (rec->flags & FTRACE_FL_ENABLED)
396 return 0; 377 return 0;
378
397 rec->flags |= FTRACE_FL_ENABLED; 379 rec->flags |= FTRACE_FL_ENABLED;
380
398 } else { 381 } else {
382
383 /* if record is not enabled do nothing */
399 if (!(rec->flags & FTRACE_FL_ENABLED)) 384 if (!(rec->flags & FTRACE_FL_ENABLED))
400 return 0; 385 return 0;
386
401 rec->flags &= ~FTRACE_FL_ENABLED; 387 rec->flags &= ~FTRACE_FL_ENABLED;
402 } 388 }
403 } 389 }
404 390
391 call = ftrace_call_replace(ip, FTRACE_ADDR);
392
393 if (rec->flags & FTRACE_FL_ENABLED) {
394 old = nop;
395 new = call;
396 } else {
397 old = call;
398 new = nop;
399 }
400
405 return ftrace_modify_code(ip, old, new); 401 return ftrace_modify_code(ip, old, new);
406} 402}
407 403
408static void ftrace_replace_code(int enable) 404static void ftrace_replace_code(int enable)
409{ 405{
410 int i, failed; 406 int i, failed;
411 unsigned char *new = NULL, *old = NULL; 407 unsigned char *nop = NULL;
412 struct dyn_ftrace *rec; 408 struct dyn_ftrace *rec;
413 struct ftrace_page *pg; 409 struct ftrace_page *pg;
414 410
415 if (enable) 411 nop = ftrace_nop_replace();
416 old = ftrace_nop_replace();
417 else
418 new = ftrace_nop_replace();
419 412
420 for (pg = ftrace_pages_start; pg; pg = pg->next) { 413 for (pg = ftrace_pages_start; pg; pg = pg->next) {
421 for (i = 0; i < pg->index; i++) { 414 for (i = 0; i < pg->index; i++) {
@@ -433,7 +426,7 @@ static void ftrace_replace_code(int enable)
433 unfreeze_record(rec); 426 unfreeze_record(rec);
434 } 427 }
435 428
436 failed = __ftrace_replace_code(rec, old, new, enable); 429 failed = __ftrace_replace_code(rec, nop, enable);
437 if (failed && (rec->flags & FTRACE_FL_CONVERTED)) { 430 if (failed && (rec->flags & FTRACE_FL_CONVERTED)) {
438 rec->flags |= FTRACE_FL_FAILED; 431 rec->flags |= FTRACE_FL_FAILED;
439 if ((system_state == SYSTEM_BOOTING) || 432 if ((system_state == SYSTEM_BOOTING) ||
@@ -534,8 +527,7 @@ static void ftrace_startup(void)
534 527
535 mutex_lock(&ftrace_start_lock); 528 mutex_lock(&ftrace_start_lock);
536 ftrace_start++; 529 ftrace_start++;
537 if (ftrace_start == 1) 530 command |= FTRACE_ENABLE_CALLS;
538 command |= FTRACE_ENABLE_CALLS;
539 531
540 if (saved_ftrace_func != ftrace_trace_function) { 532 if (saved_ftrace_func != ftrace_trace_function) {
541 saved_ftrace_func = ftrace_trace_function; 533 saved_ftrace_func = ftrace_trace_function;
@@ -734,6 +726,9 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
734 ((iter->flags & FTRACE_ITER_FAILURES) && 726 ((iter->flags & FTRACE_ITER_FAILURES) &&
735 !(rec->flags & FTRACE_FL_FAILED)) || 727 !(rec->flags & FTRACE_FL_FAILED)) ||
736 728
729 ((iter->flags & FTRACE_ITER_FILTER) &&
730 !(rec->flags & FTRACE_FL_FILTER)) ||
731
737 ((iter->flags & FTRACE_ITER_NOTRACE) && 732 ((iter->flags & FTRACE_ITER_NOTRACE) &&
738 !(rec->flags & FTRACE_FL_NOTRACE))) { 733 !(rec->flags & FTRACE_FL_NOTRACE))) {
739 rec = NULL; 734 rec = NULL;
@@ -1186,7 +1181,7 @@ ftrace_regex_release(struct inode *inode, struct file *file, int enable)
1186 1181
1187 mutex_lock(&ftrace_sysctl_lock); 1182 mutex_lock(&ftrace_sysctl_lock);
1188 mutex_lock(&ftrace_start_lock); 1183 mutex_lock(&ftrace_start_lock);
1189 if (iter->filtered && ftrace_start && ftrace_enabled) 1184 if (ftrace_start && ftrace_enabled)
1190 ftrace_run_update_code(FTRACE_ENABLE_CALLS); 1185 ftrace_run_update_code(FTRACE_ENABLE_CALLS);
1191 mutex_unlock(&ftrace_start_lock); 1186 mutex_unlock(&ftrace_start_lock);
1192 mutex_unlock(&ftrace_sysctl_lock); 1187 mutex_unlock(&ftrace_sysctl_lock);