aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/marker.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-10-15 07:46:29 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-15 07:46:29 -0400
commitb2aaf8f74cdc84a9182f6cabf198b7763bcb9d40 (patch)
tree53ccb1c2c14751fe69cf93102e76e97021f6df07 /kernel/marker.c
parent4f962d4d65923d7b722192e729840cfb79af0a5a (diff)
parent278429cff8809958d25415ba0ed32b59866ab1a8 (diff)
Merge branch 'linus' into stackprotector
Conflicts: arch/x86/kernel/Makefile include/asm-x86/pda.h
Diffstat (limited to 'kernel/marker.c')
-rw-r--r--kernel/marker.c67
1 files changed, 32 insertions, 35 deletions
diff --git a/kernel/marker.c b/kernel/marker.c
index b5a9fe1d50d5..7d1faecd7a51 100644
--- a/kernel/marker.c
+++ b/kernel/marker.c
@@ -55,8 +55,8 @@ static DEFINE_MUTEX(markers_mutex);
55struct marker_entry { 55struct marker_entry {
56 struct hlist_node hlist; 56 struct hlist_node hlist;
57 char *format; 57 char *format;
58 void (*call)(const struct marker *mdata, /* Probe wrapper */ 58 /* Probe wrapper */
59 void *call_private, const char *fmt, ...); 59 void (*call)(const struct marker *mdata, void *call_private, ...);
60 struct marker_probe_closure single; 60 struct marker_probe_closure single;
61 struct marker_probe_closure *multi; 61 struct marker_probe_closure *multi;
62 int refcount; /* Number of times armed. 0 if disarmed. */ 62 int refcount; /* Number of times armed. 0 if disarmed. */
@@ -91,15 +91,13 @@ EXPORT_SYMBOL_GPL(__mark_empty_function);
91 * marker_probe_cb Callback that prepares the variable argument list for probes. 91 * marker_probe_cb Callback that prepares the variable argument list for probes.
92 * @mdata: pointer of type struct marker 92 * @mdata: pointer of type struct marker
93 * @call_private: caller site private data 93 * @call_private: caller site private data
94 * @fmt: format string
95 * @...: Variable argument list. 94 * @...: Variable argument list.
96 * 95 *
97 * Since we do not use "typical" pointer based RCU in the 1 argument case, we 96 * Since we do not use "typical" pointer based RCU in the 1 argument case, we
98 * need to put a full smp_rmb() in this branch. This is why we do not use 97 * need to put a full smp_rmb() in this branch. This is why we do not use
99 * rcu_dereference() for the pointer read. 98 * rcu_dereference() for the pointer read.
100 */ 99 */
101void marker_probe_cb(const struct marker *mdata, void *call_private, 100void marker_probe_cb(const struct marker *mdata, void *call_private, ...)
102 const char *fmt, ...)
103{ 101{
104 va_list args; 102 va_list args;
105 char ptype; 103 char ptype;
@@ -120,13 +118,19 @@ void marker_probe_cb(const struct marker *mdata, void *call_private,
120 /* Must read the ptr before private data. They are not data 118 /* Must read the ptr before private data. They are not data
121 * dependant, so we put an explicit smp_rmb() here. */ 119 * dependant, so we put an explicit smp_rmb() here. */
122 smp_rmb(); 120 smp_rmb();
123 va_start(args, fmt); 121 va_start(args, call_private);
124 func(mdata->single.probe_private, call_private, fmt, &args); 122 func(mdata->single.probe_private, call_private, mdata->format,
123 &args);
125 va_end(args); 124 va_end(args);
126 } else { 125 } else {
127 struct marker_probe_closure *multi; 126 struct marker_probe_closure *multi;
128 int i; 127 int i;
129 /* 128 /*
129 * Read mdata->ptype before mdata->multi.
130 */
131 smp_rmb();
132 multi = mdata->multi;
133 /*
130 * multi points to an array, therefore accessing the array 134 * multi points to an array, therefore accessing the array
131 * depends on reading multi. However, even in this case, 135 * depends on reading multi. However, even in this case,
132 * we must insure that the pointer is read _before_ the array 136 * we must insure that the pointer is read _before_ the array
@@ -134,11 +138,10 @@ void marker_probe_cb(const struct marker *mdata, void *call_private,
134 * in the fast path, so put the explicit barrier here. 138 * in the fast path, so put the explicit barrier here.
135 */ 139 */
136 smp_read_barrier_depends(); 140 smp_read_barrier_depends();
137 multi = mdata->multi;
138 for (i = 0; multi[i].func; i++) { 141 for (i = 0; multi[i].func; i++) {
139 va_start(args, fmt); 142 va_start(args, call_private);
140 multi[i].func(multi[i].probe_private, call_private, fmt, 143 multi[i].func(multi[i].probe_private, call_private,
141 &args); 144 mdata->format, &args);
142 va_end(args); 145 va_end(args);
143 } 146 }
144 } 147 }
@@ -150,13 +153,11 @@ EXPORT_SYMBOL_GPL(marker_probe_cb);
150 * marker_probe_cb Callback that does not prepare the variable argument list. 153 * marker_probe_cb Callback that does not prepare the variable argument list.
151 * @mdata: pointer of type struct marker 154 * @mdata: pointer of type struct marker
152 * @call_private: caller site private data 155 * @call_private: caller site private data
153 * @fmt: format string
154 * @...: Variable argument list. 156 * @...: Variable argument list.
155 * 157 *
156 * Should be connected to markers "MARK_NOARGS". 158 * Should be connected to markers "MARK_NOARGS".
157 */ 159 */
158void marker_probe_cb_noarg(const struct marker *mdata, 160void marker_probe_cb_noarg(const struct marker *mdata, void *call_private, ...)
159 void *call_private, const char *fmt, ...)
160{ 161{
161 va_list args; /* not initialized */ 162 va_list args; /* not initialized */
162 char ptype; 163 char ptype;
@@ -172,11 +173,17 @@ void marker_probe_cb_noarg(const struct marker *mdata,
172 /* Must read the ptr before private data. They are not data 173 /* Must read the ptr before private data. They are not data
173 * dependant, so we put an explicit smp_rmb() here. */ 174 * dependant, so we put an explicit smp_rmb() here. */
174 smp_rmb(); 175 smp_rmb();
175 func(mdata->single.probe_private, call_private, fmt, &args); 176 func(mdata->single.probe_private, call_private, mdata->format,
177 &args);
176 } else { 178 } else {
177 struct marker_probe_closure *multi; 179 struct marker_probe_closure *multi;
178 int i; 180 int i;
179 /* 181 /*
182 * Read mdata->ptype before mdata->multi.
183 */
184 smp_rmb();
185 multi = mdata->multi;
186 /*
180 * multi points to an array, therefore accessing the array 187 * multi points to an array, therefore accessing the array
181 * depends on reading multi. However, even in this case, 188 * depends on reading multi. However, even in this case,
182 * we must insure that the pointer is read _before_ the array 189 * we must insure that the pointer is read _before_ the array
@@ -184,10 +191,9 @@ void marker_probe_cb_noarg(const struct marker *mdata,
184 * in the fast path, so put the explicit barrier here. 191 * in the fast path, so put the explicit barrier here.
185 */ 192 */
186 smp_read_barrier_depends(); 193 smp_read_barrier_depends();
187 multi = mdata->multi;
188 for (i = 0; multi[i].func; i++) 194 for (i = 0; multi[i].func; i++)
189 multi[i].func(multi[i].probe_private, call_private, fmt, 195 multi[i].func(multi[i].probe_private, call_private,
190 &args); 196 mdata->format, &args);
191 } 197 }
192 preempt_enable(); 198 preempt_enable();
193} 199}
@@ -443,7 +449,7 @@ static int remove_marker(const char *name)
443 hlist_del(&e->hlist); 449 hlist_del(&e->hlist);
444 /* Make sure the call_rcu has been executed */ 450 /* Make sure the call_rcu has been executed */
445 if (e->rcu_pending) 451 if (e->rcu_pending)
446 rcu_barrier(); 452 rcu_barrier_sched();
447 kfree(e); 453 kfree(e);
448 return 0; 454 return 0;
449} 455}
@@ -478,7 +484,7 @@ static int marker_set_format(struct marker_entry **entry, const char *format)
478 hlist_del(&(*entry)->hlist); 484 hlist_del(&(*entry)->hlist);
479 /* Make sure the call_rcu has been executed */ 485 /* Make sure the call_rcu has been executed */
480 if ((*entry)->rcu_pending) 486 if ((*entry)->rcu_pending)
481 rcu_barrier(); 487 rcu_barrier_sched();
482 kfree(*entry); 488 kfree(*entry);
483 *entry = e; 489 *entry = e;
484 trace_mark(core_marker_format, "name %s format %s", 490 trace_mark(core_marker_format, "name %s format %s",
@@ -657,7 +663,7 @@ int marker_probe_register(const char *name, const char *format,
657 * make sure it's executed now. 663 * make sure it's executed now.
658 */ 664 */
659 if (entry->rcu_pending) 665 if (entry->rcu_pending)
660 rcu_barrier(); 666 rcu_barrier_sched();
661 old = marker_entry_add_probe(entry, probe, probe_private); 667 old = marker_entry_add_probe(entry, probe, probe_private);
662 if (IS_ERR(old)) { 668 if (IS_ERR(old)) {
663 ret = PTR_ERR(old); 669 ret = PTR_ERR(old);
@@ -672,10 +678,7 @@ int marker_probe_register(const char *name, const char *format,
672 entry->rcu_pending = 1; 678 entry->rcu_pending = 1;
673 /* write rcu_pending before calling the RCU callback */ 679 /* write rcu_pending before calling the RCU callback */
674 smp_wmb(); 680 smp_wmb();
675#ifdef CONFIG_PREEMPT_RCU 681 call_rcu_sched(&entry->rcu, free_old_closure);
676 synchronize_sched(); /* Until we have the call_rcu_sched() */
677#endif
678 call_rcu(&entry->rcu, free_old_closure);
679end: 682end:
680 mutex_unlock(&markers_mutex); 683 mutex_unlock(&markers_mutex);
681 return ret; 684 return ret;
@@ -706,7 +709,7 @@ int marker_probe_unregister(const char *name,
706 if (!entry) 709 if (!entry)
707 goto end; 710 goto end;
708 if (entry->rcu_pending) 711 if (entry->rcu_pending)
709 rcu_barrier(); 712 rcu_barrier_sched();
710 old = marker_entry_remove_probe(entry, probe, probe_private); 713 old = marker_entry_remove_probe(entry, probe, probe_private);
711 mutex_unlock(&markers_mutex); 714 mutex_unlock(&markers_mutex);
712 marker_update_probes(); /* may update entry */ 715 marker_update_probes(); /* may update entry */
@@ -718,10 +721,7 @@ int marker_probe_unregister(const char *name,
718 entry->rcu_pending = 1; 721 entry->rcu_pending = 1;
719 /* write rcu_pending before calling the RCU callback */ 722 /* write rcu_pending before calling the RCU callback */
720 smp_wmb(); 723 smp_wmb();
721#ifdef CONFIG_PREEMPT_RCU 724 call_rcu_sched(&entry->rcu, free_old_closure);
722 synchronize_sched(); /* Until we have the call_rcu_sched() */
723#endif
724 call_rcu(&entry->rcu, free_old_closure);
725 remove_marker(name); /* Ignore busy error message */ 725 remove_marker(name); /* Ignore busy error message */
726 ret = 0; 726 ret = 0;
727end: 727end:
@@ -788,7 +788,7 @@ int marker_probe_unregister_private_data(marker_probe_func *probe,
788 goto end; 788 goto end;
789 } 789 }
790 if (entry->rcu_pending) 790 if (entry->rcu_pending)
791 rcu_barrier(); 791 rcu_barrier_sched();
792 old = marker_entry_remove_probe(entry, NULL, probe_private); 792 old = marker_entry_remove_probe(entry, NULL, probe_private);
793 mutex_unlock(&markers_mutex); 793 mutex_unlock(&markers_mutex);
794 marker_update_probes(); /* may update entry */ 794 marker_update_probes(); /* may update entry */
@@ -799,10 +799,7 @@ int marker_probe_unregister_private_data(marker_probe_func *probe,
799 entry->rcu_pending = 1; 799 entry->rcu_pending = 1;
800 /* write rcu_pending before calling the RCU callback */ 800 /* write rcu_pending before calling the RCU callback */
801 smp_wmb(); 801 smp_wmb();
802#ifdef CONFIG_PREEMPT_RCU 802 call_rcu_sched(&entry->rcu, free_old_closure);
803 synchronize_sched(); /* Until we have the call_rcu_sched() */
804#endif
805 call_rcu(&entry->rcu, free_old_closure);
806 remove_marker(entry->name); /* Ignore busy error message */ 803 remove_marker(entry->name); /* Ignore busy error message */
807end: 804end:
808 mutex_unlock(&markers_mutex); 805 mutex_unlock(&markers_mutex);