diff options
| author | Takashi Iwai <tiwai@suse.de> | 2013-01-27 04:20:22 -0500 |
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2013-01-27 04:20:22 -0500 |
| commit | 257c2a02a8f668ea195bcb56eebbddc1af718e5e (patch) | |
| tree | 27ccff43bc36d119dc3afeaf610638a56f4bf3ea /kernel | |
| parent | 0712eea349d8e2b6d0e44b94a752d999319027fb (diff) | |
| parent | a8c136d2eba7b0b0c872e59eb404b1fe36504112 (diff) | |
Merge tag 'asoc-3.8-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Updates for v3.8-rc4
The usual set of driver updates, nothing too thrilling in here - one
core change for the regulator bypass mode which was just not doing the
right thing at all and a bunch of driver specifics.
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/async.c | 3 | ||||
| -rw-r--r-- | kernel/audit.c | 40 | ||||
| -rw-r--r-- | kernel/audit_tree.c | 26 | ||||
| -rw-r--r-- | kernel/audit_watch.c | 2 | ||||
| -rw-r--r-- | kernel/auditfilter.c | 1 | ||||
| -rw-r--r-- | kernel/auditsc.c | 20 | ||||
| -rw-r--r-- | kernel/module.c | 27 | ||||
| -rw-r--r-- | kernel/rwsem.c | 10 | ||||
| -rw-r--r-- | kernel/trace/trace.c | 17 |
9 files changed, 112 insertions, 34 deletions
diff --git a/kernel/async.c b/kernel/async.c index 9d3118384858..a1d585c351d6 100644 --- a/kernel/async.c +++ b/kernel/async.c | |||
| @@ -196,6 +196,9 @@ static async_cookie_t __async_schedule(async_func_ptr *ptr, void *data, struct a | |||
| 196 | atomic_inc(&entry_count); | 196 | atomic_inc(&entry_count); |
| 197 | spin_unlock_irqrestore(&async_lock, flags); | 197 | spin_unlock_irqrestore(&async_lock, flags); |
| 198 | 198 | ||
| 199 | /* mark that this task has queued an async job, used by module init */ | ||
| 200 | current->flags |= PF_USED_ASYNC; | ||
| 201 | |||
| 199 | /* schedule for execution */ | 202 | /* schedule for execution */ |
| 200 | queue_work(system_unbound_wq, &entry->work); | 203 | queue_work(system_unbound_wq, &entry->work); |
| 201 | 204 | ||
diff --git a/kernel/audit.c b/kernel/audit.c index 40414e9143db..d596e5355f15 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
| @@ -272,6 +272,8 @@ static int audit_log_config_change(char *function_name, int new, int old, | |||
| 272 | int rc = 0; | 272 | int rc = 0; |
| 273 | 273 | ||
| 274 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); | 274 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); |
| 275 | if (unlikely(!ab)) | ||
| 276 | return rc; | ||
| 275 | audit_log_format(ab, "%s=%d old=%d auid=%u ses=%u", function_name, new, | 277 | audit_log_format(ab, "%s=%d old=%d auid=%u ses=%u", function_name, new, |
| 276 | old, from_kuid(&init_user_ns, loginuid), sessionid); | 278 | old, from_kuid(&init_user_ns, loginuid), sessionid); |
| 277 | if (sid) { | 279 | if (sid) { |
| @@ -619,6 +621,8 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type, | |||
| 619 | } | 621 | } |
| 620 | 622 | ||
| 621 | *ab = audit_log_start(NULL, GFP_KERNEL, msg_type); | 623 | *ab = audit_log_start(NULL, GFP_KERNEL, msg_type); |
| 624 | if (unlikely(!*ab)) | ||
| 625 | return rc; | ||
| 622 | audit_log_format(*ab, "pid=%d uid=%u auid=%u ses=%u", | 626 | audit_log_format(*ab, "pid=%d uid=%u auid=%u ses=%u", |
| 623 | task_tgid_vnr(current), | 627 | task_tgid_vnr(current), |
| 624 | from_kuid(&init_user_ns, current_uid()), | 628 | from_kuid(&init_user_ns, current_uid()), |
| @@ -1097,6 +1101,23 @@ static inline void audit_get_stamp(struct audit_context *ctx, | |||
| 1097 | } | 1101 | } |
| 1098 | } | 1102 | } |
| 1099 | 1103 | ||
| 1104 | /* | ||
| 1105 | * Wait for auditd to drain the queue a little | ||
| 1106 | */ | ||
| 1107 | static void wait_for_auditd(unsigned long sleep_time) | ||
| 1108 | { | ||
| 1109 | DECLARE_WAITQUEUE(wait, current); | ||
| 1110 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 1111 | add_wait_queue(&audit_backlog_wait, &wait); | ||
| 1112 | |||
| 1113 | if (audit_backlog_limit && | ||
| 1114 | skb_queue_len(&audit_skb_queue) > audit_backlog_limit) | ||
| 1115 | schedule_timeout(sleep_time); | ||
| 1116 | |||
| 1117 | __set_current_state(TASK_RUNNING); | ||
| 1118 | remove_wait_queue(&audit_backlog_wait, &wait); | ||
| 1119 | } | ||
| 1120 | |||
| 1100 | /* Obtain an audit buffer. This routine does locking to obtain the | 1121 | /* Obtain an audit buffer. This routine does locking to obtain the |
| 1101 | * audit buffer, but then no locking is required for calls to | 1122 | * audit buffer, but then no locking is required for calls to |
| 1102 | * audit_log_*format. If the tsk is a task that is currently in a | 1123 | * audit_log_*format. If the tsk is a task that is currently in a |
| @@ -1142,20 +1163,13 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, | |||
| 1142 | 1163 | ||
| 1143 | while (audit_backlog_limit | 1164 | while (audit_backlog_limit |
| 1144 | && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) { | 1165 | && skb_queue_len(&audit_skb_queue) > audit_backlog_limit + reserve) { |
| 1145 | if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time | 1166 | if (gfp_mask & __GFP_WAIT && audit_backlog_wait_time) { |
| 1146 | && time_before(jiffies, timeout_start + audit_backlog_wait_time)) { | 1167 | unsigned long sleep_time; |
| 1147 | 1168 | ||
| 1148 | /* Wait for auditd to drain the queue a little */ | 1169 | sleep_time = timeout_start + audit_backlog_wait_time - |
| 1149 | DECLARE_WAITQUEUE(wait, current); | 1170 | jiffies; |
| 1150 | set_current_state(TASK_INTERRUPTIBLE); | 1171 | if ((long)sleep_time > 0) |
| 1151 | add_wait_queue(&audit_backlog_wait, &wait); | 1172 | wait_for_auditd(sleep_time); |
| 1152 | |||
| 1153 | if (audit_backlog_limit && | ||
| 1154 | skb_queue_len(&audit_skb_queue) > audit_backlog_limit) | ||
| 1155 | schedule_timeout(timeout_start + audit_backlog_wait_time - jiffies); | ||
| 1156 | |||
| 1157 | __set_current_state(TASK_RUNNING); | ||
| 1158 | remove_wait_queue(&audit_backlog_wait, &wait); | ||
| 1159 | continue; | 1173 | continue; |
| 1160 | } | 1174 | } |
| 1161 | if (audit_rate_check() && printk_ratelimit()) | 1175 | if (audit_rate_check() && printk_ratelimit()) |
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index e81175ef25f8..642a89c4f3d6 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c | |||
| @@ -449,11 +449,26 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) | |||
| 449 | return 0; | 449 | return 0; |
| 450 | } | 450 | } |
| 451 | 451 | ||
| 452 | static void audit_log_remove_rule(struct audit_krule *rule) | ||
| 453 | { | ||
| 454 | struct audit_buffer *ab; | ||
| 455 | |||
| 456 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); | ||
| 457 | if (unlikely(!ab)) | ||
| 458 | return; | ||
| 459 | audit_log_format(ab, "op="); | ||
| 460 | audit_log_string(ab, "remove rule"); | ||
| 461 | audit_log_format(ab, " dir="); | ||
| 462 | audit_log_untrustedstring(ab, rule->tree->pathname); | ||
| 463 | audit_log_key(ab, rule->filterkey); | ||
| 464 | audit_log_format(ab, " list=%d res=1", rule->listnr); | ||
| 465 | audit_log_end(ab); | ||
| 466 | } | ||
| 467 | |||
| 452 | static void kill_rules(struct audit_tree *tree) | 468 | static void kill_rules(struct audit_tree *tree) |
| 453 | { | 469 | { |
| 454 | struct audit_krule *rule, *next; | 470 | struct audit_krule *rule, *next; |
| 455 | struct audit_entry *entry; | 471 | struct audit_entry *entry; |
| 456 | struct audit_buffer *ab; | ||
| 457 | 472 | ||
| 458 | list_for_each_entry_safe(rule, next, &tree->rules, rlist) { | 473 | list_for_each_entry_safe(rule, next, &tree->rules, rlist) { |
| 459 | entry = container_of(rule, struct audit_entry, rule); | 474 | entry = container_of(rule, struct audit_entry, rule); |
| @@ -461,14 +476,7 @@ static void kill_rules(struct audit_tree *tree) | |||
| 461 | list_del_init(&rule->rlist); | 476 | list_del_init(&rule->rlist); |
| 462 | if (rule->tree) { | 477 | if (rule->tree) { |
| 463 | /* not a half-baked one */ | 478 | /* not a half-baked one */ |
| 464 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE); | 479 | audit_log_remove_rule(rule); |
| 465 | audit_log_format(ab, "op="); | ||
| 466 | audit_log_string(ab, "remove rule"); | ||
| 467 | audit_log_format(ab, " dir="); | ||
| 468 | audit_log_untrustedstring(ab, rule->tree->pathname); | ||
| 469 | audit_log_key(ab, rule->filterkey); | ||
| 470 | audit_log_format(ab, " list=%d res=1", rule->listnr); | ||
| 471 | audit_log_end(ab); | ||
| 472 | rule->tree = NULL; | 480 | rule->tree = NULL; |
| 473 | list_del_rcu(&entry->list); | 481 | list_del_rcu(&entry->list); |
| 474 | list_del(&entry->rule.list); | 482 | list_del(&entry->rule.list); |
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index 4a599f699adc..22831c4d369c 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c | |||
| @@ -240,6 +240,8 @@ static void audit_watch_log_rule_change(struct audit_krule *r, struct audit_watc | |||
| 240 | if (audit_enabled) { | 240 | if (audit_enabled) { |
| 241 | struct audit_buffer *ab; | 241 | struct audit_buffer *ab; |
| 242 | ab = audit_log_start(NULL, GFP_NOFS, AUDIT_CONFIG_CHANGE); | 242 | ab = audit_log_start(NULL, GFP_NOFS, AUDIT_CONFIG_CHANGE); |
| 243 | if (unlikely(!ab)) | ||
| 244 | return; | ||
| 243 | audit_log_format(ab, "auid=%u ses=%u op=", | 245 | audit_log_format(ab, "auid=%u ses=%u op=", |
| 244 | from_kuid(&init_user_ns, audit_get_loginuid(current)), | 246 | from_kuid(&init_user_ns, audit_get_loginuid(current)), |
| 245 | audit_get_sessionid(current)); | 247 | audit_get_sessionid(current)); |
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 7f19f23d38a3..f9fc54bbe06f 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c | |||
| @@ -1144,7 +1144,6 @@ static void audit_log_rule_change(kuid_t loginuid, u32 sessionid, u32 sid, | |||
| 1144 | * audit_receive_filter - apply all rules to the specified message type | 1144 | * audit_receive_filter - apply all rules to the specified message type |
| 1145 | * @type: audit message type | 1145 | * @type: audit message type |
| 1146 | * @pid: target pid for netlink audit messages | 1146 | * @pid: target pid for netlink audit messages |
| 1147 | * @uid: target uid for netlink audit messages | ||
| 1148 | * @seq: netlink audit message sequence (serial) number | 1147 | * @seq: netlink audit message sequence (serial) number |
| 1149 | * @data: payload data | 1148 | * @data: payload data |
| 1150 | * @datasz: size of payload data | 1149 | * @datasz: size of payload data |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index e37e6a12c5e3..a371f857a0a9 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
| @@ -1464,14 +1464,14 @@ static void show_special(struct audit_context *context, int *call_panic) | |||
| 1464 | audit_log_end(ab); | 1464 | audit_log_end(ab); |
| 1465 | ab = audit_log_start(context, GFP_KERNEL, | 1465 | ab = audit_log_start(context, GFP_KERNEL, |
| 1466 | AUDIT_IPC_SET_PERM); | 1466 | AUDIT_IPC_SET_PERM); |
| 1467 | if (unlikely(!ab)) | ||
| 1468 | return; | ||
| 1467 | audit_log_format(ab, | 1469 | audit_log_format(ab, |
| 1468 | "qbytes=%lx ouid=%u ogid=%u mode=%#ho", | 1470 | "qbytes=%lx ouid=%u ogid=%u mode=%#ho", |
| 1469 | context->ipc.qbytes, | 1471 | context->ipc.qbytes, |
| 1470 | context->ipc.perm_uid, | 1472 | context->ipc.perm_uid, |
| 1471 | context->ipc.perm_gid, | 1473 | context->ipc.perm_gid, |
| 1472 | context->ipc.perm_mode); | 1474 | context->ipc.perm_mode); |
| 1473 | if (!ab) | ||
| 1474 | return; | ||
| 1475 | } | 1475 | } |
| 1476 | break; } | 1476 | break; } |
| 1477 | case AUDIT_MQ_OPEN: { | 1477 | case AUDIT_MQ_OPEN: { |
| @@ -2675,7 +2675,7 @@ void __audit_mmap_fd(int fd, int flags) | |||
| 2675 | context->type = AUDIT_MMAP; | 2675 | context->type = AUDIT_MMAP; |
| 2676 | } | 2676 | } |
| 2677 | 2677 | ||
| 2678 | static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr) | 2678 | static void audit_log_task(struct audit_buffer *ab) |
| 2679 | { | 2679 | { |
| 2680 | kuid_t auid, uid; | 2680 | kuid_t auid, uid; |
| 2681 | kgid_t gid; | 2681 | kgid_t gid; |
| @@ -2693,6 +2693,11 @@ static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr) | |||
| 2693 | audit_log_task_context(ab); | 2693 | audit_log_task_context(ab); |
| 2694 | audit_log_format(ab, " pid=%d comm=", current->pid); | 2694 | audit_log_format(ab, " pid=%d comm=", current->pid); |
| 2695 | audit_log_untrustedstring(ab, current->comm); | 2695 | audit_log_untrustedstring(ab, current->comm); |
| 2696 | } | ||
| 2697 | |||
| 2698 | static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr) | ||
| 2699 | { | ||
| 2700 | audit_log_task(ab); | ||
| 2696 | audit_log_format(ab, " reason="); | 2701 | audit_log_format(ab, " reason="); |
| 2697 | audit_log_string(ab, reason); | 2702 | audit_log_string(ab, reason); |
| 2698 | audit_log_format(ab, " sig=%ld", signr); | 2703 | audit_log_format(ab, " sig=%ld", signr); |
| @@ -2715,6 +2720,8 @@ void audit_core_dumps(long signr) | |||
| 2715 | return; | 2720 | return; |
| 2716 | 2721 | ||
| 2717 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); | 2722 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); |
| 2723 | if (unlikely(!ab)) | ||
| 2724 | return; | ||
| 2718 | audit_log_abend(ab, "memory violation", signr); | 2725 | audit_log_abend(ab, "memory violation", signr); |
| 2719 | audit_log_end(ab); | 2726 | audit_log_end(ab); |
| 2720 | } | 2727 | } |
| @@ -2723,8 +2730,11 @@ void __audit_seccomp(unsigned long syscall, long signr, int code) | |||
| 2723 | { | 2730 | { |
| 2724 | struct audit_buffer *ab; | 2731 | struct audit_buffer *ab; |
| 2725 | 2732 | ||
| 2726 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); | 2733 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_SECCOMP); |
| 2727 | audit_log_abend(ab, "seccomp", signr); | 2734 | if (unlikely(!ab)) |
| 2735 | return; | ||
| 2736 | audit_log_task(ab); | ||
| 2737 | audit_log_format(ab, " sig=%ld", signr); | ||
| 2728 | audit_log_format(ab, " syscall=%ld", syscall); | 2738 | audit_log_format(ab, " syscall=%ld", syscall); |
| 2729 | audit_log_format(ab, " compat=%d", is_compat_task()); | 2739 | audit_log_format(ab, " compat=%d", is_compat_task()); |
| 2730 | audit_log_format(ab, " ip=0x%lx", KSTK_EIP(current)); | 2740 | audit_log_format(ab, " ip=0x%lx", KSTK_EIP(current)); |
diff --git a/kernel/module.c b/kernel/module.c index 250092c1d57d..b10b048367e1 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -3013,6 +3013,12 @@ static int do_init_module(struct module *mod) | |||
| 3013 | { | 3013 | { |
| 3014 | int ret = 0; | 3014 | int ret = 0; |
| 3015 | 3015 | ||
| 3016 | /* | ||
| 3017 | * We want to find out whether @mod uses async during init. Clear | ||
| 3018 | * PF_USED_ASYNC. async_schedule*() will set it. | ||
| 3019 | */ | ||
| 3020 | current->flags &= ~PF_USED_ASYNC; | ||
| 3021 | |||
| 3016 | blocking_notifier_call_chain(&module_notify_list, | 3022 | blocking_notifier_call_chain(&module_notify_list, |
| 3017 | MODULE_STATE_COMING, mod); | 3023 | MODULE_STATE_COMING, mod); |
| 3018 | 3024 | ||
| @@ -3058,8 +3064,25 @@ static int do_init_module(struct module *mod) | |||
| 3058 | blocking_notifier_call_chain(&module_notify_list, | 3064 | blocking_notifier_call_chain(&module_notify_list, |
| 3059 | MODULE_STATE_LIVE, mod); | 3065 | MODULE_STATE_LIVE, mod); |
| 3060 | 3066 | ||
| 3061 | /* We need to finish all async code before the module init sequence is done */ | 3067 | /* |
| 3062 | async_synchronize_full(); | 3068 | * We need to finish all async code before the module init sequence |
| 3069 | * is done. This has potential to deadlock. For example, a newly | ||
| 3070 | * detected block device can trigger request_module() of the | ||
| 3071 | * default iosched from async probing task. Once userland helper | ||
| 3072 | * reaches here, async_synchronize_full() will wait on the async | ||
| 3073 | * task waiting on request_module() and deadlock. | ||
| 3074 | * | ||
| 3075 | * This deadlock is avoided by perfomring async_synchronize_full() | ||
| 3076 | * iff module init queued any async jobs. This isn't a full | ||
| 3077 | * solution as it will deadlock the same if module loading from | ||
| 3078 | * async jobs nests more than once; however, due to the various | ||
| 3079 | * constraints, this hack seems to be the best option for now. | ||
| 3080 | * Please refer to the following thread for details. | ||
| 3081 | * | ||
| 3082 | * http://thread.gmane.org/gmane.linux.kernel/1420814 | ||
| 3083 | */ | ||
| 3084 | if (current->flags & PF_USED_ASYNC) | ||
| 3085 | async_synchronize_full(); | ||
| 3063 | 3086 | ||
| 3064 | mutex_lock(&module_mutex); | 3087 | mutex_lock(&module_mutex); |
| 3065 | /* Drop initial reference. */ | 3088 | /* Drop initial reference. */ |
diff --git a/kernel/rwsem.c b/kernel/rwsem.c index 6850f53e02d8..b3c6c3fcd847 100644 --- a/kernel/rwsem.c +++ b/kernel/rwsem.c | |||
| @@ -116,6 +116,16 @@ void down_read_nested(struct rw_semaphore *sem, int subclass) | |||
| 116 | 116 | ||
| 117 | EXPORT_SYMBOL(down_read_nested); | 117 | EXPORT_SYMBOL(down_read_nested); |
| 118 | 118 | ||
| 119 | void _down_write_nest_lock(struct rw_semaphore *sem, struct lockdep_map *nest) | ||
| 120 | { | ||
| 121 | might_sleep(); | ||
| 122 | rwsem_acquire_nest(&sem->dep_map, 0, 0, nest, _RET_IP_); | ||
| 123 | |||
| 124 | LOCK_CONTENDED(sem, __down_write_trylock, __down_write); | ||
| 125 | } | ||
| 126 | |||
| 127 | EXPORT_SYMBOL(_down_write_nest_lock); | ||
| 128 | |||
| 119 | void down_write_nested(struct rw_semaphore *sem, int subclass) | 129 | void down_write_nested(struct rw_semaphore *sem, int subclass) |
| 120 | { | 130 | { |
| 121 | might_sleep(); | 131 | might_sleep(); |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index e5125677efa0..3c13e46d7d24 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
| @@ -2899,6 +2899,8 @@ tracing_trace_options_write(struct file *filp, const char __user *ubuf, | |||
| 2899 | if (copy_from_user(&buf, ubuf, cnt)) | 2899 | if (copy_from_user(&buf, ubuf, cnt)) |
| 2900 | return -EFAULT; | 2900 | return -EFAULT; |
| 2901 | 2901 | ||
| 2902 | buf[cnt] = 0; | ||
| 2903 | |||
| 2902 | trace_set_options(buf); | 2904 | trace_set_options(buf); |
| 2903 | 2905 | ||
| 2904 | *ppos += cnt; | 2906 | *ppos += cnt; |
| @@ -3452,7 +3454,7 @@ static int tracing_wait_pipe(struct file *filp) | |||
| 3452 | return -EINTR; | 3454 | return -EINTR; |
| 3453 | 3455 | ||
| 3454 | /* | 3456 | /* |
| 3455 | * We block until we read something and tracing is enabled. | 3457 | * We block until we read something and tracing is disabled. |
| 3456 | * We still block if tracing is disabled, but we have never | 3458 | * We still block if tracing is disabled, but we have never |
| 3457 | * read anything. This allows a user to cat this file, and | 3459 | * read anything. This allows a user to cat this file, and |
| 3458 | * then enable tracing. But after we have read something, | 3460 | * then enable tracing. But after we have read something, |
| @@ -3460,7 +3462,7 @@ static int tracing_wait_pipe(struct file *filp) | |||
| 3460 | * | 3462 | * |
| 3461 | * iter->pos will be 0 if we haven't read anything. | 3463 | * iter->pos will be 0 if we haven't read anything. |
| 3462 | */ | 3464 | */ |
| 3463 | if (tracing_is_enabled() && iter->pos) | 3465 | if (!tracing_is_enabled() && iter->pos) |
| 3464 | break; | 3466 | break; |
| 3465 | } | 3467 | } |
| 3466 | 3468 | ||
| @@ -4815,10 +4817,17 @@ rb_simple_write(struct file *filp, const char __user *ubuf, | |||
| 4815 | return ret; | 4817 | return ret; |
| 4816 | 4818 | ||
| 4817 | if (buffer) { | 4819 | if (buffer) { |
| 4818 | if (val) | 4820 | mutex_lock(&trace_types_lock); |
| 4821 | if (val) { | ||
| 4819 | ring_buffer_record_on(buffer); | 4822 | ring_buffer_record_on(buffer); |
| 4820 | else | 4823 | if (current_trace->start) |
| 4824 | current_trace->start(tr); | ||
| 4825 | } else { | ||
| 4821 | ring_buffer_record_off(buffer); | 4826 | ring_buffer_record_off(buffer); |
| 4827 | if (current_trace->stop) | ||
| 4828 | current_trace->stop(tr); | ||
| 4829 | } | ||
| 4830 | mutex_unlock(&trace_types_lock); | ||
| 4822 | } | 4831 | } |
| 4823 | 4832 | ||
| 4824 | (*ppos)++; | 4833 | (*ppos)++; |
