aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/marker.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/marker.c')
-rw-r--r--kernel/marker.c37
1 files changed, 18 insertions, 19 deletions
diff --git a/kernel/marker.c b/kernel/marker.c
index 1abfb923b761..7d1faecd7a51 100644
--- a/kernel/marker.c
+++ b/kernel/marker.c
@@ -126,6 +126,11 @@ void marker_probe_cb(const struct marker *mdata, void *call_private, ...)
126 struct marker_probe_closure *multi; 126 struct marker_probe_closure *multi;
127 int i; 127 int i;
128 /* 128 /*
129 * Read mdata->ptype before mdata->multi.
130 */
131 smp_rmb();
132 multi = mdata->multi;
133 /*
129 * multi points to an array, therefore accessing the array 134 * multi points to an array, therefore accessing the array
130 * depends on reading multi. However, even in this case, 135 * depends on reading multi. However, even in this case,
131 * we must insure that the pointer is read _before_ the array 136 * we must insure that the pointer is read _before_ the array
@@ -133,7 +138,6 @@ void marker_probe_cb(const struct marker *mdata, void *call_private, ...)
133 * in the fast path, so put the explicit barrier here. 138 * in the fast path, so put the explicit barrier here.
134 */ 139 */
135 smp_read_barrier_depends(); 140 smp_read_barrier_depends();
136 multi = mdata->multi;
137 for (i = 0; multi[i].func; i++) { 141 for (i = 0; multi[i].func; i++) {
138 va_start(args, call_private); 142 va_start(args, call_private);
139 multi[i].func(multi[i].probe_private, call_private, 143 multi[i].func(multi[i].probe_private, call_private,
@@ -175,6 +179,11 @@ void marker_probe_cb_noarg(const struct marker *mdata, void *call_private, ...)
175 struct marker_probe_closure *multi; 179 struct marker_probe_closure *multi;
176 int i; 180 int i;
177 /* 181 /*
182 * Read mdata->ptype before mdata->multi.
183 */
184 smp_rmb();
185 multi = mdata->multi;
186 /*
178 * multi points to an array, therefore accessing the array 187 * multi points to an array, therefore accessing the array
179 * depends on reading multi. However, even in this case, 188 * depends on reading multi. However, even in this case,
180 * we must insure that the pointer is read _before_ the array 189 * we must insure that the pointer is read _before_ the array
@@ -182,7 +191,6 @@ void marker_probe_cb_noarg(const struct marker *mdata, void *call_private, ...)
182 * in the fast path, so put the explicit barrier here. 191 * in the fast path, so put the explicit barrier here.
183 */ 192 */
184 smp_read_barrier_depends(); 193 smp_read_barrier_depends();
185 multi = mdata->multi;
186 for (i = 0; multi[i].func; i++) 194 for (i = 0; multi[i].func; i++)
187 multi[i].func(multi[i].probe_private, call_private, 195 multi[i].func(multi[i].probe_private, call_private,
188 mdata->format, &args); 196 mdata->format, &args);
@@ -441,7 +449,7 @@ static int remove_marker(const char *name)
441 hlist_del(&e->hlist); 449 hlist_del(&e->hlist);
442 /* Make sure the call_rcu has been executed */ 450 /* Make sure the call_rcu has been executed */
443 if (e->rcu_pending) 451 if (e->rcu_pending)
444 rcu_barrier(); 452 rcu_barrier_sched();
445 kfree(e); 453 kfree(e);
446 return 0; 454 return 0;
447} 455}
@@ -476,7 +484,7 @@ static int marker_set_format(struct marker_entry **entry, const char *format)
476 hlist_del(&(*entry)->hlist); 484 hlist_del(&(*entry)->hlist);
477 /* Make sure the call_rcu has been executed */ 485 /* Make sure the call_rcu has been executed */
478 if ((*entry)->rcu_pending) 486 if ((*entry)->rcu_pending)
479 rcu_barrier(); 487 rcu_barrier_sched();
480 kfree(*entry); 488 kfree(*entry);
481 *entry = e; 489 *entry = e;
482 trace_mark(core_marker_format, "name %s format %s", 490 trace_mark(core_marker_format, "name %s format %s",
@@ -655,7 +663,7 @@ int marker_probe_register(const char *name, const char *format,
655 * make sure it's executed now. 663 * make sure it's executed now.
656 */ 664 */
657 if (entry->rcu_pending) 665 if (entry->rcu_pending)
658 rcu_barrier(); 666 rcu_barrier_sched();
659 old = marker_entry_add_probe(entry, probe, probe_private); 667 old = marker_entry_add_probe(entry, probe, probe_private);
660 if (IS_ERR(old)) { 668 if (IS_ERR(old)) {
661 ret = PTR_ERR(old); 669 ret = PTR_ERR(old);
@@ -670,10 +678,7 @@ int marker_probe_register(const char *name, const char *format,
670 entry->rcu_pending = 1; 678 entry->rcu_pending = 1;
671 /* write rcu_pending before calling the RCU callback */ 679 /* write rcu_pending before calling the RCU callback */
672 smp_wmb(); 680 smp_wmb();
673#ifdef CONFIG_PREEMPT_RCU 681 call_rcu_sched(&entry->rcu, free_old_closure);
674 synchronize_sched(); /* Until we have the call_rcu_sched() */
675#endif
676 call_rcu(&entry->rcu, free_old_closure);
677end: 682end:
678 mutex_unlock(&markers_mutex); 683 mutex_unlock(&markers_mutex);
679 return ret; 684 return ret;
@@ -704,7 +709,7 @@ int marker_probe_unregister(const char *name,
704 if (!entry) 709 if (!entry)
705 goto end; 710 goto end;
706 if (entry->rcu_pending) 711 if (entry->rcu_pending)
707 rcu_barrier(); 712 rcu_barrier_sched();
708 old = marker_entry_remove_probe(entry, probe, probe_private); 713 old = marker_entry_remove_probe(entry, probe, probe_private);
709 mutex_unlock(&markers_mutex); 714 mutex_unlock(&markers_mutex);
710 marker_update_probes(); /* may update entry */ 715 marker_update_probes(); /* may update entry */
@@ -716,10 +721,7 @@ int marker_probe_unregister(const char *name,
716 entry->rcu_pending = 1; 721 entry->rcu_pending = 1;
717 /* write rcu_pending before calling the RCU callback */ 722 /* write rcu_pending before calling the RCU callback */
718 smp_wmb(); 723 smp_wmb();
719#ifdef CONFIG_PREEMPT_RCU 724 call_rcu_sched(&entry->rcu, free_old_closure);
720 synchronize_sched(); /* Until we have the call_rcu_sched() */
721#endif
722 call_rcu(&entry->rcu, free_old_closure);
723 remove_marker(name); /* Ignore busy error message */ 725 remove_marker(name); /* Ignore busy error message */
724 ret = 0; 726 ret = 0;
725end: 727end:
@@ -786,7 +788,7 @@ int marker_probe_unregister_private_data(marker_probe_func *probe,
786 goto end; 788 goto end;
787 } 789 }
788 if (entry->rcu_pending) 790 if (entry->rcu_pending)
789 rcu_barrier(); 791 rcu_barrier_sched();
790 old = marker_entry_remove_probe(entry, NULL, probe_private); 792 old = marker_entry_remove_probe(entry, NULL, probe_private);
791 mutex_unlock(&markers_mutex); 793 mutex_unlock(&markers_mutex);
792 marker_update_probes(); /* may update entry */ 794 marker_update_probes(); /* may update entry */
@@ -797,10 +799,7 @@ int marker_probe_unregister_private_data(marker_probe_func *probe,
797 entry->rcu_pending = 1; 799 entry->rcu_pending = 1;
798 /* write rcu_pending before calling the RCU callback */ 800 /* write rcu_pending before calling the RCU callback */
799 smp_wmb(); 801 smp_wmb();
800#ifdef CONFIG_PREEMPT_RCU 802 call_rcu_sched(&entry->rcu, free_old_closure);
801 synchronize_sched(); /* Until we have the call_rcu_sched() */
802#endif
803 call_rcu(&entry->rcu, free_old_closure);
804 remove_marker(entry->name); /* Ignore busy error message */ 803 remove_marker(entry->name); /* Ignore busy error message */
805end: 804end:
806 mutex_unlock(&markers_mutex); 805 mutex_unlock(&markers_mutex);