From patchwork Thu Nov 21 01:05:06 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Walls X-Patchwork-Id: 3216221 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 5DB819F26C for ; Thu, 21 Nov 2013 01:03:41 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6F64720783 for ; Thu, 21 Nov 2013 01:03:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 098D62074B for ; Thu, 21 Nov 2013 01:03:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754161Ab3KUBDh (ORCPT ); Wed, 20 Nov 2013 20:03:37 -0500 Received: from proofpoint-cluster.metrocast.net ([65.175.128.136]:43945 "EHLO proofpoint-cluster.metrocast.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753481Ab3KUBDg (ORCPT ); Wed, 20 Nov 2013 20:03:36 -0500 Received: from [192.168.1.2] (d-24-153-52-48.cpe.metrocast.net [24.153.52.48]) (authenticated bits=0) by pear.metrocast.net (8.13.8/8.13.8) with ESMTP id rAL13SlP020006; Thu, 21 Nov 2013 01:03:28 GMT Message-ID: <1384995906.1917.12.camel@palomino.walls.org> Subject: [PATCH RFC] videobuf2: Improve file I/O emulation to handle buffers in any order From: Andy Walls To: linux-media@vger.kernel.org Cc: Hans Verkuil , Marek Szyprowski , Kyungmin Park , PawelOsciak Date: Wed, 20 Nov 2013 20:05:06 -0500 X-Mailer: Evolution 3.4.4 (3.4.4-2.fc17) Mime-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:5.10.8794, 1.0.14, 0.0.0000 definitions=2013-11-20_08:2013-11-20, 2013-11-20, 1970-01-01 signatures=0 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 spamscore=0 ipscore=0 suspectscore=1 phishscore=0 bulkscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=6.0.2-1305240000 definitions=main-1311200209 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP (This patch is RFC, because it was compiled and tested against kernel v3.5) videobuf2 file I/O emulation assumed that buffers dequeued from the driver would return in the order they were enqueued in the driver. Improve the file I/O emulator's book-keeping to remove this assumption. Also remove the, AFAICT, assumption that only read() calls would need to dequeue a buffer from the driver. Also set the buf->size properly, if a write() dequeues a buffer. Signed-off-by: Andy Walls Cc: Kyungmin Park Cc: PawelOsciak Cc: Marek Szyprowski --- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c index 9d4e9ed..f330aa4 100644 --- a/drivers/media/video/videobuf2-core.c +++ b/drivers/media/video/videobuf2-core.c @@ -1796,6 +1796,7 @@ struct vb2_fileio_data { unsigned int dq_count; unsigned int flags; }; +#define FILEIO_INDEX_NOT_SET ((unsigned int) INT_MAX) /** * __vb2_init_fileio() - initialize file io emulator @@ -1889,6 +1890,7 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read) goto err_reqbufs; fileio->bufs[i].queued = 1; } + fileio->index = FILEIO_INDEX_NOT_SET; /* * Start streaming. @@ -1975,15 +1977,11 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ */ q->fileio = NULL; - index = fileio->index; - buf = &fileio->bufs[index]; - /* * Check if we need to dequeue the buffer. */ - if (buf->queued) { - struct vb2_buffer *vb; - + index = fileio->index; + if (index == FILEIO_INDEX_NOT_SET) { /* * Call vb2_dqbuf to get buffer back. */ @@ -1997,12 +1995,19 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ goto end; fileio->dq_count += 1; + fileio->index = fileio->b.index; + index = fileio->index; + buf = &fileio->bufs[index]; + /* * Get number of bytes filled by the driver */ - vb = q->bufs[index]; - buf->size = vb2_get_plane_payload(vb, 0); + buf->pos = 0; buf->queued = 0; + buf->size = read ? vb2_get_plane_payload(q->bufs[index], 0) + : vb2_plane_size(q->bufs[index], 0); + } else { + buf = &fileio->bufs[index]; } /* @@ -2070,13 +2075,28 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ */ buf->pos = 0; buf->queued = 1; - buf->size = q->bufs[0]->v4l2_planes[0].length; + buf->size = vb2_plane_size(q->bufs[index], 0); fileio->q_count += 1; /* - * Switch to the next buffer + * Decide on the next buffer */ - fileio->index = (index + 1) % q->num_buffers; + if (read || (q->num_buffers == 1)) { + /* Use the next buffer the driver provides back */ + fileio->index = FILEIO_INDEX_NOT_SET; + } else { + /* Prefer a buffer that is not quequed in the driver */ + int initial_index = fileio->index; + fileio->index = FILEIO_INDEX_NOT_SET; + do { + if (++index == q->num_buffers) + index = 0; + if (!fileio->bufs[index].queued) { + fileio->index = index; + break; + } + } while (index != initial_index); + } /* * Start streaming if required.