Merge branch 'tracing-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'tracing-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
ftrace: fix dyn ftrace filter selection
ftrace: make filtered functions effective on setting
ftrace: fix set_ftrace_filter
trace: introduce missing mutex_unlock()
tracing: kernel/trace/trace.c: introduce missing kfree()

+58 -61
+56 -61
kernel/trace/ftrace.c
··· 326 326 327 327 static int 328 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 331 unsigned long ip, fl; 332 + unsigned char *call, *old, *new; 332 333 333 334 ip = rec->ip; 334 335 335 - if (ftrace_filtered && enable) { 336 - /* 337 - * If 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 - */ 357 - 358 - fl = rec->flags & (FTRACE_FL_FILTER | FTRACE_FL_NOTRACE | 359 - FTRACE_FL_ENABLED); 360 - 361 - if ((fl == (FTRACE_FL_FILTER | FTRACE_FL_ENABLED)) || 362 - (fl == (FTRACE_FL_FILTER | FTRACE_FL_NOTRACE)) || 363 - !fl || (fl == FTRACE_FL_NOTRACE)) 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 364 348 return 0; 365 349 350 + } else if (ftrace_filtered && enable) { 366 351 /* 367 - * If it is enabled disable it, 368 - * otherwise enable it! 352 + * Filtering is on: 369 353 */ 370 - if (fl & FTRACE_FL_ENABLED) { 371 - /* swap new and old */ 372 - new = old; 373 - old = ftrace_call_replace(ip, FTRACE_ADDR); 354 + 355 + fl = rec->flags & (FTRACE_FL_FILTER | FTRACE_FL_ENABLED); 356 + 357 + /* Record is filtered and enabled, do nothing */ 358 + if (fl == (FTRACE_FL_FILTER | FTRACE_FL_ENABLED)) 359 + return 0; 360 + 361 + /* Record is not filtered and is not enabled do nothing */ 362 + if (!fl) 363 + return 0; 364 + 365 + /* Record is not filtered but enabled, disable it */ 366 + if (fl == FTRACE_FL_ENABLED) 374 367 rec->flags &= ~FTRACE_FL_ENABLED; 375 - } else { 376 - new = ftrace_call_replace(ip, FTRACE_ADDR); 368 + else 369 + /* Otherwise record is filtered but not enabled, enable it */ 377 370 rec->flags |= FTRACE_FL_ENABLED; 378 - } 379 371 } else { 372 + /* Disable or not filtered */ 380 373 381 374 if (enable) { 382 - /* 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) { 375 + /* if record is enabled, do nothing */ 395 376 if (rec->flags & FTRACE_FL_ENABLED) 396 377 return 0; 378 + 397 379 rec->flags |= FTRACE_FL_ENABLED; 380 + 398 381 } else { 382 + 383 + /* if record is not enabled do nothing */ 399 384 if (!(rec->flags & FTRACE_FL_ENABLED)) 400 385 return 0; 386 + 401 387 rec->flags &= ~FTRACE_FL_ENABLED; 402 388 } 389 + } 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; 403 399 } 404 400 405 401 return ftrace_modify_code(ip, old, new); ··· 404 408 static void ftrace_replace_code(int enable) 405 409 { 406 410 int i, failed; 407 - unsigned char *new = NULL, *old = NULL; 411 + unsigned char *nop = NULL; 408 412 struct dyn_ftrace *rec; 409 413 struct ftrace_page *pg; 410 414 411 - if (enable) 412 - old = ftrace_nop_replace(); 413 - else 414 - new = ftrace_nop_replace(); 415 + nop = ftrace_nop_replace(); 415 416 416 417 for (pg = ftrace_pages_start; pg; pg = pg->next) { 417 418 for (i = 0; i < pg->index; i++) { ··· 426 433 unfreeze_record(rec); 427 434 } 428 435 429 - failed = __ftrace_replace_code(rec, old, new, enable); 436 + failed = __ftrace_replace_code(rec, nop, enable); 430 437 if (failed && (rec->flags & FTRACE_FL_CONVERTED)) { 431 438 rec->flags |= FTRACE_FL_FAILED; 432 439 if ((system_state == SYSTEM_BOOTING) || ··· 527 534 528 535 mutex_lock(&ftrace_start_lock); 529 536 ftrace_start++; 530 - if (ftrace_start == 1) 531 - command |= FTRACE_ENABLE_CALLS; 537 + command |= FTRACE_ENABLE_CALLS; 532 538 533 539 if (saved_ftrace_func != ftrace_trace_function) { 534 540 saved_ftrace_func = ftrace_trace_function; ··· 725 733 726 734 ((iter->flags & FTRACE_ITER_FAILURES) && 727 735 !(rec->flags & FTRACE_FL_FAILED)) || 736 + 737 + ((iter->flags & FTRACE_ITER_FILTER) && 738 + !(rec->flags & FTRACE_FL_FILTER)) || 728 739 729 740 ((iter->flags & FTRACE_ITER_NOTRACE) && 730 741 !(rec->flags & FTRACE_FL_NOTRACE))) { ··· 1181 1186 1182 1187 mutex_lock(&ftrace_sysctl_lock); 1183 1188 mutex_lock(&ftrace_start_lock); 1184 - if (iter->filtered && ftrace_start && ftrace_enabled) 1189 + if (ftrace_start && ftrace_enabled) 1185 1190 ftrace_run_update_code(FTRACE_ENABLE_CALLS); 1186 1191 mutex_unlock(&ftrace_start_lock); 1187 1192 mutex_unlock(&ftrace_sysctl_lock);
+1
kernel/trace/ring_buffer.c
··· 617 617 list_del_init(&page->list); 618 618 free_buffer_page(page); 619 619 } 620 + mutex_unlock(&buffer->mutex); 620 621 return -ENOMEM; 621 622 } 622 623
+1
kernel/trace/trace.c
··· 1936 1936 ring_buffer_read_finish(iter->buffer_iter[cpu]); 1937 1937 } 1938 1938 mutex_unlock(&trace_types_lock); 1939 + kfree(iter); 1939 1940 1940 1941 return ERR_PTR(-ENOMEM); 1941 1942 }