diff options
Diffstat (limited to 'kernel/trace/ring_buffer.c')
| -rw-r--r-- | kernel/trace/ring_buffer.c | 37 | 
1 files changed, 23 insertions, 14 deletions
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index cc2f66f68dc..ff7027199a9 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -543,7 +543,7 @@ static void rb_wake_up_waiters(struct irq_work *work)   * as data is added to any of the @buffer's cpu buffers. Otherwise   * it will wait for data to be added to a specific cpu buffer.   */ -void ring_buffer_wait(struct ring_buffer *buffer, int cpu) +int ring_buffer_wait(struct ring_buffer *buffer, int cpu)  {  	struct ring_buffer_per_cpu *cpu_buffer;  	DEFINE_WAIT(wait); @@ -557,6 +557,8 @@ void ring_buffer_wait(struct ring_buffer *buffer, int cpu)  	if (cpu == RING_BUFFER_ALL_CPUS)  		work = &buffer->irq_work;  	else { +		if (!cpumask_test_cpu(cpu, buffer->cpumask)) +			return -ENODEV;  		cpu_buffer = buffer->buffers[cpu];  		work = &cpu_buffer->irq_work;  	} @@ -591,6 +593,7 @@ void ring_buffer_wait(struct ring_buffer *buffer, int cpu)  		schedule();  	finish_wait(&work->waiters, &wait); +	return 0;  }  /** @@ -613,10 +616,6 @@ int ring_buffer_poll_wait(struct ring_buffer *buffer, int cpu,  	struct ring_buffer_per_cpu *cpu_buffer;  	struct rb_irq_work *work; -	if ((cpu == RING_BUFFER_ALL_CPUS && !ring_buffer_empty(buffer)) || -	    (cpu != RING_BUFFER_ALL_CPUS && !ring_buffer_empty_cpu(buffer, cpu))) -		return POLLIN | POLLRDNORM; -  	if (cpu == RING_BUFFER_ALL_CPUS)  		work = &buffer->irq_work;  	else { @@ -1301,7 +1300,7 @@ struct ring_buffer *__ring_buffer_alloc(unsigned long size, unsigned flags,  	 * In that off case, we need to allocate for all possible cpus.  	 */  #ifdef CONFIG_HOTPLUG_CPU -	get_online_cpus(); +	cpu_notifier_register_begin();  	cpumask_copy(buffer->cpumask, cpu_online_mask);  #else  	cpumask_copy(buffer->cpumask, cpu_possible_mask); @@ -1324,10 +1323,10 @@ struct ring_buffer *__ring_buffer_alloc(unsigned long size, unsigned flags,  #ifdef CONFIG_HOTPLUG_CPU  	buffer->cpu_notify.notifier_call = rb_cpu_notify;  	buffer->cpu_notify.priority = 0; -	register_cpu_notifier(&buffer->cpu_notify); +	__register_cpu_notifier(&buffer->cpu_notify); +	cpu_notifier_register_done();  #endif -	put_online_cpus();  	mutex_init(&buffer->mutex);  	return buffer; @@ -1341,7 +1340,9 @@ struct ring_buffer *__ring_buffer_alloc(unsigned long size, unsigned flags,   fail_free_cpumask:  	free_cpumask_var(buffer->cpumask); -	put_online_cpus(); +#ifdef CONFIG_HOTPLUG_CPU +	cpu_notifier_register_done(); +#endif   fail_free_buffer:  	kfree(buffer); @@ -1358,16 +1359,17 @@ ring_buffer_free(struct ring_buffer *buffer)  {  	int cpu; -	get_online_cpus(); -  #ifdef CONFIG_HOTPLUG_CPU -	unregister_cpu_notifier(&buffer->cpu_notify); +	cpu_notifier_register_begin(); +	__unregister_cpu_notifier(&buffer->cpu_notify);  #endif  	for_each_buffer_cpu(buffer, cpu)  		rb_free_cpu_buffer(buffer->buffers[cpu]); -	put_online_cpus(); +#ifdef CONFIG_HOTPLUG_CPU +	cpu_notifier_register_done(); +#endif  	kfree(buffer->buffers);  	free_cpumask_var(buffer->cpumask); @@ -2397,6 +2399,13 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,  	write &= RB_WRITE_MASK;  	tail = write - length; +	/* +	 * If this is the first commit on the page, then it has the same +	 * timestamp as the page itself. +	 */ +	if (!tail) +		delta = 0; +  	/* See if we shot pass the end of this buffer page */  	if (unlikely(write > BUF_PAGE_SIZE))  		return rb_move_tail(cpu_buffer, length, tail, @@ -2558,7 +2567,7 @@ rb_reserve_next_event(struct ring_buffer *buffer,  		if (unlikely(test_time_stamp(delta))) {  			int local_clock_stable = 1;  #ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK -			local_clock_stable = sched_clock_stable; +			local_clock_stable = sched_clock_stable();  #endif  			WARN_ONCE(delta > (1ULL << 59),  				  KERN_WARNING "Delta way too big! %llu ts=%llu write stamp = %llu\n%s",  | 
