From patchwork Fri Feb 15 02:42:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Souptick Joarder X-Patchwork-Id: 10814109 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C2B5C1390 for ; Fri, 15 Feb 2019 02:38:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AECDF2F1DA for ; Fri, 15 Feb 2019 02:38:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A1F722F23E; Fri, 15 Feb 2019 02:38:33 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable 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 921FE2F1DA for ; Fri, 15 Feb 2019 02:38:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729446AbfBOCiZ (ORCPT ); Thu, 14 Feb 2019 21:38:25 -0500 Received: from mail-pf1-f195.google.com ([209.85.210.195]:41085 "EHLO mail-pf1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727023AbfBOCiX (ORCPT ); Thu, 14 Feb 2019 21:38:23 -0500 Received: by mail-pf1-f195.google.com with SMTP id b7so4085475pfi.8; Thu, 14 Feb 2019 18:38:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:mime-version:content-disposition :user-agent; bh=QS3mWzK39q3lW8WqJHFL6wuRYacMcGaOmOmP8soCdrs=; b=SvKO/8Qua3oK4cc04JxBOABmX9Lcs7OlPSis//wxrWJYxpUEEW0AwWfwFg7XPPkM9+ QADPLQsqmaC/p2ZufsCfS3Ge83uGWPUWE09/20bfO/mh4I0ezFUGT63uVWuoI3PWUc0b 7tkcSKGPRr9Z/G3N+gPRFwa09FtMiLR/oAZZ6Nfw3V/23rM4gjawS+m+B/f2q95GXwF4 DG85JqW8Awyst8kSFZ/+DNXV1GycMdMZkuYlI9X+lNzCnx33LVj20wM0JmDE1ZhBX9ye ahW788DDSK1er+310WveH4ER6u0KEwCb0tkfiCK/ym7po3kDquKXj0FnrzXnfMhf5v6s OI/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-disposition:user-agent; bh=QS3mWzK39q3lW8WqJHFL6wuRYacMcGaOmOmP8soCdrs=; b=TfaH8amXa3d6PRSIj5y37aagaSO800dCkgLt+IrYiXVyRjHc1iC5x6rxLgGOA9chx+ oct8FpIqJoqbVDME1eKQCH028XlxQ4BrekrfYS4nkkWfdRTHOUkvevV8f5wzm7b8fXFL j8aYtBo0djPvV7VSgIWrB38rn5L2cQq60YOPju+pHCT6+qp/n6lhem2CpZG6oLqxd3lT O/lPJIpJgZ44UnFTbPabDg7g+fBW22j1Rx25tY6dzyuuKOUcHLrN9bS9rAc1urjm8baV nd0kzQmgNLkobAmBTC11cB6TuxzOkBKr68QyYYOddpVUsdMKYNFqnHFzR0RP9R0tU80Z tZTQ== X-Gm-Message-State: AHQUAuborwtYbTUiX5ZilrJVM0BCG11XXrty6JTUwlujnj7IcqwMO7MP 1PT1fsu1aSazsxPLv8d0jeLsnbmF X-Google-Smtp-Source: AHgI3Iba0jcQFwegqG4NLDbZHaOWcAX7sXcmudyJYCZAfU2Rx3rH8jIxfvL/3yVO80UpTMBO9iuHZQ== X-Received: by 2002:a62:e704:: with SMTP id s4mr7409860pfh.94.1550198301951; Thu, 14 Feb 2019 18:38:21 -0800 (PST) Received: from jordon-HP-15-Notebook-PC ([49.207.53.51]) by smtp.gmail.com with ESMTPSA id d13sm5397358pfd.58.2019.02.14.18.38.20 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 14 Feb 2019 18:38:21 -0800 (PST) Date: Fri, 15 Feb 2019 08:12:41 +0530 From: Souptick Joarder To: akpm@linux-foundation.org, willy@infradead.org, mhocko@suse.com, kirill.shutemov@linux.intel.com, vbabka@suse.cz, riel@surriel.com, sfr@canb.auug.org.au, rppt@linux.vnet.ibm.com, peterz@infradead.org, linux@armlinux.org.uk, robin.murphy@arm.com, iamjoonsoo.kim@lge.com, treding@nvidia.com, keescook@chromium.org, m.szyprowski@samsung.com, stefanr@s5r6.in-berlin.de, hjc@rock-chips.com, heiko@sntech.de, airlied@linux.ie, oleksandr_andrushchenko@epam.com, joro@8bytes.org, pawel@osciak.com, kyungmin.park@samsung.com, mchehab@kernel.org, boris.ostrovsky@oracle.com, jgross@suse.com Cc: linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-arm-kernel@lists.infradead.org, linux1394-devel@lists.sourceforge.net, dri-devel@lists.freedesktop.org, linux-rockchip@lists.infradead.org, xen-devel@lists.xen.org, iommu@lists.linux-foundation.org, linux-media@vger.kernel.org Subject: [PATCH v4 1/9] mm: Introduce new vm_map_pages() and vm_map_pages_zero() API Message-ID: <20190215024241.GA26350@jordon-HP-15-Notebook-PC> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) 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 Previouly drivers have their own way of mapping range of kernel pages/memory into user vma and this was done by invoking vm_insert_page() within a loop. As this pattern is common across different drivers, it can be generalized by creating new functions and use it across the drivers. vm_map_pages() is the API which could be used to mapped kernel memory/pages in drivers which has considered vm_pgoff vm_map_pages_zero() is the API which could be used to map range of kernel memory/pages in drivers which has not considered vm_pgoff. vm_pgoff is passed default as 0 for those drivers. We _could_ then at a later "fix" these drivers which are using vm_map_pages_zero() to behave according to the normal vm_pgoff offsetting simply by removing the _zero suffix on the function name and if that causes regressions, it gives us an easy way to revert. Tested on Rockchip hardware and display is working, including talking to Lima via prime. Signed-off-by: Souptick Joarder Suggested-by: Russell King Suggested-by: Matthew Wilcox Reviewed-by: Mike Rapoport Tested-by: Heiko Stuebner --- include/linux/mm.h | 4 +++ mm/memory.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ mm/nommu.c | 14 ++++++++++ 3 files changed, 99 insertions(+) diff --git a/include/linux/mm.h b/include/linux/mm.h index 80bb640..e0aaa73 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2565,6 +2565,10 @@ unsigned long change_prot_numa(struct vm_area_struct *vma, int remap_pfn_range(struct vm_area_struct *, unsigned long addr, unsigned long pfn, unsigned long size, pgprot_t); int vm_insert_page(struct vm_area_struct *, unsigned long addr, struct page *); +int vm_map_pages(struct vm_area_struct *vma, struct page **pages, + unsigned long num); +int vm_map_pages_zero(struct vm_area_struct *vma, struct page **pages, + unsigned long num); vm_fault_t vmf_insert_pfn(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn); vm_fault_t vmf_insert_pfn_prot(struct vm_area_struct *vma, unsigned long addr, diff --git a/mm/memory.c b/mm/memory.c index e11ca9d..cad3e27 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1520,6 +1520,87 @@ int vm_insert_page(struct vm_area_struct *vma, unsigned long addr, } EXPORT_SYMBOL(vm_insert_page); +/* + * __vm_map_pages - maps range of kernel pages into user vma + * @vma: user vma to map to + * @pages: pointer to array of source kernel pages + * @num: number of pages in page array + * @offset: user's requested vm_pgoff + * + * This allows drivers to map range of kernel pages into a user vma. + * + * Return: 0 on success and error code otherwise. + */ +static int __vm_map_pages(struct vm_area_struct *vma, struct page **pages, + unsigned long num, unsigned long offset) +{ + unsigned long count = vma_pages(vma); + unsigned long uaddr = vma->vm_start; + int ret, i; + + /* Fail if the user requested offset is beyond the end of the object */ + if (offset > num) + return -ENXIO; + + /* Fail if the user requested size exceeds available object size */ + if (count > num - offset) + return -ENXIO; + + for (i = 0; i < count; i++) { + ret = vm_insert_page(vma, uaddr, pages[offset + i]); + if (ret < 0) + return ret; + uaddr += PAGE_SIZE; + } + + return 0; +} + +/** + * vm_map_pages - maps range of kernel pages starts with non zero offset + * @vma: user vma to map to + * @pages: pointer to array of source kernel pages + * @num: number of pages in page array + * + * Maps an object consisting of @num pages, catering for the user's + * requested vm_pgoff + * + * If we fail to insert any page into the vma, the function will return + * immediately leaving any previously inserted pages present. Callers + * from the mmap handler may immediately return the error as their caller + * will destroy the vma, removing any successfully inserted pages. Other + * callers should make their own arrangements for calling unmap_region(). + * + * Context: Process context. Called by mmap handlers. + * Return: 0 on success and error code otherwise. + */ +int vm_map_pages(struct vm_area_struct *vma, struct page **pages, + unsigned long num) +{ + return __vm_map_pages(vma, pages, num, vma->vm_pgoff); +} +EXPORT_SYMBOL(vm_map_pages); + +/** + * vm_map_pages_zero - map range of kernel pages starts with zero offset + * @vma: user vma to map to + * @pages: pointer to array of source kernel pages + * @num: number of pages in page array + * + * Similar to vm_map_pages(), except that it explicitly sets the offset + * to 0. This function is intended for the drivers that did not consider + * vm_pgoff. + * + * Context: Process context. Called by mmap handlers. + * Return: 0 on success and error code otherwise. + */ +int vm_map_pages_zero(struct vm_area_struct *vma, struct page **pages, + unsigned long num) +{ + return __vm_map_pages(vma, pages, num, 0); +} +EXPORT_SYMBOL(vm_map_pages_zero); + static vm_fault_t insert_pfn(struct vm_area_struct *vma, unsigned long addr, pfn_t pfn, pgprot_t prot, bool mkwrite) { diff --git a/mm/nommu.c b/mm/nommu.c index 749276b..b492fd1 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -473,6 +473,20 @@ int vm_insert_page(struct vm_area_struct *vma, unsigned long addr, } EXPORT_SYMBOL(vm_insert_page); +int vm_map_pages(struct vm_area_struct *vma, struct page **pages, + unsigned long num) +{ + return -EINVAL; +} +EXPORT_SYMBOL(vm_map_pages); + +int vm_map_pages_zero(struct vm_area_struct *vma, struct page **pages, + unsigned long num) +{ + return -EINVAL; +} +EXPORT_SYMBOL(vm_map_pages_zero); + /* * sys_brk() for the most part doesn't need the global kernel * lock, except when an application is doing something nasty From patchwork Fri Feb 15 02:47:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Souptick Joarder X-Patchwork-Id: 10814131 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E46051390 for ; Fri, 15 Feb 2019 02:43:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D18892F424 for ; Fri, 15 Feb 2019 02:43:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C480C2F45F; Fri, 15 Feb 2019 02:43:37 +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=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable 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 6A4E82F424 for ; Fri, 15 Feb 2019 02:43:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730872AbfBOCn0 (ORCPT ); Thu, 14 Feb 2019 21:43:26 -0500 Received: from mail-pg1-f196.google.com ([209.85.215.196]:40979 "EHLO mail-pg1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727207AbfBOCn0 (ORCPT ); Thu, 14 Feb 2019 21:43:26 -0500 Received: by mail-pg1-f196.google.com with SMTP id m1so4058353pgq.8; Thu, 14 Feb 2019 18:43:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:mime-version:content-disposition :user-agent; bh=36ygGGspzW8ypHYiojY4a19UR4qM+LFcK/AqwiiUnW8=; b=inn83Ew357K/ih8pfbluD0tHChrNBeWgVepxNoqLsPfTGsSVcd+Y2TvNyaOt6tsH+E l50EUJtl8WJgmunL6lScD8TdLHN40Al7FiBSXz8sPTFqYjA1D9Y538OponFb/96GzpPK c7Gs+mH17TuI2e4p6V0hcG4Do42SWlWbQApZfFxh68EAjYcMIWUuUYrw86EOJbzKhDiD F9cHRzu5G/0kaQnWGWV+JeffZh9moTJCTuaKNTxwhDR9Q9myrlC+HXeayONpB5vLZOo9 qKY92nsunQvlYAczN6fc4SxQaNmIXCkZXCJd5cqy9NompO6I5cSTc/B1zSJVmYRUGkNJ MolA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-disposition:user-agent; bh=36ygGGspzW8ypHYiojY4a19UR4qM+LFcK/AqwiiUnW8=; b=AX45/ShrLoPzr6ywwVA6Q22JrFDIHu38xk325zoRiQMQrZbeCxAjVmb+SLYFcwvofi qMUcgmuvxVFJdSyTJmWOCcSXgCNXosJp8XNE1InUTO83JQAHg36+MJvGE/H1e2mw1sT+ ob+fKrOmKFQLk3y2adnXHGdv9S+6jFT2rpMvoJBtv33MPNO28KI8u62YcLEhLcW0VFvZ 7rEJ5/saD1ZkzvK3BNSBYFQSxx0SybVzp3EOGI4NbBwy1xZovKkrLuGpL5clO3LgsXsh +tsXbQODc6artJdqA2jwXJpybteEM0pomlor7W3shoJOVFC8uRiIK4DTwSKwszYZCNT4 c1WA== X-Gm-Message-State: AHQUAuaOJBe6vD0ZER3OOk8Rr7i1SmYO/He3cQXUDsPa9xwarwPez6vZ H75+jbaSGQzgkah/HAlYdW8= X-Google-Smtp-Source: AHgI3IY4Y9LsUJAtQBeI8TTrDehjCuwGc2OKrBuTZ9TvWhq4etnfiX7gHURQ6oqPUVyDoepRwe1zcQ== X-Received: by 2002:a65:6249:: with SMTP id q9mr3013034pgv.229.1550198605218; Thu, 14 Feb 2019 18:43:25 -0800 (PST) Received: from jordon-HP-15-Notebook-PC ([49.207.53.51]) by smtp.gmail.com with ESMTPSA id g10sm4582058pgo.64.2019.02.14.18.43.23 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 14 Feb 2019 18:43:24 -0800 (PST) Date: Fri, 15 Feb 2019 08:17:45 +0530 From: Souptick Joarder To: akpm@linux-foundation.org, willy@infradead.org, mhocko@suse.com, pawel@osciak.com, m.szyprowski@samsung.com, kyungmin.park@samsung.com, mchehab@kernel.org, linux@armlinux.org.uk, robin.murphy@arm.com Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: [PATCH v4 7/9] videobuf2/videobuf2-dma-sg.c: Convert to use vm_map_pages() Message-ID: <20190215024745.GA26461@jordon-HP-15-Notebook-PC> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) 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 Convert to use vm_map_pages() to map range of kernel memory to user vma. vm_pgoff is treated in V4L2 API as a 'cookie' to select a buffer, not as a in-buffer offset by design and it always want to mmap a whole buffer from its beginning. Signed-off-by: Souptick Joarder Suggested-by: Marek Szyprowski Reviewed-by: Marek Szyprowski --- drivers/media/common/videobuf2/videobuf2-core.c | 7 +++++++ .../media/common/videobuf2/videobuf2-dma-contig.c | 6 ------ drivers/media/common/videobuf2/videobuf2-dma-sg.c | 22 ++++++---------------- 3 files changed, 13 insertions(+), 22 deletions(-) diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c index 70e8c33..ca4577a 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -2175,6 +2175,13 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma) goto unlock; } + /* + * vm_pgoff is treated in V4L2 API as a 'cookie' to select a buffer, + * not as a in-buffer offset. We always want to mmap a whole buffer + * from its beginning. + */ + vma->vm_pgoff = 0; + ret = call_memop(vb, mmap, vb->planes[plane].mem_priv, vma); unlock: diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c index aff0ab7..46245c5 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c @@ -186,12 +186,6 @@ static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma) return -EINVAL; } - /* - * dma_mmap_* uses vm_pgoff as in-buffer offset, but we want to - * map whole buffer - */ - vma->vm_pgoff = 0; - ret = dma_mmap_attrs(buf->dev, vma, buf->cookie, buf->dma_addr, buf->size, buf->attrs); diff --git a/drivers/media/common/videobuf2/videobuf2-dma-sg.c b/drivers/media/common/videobuf2/videobuf2-dma-sg.c index 015e737..d6b8eca 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-sg.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c @@ -328,28 +328,18 @@ static unsigned int vb2_dma_sg_num_users(void *buf_priv) static int vb2_dma_sg_mmap(void *buf_priv, struct vm_area_struct *vma) { struct vb2_dma_sg_buf *buf = buf_priv; - unsigned long uaddr = vma->vm_start; - unsigned long usize = vma->vm_end - vma->vm_start; - int i = 0; + int err; if (!buf) { printk(KERN_ERR "No memory to map\n"); return -EINVAL; } - do { - int ret; - - ret = vm_insert_page(vma, uaddr, buf->pages[i++]); - if (ret) { - printk(KERN_ERR "Remapping memory, error: %d\n", ret); - return ret; - } - - uaddr += PAGE_SIZE; - usize -= PAGE_SIZE; - } while (usize > 0); - + err = vm_map_pages(vma, buf->pages, buf->num_pages); + if (err) { + printk(KERN_ERR "Remapping memory, error: %d\n", err); + return err; + } /* * Use common vm_area operations to track buffer refcount.