aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/ring_buffer_benchmark.c
diff options
context:
space:
mode:
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