diff options
author | Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> | 2008-11-14 17:47:35 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-11-16 09:01:26 +0100 |
commit | 2bdba316c989da028a59becf7516c6350ce3c173 (patch) | |
tree | 18ee77474c243ebea424b0bdb3e38c444f6f0e0b | |
parent | 954e100d2275cb2f150f2b18d5cddcdf67b956ac (diff) | |
download | linux-2bdba316c989da028a59becf7516c6350ce3c173.tar.gz linux-2bdba316c989da028a59becf7516c6350ce3c173.tar.bz2 linux-2bdba316c989da028a59becf7516c6350ce3c173.zip |
markers: fix unregister
Impact: fix marker registers/unregister race
get_marker() can return a NULL entry because the mutex is released in
the middle of those functions. Make sure we check to see if it has been
concurrently removed.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | kernel/marker.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/kernel/marker.c b/kernel/marker.c index 2898b647d415..de683a7799e7 100644 --- a/kernel/marker.c +++ b/kernel/marker.c @@ -653,10 +653,11 @@ int marker_probe_register(const char *name, const char *format, goto end; } mutex_unlock(&markers_mutex); - marker_update_probes(); /* may update entry */ + marker_update_probes(); mutex_lock(&markers_mutex); entry = get_marker(name); - WARN_ON(!entry); + if (!entry) + goto end; if (entry->rcu_pending) rcu_barrier_sched(); entry->oldptr = old; @@ -697,7 +698,7 @@ int marker_probe_unregister(const char *name, rcu_barrier_sched(); old = marker_entry_remove_probe(entry, probe, probe_private); mutex_unlock(&markers_mutex); - marker_update_probes(); /* may update entry */ + marker_update_probes(); mutex_lock(&markers_mutex); entry = get_marker(name); if (!entry) @@ -778,10 +779,11 @@ int marker_probe_unregister_private_data(marker_probe_func *probe, rcu_barrier_sched(); old = marker_entry_remove_probe(entry, NULL, probe_private); mutex_unlock(&markers_mutex); - marker_update_probes(); /* may update entry */ + marker_update_probes(); mutex_lock(&markers_mutex); entry = get_marker_from_private_data(probe, probe_private); - WARN_ON(!entry); + if (!entry) + goto end; if (entry->rcu_pending) rcu_barrier_sched(); entry->oldptr = old; |