From patchwork Wed Nov 6 19:48:49 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ricardo Ribalda Delgado X-Patchwork-Id: 3148961 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id E6999BEEB2 for ; Wed, 6 Nov 2013 19:48:59 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id EFA4F20513 for ; Wed, 6 Nov 2013 19:48:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 16AAE204E2 for ; Wed, 6 Nov 2013 19:48:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754897Ab3KFTsz (ORCPT ); Wed, 6 Nov 2013 14:48:55 -0500 Received: from mail-lb0-f180.google.com ([209.85.217.180]:40973 "EHLO mail-lb0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753042Ab3KFTsz (ORCPT ); Wed, 6 Nov 2013 14:48:55 -0500 Received: by mail-lb0-f180.google.com with SMTP id y6so112886lbh.25 for ; Wed, 06 Nov 2013 11:48:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=kBtOuY51UGGOdy2j6o1LDeMpq6R+wBPAepCDT26QLHQ=; b=DI/+asY16kU+1z6sFFuTRgSW9VFYI5KDkeiV3loRKxeWBRRSl60cNTZXoMoeU1FSUr n7ABhZY0A8J+xc90rIBNsVmqhvtc+bPZ+J/Giqfk+i5oJrhDo5G0MT6gjKRm8bwqL8+1 RCh6XvdGKWcp2MjZJ+Myx2BHsc70B/4iksMo1QkRYBGGRRQwds0k73snIkCqLa1/EMVM nFyekOd5oYXbKzfNoFGH/A1KVnALy2EwYpaza4LmqKZ1EFDZdjOA1TLJoQxE5ibVysje e3K0Cc1E6G+Y9sb7JFQFUOzkFySyfWRQybFrt3NubhOsCzliUmaH1HffGGf3uQbgXIzK G6UQ== X-Received: by 10.112.168.170 with SMTP id zx10mr3903077lbb.0.1383767333844; Wed, 06 Nov 2013 11:48:53 -0800 (PST) Received: from neopili.qtec.com (0x4dd4aed9.adsl.cybercity.dk. [77.212.174.217]) by mx.google.com with ESMTPSA id qj3sm286051lbb.6.2013.11.06.11.48.52 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 06 Nov 2013 11:48:52 -0800 (PST) From: Ricardo Ribalda Delgado To: Pawel Osciak , Marek Szyprowski , Kyungmin Park , Mauro Carvalho Chehab , linux-media@vger.kernel.org (open list:VIDEOBUF2 FRAMEWORK), sylvester.nawrocki@gmail.com Cc: Ricardo Ribalda Delgado Subject: [PATCH] videobuf2-dma-sg: Support io userptr operations on io memory Date: Wed, 6 Nov 2013 20:48:49 +0100 Message-Id: <1383767329-29985-1-git-send-email-ricardo.ribalda@gmail.com> X-Mailer: git-send-email 1.8.4.rc3 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, 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 Memory exported via remap_pfn_range cannot be remapped via get_user_pages. Other videobuf2 methods (like the dma-contig) supports io memory. This patch adds support for this kind of memory. Signed-off-by: Ricardo Ribalda Delgado --- drivers/media/v4l2-core/videobuf2-dma-sg.c | 35 ++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c index 2f86054..44ddfe1 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c @@ -40,6 +40,7 @@ struct vb2_dma_sg_buf { unsigned int num_pages; atomic_t refcount; struct vb2_vmarea_handler handler; + struct vm_area_struct *vma; }; static void vb2_dma_sg_put(void *buf_priv); @@ -155,6 +156,11 @@ static void vb2_dma_sg_put(void *buf_priv) } } +static inline int vma_is_io(struct vm_area_struct *vma) +{ + return !!(vma->vm_flags & (VM_IO | VM_PFNMAP)); +} + static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr, unsigned long size, int write) { @@ -180,7 +186,26 @@ static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr, if (!buf->pages) return NULL; - num_pages_from_user = get_user_pages(current, current->mm, + buf->vma = find_vma(current->mm, vaddr); + if (!buf->vma) { + dprintk(1, "no vma for address %lu\n", vaddr); + return NULL; + } + + if (vma_is_io(buf->vma)) { + for (num_pages_from_user = 0; + num_pages_from_user < buf->num_pages; + ++num_pages_from_user, vaddr += PAGE_SIZE) { + unsigned long pfn; + + if (follow_pfn(buf->vma, vaddr, &pfn)) { + dprintk(1, "no page for address %lu\n", vaddr); + break; + } + buf->pages[num_pages_from_user] = pfn_to_page(pfn); + } + } else + num_pages_from_user = get_user_pages(current, current->mm, vaddr & PAGE_MASK, buf->num_pages, write, @@ -201,8 +226,9 @@ userptr_fail_alloc_table_from_pages: userptr_fail_get_user_pages: dprintk(1, "get_user_pages requested/got: %d/%d]\n", num_pages_from_user, buf->num_pages); - while (--num_pages_from_user >= 0) - put_page(buf->pages[num_pages_from_user]); + if (!vma_is_io(buf->vma)) + while (--num_pages_from_user >= 0) + put_page(buf->pages[num_pages_from_user]); kfree(buf->pages); kfree(buf); return NULL; @@ -225,7 +251,8 @@ static void vb2_dma_sg_put_userptr(void *buf_priv) while (--i >= 0) { if (buf->write) set_page_dirty_lock(buf->pages[i]); - put_page(buf->pages[i]); + if (!vma_is_io(buf->vma)) + put_page(buf->pages[i]); } kfree(buf->pages); kfree(buf);