aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace
diff options
context:
space:
mode:
authorSteven Rostedt <rostedt@goodmis.org>2014-10-08 13:52:16 -0400
committerSteven Rostedt <rostedt@goodmis.org>2014-10-09 11:15:08 -0400
commitaddff1feb02b03cb766b9a611c6b2cebf29bc285 (patch)
treefaf54b05294f2feac72d62ebafb2fcbe959185e0 /kernel/trace
parentfe0e01c77dd9f7a60916aec2149d8a1182baf63c (diff)
tracing: Clean up scheduling in trace_wakeup_test_thread()
Peter's new debugging tool triggers when tasks exit with !TASK_RUNNING. The code in trace_wakeup_test_thread() also has a single schedule() call that should be encompassed by a loop. This cleans up the code a little to make it a bit more robust and also makes the return exit properly with TASK_RUNNING. Link: http://lkml.kernel.org/p/20141008135216.76142204@gandalf.local.home Reported-by: Peter Zijlstra <peterz@infradead.org> Acked-by: Peter Zijlstra <peterz@infreadead.org> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace')
-rw-r--r--kernel/trace/trace_selftest.c47
1 files changed, 30 insertions, 17 deletions
diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c
index 5ef60499dc8e..593f52b73551 100644
--- a/kernel/trace/trace_selftest.c
+++ b/kernel/trace/trace_selftest.c
@@ -1025,6 +1025,12 @@ trace_selftest_startup_nop(struct tracer *trace, struct trace_array *tr)
1025#endif 1025#endif
1026 1026
1027#ifdef CONFIG_SCHED_TRACER 1027#ifdef CONFIG_SCHED_TRACER
1028
1029struct wakeup_test_data {
1030 struct completion is_ready;
1031 int go;
1032};
1033
1028static int trace_wakeup_test_thread(void *data) 1034static int trace_wakeup_test_thread(void *data)
1029{ 1035{
1030 /* Make this a -deadline thread */ 1036 /* Make this a -deadline thread */
@@ -1034,51 +1040,56 @@ static int trace_wakeup_test_thread(void *data)
1034 .sched_deadline = 10000000ULL, 1040 .sched_deadline = 10000000ULL,
1035 .sched_period = 10000000ULL 1041 .sched_period = 10000000ULL
1036 }; 1042 };
1037 struct completion *x = data; 1043 struct wakeup_test_data *x = data;
1038 1044
1039 sched_setattr(current, &attr); 1045 sched_setattr(current, &attr);
1040 1046
1041 /* Make it know we have a new prio */ 1047 /* Make it know we have a new prio */
1042 complete(x); 1048 complete(&x->is_ready);
1043 1049
1044 /* now go to sleep and let the test wake us up */ 1050 /* now go to sleep and let the test wake us up */
1045 set_current_state(TASK_INTERRUPTIBLE); 1051 set_current_state(TASK_INTERRUPTIBLE);
1046 schedule(); 1052 while (!x->go) {
1053 schedule();
1054 set_current_state(TASK_INTERRUPTIBLE);
1055 }
1047 1056
1048 complete(x); 1057 complete(&x->is_ready);
1058
1059 set_current_state(TASK_INTERRUPTIBLE);
1049 1060
1050 /* we are awake, now wait to disappear */ 1061 /* we are awake, now wait to disappear */
1051 while (!kthread_should_stop()) { 1062 while (!kthread_should_stop()) {
1052 /* 1063 schedule();
1053 * This will likely be the system top priority 1064 set_current_state(TASK_INTERRUPTIBLE);
1054 * task, do short sleeps to let others run.
1055 */
1056 msleep(100);
1057 } 1065 }
1058 1066
1067 __set_current_state(TASK_RUNNING);
1068
1059 return 0; 1069 return 0;
1060} 1070}
1061
1062int 1071int
1063trace_selftest_startup_wakeup(struct tracer *trace, struct trace_array *tr) 1072trace_selftest_startup_wakeup(struct tracer *trace, struct trace_array *tr)
1064{ 1073{
1065 unsigned long save_max = tr->max_latency; 1074 unsigned long save_max = tr->max_latency;
1066 struct task_struct *p; 1075 struct task_struct *p;
1067 struct completion is_ready; 1076 struct wakeup_test_data data;
1068 unsigned long count; 1077 unsigned long count;
1069 int ret; 1078 int ret;
1070 1079
1071 init_completion(&is_ready); 1080 memset(&data, 0, sizeof(data));
1081
1082 init_completion(&data.is_ready);
1072 1083
1073 /* create a -deadline thread */ 1084 /* create a -deadline thread */
1074 p = kthread_run(trace_wakeup_test_thread, &is_ready, "ftrace-test"); 1085 p = kthread_run(trace_wakeup_test_thread, &data, "ftrace-test");
1075 if (IS_ERR(p)) { 1086 if (IS_ERR(p)) {
1076 printk(KERN_CONT "Failed to create ftrace wakeup test thread "); 1087 printk(KERN_CONT "Failed to create ftrace wakeup test thread ");
1077 return -1; 1088 return -1;
1078 } 1089 }
1079 1090
1080 /* make sure the thread is running at -deadline policy */ 1091 /* make sure the thread is running at -deadline policy */
1081 wait_for_completion(&is_ready); 1092 wait_for_completion(&data.is_ready);
1082 1093
1083 /* start the tracing */ 1094 /* start the tracing */
1084 ret = tracer_init(trace, tr); 1095 ret = tracer_init(trace, tr);
@@ -1099,18 +1110,20 @@ trace_selftest_startup_wakeup(struct tracer *trace, struct trace_array *tr)
1099 msleep(100); 1110 msleep(100);
1100 } 1111 }
1101 1112
1102 init_completion(&is_ready); 1113 init_completion(&data.is_ready);
1114
1115 data.go = 1;
1116 /* memory barrier is in the wake_up_process() */
1103 1117
1104 wake_up_process(p); 1118 wake_up_process(p);
1105 1119
1106 /* Wait for the task to wake up */ 1120 /* Wait for the task to wake up */
1107 wait_for_completion(&is_ready); 1121 wait_for_completion(&data.is_ready);
1108 1122
1109 /* stop the tracing. */ 1123 /* stop the tracing. */
1110 tracing_stop(); 1124 tracing_stop();
1111 /* check both trace buffers */ 1125 /* check both trace buffers */
1112 ret = trace_test_buffer(&tr->trace_buffer, NULL); 1126 ret = trace_test_buffer(&tr->trace_buffer, NULL);
1113 printk("ret = %d\n", ret);
1114 if (!ret) 1127 if (!ret)
1115 ret = trace_test_buffer(&tr->max_buffer, &count); 1128 ret = trace_test_buffer(&tr->max_buffer, &count);
1116 1129