From patchwork Fri Mar 2 19:34:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauro Carvalho Chehab X-Patchwork-Id: 10255595 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id E8B2A602B5 for ; Fri, 2 Mar 2018 19:35:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D8A9228384 for ; Fri, 2 Mar 2018 19:35:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CD3A728403; Fri, 2 Mar 2018 19:35:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 62DE128384 for ; Fri, 2 Mar 2018 19:35:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752904AbeCBTfR (ORCPT ); Fri, 2 Mar 2018 14:35:17 -0500 Received: from osg.samsung.com ([64.30.133.232]:32938 "EHLO osg.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752561AbeCBTfC (ORCPT ); Fri, 2 Mar 2018 14:35:02 -0500 Received: from localhost (localhost [127.0.0.1]) by osg.samsung.com (Postfix) with ESMTP id E2D7A33307; Fri, 2 Mar 2018 11:35:01 -0800 (PST) X-Virus-Scanned: Debian amavisd-new at dev.s-opensource.com X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References" Received: from osg.samsung.com ([127.0.0.1]) by localhost (localhost [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id tj6vLCwVQUQn; Fri, 2 Mar 2018 11:35:00 -0800 (PST) Received: from smtp.s-opensource.com (201.86.168.135.dynamic.adsl.gvt.net.br [201.86.168.135]) by osg.samsung.com (Postfix) with ESMTPSA id ED8E9332D3; Fri, 2 Mar 2018 11:34:54 -0800 (PST) Received: from mchehab by smtp.s-opensource.com with local (Exim 4.90_1) (envelope-from ) id 1erqSC-00089b-6B; Fri, 02 Mar 2018 16:34:52 -0300 From: Mauro Carvalho Chehab To: Linux Media Mailing List Cc: Mauro Carvalho Chehab , Mauro Carvalho Chehab Subject: [PATCH 1/8] media: em28xx: don't use coherent buffer for DMA transfers Date: Fri, 2 Mar 2018 16:34:42 -0300 Message-Id: X-Mailer: git-send-email 2.14.3 In-Reply-To: References: In-Reply-To: References: Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP While coherent memory is cheap on x86, it may cause performance impacts on other archs. As we don't have any good reason to use it, let's change the logic by allocating memory via kmalloc() and letting the USB core to do the DMA mapping and memory free for us. While here, also fixes an issue that it was not de-allocating memories if something gets wrong during memory block allocation. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-core.c | 51 +++++++++++++++------------------- drivers/media/usb/em28xx/em28xx.h | 2 +- 2 files changed, 24 insertions(+), 29 deletions(-) diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c index 1d0d8cc06103..932ab93a05a6 100644 --- a/drivers/media/usb/em28xx/em28xx-core.c +++ b/drivers/media/usb/em28xx/em28xx-core.c @@ -800,7 +800,6 @@ void em28xx_uninit_usb_xfer(struct em28xx *dev, enum em28xx_mode mode) { struct urb *urb; struct em28xx_usb_bufs *usb_bufs; - struct usb_device *udev = interface_to_usbdev(dev->intf); int i; em28xx_isocdbg("em28xx: called em28xx_uninit_usb_xfer in mode %d\n", @@ -819,23 +818,16 @@ void em28xx_uninit_usb_xfer(struct em28xx *dev, enum em28xx_mode mode) else usb_unlink_urb(urb); - if (usb_bufs->transfer_buffer[i]) { - usb_free_coherent(udev, - urb->transfer_buffer_length, - usb_bufs->transfer_buffer[i], - urb->transfer_dma); - } usb_free_urb(urb); usb_bufs->urb[i] = NULL; } - usb_bufs->transfer_buffer[i] = NULL; } kfree(usb_bufs->urb); - kfree(usb_bufs->transfer_buffer); + kfree(usb_bufs->buf); usb_bufs->urb = NULL; - usb_bufs->transfer_buffer = NULL; + usb_bufs->buf = NULL; usb_bufs->num_bufs = 0; em28xx_capture_start(dev, 0); @@ -912,14 +904,13 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, usb_bufs->num_bufs = num_bufs; - usb_bufs->urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL); + usb_bufs->urb = kcalloc(sizeof(void *), num_bufs, GFP_KERNEL); if (!usb_bufs->urb) return -ENOMEM; - usb_bufs->transfer_buffer = kzalloc(sizeof(void *)*num_bufs, - GFP_KERNEL); - if (!usb_bufs->transfer_buffer) { - kfree(usb_bufs->urb); + usb_bufs->buf = kcalloc(sizeof(void *), num_bufs, GFP_KERNEL); + if (!usb_bufs->buf) { + kfree(usb_bufs->buf); return -ENOMEM; } @@ -942,37 +933,41 @@ int em28xx_alloc_urbs(struct em28xx *dev, enum em28xx_mode mode, int xfer_bulk, } usb_bufs->urb[i] = urb; - usb_bufs->transfer_buffer[i] = usb_alloc_coherent(udev, - sb_size, GFP_KERNEL, &urb->transfer_dma); - if (!usb_bufs->transfer_buffer[i]) { + usb_bufs->buf[i] = kzalloc(sb_size, GFP_KERNEL); + if (!usb_bufs->buf[i]) { dev_err(&dev->intf->dev, "unable to allocate %i bytes for transfer buffer %i%s\n", sb_size, i, in_interrupt() ? " while in int" : ""); + em28xx_uninit_usb_xfer(dev, mode); + + for (i--; i >= 0; i--) + kfree(usb_bufs->buf[i]); + + kfree(usb_bufs->buf); + usb_bufs->buf = NULL; + return -ENOMEM; } - memset(usb_bufs->transfer_buffer[i], 0, sb_size); + + urb->transfer_flags = URB_FREE_BUFFER; if (xfer_bulk) { /* bulk */ pipe = usb_rcvbulkpipe(udev, mode == EM28XX_ANALOG_MODE ? dev->analog_ep_bulk : dev->dvb_ep_bulk); - usb_fill_bulk_urb(urb, udev, pipe, - usb_bufs->transfer_buffer[i], sb_size, - em28xx_irq_callback, dev); - urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; + usb_fill_bulk_urb(urb, udev, pipe, usb_bufs->buf[i], + sb_size, em28xx_irq_callback, dev); } else { /* isoc */ pipe = usb_rcvisocpipe(udev, mode == EM28XX_ANALOG_MODE ? dev->analog_ep_isoc : dev->dvb_ep_isoc); - usb_fill_int_urb(urb, udev, pipe, - usb_bufs->transfer_buffer[i], sb_size, - em28xx_irq_callback, dev, 1); - urb->transfer_flags = URB_ISO_ASAP | - URB_NO_TRANSFER_DMA_MAP; + usb_fill_int_urb(urb, udev, pipe, usb_bufs->buf[i], + sb_size, em28xx_irq_callback, dev, 1); + urb->transfer_flags |= URB_ISO_ASAP; k = 0; for (j = 0; j < usb_bufs->num_packets; j++) { urb->iso_frame_desc[j].offset = k; diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h index 88084f24f033..bd6eaf642662 100644 --- a/drivers/media/usb/em28xx/em28xx.h +++ b/drivers/media/usb/em28xx/em28xx.h @@ -239,7 +239,7 @@ struct em28xx_usb_bufs { struct urb **urb; /* transfer buffers for isoc/bulk transfer */ - char **transfer_buffer; + char **buf; }; struct em28xx_usb_ctl {