diff options
| author | Xiao Guangrong <xiaoguangrong@cn.fujitsu.com> | 2009-07-23 00:01:22 -0400 |
|---|---|---|
| committer | Steven Rostedt <rostedt@goodmis.org> | 2009-07-23 20:54:40 -0400 |
| commit | 75e33751ca8bbb72dd6f1a74d2810ddc8cbe4bdf (patch) | |
| tree | 35402f5e41b3e823ceed21ee535045f39cd5465a | |
| parent | 8e068542a8d9efec55126284d2f5cb32f003d507 (diff) | |
tracing/ksym_tracer: support quick clear for ksym_trace_filter -- v2
It's rather boring to clear symbol one by one in ksym_trace_filter
file, so, this patch will let ksym_trace_filter file support quickly
clear all break points. We can write "0" to this file and it will clear
all symbols
for example:
# cat ksym_trace_filter
ksym_filter_head:rw-
global_trace:rw-
# echo 0 > ksym_trace_filter
# cat ksym_trace_filter
#
Changelog v1->v2:
Add other ways to clear all breakpoints by writing NULL or "*:---"
to ksym_trace_filter file base on K.Prasad's suggestion
Signed-off-by: Xiao Guangrong <xiaoguangrong@cn.fujitsu.com>
LKML-Reference: <4A67E092.3080202@cn.fujitsu.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
| -rw-r--r-- | kernel/trace/trace_ksym.c | 53 |
1 files changed, 35 insertions, 18 deletions
diff --git a/kernel/trace/trace_ksym.c b/kernel/trace/trace_ksym.c index cd5cb656c3d2..2fde875ead4c 100644 --- a/kernel/trace/trace_ksym.c +++ b/kernel/trace/trace_ksym.c | |||
| @@ -163,8 +163,6 @@ static int parse_ksym_trace_str(char *input_string, char **ksymname, | |||
| 163 | { | 163 | { |
| 164 | int ret; | 164 | int ret; |
| 165 | 165 | ||
| 166 | strstrip(input_string); | ||
| 167 | |||
| 168 | *ksymname = strsep(&input_string, ":"); | 166 | *ksymname = strsep(&input_string, ":"); |
| 169 | *addr = kallsyms_lookup_name(*ksymname); | 167 | *addr = kallsyms_lookup_name(*ksymname); |
| 170 | 168 | ||
| @@ -262,6 +260,25 @@ static ssize_t ksym_trace_filter_read(struct file *filp, char __user *ubuf, | |||
| 262 | return cnt; | 260 | return cnt; |
| 263 | } | 261 | } |
| 264 | 262 | ||
| 263 | static void __ksym_trace_reset(void) | ||
| 264 | { | ||
| 265 | struct trace_ksym *entry; | ||
| 266 | struct hlist_node *node, *node1; | ||
| 267 | |||
| 268 | mutex_lock(&ksym_tracer_mutex); | ||
| 269 | hlist_for_each_entry_safe(entry, node, node1, &ksym_filter_head, | ||
| 270 | ksym_hlist) { | ||
| 271 | unregister_kernel_hw_breakpoint(entry->ksym_hbp); | ||
| 272 | ksym_filter_entry_count--; | ||
| 273 | hlist_del_rcu(&(entry->ksym_hlist)); | ||
| 274 | synchronize_rcu(); | ||
| 275 | kfree(entry->ksym_hbp->info.name); | ||
| 276 | kfree(entry->ksym_hbp); | ||
| 277 | kfree(entry); | ||
| 278 | } | ||
| 279 | mutex_unlock(&ksym_tracer_mutex); | ||
| 280 | } | ||
| 281 | |||
| 265 | static ssize_t ksym_trace_filter_write(struct file *file, | 282 | static ssize_t ksym_trace_filter_write(struct file *file, |
| 266 | const char __user *buffer, | 283 | const char __user *buffer, |
| 267 | size_t count, loff_t *ppos) | 284 | size_t count, loff_t *ppos) |
| @@ -282,6 +299,21 @@ static ssize_t ksym_trace_filter_write(struct file *file, | |||
| 282 | } | 299 | } |
| 283 | input_string[count] = '\0'; | 300 | input_string[count] = '\0'; |
| 284 | 301 | ||
| 302 | strstrip(input_string); | ||
| 303 | |||
| 304 | /* | ||
| 305 | * Clear all breakpoints if: | ||
| 306 | * 1: echo > ksym_trace_filter | ||
| 307 | * 2: echo 0 > ksym_trace_filter | ||
| 308 | * 3: echo "*:---" > ksym_trace_filter | ||
| 309 | */ | ||
| 310 | if (!input_string[0] || !strcmp(input_string, "0") || | ||
| 311 | !strcmp(input_string, "*:---")) { | ||
| 312 | __ksym_trace_reset(); | ||
| 313 | kfree(input_string); | ||
| 314 | return count; | ||
| 315 | } | ||
| 316 | |||
| 285 | ret = op = parse_ksym_trace_str(input_string, &ksymname, &ksym_addr); | 317 | ret = op = parse_ksym_trace_str(input_string, &ksymname, &ksym_addr); |
| 286 | if (ret < 0) { | 318 | if (ret < 0) { |
| 287 | kfree(input_string); | 319 | kfree(input_string); |
| @@ -341,23 +373,8 @@ static const struct file_operations ksym_tracing_fops = { | |||
| 341 | 373 | ||
| 342 | static void ksym_trace_reset(struct trace_array *tr) | 374 | static void ksym_trace_reset(struct trace_array *tr) |
| 343 | { | 375 | { |
| 344 | struct trace_ksym *entry; | ||
| 345 | struct hlist_node *node, *node1; | ||
| 346 | |||
| 347 | ksym_tracing_enabled = 0; | 376 | ksym_tracing_enabled = 0; |
| 348 | 377 | __ksym_trace_reset(); | |
| 349 | mutex_lock(&ksym_tracer_mutex); | ||
| 350 | hlist_for_each_entry_safe(entry, node, node1, &ksym_filter_head, | ||
| 351 | ksym_hlist) { | ||
| 352 | unregister_kernel_hw_breakpoint(entry->ksym_hbp); | ||
| 353 | ksym_filter_entry_count--; | ||
| 354 | hlist_del_rcu(&(entry->ksym_hlist)); | ||
| 355 | synchronize_rcu(); | ||
| 356 | kfree(entry->ksym_hbp->info.name); | ||
| 357 | kfree(entry->ksym_hbp); | ||
| 358 | kfree(entry); | ||
| 359 | } | ||
| 360 | mutex_unlock(&ksym_tracer_mutex); | ||
| 361 | } | 378 | } |
| 362 | 379 | ||
| 363 | static int ksym_trace_init(struct trace_array *tr) | 380 | static int ksym_trace_init(struct trace_array *tr) |
