aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>2008-11-14 17:47:35 -0500
committerIngo Molnar <mingo@elte.hu>2008-11-16 03:01:26 -0500
commit2bdba316c989da028a59becf7516c6350ce3c173 (patch)
tree18ee77474c243ebea424b0bdb3e38c444f6f0e0b
parent954e100d2275cb2f150f2b18d5cddcdf67b956ac (diff)
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.c12
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,
653 goto end; 653 goto end;
654 } 654 }
655 mutex_unlock(&markers_mutex); 655 mutex_unlock(&markers_mutex);
656 marker_update_probes(); /* may update entry */ 656 marker_update_probes();
657 mutex_lock(&markers_mutex); 657 mutex_lock(&markers_mutex);
658 entry = get_marker(name); 658 entry = get_marker(name);
659 WARN_ON(!entry); 659 if (!entry)
660 goto end;
660 if (entry->rcu_pending) 661 if (entry->rcu_pending)
661 rcu_barrier_sched(); 662 rcu_barrier_sched();
662 entry->oldptr = old; 663 entry->oldptr = old;
@@ -697,7 +698,7 @@ int marker_probe_unregister(const char *name,
697 rcu_barrier_sched(); 698 rcu_barrier_sched();
698 old = marker_entry_remove_probe(entry, probe, probe_private); 699 old = marker_entry_remove_probe(entry, probe, probe_private);
699 mutex_unlock(&markers_mutex); 700 mutex_unlock(&markers_mutex);
700 marker_update_probes(); /* may update entry */ 701 marker_update_probes();
701 mutex_lock(&markers_mutex); 702 mutex_lock(&markers_mutex);
702 entry = get_marker(name); 703 entry = get_marker(name);
703 if (!entry) 704 if (!entry)
@@ -778,10 +779,11 @@ int marker_probe_unregister_private_data(marker_probe_func *probe,
778 rcu_barrier_sched(); 779 rcu_barrier_sched();
779 old = marker_entry_remove_probe(entry, NULL, probe_private); 780 old = marker_entry_remove_probe(entry, NULL, probe_private);
780 mutex_unlock(&markers_mutex); 781 mutex_unlock(&markers_mutex);
781 marker_update_probes(); /* may update entry */ 782 marker_update_probes();
782 mutex_lock(&markers_mutex); 783 mutex_lock(&markers_mutex);
783 entry = get_marker_from_private_data(probe, probe_private); 784 entry = get_marker_from_private_data(probe, probe_private);
784 WARN_ON(!entry); 785 if (!entry)
786 goto end;
785 if (entry->rcu_pending) 787 if (entry->rcu_pending)
786 rcu_barrier_sched(); 788 rcu_barrier_sched();
787 entry->oldptr = old; 789 entry->oldptr = old;