Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933359AbbFWQE1 (ORCPT ); Tue, 23 Jun 2015 12:04:27 -0400 Received: from mail-la0-f42.google.com ([209.85.215.42]:32800 "EHLO mail-la0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754842AbbFWQEG (ORCPT ); Tue, 23 Jun 2015 12:04:06 -0400 From: Dmitry Kalinkin To: linux-kernel@vger.kernel.org, devel@driverdev.osuosl.org Cc: Martyn Welch , Manohar Vanga , Greg Kroah-Hartman , Dmitry Kalinkin Subject: [PATCHv2 5/9] staging: vme_user: allow large read()/write() Date: Tue, 23 Jun 2015 19:03:35 +0300 Message-Id: <1435075419-28211-6-git-send-email-dmitry.kalinkin@gmail.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1435075419-28211-1-git-send-email-dmitry.kalinkin@gmail.com> References: <20150623135124.GP28762@mwanda> <1435075419-28211-1-git-send-email-dmitry.kalinkin@gmail.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3772 Lines: 116 This changes large master transfers to do shorter read/write rather than return -EINVAL. User space will now be able to optimistically request a large transfer and get at least some data. This also removes comments suggesting on how to implement large transfers. Current vme_master_* read and write implementations use CPU copies that don't produce burst PCI accesses and subsequently no block transfer on VME bus. In the end overall performance is quiet low and it can't be fixed by doing direct copy to user space. Much easier solution would be to just reuse kernel buffer. Signed-off-by: Dmitry Kalinkin --- drivers/staging/vme/devices/vme_user.c | 67 ++++++++++++---------------------- 1 file changed, 24 insertions(+), 43 deletions(-) diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index 3467cde..101f7b9 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -132,63 +132,44 @@ static ssize_t resource_to_user(int minor, char __user *buf, size_t count, ssize_t retval; ssize_t copied = 0; - if (count <= image[minor].size_buf) { - /* We copy to kernel buffer */ - copied = vme_master_read(image[minor].resource, - image[minor].kern_buf, count, *ppos); - if (copied < 0) - return (int)copied; - - retval = __copy_to_user(buf, image[minor].kern_buf, - (unsigned long)copied); - if (retval != 0) { - copied = (copied - retval); - pr_info("User copy failed\n"); - return -EINVAL; - } + if (count > image[minor].size_buf) + count = image[minor].size_buf; - } else { - /* XXX Need to write this */ - pr_info("Currently don't support large transfers\n"); - /* Map in pages from userspace */ + /* We copy to kernel buffer */ + copied = vme_master_read(image[minor].resource, image[minor].kern_buf, + count, *ppos); + if (copied < 0) + return (int)copied; - /* Call vme_master_read to do the transfer */ + retval = __copy_to_user(buf, image[minor].kern_buf, + (unsigned long)copied); + if (retval != 0) { + copied = (copied - retval); + pr_info("User copy failed\n"); return -EINVAL; } return copied; } -/* - * We are going to alloc a page during init per window for small transfers. - * Small transfers will go user space -> buffer -> VME. Larger (more than a - * page) transfers will lock the user space buffer into memory and then - * transfer the data directly from the user space buffers out to VME. - */ static ssize_t resource_from_user(unsigned int minor, const char __user *buf, size_t count, loff_t *ppos) { ssize_t retval; ssize_t copied = 0; - if (count <= image[minor].size_buf) { - retval = __copy_from_user(image[minor].kern_buf, buf, - (unsigned long)count); - if (retval != 0) - copied = (copied - retval); - else - copied = count; - - copied = vme_master_write(image[minor].resource, - image[minor].kern_buf, copied, *ppos); - } else { - /* XXX Need to write this */ - pr_info("Currently don't support large transfers\n"); - /* Map in pages from userspace */ - - /* Call vme_master_write to do the transfer */ - return -EINVAL; - } + if (count > image[minor].size_buf) + count = image[minor].size_buf; + + retval = __copy_from_user(image[minor].kern_buf, buf, + (unsigned long)count); + if (retval != 0) + copied = (copied - retval); + else + copied = count; + + copied = vme_master_write(image[minor].resource, image[minor].kern_buf, + copied, *ppos); return copied; } -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/