diff options
Diffstat (limited to 'kernel/trace/ring_buffer.c')
| -rw-r--r-- | kernel/trace/ring_buffer.c | 14 | 
1 files changed, 13 insertions, 1 deletions
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 14d8001140c8..de061dd47313 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -536,6 +536,7 @@ struct trace_buffer {  	unsigned			flags;  	int				cpus;  	atomic_t			record_disabled; +	atomic_t			resizing;  	cpumask_var_t			cpumask;  	struct lock_class_key		*reader_lock_key; @@ -2167,7 +2168,7 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size,  	/* prevent another thread from changing buffer sizes */  	mutex_lock(&buffer->mutex); - +	atomic_inc(&buffer->resizing);  	if (cpu_id == RING_BUFFER_ALL_CPUS) {  		/* @@ -2322,6 +2323,7 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size,  		atomic_dec(&buffer->record_disabled);  	} +	atomic_dec(&buffer->resizing);  	mutex_unlock(&buffer->mutex);  	return 0; @@ -2342,6 +2344,7 @@ int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size,  		}  	}   out_err_unlock: +	atomic_dec(&buffer->resizing);  	mutex_unlock(&buffer->mutex);  	return err;  } @@ -5541,6 +5544,15 @@ int ring_buffer_swap_cpu(struct trace_buffer *buffer_a,  	if (local_read(&cpu_buffer_b->committing))  		goto out_dec; +	/* +	 * When resize is in progress, we cannot swap it because +	 * it will mess the state of the cpu buffer. +	 */ +	if (atomic_read(&buffer_a->resizing)) +		goto out_dec; +	if (atomic_read(&buffer_b->resizing)) +		goto out_dec; +  	buffer_a->buffers[cpu] = cpu_buffer_b;  	buffer_b->buffers[cpu] = cpu_buffer_a;  |