diff options
author | Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> | 2014-06-17 07:04:42 -0400 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2014-07-01 07:13:34 -0400 |
commit | 5c27c775d5e698d5b754d213747e9fb85290e3b8 (patch) | |
tree | 5bb984d47fddd7d04541ce0c1dda0e68457610d3 /kernel/trace/ftrace.c | |
parent | d8fae2f64433cbe7f0389f965081348272b61ff9 (diff) |
ftrace: Simplify ftrace_hash_disable/enable path in ftrace_hash_move
Simplify ftrace_hash_disable/enable path in ftrace_hash_move
for hardening the process if the memory allocation failed.
Link: http://lkml.kernel.org/p/20140617110442.15167.81076.stgit@kbuild-fedora.novalocal
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r-- | kernel/trace/ftrace.c | 33 |
1 files changed, 11 insertions, 22 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 3ded796e10e0..8323082dbc21 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -1306,25 +1306,15 @@ ftrace_hash_move(struct ftrace_ops *ops, int enable, | |||
1306 | struct ftrace_hash *new_hash; | 1306 | struct ftrace_hash *new_hash; |
1307 | int size = src->count; | 1307 | int size = src->count; |
1308 | int bits = 0; | 1308 | int bits = 0; |
1309 | int ret; | ||
1310 | int i; | 1309 | int i; |
1311 | 1310 | ||
1312 | /* | 1311 | /* |
1313 | * Remove the current set, update the hash and add | ||
1314 | * them back. | ||
1315 | */ | ||
1316 | ftrace_hash_rec_disable(ops, enable); | ||
1317 | |||
1318 | /* | ||
1319 | * If the new source is empty, just free dst and assign it | 1312 | * If the new source is empty, just free dst and assign it |
1320 | * the empty_hash. | 1313 | * the empty_hash. |
1321 | */ | 1314 | */ |
1322 | if (!src->count) { | 1315 | if (!src->count) { |
1323 | free_ftrace_hash_rcu(*dst); | 1316 | new_hash = EMPTY_HASH; |
1324 | rcu_assign_pointer(*dst, EMPTY_HASH); | 1317 | goto update; |
1325 | /* still need to update the function records */ | ||
1326 | ret = 0; | ||
1327 | goto out; | ||
1328 | } | 1318 | } |
1329 | 1319 | ||
1330 | /* | 1320 | /* |
@@ -1337,10 +1327,9 @@ ftrace_hash_move(struct ftrace_ops *ops, int enable, | |||
1337 | if (bits > FTRACE_HASH_MAX_BITS) | 1327 | if (bits > FTRACE_HASH_MAX_BITS) |
1338 | bits = FTRACE_HASH_MAX_BITS; | 1328 | bits = FTRACE_HASH_MAX_BITS; |
1339 | 1329 | ||
1340 | ret = -ENOMEM; | ||
1341 | new_hash = alloc_ftrace_hash(bits); | 1330 | new_hash = alloc_ftrace_hash(bits); |
1342 | if (!new_hash) | 1331 | if (!new_hash) |
1343 | goto out; | 1332 | return -ENOMEM; |
1344 | 1333 | ||
1345 | size = 1 << src->size_bits; | 1334 | size = 1 << src->size_bits; |
1346 | for (i = 0; i < size; i++) { | 1335 | for (i = 0; i < size; i++) { |
@@ -1351,20 +1340,20 @@ ftrace_hash_move(struct ftrace_ops *ops, int enable, | |||
1351 | } | 1340 | } |
1352 | } | 1341 | } |
1353 | 1342 | ||
1343 | update: | ||
1344 | /* | ||
1345 | * Remove the current set, update the hash and add | ||
1346 | * them back. | ||
1347 | */ | ||
1348 | ftrace_hash_rec_disable(ops, enable); | ||
1349 | |||
1354 | old_hash = *dst; | 1350 | old_hash = *dst; |
1355 | rcu_assign_pointer(*dst, new_hash); | 1351 | rcu_assign_pointer(*dst, new_hash); |
1356 | free_ftrace_hash_rcu(old_hash); | 1352 | free_ftrace_hash_rcu(old_hash); |
1357 | 1353 | ||
1358 | ret = 0; | ||
1359 | out: | ||
1360 | /* | ||
1361 | * Enable regardless of ret: | ||
1362 | * On success, we enable the new hash. | ||
1363 | * On failure, we re-enable the original hash. | ||
1364 | */ | ||
1365 | ftrace_hash_rec_enable(ops, enable); | 1354 | ftrace_hash_rec_enable(ops, enable); |
1366 | 1355 | ||
1367 | return ret; | 1356 | return 0; |
1368 | } | 1357 | } |
1369 | 1358 | ||
1370 | /* | 1359 | /* |