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

Commit 90e406f9 authored by Changbin Du's avatar Changbin Du Committed by Steven Rostedt (VMware)
Browse files

tracing: Allocate mask_str buffer dynamically

The default NR_CPUS can be very large, but actual possible nr_cpu_ids
usually is very small. For my x86 distribution, the NR_CPUS is 8192 and
nr_cpu_ids is 4. About 2 pages are wasted.

Most machines don't have so many CPUs, so define a array with NR_CPUS
just wastes memory. So let's allocate the buffer dynamically when need.

With this change, the mutext tracing_cpumask_update_lock also can be
removed now, which was used to protect mask_str.

Link: http://lkml.kernel.org/r/1512013183-19107-1-git-send-email-changbin.du@intel.com



Fixes: 36dfe925 ("ftrace: make use of tracing_cpumask")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarChangbin Du <changbin.du@intel.com>
Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
parent 250d0c77
Loading
Loading
Loading
Loading
+9 −20
Original line number Original line Diff line number Diff line
@@ -4178,37 +4178,30 @@ static const struct file_operations show_traces_fops = {
	.llseek		= seq_lseek,
	.llseek		= seq_lseek,
};
};


/*
 * The tracer itself will not take this lock, but still we want
 * to provide a consistent cpumask to user-space:
 */
static DEFINE_MUTEX(tracing_cpumask_update_lock);

/*
 * Temporary storage for the character representation of the
 * CPU bitmask (and one more byte for the newline):
 */
static char mask_str[NR_CPUS + 1];

static ssize_t
static ssize_t
tracing_cpumask_read(struct file *filp, char __user *ubuf,
tracing_cpumask_read(struct file *filp, char __user *ubuf,
		     size_t count, loff_t *ppos)
		     size_t count, loff_t *ppos)
{
{
	struct trace_array *tr = file_inode(filp)->i_private;
	struct trace_array *tr = file_inode(filp)->i_private;
	char *mask_str;
	int len;
	int len;


	mutex_lock(&tracing_cpumask_update_lock);
	len = snprintf(NULL, 0, "%*pb\n",
		       cpumask_pr_args(tr->tracing_cpumask)) + 1;
	mask_str = kmalloc(len, GFP_KERNEL);
	if (!mask_str)
		return -ENOMEM;


	len = snprintf(mask_str, count, "%*pb\n",
	len = snprintf(mask_str, len, "%*pb\n",
		       cpumask_pr_args(tr->tracing_cpumask));
		       cpumask_pr_args(tr->tracing_cpumask));
	if (len >= count) {
	if (len >= count) {
		count = -EINVAL;
		count = -EINVAL;
		goto out_err;
		goto out_err;
	}
	}
	count = simple_read_from_buffer(ubuf, count, ppos, mask_str, NR_CPUS+1);
	count = simple_read_from_buffer(ubuf, count, ppos, mask_str, len);


out_err:
out_err:
	mutex_unlock(&tracing_cpumask_update_lock);
	kfree(mask_str);


	return count;
	return count;
}
}
@@ -4228,8 +4221,6 @@ tracing_cpumask_write(struct file *filp, const char __user *ubuf,
	if (err)
	if (err)
		goto err_unlock;
		goto err_unlock;


	mutex_lock(&tracing_cpumask_update_lock);

	local_irq_disable();
	local_irq_disable();
	arch_spin_lock(&tr->max_lock);
	arch_spin_lock(&tr->max_lock);
	for_each_tracing_cpu(cpu) {
	for_each_tracing_cpu(cpu) {
@@ -4252,8 +4243,6 @@ tracing_cpumask_write(struct file *filp, const char __user *ubuf,
	local_irq_enable();
	local_irq_enable();


	cpumask_copy(tr->tracing_cpumask, tracing_cpumask_new);
	cpumask_copy(tr->tracing_cpumask, tracing_cpumask_new);

	mutex_unlock(&tracing_cpumask_update_lock);
	free_cpumask_var(tracing_cpumask_new);
	free_cpumask_var(tracing_cpumask_new);


	return count;
	return count;