aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/marker.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/marker.c')
-rw-r--r--kernel/marker.c40
1 files changed, 23 insertions, 17 deletions
diff --git a/kernel/marker.c b/kernel/marker.c
index 48a4ea5afffd..005b95954593 100644
--- a/kernel/marker.c
+++ b/kernel/marker.c
@@ -104,18 +104,18 @@ void marker_probe_cb(const struct marker *mdata, void *call_private,
104 char ptype; 104 char ptype;
105 105
106 /* 106 /*
107 * disabling preemption to make sure the teardown of the callbacks can 107 * preempt_disable does two things : disabling preemption to make sure
108 * be done correctly when they are in modules and they insure RCU read 108 * the teardown of the callbacks can be done correctly when they are in
109 * coherency. 109 * modules and they insure RCU read coherency.
110 */ 110 */
111 preempt_disable(); 111 preempt_disable();
112 ptype = ACCESS_ONCE(mdata->ptype); 112 ptype = mdata->ptype;
113 if (likely(!ptype)) { 113 if (likely(!ptype)) {
114 marker_probe_func *func; 114 marker_probe_func *func;
115 /* Must read the ptype before ptr. They are not data dependant, 115 /* Must read the ptype before ptr. They are not data dependant,
116 * so we put an explicit smp_rmb() here. */ 116 * so we put an explicit smp_rmb() here. */
117 smp_rmb(); 117 smp_rmb();
118 func = ACCESS_ONCE(mdata->single.func); 118 func = mdata->single.func;
119 /* Must read the ptr before private data. They are not data 119 /* Must read the ptr before private data. They are not data
120 * dependant, so we put an explicit smp_rmb() here. */ 120 * dependant, so we put an explicit smp_rmb() here. */
121 smp_rmb(); 121 smp_rmb();
@@ -133,7 +133,7 @@ void marker_probe_cb(const struct marker *mdata, void *call_private,
133 * in the fast path, so put the explicit barrier here. 133 * in the fast path, so put the explicit barrier here.
134 */ 134 */
135 smp_read_barrier_depends(); 135 smp_read_barrier_depends();
136 multi = ACCESS_ONCE(mdata->multi); 136 multi = mdata->multi;
137 for (i = 0; multi[i].func; i++) { 137 for (i = 0; multi[i].func; i++) {
138 va_start(args, fmt); 138 va_start(args, fmt);
139 multi[i].func(multi[i].probe_private, call_private, fmt, 139 multi[i].func(multi[i].probe_private, call_private, fmt,
@@ -161,13 +161,13 @@ void marker_probe_cb_noarg(const struct marker *mdata,
161 char ptype; 161 char ptype;
162 162
163 preempt_disable(); 163 preempt_disable();
164 ptype = ACCESS_ONCE(mdata->ptype); 164 ptype = mdata->ptype;
165 if (likely(!ptype)) { 165 if (likely(!ptype)) {
166 marker_probe_func *func; 166 marker_probe_func *func;
167 /* Must read the ptype before ptr. They are not data dependant, 167 /* Must read the ptype before ptr. They are not data dependant,
168 * so we put an explicit smp_rmb() here. */ 168 * so we put an explicit smp_rmb() here. */
169 smp_rmb(); 169 smp_rmb();
170 func = ACCESS_ONCE(mdata->single.func); 170 func = mdata->single.func;
171 /* Must read the ptr before private data. They are not data 171 /* Must read the ptr before private data. They are not data
172 * dependant, so we put an explicit smp_rmb() here. */ 172 * dependant, so we put an explicit smp_rmb() here. */
173 smp_rmb(); 173 smp_rmb();
@@ -183,7 +183,7 @@ void marker_probe_cb_noarg(const struct marker *mdata,
183 * in the fast path, so put the explicit barrier here. 183 * in the fast path, so put the explicit barrier here.
184 */ 184 */
185 smp_read_barrier_depends(); 185 smp_read_barrier_depends();
186 multi = ACCESS_ONCE(mdata->multi); 186 multi = mdata->multi;
187 for (i = 0; multi[i].func; i++) 187 for (i = 0; multi[i].func; i++)
188 multi[i].func(multi[i].probe_private, call_private, fmt, 188 multi[i].func(multi[i].probe_private, call_private, fmt,
189 &args); 189 &args);
@@ -551,9 +551,9 @@ static int set_marker(struct marker_entry **entry, struct marker *elem,
551 551
552/* 552/*
553 * Disable a marker and its probe callback. 553 * Disable a marker and its probe callback.
554 * Note: only after a synchronize_sched() issued after setting elem->call to the 554 * Note: only waiting an RCU period after setting elem->call to the empty
555 * empty function insures that the original callback is not used anymore. This 555 * function insures that the original callback is not used anymore. This insured
556 * insured by preemption disabling around the call site. 556 * by preempt_disable around the call site.
557 */ 557 */
558static void disable_marker(struct marker *elem) 558static void disable_marker(struct marker *elem)
559{ 559{
@@ -565,8 +565,8 @@ static void disable_marker(struct marker *elem)
565 elem->ptype = 0; /* single probe */ 565 elem->ptype = 0; /* single probe */
566 /* 566 /*
567 * Leave the private data and id there, because removal is racy and 567 * Leave the private data and id there, because removal is racy and
568 * should be done only after a synchronize_sched(). These are never used 568 * should be done only after an RCU period. These are never used until
569 * until the next initialization anyway. 569 * the next initialization anyway.
570 */ 570 */
571} 571}
572 572
@@ -601,9 +601,6 @@ void marker_update_probe_range(struct marker *begin,
601 601
602/* 602/*
603 * Update probes, removing the faulty probes. 603 * Update probes, removing the faulty probes.
604 * Issues a synchronize_sched() when no reference to the module passed
605 * as parameter is found in the probes so the probe module can be
606 * safely unloaded from now on.
607 * 604 *
608 * Internal callback only changed before the first probe is connected to it. 605 * Internal callback only changed before the first probe is connected to it.
609 * Single probe private data can only be changed on 0 -> 1 and 2 -> 1 606 * Single probe private data can only be changed on 0 -> 1 and 2 -> 1
@@ -674,6 +671,9 @@ int marker_probe_register(const char *name, const char *format,
674 entry->rcu_pending = 1; 671 entry->rcu_pending = 1;
675 /* write rcu_pending before calling the RCU callback */ 672 /* write rcu_pending before calling the RCU callback */
676 smp_wmb(); 673 smp_wmb();
674#ifdef CONFIG_PREEMPT_RCU
675 synchronize_sched(); /* Until we have the call_rcu_sched() */
676#endif
677 call_rcu(&entry->rcu, free_old_closure); 677 call_rcu(&entry->rcu, free_old_closure);
678end: 678end:
679 mutex_unlock(&markers_mutex); 679 mutex_unlock(&markers_mutex);
@@ -717,6 +717,9 @@ int marker_probe_unregister(const char *name,
717 entry->rcu_pending = 1; 717 entry->rcu_pending = 1;
718 /* write rcu_pending before calling the RCU callback */ 718 /* write rcu_pending before calling the RCU callback */
719 smp_wmb(); 719 smp_wmb();
720#ifdef CONFIG_PREEMPT_RCU
721 synchronize_sched(); /* Until we have the call_rcu_sched() */
722#endif
720 call_rcu(&entry->rcu, free_old_closure); 723 call_rcu(&entry->rcu, free_old_closure);
721 remove_marker(name); /* Ignore busy error message */ 724 remove_marker(name); /* Ignore busy error message */
722 ret = 0; 725 ret = 0;
@@ -795,6 +798,9 @@ int marker_probe_unregister_private_data(marker_probe_func *probe,
795 entry->rcu_pending = 1; 798 entry->rcu_pending = 1;
796 /* write rcu_pending before calling the RCU callback */ 799 /* write rcu_pending before calling the RCU callback */
797 smp_wmb(); 800 smp_wmb();
801#ifdef CONFIG_PREEMPT_RCU
802 synchronize_sched(); /* Until we have the call_rcu_sched() */
803#endif
798 call_rcu(&entry->rcu, free_old_closure); 804 call_rcu(&entry->rcu, free_old_closure);
799 remove_marker(entry->name); /* Ignore busy error message */ 805 remove_marker(entry->name); /* Ignore busy error message */
800end: 806end: