diff options
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r-- | kernel/trace/ftrace.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 8affb6d00ec1..eadd0eaea9b6 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -294,13 +294,37 @@ static inline void ftrace_del_hash(struct dyn_ftrace *node) | |||
294 | 294 | ||
295 | static void ftrace_free_rec(struct dyn_ftrace *rec) | 295 | static void ftrace_free_rec(struct dyn_ftrace *rec) |
296 | { | 296 | { |
297 | /* no locking, only called from kstop_machine */ | ||
298 | |||
299 | rec->ip = (unsigned long)ftrace_free_records; | 297 | rec->ip = (unsigned long)ftrace_free_records; |
300 | ftrace_free_records = rec; | 298 | ftrace_free_records = rec; |
301 | rec->flags |= FTRACE_FL_FREE; | 299 | rec->flags |= FTRACE_FL_FREE; |
302 | } | 300 | } |
303 | 301 | ||
302 | void ftrace_release(void *start, unsigned long size) | ||
303 | { | ||
304 | struct dyn_ftrace *rec; | ||
305 | struct ftrace_page *pg; | ||
306 | unsigned long s = (unsigned long)start; | ||
307 | unsigned long e = s + size; | ||
308 | int i; | ||
309 | |||
310 | if (!start) | ||
311 | return; | ||
312 | |||
313 | /* No interrupt should call this */ | ||
314 | spin_lock(&ftrace_lock); | ||
315 | |||
316 | for (pg = ftrace_pages_start; pg; pg = pg->next) { | ||
317 | for (i = 0; i < pg->index; i++) { | ||
318 | rec = &pg->records[i]; | ||
319 | |||
320 | if ((rec->ip >= s) && (rec->ip < e)) | ||
321 | ftrace_free_rec(rec); | ||
322 | } | ||
323 | } | ||
324 | spin_unlock(&ftrace_lock); | ||
325 | |||
326 | } | ||
327 | |||
304 | static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip) | 328 | static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip) |
305 | { | 329 | { |
306 | struct dyn_ftrace *rec; | 330 | struct dyn_ftrace *rec; |
@@ -1527,7 +1551,9 @@ static int ftrace_convert_nops(unsigned long *start, | |||
1527 | p = start; | 1551 | p = start; |
1528 | while (p < end) { | 1552 | while (p < end) { |
1529 | addr = ftrace_call_adjust(*p++); | 1553 | addr = ftrace_call_adjust(*p++); |
1554 | spin_lock(&ftrace_lock); | ||
1530 | ftrace_record_ip(addr); | 1555 | ftrace_record_ip(addr); |
1556 | spin_unlock(&ftrace_lock); | ||
1531 | ftrace_shutdown_replenish(); | 1557 | ftrace_shutdown_replenish(); |
1532 | } | 1558 | } |
1533 | 1559 | ||
@@ -1541,6 +1567,8 @@ static int ftrace_convert_nops(unsigned long *start, | |||
1541 | 1567 | ||
1542 | void ftrace_init_module(unsigned long *start, unsigned long *end) | 1568 | void ftrace_init_module(unsigned long *start, unsigned long *end) |
1543 | { | 1569 | { |
1570 | if (start == end) | ||
1571 | return; | ||
1544 | ftrace_convert_nops(start, end); | 1572 | ftrace_convert_nops(start, end); |
1545 | } | 1573 | } |
1546 | 1574 | ||