Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 724baf5d authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "soc: qcom: ipc_logging: Add enable/disable feature for IPC log"

parents 185da679 f76b236c
Loading
Loading
Loading
Loading
+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
@@ -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
 *
+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
@@ -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)
@@ -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);
@@ -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
 *
+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
@@ -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)
{
@@ -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,
@@ -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);
@@ -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,
+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
@@ -121,6 +121,7 @@ struct ipc_log_context {
	struct completion read_avail;
	struct kref refcount;
	bool destroyed;
	bool disabled;
};

struct dfunc_info {