diff options
author | Tao Huang <huangtao@rock-chips.com> | 2018-09-07 17:34:34 +0800 |
---|---|---|
committer | Tao Huang <huangtao@rock-chips.com> | 2018-09-07 17:34:34 +0800 |
commit | 75654db87775a407f17aa04fd31562fc2bdaa72f (patch) | |
tree | efbaa9c47e541b0ee8861105de6bf49fa27e22ab /kernel/trace | |
parent | 78585b99a328f6f2a9f76ef2f4b2fee2b1a8d788 (diff) | |
parent | 82eacc8a7bb8eb5809ef9ad8fae8104110626305 (diff) |
Merge branch 'linux-linaro-lsk-v4.4' of git://git.linaro.org/kernel/linux-linaro-stable.git
* linux-linaro-lsk-v4.4: (519 commits)
Linux 4.4.154
cdrom: Fix info leak/OOB read in cdrom_ioctl_drive_status
iscsi target: fix session creation failure handling
scsi: core: Avoid that SCSI device removal through sysfs triggers a deadlock
scsi: sysfs: Introduce sysfs_{un,}break_active_protection()
MIPS: lib: Provide MIPS64r6 __multi3() for GCC < 7
MIPS: Correct the 64-bit DSP accumulator register size
kprobes: Make list and blacklist root user read only
s390/pci: fix out of bounds access during irq setup
s390/qdio: reset old sbal_state flags
s390: fix br_r1_trampoline for machines without exrl
x86/spectre: Add missing family 6 check to microcode check
x86/irqflags: Mark native_restore_fl extern inline
pinctrl: freescale: off by one in imx1_pinconf_group_dbg_show()
ASoC: sirf: Fix potential NULL pointer dereference
ASoC: dpcm: don't merge format from invalid codec dai
udl-kms: fix crash due to uninitialized memory
udl-kms: handle allocation failure
udl-kms: change down_interruptible to down
fuse: Add missed unlock_page() to fuse_readpages_fill()
...
Conflicts:
Makefile
arch/arm64/mm/init.c
fs/squashfs/block.c
include/uapi/linux/prctl.h
kernel/sys.c
Change-Id: Ie03b5adfbbb4ab2bf16bc55d99f0d8a9c540a53b
Diffstat (limited to 'kernel/trace')
-rw-r--r-- | kernel/trace/ring_buffer.c | 16 | ||||
-rw-r--r-- | kernel/trace/trace.c | 11 | ||||
-rw-r--r-- | kernel/trace/trace_events_trigger.c | 18 | ||||
-rw-r--r-- | kernel/trace/trace_kprobe.c | 15 |
4 files changed, 53 insertions, 7 deletions
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index d9cd6191760b..fdaa88f38aec 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -3142,6 +3142,22 @@ int ring_buffer_record_is_on(struct ring_buffer *buffer) } /** + * ring_buffer_record_is_set_on - return true if the ring buffer is set writable + * @buffer: The ring buffer to see if write is set enabled + * + * Returns true if the ring buffer is set writable by ring_buffer_record_on(). + * Note that this does NOT mean it is in a writable state. + * + * It may return true when the ring buffer has been disabled by + * ring_buffer_record_disable(), as that is a temporary disabling of + * the ring buffer. + */ +int ring_buffer_record_is_set_on(struct ring_buffer *buffer) +{ + return !(atomic_read(&buffer->record_disabled) & RB_BUFFER_OFF); +} + +/** * ring_buffer_record_disable_cpu - stop all writes into the cpu_buffer * @buffer: The ring buffer to stop writes to. * @cpu: The CPU buffer to stop diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 293faa2ff763..efdddec2af6e 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1089,6 +1089,12 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) arch_spin_lock(&tr->max_lock); + /* Inherit the recordable setting from trace_buffer */ + if (ring_buffer_record_is_set_on(tr->trace_buffer.buffer)) + ring_buffer_record_on(tr->max_buffer.buffer); + else + ring_buffer_record_off(tr->max_buffer.buffer); + buf = tr->trace_buffer.buffer; tr->trace_buffer.buffer = tr->max_buffer.buffer; tr->max_buffer.buffer = buf; @@ -2201,6 +2207,7 @@ out: } EXPORT_SYMBOL_GPL(trace_vbprintk); +__printf(3, 0) static int __trace_array_vprintk(struct ring_buffer *buffer, unsigned long ip, const char *fmt, va_list args) @@ -2251,12 +2258,14 @@ __trace_array_vprintk(struct ring_buffer *buffer, return len; } +__printf(3, 0) int trace_array_vprintk(struct trace_array *tr, unsigned long ip, const char *fmt, va_list args) { return __trace_array_vprintk(tr->trace_buffer.buffer, ip, fmt, args); } +__printf(3, 0) int trace_array_printk(struct trace_array *tr, unsigned long ip, const char *fmt, ...) { @@ -2272,6 +2281,7 @@ int trace_array_printk(struct trace_array *tr, return ret; } +__printf(3, 4) int trace_array_printk_buf(struct ring_buffer *buffer, unsigned long ip, const char *fmt, ...) { @@ -2287,6 +2297,7 @@ int trace_array_printk_buf(struct ring_buffer *buffer, return ret; } +__printf(2, 0) int trace_vprintk(unsigned long ip, const char *fmt, va_list args) { return trace_array_vprintk(&global_trace, ip, fmt, args); diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c index 2172dd61577e..b8a894adab2c 100644 --- a/kernel/trace/trace_events_trigger.c +++ b/kernel/trace/trace_events_trigger.c @@ -663,6 +663,8 @@ event_trigger_callback(struct event_command *cmd_ops, goto out_free; out_reg: + /* Up the trigger_data count to make sure reg doesn't free it on failure */ + event_trigger_init(trigger_ops, trigger_data); ret = cmd_ops->reg(glob, trigger_ops, trigger_data, file); /* * The above returns on success the # of functions enabled, @@ -670,11 +672,13 @@ event_trigger_callback(struct event_command *cmd_ops, * Consider no functions a failure too. */ if (!ret) { + cmd_ops->unreg(glob, trigger_ops, trigger_data, file); ret = -ENOENT; - goto out_free; - } else if (ret < 0) - goto out_free; - ret = 0; + } else if (ret > 0) + ret = 0; + + /* Down the counter of trigger_data or free it if not used anymore */ + event_trigger_free(trigger_ops, trigger_data); out: return ret; @@ -1227,6 +1231,9 @@ event_enable_trigger_func(struct event_command *cmd_ops, goto out; } + /* Up the trigger_data count to make sure nothing frees it on failure */ + event_trigger_init(trigger_ops, trigger_data); + if (trigger) { number = strsep(&trigger, ":"); @@ -1277,6 +1284,7 @@ event_enable_trigger_func(struct event_command *cmd_ops, goto out_disable; /* Just return zero, not the number of enabled functions */ ret = 0; + event_trigger_free(trigger_ops, trigger_data); out: return ret; @@ -1287,7 +1295,7 @@ event_enable_trigger_func(struct event_command *cmd_ops, out_free: if (cmd_ops->set_filter) cmd_ops->set_filter(NULL, trigger_data, NULL); - kfree(trigger_data); + event_trigger_free(trigger_ops, trigger_data); kfree(enable_data); goto out; } diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index f2682799c215..f0ee722be520 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -349,11 +349,10 @@ static struct trace_kprobe *find_trace_kprobe(const char *event, static int enable_trace_kprobe(struct trace_kprobe *tk, struct trace_event_file *file) { + struct event_file_link *link = NULL; int ret = 0; if (file) { - struct event_file_link *link; - link = kmalloc(sizeof(*link), GFP_KERNEL); if (!link) { ret = -ENOMEM; @@ -373,6 +372,18 @@ enable_trace_kprobe(struct trace_kprobe *tk, struct trace_event_file *file) else ret = enable_kprobe(&tk->rp.kp); } + + if (ret) { + if (file) { + /* Notice the if is true on not WARN() */ + if (!WARN_ON_ONCE(!link)) + list_del_rcu(&link->list); + kfree(link); + tk->tp.flags &= ~TP_FLAG_TRACE; + } else { + tk->tp.flags &= ~TP_FLAG_PROFILE; + } + } out: return ret; } |