From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932091AbcBGTXK (ORCPT ); Sun, 7 Feb 2016 14:23:10 -0500 Received: from mout.web.de ([212.227.17.12]:51093 "EHLO mout.web.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750997AbcBGTXI convert rfc822-to-8bit (ORCPT ); Sun, 7 Feb 2016 14:23:08 -0500 Subject: Re: [PATCH] media: dvb_ringbuffer: Add memory barriers To: Mauro Carvalho Chehab References: <1451248920-4935-1-git-send-email-smoch@web.de> Cc: Soeren Moch , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org From: Soeren Moch X-Enigmail-Draft-Status: N1110 Message-ID: <56B7997C.1070503@web.de> Date: Sun, 7 Feb 2016 20:22:36 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.5.1 MIME-Version: 1.0 In-Reply-To: <1451248920-4935-1-git-send-email-smoch@web.de> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8BIT X-Provags-ID: V03:K0:+MJzMawgTmGUQ6+0Pe5QOVm5pMetCl2fGOpRtjpqwn+Hdqln2zH F2Kv21PDa3uui8L3/urkLfeSd6QiTFP1tqYxC/NNKX3MMaV7SkBpA5ad+BDU/l1f96gvQmR /+bQyYZdUKzQ+BiaY3l/GUaibLBAmxwp14/nc2IP/iRyHsZeZclYBnmP0hN5zYlr0cw/zbe b89g2I9IqA2A8QRtGM8QA== X-UI-Out-Filterresults: notjunk:1;V01:K0:7wpQr9IZBeo=:bETdIpixrI6iyfeqNKXFEr BQKGV4O8u8dN8al0Vyanf20zAq5I3J1CqH47pYzffwpx7F6eVQgJxP6sg9beBx5ZGL+N7bODQ ehnpTkFXY4+kD+LQLKbzq5WWFfgeW0zMyw/8uK+gG00BPPBmQ7sGmJUgU1LwweHAaonbj9IwU 7VTbfGEi781KHUN/cB9CK1s1X/GbQcA12St0qL2mwdQAVZsrSfOvkl6+jjfhXBZxuU7yZn7BU tSLI7/0GIVaT9gAySt6iShr5SaRLBEc6/1sbv7E5H8CymJxCo8C5vU8cW3pvARPpqX9VMraa+ yOvBssqEmXvzJV66dDVI6btPj3Q1VHEAXR7f2YxWgj6InZYYL7GDYhhA4XG8+Us7uGPsyJyv/ FSxi8rbNF9EtW4gbWr+iZ2VN70Isf4EtVarRyxHYOqcYdC/E7HPzeyxe/JIKG7vmNhbcEF6r2 fnN6yHIju/yNghIPfHHRuE7NTTNGUFihbfQ6I6TWNIw6If3ZwvflFvqp5MxUN9NAB8g5bd4KI Sqe6+eMwMg4kFqY2f7DGoFq8DbFY7mRElOY3Ubh4ZqRYCrmDt4/7EmoR5L9ACPJicAwO7WKoC X4lMciblrUC4aNQP75VqSpKJ1TPVyereMtGX+KcsDMzeUWEYrGoaBQ64USXZSFzGlE+xtK8B8 ixOce4H0NycEg5jmInCYYdjuDetEHQxnjidy/azbIdOOS6KlyJq9hw9UL3WS9YKiHjjhFTW26 ErDCwfyUuizJNDqVGanCqgM1xYzZNy27DkQho/6VH+e8UWBJb87LtHn5/5KmveL7pDqbIDusN t7a7zs9SDQg1DZ8LMFXkKUsCskqSA== Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 27.12.2015 21:41, Soeren Moch wrote: > Implement memory barriers according to Documentation/circular-buffers.txt: > - use smp_store_release() to update ringbuffer read/write pointers > - use smp_load_acquire() to load write pointer on reader side > - use ACCESS_ONCE() to load read pointer on writer side > > This fixes data stream corruptions observed e.g. on an ARM Cortex-A9 > quad core system with different types (PCI, USB) of DVB tuners. > > Signed-off-by: Soeren Moch > Cc: stable@vger.kernel.org # 3.14+ Mauro, any news or comments on this? Since this is a real fix for broken behaviour, can you pick this up, please? Regards, Soeren > --- > Cc: Mauro Carvalho Chehab > Cc: linux-media@vger.kernel.org > Cc: linux-kernel@vger.kernel.org > > Since smp_store_release() and smp_load_acquire() were introduced in linux-3.14, > a 3.14+ stable tag was added. Is it desired to apply a similar patch to older > stable kernels? > --- > drivers/media/dvb-core/dvb_ringbuffer.c | 27 ++++++++++++++------------- > 1 file changed, 14 insertions(+), 13 deletions(-) > > diff --git a/drivers/media/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb-core/dvb_ringbuffer.c > index 1100e98..58b5968 100644 > --- a/drivers/media/dvb-core/dvb_ringbuffer.c > +++ b/drivers/media/dvb-core/dvb_ringbuffer.c > @@ -55,7 +55,7 @@ void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len) > > int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf) > { > - return (rbuf->pread==rbuf->pwrite); > + return (rbuf->pread == smp_load_acquire(&rbuf->pwrite)); > } > > > @@ -64,7 +64,7 @@ ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf) > { > ssize_t free; > > - free = rbuf->pread - rbuf->pwrite; > + free = ACCESS_ONCE(rbuf->pread) - rbuf->pwrite; > if (free <= 0) > free += rbuf->size; > return free-1; > @@ -76,7 +76,7 @@ ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf) > { > ssize_t avail; > > - avail = rbuf->pwrite - rbuf->pread; > + avail = smp_load_acquire(&rbuf->pwrite) - rbuf->pread; > if (avail < 0) > avail += rbuf->size; > return avail; > @@ -86,14 +86,15 @@ ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf) > > void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf) > { > - rbuf->pread = rbuf->pwrite; > + smp_store_release(&rbuf->pread, smp_load_acquire(&rbuf->pwrite)); > rbuf->error = 0; > } > EXPORT_SYMBOL(dvb_ringbuffer_flush); > > void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf) > { > - rbuf->pread = rbuf->pwrite = 0; > + smp_store_release(&rbuf->pread, 0); > + smp_store_release(&rbuf->pwrite, 0); > rbuf->error = 0; > } > > @@ -119,12 +120,12 @@ ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, u8 __user *buf, si > return -EFAULT; > buf += split; > todo -= split; > - rbuf->pread = 0; > + smp_store_release(&rbuf->pread, 0); > } > if (copy_to_user(buf, rbuf->data+rbuf->pread, todo)) > return -EFAULT; > > - rbuf->pread = (rbuf->pread + todo) % rbuf->size; > + smp_store_release(&rbuf->pread, (rbuf->pread + todo) % rbuf->size); > > return len; > } > @@ -139,11 +140,11 @@ void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len) > memcpy(buf, rbuf->data+rbuf->pread, split); > buf += split; > todo -= split; > - rbuf->pread = 0; > + smp_store_release(&rbuf->pread, 0); > } > memcpy(buf, rbuf->data+rbuf->pread, todo); > > - rbuf->pread = (rbuf->pread + todo) % rbuf->size; > + smp_store_release(&rbuf->pread, (rbuf->pread + todo) % rbuf->size); > } > > > @@ -158,10 +159,10 @@ ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t > memcpy(rbuf->data+rbuf->pwrite, buf, split); > buf += split; > todo -= split; > - rbuf->pwrite = 0; > + smp_store_release(&rbuf->pwrite, 0); > } > memcpy(rbuf->data+rbuf->pwrite, buf, todo); > - rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size; > + smp_store_release(&rbuf->pwrite, (rbuf->pwrite + todo) % rbuf->size); > > return len; > } > @@ -181,12 +182,12 @@ ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf, > return len - todo; > buf += split; > todo -= split; > - rbuf->pwrite = 0; > + smp_store_release(&rbuf->pwrite, 0); > } > status = copy_from_user(rbuf->data+rbuf->pwrite, buf, todo); > if (status) > return len - todo; > - rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size; > + smp_store_release(&rbuf->pwrite, (rbuf->pwrite + todo) % rbuf->size); > > return len; > }