diff options
author | Ingo Molnar <mingo@elte.hu> | 2012-01-08 03:51:24 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2012-01-08 03:51:24 -0500 |
commit | 675eef66e3edcab8065533edfefbcbbacb9a30d3 (patch) | |
tree | 49648661263d7c3b7645df904b3dbb18723ff744 | |
parent | 03f70388c39cef5dfdc70ce5473ec31577a18e6b (diff) | |
parent | 96de37b62ca525cd77d2e85aea1472846ee31c4d (diff) |
Merge branch 'tip/perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace into perf/core
-rw-r--r-- | Documentation/kernel-parameters.txt | 8 | ||||
-rw-r--r-- | include/linux/compiler-gcc.h | 5 | ||||
-rw-r--r-- | include/linux/ftrace.h | 77 | ||||
-rw-r--r-- | kernel/trace/ftrace.c | 715 | ||||
-rw-r--r-- | kernel/trace/trace_events_filter.c | 283 | ||||
-rw-r--r-- | kernel/trace/trace_stack.c | 30 |
6 files changed, 768 insertions, 350 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 0293fc8daca3..31e3377d8e14 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -2437,6 +2437,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
2437 | stacktrace [FTRACE] | 2437 | stacktrace [FTRACE] |
2438 | Enabled the stack tracer on boot up. | 2438 | Enabled the stack tracer on boot up. |
2439 | 2439 | ||
2440 | stacktrace_filter=[function-list] | ||
2441 | [FTRACE] Limit the functions that the stack tracer | ||
2442 | will trace at boot up. function-list is a comma separated | ||
2443 | list of functions. This list can be changed at run | ||
2444 | time by the stack_trace_filter file in the debugfs | ||
2445 | tracing directory. Note, this enables stack tracing | ||
2446 | and the stacktrace above is not needed. | ||
2447 | |||
2440 | sti= [PARISC,HW] | 2448 | sti= [PARISC,HW] |
2441 | Format: <num> | 2449 | Format: <num> |
2442 | Set the STI (builtin display/keyboard on the HP-PARISC | 2450 | Set the STI (builtin display/keyboard on the HP-PARISC |
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index 59e4028e833d..3fd17c249221 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h | |||
@@ -50,6 +50,11 @@ | |||
50 | # define inline inline __attribute__((always_inline)) | 50 | # define inline inline __attribute__((always_inline)) |
51 | # define __inline__ __inline__ __attribute__((always_inline)) | 51 | # define __inline__ __inline__ __attribute__((always_inline)) |
52 | # define __inline __inline __attribute__((always_inline)) | 52 | # define __inline __inline __attribute__((always_inline)) |
53 | #else | ||
54 | /* A lot of inline functions can cause havoc with function tracing */ | ||
55 | # define inline inline notrace | ||
56 | # define __inline__ __inline__ notrace | ||
57 | # define __inline __inline notrace | ||
53 | #endif | 58 | #endif |
54 | 59 | ||
55 | #define __deprecated __attribute__((deprecated)) | 60 | #define __deprecated __attribute__((deprecated)) |
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 26eafcef75be..028e26f0bf08 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h | |||
@@ -133,6 +133,8 @@ struct ftrace_func_command { | |||
133 | int ftrace_arch_code_modify_prepare(void); | 133 | int ftrace_arch_code_modify_prepare(void); |
134 | int ftrace_arch_code_modify_post_process(void); | 134 | int ftrace_arch_code_modify_post_process(void); |
135 | 135 | ||
136 | void ftrace_bug(int err, unsigned long ip); | ||
137 | |||
136 | struct seq_file; | 138 | struct seq_file; |
137 | 139 | ||
138 | struct ftrace_probe_ops { | 140 | struct ftrace_probe_ops { |
@@ -161,7 +163,6 @@ extern int ftrace_text_reserved(void *start, void *end); | |||
161 | 163 | ||
162 | enum { | 164 | enum { |
163 | FTRACE_FL_ENABLED = (1 << 30), | 165 | FTRACE_FL_ENABLED = (1 << 30), |
164 | FTRACE_FL_FREE = (1 << 31), | ||
165 | }; | 166 | }; |
166 | 167 | ||
167 | #define FTRACE_FL_MASK (0x3UL << 30) | 168 | #define FTRACE_FL_MASK (0x3UL << 30) |
@@ -172,10 +173,7 @@ struct dyn_ftrace { | |||
172 | unsigned long ip; /* address of mcount call-site */ | 173 | unsigned long ip; /* address of mcount call-site */ |
173 | struct dyn_ftrace *freelist; | 174 | struct dyn_ftrace *freelist; |
174 | }; | 175 | }; |
175 | union { | 176 | unsigned long flags; |
176 | unsigned long flags; | ||
177 | struct dyn_ftrace *newlist; | ||
178 | }; | ||
179 | struct dyn_arch_ftrace arch; | 177 | struct dyn_arch_ftrace arch; |
180 | }; | 178 | }; |
181 | 179 | ||
@@ -190,6 +188,56 @@ void ftrace_set_global_notrace(unsigned char *buf, int len, int reset); | |||
190 | int register_ftrace_command(struct ftrace_func_command *cmd); | 188 | int register_ftrace_command(struct ftrace_func_command *cmd); |
191 | int unregister_ftrace_command(struct ftrace_func_command *cmd); | 189 | int unregister_ftrace_command(struct ftrace_func_command *cmd); |
192 | 190 | ||
191 | enum { | ||
192 | FTRACE_UPDATE_CALLS = (1 << 0), | ||
193 | FTRACE_DISABLE_CALLS = (1 << 1), | ||
194 | FTRACE_UPDATE_TRACE_FUNC = (1 << 2), | ||
195 | FTRACE_START_FUNC_RET = (1 << 3), | ||
196 | FTRACE_STOP_FUNC_RET = (1 << 4), | ||
197 | }; | ||
198 | |||
199 | enum { | ||
200 | FTRACE_UPDATE_IGNORE, | ||
201 | FTRACE_UPDATE_MAKE_CALL, | ||
202 | FTRACE_UPDATE_MAKE_NOP, | ||
203 | }; | ||
204 | |||
205 | enum { | ||
206 | FTRACE_ITER_FILTER = (1 << 0), | ||
207 | FTRACE_ITER_NOTRACE = (1 << 1), | ||
208 | FTRACE_ITER_PRINTALL = (1 << 2), | ||
209 | FTRACE_ITER_DO_HASH = (1 << 3), | ||
210 | FTRACE_ITER_HASH = (1 << 4), | ||
211 | FTRACE_ITER_ENABLED = (1 << 5), | ||
212 | }; | ||
213 | |||
214 | void arch_ftrace_update_code(int command); | ||
215 | |||
216 | struct ftrace_rec_iter; | ||
217 | |||
218 | struct ftrace_rec_iter *ftrace_rec_iter_start(void); | ||
219 | struct ftrace_rec_iter *ftrace_rec_iter_next(struct ftrace_rec_iter *iter); | ||
220 | struct dyn_ftrace *ftrace_rec_iter_record(struct ftrace_rec_iter *iter); | ||
221 | |||
222 | int ftrace_update_record(struct dyn_ftrace *rec, int enable); | ||
223 | int ftrace_test_record(struct dyn_ftrace *rec, int enable); | ||
224 | void ftrace_run_stop_machine(int command); | ||
225 | int ftrace_location(unsigned long ip); | ||
226 | |||
227 | extern ftrace_func_t ftrace_trace_function; | ||
228 | |||
229 | int ftrace_regex_open(struct ftrace_ops *ops, int flag, | ||
230 | struct inode *inode, struct file *file); | ||
231 | ssize_t ftrace_filter_write(struct file *file, const char __user *ubuf, | ||
232 | size_t cnt, loff_t *ppos); | ||
233 | ssize_t ftrace_notrace_write(struct file *file, const char __user *ubuf, | ||
234 | size_t cnt, loff_t *ppos); | ||
235 | loff_t ftrace_regex_lseek(struct file *file, loff_t offset, int origin); | ||
236 | int ftrace_regex_release(struct inode *inode, struct file *file); | ||
237 | |||
238 | void __init | ||
239 | ftrace_set_early_filter(struct ftrace_ops *ops, char *buf, int enable); | ||
240 | |||
193 | /* defined in arch */ | 241 | /* defined in arch */ |
194 | extern int ftrace_ip_converted(unsigned long ip); | 242 | extern int ftrace_ip_converted(unsigned long ip); |
195 | extern int ftrace_dyn_arch_init(void *data); | 243 | extern int ftrace_dyn_arch_init(void *data); |
@@ -284,6 +332,25 @@ static inline int ftrace_text_reserved(void *start, void *end) | |||
284 | { | 332 | { |
285 | return 0; | 333 | return 0; |
286 | } | 334 | } |
335 | |||
336 | /* | ||
337 | * Again users of functions that have ftrace_ops may not | ||
338 | * have them defined when ftrace is not enabled, but these | ||
339 | * functions may still be called. Use a macro instead of inline. | ||
340 | */ | ||
341 | #define ftrace_regex_open(ops, flag, inod, file) ({ -ENODEV; }) | ||
342 | #define ftrace_set_early_filter(ops, buf, enable) do { } while (0) | ||
343 | |||
344 | static inline ssize_t ftrace_filter_write(struct file *file, const char __user *ubuf, | ||
345 | size_t cnt, loff_t *ppos) { return -ENODEV; } | ||
346 | static inline ssize_t ftrace_notrace_write(struct file *file, const char __user *ubuf, | ||
347 | size_t cnt, loff_t *ppos) { return -ENODEV; } | ||
348 | static inline loff_t ftrace_regex_lseek(struct file *file, loff_t offset, int origin) | ||
349 | { | ||
350 | return -ENODEV; | ||
351 | } | ||
352 | static inline int | ||
353 | ftrace_regex_release(struct inode *inode, struct file *file) { return -ENODEV; } | ||
287 | #endif /* CONFIG_DYNAMIC_FTRACE */ | 354 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
288 | 355 | ||
289 | /* totally disable ftrace - can not re-enable after this */ | 356 | /* totally disable ftrace - can not re-enable after this */ |
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index b1e8943fed1d..683d559a0eef 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -22,11 +22,13 @@ | |||
22 | #include <linux/hardirq.h> | 22 | #include <linux/hardirq.h> |
23 | #include <linux/kthread.h> | 23 | #include <linux/kthread.h> |
24 | #include <linux/uaccess.h> | 24 | #include <linux/uaccess.h> |
25 | #include <linux/bsearch.h> | ||
25 | #include <linux/module.h> | 26 | #include <linux/module.h> |
26 | #include <linux/ftrace.h> | 27 | #include <linux/ftrace.h> |
27 | #include <linux/sysctl.h> | 28 | #include <linux/sysctl.h> |
28 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
29 | #include <linux/ctype.h> | 30 | #include <linux/ctype.h> |
31 | #include <linux/sort.h> | ||
30 | #include <linux/list.h> | 32 | #include <linux/list.h> |
31 | #include <linux/hash.h> | 33 | #include <linux/hash.h> |
32 | #include <linux/rcupdate.h> | 34 | #include <linux/rcupdate.h> |
@@ -947,13 +949,6 @@ struct ftrace_func_probe { | |||
947 | struct rcu_head rcu; | 949 | struct rcu_head rcu; |
948 | }; | 950 | }; |
949 | 951 | ||
950 | enum { | ||
951 | FTRACE_ENABLE_CALLS = (1 << 0), | ||
952 | FTRACE_DISABLE_CALLS = (1 << 1), | ||
953 | FTRACE_UPDATE_TRACE_FUNC = (1 << 2), | ||
954 | FTRACE_START_FUNC_RET = (1 << 3), | ||
955 | FTRACE_STOP_FUNC_RET = (1 << 4), | ||
956 | }; | ||
957 | struct ftrace_func_entry { | 952 | struct ftrace_func_entry { |
958 | struct hlist_node hlist; | 953 | struct hlist_node hlist; |
959 | unsigned long ip; | 954 | unsigned long ip; |
@@ -984,18 +979,19 @@ static struct ftrace_ops global_ops = { | |||
984 | .filter_hash = EMPTY_HASH, | 979 | .filter_hash = EMPTY_HASH, |
985 | }; | 980 | }; |
986 | 981 | ||
987 | static struct dyn_ftrace *ftrace_new_addrs; | ||
988 | |||
989 | static DEFINE_MUTEX(ftrace_regex_lock); | 982 | static DEFINE_MUTEX(ftrace_regex_lock); |
990 | 983 | ||
991 | struct ftrace_page { | 984 | struct ftrace_page { |
992 | struct ftrace_page *next; | 985 | struct ftrace_page *next; |
986 | struct dyn_ftrace *records; | ||
993 | int index; | 987 | int index; |
994 | struct dyn_ftrace records[]; | 988 | int size; |
995 | }; | 989 | }; |
996 | 990 | ||
997 | #define ENTRIES_PER_PAGE \ | 991 | static struct ftrace_page *ftrace_new_pgs; |
998 | ((PAGE_SIZE - sizeof(struct ftrace_page)) / sizeof(struct dyn_ftrace)) | 992 | |
993 | #define ENTRY_SIZE sizeof(struct dyn_ftrace) | ||
994 | #define ENTRIES_PER_PAGE (PAGE_SIZE / ENTRY_SIZE) | ||
999 | 995 | ||
1000 | /* estimate from running different kernels */ | 996 | /* estimate from running different kernels */ |
1001 | #define NR_TO_INIT 10000 | 997 | #define NR_TO_INIT 10000 |
@@ -1003,7 +999,10 @@ struct ftrace_page { | |||
1003 | static struct ftrace_page *ftrace_pages_start; | 999 | static struct ftrace_page *ftrace_pages_start; |
1004 | static struct ftrace_page *ftrace_pages; | 1000 | static struct ftrace_page *ftrace_pages; |
1005 | 1001 | ||
1006 | static struct dyn_ftrace *ftrace_free_records; | 1002 | static bool ftrace_hash_empty(struct ftrace_hash *hash) |
1003 | { | ||
1004 | return !hash || !hash->count; | ||
1005 | } | ||
1007 | 1006 | ||
1008 | static struct ftrace_func_entry * | 1007 | static struct ftrace_func_entry * |
1009 | ftrace_lookup_ip(struct ftrace_hash *hash, unsigned long ip) | 1008 | ftrace_lookup_ip(struct ftrace_hash *hash, unsigned long ip) |
@@ -1013,7 +1012,7 @@ ftrace_lookup_ip(struct ftrace_hash *hash, unsigned long ip) | |||
1013 | struct hlist_head *hhd; | 1012 | struct hlist_head *hhd; |
1014 | struct hlist_node *n; | 1013 | struct hlist_node *n; |
1015 | 1014 | ||
1016 | if (!hash->count) | 1015 | if (ftrace_hash_empty(hash)) |
1017 | return NULL; | 1016 | return NULL; |
1018 | 1017 | ||
1019 | if (hash->size_bits > 0) | 1018 | if (hash->size_bits > 0) |
@@ -1157,7 +1156,7 @@ alloc_and_copy_ftrace_hash(int size_bits, struct ftrace_hash *hash) | |||
1157 | return NULL; | 1156 | return NULL; |
1158 | 1157 | ||
1159 | /* Empty hash? */ | 1158 | /* Empty hash? */ |
1160 | if (!hash || !hash->count) | 1159 | if (ftrace_hash_empty(hash)) |
1161 | return new_hash; | 1160 | return new_hash; |
1162 | 1161 | ||
1163 | size = 1 << hash->size_bits; | 1162 | size = 1 << hash->size_bits; |
@@ -1282,9 +1281,9 @@ ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip) | |||
1282 | filter_hash = rcu_dereference_raw(ops->filter_hash); | 1281 | filter_hash = rcu_dereference_raw(ops->filter_hash); |
1283 | notrace_hash = rcu_dereference_raw(ops->notrace_hash); | 1282 | notrace_hash = rcu_dereference_raw(ops->notrace_hash); |
1284 | 1283 | ||
1285 | if ((!filter_hash || !filter_hash->count || | 1284 | if ((ftrace_hash_empty(filter_hash) || |
1286 | ftrace_lookup_ip(filter_hash, ip)) && | 1285 | ftrace_lookup_ip(filter_hash, ip)) && |
1287 | (!notrace_hash || !notrace_hash->count || | 1286 | (ftrace_hash_empty(notrace_hash) || |
1288 | !ftrace_lookup_ip(notrace_hash, ip))) | 1287 | !ftrace_lookup_ip(notrace_hash, ip))) |
1289 | ret = 1; | 1288 | ret = 1; |
1290 | else | 1289 | else |
@@ -1307,6 +1306,47 @@ ftrace_ops_test(struct ftrace_ops *ops, unsigned long ip) | |||
1307 | } \ | 1306 | } \ |
1308 | } | 1307 | } |
1309 | 1308 | ||
1309 | |||
1310 | static int ftrace_cmp_recs(const void *a, const void *b) | ||
1311 | { | ||
1312 | const struct dyn_ftrace *reca = a; | ||
1313 | const struct dyn_ftrace *recb = b; | ||
1314 | |||
1315 | if (reca->ip > recb->ip) | ||
1316 | return 1; | ||
1317 | if (reca->ip < recb->ip) | ||
1318 | return -1; | ||
1319 | return 0; | ||
1320 | } | ||
1321 | |||
1322 | /** | ||
1323 | * ftrace_location - return true if the ip giving is a traced location | ||
1324 | * @ip: the instruction pointer to check | ||
1325 | * | ||
1326 | * Returns 1 if @ip given is a pointer to a ftrace location. | ||
1327 | * That is, the instruction that is either a NOP or call to | ||
1328 | * the function tracer. It checks the ftrace internal tables to | ||
1329 | * determine if the address belongs or not. | ||
1330 | */ | ||
1331 | int ftrace_location(unsigned long ip) | ||
1332 | { | ||
1333 | struct ftrace_page *pg; | ||
1334 | struct dyn_ftrace *rec; | ||
1335 | struct dyn_ftrace key; | ||
1336 | |||
1337 | key.ip = ip; | ||
1338 | |||
1339 | for (pg = ftrace_pages_start; pg; pg = pg->next) { | ||
1340 | rec = bsearch(&key, pg->records, pg->index, | ||
1341 | sizeof(struct dyn_ftrace), | ||
1342 | ftrace_cmp_recs); | ||
1343 | if (rec) | ||
1344 | return 1; | ||
1345 | } | ||
1346 | |||
1347 | return 0; | ||
1348 | } | ||
1349 | |||
1310 | static void __ftrace_hash_rec_update(struct ftrace_ops *ops, | 1350 | static void __ftrace_hash_rec_update(struct ftrace_ops *ops, |
1311 | int filter_hash, | 1351 | int filter_hash, |
1312 | bool inc) | 1352 | bool inc) |
@@ -1336,7 +1376,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops, | |||
1336 | if (filter_hash) { | 1376 | if (filter_hash) { |
1337 | hash = ops->filter_hash; | 1377 | hash = ops->filter_hash; |
1338 | other_hash = ops->notrace_hash; | 1378 | other_hash = ops->notrace_hash; |
1339 | if (!hash || !hash->count) | 1379 | if (ftrace_hash_empty(hash)) |
1340 | all = 1; | 1380 | all = 1; |
1341 | } else { | 1381 | } else { |
1342 | inc = !inc; | 1382 | inc = !inc; |
@@ -1346,7 +1386,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops, | |||
1346 | * If the notrace hash has no items, | 1386 | * If the notrace hash has no items, |
1347 | * then there's nothing to do. | 1387 | * then there's nothing to do. |
1348 | */ | 1388 | */ |
1349 | if (hash && !hash->count) | 1389 | if (ftrace_hash_empty(hash)) |
1350 | return; | 1390 | return; |
1351 | } | 1391 | } |
1352 | 1392 | ||
@@ -1363,8 +1403,8 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops, | |||
1363 | if (!other_hash || !ftrace_lookup_ip(other_hash, rec->ip)) | 1403 | if (!other_hash || !ftrace_lookup_ip(other_hash, rec->ip)) |
1364 | match = 1; | 1404 | match = 1; |
1365 | } else { | 1405 | } else { |
1366 | in_hash = hash && !!ftrace_lookup_ip(hash, rec->ip); | 1406 | in_hash = !!ftrace_lookup_ip(hash, rec->ip); |
1367 | in_other_hash = other_hash && !!ftrace_lookup_ip(other_hash, rec->ip); | 1407 | in_other_hash = !!ftrace_lookup_ip(other_hash, rec->ip); |
1368 | 1408 | ||
1369 | /* | 1409 | /* |
1370 | * | 1410 | * |
@@ -1372,7 +1412,7 @@ static void __ftrace_hash_rec_update(struct ftrace_ops *ops, | |||
1372 | if (filter_hash && in_hash && !in_other_hash) | 1412 | if (filter_hash && in_hash && !in_other_hash) |
1373 | match = 1; | 1413 | match = 1; |
1374 | else if (!filter_hash && in_hash && | 1414 | else if (!filter_hash && in_hash && |
1375 | (in_other_hash || !other_hash->count)) | 1415 | (in_other_hash || ftrace_hash_empty(other_hash))) |
1376 | match = 1; | 1416 | match = 1; |
1377 | } | 1417 | } |
1378 | if (!match) | 1418 | if (!match) |
@@ -1406,40 +1446,12 @@ static void ftrace_hash_rec_enable(struct ftrace_ops *ops, | |||
1406 | __ftrace_hash_rec_update(ops, filter_hash, 1); | 1446 | __ftrace_hash_rec_update(ops, filter_hash, 1); |
1407 | } | 1447 | } |
1408 | 1448 | ||
1409 | static void ftrace_free_rec(struct dyn_ftrace *rec) | ||
1410 | { | ||
1411 | rec->freelist = ftrace_free_records; | ||
1412 | ftrace_free_records = rec; | ||
1413 | rec->flags |= FTRACE_FL_FREE; | ||
1414 | } | ||
1415 | |||
1416 | static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip) | 1449 | static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip) |
1417 | { | 1450 | { |
1418 | struct dyn_ftrace *rec; | 1451 | if (ftrace_pages->index == ftrace_pages->size) { |
1419 | 1452 | /* We should have allocated enough */ | |
1420 | /* First check for freed records */ | 1453 | if (WARN_ON(!ftrace_pages->next)) |
1421 | if (ftrace_free_records) { | ||
1422 | rec = ftrace_free_records; | ||
1423 | |||
1424 | if (unlikely(!(rec->flags & FTRACE_FL_FREE))) { | ||
1425 | FTRACE_WARN_ON_ONCE(1); | ||
1426 | ftrace_free_records = NULL; | ||
1427 | return NULL; | 1454 | return NULL; |
1428 | } | ||
1429 | |||
1430 | ftrace_free_records = rec->freelist; | ||
1431 | memset(rec, 0, sizeof(*rec)); | ||
1432 | return rec; | ||
1433 | } | ||
1434 | |||
1435 | if (ftrace_pages->index == ENTRIES_PER_PAGE) { | ||
1436 | if (!ftrace_pages->next) { | ||
1437 | /* allocate another page */ | ||
1438 | ftrace_pages->next = | ||
1439 | (void *)get_zeroed_page(GFP_KERNEL); | ||
1440 | if (!ftrace_pages->next) | ||
1441 | return NULL; | ||
1442 | } | ||
1443 | ftrace_pages = ftrace_pages->next; | 1455 | ftrace_pages = ftrace_pages->next; |
1444 | } | 1456 | } |
1445 | 1457 | ||
@@ -1459,8 +1471,6 @@ ftrace_record_ip(unsigned long ip) | |||
1459 | return NULL; | 1471 | return NULL; |
1460 | 1472 | ||
1461 | rec->ip = ip; | 1473 | rec->ip = ip; |
1462 | rec->newlist = ftrace_new_addrs; | ||
1463 | ftrace_new_addrs = rec; | ||
1464 | 1474 | ||
1465 | return rec; | 1475 | return rec; |
1466 | } | 1476 | } |
@@ -1475,7 +1485,19 @@ static void print_ip_ins(const char *fmt, unsigned char *p) | |||
1475 | printk(KERN_CONT "%s%02x", i ? ":" : "", p[i]); | 1485 | printk(KERN_CONT "%s%02x", i ? ":" : "", p[i]); |
1476 | } | 1486 | } |
1477 | 1487 | ||
1478 | static void ftrace_bug(int failed, unsigned long ip) | 1488 | /** |
1489 | * ftrace_bug - report and shutdown function tracer | ||
1490 | * @failed: The failed type (EFAULT, EINVAL, EPERM) | ||
1491 | * @ip: The address that failed | ||
1492 | * | ||
1493 | * The arch code that enables or disables the function tracing | ||
1494 | * can call ftrace_bug() when it has detected a problem in | ||
1495 | * modifying the code. @failed should be one of either: | ||
1496 | * EFAULT - if the problem happens on reading the @ip address | ||
1497 | * EINVAL - if what is read at @ip is not what was expected | ||
1498 | * EPERM - if the problem happens on writting to the @ip address | ||
1499 | */ | ||
1500 | void ftrace_bug(int failed, unsigned long ip) | ||
1479 | { | 1501 | { |
1480 | switch (failed) { | 1502 | switch (failed) { |
1481 | case -EFAULT: | 1503 | case -EFAULT: |
@@ -1517,24 +1539,19 @@ int ftrace_text_reserved(void *start, void *end) | |||
1517 | return 0; | 1539 | return 0; |
1518 | } | 1540 | } |
1519 | 1541 | ||
1520 | 1542 | static int ftrace_check_record(struct dyn_ftrace *rec, int enable, int update) | |
1521 | static int | ||
1522 | __ftrace_replace_code(struct dyn_ftrace *rec, int enable) | ||
1523 | { | 1543 | { |
1524 | unsigned long ftrace_addr; | ||
1525 | unsigned long flag = 0UL; | 1544 | unsigned long flag = 0UL; |
1526 | 1545 | ||
1527 | ftrace_addr = (unsigned long)FTRACE_ADDR; | ||
1528 | |||
1529 | /* | 1546 | /* |
1530 | * If we are enabling tracing: | 1547 | * If we are updating calls: |
1531 | * | 1548 | * |
1532 | * If the record has a ref count, then we need to enable it | 1549 | * If the record has a ref count, then we need to enable it |
1533 | * because someone is using it. | 1550 | * because someone is using it. |
1534 | * | 1551 | * |
1535 | * Otherwise we make sure its disabled. | 1552 | * Otherwise we make sure its disabled. |
1536 | * | 1553 | * |
1537 | * If we are disabling tracing, then disable all records that | 1554 | * If we are disabling calls, then disable all records that |
1538 | * are enabled. | 1555 | * are enabled. |
1539 | */ | 1556 | */ |
1540 | if (enable && (rec->flags & ~FTRACE_FL_MASK)) | 1557 | if (enable && (rec->flags & ~FTRACE_FL_MASK)) |
@@ -1542,18 +1559,72 @@ __ftrace_replace_code(struct dyn_ftrace *rec, int enable) | |||
1542 | 1559 | ||
1543 | /* If the state of this record hasn't changed, then do nothing */ | 1560 | /* If the state of this record hasn't changed, then do nothing */ |
1544 | if ((rec->flags & FTRACE_FL_ENABLED) == flag) | 1561 | if ((rec->flags & FTRACE_FL_ENABLED) == flag) |
1545 | return 0; | 1562 | return FTRACE_UPDATE_IGNORE; |
1546 | 1563 | ||
1547 | if (flag) { | 1564 | if (flag) { |
1548 | rec->flags |= FTRACE_FL_ENABLED; | 1565 | if (update) |
1566 | rec->flags |= FTRACE_FL_ENABLED; | ||
1567 | return FTRACE_UPDATE_MAKE_CALL; | ||
1568 | } | ||
1569 | |||
1570 | if (update) | ||
1571 | rec->flags &= ~FTRACE_FL_ENABLED; | ||
1572 | |||
1573 | return FTRACE_UPDATE_MAKE_NOP; | ||
1574 | } | ||
1575 | |||
1576 | /** | ||
1577 | * ftrace_update_record, set a record that now is tracing or not | ||
1578 | * @rec: the record to update | ||
1579 | * @enable: set to 1 if the record is tracing, zero to force disable | ||
1580 | * | ||
1581 | * The records that represent all functions that can be traced need | ||
1582 | * to be updated when tracing has been enabled. | ||
1583 | */ | ||
1584 | int ftrace_update_record(struct dyn_ftrace *rec, int enable) | ||
1585 | { | ||
1586 | return ftrace_check_record(rec, enable, 1); | ||
1587 | } | ||
1588 | |||
1589 | /** | ||
1590 | * ftrace_test_record, check if the record has been enabled or not | ||
1591 | * @rec: the record to test | ||
1592 | * @enable: set to 1 to check if enabled, 0 if it is disabled | ||
1593 | * | ||
1594 | * The arch code may need to test if a record is already set to | ||
1595 | * tracing to determine how to modify the function code that it | ||
1596 | * represents. | ||
1597 | */ | ||
1598 | int ftrace_test_record(struct dyn_ftrace *rec, int enable) | ||
1599 | { | ||
1600 | return ftrace_check_record(rec, enable, 0); | ||
1601 | } | ||
1602 | |||
1603 | static int | ||
1604 | __ftrace_replace_code(struct dyn_ftrace *rec, int enable) | ||
1605 | { | ||
1606 | unsigned long ftrace_addr; | ||
1607 | int ret; | ||
1608 | |||
1609 | ftrace_addr = (unsigned long)FTRACE_ADDR; | ||
1610 | |||
1611 | ret = ftrace_update_record(rec, enable); | ||
1612 | |||
1613 | switch (ret) { | ||
1614 | case FTRACE_UPDATE_IGNORE: | ||
1615 | return 0; | ||
1616 | |||
1617 | case FTRACE_UPDATE_MAKE_CALL: | ||
1549 | return ftrace_make_call(rec, ftrace_addr); | 1618 | return ftrace_make_call(rec, ftrace_addr); |
1619 | |||
1620 | case FTRACE_UPDATE_MAKE_NOP: | ||
1621 | return ftrace_make_nop(NULL, rec, ftrace_addr); | ||
1550 | } | 1622 | } |
1551 | 1623 | ||
1552 | rec->flags &= ~FTRACE_FL_ENABLED; | 1624 | return -1; /* unknow ftrace bug */ |
1553 | return ftrace_make_nop(NULL, rec, ftrace_addr); | ||
1554 | } | 1625 | } |
1555 | 1626 | ||
1556 | static void ftrace_replace_code(int enable) | 1627 | static void ftrace_replace_code(int update) |
1557 | { | 1628 | { |
1558 | struct dyn_ftrace *rec; | 1629 | struct dyn_ftrace *rec; |
1559 | struct ftrace_page *pg; | 1630 | struct ftrace_page *pg; |
@@ -1563,11 +1634,7 @@ static void ftrace_replace_code(int enable) | |||
1563 | return; | 1634 | return; |
1564 | 1635 | ||
1565 | do_for_each_ftrace_rec(pg, rec) { | 1636 | do_for_each_ftrace_rec(pg, rec) { |
1566 | /* Skip over free records */ | 1637 | failed = __ftrace_replace_code(rec, update); |
1567 | if (rec->flags & FTRACE_FL_FREE) | ||
1568 | continue; | ||
1569 | |||
1570 | failed = __ftrace_replace_code(rec, enable); | ||
1571 | if (failed) { | 1638 | if (failed) { |
1572 | ftrace_bug(failed, rec->ip); | 1639 | ftrace_bug(failed, rec->ip); |
1573 | /* Stop processing */ | 1640 | /* Stop processing */ |
@@ -1576,6 +1643,78 @@ static void ftrace_replace_code(int enable) | |||
1576 | } while_for_each_ftrace_rec(); | 1643 | } while_for_each_ftrace_rec(); |
1577 | } | 1644 | } |
1578 | 1645 | ||
1646 | struct ftrace_rec_iter { | ||
1647 | struct ftrace_page *pg; | ||
1648 | int index; | ||
1649 | }; | ||
1650 | |||
1651 | /** | ||
1652 | * ftrace_rec_iter_start, start up iterating over traced functions | ||
1653 | * | ||
1654 | * Returns an iterator handle that is used to iterate over all | ||
1655 | * the records that represent address locations where functions | ||
1656 | * are traced. | ||
1657 | * | ||
1658 | * May return NULL if no records are available. | ||
1659 | */ | ||
1660 | struct ftrace_rec_iter *ftrace_rec_iter_start(void) | ||
1661 | { | ||
1662 | /* | ||
1663 | * We only use a single iterator. | ||
1664 | * Protected by the ftrace_lock mutex. | ||
1665 | */ | ||
1666 | static struct ftrace_rec_iter ftrace_rec_iter; | ||
1667 | struct ftrace_rec_iter *iter = &ftrace_rec_iter; | ||
1668 | |||
1669 | iter->pg = ftrace_pages_start; | ||
1670 | iter->index = 0; | ||
1671 | |||
1672 | /* Could have empty pages */ | ||
1673 | while (iter->pg && !iter->pg->index) | ||
1674 | iter->pg = iter->pg->next; | ||
1675 | |||
1676 | if (!iter->pg) | ||
1677 | return NULL; | ||
1678 | |||
1679 | return iter; | ||
1680 | } | ||
1681 | |||
1682 | /** | ||
1683 | * ftrace_rec_iter_next, get the next record to process. | ||
1684 | * @iter: The handle to the iterator. | ||
1685 | * | ||
1686 | * Returns the next iterator after the given iterator @iter. | ||
1687 | */ | ||
1688 | struct ftrace_rec_iter *ftrace_rec_iter_next(struct ftrace_rec_iter *iter) | ||
1689 | { | ||
1690 | iter->index++; | ||
1691 | |||
1692 | if (iter->index >= iter->pg->index) { | ||
1693 | iter->pg = iter->pg->next; | ||
1694 | iter->index = 0; | ||
1695 | |||
1696 | /* Could have empty pages */ | ||
1697 | while (iter->pg && !iter->pg->index) | ||
1698 | iter->pg = iter->pg->next; | ||
1699 | } | ||
1700 | |||
1701 | if (!iter->pg) | ||
1702 | return NULL; | ||
1703 | |||
1704 | return iter; | ||
1705 | } | ||
1706 | |||
1707 | /** | ||
1708 | * ftrace_rec_iter_record, get the record at the iterator location | ||
1709 | * @iter: The current iterator location | ||
1710 | * | ||
1711 | * Returns the record that the current @iter is at. | ||
1712 | */ | ||
1713 | struct dyn_ftrace *ftrace_rec_iter_record(struct ftrace_rec_iter *iter) | ||
1714 | { | ||
1715 | return &iter->pg->records[iter->index]; | ||
1716 | } | ||
1717 | |||
1579 | static int | 1718 | static int |
1580 | ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec) | 1719 | ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec) |
1581 | { | 1720 | { |
@@ -1617,13 +1756,7 @@ static int __ftrace_modify_code(void *data) | |||
1617 | { | 1756 | { |
1618 | int *command = data; | 1757 | int *command = data; |
1619 | 1758 | ||
1620 | /* | 1759 | if (*command & FTRACE_UPDATE_CALLS) |
1621 | * Do not call function tracer while we update the code. | ||
1622 | * We are in stop machine, no worrying about races. | ||
1623 | */ | ||
1624 | function_trace_stop++; | ||
1625 | |||
1626 | if (*command & FTRACE_ENABLE_CALLS) | ||
1627 | ftrace_replace_code(1); | 1760 | ftrace_replace_code(1); |
1628 | else if (*command & FTRACE_DISABLE_CALLS) | 1761 | else if (*command & FTRACE_DISABLE_CALLS) |
1629 | ftrace_replace_code(0); | 1762 | ftrace_replace_code(0); |
@@ -1636,21 +1769,33 @@ static int __ftrace_modify_code(void *data) | |||
1636 | else if (*command & FTRACE_STOP_FUNC_RET) | 1769 | else if (*command & FTRACE_STOP_FUNC_RET) |
1637 | ftrace_disable_ftrace_graph_caller(); | 1770 | ftrace_disable_ftrace_graph_caller(); |
1638 | 1771 | ||
1639 | #ifndef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST | ||
1640 | /* | ||
1641 | * For archs that call ftrace_test_stop_func(), we must | ||
1642 | * wait till after we update all the function callers | ||
1643 | * before we update the callback. This keeps different | ||
1644 | * ops that record different functions from corrupting | ||
1645 | * each other. | ||
1646 | */ | ||
1647 | __ftrace_trace_function = __ftrace_trace_function_delay; | ||
1648 | #endif | ||
1649 | function_trace_stop--; | ||
1650 | |||
1651 | return 0; | 1772 | return 0; |
1652 | } | 1773 | } |
1653 | 1774 | ||
1775 | /** | ||
1776 | * ftrace_run_stop_machine, go back to the stop machine method | ||
1777 | * @command: The command to tell ftrace what to do | ||
1778 | * | ||
1779 | * If an arch needs to fall back to the stop machine method, the | ||
1780 | * it can call this function. | ||
1781 | */ | ||
1782 | void ftrace_run_stop_machine(int command) | ||
1783 | { | ||
1784 | stop_machine(__ftrace_modify_code, &command, NULL); | ||
1785 | } | ||
1786 | |||
1787 | /** | ||
1788 | * arch_ftrace_update_code, modify the code to trace or not trace | ||
1789 | * @command: The command that needs to be done | ||
1790 | * | ||
1791 | * Archs can override this function if it does not need to | ||
1792 | * run stop_machine() to modify code. | ||
1793 | */ | ||
1794 | void __weak arch_ftrace_update_code(int command) | ||
1795 | { | ||
1796 | ftrace_run_stop_machine(command); | ||
1797 | } | ||
1798 | |||
1654 | static void ftrace_run_update_code(int command) | 1799 | static void ftrace_run_update_code(int command) |
1655 | { | 1800 | { |
1656 | int ret; | 1801 | int ret; |
@@ -1659,8 +1804,31 @@ static void ftrace_run_update_code(int command) | |||
1659 | FTRACE_WARN_ON(ret); | 1804 | FTRACE_WARN_ON(ret); |
1660 | if (ret) | 1805 | if (ret) |
1661 | return; | 1806 | return; |
1807 | /* | ||
1808 | * Do not call function tracer while we update the code. | ||
1809 | * We are in stop machine. | ||
1810 | */ | ||
1811 | function_trace_stop++; | ||
1662 | 1812 | ||
1663 | stop_machine(__ftrace_modify_code, &command, NULL); | 1813 | /* |
1814 | * By default we use stop_machine() to modify the code. | ||
1815 | * But archs can do what ever they want as long as it | ||
1816 | * is safe. The stop_machine() is the safest, but also | ||
1817 | * produces the most overhead. | ||
1818 | */ | ||
1819 | arch_ftrace_update_code(command); | ||
1820 | |||
1821 | #ifndef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST | ||
1822 | /* | ||
1823 | * For archs that call ftrace_test_stop_func(), we must | ||
1824 | * wait till after we update all the function callers | ||
1825 | * before we update the callback. This keeps different | ||
1826 | * ops that record different functions from corrupting | ||
1827 | * each other. | ||
1828 | */ | ||
1829 | __ftrace_trace_function = __ftrace_trace_function_delay; | ||
1830 | #endif | ||
1831 | function_trace_stop--; | ||
1664 | 1832 | ||
1665 | ret = ftrace_arch_code_modify_post_process(); | 1833 | ret = ftrace_arch_code_modify_post_process(); |
1666 | FTRACE_WARN_ON(ret); | 1834 | FTRACE_WARN_ON(ret); |
@@ -1691,7 +1859,7 @@ static int ftrace_startup(struct ftrace_ops *ops, int command) | |||
1691 | return -ENODEV; | 1859 | return -ENODEV; |
1692 | 1860 | ||
1693 | ftrace_start_up++; | 1861 | ftrace_start_up++; |
1694 | command |= FTRACE_ENABLE_CALLS; | 1862 | command |= FTRACE_UPDATE_CALLS; |
1695 | 1863 | ||
1696 | /* ops marked global share the filter hashes */ | 1864 | /* ops marked global share the filter hashes */ |
1697 | if (ops->flags & FTRACE_OPS_FL_GLOBAL) { | 1865 | if (ops->flags & FTRACE_OPS_FL_GLOBAL) { |
@@ -1743,8 +1911,7 @@ static void ftrace_shutdown(struct ftrace_ops *ops, int command) | |||
1743 | if (ops != &global_ops || !global_start_up) | 1911 | if (ops != &global_ops || !global_start_up) |
1744 | ops->flags &= ~FTRACE_OPS_FL_ENABLED; | 1912 | ops->flags &= ~FTRACE_OPS_FL_ENABLED; |
1745 | 1913 | ||
1746 | if (!ftrace_start_up) | 1914 | command |= FTRACE_UPDATE_CALLS; |
1747 | command |= FTRACE_DISABLE_CALLS; | ||
1748 | 1915 | ||
1749 | if (saved_ftrace_func != ftrace_trace_function) { | 1916 | if (saved_ftrace_func != ftrace_trace_function) { |
1750 | saved_ftrace_func = ftrace_trace_function; | 1917 | saved_ftrace_func = ftrace_trace_function; |
@@ -1766,7 +1933,7 @@ static void ftrace_startup_sysctl(void) | |||
1766 | saved_ftrace_func = NULL; | 1933 | saved_ftrace_func = NULL; |
1767 | /* ftrace_start_up is true if we want ftrace running */ | 1934 | /* ftrace_start_up is true if we want ftrace running */ |
1768 | if (ftrace_start_up) | 1935 | if (ftrace_start_up) |
1769 | ftrace_run_update_code(FTRACE_ENABLE_CALLS); | 1936 | ftrace_run_update_code(FTRACE_UPDATE_CALLS); |
1770 | } | 1937 | } |
1771 | 1938 | ||
1772 | static void ftrace_shutdown_sysctl(void) | 1939 | static void ftrace_shutdown_sysctl(void) |
@@ -1788,14 +1955,16 @@ static int ops_traces_mod(struct ftrace_ops *ops) | |||
1788 | struct ftrace_hash *hash; | 1955 | struct ftrace_hash *hash; |
1789 | 1956 | ||
1790 | hash = ops->filter_hash; | 1957 | hash = ops->filter_hash; |
1791 | return !!(!hash || !hash->count); | 1958 | return ftrace_hash_empty(hash); |
1792 | } | 1959 | } |
1793 | 1960 | ||
1794 | static int ftrace_update_code(struct module *mod) | 1961 | static int ftrace_update_code(struct module *mod) |
1795 | { | 1962 | { |
1963 | struct ftrace_page *pg; | ||
1796 | struct dyn_ftrace *p; | 1964 | struct dyn_ftrace *p; |
1797 | cycle_t start, stop; | 1965 | cycle_t start, stop; |
1798 | unsigned long ref = 0; | 1966 | unsigned long ref = 0; |
1967 | int i; | ||
1799 | 1968 | ||
1800 | /* | 1969 | /* |
1801 | * When adding a module, we need to check if tracers are | 1970 | * When adding a module, we need to check if tracers are |
@@ -1817,46 +1986,44 @@ static int ftrace_update_code(struct module *mod) | |||
1817 | start = ftrace_now(raw_smp_processor_id()); | 1986 | start = ftrace_now(raw_smp_processor_id()); |
1818 | ftrace_update_cnt = 0; | 1987 | ftrace_update_cnt = 0; |
1819 | 1988 | ||
1820 | while (ftrace_new_addrs) { | 1989 | for (pg = ftrace_new_pgs; pg; pg = pg->next) { |
1821 | 1990 | ||
1822 | /* If something went wrong, bail without enabling anything */ | 1991 | for (i = 0; i < pg->index; i++) { |
1823 | if (unlikely(ftrace_disabled)) | 1992 | /* If something went wrong, bail without enabling anything */ |
1824 | return -1; | 1993 | if (unlikely(ftrace_disabled)) |
1994 | return -1; | ||
1825 | 1995 | ||
1826 | p = ftrace_new_addrs; | 1996 | p = &pg->records[i]; |
1827 | ftrace_new_addrs = p->newlist; | 1997 | p->flags = ref; |
1828 | p->flags = ref; | ||
1829 | 1998 | ||
1830 | /* | 1999 | /* |
1831 | * Do the initial record conversion from mcount jump | 2000 | * Do the initial record conversion from mcount jump |
1832 | * to the NOP instructions. | 2001 | * to the NOP instructions. |
1833 | */ | 2002 | */ |
1834 | if (!ftrace_code_disable(mod, p)) { | 2003 | if (!ftrace_code_disable(mod, p)) |
1835 | ftrace_free_rec(p); | 2004 | break; |
1836 | /* Game over */ | ||
1837 | break; | ||
1838 | } | ||
1839 | 2005 | ||
1840 | ftrace_update_cnt++; | 2006 | ftrace_update_cnt++; |
1841 | 2007 | ||
1842 | /* | 2008 | /* |
1843 | * If the tracing is enabled, go ahead and enable the record. | 2009 | * If the tracing is enabled, go ahead and enable the record. |
1844 | * | 2010 | * |
1845 | * The reason not to enable the record immediatelly is the | 2011 | * The reason not to enable the record immediatelly is the |
1846 | * inherent check of ftrace_make_nop/ftrace_make_call for | 2012 | * inherent check of ftrace_make_nop/ftrace_make_call for |
1847 | * correct previous instructions. Making first the NOP | 2013 | * correct previous instructions. Making first the NOP |
1848 | * conversion puts the module to the correct state, thus | 2014 | * conversion puts the module to the correct state, thus |
1849 | * passing the ftrace_make_call check. | 2015 | * passing the ftrace_make_call check. |
1850 | */ | 2016 | */ |
1851 | if (ftrace_start_up && ref) { | 2017 | if (ftrace_start_up && ref) { |
1852 | int failed = __ftrace_replace_code(p, 1); | 2018 | int failed = __ftrace_replace_code(p, 1); |
1853 | if (failed) { | 2019 | if (failed) |
1854 | ftrace_bug(failed, p->ip); | 2020 | ftrace_bug(failed, p->ip); |
1855 | ftrace_free_rec(p); | ||
1856 | } | 2021 | } |
1857 | } | 2022 | } |
1858 | } | 2023 | } |
1859 | 2024 | ||
2025 | ftrace_new_pgs = NULL; | ||
2026 | |||
1860 | stop = ftrace_now(raw_smp_processor_id()); | 2027 | stop = ftrace_now(raw_smp_processor_id()); |
1861 | ftrace_update_time = stop - start; | 2028 | ftrace_update_time = stop - start; |
1862 | ftrace_update_tot_cnt += ftrace_update_cnt; | 2029 | ftrace_update_tot_cnt += ftrace_update_cnt; |
@@ -1864,57 +2031,108 @@ static int ftrace_update_code(struct module *mod) | |||
1864 | return 0; | 2031 | return 0; |
1865 | } | 2032 | } |
1866 | 2033 | ||
1867 | static int __init ftrace_dyn_table_alloc(unsigned long num_to_init) | 2034 | static int ftrace_allocate_records(struct ftrace_page *pg, int count) |
1868 | { | 2035 | { |
1869 | struct ftrace_page *pg; | 2036 | int order; |
1870 | int cnt; | 2037 | int cnt; |
1871 | int i; | ||
1872 | 2038 | ||
1873 | /* allocate a few pages */ | 2039 | if (WARN_ON(!count)) |
1874 | ftrace_pages_start = (void *)get_zeroed_page(GFP_KERNEL); | 2040 | return -EINVAL; |
1875 | if (!ftrace_pages_start) | 2041 | |
1876 | return -1; | 2042 | order = get_count_order(DIV_ROUND_UP(count, ENTRIES_PER_PAGE)); |
1877 | 2043 | ||
1878 | /* | 2044 | /* |
1879 | * Allocate a few more pages. | 2045 | * We want to fill as much as possible. No more than a page |
1880 | * | 2046 | * may be empty. |
1881 | * TODO: have some parser search vmlinux before | ||
1882 | * final linking to find all calls to ftrace. | ||
1883 | * Then we can: | ||
1884 | * a) know how many pages to allocate. | ||
1885 | * and/or | ||
1886 | * b) set up the table then. | ||
1887 | * | ||
1888 | * The dynamic code is still necessary for | ||
1889 | * modules. | ||
1890 | */ | 2047 | */ |
2048 | while ((PAGE_SIZE << order) / ENTRY_SIZE >= count + ENTRIES_PER_PAGE) | ||
2049 | order--; | ||
1891 | 2050 | ||
1892 | pg = ftrace_pages = ftrace_pages_start; | 2051 | again: |
2052 | pg->records = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order); | ||
1893 | 2053 | ||
1894 | cnt = num_to_init / ENTRIES_PER_PAGE; | 2054 | if (!pg->records) { |
1895 | pr_info("ftrace: allocating %ld entries in %d pages\n", | 2055 | /* if we can't allocate this size, try something smaller */ |
1896 | num_to_init, cnt + 1); | 2056 | if (!order) |
2057 | return -ENOMEM; | ||
2058 | order >>= 1; | ||
2059 | goto again; | ||
2060 | } | ||
1897 | 2061 | ||
1898 | for (i = 0; i < cnt; i++) { | 2062 | cnt = (PAGE_SIZE << order) / ENTRY_SIZE; |
1899 | pg->next = (void *)get_zeroed_page(GFP_KERNEL); | 2063 | pg->size = cnt; |
1900 | 2064 | ||
1901 | /* If we fail, we'll try later anyway */ | 2065 | if (cnt > count) |
1902 | if (!pg->next) | 2066 | cnt = count; |
2067 | |||
2068 | return cnt; | ||
2069 | } | ||
2070 | |||
2071 | static struct ftrace_page * | ||
2072 | ftrace_allocate_pages(unsigned long num_to_init) | ||
2073 | { | ||
2074 | struct ftrace_page *start_pg; | ||
2075 | struct ftrace_page *pg; | ||
2076 | int order; | ||
2077 | int cnt; | ||
2078 | |||
2079 | if (!num_to_init) | ||
2080 | return 0; | ||
2081 | |||
2082 | start_pg = pg = kzalloc(sizeof(*pg), GFP_KERNEL); | ||
2083 | if (!pg) | ||
2084 | return NULL; | ||
2085 | |||
2086 | /* | ||
2087 | * Try to allocate as much as possible in one continues | ||
2088 | * location that fills in all of the space. We want to | ||
2089 | * waste as little space as possible. | ||
2090 | */ | ||
2091 | for (;;) { | ||
2092 | cnt = ftrace_allocate_records(pg, num_to_init); | ||
2093 | if (cnt < 0) | ||
2094 | goto free_pages; | ||
2095 | |||
2096 | num_to_init -= cnt; | ||
2097 | if (!num_to_init) | ||
1903 | break; | 2098 | break; |
1904 | 2099 | ||
2100 | pg->next = kzalloc(sizeof(*pg), GFP_KERNEL); | ||
2101 | if (!pg->next) | ||
2102 | goto free_pages; | ||
2103 | |||
1905 | pg = pg->next; | 2104 | pg = pg->next; |
1906 | } | 2105 | } |
1907 | 2106 | ||
1908 | return 0; | 2107 | return start_pg; |
2108 | |||
2109 | free_pages: | ||
2110 | while (start_pg) { | ||
2111 | order = get_count_order(pg->size / ENTRIES_PER_PAGE); | ||
2112 | free_pages((unsigned long)pg->records, order); | ||
2113 | start_pg = pg->next; | ||
2114 | kfree(pg); | ||
2115 | pg = start_pg; | ||
2116 | } | ||
2117 | pr_info("ftrace: FAILED to allocate memory for functions\n"); | ||
2118 | return NULL; | ||
1909 | } | 2119 | } |
1910 | 2120 | ||
1911 | enum { | 2121 | static int __init ftrace_dyn_table_alloc(unsigned long num_to_init) |
1912 | FTRACE_ITER_FILTER = (1 << 0), | 2122 | { |
1913 | FTRACE_ITER_NOTRACE = (1 << 1), | 2123 | int cnt; |
1914 | FTRACE_ITER_PRINTALL = (1 << 2), | 2124 | |
1915 | FTRACE_ITER_HASH = (1 << 3), | 2125 | if (!num_to_init) { |
1916 | FTRACE_ITER_ENABLED = (1 << 4), | 2126 | pr_info("ftrace: No functions to be traced?\n"); |
1917 | }; | 2127 | return -1; |
2128 | } | ||
2129 | |||
2130 | cnt = num_to_init / ENTRIES_PER_PAGE; | ||
2131 | pr_info("ftrace: allocating %ld entries in %d pages\n", | ||
2132 | num_to_init, cnt + 1); | ||
2133 | |||
2134 | return 0; | ||
2135 | } | ||
1918 | 2136 | ||
1919 | #define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */ | 2137 | #define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */ |
1920 | 2138 | ||
@@ -1980,6 +2198,9 @@ static void *t_hash_start(struct seq_file *m, loff_t *pos) | |||
1980 | void *p = NULL; | 2198 | void *p = NULL; |
1981 | loff_t l; | 2199 | loff_t l; |
1982 | 2200 | ||
2201 | if (!(iter->flags & FTRACE_ITER_DO_HASH)) | ||
2202 | return NULL; | ||
2203 | |||
1983 | if (iter->func_pos > *pos) | 2204 | if (iter->func_pos > *pos) |
1984 | return NULL; | 2205 | return NULL; |
1985 | 2206 | ||
@@ -2023,7 +2244,7 @@ static void * | |||
2023 | t_next(struct seq_file *m, void *v, loff_t *pos) | 2244 | t_next(struct seq_file *m, void *v, loff_t *pos) |
2024 | { | 2245 | { |
2025 | struct ftrace_iterator *iter = m->private; | 2246 | struct ftrace_iterator *iter = m->private; |
2026 | struct ftrace_ops *ops = &global_ops; | 2247 | struct ftrace_ops *ops = iter->ops; |
2027 | struct dyn_ftrace *rec = NULL; | 2248 | struct dyn_ftrace *rec = NULL; |
2028 | 2249 | ||
2029 | if (unlikely(ftrace_disabled)) | 2250 | if (unlikely(ftrace_disabled)) |
@@ -2047,9 +2268,7 @@ t_next(struct seq_file *m, void *v, loff_t *pos) | |||
2047 | } | 2268 | } |
2048 | } else { | 2269 | } else { |
2049 | rec = &iter->pg->records[iter->idx++]; | 2270 | rec = &iter->pg->records[iter->idx++]; |
2050 | if ((rec->flags & FTRACE_FL_FREE) || | 2271 | if (((iter->flags & FTRACE_ITER_FILTER) && |
2051 | |||
2052 | ((iter->flags & FTRACE_ITER_FILTER) && | ||
2053 | !(ftrace_lookup_ip(ops->filter_hash, rec->ip))) || | 2272 | !(ftrace_lookup_ip(ops->filter_hash, rec->ip))) || |
2054 | 2273 | ||
2055 | ((iter->flags & FTRACE_ITER_NOTRACE) && | 2274 | ((iter->flags & FTRACE_ITER_NOTRACE) && |
@@ -2081,7 +2300,7 @@ static void reset_iter_read(struct ftrace_iterator *iter) | |||
2081 | static void *t_start(struct seq_file *m, loff_t *pos) | 2300 | static void *t_start(struct seq_file *m, loff_t *pos) |
2082 | { | 2301 | { |
2083 | struct ftrace_iterator *iter = m->private; | 2302 | struct ftrace_iterator *iter = m->private; |
2084 | struct ftrace_ops *ops = &global_ops; | 2303 | struct ftrace_ops *ops = iter->ops; |
2085 | void *p = NULL; | 2304 | void *p = NULL; |
2086 | loff_t l; | 2305 | loff_t l; |
2087 | 2306 | ||
@@ -2101,7 +2320,8 @@ static void *t_start(struct seq_file *m, loff_t *pos) | |||
2101 | * off, we can short cut and just print out that all | 2320 | * off, we can short cut and just print out that all |
2102 | * functions are enabled. | 2321 | * functions are enabled. |
2103 | */ | 2322 | */ |
2104 | if (iter->flags & FTRACE_ITER_FILTER && !ops->filter_hash->count) { | 2323 | if (iter->flags & FTRACE_ITER_FILTER && |
2324 | ftrace_hash_empty(ops->filter_hash)) { | ||
2105 | if (*pos > 0) | 2325 | if (*pos > 0) |
2106 | return t_hash_start(m, pos); | 2326 | return t_hash_start(m, pos); |
2107 | iter->flags |= FTRACE_ITER_PRINTALL; | 2327 | iter->flags |= FTRACE_ITER_PRINTALL; |
@@ -2126,12 +2346,8 @@ static void *t_start(struct seq_file *m, loff_t *pos) | |||
2126 | break; | 2346 | break; |
2127 | } | 2347 | } |
2128 | 2348 | ||
2129 | if (!p) { | 2349 | if (!p) |
2130 | if (iter->flags & FTRACE_ITER_FILTER) | 2350 | return t_hash_start(m, pos); |
2131 | return t_hash_start(m, pos); | ||
2132 | |||
2133 | return NULL; | ||
2134 | } | ||
2135 | 2351 | ||
2136 | return iter; | 2352 | return iter; |
2137 | } | 2353 | } |
@@ -2189,6 +2405,7 @@ ftrace_avail_open(struct inode *inode, struct file *file) | |||
2189 | return -ENOMEM; | 2405 | return -ENOMEM; |
2190 | 2406 | ||
2191 | iter->pg = ftrace_pages_start; | 2407 | iter->pg = ftrace_pages_start; |
2408 | iter->ops = &global_ops; | ||
2192 | 2409 | ||
2193 | ret = seq_open(file, &show_ftrace_seq_ops); | 2410 | ret = seq_open(file, &show_ftrace_seq_ops); |
2194 | if (!ret) { | 2411 | if (!ret) { |
@@ -2217,6 +2434,7 @@ ftrace_enabled_open(struct inode *inode, struct file *file) | |||
2217 | 2434 | ||
2218 | iter->pg = ftrace_pages_start; | 2435 | iter->pg = ftrace_pages_start; |
2219 | iter->flags = FTRACE_ITER_ENABLED; | 2436 | iter->flags = FTRACE_ITER_ENABLED; |
2437 | iter->ops = &global_ops; | ||
2220 | 2438 | ||
2221 | ret = seq_open(file, &show_ftrace_seq_ops); | 2439 | ret = seq_open(file, &show_ftrace_seq_ops); |
2222 | if (!ret) { | 2440 | if (!ret) { |
@@ -2237,7 +2455,23 @@ static void ftrace_filter_reset(struct ftrace_hash *hash) | |||
2237 | mutex_unlock(&ftrace_lock); | 2455 | mutex_unlock(&ftrace_lock); |
2238 | } | 2456 | } |
2239 | 2457 | ||
2240 | static int | 2458 | /** |
2459 | * ftrace_regex_open - initialize function tracer filter files | ||
2460 | * @ops: The ftrace_ops that hold the hash filters | ||
2461 | * @flag: The type of filter to process | ||
2462 | * @inode: The inode, usually passed in to your open routine | ||
2463 | * @file: The file, usually passed in to your open routine | ||
2464 | * | ||
2465 | * ftrace_regex_open() initializes the filter files for the | ||
2466 | * @ops. Depending on @flag it may process the filter hash or | ||
2467 | * the notrace hash of @ops. With this called from the open | ||
2468 | * routine, you can use ftrace_filter_write() for the write | ||
2469 | * routine if @flag has FTRACE_ITER_FILTER set, or | ||
2470 | * ftrace_notrace_write() if @flag has FTRACE_ITER_NOTRACE set. | ||
2471 | * ftrace_regex_lseek() should be used as the lseek routine, and | ||
2472 | * release must call ftrace_regex_release(). | ||
2473 | */ | ||
2474 | int | ||
2241 | ftrace_regex_open(struct ftrace_ops *ops, int flag, | 2475 | ftrace_regex_open(struct ftrace_ops *ops, int flag, |
2242 | struct inode *inode, struct file *file) | 2476 | struct inode *inode, struct file *file) |
2243 | { | 2477 | { |
@@ -2306,8 +2540,9 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag, | |||
2306 | static int | 2540 | static int |
2307 | ftrace_filter_open(struct inode *inode, struct file *file) | 2541 | ftrace_filter_open(struct inode *inode, struct file *file) |
2308 | { | 2542 | { |
2309 | return ftrace_regex_open(&global_ops, FTRACE_ITER_FILTER, | 2543 | return ftrace_regex_open(&global_ops, |
2310 | inode, file); | 2544 | FTRACE_ITER_FILTER | FTRACE_ITER_DO_HASH, |
2545 | inode, file); | ||
2311 | } | 2546 | } |
2312 | 2547 | ||
2313 | static int | 2548 | static int |
@@ -2317,7 +2552,7 @@ ftrace_notrace_open(struct inode *inode, struct file *file) | |||
2317 | inode, file); | 2552 | inode, file); |
2318 | } | 2553 | } |
2319 | 2554 | ||
2320 | static loff_t | 2555 | loff_t |
2321 | ftrace_regex_lseek(struct file *file, loff_t offset, int origin) | 2556 | ftrace_regex_lseek(struct file *file, loff_t offset, int origin) |
2322 | { | 2557 | { |
2323 | loff_t ret; | 2558 | loff_t ret; |
@@ -2426,7 +2661,6 @@ match_records(struct ftrace_hash *hash, char *buff, | |||
2426 | goto out_unlock; | 2661 | goto out_unlock; |
2427 | 2662 | ||
2428 | do_for_each_ftrace_rec(pg, rec) { | 2663 | do_for_each_ftrace_rec(pg, rec) { |
2429 | |||
2430 | if (ftrace_match_record(rec, mod, search, search_len, type)) { | 2664 | if (ftrace_match_record(rec, mod, search, search_len, type)) { |
2431 | ret = enter_record(hash, rec, not); | 2665 | ret = enter_record(hash, rec, not); |
2432 | if (ret < 0) { | 2666 | if (ret < 0) { |
@@ -2871,14 +3105,14 @@ out_unlock: | |||
2871 | return ret; | 3105 | return ret; |
2872 | } | 3106 | } |
2873 | 3107 | ||
2874 | static ssize_t | 3108 | ssize_t |
2875 | ftrace_filter_write(struct file *file, const char __user *ubuf, | 3109 | ftrace_filter_write(struct file *file, const char __user *ubuf, |
2876 | size_t cnt, loff_t *ppos) | 3110 | size_t cnt, loff_t *ppos) |
2877 | { | 3111 | { |
2878 | return ftrace_regex_write(file, ubuf, cnt, ppos, 1); | 3112 | return ftrace_regex_write(file, ubuf, cnt, ppos, 1); |
2879 | } | 3113 | } |
2880 | 3114 | ||
2881 | static ssize_t | 3115 | ssize_t |
2882 | ftrace_notrace_write(struct file *file, const char __user *ubuf, | 3116 | ftrace_notrace_write(struct file *file, const char __user *ubuf, |
2883 | size_t cnt, loff_t *ppos) | 3117 | size_t cnt, loff_t *ppos) |
2884 | { | 3118 | { |
@@ -2919,7 +3153,7 @@ ftrace_set_regex(struct ftrace_ops *ops, unsigned char *buf, int len, | |||
2919 | ret = ftrace_hash_move(ops, enable, orig_hash, hash); | 3153 | ret = ftrace_hash_move(ops, enable, orig_hash, hash); |
2920 | if (!ret && ops->flags & FTRACE_OPS_FL_ENABLED | 3154 | if (!ret && ops->flags & FTRACE_OPS_FL_ENABLED |
2921 | && ftrace_enabled) | 3155 | && ftrace_enabled) |
2922 | ftrace_run_update_code(FTRACE_ENABLE_CALLS); | 3156 | ftrace_run_update_code(FTRACE_UPDATE_CALLS); |
2923 | 3157 | ||
2924 | mutex_unlock(&ftrace_lock); | 3158 | mutex_unlock(&ftrace_lock); |
2925 | 3159 | ||
@@ -3045,8 +3279,8 @@ static void __init set_ftrace_early_graph(char *buf) | |||
3045 | } | 3279 | } |
3046 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 3280 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
3047 | 3281 | ||
3048 | static void __init | 3282 | void __init |
3049 | set_ftrace_early_filter(struct ftrace_ops *ops, char *buf, int enable) | 3283 | ftrace_set_early_filter(struct ftrace_ops *ops, char *buf, int enable) |
3050 | { | 3284 | { |
3051 | char *func; | 3285 | char *func; |
3052 | 3286 | ||
@@ -3059,17 +3293,16 @@ set_ftrace_early_filter(struct ftrace_ops *ops, char *buf, int enable) | |||
3059 | static void __init set_ftrace_early_filters(void) | 3293 | static void __init set_ftrace_early_filters(void) |
3060 | { | 3294 | { |
3061 | if (ftrace_filter_buf[0]) | 3295 | if (ftrace_filter_buf[0]) |
3062 | set_ftrace_early_filter(&global_ops, ftrace_filter_buf, 1); | 3296 | ftrace_set_early_filter(&global_ops, ftrace_filter_buf, 1); |
3063 | if (ftrace_notrace_buf[0]) | 3297 | if (ftrace_notrace_buf[0]) |
3064 | set_ftrace_early_filter(&global_ops, ftrace_notrace_buf, 0); | 3298 | ftrace_set_early_filter(&global_ops, ftrace_notrace_buf, 0); |
3065 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 3299 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
3066 | if (ftrace_graph_buf[0]) | 3300 | if (ftrace_graph_buf[0]) |
3067 | set_ftrace_early_graph(ftrace_graph_buf); | 3301 | set_ftrace_early_graph(ftrace_graph_buf); |
3068 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 3302 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
3069 | } | 3303 | } |
3070 | 3304 | ||
3071 | static int | 3305 | int ftrace_regex_release(struct inode *inode, struct file *file) |
3072 | ftrace_regex_release(struct inode *inode, struct file *file) | ||
3073 | { | 3306 | { |
3074 | struct seq_file *m = (struct seq_file *)file->private_data; | 3307 | struct seq_file *m = (struct seq_file *)file->private_data; |
3075 | struct ftrace_iterator *iter; | 3308 | struct ftrace_iterator *iter; |
@@ -3107,7 +3340,7 @@ ftrace_regex_release(struct inode *inode, struct file *file) | |||
3107 | orig_hash, iter->hash); | 3340 | orig_hash, iter->hash); |
3108 | if (!ret && (iter->ops->flags & FTRACE_OPS_FL_ENABLED) | 3341 | if (!ret && (iter->ops->flags & FTRACE_OPS_FL_ENABLED) |
3109 | && ftrace_enabled) | 3342 | && ftrace_enabled) |
3110 | ftrace_run_update_code(FTRACE_ENABLE_CALLS); | 3343 | ftrace_run_update_code(FTRACE_UPDATE_CALLS); |
3111 | 3344 | ||
3112 | mutex_unlock(&ftrace_lock); | 3345 | mutex_unlock(&ftrace_lock); |
3113 | } | 3346 | } |
@@ -3270,9 +3503,6 @@ ftrace_set_func(unsigned long *array, int *idx, char *buffer) | |||
3270 | 3503 | ||
3271 | do_for_each_ftrace_rec(pg, rec) { | 3504 | do_for_each_ftrace_rec(pg, rec) { |
3272 | 3505 | ||
3273 | if (rec->flags & FTRACE_FL_FREE) | ||
3274 | continue; | ||
3275 | |||
3276 | if (ftrace_match_record(rec, NULL, search, search_len, type)) { | 3506 | if (ftrace_match_record(rec, NULL, search, search_len, type)) { |
3277 | /* if it is in the array */ | 3507 | /* if it is in the array */ |
3278 | exists = false; | 3508 | exists = false; |
@@ -3381,15 +3611,62 @@ static __init int ftrace_init_dyn_debugfs(struct dentry *d_tracer) | |||
3381 | return 0; | 3611 | return 0; |
3382 | } | 3612 | } |
3383 | 3613 | ||
3614 | static void ftrace_swap_recs(void *a, void *b, int size) | ||
3615 | { | ||
3616 | struct dyn_ftrace *reca = a; | ||
3617 | struct dyn_ftrace *recb = b; | ||
3618 | struct dyn_ftrace t; | ||
3619 | |||
3620 | t = *reca; | ||
3621 | *reca = *recb; | ||
3622 | *recb = t; | ||
3623 | } | ||
3624 | |||
3384 | static int ftrace_process_locs(struct module *mod, | 3625 | static int ftrace_process_locs(struct module *mod, |
3385 | unsigned long *start, | 3626 | unsigned long *start, |
3386 | unsigned long *end) | 3627 | unsigned long *end) |
3387 | { | 3628 | { |
3629 | struct ftrace_page *pg; | ||
3630 | unsigned long count; | ||
3388 | unsigned long *p; | 3631 | unsigned long *p; |
3389 | unsigned long addr; | 3632 | unsigned long addr; |
3390 | unsigned long flags = 0; /* Shut up gcc */ | 3633 | unsigned long flags = 0; /* Shut up gcc */ |
3634 | int ret = -ENOMEM; | ||
3635 | |||
3636 | count = end - start; | ||
3637 | |||
3638 | if (!count) | ||
3639 | return 0; | ||
3640 | |||
3641 | pg = ftrace_allocate_pages(count); | ||
3642 | if (!pg) | ||
3643 | return -ENOMEM; | ||
3391 | 3644 | ||
3392 | mutex_lock(&ftrace_lock); | 3645 | mutex_lock(&ftrace_lock); |
3646 | |||
3647 | /* | ||
3648 | * Core and each module needs their own pages, as | ||
3649 | * modules will free them when they are removed. | ||
3650 | * Force a new page to be allocated for modules. | ||
3651 | */ | ||
3652 | if (!mod) { | ||
3653 | WARN_ON(ftrace_pages || ftrace_pages_start); | ||
3654 | /* First initialization */ | ||
3655 | ftrace_pages = ftrace_pages_start = pg; | ||
3656 | } else { | ||
3657 | if (!ftrace_pages) | ||
3658 | goto out; | ||
3659 | |||
3660 | if (WARN_ON(ftrace_pages->next)) { | ||
3661 | /* Hmm, we have free pages? */ | ||
3662 | while (ftrace_pages->next) | ||
3663 | ftrace_pages = ftrace_pages->next; | ||
3664 | } | ||
3665 | |||
3666 | ftrace_pages->next = pg; | ||
3667 | ftrace_pages = pg; | ||
3668 | } | ||
3669 | |||
3393 | p = start; | 3670 | p = start; |
3394 | while (p < end) { | 3671 | while (p < end) { |
3395 | addr = ftrace_call_adjust(*p++); | 3672 | addr = ftrace_call_adjust(*p++); |
@@ -3401,9 +3678,18 @@ static int ftrace_process_locs(struct module *mod, | |||
3401 | */ | 3678 | */ |
3402 | if (!addr) | 3679 | if (!addr) |
3403 | continue; | 3680 | continue; |
3404 | ftrace_record_ip(addr); | 3681 | if (!ftrace_record_ip(addr)) |
3682 | break; | ||
3405 | } | 3683 | } |
3406 | 3684 | ||
3685 | /* These new locations need to be initialized */ | ||
3686 | ftrace_new_pgs = pg; | ||
3687 | |||
3688 | /* Make each individual set of pages sorted by ips */ | ||
3689 | for (; pg; pg = pg->next) | ||
3690 | sort(pg->records, pg->index, sizeof(struct dyn_ftrace), | ||
3691 | ftrace_cmp_recs, ftrace_swap_recs); | ||
3692 | |||
3407 | /* | 3693 | /* |
3408 | * We only need to disable interrupts on start up | 3694 | * We only need to disable interrupts on start up |
3409 | * because we are modifying code that an interrupt | 3695 | * because we are modifying code that an interrupt |
@@ -3417,32 +3703,55 @@ static int ftrace_process_locs(struct module *mod, | |||
3417 | ftrace_update_code(mod); | 3703 | ftrace_update_code(mod); |
3418 | if (!mod) | 3704 | if (!mod) |
3419 | local_irq_restore(flags); | 3705 | local_irq_restore(flags); |
3706 | ret = 0; | ||
3707 | out: | ||
3420 | mutex_unlock(&ftrace_lock); | 3708 | mutex_unlock(&ftrace_lock); |
3421 | 3709 | ||
3422 | return 0; | 3710 | return ret; |
3423 | } | 3711 | } |
3424 | 3712 | ||
3425 | #ifdef CONFIG_MODULES | 3713 | #ifdef CONFIG_MODULES |
3714 | |||
3715 | #define next_to_ftrace_page(p) container_of(p, struct ftrace_page, next) | ||
3716 | |||
3426 | void ftrace_release_mod(struct module *mod) | 3717 | void ftrace_release_mod(struct module *mod) |
3427 | { | 3718 | { |
3428 | struct dyn_ftrace *rec; | 3719 | struct dyn_ftrace *rec; |
3720 | struct ftrace_page **last_pg; | ||
3429 | struct ftrace_page *pg; | 3721 | struct ftrace_page *pg; |
3722 | int order; | ||
3430 | 3723 | ||
3431 | mutex_lock(&ftrace_lock); | 3724 | mutex_lock(&ftrace_lock); |
3432 | 3725 | ||
3433 | if (ftrace_disabled) | 3726 | if (ftrace_disabled) |
3434 | goto out_unlock; | 3727 | goto out_unlock; |
3435 | 3728 | ||
3436 | do_for_each_ftrace_rec(pg, rec) { | 3729 | /* |
3730 | * Each module has its own ftrace_pages, remove | ||
3731 | * them from the list. | ||
3732 | */ | ||
3733 | last_pg = &ftrace_pages_start; | ||
3734 | for (pg = ftrace_pages_start; pg; pg = *last_pg) { | ||
3735 | rec = &pg->records[0]; | ||
3437 | if (within_module_core(rec->ip, mod)) { | 3736 | if (within_module_core(rec->ip, mod)) { |
3438 | /* | 3737 | /* |
3439 | * rec->ip is changed in ftrace_free_rec() | 3738 | * As core pages are first, the first |
3440 | * It should not between s and e if record was freed. | 3739 | * page should never be a module page. |
3441 | */ | 3740 | */ |
3442 | FTRACE_WARN_ON(rec->flags & FTRACE_FL_FREE); | 3741 | if (WARN_ON(pg == ftrace_pages_start)) |
3443 | ftrace_free_rec(rec); | 3742 | goto out_unlock; |
3444 | } | 3743 | |
3445 | } while_for_each_ftrace_rec(); | 3744 | /* Check if we are deleting the last page */ |
3745 | if (pg == ftrace_pages) | ||
3746 | ftrace_pages = next_to_ftrace_page(last_pg); | ||
3747 | |||
3748 | *last_pg = pg->next; | ||
3749 | order = get_count_order(pg->size / ENTRIES_PER_PAGE); | ||
3750 | free_pages((unsigned long)pg->records, order); | ||
3751 | kfree(pg); | ||
3752 | } else | ||
3753 | last_pg = &pg->next; | ||
3754 | } | ||
3446 | out_unlock: | 3755 | out_unlock: |
3447 | mutex_unlock(&ftrace_lock); | 3756 | mutex_unlock(&ftrace_lock); |
3448 | } | 3757 | } |
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index f04cc3136bd3..24aee7127451 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c | |||
@@ -1738,11 +1738,121 @@ static int replace_system_preds(struct event_subsystem *system, | |||
1738 | return -ENOMEM; | 1738 | return -ENOMEM; |
1739 | } | 1739 | } |
1740 | 1740 | ||
1741 | static int create_filter_start(char *filter_str, bool set_str, | ||
1742 | struct filter_parse_state **psp, | ||
1743 | struct event_filter **filterp) | ||
1744 | { | ||
1745 | struct event_filter *filter; | ||
1746 | struct filter_parse_state *ps = NULL; | ||
1747 | int err = 0; | ||
1748 | |||
1749 | WARN_ON_ONCE(*psp || *filterp); | ||
1750 | |||
1751 | /* allocate everything, and if any fails, free all and fail */ | ||
1752 | filter = __alloc_filter(); | ||
1753 | if (filter && set_str) | ||
1754 | err = replace_filter_string(filter, filter_str); | ||
1755 | |||
1756 | ps = kzalloc(sizeof(*ps), GFP_KERNEL); | ||
1757 | |||
1758 | if (!filter || !ps || err) { | ||
1759 | kfree(ps); | ||
1760 | __free_filter(filter); | ||
1761 | return -ENOMEM; | ||
1762 | } | ||
1763 | |||
1764 | /* we're committed to creating a new filter */ | ||
1765 | *filterp = filter; | ||
1766 | *psp = ps; | ||
1767 | |||
1768 | parse_init(ps, filter_ops, filter_str); | ||
1769 | err = filter_parse(ps); | ||
1770 | if (err && set_str) | ||
1771 | append_filter_err(ps, filter); | ||
1772 | return err; | ||
1773 | } | ||
1774 | |||
1775 | static void create_filter_finish(struct filter_parse_state *ps) | ||
1776 | { | ||
1777 | if (ps) { | ||
1778 | filter_opstack_clear(ps); | ||
1779 | postfix_clear(ps); | ||
1780 | kfree(ps); | ||
1781 | } | ||
1782 | } | ||
1783 | |||
1784 | /** | ||
1785 | * create_filter - create a filter for a ftrace_event_call | ||
1786 | * @call: ftrace_event_call to create a filter for | ||
1787 | * @filter_str: filter string | ||
1788 | * @set_str: remember @filter_str and enable detailed error in filter | ||
1789 | * @filterp: out param for created filter (always updated on return) | ||
1790 | * | ||
1791 | * Creates a filter for @call with @filter_str. If @set_str is %true, | ||
1792 | * @filter_str is copied and recorded in the new filter. | ||
1793 | * | ||
1794 | * On success, returns 0 and *@filterp points to the new filter. On | ||
1795 | * failure, returns -errno and *@filterp may point to %NULL or to a new | ||
1796 | * filter. In the latter case, the returned filter contains error | ||
1797 | * information if @set_str is %true and the caller is responsible for | ||
1798 | * freeing it. | ||
1799 | */ | ||
1800 | static int create_filter(struct ftrace_event_call *call, | ||
1801 | char *filter_str, bool set_str, | ||
1802 | struct event_filter **filterp) | ||
1803 | { | ||
1804 | struct event_filter *filter = NULL; | ||
1805 | struct filter_parse_state *ps = NULL; | ||
1806 | int err; | ||
1807 | |||
1808 | err = create_filter_start(filter_str, set_str, &ps, &filter); | ||
1809 | if (!err) { | ||
1810 | err = replace_preds(call, filter, ps, filter_str, false); | ||
1811 | if (err && set_str) | ||
1812 | append_filter_err(ps, filter); | ||
1813 | } | ||
1814 | create_filter_finish(ps); | ||
1815 | |||
1816 | *filterp = filter; | ||
1817 | return err; | ||
1818 | } | ||
1819 | |||
1820 | /** | ||
1821 | * create_system_filter - create a filter for an event_subsystem | ||
1822 | * @system: event_subsystem to create a filter for | ||
1823 | * @filter_str: filter string | ||
1824 | * @filterp: out param for created filter (always updated on return) | ||
1825 | * | ||
1826 | * Identical to create_filter() except that it creates a subsystem filter | ||
1827 | * and always remembers @filter_str. | ||
1828 | */ | ||
1829 | static int create_system_filter(struct event_subsystem *system, | ||
1830 | char *filter_str, struct event_filter **filterp) | ||
1831 | { | ||
1832 | struct event_filter *filter = NULL; | ||
1833 | struct filter_parse_state *ps = NULL; | ||
1834 | int err; | ||
1835 | |||
1836 | err = create_filter_start(filter_str, true, &ps, &filter); | ||
1837 | if (!err) { | ||
1838 | err = replace_system_preds(system, ps, filter_str); | ||
1839 | if (!err) { | ||
1840 | /* System filters just show a default message */ | ||
1841 | kfree(filter->filter_string); | ||
1842 | filter->filter_string = NULL; | ||
1843 | } else { | ||
1844 | append_filter_err(ps, filter); | ||
1845 | } | ||
1846 | } | ||
1847 | create_filter_finish(ps); | ||
1848 | |||
1849 | *filterp = filter; | ||
1850 | return err; | ||
1851 | } | ||
1852 | |||
1741 | int apply_event_filter(struct ftrace_event_call *call, char *filter_string) | 1853 | int apply_event_filter(struct ftrace_event_call *call, char *filter_string) |
1742 | { | 1854 | { |
1743 | struct filter_parse_state *ps; | ||
1744 | struct event_filter *filter; | 1855 | struct event_filter *filter; |
1745 | struct event_filter *tmp; | ||
1746 | int err = 0; | 1856 | int err = 0; |
1747 | 1857 | ||
1748 | mutex_lock(&event_mutex); | 1858 | mutex_lock(&event_mutex); |
@@ -1759,49 +1869,30 @@ int apply_event_filter(struct ftrace_event_call *call, char *filter_string) | |||
1759 | goto out_unlock; | 1869 | goto out_unlock; |
1760 | } | 1870 | } |
1761 | 1871 | ||
1762 | err = -ENOMEM; | 1872 | err = create_filter(call, filter_string, true, &filter); |
1763 | ps = kzalloc(sizeof(*ps), GFP_KERNEL); | ||
1764 | if (!ps) | ||
1765 | goto out_unlock; | ||
1766 | |||
1767 | filter = __alloc_filter(); | ||
1768 | if (!filter) { | ||
1769 | kfree(ps); | ||
1770 | goto out_unlock; | ||
1771 | } | ||
1772 | |||
1773 | replace_filter_string(filter, filter_string); | ||
1774 | |||
1775 | parse_init(ps, filter_ops, filter_string); | ||
1776 | err = filter_parse(ps); | ||
1777 | if (err) { | ||
1778 | append_filter_err(ps, filter); | ||
1779 | goto out; | ||
1780 | } | ||
1781 | 1873 | ||
1782 | err = replace_preds(call, filter, ps, filter_string, false); | ||
1783 | if (err) { | ||
1784 | filter_disable(call); | ||
1785 | append_filter_err(ps, filter); | ||
1786 | } else | ||
1787 | call->flags |= TRACE_EVENT_FL_FILTERED; | ||
1788 | out: | ||
1789 | /* | 1874 | /* |
1790 | * Always swap the call filter with the new filter | 1875 | * Always swap the call filter with the new filter |
1791 | * even if there was an error. If there was an error | 1876 | * even if there was an error. If there was an error |
1792 | * in the filter, we disable the filter and show the error | 1877 | * in the filter, we disable the filter and show the error |
1793 | * string | 1878 | * string |
1794 | */ | 1879 | */ |
1795 | tmp = call->filter; | 1880 | if (filter) { |
1796 | rcu_assign_pointer(call->filter, filter); | 1881 | struct event_filter *tmp = call->filter; |
1797 | if (tmp) { | 1882 | |
1798 | /* Make sure the call is done with the filter */ | 1883 | if (!err) |
1799 | synchronize_sched(); | 1884 | call->flags |= TRACE_EVENT_FL_FILTERED; |
1800 | __free_filter(tmp); | 1885 | else |
1886 | filter_disable(call); | ||
1887 | |||
1888 | rcu_assign_pointer(call->filter, filter); | ||
1889 | |||
1890 | if (tmp) { | ||
1891 | /* Make sure the call is done with the filter */ | ||
1892 | synchronize_sched(); | ||
1893 | __free_filter(tmp); | ||
1894 | } | ||
1801 | } | 1895 | } |
1802 | filter_opstack_clear(ps); | ||
1803 | postfix_clear(ps); | ||
1804 | kfree(ps); | ||
1805 | out_unlock: | 1896 | out_unlock: |
1806 | mutex_unlock(&event_mutex); | 1897 | mutex_unlock(&event_mutex); |
1807 | 1898 | ||
@@ -1811,7 +1902,6 @@ out_unlock: | |||
1811 | int apply_subsystem_event_filter(struct event_subsystem *system, | 1902 | int apply_subsystem_event_filter(struct event_subsystem *system, |
1812 | char *filter_string) | 1903 | char *filter_string) |
1813 | { | 1904 | { |
1814 | struct filter_parse_state *ps; | ||
1815 | struct event_filter *filter; | 1905 | struct event_filter *filter; |
1816 | int err = 0; | 1906 | int err = 0; |
1817 | 1907 | ||
@@ -1835,48 +1925,19 @@ int apply_subsystem_event_filter(struct event_subsystem *system, | |||
1835 | goto out_unlock; | 1925 | goto out_unlock; |
1836 | } | 1926 | } |
1837 | 1927 | ||
1838 | err = -ENOMEM; | 1928 | err = create_system_filter(system, filter_string, &filter); |
1839 | ps = kzalloc(sizeof(*ps), GFP_KERNEL); | 1929 | if (filter) { |
1840 | if (!ps) | 1930 | /* |
1841 | goto out_unlock; | 1931 | * No event actually uses the system filter |
1842 | 1932 | * we can free it without synchronize_sched(). | |
1843 | filter = __alloc_filter(); | 1933 | */ |
1844 | if (!filter) | 1934 | __free_filter(system->filter); |
1845 | goto out; | 1935 | system->filter = filter; |
1846 | 1936 | } | |
1847 | /* System filters just show a default message */ | ||
1848 | kfree(filter->filter_string); | ||
1849 | filter->filter_string = NULL; | ||
1850 | |||
1851 | /* | ||
1852 | * No event actually uses the system filter | ||
1853 | * we can free it without synchronize_sched(). | ||
1854 | */ | ||
1855 | __free_filter(system->filter); | ||
1856 | system->filter = filter; | ||
1857 | |||
1858 | parse_init(ps, filter_ops, filter_string); | ||
1859 | err = filter_parse(ps); | ||
1860 | if (err) | ||
1861 | goto err_filter; | ||
1862 | |||
1863 | err = replace_system_preds(system, ps, filter_string); | ||
1864 | if (err) | ||
1865 | goto err_filter; | ||
1866 | |||
1867 | out: | ||
1868 | filter_opstack_clear(ps); | ||
1869 | postfix_clear(ps); | ||
1870 | kfree(ps); | ||
1871 | out_unlock: | 1937 | out_unlock: |
1872 | mutex_unlock(&event_mutex); | 1938 | mutex_unlock(&event_mutex); |
1873 | 1939 | ||
1874 | return err; | 1940 | return err; |
1875 | |||
1876 | err_filter: | ||
1877 | replace_filter_string(filter, filter_string); | ||
1878 | append_filter_err(ps, system->filter); | ||
1879 | goto out; | ||
1880 | } | 1941 | } |
1881 | 1942 | ||
1882 | #ifdef CONFIG_PERF_EVENTS | 1943 | #ifdef CONFIG_PERF_EVENTS |
@@ -1894,7 +1955,6 @@ int ftrace_profile_set_filter(struct perf_event *event, int event_id, | |||
1894 | { | 1955 | { |
1895 | int err; | 1956 | int err; |
1896 | struct event_filter *filter; | 1957 | struct event_filter *filter; |
1897 | struct filter_parse_state *ps; | ||
1898 | struct ftrace_event_call *call; | 1958 | struct ftrace_event_call *call; |
1899 | 1959 | ||
1900 | mutex_lock(&event_mutex); | 1960 | mutex_lock(&event_mutex); |
@@ -1909,33 +1969,10 @@ int ftrace_profile_set_filter(struct perf_event *event, int event_id, | |||
1909 | if (event->filter) | 1969 | if (event->filter) |
1910 | goto out_unlock; | 1970 | goto out_unlock; |
1911 | 1971 | ||
1912 | filter = __alloc_filter(); | 1972 | err = create_filter(call, filter_str, false, &filter); |
1913 | if (!filter) { | ||
1914 | err = PTR_ERR(filter); | ||
1915 | goto out_unlock; | ||
1916 | } | ||
1917 | |||
1918 | err = -ENOMEM; | ||
1919 | ps = kzalloc(sizeof(*ps), GFP_KERNEL); | ||
1920 | if (!ps) | ||
1921 | goto free_filter; | ||
1922 | |||
1923 | parse_init(ps, filter_ops, filter_str); | ||
1924 | err = filter_parse(ps); | ||
1925 | if (err) | ||
1926 | goto free_ps; | ||
1927 | |||
1928 | err = replace_preds(call, filter, ps, filter_str, false); | ||
1929 | if (!err) | 1973 | if (!err) |
1930 | event->filter = filter; | 1974 | event->filter = filter; |
1931 | 1975 | else | |
1932 | free_ps: | ||
1933 | filter_opstack_clear(ps); | ||
1934 | postfix_clear(ps); | ||
1935 | kfree(ps); | ||
1936 | |||
1937 | free_filter: | ||
1938 | if (err) | ||
1939 | __free_filter(filter); | 1976 | __free_filter(filter); |
1940 | 1977 | ||
1941 | out_unlock: | 1978 | out_unlock: |
@@ -1954,43 +1991,6 @@ out_unlock: | |||
1954 | #define CREATE_TRACE_POINTS | 1991 | #define CREATE_TRACE_POINTS |
1955 | #include "trace_events_filter_test.h" | 1992 | #include "trace_events_filter_test.h" |
1956 | 1993 | ||
1957 | static int test_get_filter(char *filter_str, struct ftrace_event_call *call, | ||
1958 | struct event_filter **pfilter) | ||
1959 | { | ||
1960 | struct event_filter *filter; | ||
1961 | struct filter_parse_state *ps; | ||
1962 | int err = -ENOMEM; | ||
1963 | |||
1964 | filter = __alloc_filter(); | ||
1965 | if (!filter) | ||
1966 | goto out; | ||
1967 | |||
1968 | ps = kzalloc(sizeof(*ps), GFP_KERNEL); | ||
1969 | if (!ps) | ||
1970 | goto free_filter; | ||
1971 | |||
1972 | parse_init(ps, filter_ops, filter_str); | ||
1973 | err = filter_parse(ps); | ||
1974 | if (err) | ||
1975 | goto free_ps; | ||
1976 | |||
1977 | err = replace_preds(call, filter, ps, filter_str, false); | ||
1978 | if (!err) | ||
1979 | *pfilter = filter; | ||
1980 | |||
1981 | free_ps: | ||
1982 | filter_opstack_clear(ps); | ||
1983 | postfix_clear(ps); | ||
1984 | kfree(ps); | ||
1985 | |||
1986 | free_filter: | ||
1987 | if (err) | ||
1988 | __free_filter(filter); | ||
1989 | |||
1990 | out: | ||
1991 | return err; | ||
1992 | } | ||
1993 | |||
1994 | #define DATA_REC(m, va, vb, vc, vd, ve, vf, vg, vh, nvisit) \ | 1994 | #define DATA_REC(m, va, vb, vc, vd, ve, vf, vg, vh, nvisit) \ |
1995 | { \ | 1995 | { \ |
1996 | .filter = FILTER, \ | 1996 | .filter = FILTER, \ |
@@ -2109,12 +2109,13 @@ static __init int ftrace_test_event_filter(void) | |||
2109 | struct test_filter_data_t *d = &test_filter_data[i]; | 2109 | struct test_filter_data_t *d = &test_filter_data[i]; |
2110 | int err; | 2110 | int err; |
2111 | 2111 | ||
2112 | err = test_get_filter(d->filter, &event_ftrace_test_filter, | 2112 | err = create_filter(&event_ftrace_test_filter, d->filter, |
2113 | &filter); | 2113 | false, &filter); |
2114 | if (err) { | 2114 | if (err) { |
2115 | printk(KERN_INFO | 2115 | printk(KERN_INFO |
2116 | "Failed to get filter for '%s', err %d\n", | 2116 | "Failed to get filter for '%s', err %d\n", |
2117 | d->filter, err); | 2117 | d->filter, err); |
2118 | __free_filter(filter); | ||
2118 | break; | 2119 | break; |
2119 | } | 2120 | } |
2120 | 2121 | ||
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c index 77575b386d97..d4545f49242e 100644 --- a/kernel/trace/trace_stack.c +++ b/kernel/trace/trace_stack.c | |||
@@ -13,6 +13,9 @@ | |||
13 | #include <linux/sysctl.h> | 13 | #include <linux/sysctl.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/fs.h> | 15 | #include <linux/fs.h> |
16 | |||
17 | #include <asm/setup.h> | ||
18 | |||
16 | #include "trace.h" | 19 | #include "trace.h" |
17 | 20 | ||
18 | #define STACK_TRACE_ENTRIES 500 | 21 | #define STACK_TRACE_ENTRIES 500 |
@@ -133,7 +136,6 @@ stack_trace_call(unsigned long ip, unsigned long parent_ip) | |||
133 | static struct ftrace_ops trace_ops __read_mostly = | 136 | static struct ftrace_ops trace_ops __read_mostly = |
134 | { | 137 | { |
135 | .func = stack_trace_call, | 138 | .func = stack_trace_call, |
136 | .flags = FTRACE_OPS_FL_GLOBAL, | ||
137 | }; | 139 | }; |
138 | 140 | ||
139 | static ssize_t | 141 | static ssize_t |
@@ -311,6 +313,21 @@ static const struct file_operations stack_trace_fops = { | |||
311 | .release = seq_release, | 313 | .release = seq_release, |
312 | }; | 314 | }; |
313 | 315 | ||
316 | static int | ||
317 | stack_trace_filter_open(struct inode *inode, struct file *file) | ||
318 | { | ||
319 | return ftrace_regex_open(&trace_ops, FTRACE_ITER_FILTER, | ||
320 | inode, file); | ||
321 | } | ||
322 | |||
323 | static const struct file_operations stack_trace_filter_fops = { | ||
324 | .open = stack_trace_filter_open, | ||
325 | .read = seq_read, | ||
326 | .write = ftrace_filter_write, | ||
327 | .llseek = ftrace_regex_lseek, | ||
328 | .release = ftrace_regex_release, | ||
329 | }; | ||
330 | |||
314 | int | 331 | int |
315 | stack_trace_sysctl(struct ctl_table *table, int write, | 332 | stack_trace_sysctl(struct ctl_table *table, int write, |
316 | void __user *buffer, size_t *lenp, | 333 | void __user *buffer, size_t *lenp, |
@@ -338,8 +355,13 @@ stack_trace_sysctl(struct ctl_table *table, int write, | |||
338 | return ret; | 355 | return ret; |
339 | } | 356 | } |
340 | 357 | ||
358 | static char stack_trace_filter_buf[COMMAND_LINE_SIZE+1] __initdata; | ||
359 | |||
341 | static __init int enable_stacktrace(char *str) | 360 | static __init int enable_stacktrace(char *str) |
342 | { | 361 | { |
362 | if (strncmp(str, "_filter=", 8) == 0) | ||
363 | strncpy(stack_trace_filter_buf, str+8, COMMAND_LINE_SIZE); | ||
364 | |||
343 | stack_tracer_enabled = 1; | 365 | stack_tracer_enabled = 1; |
344 | last_stack_tracer_enabled = 1; | 366 | last_stack_tracer_enabled = 1; |
345 | return 1; | 367 | return 1; |
@@ -358,6 +380,12 @@ static __init int stack_trace_init(void) | |||
358 | trace_create_file("stack_trace", 0444, d_tracer, | 380 | trace_create_file("stack_trace", 0444, d_tracer, |
359 | NULL, &stack_trace_fops); | 381 | NULL, &stack_trace_fops); |
360 | 382 | ||
383 | trace_create_file("stack_trace_filter", 0444, d_tracer, | ||
384 | NULL, &stack_trace_filter_fops); | ||
385 | |||
386 | if (stack_trace_filter_buf[0]) | ||
387 | ftrace_set_early_filter(&trace_ops, stack_trace_filter_buf, 1); | ||
388 | |||
361 | if (stack_tracer_enabled) | 389 | if (stack_tracer_enabled) |
362 | register_ftrace_function(&trace_ops); | 390 | register_ftrace_function(&trace_ops); |
363 | 391 | ||