summaryrefslogtreecommitdiff
path: root/kernel/marker.c
diff options
context:
space:
mode:
authorMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>2008-11-14 22:47:35 (GMT)
committerIngo Molnar <mingo@elte.hu>2008-11-16 08:01:26 (GMT)
commit2bdba316c989da028a59becf7516c6350ce3c173 (patch)
tree18ee77474c243ebea424b0bdb3e38c444f6f0e0b /kernel/marker.c
parent954e100d2275cb2f150f2b18d5cddcdf67b956ac (diff)
downloadlinux-2bdba316c989da028a59becf7516c6350ce3c173.tar.xz
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>
Diffstat (limited to 'kernel/marker.c')
-rw-r--r--kernel/marker.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/kernel/marker.c b/kernel/marker.c
index 2898b64..de683a7 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;