Re: FAILED: patch "[PATCH] ring-buffer: Check if buffer exists before polling" failed to apply to 3.10-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jul 08, 2014 at 03:16:43PM -0400, Steven Rostedt wrote:
> On Mon, 07 Jul 2014 13:00:14 -0700
> <gregkh@xxxxxxxxxxxxxxxxxxx> wrote:
> 
> > 
> > The patch below does not apply to the 3.10-stable tree.
> > If someone wants it applied there, or to any other stable or longterm
> > tree, then please email the backport, including the original git commit
> > id to <stable@xxxxxxxxxxxxxxx>.
> > 
> > thanks,
> > 
> > greg k-h
> > 
> 
> Here's the fix for 3.10 :
> 
> -- Steve
>

It looks like this backport could be used for the 3.11 kernel as
well.  Thanks!

Cheers,
--
Luís

> 
> ------------------ original commit in Linus's tree ------------------
> 
> >From 8b8b36834d0fff67fc8668093f4312dd04dcf21d Mon Sep 17 00:00:00 2001
> From: "Steven Rostedt (Red Hat)" <rostedt@xxxxxxxxxxx>
> Date: Tue, 10 Jun 2014 09:46:00 -0400
> Subject: [PATCH] ring-buffer: Check if buffer exists before polling
> 
> The per_cpu buffers are created one per possible CPU. But these do
> not mean that those CPUs are online, nor do they even exist.
> 
> With the addition of the ring buffer polling, it assumes that the
> caller polls on an existing buffer. But this is not the case if
> the user reads trace_pipe from a CPU that does not exist, and this
> causes the kernel to crash.
> 
> Simple fix is to check the cpu against buffer bitmask against to see
> if the buffer was allocated or not and return -ENODEV if it is
> not.
> 
> More updates were done to pass the -ENODEV back up to userspace.
> 
> Link: http://lkml.kernel.org/r/5393DB61.6060707@xxxxxxxxxx
> 
> Reported-by: Sasha Levin <sasha.levin@xxxxxxxxxx>
> Cc: stable@xxxxxxxxxxxxxxx # 3.10+
> Signed-off-by: Steven Rostedt <rostedt@xxxxxxxxxxx>
> 
> ---
>  include/linux/ring_buffer.h |    2 +-
>  kernel/trace/ring_buffer.c  |    5 ++++-
>  kernel/trace/trace.c        |   25 ++++++++++++++++++-------
>  kernel/trace/trace.h        |    4 ++--
>  4 files changed, 25 insertions(+), 11 deletions(-)
> 
> Index: linux-trace.git/include/linux/ring_buffer.h
> ===================================================================
> --- linux-trace.git.orig/include/linux/ring_buffer.h	2014-07-08 15:08:37.214727623 -0400
> +++ linux-trace.git/include/linux/ring_buffer.h	2014-07-08 15:08:39.860703457 -0400
> @@ -97,7 +97,7 @@
>  	__ring_buffer_alloc((size), (flags), &__key);	\
>  })
>  
> -void ring_buffer_wait(struct ring_buffer *buffer, int cpu);
> +int ring_buffer_wait(struct ring_buffer *buffer, int cpu);
>  int ring_buffer_poll_wait(struct ring_buffer *buffer, int cpu,
>  			  struct file *filp, poll_table *poll_table);
>  
> Index: linux-trace.git/kernel/trace/ring_buffer.c
> ===================================================================
> --- linux-trace.git.orig/kernel/trace/ring_buffer.c	2014-07-08 15:08:37.217727595 -0400
> +++ linux-trace.git/kernel/trace/ring_buffer.c	2014-07-08 15:08:39.862703439 -0400
> @@ -543,7 +543,7 @@
>   * 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 @@
>  	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 @@
>  		schedule();
>  
>  	finish_wait(&work->waiters, &wait);
> +	return 0;
>  }
>  
>  /**
> Index: linux-trace.git/kernel/trace/trace.c
> ===================================================================
> --- linux-trace.git.orig/kernel/trace/trace.c	2014-07-08 15:08:37.221727559 -0400
> +++ linux-trace.git/kernel/trace/trace.c	2014-07-08 15:08:39.865703412 -0400
> @@ -1027,13 +1027,13 @@
>  }
>  #endif /* CONFIG_TRACER_MAX_TRACE */
>  
> -static void default_wait_pipe(struct trace_iterator *iter)
> +static int default_wait_pipe(struct trace_iterator *iter)
>  {
>  	/* Iterators are static, they should be filled or empty */
>  	if (trace_buffer_iter(iter, iter->cpu_file))
> -		return;
> +		return 0;
>  
> -	ring_buffer_wait(iter->trace_buffer->buffer, iter->cpu_file);
> +	return ring_buffer_wait(iter->trace_buffer->buffer, iter->cpu_file);
>  }
>  
>  #ifdef CONFIG_FTRACE_STARTUP_TEST
> @@ -4056,17 +4056,19 @@
>   *
>   *     Anyway, this is really very primitive wakeup.
>   */
> -void poll_wait_pipe(struct trace_iterator *iter)
> +int poll_wait_pipe(struct trace_iterator *iter)
>  {
>  	set_current_state(TASK_INTERRUPTIBLE);
>  	/* sleep for 100 msecs, and try again. */
>  	schedule_timeout(HZ / 10);
> +	return 0;
>  }
>  
>  /* Must be called with trace_types_lock mutex held. */
>  static int tracing_wait_pipe(struct file *filp)
>  {
>  	struct trace_iterator *iter = filp->private_data;
> +	int ret;
>  
>  	while (trace_empty(iter)) {
>  
> @@ -4076,10 +4078,13 @@
>  
>  		mutex_unlock(&iter->mutex);
>  
> -		iter->trace->wait_pipe(iter);
> +		ret = iter->trace->wait_pipe(iter);
>  
>  		mutex_lock(&iter->mutex);
>  
> +		if (ret)
> +			return ret;
> +
>  		if (signal_pending(current))
>  			return -EINTR;
>  
> @@ -5013,8 +5018,12 @@
>  				goto out_unlock;
>  			}
>  			mutex_unlock(&trace_types_lock);
> -			iter->trace->wait_pipe(iter);
> +			ret = iter->trace->wait_pipe(iter);
>  			mutex_lock(&trace_types_lock);
> +			if (ret) {
> +				size = ret;
> +				goto out_unlock;
> +			}
>  			if (signal_pending(current)) {
>  				size = -EINTR;
>  				goto out_unlock;
> @@ -5226,8 +5235,10 @@
>  			goto out;
>  		}
>  		mutex_unlock(&trace_types_lock);
> -		iter->trace->wait_pipe(iter);
> +		ret = iter->trace->wait_pipe(iter);
>  		mutex_lock(&trace_types_lock);
> +		if (ret)
> +			goto out;
>  		if (signal_pending(current)) {
>  			ret = -EINTR;
>  			goto out;
> Index: linux-trace.git/kernel/trace/trace.h
> ===================================================================
> --- linux-trace.git.orig/kernel/trace/trace.h	2014-07-08 15:08:37.223727540 -0400
> +++ linux-trace.git/kernel/trace/trace.h	2014-07-08 15:08:54.542569018 -0400
> @@ -342,7 +342,7 @@
>  	void			(*stop)(struct trace_array *tr);
>  	void			(*open)(struct trace_iterator *iter);
>  	void			(*pipe_open)(struct trace_iterator *iter);
> -	void			(*wait_pipe)(struct trace_iterator *iter);
> +	int			(*wait_pipe)(struct trace_iterator *iter);
>  	void			(*close)(struct trace_iterator *iter);
>  	void			(*pipe_close)(struct trace_iterator *iter);
>  	ssize_t			(*read)(struct trace_iterator *iter,
> @@ -557,7 +557,7 @@
>  
>  void tracing_iter_reset(struct trace_iterator *iter, int cpu);
>  
> -void poll_wait_pipe(struct trace_iterator *iter);
> +int poll_wait_pipe(struct trace_iterator *iter);
>  
>  void ftrace(struct trace_array *tr,
>  			    struct trace_array_cpu *data,
> --
> To unsubscribe from this list: send the line "unsubscribe stable" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]