diff options
-rw-r--r-- | kernel/trace/trace.c | 38 | ||||
-rw-r--r-- | kernel/trace/trace.h | 5 |
2 files changed, 36 insertions, 7 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index b9126ef46a9e..32f9106d612c 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -2307,11 +2307,15 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) | |||
2307 | if (!iter) | 2307 | if (!iter) |
2308 | return -ENOMEM; | 2308 | return -ENOMEM; |
2309 | 2309 | ||
2310 | mutex_lock(&trace_types_lock); | ||
2310 | iter->tr = &global_trace; | 2311 | iter->tr = &global_trace; |
2311 | iter->trace = current_trace; | 2312 | iter->trace = current_trace; |
2312 | |||
2313 | filp->private_data = iter; | 2313 | filp->private_data = iter; |
2314 | 2314 | ||
2315 | if (iter->trace->pipe_open) | ||
2316 | iter->trace->pipe_open(iter); | ||
2317 | mutex_unlock(&trace_types_lock); | ||
2318 | |||
2315 | return 0; | 2319 | return 0; |
2316 | } | 2320 | } |
2317 | 2321 | ||
@@ -2380,13 +2384,24 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, | |||
2380 | return cnt; | 2384 | return cnt; |
2381 | } | 2385 | } |
2382 | 2386 | ||
2387 | mutex_lock(&trace_types_lock); | ||
2388 | if (iter->trace->read) { | ||
2389 | ret = iter->trace->read(iter, filp, ubuf, cnt, ppos); | ||
2390 | if (ret) { | ||
2391 | read = ret; | ||
2392 | goto out; | ||
2393 | } | ||
2394 | } | ||
2395 | |||
2383 | trace_seq_reset(&iter->seq); | 2396 | trace_seq_reset(&iter->seq); |
2384 | start = 0; | 2397 | start = 0; |
2385 | 2398 | ||
2386 | while (trace_empty(iter)) { | 2399 | while (trace_empty(iter)) { |
2387 | 2400 | ||
2388 | if ((filp->f_flags & O_NONBLOCK)) | 2401 | if ((filp->f_flags & O_NONBLOCK)) { |
2389 | return -EAGAIN; | 2402 | read = -EAGAIN; |
2403 | goto out; | ||
2404 | } | ||
2390 | 2405 | ||
2391 | /* | 2406 | /* |
2392 | * This is a make-shift waitqueue. The reason we don't use | 2407 | * This is a make-shift waitqueue. The reason we don't use |
@@ -2400,16 +2415,22 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, | |||
2400 | set_current_state(TASK_INTERRUPTIBLE); | 2415 | set_current_state(TASK_INTERRUPTIBLE); |
2401 | iter->tr->waiter = current; | 2416 | iter->tr->waiter = current; |
2402 | 2417 | ||
2418 | mutex_unlock(&trace_types_lock); | ||
2419 | |||
2403 | /* sleep for one second, and try again. */ | 2420 | /* sleep for one second, and try again. */ |
2404 | schedule_timeout(HZ); | 2421 | schedule_timeout(HZ); |
2405 | 2422 | ||
2423 | mutex_lock(&trace_types_lock); | ||
2424 | |||
2406 | iter->tr->waiter = NULL; | 2425 | iter->tr->waiter = NULL; |
2407 | 2426 | ||
2408 | if (signal_pending(current)) | 2427 | if (signal_pending(current)) { |
2409 | return -EINTR; | 2428 | read = -EINTR; |
2429 | goto out; | ||
2430 | } | ||
2410 | 2431 | ||
2411 | if (iter->trace != current_trace) | 2432 | if (iter->trace != current_trace) |
2412 | return 0; | 2433 | goto out; |
2413 | 2434 | ||
2414 | /* | 2435 | /* |
2415 | * We block until we read something and tracing is disabled. | 2436 | * We block until we read something and tracing is disabled. |
@@ -2428,7 +2449,7 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, | |||
2428 | 2449 | ||
2429 | /* stop when tracing is finished */ | 2450 | /* stop when tracing is finished */ |
2430 | if (trace_empty(iter)) | 2451 | if (trace_empty(iter)) |
2431 | return 0; | 2452 | goto out; |
2432 | 2453 | ||
2433 | if (cnt >= PAGE_SIZE) | 2454 | if (cnt >= PAGE_SIZE) |
2434 | cnt = PAGE_SIZE - 1; | 2455 | cnt = PAGE_SIZE - 1; |
@@ -2518,6 +2539,9 @@ tracing_read_pipe(struct file *filp, char __user *ubuf, | |||
2518 | if (ret) | 2539 | if (ret) |
2519 | read = -EFAULT; | 2540 | read = -EFAULT; |
2520 | 2541 | ||
2542 | out: | ||
2543 | mutex_unlock(&trace_types_lock); | ||
2544 | |||
2521 | return read; | 2545 | return read; |
2522 | } | 2546 | } |
2523 | 2547 | ||
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index c1ec134ac356..ee53d706066f 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
@@ -135,9 +135,13 @@ struct tracer { | |||
135 | void (*init)(struct trace_array *tr); | 135 | void (*init)(struct trace_array *tr); |
136 | void (*reset)(struct trace_array *tr); | 136 | void (*reset)(struct trace_array *tr); |
137 | void (*open)(struct trace_iterator *iter); | 137 | void (*open)(struct trace_iterator *iter); |
138 | void (*pipe_open)(struct trace_iterator *iter); | ||
138 | void (*close)(struct trace_iterator *iter); | 139 | void (*close)(struct trace_iterator *iter); |
139 | void (*start)(struct trace_iterator *iter); | 140 | void (*start)(struct trace_iterator *iter); |
140 | void (*stop)(struct trace_iterator *iter); | 141 | void (*stop)(struct trace_iterator *iter); |
142 | ssize_t (*read)(struct trace_iterator *iter, | ||
143 | struct file *filp, char __user *ubuf, | ||
144 | size_t cnt, loff_t *ppos); | ||
141 | void (*ctrl_update)(struct trace_array *tr); | 145 | void (*ctrl_update)(struct trace_array *tr); |
142 | #ifdef CONFIG_FTRACE_STARTUP_TEST | 146 | #ifdef CONFIG_FTRACE_STARTUP_TEST |
143 | int (*selftest)(struct tracer *trace, | 147 | int (*selftest)(struct tracer *trace, |
@@ -160,6 +164,7 @@ struct trace_seq { | |||
160 | struct trace_iterator { | 164 | struct trace_iterator { |
161 | struct trace_array *tr; | 165 | struct trace_array *tr; |
162 | struct tracer *trace; | 166 | struct tracer *trace; |
167 | void *private; | ||
163 | long last_overrun[NR_CPUS]; | 168 | long last_overrun[NR_CPUS]; |
164 | long overrun[NR_CPUS]; | 169 | long overrun[NR_CPUS]; |
165 | 170 | ||