• Oleg Nesterov's avatar
    uprobes/perf: Teach trace_uprobe/perf code to pre-filter · 31ba3348
    Oleg Nesterov authored
    Finally implement uprobe_perf_filter() which checks ->nr_systemwide or
    ->perf_events to figure out whether we need to insert the breakpoint.
    
    uprobe_perf_open/close are changed to do uprobe_apply(true/false) when
    the new perf event comes or goes away.
    
    Note that currently this is very suboptimal:
    
    	- uprobe_register() called by TRACE_REG_PERF_REGISTER becomes a
    	  heavy nop, consumer->filter() always returns F at this stage.
    
    	  As it was already discussed we need uprobe_register_only() to
    	  avoid the costly register_for_each_vma() when possible.
    
    	- uprobe_apply() is oftenly overkill. Unless "nr_systemwide != 0"
    	  changes we need uprobe_apply_mm(), unapply_uprobe() is almost
    	  what we need.
    
    	- uprobe_apply() can be simply avoided sometimes, see the next
    	  changes.
    
    Testing:
    
    	# perf probe -x /lib/libc.so.6 syscall
    
    	# perl -e 'syscall -1 while 1' &
    	[1] 530
    
    	# perf record -e probe_libc:syscall perl -e 'syscall -1 for 1..10; sleep 1'
    
    	# perf report --show-total-period
    		100.00%            10     perl  libc-2.8.so    [.] syscall
    
    Before this patch:
    
    	# cat /sys/kernel/debug/tracing/uprobe_profile
    		/lib/libc.so.6 syscall				79291
    
    A huge ->nrhit == 79291 reflects the fact that the background process
    530 constantly hits this breakpoint too, even if doesn't contribute to
    the output.
    
    After the patch:
    
    	# cat /sys/kernel/debug/tracing/uprobe_profile
    		/lib/libc.so.6 syscall				10
    
    This shows that only the target process was punished by int3.
    Signed-off-by: default avatarOleg Nesterov <oleg@redhat.com>
    31ba3348
trace_uprobe.c 19.7 KB