markers: fix unregister
authorMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Fri, 14 Nov 2008 22:47:35 +0000 (17:47 -0500)
committerIngo Molnar <mingo@elte.hu>
Sun, 16 Nov 2008 08:01:26 +0000 (09:01 +0100)
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>
kernel/marker.c

index 2898b64..de683a7 100644 (file)
@@ -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;