diff options
Diffstat (limited to 'kernel/trace/ring_buffer.c')
| -rw-r--r-- | kernel/trace/ring_buffer.c | 55 | 
1 files changed, 31 insertions, 24 deletions
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index bd38c5cfd8a..b36d7374cee 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -123,8 +123,7 @@ void ring_buffer_normalize_time_stamp(int cpu, u64 *ts)  EXPORT_SYMBOL_GPL(ring_buffer_normalize_time_stamp);  #define RB_EVNT_HDR_SIZE (sizeof(struct ring_buffer_event)) -#define RB_ALIGNMENT_SHIFT	2 -#define RB_ALIGNMENT		(1 << RB_ALIGNMENT_SHIFT) +#define RB_ALIGNMENT		4U  #define RB_MAX_SMALL_DATA	28  enum { @@ -133,7 +132,7 @@ enum {  };  /* inline for ring buffer fast paths */ -static inline unsigned +static unsigned  rb_event_length(struct ring_buffer_event *event)  {  	unsigned length; @@ -151,7 +150,7 @@ rb_event_length(struct ring_buffer_event *event)  	case RINGBUF_TYPE_DATA:  		if (event->len) -			length = event->len << RB_ALIGNMENT_SHIFT; +			length = event->len * RB_ALIGNMENT;  		else  			length = event->array[0];  		return length + RB_EVNT_HDR_SIZE; @@ -179,7 +178,7 @@ unsigned ring_buffer_event_length(struct ring_buffer_event *event)  EXPORT_SYMBOL_GPL(ring_buffer_event_length);  /* inline for ring buffer fast paths */ -static inline void * +static void *  rb_event_data(struct ring_buffer_event *event)  {  	BUG_ON(event->type != RINGBUF_TYPE_DATA); @@ -229,10 +228,9 @@ static void rb_init_page(struct buffer_data_page *bpage)   * Also stolen from mm/slob.c. Thanks to Mathieu Desnoyers for pointing   * this issue out.   */ -static inline void free_buffer_page(struct buffer_page *bpage) +static void free_buffer_page(struct buffer_page *bpage)  { -	if (bpage->page) -		free_page((unsigned long)bpage->page); +	free_page((unsigned long)bpage->page);  	kfree(bpage);  } @@ -811,7 +809,7 @@ rb_event_index(struct ring_buffer_event *event)  	return (addr & ~PAGE_MASK) - (PAGE_SIZE - BUF_PAGE_SIZE);  } -static inline int +static int  rb_is_commit(struct ring_buffer_per_cpu *cpu_buffer,  	     struct ring_buffer_event *event)  { @@ -825,7 +823,7 @@ rb_is_commit(struct ring_buffer_per_cpu *cpu_buffer,  		rb_commit_index(cpu_buffer) == index;  } -static inline void +static void  rb_set_commit_event(struct ring_buffer_per_cpu *cpu_buffer,  		    struct ring_buffer_event *event)  { @@ -850,7 +848,7 @@ rb_set_commit_event(struct ring_buffer_per_cpu *cpu_buffer,  	local_set(&cpu_buffer->commit_page->page->commit, index);  } -static inline void +static void  rb_set_commit_to_write(struct ring_buffer_per_cpu *cpu_buffer)  {  	/* @@ -896,7 +894,7 @@ static void rb_reset_reader_page(struct ring_buffer_per_cpu *cpu_buffer)  	cpu_buffer->reader_page->read = 0;  } -static inline void rb_inc_iter(struct ring_buffer_iter *iter) +static void rb_inc_iter(struct ring_buffer_iter *iter)  {  	struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer; @@ -926,7 +924,7 @@ static inline void rb_inc_iter(struct ring_buffer_iter *iter)   * and with this, we can determine what to place into the   * data field.   */ -static inline void +static void  rb_update_event(struct ring_buffer_event *event,  			 unsigned type, unsigned length)  { @@ -938,15 +936,11 @@ rb_update_event(struct ring_buffer_event *event,  		break;  	case RINGBUF_TYPE_TIME_EXTEND: -		event->len = -			(RB_LEN_TIME_EXTEND + (RB_ALIGNMENT-1)) -			>> RB_ALIGNMENT_SHIFT; +		event->len = DIV_ROUND_UP(RB_LEN_TIME_EXTEND, RB_ALIGNMENT);  		break;  	case RINGBUF_TYPE_TIME_STAMP: -		event->len = -			(RB_LEN_TIME_STAMP + (RB_ALIGNMENT-1)) -			>> RB_ALIGNMENT_SHIFT; +		event->len = DIV_ROUND_UP(RB_LEN_TIME_STAMP, RB_ALIGNMENT);  		break;  	case RINGBUF_TYPE_DATA: @@ -955,16 +949,14 @@ rb_update_event(struct ring_buffer_event *event,  			event->len = 0;  			event->array[0] = length;  		} else -			event->len = -				(length + (RB_ALIGNMENT-1)) -				>> RB_ALIGNMENT_SHIFT; +			event->len = DIV_ROUND_UP(length, RB_ALIGNMENT);  		break;  	default:  		BUG();  	}  } -static inline unsigned rb_calculate_event_length(unsigned length) +static unsigned rb_calculate_event_length(unsigned length)  {  	struct ring_buffer_event event; /* Used only for sizeof array */ @@ -1438,7 +1430,7 @@ int ring_buffer_write(struct ring_buffer *buffer,  }  EXPORT_SYMBOL_GPL(ring_buffer_write); -static inline int rb_per_cpu_empty(struct ring_buffer_per_cpu *cpu_buffer) +static int rb_per_cpu_empty(struct ring_buffer_per_cpu *cpu_buffer)  {  	struct buffer_page *reader = cpu_buffer->reader_page;  	struct buffer_page *head = cpu_buffer->head_page; @@ -2277,9 +2269,24 @@ int ring_buffer_swap_cpu(struct ring_buffer *buffer_a,  	if (buffer_a->pages != buffer_b->pages)  		return -EINVAL; +	if (ring_buffer_flags != RB_BUFFERS_ON) +		return -EAGAIN; + +	if (atomic_read(&buffer_a->record_disabled)) +		return -EAGAIN; + +	if (atomic_read(&buffer_b->record_disabled)) +		return -EAGAIN; +  	cpu_buffer_a = buffer_a->buffers[cpu];  	cpu_buffer_b = buffer_b->buffers[cpu]; +	if (atomic_read(&cpu_buffer_a->record_disabled)) +		return -EAGAIN; + +	if (atomic_read(&cpu_buffer_b->record_disabled)) +		return -EAGAIN; +  	/*  	 * We can't do a synchronize_sched here because this  	 * function can be called in atomic context.  |