Loading include/linux/ipc_logging.h +8 −1 Original line number Diff line number Diff line /* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2015, 2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -124,6 +124,13 @@ void ipc_log_write(void *ctxt, struct encode_context *ectxt); */ int ipc_log_string(void *ilctxt, const char *fmt, ...) __printf(2, 3); /* * ipc_log_ctrl_all - disable/enable logging in all clients * * @ Data specified using format specifiers */ void ipc_log_ctrl_all(bool disable); /** * ipc_log_extract - Reads and deserializes log * Loading kernel/trace/ipc_logging.c +32 −1 Original line number Diff line number Diff line /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -295,6 +295,8 @@ void ipc_log_write(void *ctxt, struct encode_context *ectxt) return; } if (ilctxt->disabled) return; read_lock_irqsave(&context_list_lock_lha1, flags); spin_lock(&ilctxt->context_lock_lhb1); while (ilctxt->write_avail <= ectxt->offset) Loading Loading @@ -508,11 +510,14 @@ int ipc_log_string(void *ilctxt, const char *fmt, ...) { struct encode_context ectxt; int avail_size, data_size, hdr_size = sizeof(struct tsv_header); struct ipc_log_context *ctxt = (struct ipc_log_context *)ilctxt; va_list arg_list; if (!ilctxt) return -EINVAL; if (ctxt->disabled) return -EBUSY; msg_encode_start(&ectxt, TSV_TYPE_STRING); tsv_timestamp_write(&ectxt); tsv_qtimer_write(&ectxt); Loading @@ -529,6 +534,32 @@ int ipc_log_string(void *ilctxt, const char *fmt, ...) } EXPORT_SYMBOL(ipc_log_string); /* * ipc_log_ctrl_all - disable/enable logging in all clients * * @ Data specified using format specifiers */ void ipc_log_ctrl_all(bool disable) { struct ipc_log_context *ctxt = NULL; unsigned long flags; read_lock_irqsave(&context_list_lock_lha1, flags); list_for_each_entry(ctxt, &ipc_log_context_list, list) { if (disable) { ipc_log_string(ctxt, "LOGGING DISABLED FOR ALL CLIENTS!!\n"); ctxt->disabled = disable; } else { ctxt->disabled = disable; ipc_log_string(ctxt, "LOGGING ENABLED FOR ALL CLIENTS!!\n"); } } read_unlock_irqrestore(&context_list_lock_lha1, flags); } EXPORT_SYMBOL(ipc_log_ctrl_all); /** * ipc_log_extract - Reads and deserializes log * Loading kernel/trace/ipc_logging_debug.c +93 −1 Original line number Diff line number Diff line /* Copyright (c) 2012-2015, 2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2015,2017-2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -113,6 +113,83 @@ static ssize_t debug_read_helper(struct file *file, char __user *buff, return bsize; } static ssize_t debug_write_ctrl(struct file *file, const char __user *buff, size_t count, loff_t *ppos) { struct ipc_log_context *ilctxt; struct dentry *d = file->f_path.dentry; int bsize = 1; int srcu_idx; int r; char local_buf[3]; r = debugfs_use_file_start(d, &srcu_idx); if (!r) { ilctxt = file->private_data; r = kref_get_unless_zero(&ilctxt->refcount) ? 0 : -EIO; } debugfs_use_file_finish(srcu_idx); if (r) return r; if (copy_from_user(local_buf, buff, bsize)) { count = -EFAULT; goto done; } if (*local_buf == '1') { ipc_log_string(ilctxt, "LOGGING DISABLED FOR THIS CLIENT!!\n"); ilctxt->disabled = true; } else if (*local_buf == '0') { ilctxt->disabled = false; ipc_log_string(ilctxt, "LOGGING ENABLED FOR THIS CLIENT!!\n"); } done: ipc_log_context_put(ilctxt); return count; } static ssize_t debug_write_ctrl_all(struct file *file, const char __user *buff, size_t count, loff_t *ppos) { int bsize = 1; char local_buf[3]; if (copy_from_user(local_buf, buff, bsize)) return -EFAULT; if (*local_buf == '1') ipc_log_ctrl_all(true); else if (*local_buf == '0') ipc_log_ctrl_all(false); return count; } static ssize_t debug_read_ctrl(struct file *file, char __user *buff, size_t count, loff_t *ppos) { struct ipc_log_context *ilctxt; struct dentry *d = file->f_path.dentry; int bsize = 2; int srcu_idx; int r; r = debugfs_use_file_start(d, &srcu_idx); if (!r) { ilctxt = file->private_data; r = kref_get_unless_zero(&ilctxt->refcount) ? 0 : -EIO; } debugfs_use_file_finish(srcu_idx); if (r) return r; bsize = simple_read_from_buffer(buff, count, ppos, ilctxt->disabled?"1\n":"0\n", bsize); ipc_log_context_put(ilctxt); return bsize; } static ssize_t debug_read(struct file *file, char __user *buff, size_t count, loff_t *ppos) { Loading Loading @@ -141,6 +218,16 @@ static const struct file_operations debug_ops_cont = { .open = debug_open, }; static const struct file_operations debug_ops_ctrl = { .read = debug_read_ctrl, .write = debug_write_ctrl, .open = debug_open, }; static const struct file_operations debug_ops_ctrl_all = { .write = debug_write_ctrl_all, }; static void debug_create(const char *name, mode_t mode, struct dentry *dent, struct ipc_log_context *ilctxt, Loading Loading @@ -176,6 +263,9 @@ void check_and_create_debugfs(void) pr_err("%s: unable to create debugfs %ld\n", __func__, PTR_ERR(root_dent)); root_dent = NULL; } else { debug_create("ctrl_all", 0444, root_dent, NULL, &debug_ops_ctrl_all); } } mutex_unlock(&ipc_log_debugfs_init_lock); Loading @@ -195,6 +285,8 @@ void create_ctx_debugfs(struct ipc_log_context *ctxt, ctxt, &debug_ops); debug_create("log_cont", 0444, ctxt->dent, ctxt, &debug_ops_cont); debug_create("log_disable", 0444, ctxt->dent, ctxt, &debug_ops_ctrl); } } add_deserialization_func((void *)ctxt, Loading kernel/trace/ipc_logging_private.h +2 −1 Original line number Diff line number Diff line /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -121,6 +121,7 @@ struct ipc_log_context { struct completion read_avail; struct kref refcount; bool destroyed; bool disabled; }; struct dfunc_info { Loading Loading
include/linux/ipc_logging.h +8 −1 Original line number Diff line number Diff line /* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2015, 2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -124,6 +124,13 @@ void ipc_log_write(void *ctxt, struct encode_context *ectxt); */ int ipc_log_string(void *ilctxt, const char *fmt, ...) __printf(2, 3); /* * ipc_log_ctrl_all - disable/enable logging in all clients * * @ Data specified using format specifiers */ void ipc_log_ctrl_all(bool disable); /** * ipc_log_extract - Reads and deserializes log * Loading
kernel/trace/ipc_logging.c +32 −1 Original line number Diff line number Diff line /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -295,6 +295,8 @@ void ipc_log_write(void *ctxt, struct encode_context *ectxt) return; } if (ilctxt->disabled) return; read_lock_irqsave(&context_list_lock_lha1, flags); spin_lock(&ilctxt->context_lock_lhb1); while (ilctxt->write_avail <= ectxt->offset) Loading Loading @@ -508,11 +510,14 @@ int ipc_log_string(void *ilctxt, const char *fmt, ...) { struct encode_context ectxt; int avail_size, data_size, hdr_size = sizeof(struct tsv_header); struct ipc_log_context *ctxt = (struct ipc_log_context *)ilctxt; va_list arg_list; if (!ilctxt) return -EINVAL; if (ctxt->disabled) return -EBUSY; msg_encode_start(&ectxt, TSV_TYPE_STRING); tsv_timestamp_write(&ectxt); tsv_qtimer_write(&ectxt); Loading @@ -529,6 +534,32 @@ int ipc_log_string(void *ilctxt, const char *fmt, ...) } EXPORT_SYMBOL(ipc_log_string); /* * ipc_log_ctrl_all - disable/enable logging in all clients * * @ Data specified using format specifiers */ void ipc_log_ctrl_all(bool disable) { struct ipc_log_context *ctxt = NULL; unsigned long flags; read_lock_irqsave(&context_list_lock_lha1, flags); list_for_each_entry(ctxt, &ipc_log_context_list, list) { if (disable) { ipc_log_string(ctxt, "LOGGING DISABLED FOR ALL CLIENTS!!\n"); ctxt->disabled = disable; } else { ctxt->disabled = disable; ipc_log_string(ctxt, "LOGGING ENABLED FOR ALL CLIENTS!!\n"); } } read_unlock_irqrestore(&context_list_lock_lha1, flags); } EXPORT_SYMBOL(ipc_log_ctrl_all); /** * ipc_log_extract - Reads and deserializes log * Loading
kernel/trace/ipc_logging_debug.c +93 −1 Original line number Diff line number Diff line /* Copyright (c) 2012-2015, 2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2015,2017-2018 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -113,6 +113,83 @@ static ssize_t debug_read_helper(struct file *file, char __user *buff, return bsize; } static ssize_t debug_write_ctrl(struct file *file, const char __user *buff, size_t count, loff_t *ppos) { struct ipc_log_context *ilctxt; struct dentry *d = file->f_path.dentry; int bsize = 1; int srcu_idx; int r; char local_buf[3]; r = debugfs_use_file_start(d, &srcu_idx); if (!r) { ilctxt = file->private_data; r = kref_get_unless_zero(&ilctxt->refcount) ? 0 : -EIO; } debugfs_use_file_finish(srcu_idx); if (r) return r; if (copy_from_user(local_buf, buff, bsize)) { count = -EFAULT; goto done; } if (*local_buf == '1') { ipc_log_string(ilctxt, "LOGGING DISABLED FOR THIS CLIENT!!\n"); ilctxt->disabled = true; } else if (*local_buf == '0') { ilctxt->disabled = false; ipc_log_string(ilctxt, "LOGGING ENABLED FOR THIS CLIENT!!\n"); } done: ipc_log_context_put(ilctxt); return count; } static ssize_t debug_write_ctrl_all(struct file *file, const char __user *buff, size_t count, loff_t *ppos) { int bsize = 1; char local_buf[3]; if (copy_from_user(local_buf, buff, bsize)) return -EFAULT; if (*local_buf == '1') ipc_log_ctrl_all(true); else if (*local_buf == '0') ipc_log_ctrl_all(false); return count; } static ssize_t debug_read_ctrl(struct file *file, char __user *buff, size_t count, loff_t *ppos) { struct ipc_log_context *ilctxt; struct dentry *d = file->f_path.dentry; int bsize = 2; int srcu_idx; int r; r = debugfs_use_file_start(d, &srcu_idx); if (!r) { ilctxt = file->private_data; r = kref_get_unless_zero(&ilctxt->refcount) ? 0 : -EIO; } debugfs_use_file_finish(srcu_idx); if (r) return r; bsize = simple_read_from_buffer(buff, count, ppos, ilctxt->disabled?"1\n":"0\n", bsize); ipc_log_context_put(ilctxt); return bsize; } static ssize_t debug_read(struct file *file, char __user *buff, size_t count, loff_t *ppos) { Loading Loading @@ -141,6 +218,16 @@ static const struct file_operations debug_ops_cont = { .open = debug_open, }; static const struct file_operations debug_ops_ctrl = { .read = debug_read_ctrl, .write = debug_write_ctrl, .open = debug_open, }; static const struct file_operations debug_ops_ctrl_all = { .write = debug_write_ctrl_all, }; static void debug_create(const char *name, mode_t mode, struct dentry *dent, struct ipc_log_context *ilctxt, Loading Loading @@ -176,6 +263,9 @@ void check_and_create_debugfs(void) pr_err("%s: unable to create debugfs %ld\n", __func__, PTR_ERR(root_dent)); root_dent = NULL; } else { debug_create("ctrl_all", 0444, root_dent, NULL, &debug_ops_ctrl_all); } } mutex_unlock(&ipc_log_debugfs_init_lock); Loading @@ -195,6 +285,8 @@ void create_ctx_debugfs(struct ipc_log_context *ctxt, ctxt, &debug_ops); debug_create("log_cont", 0444, ctxt->dent, ctxt, &debug_ops_cont); debug_create("log_disable", 0444, ctxt->dent, ctxt, &debug_ops_ctrl); } } add_deserialization_func((void *)ctxt, Loading
kernel/trace/ipc_logging_private.h +2 −1 Original line number Diff line number Diff line /* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -121,6 +121,7 @@ struct ipc_log_context { struct completion read_avail; struct kref refcount; bool destroyed; bool disabled; }; struct dfunc_info { Loading