diff options
| -rw-r--r-- | kernel/trace/ring_buffer.c | 33 | 
1 files changed, 27 insertions, 6 deletions
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 65fe2a4f982..d1c85c5f5f5 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -1679,11 +1679,22 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size,  			if (!cpu_buffer->nr_pages_to_update)  				continue; -			if (cpu_online(cpu)) +			/* The update must run on the CPU that is being updated. */ +			preempt_disable(); +			if (cpu == smp_processor_id() || !cpu_online(cpu)) { +				rb_update_pages(cpu_buffer); +				cpu_buffer->nr_pages_to_update = 0; +			} else { +				/* +				 * Can not disable preemption for schedule_work_on() +				 * on PREEMPT_RT. +				 */ +				preempt_enable();  				schedule_work_on(cpu,  						&cpu_buffer->update_pages_work); -			else -				rb_update_pages(cpu_buffer); +				preempt_disable(); +			} +			preempt_enable();  		}  		/* wait for all the updates to complete */ @@ -1721,12 +1732,22 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size,  		get_online_cpus(); -		if (cpu_online(cpu_id)) { +		preempt_disable(); +		/* The update must run on the CPU that is being updated. */ +		if (cpu_id == smp_processor_id() || !cpu_online(cpu_id)) +			rb_update_pages(cpu_buffer); +		else { +			/* +			 * Can not disable preemption for schedule_work_on() +			 * on PREEMPT_RT. +			 */ +			preempt_enable();  			schedule_work_on(cpu_id,  					 &cpu_buffer->update_pages_work);  			wait_for_completion(&cpu_buffer->update_done); -		} else -			rb_update_pages(cpu_buffer); +			preempt_disable(); +		} +		preempt_enable();  		cpu_buffer->nr_pages_to_update = 0;  		put_online_cpus();  |