diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-06 16:30:20 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-06 16:30:20 -0500 |
| commit | 22402cd0af685c1a5d067c87db3051db7fff7709 (patch) | |
| tree | 4f06ef31f643be28f3d4c92821df36b8ff321d9b /kernel/trace/ring_buffer_benchmark.c | |
| parent | 7c623cac4939fb36916c029609dd22e3dec0a014 (diff) | |
| parent | d227c3ae4e94e5eb11dd780a811f59e1a7b74ccd (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.c | 79 |
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 { | |||
| 24 | static int wakeup_interval = 100; | 24 | static int wakeup_interval = 100; |
| 25 | 25 | ||
| 26 | static int reader_finish; | 26 | static int reader_finish; |
| 27 | static struct completion read_start; | 27 | static DECLARE_COMPLETION(read_start); |
| 28 | static struct completion read_done; | 28 | static DECLARE_COMPLETION(read_done); |
| 29 | 29 | ||
| 30 | static struct ring_buffer *buffer; | 30 | static struct ring_buffer *buffer; |
| 31 | static struct task_struct *producer; | 31 | static struct task_struct *producer; |
| @@ -60,12 +60,12 @@ MODULE_PARM_DESC(consumer_fifo, "fifo prio for consumer"); | |||
| 60 | 60 | ||
| 61 | static int read_events; | 61 | static int read_events; |
| 62 | 62 | ||
| 63 | static int kill_test; | 63 | static 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 | ||
| 78 | static bool break_test(void) | ||
| 79 | { | ||
| 80 | return test_error || kthread_should_stop(); | ||
| 81 | } | ||
| 82 | |||
| 78 | static enum event_status read_event(int cpu) | 83 | static 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 | ||
| 369 | static int ring_buffer_consumer_thread(void *arg) | 379 | static 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 | ||
| 390 | static int ring_buffer_producer_thread(void *arg) | 399 | static 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 | ||
| 412 | out_kill: | 420 | out_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 | ||
