aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/ring_buffer_benchmark.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-11-06 16:30:20 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-11-06 16:30:20 -0500
commit22402cd0af685c1a5d067c87db3051db7fff7709 (patch)
tree4f06ef31f643be28f3d4c92821df36b8ff321d9b /kernel/trace/ring_buffer_benchmark.c
parent7c623cac4939fb36916c029609dd22e3dec0a014 (diff)
parentd227c3ae4e94e5eb11dd780a811f59e1a7b74ccd (diff)
Merge tag 'trace-v4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace
Pull tracking updates from Steven Rostedt: "Most of the changes are clean ups and small fixes. Some of them have stable tags to them. I searched through my INBOX just as the merge window opened and found lots of patches to pull. I ran them through all my tests and they were in linux-next for a few days. Features added this release: ---------------------------- - Module globbing. You can now filter function tracing to several modules. # echo '*:mod:*snd*' > set_ftrace_filter (Dmitry Safonov) - Tracer specific options are now visible even when the tracer is not active. It was rather annoying that you can only see and modify tracer options after enabling the tracer. Now they are in the options/ directory even when the tracer is not active. Although they are still only visible when the tracer is active in the trace_options file. - Trace options are now per instance (although some of the tracer specific options are global) - New tracefs file: set_event_pid. If any pid is added to this file, then all events in the instance will filter out events that are not part of this pid. sched_switch and sched_wakeup events handle next and the wakee pids" * tag 'trace-v4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: (68 commits) tracefs: Fix refcount imbalance in start_creating() tracing: Put back comma for empty fields in boot string parsing tracing: Apply tracer specific options from kernel command line. tracing: Add some documentation about set_event_pid ring_buffer: Remove unneeded smp_wmb() before wakeup of reader benchmark tracing: Allow dumping traces without tracking trace started cpus ring_buffer: Fix more races when terminating the producer in the benchmark ring_buffer: Do no not complete benchmark reader too early tracing: Remove redundant TP_ARGS redefining tracing: Rename max_stack_lock to stack_trace_max_lock tracing: Allow arch-specific stack tracer recordmcount: arm64: Replace the ignored mcount call into nop recordmcount: Fix endianness handling bug for nop_mcount tracepoints: Fix documentation of RCU lockdep checks tracing: ftrace_event_is_function() can return boolean tracing: is_legal_op() can return boolean ring-buffer: rb_event_is_commit() can return boolean ring-buffer: rb_per_cpu_empty() can return boolean ring_buffer: ring_buffer_empty{cpu}() can return boolean ring-buffer: rb_is_reader_page() can return boolean ...
Diffstat (limited to 'kernel/trace/ring_buffer_benchmark.c')
-rw-r--r--kernel/trace/ring_buffer_benchmark.c79
1 files changed, 44 insertions, 35 deletions
diff --git a/kernel/trace/ring_buffer_benchmark.c b/kernel/trace/ring_buffer_benchmark.c
index a1503a027ee2..6df9a83e20d7 100644
--- a/kernel/trace/ring_buffer_benchmark.c
+++ b/kernel/trace/ring_buffer_benchmark.c
@@ -24,8 +24,8 @@ struct rb_page {
24static int wakeup_interval = 100; 24static int wakeup_interval = 100;
25 25
26static int reader_finish; 26static int reader_finish;
27static struct completion read_start; 27static DECLARE_COMPLETION(read_start);
28static struct completion read_done; 28static DECLARE_COMPLETION(read_done);
29 29
30static struct ring_buffer *buffer; 30static struct ring_buffer *buffer;
31static struct task_struct *producer; 31static struct task_struct *producer;
@@ -60,12 +60,12 @@ MODULE_PARM_DESC(consumer_fifo, "fifo prio for consumer");
60 60
61static int read_events; 61static int read_events;
62 62
63static int kill_test; 63static int test_error;
64 64
65#define KILL_TEST() \ 65#define TEST_ERROR() \
66 do { \ 66 do { \
67 if (!kill_test) { \ 67 if (!test_error) { \
68 kill_test = 1; \ 68 test_error = 1; \
69 WARN_ON(1); \ 69 WARN_ON(1); \
70 } \ 70 } \
71 } while (0) 71 } while (0)
@@ -75,6 +75,11 @@ enum event_status {
75 EVENT_DROPPED, 75 EVENT_DROPPED,
76}; 76};
77 77
78static bool break_test(void)
79{
80 return test_error || kthread_should_stop();
81}
82
78static enum event_status read_event(int cpu) 83static enum event_status read_event(int cpu)
79{ 84{
80 struct ring_buffer_event *event; 85 struct ring_buffer_event *event;
@@ -87,7 +92,7 @@ static enum event_status read_event(int cpu)
87 92
88 entry = ring_buffer_event_data(event); 93 entry = ring_buffer_event_data(event);
89 if (*entry != cpu) { 94 if (*entry != cpu) {
90 KILL_TEST(); 95 TEST_ERROR();
91 return EVENT_DROPPED; 96 return EVENT_DROPPED;
92 } 97 }
93 98
@@ -115,10 +120,10 @@ static enum event_status read_page(int cpu)
115 rpage = bpage; 120 rpage = bpage;
116 /* The commit may have missed event flags set, clear them */ 121 /* The commit may have missed event flags set, clear them */
117 commit = local_read(&rpage->commit) & 0xfffff; 122 commit = local_read(&rpage->commit) & 0xfffff;
118 for (i = 0; i < commit && !kill_test; i += inc) { 123 for (i = 0; i < commit && !test_error ; i += inc) {
119 124
120 if (i >= (PAGE_SIZE - offsetof(struct rb_page, data))) { 125 if (i >= (PAGE_SIZE - offsetof(struct rb_page, data))) {
121 KILL_TEST(); 126 TEST_ERROR();
122 break; 127 break;
123 } 128 }
124 129
@@ -128,7 +133,7 @@ static enum event_status read_page(int cpu)
128 case RINGBUF_TYPE_PADDING: 133 case RINGBUF_TYPE_PADDING:
129 /* failed writes may be discarded events */ 134 /* failed writes may be discarded events */
130 if (!event->time_delta) 135 if (!event->time_delta)
131 KILL_TEST(); 136 TEST_ERROR();
132 inc = event->array[0] + 4; 137 inc = event->array[0] + 4;
133 break; 138 break;
134 case RINGBUF_TYPE_TIME_EXTEND: 139 case RINGBUF_TYPE_TIME_EXTEND:
@@ -137,12 +142,12 @@ static enum event_status read_page(int cpu)
137 case 0: 142 case 0:
138 entry = ring_buffer_event_data(event); 143 entry = ring_buffer_event_data(event);
139 if (*entry != cpu) { 144 if (*entry != cpu) {
140 KILL_TEST(); 145 TEST_ERROR();
141 break; 146 break;
142 } 147 }
143 read++; 148 read++;
144 if (!event->array[0]) { 149 if (!event->array[0]) {
145 KILL_TEST(); 150 TEST_ERROR();
146 break; 151 break;
147 } 152 }
148 inc = event->array[0] + 4; 153 inc = event->array[0] + 4;
@@ -150,17 +155,17 @@ static enum event_status read_page(int cpu)
150 default: 155 default:
151 entry = ring_buffer_event_data(event); 156 entry = ring_buffer_event_data(event);
152 if (*entry != cpu) { 157 if (*entry != cpu) {
153 KILL_TEST(); 158 TEST_ERROR();
154 break; 159 break;
155 } 160 }
156 read++; 161 read++;
157 inc = ((event->type_len + 1) * 4); 162 inc = ((event->type_len + 1) * 4);
158 } 163 }
159 if (kill_test) 164 if (test_error)
160 break; 165 break;
161 166
162 if (inc <= 0) { 167 if (inc <= 0) {
163 KILL_TEST(); 168 TEST_ERROR();
164 break; 169 break;
165 } 170 }
166 } 171 }
@@ -178,10 +183,14 @@ static void ring_buffer_consumer(void)
178 read_events ^= 1; 183 read_events ^= 1;
179 184
180 read = 0; 185 read = 0;
181 while (!reader_finish && !kill_test) { 186 /*
182 int found; 187 * Continue running until the producer specifically asks to stop
188 * and is ready for the completion.
189 */
190 while (!READ_ONCE(reader_finish)) {
191 int found = 1;
183 192
184 do { 193 while (found && !test_error) {
185 int cpu; 194 int cpu;
186 195
187 found = 0; 196 found = 0;
@@ -193,19 +202,25 @@ static void ring_buffer_consumer(void)
193 else 202 else
194 stat = read_page(cpu); 203 stat = read_page(cpu);
195 204
196 if (kill_test) 205 if (test_error)
197 break; 206 break;
207
198 if (stat == EVENT_FOUND) 208 if (stat == EVENT_FOUND)
199 found = 1; 209 found = 1;
210
200 } 211 }
201 } while (found && !kill_test); 212 }
202 213
214 /* Wait till the producer wakes us up when there is more data
215 * available or when the producer wants us to finish reading.
216 */
203 set_current_state(TASK_INTERRUPTIBLE); 217 set_current_state(TASK_INTERRUPTIBLE);
204 if (reader_finish) 218 if (reader_finish)
205 break; 219 break;
206 220
207 schedule(); 221 schedule();
208 } 222 }
223 __set_current_state(TASK_RUNNING);
209 reader_finish = 0; 224 reader_finish = 0;
210 complete(&read_done); 225 complete(&read_done);
211} 226}
@@ -263,10 +278,7 @@ static void ring_buffer_producer(void)
263 if (cnt % wakeup_interval) 278 if (cnt % wakeup_interval)
264 cond_resched(); 279 cond_resched();
265#endif 280#endif
266 if (kthread_should_stop()) 281 } while (ktime_before(end_time, timeout) && !break_test());
267 kill_test = 1;
268
269 } while (ktime_before(end_time, timeout) && !kill_test);
270 trace_printk("End ring buffer hammer\n"); 282 trace_printk("End ring buffer hammer\n");
271 283
272 if (consumer) { 284 if (consumer) {
@@ -276,8 +288,6 @@ static void ring_buffer_producer(void)
276 /* the completions must be visible before the finish var */ 288 /* the completions must be visible before the finish var */
277 smp_wmb(); 289 smp_wmb();
278 reader_finish = 1; 290 reader_finish = 1;
279 /* finish var visible before waking up the consumer */
280 smp_wmb();
281 wake_up_process(consumer); 291 wake_up_process(consumer);
282 wait_for_completion(&read_done); 292 wait_for_completion(&read_done);
283 } 293 }
@@ -287,7 +297,7 @@ static void ring_buffer_producer(void)
287 entries = ring_buffer_entries(buffer); 297 entries = ring_buffer_entries(buffer);
288 overruns = ring_buffer_overruns(buffer); 298 overruns = ring_buffer_overruns(buffer);
289 299
290 if (kill_test && !kthread_should_stop()) 300 if (test_error)
291 trace_printk("ERROR!\n"); 301 trace_printk("ERROR!\n");
292 302
293 if (!disable_reader) { 303 if (!disable_reader) {
@@ -368,15 +378,14 @@ static void wait_to_die(void)
368 378
369static int ring_buffer_consumer_thread(void *arg) 379static int ring_buffer_consumer_thread(void *arg)
370{ 380{
371 while (!kthread_should_stop() && !kill_test) { 381 while (!break_test()) {
372 complete(&read_start); 382 complete(&read_start);
373 383
374 ring_buffer_consumer(); 384 ring_buffer_consumer();
375 385
376 set_current_state(TASK_INTERRUPTIBLE); 386 set_current_state(TASK_INTERRUPTIBLE);
377 if (kthread_should_stop() || kill_test) 387 if (break_test())
378 break; 388 break;
379
380 schedule(); 389 schedule();
381 } 390 }
382 __set_current_state(TASK_RUNNING); 391 __set_current_state(TASK_RUNNING);
@@ -389,27 +398,27 @@ static int ring_buffer_consumer_thread(void *arg)
389 398
390static int ring_buffer_producer_thread(void *arg) 399static int ring_buffer_producer_thread(void *arg)
391{ 400{
392 init_completion(&read_start); 401 while (!break_test()) {
393
394 while (!kthread_should_stop() && !kill_test) {
395 ring_buffer_reset(buffer); 402 ring_buffer_reset(buffer);
396 403
397 if (consumer) { 404 if (consumer) {
398 smp_wmb();
399 wake_up_process(consumer); 405 wake_up_process(consumer);
400 wait_for_completion(&read_start); 406 wait_for_completion(&read_start);
401 } 407 }
402 408
403 ring_buffer_producer(); 409 ring_buffer_producer();
404 if (kill_test) 410 if (break_test())
405 goto out_kill; 411 goto out_kill;
406 412
407 trace_printk("Sleeping for 10 secs\n"); 413 trace_printk("Sleeping for 10 secs\n");
408 set_current_state(TASK_INTERRUPTIBLE); 414 set_current_state(TASK_INTERRUPTIBLE);
415 if (break_test())
416 goto out_kill;
409 schedule_timeout(HZ * SLEEP_TIME); 417 schedule_timeout(HZ * SLEEP_TIME);
410 } 418 }
411 419
412out_kill: 420out_kill:
421 __set_current_state(TASK_RUNNING);
413 if (!kthread_should_stop()) 422 if (!kthread_should_stop())
414 wait_to_die(); 423 wait_to_die();
415 424