mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	ring-buffer: Do not die if rb_iter_peek() fails more than thrice
As the iterator will be reading a live buffer, and if the event being read is on a page that a writer crosses, it will fail and try again, the condition in rb_iter_peek() that only allows a retry to happen three times is no longer valid. Allow rb_iter_peek() to retry more than three times without killing the ring buffer, but only if rb_iter_head_event() had failed at least once. Link: http://lkml.kernel.org/r/20200317213416.452888193@goodmis.org Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
This commit is contained in:
		
							parent
							
								
									785888c544
								
							
						
					
					
						commit
						ff84c50cfb
					
				
					 1 changed files with 10 additions and 3 deletions
				
			
		| 
						 | 
					@ -4012,6 +4012,7 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
 | 
				
			||||||
	struct ring_buffer_per_cpu *cpu_buffer;
 | 
						struct ring_buffer_per_cpu *cpu_buffer;
 | 
				
			||||||
	struct ring_buffer_event *event;
 | 
						struct ring_buffer_event *event;
 | 
				
			||||||
	int nr_loops = 0;
 | 
						int nr_loops = 0;
 | 
				
			||||||
 | 
						bool failed = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ts)
 | 
						if (ts)
 | 
				
			||||||
		*ts = 0;
 | 
							*ts = 0;
 | 
				
			||||||
| 
						 | 
					@ -4038,10 +4039,14 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
 | 
				
			||||||
	 * to a data event, we should never loop more than three times.
 | 
						 * to a data event, we should never loop more than three times.
 | 
				
			||||||
	 * Once for going to next page, once on time extend, and
 | 
						 * Once for going to next page, once on time extend, and
 | 
				
			||||||
	 * finally once to get the event.
 | 
						 * finally once to get the event.
 | 
				
			||||||
	 * (We never hit the following condition more than thrice).
 | 
						 * We should never hit the following condition more than thrice,
 | 
				
			||||||
 | 
						 * unless the buffer is very small, and there's a writer
 | 
				
			||||||
 | 
						 * that is causing the reader to fail getting an event.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (RB_WARN_ON(cpu_buffer, ++nr_loops > 3))
 | 
						if (++nr_loops > 3) {
 | 
				
			||||||
 | 
							RB_WARN_ON(cpu_buffer, !failed);
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (rb_per_cpu_empty(cpu_buffer))
 | 
						if (rb_per_cpu_empty(cpu_buffer))
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
| 
						 | 
					@ -4052,8 +4057,10 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	event = rb_iter_head_event(iter);
 | 
						event = rb_iter_head_event(iter);
 | 
				
			||||||
	if (!event)
 | 
						if (!event) {
 | 
				
			||||||
 | 
							failed = true;
 | 
				
			||||||
		goto again;
 | 
							goto again;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (event->type_len) {
 | 
						switch (event->type_len) {
 | 
				
			||||||
	case RINGBUF_TYPE_PADDING:
 | 
						case RINGBUF_TYPE_PADDING:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue