From patchwork Tue Dec 5 05:35:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Kasireddy, Vivek" X-Patchwork-Id: 13479376 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9CA2DC10DC3 for ; Tue, 5 Dec 2023 05:58:57 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 3875C6B0075; Tue, 5 Dec 2023 00:58:56 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 337186B0078; Tue, 5 Dec 2023 00:58:56 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 1D7B26B007D; Tue, 5 Dec 2023 00:58:56 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id EC20D6B0078 for ; Tue, 5 Dec 2023 00:58:55 -0500 (EST) Received: from smtpin29.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay05.hostedemail.com (Postfix) with ESMTP id C575D40197 for ; Tue, 5 Dec 2023 05:58:55 +0000 (UTC) X-FDA: 81531711030.29.F37AD65 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.12]) by imf21.hostedemail.com (Postfix) with ESMTP id C260A1C0016 for ; Tue, 5 Dec 2023 05:58:53 +0000 (UTC) Authentication-Results: imf21.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b=QBlfkewm; dmarc=pass (policy=none) header.from=intel.com; spf=pass (imf21.hostedemail.com: domain of vivek.kasireddy@intel.com designates 198.175.65.12 as permitted sender) smtp.mailfrom=vivek.kasireddy@intel.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1701755934; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=OFWxI1i+p4efvmikRdB46knSq10ZwkVaViiQ0SsvQMA=; b=NHjt8xV1nNZWVj+2yJGuK3THMn2jpEi+B3+Pzc9Gc6PmjPKnEaFngeI3rOBR365cEA+c5K eIKA2WGMqzUynJaR/JDqZZ1rR9QVDG+Fy3w1WsaQfc3ljdNXg2yxY3su8jQKSTX5j0RAzd VPbvP41D+/m2MrLRC2z9wAAcgqRxlSw= ARC-Authentication-Results: i=1; imf21.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b=QBlfkewm; dmarc=pass (policy=none) header.from=intel.com; spf=pass (imf21.hostedemail.com: domain of vivek.kasireddy@intel.com designates 198.175.65.12 as permitted sender) smtp.mailfrom=vivek.kasireddy@intel.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1701755934; a=rsa-sha256; cv=none; b=b0PsLqxm2TktTWc6ArUpBP7qXebGQhxPBC1rZ8/H+Qhzc1UyWzdeXBfIEaStCMXoAMHeER Ymmq3YDHfv38i1+vSwsOAnvc3UPNDT7dObvGsQnou/VGR13PYMEo60J74P369AQ2SnU+Ne BE04L7UmpyAbcl3n0NTQvOG23tJHcco= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1701755934; x=1733291934; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=U5Op4CjhDDAHfKtiDzpe6+9a1b7R8CllBxVTE/TesJE=; b=QBlfkewmSkH3F/PRtnMfqDPBP7Fy7qv2m5D4tveuWaeCIWGvJwrwRUMS gtlEyPnDj/VQgksRb6tmSQzhZxWDtfgYOLZBSch+CAVkt1yqN2Mt1RLPn kPc/r9cybOTn8bZREyutjJ8tH2oYkyYHRe4KfJZlit3+d37fDOQ58b7eR tyfCDw9SsIU5be0y1rMt8PRcDLVwcP4lEEAH9UZP60THTFNS8eoIFPl34 vQDbWtscjOYlrsdY6dPR8940r3DvLiUvZ8BRRRZHuONupdje5dcC4PCrV ELS5+3z951FM456YjMRArVmsP/0eUdAY58CFsfecHyD74Ngl7wVmpu63C Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10914"; a="906305" X-IronPort-AV: E=Sophos;i="6.04,251,1695711600"; d="scan'208";a="906305" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orvoesa104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Dec 2023 21:58:51 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10914"; a="888807724" X-IronPort-AV: E=Sophos;i="6.04,251,1695711600"; d="scan'208";a="888807724" Received: from vkasired-desk2.fm.intel.com ([10.105.128.132]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Dec 2023 21:58:50 -0800 From: Vivek Kasireddy To: dri-devel@lists.freedesktop.org, linux-mm@kvack.org Cc: Vivek Kasireddy , David Hildenbrand , Daniel Vetter , Mike Kravetz , Hugh Dickins , Peter Xu , Jason Gunthorpe , Gerd Hoffmann , Dongwon Kim , Junxiao Chang Subject: [PATCH v6 1/5] udmabuf: Use vmf_insert_pfn and VM_PFNMAP for handling mmap Date: Mon, 4 Dec 2023 21:35:05 -0800 Message-Id: <20231205053509.2342169-2-vivek.kasireddy@intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231205053509.2342169-1-vivek.kasireddy@intel.com> References: <20231205053509.2342169-1-vivek.kasireddy@intel.com> MIME-Version: 1.0 X-Rspam-User: X-Rspamd-Server: rspam12 X-Rspamd-Queue-Id: C260A1C0016 X-Stat-Signature: hnp549a9415kfjre8zc7f1bqn9xxbkoq X-HE-Tag: 1701755933-577855 X-HE-Meta: U2FsdGVkX18onwMPhtn7RrWQDQ0E9jJ1oeDEc/VGXGF+7oqSLHrtXbTJLHzRXAECD8gofHJSTwmih30RmqYfCIkFAUE45IqnLVkF2r3ol139C+S3eHPmDM37Jq1ieLhX/GaKEuzeVkZSg3avjmEP6dKMnoY2WUtFvdSKol4QwKkdnuidI7vRcYLr15VHQIKGsHXDI3D3fPgwymbxXlGAo7ZP+skwXedAVQNRemUXfIkmvy8X18UkV6DQI6z2IxNbRLWl+kmgWnQv+wjiFQ6npDQFhdi7BP9E32BTpHMHtzlBYA3VVVtyocJbvkd0fSWjbLZBDTprrdugoz+/Nk4km+1aYcY0AgFS2Cp+dR++nV1xoUb0JkZAmSMlpX2glUDJ5873zRA8DzZJzTAgkUt7NrPHVu5JXtu+ALwXvpIOJi+D9RxUDZcMGut/rqUEbyp0eQ74gA8ROdfwRVW42du8zNDZB2c8HA/REar7WJQYpNZfL8JZMmCfTNKkbmDj5zhwJRfpitKOzKoiIw17mjvuy1Co4TsE0oTny6MpHCu/C1OMPANUzXVJFGiZVop8lH4RzNi90rnt1PPGx4TfAa9Bj1wEx8yzWAgUh0VjJNX2B+1d/T8VAvuvQx9LWjTEwhu0lYlcOUQmZ0TWg/8CTen9nOi50/bs+dvQOGxzdH3nXPNG0G948qM3qe/atnD9bqSHAv1+2/rvrFN8NqaKGyMbBValrAyZwzeAwdRlsiA7lgG4CktpXVzAb2/PkegjB2bTNQYAAN7STNEjbDxweo/F/AEN65tzyeo4k9AQjDKu4wF2GkO/+61Kr4JGj5RZfYcaaYG5tUIYplgf0A8d/BLPITvujlXI6wnYPENiYUHFDJt9HS8P8ZNJ6ax/ibYdMKyELTtuQzQTlDNfDCE5I5rqHP2659xUdbB49XtJFKtDsPtS1Rruy5aw2N46lOtfXryRyIywihqtfRhUZ9OmFYq lQenZu+m y2jGqjAQe2mQMPcUbd43v9S7taTrahw3kLIZckyEYYuG5lsUTgWYo7IjaT5r1ZtV28bHr5QRMZkqhM2g9ewBZd1ennjXeIdhu2ewLISQQSVsdrH4ivAPWvG5KDQ8JLJsVxW87QlfdGZ7hwyPJ33J8ilBXTqO5KGZWOeLGz4+7SsLnENcGCFZwMP0e5mVs0Fw+JTSjeiGN8HcmByoUQF4YU8rF1Us7P6nLoz5GoigOokAJQl6XehzbpqCmHskHcQZ2+sjTNM4X/Mbnh8kvCrAQl3B0RQkgb4qK9h1tQB45L7HvDhs= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Add VM_PFNMAP to vm_flags in the mmap handler to ensure that the mappings would be managed without using struct page. And, in the vm_fault handler, use vmf_insert_pfn to share the page's pfn to userspace instead of directly sharing the page (via struct page *). Cc: David Hildenbrand Cc: Daniel Vetter Cc: Mike Kravetz Cc: Hugh Dickins Cc: Peter Xu Cc: Jason Gunthorpe Cc: Gerd Hoffmann Cc: Dongwon Kim Cc: Junxiao Chang Suggested-by: David Hildenbrand Acked-by: David Hildenbrand Signed-off-by: Vivek Kasireddy --- drivers/dma-buf/udmabuf.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index c40645999648..820c993c8659 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -35,12 +35,13 @@ static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf) struct vm_area_struct *vma = vmf->vma; struct udmabuf *ubuf = vma->vm_private_data; pgoff_t pgoff = vmf->pgoff; + unsigned long pfn; if (pgoff >= ubuf->pagecount) return VM_FAULT_SIGBUS; - vmf->page = ubuf->pages[pgoff]; - get_page(vmf->page); - return 0; + + pfn = page_to_pfn(ubuf->pages[pgoff]); + return vmf_insert_pfn(vma, vmf->address, pfn); } static const struct vm_operations_struct udmabuf_vm_ops = { @@ -56,6 +57,7 @@ static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct *vma) vma->vm_ops = &udmabuf_vm_ops; vma->vm_private_data = ubuf; + vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP); return 0; } From patchwork Tue Dec 5 05:35:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Kasireddy, Vivek" X-Patchwork-Id: 13479377 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id B155AC4167B for ; Tue, 5 Dec 2023 05:58:59 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 079796B0078; Tue, 5 Dec 2023 00:58:58 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 02A9C6B007D; Tue, 5 Dec 2023 00:58:57 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id E10A06B007E; Tue, 5 Dec 2023 00:58:57 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id D293B6B0078 for ; Tue, 5 Dec 2023 00:58:57 -0500 (EST) Received: from smtpin23.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id AB519C0193 for ; Tue, 5 Dec 2023 05:58:57 +0000 (UTC) X-FDA: 81531711114.23.53AB1A9 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.12]) by imf29.hostedemail.com (Postfix) with ESMTP id AC43712000A for ; Tue, 5 Dec 2023 05:58:55 +0000 (UTC) Authentication-Results: imf29.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b="ZmN/q31I"; spf=pass (imf29.hostedemail.com: domain of vivek.kasireddy@intel.com designates 198.175.65.12 as permitted sender) smtp.mailfrom=vivek.kasireddy@intel.com; dmarc=pass (policy=none) header.from=intel.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1701755935; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=RrTdeeMeNhhxZWbLlvb86lFm3325eG3oH7NhQhyl9gA=; b=J6e9jkq3yFiRAftBQGQ6AUlw4wmvJBJMyIYVpu3fJQsqK+uvbtqEDdkGrjkLurU0+UaX/J iCxbiFU3P7HACzzZD/o7JpmAyMI4afxRny+5kCHnHIiM2YVZnEopNoFxIDeFo1704NLqy6 hm38kd2Z7XcrI2+kawTzvD02hHRG93g= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1701755935; a=rsa-sha256; cv=none; b=4DaFWaTG79nn7FTx4Kc7U06Kd/wgBXsS0PDVrY9BE4C76UYuomL/CAE6cL5cpA5mDKKWWH VbEigQc4uo1GNsSFB3nqZm8ocjAICGtXmY2L7RLqujrwNLhuHcc/iRjfXbx05VOT2SQvqz 7lTofJCq0h191Fd7JW+QGBXPE6Lr2lY= ARC-Authentication-Results: i=1; imf29.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b="ZmN/q31I"; spf=pass (imf29.hostedemail.com: domain of vivek.kasireddy@intel.com designates 198.175.65.12 as permitted sender) smtp.mailfrom=vivek.kasireddy@intel.com; dmarc=pass (policy=none) header.from=intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1701755936; x=1733291936; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ObYOQ8MIUmEaPxTiLC5uRoa6H7+5D11n4MFPzMj/Kdc=; b=ZmN/q31IbLOii491z+9awQXEKPSN1Fi0k9jrpYQZpytxtE2cnXbNlqhp XorzXB/rpw2FoNLlJh6x/NmregP2nJT9nQolhXgwhrUHEAISWDhNEs5cZ Ndtjow8uE0dRSeYtPBUIY36+gT0waCB9xW83DwiToOPclyNP0QHlF66CJ obTIyR0orzp74l047wzYVWmeayoyFxINSWbAA1xm6POHdNOJEAHZ66mlL /Y327dGXaDwUsAb2SIJljsSJsvKP3US0AOB61CjwLTAg4GUUSEBgWJs2R 0v076KrU/9HDciK9lttoa1HyvKErRMZQMSAFCoC+l+zO0uXWRLljNayAT g==; X-IronPort-AV: E=McAfee;i="6600,9927,10914"; a="906313" X-IronPort-AV: E=Sophos;i="6.04,251,1695711600"; d="scan'208";a="906313" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orvoesa104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Dec 2023 21:58:51 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10914"; a="888807727" X-IronPort-AV: E=Sophos;i="6.04,251,1695711600"; d="scan'208";a="888807727" Received: from vkasired-desk2.fm.intel.com ([10.105.128.132]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Dec 2023 21:58:50 -0800 From: Vivek Kasireddy To: dri-devel@lists.freedesktop.org, linux-mm@kvack.org Cc: Vivek Kasireddy , David Hildenbrand , Daniel Vetter , Mike Kravetz , Hugh Dickins , Peter Xu , Jason Gunthorpe , Gerd Hoffmann , Dongwon Kim , Junxiao Chang Subject: [PATCH v6 2/5] udmabuf: Add back support for mapping hugetlb pages (v5) Date: Mon, 4 Dec 2023 21:35:06 -0800 Message-Id: <20231205053509.2342169-3-vivek.kasireddy@intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231205053509.2342169-1-vivek.kasireddy@intel.com> References: <20231205053509.2342169-1-vivek.kasireddy@intel.com> MIME-Version: 1.0 X-Rspamd-Queue-Id: AC43712000A X-Rspam-User: X-Stat-Signature: u3zt5rpwyw5qikd6upd8hjx6n7ha71a7 X-Rspamd-Server: rspam03 X-HE-Tag: 1701755935-183755 X-HE-Meta: U2FsdGVkX19b1G/ttVg8D1aB8VHlLUp9ABW1EWICt5Wv3fNq0lxfdheb+wlJP7r7juTPMbydOlufWEf9w/cPsU4i4cEkz8WM5U+8RGUWAEEY6Jp/pw5DBniuPzrM8DDcQyQi0tLIbGjHV5r4ZUgb04r9/upxto2T38nPfqAQmu9QhGA3wVC4p3LdkPyeXIIO2sDI0ahiFMHYZnVz247UtHZ0B4tThf1yPK1z609fun31qBB0D3Vv8R0beDcVIvqAvACIVv1PmVqo/gP28a0QFOMD4Eq7w4yQ1s2uf+cnc1ZTzSX07TcpwksiGY+eAGYhiK2kb+pyYOnV/YrzVGAtv/ACwf+uKPT6D9dQ67lSyYAE+ZpyUYEMYq/C2tTUyo9My02nUZyj7Py3VIJGGnFCELVNzGo41BFdBe4wYKWzKO4ieyV5Mp5GarnRW1+354Ad2fUmJGq/6woG7jn4cLrxFPMhQ7pDwB4wY5OTGhrqKxxw/6YjXpMDDyFNzp4VxQ8zgIZTggTAB0GDqt16CqaMTbDZ8KCjJoZo7Up1/ZmY+Bo/BZVozSmCL6ZY2bZCS77GQ/TYSaucfBvTnBot1h3lSFLKM8ogjglaFkyqw1GhLoP3woX9K4FG0Wpav708aCKIhfNMcvbv3DDvU5jIdui2c2nCGzHNLdvFbGPxFv+QG4NeAXfDBQu7NJe+iAfrnGUBzXI2/AI5vBrwpI19GuYNRmBPqtjsLIh/UpcX1wIjfkiV+qFyHnp8hkop0lnEa+1PgQsURc6M+o3iKf5cLiECy5Q/Nw0Cdn+06rzR7WXKM+yYoPBiYv2NTOQgYvoGc6Q3B6RDuMOYubnnJNuZ/f4NGycF8dNZe7YENK4fyBQJwUCit7JMSnDkrzk8WXg1Y4zh2voLlwfKVYXfb7oUyAHJJ6ILkPnH8R8RgGvQNjT1V7YTNz+5IpCFU9mr3HpDJ8bM5UeSIH+uJx85qyljGYa epyx+5gT X9zpnU6OrXob8XsAZ3JRWUBileA0XKSgp2bZ47utWd77yV7k6f17w0roiHz7Vm4tkABeagPWsYZZyiKM+CaAM06/mvZYvechgsfMFZPJdTm4O65F94RJn+bO3Aids2N58kjzL3ZhJgapE71eyrUYfYGf2TMfQg9c+1oTcAfXnS9CPLTY06n7t+rOPVrpc8X+T7Ss0o6HTmPxm7V/gVCQ7gfA3nSxeBAmj8LmHPaKb0J4FH0sftz9QXokcVZ6i/xy/cPIN X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: A user or admin can configure a VMM (Qemu) Guest's memory to be backed by hugetlb pages for various reasons. However, a Guest OS would still allocate (and pin) buffers that are backed by regular 4k sized pages. In order to map these buffers and create dma-bufs for them on the Host, we first need to find the hugetlb pages where the buffer allocations are located and then determine the offsets of individual chunks (within those pages) and use this information to eventually populate a scatterlist. Testcase: default_hugepagesz=2M hugepagesz=2M hugepages=2500 options were passed to the Host kernel and Qemu was launched with these relevant options: qemu-system-x86_64 -m 4096m.... -device virtio-gpu-pci,max_outputs=1,blob=true,xres=1920,yres=1080 -display gtk,gl=on -object memory-backend-memfd,hugetlb=on,id=mem1,size=4096M -machine memory-backend=mem1 Replacing -display gtk,gl=on with -display gtk,gl=off above would exercise the mmap handler. v2: Updated get_sg_table() to manually populate the scatterlist for both huge page and non-huge-page cases. v3: s/offsets/subpgoff/g s/hpoff/mapidx/g v4: Replaced find_get_page_flags() with __filemap_get_folio() to ensure that we only obtain head pages from the mapping v5: Fix the calculation of mapidx to ensure that it is a order-n page multiple Cc: David Hildenbrand Cc: Daniel Vetter Cc: Mike Kravetz Cc: Hugh Dickins Cc: Peter Xu Cc: Jason Gunthorpe Cc: Gerd Hoffmann Cc: Dongwon Kim Cc: Junxiao Chang Acked-by: Mike Kravetz (v2) Signed-off-by: Vivek Kasireddy --- drivers/dma-buf/udmabuf.c | 88 +++++++++++++++++++++++++++++++++------ 1 file changed, 75 insertions(+), 13 deletions(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index 820c993c8659..1d1cc5e7e613 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -28,6 +29,7 @@ struct udmabuf { struct page **pages; struct sg_table *sg; struct miscdevice *device; + pgoff_t *subpgoff; }; static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf) @@ -41,6 +43,10 @@ static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf) return VM_FAULT_SIGBUS; pfn = page_to_pfn(ubuf->pages[pgoff]); + if (ubuf->subpgoff) { + pfn += ubuf->subpgoff[pgoff] >> PAGE_SHIFT; + } + return vmf_insert_pfn(vma, vmf->address, pfn); } @@ -90,23 +96,31 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf, { struct udmabuf *ubuf = buf->priv; struct sg_table *sg; + struct scatterlist *sgl; + pgoff_t offset; + unsigned long i = 0; int ret; sg = kzalloc(sizeof(*sg), GFP_KERNEL); if (!sg) return ERR_PTR(-ENOMEM); - ret = sg_alloc_table_from_pages(sg, ubuf->pages, ubuf->pagecount, - 0, ubuf->pagecount << PAGE_SHIFT, - GFP_KERNEL); + + ret = sg_alloc_table(sg, ubuf->pagecount, GFP_KERNEL); if (ret < 0) - goto err; + goto err_alloc; + + for_each_sg(sg->sgl, sgl, ubuf->pagecount, i) { + offset = ubuf->subpgoff ? ubuf->subpgoff[i] : 0; + sg_set_page(sgl, ubuf->pages[i], PAGE_SIZE, offset); + } ret = dma_map_sgtable(dev, sg, direction, 0); if (ret < 0) - goto err; + goto err_map; return sg; -err: +err_map: sg_free_table(sg); +err_alloc: kfree(sg); return ERR_PTR(ret); } @@ -143,6 +157,7 @@ static void release_udmabuf(struct dma_buf *buf) for (pg = 0; pg < ubuf->pagecount; pg++) put_page(ubuf->pages[pg]); + kfree(ubuf->subpgoff); kfree(ubuf->pages); kfree(ubuf); } @@ -206,7 +221,10 @@ static long udmabuf_create(struct miscdevice *device, struct udmabuf *ubuf; struct dma_buf *buf; pgoff_t pgoff, pgcnt, pgidx, pgbuf = 0, pglimit; - struct page *page; + struct page *page, *hpage = NULL; + struct folio *folio; + pgoff_t mapidx, chunkoff, maxchunks; + struct hstate *hpstate; int seals, ret = -EINVAL; u32 i, flags; @@ -242,7 +260,7 @@ static long udmabuf_create(struct miscdevice *device, if (!memfd) goto err; mapping = memfd->f_mapping; - if (!shmem_mapping(mapping)) + if (!shmem_mapping(mapping) && !is_file_hugepages(memfd)) goto err; seals = memfd_fcntl(memfd, F_GET_SEALS, 0); if (seals == -EINVAL) @@ -253,16 +271,59 @@ static long udmabuf_create(struct miscdevice *device, goto err; pgoff = list[i].offset >> PAGE_SHIFT; pgcnt = list[i].size >> PAGE_SHIFT; + if (is_file_hugepages(memfd)) { + if (!ubuf->subpgoff) { + ubuf->subpgoff = kmalloc_array(ubuf->pagecount, + sizeof(*ubuf->subpgoff), + GFP_KERNEL); + if (!ubuf->subpgoff) { + ret = -ENOMEM; + goto err; + } + } + hpstate = hstate_file(memfd); + mapidx = list[i].offset >> huge_page_shift(hpstate); + mapidx <<= huge_page_order(hpstate); + chunkoff = (list[i].offset & + ~huge_page_mask(hpstate)) >> PAGE_SHIFT; + maxchunks = huge_page_size(hpstate) >> PAGE_SHIFT; + } for (pgidx = 0; pgidx < pgcnt; pgidx++) { - page = shmem_read_mapping_page(mapping, pgoff + pgidx); - if (IS_ERR(page)) { - ret = PTR_ERR(page); - goto err; + if (is_file_hugepages(memfd)) { + if (!hpage) { + folio = __filemap_get_folio(mapping, mapidx, + FGP_ACCESSED, 0); + hpage = IS_ERR(folio) ? NULL: &folio->page; + if (!hpage) { + ret = -EINVAL; + goto err; + } + } + get_page(hpage); + ubuf->pages[pgbuf] = hpage; + ubuf->subpgoff[pgbuf++] = chunkoff << PAGE_SHIFT; + if (++chunkoff == maxchunks) { + put_page(hpage); + hpage = NULL; + chunkoff = 0; + mapidx += pages_per_huge_page(hpstate); + } + } else { + mapidx = pgoff + pgidx; + page = shmem_read_mapping_page(mapping, mapidx); + if (IS_ERR(page)) { + ret = PTR_ERR(page); + goto err; + } + ubuf->pages[pgbuf++] = page; } - ubuf->pages[pgbuf++] = page; } fput(memfd); memfd = NULL; + if (hpage) { + put_page(hpage); + hpage = NULL; + } } exp_info.ops = &udmabuf_ops; @@ -287,6 +348,7 @@ static long udmabuf_create(struct miscdevice *device, put_page(ubuf->pages[--pgbuf]); if (memfd) fput(memfd); + kfree(ubuf->subpgoff); kfree(ubuf->pages); kfree(ubuf); return ret; From patchwork Tue Dec 5 05:35:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Kasireddy, Vivek" X-Patchwork-Id: 13479378 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 53F12C46CA0 for ; Tue, 5 Dec 2023 05:59:02 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 66ED76B007D; Tue, 5 Dec 2023 00:58:58 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 61DC16B0080; Tue, 5 Dec 2023 00:58:58 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 449CA6B0081; Tue, 5 Dec 2023 00:58:58 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id 1E02F6B0080 for ; Tue, 5 Dec 2023 00:58:58 -0500 (EST) Received: from smtpin22.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay07.hostedemail.com (Postfix) with ESMTP id E8AD5160185 for ; Tue, 5 Dec 2023 05:58:57 +0000 (UTC) X-FDA: 81531711114.22.0C53053 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.12]) by imf21.hostedemail.com (Postfix) with ESMTP id EF0051C0004 for ; Tue, 5 Dec 2023 05:58:55 +0000 (UTC) Authentication-Results: imf21.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b="bgTljf9/"; dmarc=pass (policy=none) header.from=intel.com; spf=pass (imf21.hostedemail.com: domain of vivek.kasireddy@intel.com designates 198.175.65.12 as permitted sender) smtp.mailfrom=vivek.kasireddy@intel.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1701755936; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=F/i3L/T0lSTylFyIMGMv6BZxPZJ3QjTIhU0pTVLezZk=; b=u8L6+1pUbYcLH9H5FBKHFxiIAfZAAgV2y76pJ4FD18U/CRgMUGY/uW/Hnk3nV51GhoO9q8 kH84Ubqii8TdKH0ddn3wvvnr76VAJhavPkOJv0m+aR/zuJkX2t4MQzHTfxmITkhKhS8K2n lbyXHHo9iZxcuV9JmJBaJ8OBc5RGl1I= ARC-Authentication-Results: i=1; imf21.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b="bgTljf9/"; dmarc=pass (policy=none) header.from=intel.com; spf=pass (imf21.hostedemail.com: domain of vivek.kasireddy@intel.com designates 198.175.65.12 as permitted sender) smtp.mailfrom=vivek.kasireddy@intel.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1701755936; a=rsa-sha256; cv=none; b=36DBWFYdKmaVPKbueqdPm+eQ1raiQCCUKLGg4rKr04l3MABGS7WSd4G2u/ScxraLnApuEs ySfNTI23iwMsE7gKO7q8n0N7IyJet0drnqeoxpyDhBmbGsshHja4IowSW+XCTip75PCgZ2 ZH47pCGrpDqMrSu8mjswtnTxTkzMW0o= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1701755936; x=1733291936; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=USaDsXb+eUlaG8Jvcx/0BopeELbgynaKZTJfyFBFcCc=; b=bgTljf9/fkPDAD0ewZjEC/y3EpJRAsazcU96jaObbaUHYDtAPiN16MgM Y6BsbZKBCYXidOzpND9x9HxKt9wgffGyPcF4PrrrydxsNCs4RbzPHwlFX dkemXddKjFfOZU9BZCtO902PQ+JGmlKHiSfQfYasluBNdRb3WnM3vTMo5 OEyYQ+dqU1OQvkB7+vX7NUKkjllq2ueEfOp0y74jxSd84c/+hi81ZFPyV qrPd9q6piEzmqlVXey5i2/DlZA6GOIeecaB8ldJ1HexwCICWhIl6h43hi O6LZt+YpVInGB32UpWtseQrGkbA0hOtKdLLjkLeXMiur/+KoYMNs/jfxk A==; X-IronPort-AV: E=McAfee;i="6600,9927,10914"; a="906322" X-IronPort-AV: E=Sophos;i="6.04,251,1695711600"; d="scan'208";a="906322" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orvoesa104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Dec 2023 21:58:51 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10914"; a="888807730" X-IronPort-AV: E=Sophos;i="6.04,251,1695711600"; d="scan'208";a="888807730" Received: from vkasired-desk2.fm.intel.com ([10.105.128.132]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Dec 2023 21:58:50 -0800 From: Vivek Kasireddy To: dri-devel@lists.freedesktop.org, linux-mm@kvack.org Cc: Vivek Kasireddy , David Hildenbrand , Christoph Hellwig , Daniel Vetter , Mike Kravetz , Hugh Dickins , Peter Xu , Gerd Hoffmann , Dongwon Kim , Junxiao Chang , Jason Gunthorpe Subject: [PATCH v6 3/5] mm/gup: Introduce memfd_pin_user_pages() for pinning memfd pages (v6) Date: Mon, 4 Dec 2023 21:35:07 -0800 Message-Id: <20231205053509.2342169-4-vivek.kasireddy@intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231205053509.2342169-1-vivek.kasireddy@intel.com> References: <20231205053509.2342169-1-vivek.kasireddy@intel.com> MIME-Version: 1.0 X-Rspam-User: X-Rspamd-Server: rspam12 X-Rspamd-Queue-Id: EF0051C0004 X-Stat-Signature: u31gbqc3nfpjic7w1cdt5ciqnufmmdpk X-HE-Tag: 1701755935-396165 X-HE-Meta: U2FsdGVkX1/SOEXrbrzeQdZ6qacpxDN1Hfqh08BLc+MW59p2N6lQpAI9aXZRl41M4c09furJ0HXYa6o9PF9xEA6dy9Zk2rsgEaqQ18r5+kWC3/PiKan9UgIkIJdrHuX5ekOr6s4X8DjQUZjfX/fBCvBRixURxdEi2f3t6T3cvaZxVt0JTXhyPX9RJ8jua/EcVnmqqv37zmHLfu+NaFB9AUZp6xDDuOvyFwV23iCYOSX1XpvAyLp0XLti/5LE8A55xZ5DAVt12h60kRnUzgIPoavFPZG1t/IW57IGGHWSklX/obITkC0RKS0pKSn32YoejhDi3PDGtEDvP1RNztc+sgXkWfIvC+y9NuhyNEIAF/GHeDXa4+zw8wSBB9poSErRco+qI0qyGGbKwTUh/REZwHKTYDR+DNnDSoI79hfQV9wGGqWDQIJXRileICTKA4/06ePcjsMMnSYLWvBVLbbcZJl5TRlagH9FX9BLC71TR/CFzalu1vQIz8AsJRjb0wF1KDwS1nT4WuF634NV1Rwp00UN/kFVDm60MKb4GY2XykHszRwtTiAvRB5XulhgAyW3bP/ldTxbGwiXpLMcQEdQZ7CayFWQp7vamfX6MkitBWGG3O5VWzAaDQQQ5uJO26d3tnucBR0f7xOvDsBgHW8EwRv202XM4pDPLEnAHw4O4fzc68y1PCsm3QUzN8Qf0sV/i65CRQ8HOEFVW7evgTeILqfIDnRwxxzLANy6YPt2qeh6w9d5uZgdACam4seTumNJq2bqrBdSERJQuBo6rjsBmVwmDBKXGiQjSG4VEK4dzwUmdLia+s75/tgRzdlaHWfILeIRAII/Aq7cb/GckYx5iJYq55FvFpF2DLjJaMM2Kyu7wo1OlmOfwxs+oPZYML327yevtPoF3td3DK8630ufT0f8ez9K7KB8ec1IWDznVMFJrNvWtdhHF6/L5NLAaDYaEUnDM/oY0srqVeN/PoS odEbCdlh BwVy0cBLaZbNSCdL8oVlHLoCJ4bJSg0NQNVGXhUygw+WU7kFozepSRwAUbcumNObs4TMSsTn3L8Q1c/kgo5W2KTdkavNCPIcKV2LgidP5AWaUPtFclhYHqLbDIJk1zqE1SkZHZHO2VoePVT1dVA6plukOz1NhWTLSK4N6xB3qjk6+0IuMthxXZ3mWYO4umEGC4tUtiHtrKpQYp1Cegcvv+2mvaxJpcQwXwElRXtDLIOZ1DBcwxQ3va4/j6rvk7FXScTVT8Fn/Rp21fx/dYhcPXOW+C9gZBGufG0wK9qDVriGQjGEchjd1BQvgTQ5x5joRIL7ZM2wfMBFpBLoVFYmYfkUAYn+aENYg7oO4s2JwUCacw8E= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: For drivers that would like to longterm-pin the pages associated with a memfd, the pin_user_pages_fd() API provides an option to not only pin the pages via FOLL_PIN but also to check and migrate them if they reside in movable zone or CMA block. This API currently works with memfds but it should work with any files that belong to either shmemfs or hugetlbfs. Files belonging to other filesystems are rejected for now. The pages need to be located first before pinning them via FOLL_PIN. If they are found in the page cache, they can be immediately pinned. Otherwise, they need to be allocated using the filesystem specific APIs and then pinned. v2: - Drop gup_flags and improve comments and commit message (David) - Allocate a page if we cannot find in page cache for the hugetlbfs case as well (David) - Don't unpin pages if there is a migration related failure (David) - Drop the unnecessary nr_pages <= 0 check (Jason) - Have the caller of the API pass in file * instead of fd (Jason) v3: (David) - Enclose the huge page allocation code with #ifdef CONFIG_HUGETLB_PAGE (Build error reported by kernel test robot ) - Don't forget memalloc_pin_restore() on non-migration related errors - Improve the readability of the cleanup code associated with non-migration related errors - Augment the comments by describing FOLL_LONGTERM like behavior - Include the R-b tag from Jason v4: - Remove the local variable "page" and instead use 3 return statements in alloc_file_page() (David) - Add the R-b tag from David v5: (David) - For hugetlb case, ensure that we only obtain head pages from the mapping by using __filemap_get_folio() instead of find_get_page_flags() - Handle -EEXIST when two or more potential users try to simultaneously add a huge page to the mapping by forcing them to retry on failure v6: (Christoph) - Rename this API to memfd_pin_user_pages() to make it clear that it is intended for memfds - Move the memfd page allocation helper from gup.c to memfd.c - Fix indentation errors in memfd_pin_user_pages() - For contiguous ranges of folios, use a helper such as filemap_get_folios_contig() to lookup the page cache in batches Cc: David Hildenbrand Cc: Christoph Hellwig Cc: Daniel Vetter Cc: Mike Kravetz Cc: Hugh Dickins Cc: Peter Xu Cc: Gerd Hoffmann Cc: Dongwon Kim Cc: Junxiao Chang Suggested-by: Jason Gunthorpe Reviewed-by: Jason Gunthorpe (v2) Reviewed-by: David Hildenbrand (v3) Signed-off-by: Vivek Kasireddy Reviewed-by: Christoph Hellwig --- include/linux/memfd.h | 5 +++ include/linux/mm.h | 2 + mm/gup.c | 102 ++++++++++++++++++++++++++++++++++++++++++ mm/memfd.c | 34 ++++++++++++++ 4 files changed, 143 insertions(+) diff --git a/include/linux/memfd.h b/include/linux/memfd.h index e7abf6fa4c52..6fc0d1282151 100644 --- a/include/linux/memfd.h +++ b/include/linux/memfd.h @@ -6,11 +6,16 @@ #ifdef CONFIG_MEMFD_CREATE extern long memfd_fcntl(struct file *file, unsigned int cmd, unsigned int arg); +extern struct page *memfd_alloc_page(struct file *memfd, pgoff_t idx); #else static inline long memfd_fcntl(struct file *f, unsigned int c, unsigned int a) { return -EINVAL; } +static inline struct page *memfd_alloc_page(struct file *memfd, pgoff_t idx) +{ + return ERR_PTR(-EINVAL); +} #endif #endif /* __LINUX_MEMFD_H */ diff --git a/include/linux/mm.h b/include/linux/mm.h index 418d26608ece..ac69db45509f 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2472,6 +2472,8 @@ long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages, struct page **pages, unsigned int gup_flags); long pin_user_pages_unlocked(unsigned long start, unsigned long nr_pages, struct page **pages, unsigned int gup_flags); +long memfd_pin_user_pages(struct file *file, pgoff_t start, + unsigned long nr_pages, struct page **pages); int get_user_pages_fast(unsigned long start, int nr_pages, unsigned int gup_flags, struct page **pages); diff --git a/mm/gup.c b/mm/gup.c index 231711efa390..eb93d1ec9dc6 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -17,6 +18,7 @@ #include #include #include +#include #include #include @@ -3410,3 +3412,103 @@ long pin_user_pages_unlocked(unsigned long start, unsigned long nr_pages, &locked, gup_flags); } EXPORT_SYMBOL(pin_user_pages_unlocked); + +/** + * memfd_pin_user_pages() - pin user pages associated with a memfd + * @memfd: the memfd whose pages are to be pinned + * @start: starting memfd offset + * @nr_pages: number of pages from start to pin + * @pages: array that receives pointers to the pages pinned. + * Should be at-least nr_pages long. + * + * Attempt to pin pages associated with a memfd; given that a memfd is either + * backed by shmem or hugetlb, the pages can either be found in the page cache + * or need to be allocated if necessary. Once the pages are located, they are + * all pinned via FOLL_PIN. And, these pinned pages need to be released either + * using unpin_user_pages() or unpin_user_page(). + * + * It must be noted that the pages may be pinned for an indefinite amount + * of time. And, in most cases, the duration of time they may stay pinned + * would be controlled by the userspace. This behavior is effectively the + * same as using FOLL_LONGTERM with other GUP APIs. + * + * Returns number of pages pinned. This would be equal to the number of + * pages requested. If no pages were pinned, it returns -errno. + */ +long memfd_pin_user_pages(struct file *memfd, pgoff_t start, + unsigned long nr_pages, struct page **pages) +{ + pgoff_t start_idx, end_idx = start + nr_pages - 1; + unsigned int flags, nr_folios, i, j; + struct folio_batch fbatch; + struct page *page = NULL; + struct folio *folio; + long ret; + + if (!nr_pages) + return -EINVAL; + + if (!memfd) + return -EINVAL; + + if (!shmem_file(memfd) && !is_file_hugepages(memfd)) + return -EINVAL; + + flags = memalloc_pin_save(); + do { + folio_batch_init(&fbatch); + start_idx = start; + i = 0; + + while (start_idx <= end_idx) { + /* + * In most cases, we should be able to find the page + * in the page cache. If we cannot find it for some + * reason, we try to allocate one and add it to the + * page cache. + */ + nr_folios = filemap_get_folios_contig(memfd->f_mapping, + &start_idx, + end_idx, + &fbatch); + if (page) { + put_page(page); + page = NULL; + } + for (j = 0; j < nr_folios; j++) { + folio = fbatch.folios[j]; + ret = try_grab_page(&folio->page, FOLL_PIN); + if (unlikely(ret)) { + folio_batch_release(&fbatch); + goto err; + } + + pages[i++] = &folio->page; + } + + folio_batch_release(&fbatch); + if (!nr_folios) { + page = memfd_alloc_page(memfd, start_idx); + if (IS_ERR(page)) { + ret = PTR_ERR(page); + if (ret != -EEXIST) + goto err; + } + } + } + + ret = check_and_migrate_movable_pages(nr_pages, pages); + } while (ret == -EAGAIN); + + memalloc_pin_restore(flags); + return ret ? ret : nr_pages; +err: + memalloc_pin_restore(flags); + while (i-- > 0) + if (pages[i]) + unpin_user_page(pages[i]); + + return ret; +} +EXPORT_SYMBOL_GPL(memfd_pin_user_pages); + diff --git a/mm/memfd.c b/mm/memfd.c index d3a1ba4208c9..b315cd12bdb7 100644 --- a/mm/memfd.c +++ b/mm/memfd.c @@ -63,6 +63,40 @@ static void memfd_tag_pins(struct xa_state *xas) xas_unlock_irq(xas); } +/* + * This is a helper function used by memfd_pin_user_pages() in GUP (gup.c). + * It is mainly called to allocate a page in a memfd when the caller + * (memfd_pin_user_pages()) cannot find a page in the page cache at a given + * index in the mapping. + */ +struct page *memfd_alloc_page(struct file *memfd, pgoff_t idx) +{ +#ifdef CONFIG_HUGETLB_PAGE + struct folio *folio; + int err; + + if (is_file_hugepages(memfd)) { + folio = alloc_hugetlb_folio_nodemask(hstate_file(memfd), + NUMA_NO_NODE, + NULL, + GFP_USER); + if (folio && folio_try_get(folio)) { + err = hugetlb_add_to_page_cache(folio, + memfd->f_mapping, + idx); + if (err) { + folio_put(folio); + free_huge_folio(folio); + return ERR_PTR(err); + } + return &folio->page; + } + return ERR_PTR(-ENOMEM); + } +#endif + return shmem_read_mapping_page(memfd->f_mapping, idx); +} + /* * Setting SEAL_WRITE requires us to verify there's no pending writer. However, * via get_user_pages(), drivers might have some pending I/O without any active From patchwork Tue Dec 5 05:35:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Kasireddy, Vivek" X-Patchwork-Id: 13479379 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id C2F56C07E97 for ; Tue, 5 Dec 2023 05:59:04 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 006456B0080; Tue, 5 Dec 2023 00:59:00 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id EF88B6B0081; Tue, 5 Dec 2023 00:58:59 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id CFCBB6B0082; Tue, 5 Dec 2023 00:58:59 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id B15A36B0080 for ; Tue, 5 Dec 2023 00:58:59 -0500 (EST) Received: from smtpin16.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id 8EC2CC0190 for ; Tue, 5 Dec 2023 05:58:59 +0000 (UTC) X-FDA: 81531711198.16.2A7DBDF Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.12]) by imf12.hostedemail.com (Postfix) with ESMTP id 781F640004 for ; Tue, 5 Dec 2023 05:58:56 +0000 (UTC) Authentication-Results: imf12.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b="XoOx/2fm"; spf=pass (imf12.hostedemail.com: domain of vivek.kasireddy@intel.com designates 198.175.65.12 as permitted sender) smtp.mailfrom=vivek.kasireddy@intel.com; dmarc=pass (policy=none) header.from=intel.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1701755936; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=vmBJDw9qqKKN35XiCpuvStJvcS2gMraGVEnNdA9VQws=; b=rLFvEhFODuKkp7K/6RCO9aUxOkDLtfmxahOlddOgAk2m+G9YITgPKAJGBfTctvdK+swmr1 UBdm2Y3vLMFXHT6WeFWKnwNdEflDQ3DViLG0ub79L1xLGnUb5UfscPMUGwNM9cplQYBt5W uAj6VjaSqHvHk+a/aKHGNwEmYFHt16w= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1701755936; a=rsa-sha256; cv=none; b=oFxghi22OtCyMWpzk4WKc3+H5Ky0MYKZblUyxnE4dGAv6af78ljeH4/bAMvKL1K3MwUI9M AGc125hihyierbtQkuGe0FWL553NNZiukx5M9E2hpc2f37ZNM2/0b1rehgE8SFtwKVw1Ai Wap/3B/ShFX5PwyMf+PHubyL9Yjs1gA= ARC-Authentication-Results: i=1; imf12.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b="XoOx/2fm"; spf=pass (imf12.hostedemail.com: domain of vivek.kasireddy@intel.com designates 198.175.65.12 as permitted sender) smtp.mailfrom=vivek.kasireddy@intel.com; dmarc=pass (policy=none) header.from=intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1701755937; x=1733291937; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=2lJJFbXrRuB2RlRAET5QtLu2irPUsw8bf+ZLAugxfOs=; b=XoOx/2fmSYZGOcnD4L/0ehNsjfu5wJtnkl9wHKXzom32LYEVuHksbatO /m9eatcxff93ZZoog/DaKzdpe3THIcDfjDBbLnvybf/T5zUx4/zyQKxDN 8MK7QEx8ViPjWd3kYXOCugVxnu3VlWYORfHF+NOnP6LsptFQJ99yKZM9y LgmFw5brRrQdTaId5HpECfLe1RnCQ3wEVNx5qeVk+e+YZlc8Eebg8qvNu yleu+0WSL1gvJhtuIbymEnEjSOEk7YIBlSKOsQVDraOcz+NHbI5nRkBDY HucnTVG537wL4Bffi1V0G6sFTcldcp6YdQSbrIk/xf/rHje1w8pIbrD88 g==; X-IronPort-AV: E=McAfee;i="6600,9927,10914"; a="906329" X-IronPort-AV: E=Sophos;i="6.04,251,1695711600"; d="scan'208";a="906329" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orvoesa104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Dec 2023 21:58:52 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10914"; a="888807735" X-IronPort-AV: E=Sophos;i="6.04,251,1695711600"; d="scan'208";a="888807735" Received: from vkasired-desk2.fm.intel.com ([10.105.128.132]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Dec 2023 21:58:50 -0800 From: Vivek Kasireddy To: dri-devel@lists.freedesktop.org, linux-mm@kvack.org Cc: Vivek Kasireddy , David Hildenbrand , Daniel Vetter , Mike Kravetz , Hugh Dickins , Peter Xu , Jason Gunthorpe , Gerd Hoffmann , Dongwon Kim , Junxiao Chang Subject: [PATCH v6 4/5] udmabuf: Pin the pages using memfd_pin_user_pages() API (v4) Date: Mon, 4 Dec 2023 21:35:08 -0800 Message-Id: <20231205053509.2342169-5-vivek.kasireddy@intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231205053509.2342169-1-vivek.kasireddy@intel.com> References: <20231205053509.2342169-1-vivek.kasireddy@intel.com> MIME-Version: 1.0 X-Rspamd-Queue-Id: 781F640004 X-Rspam-User: X-Stat-Signature: jdo5fy5csdum7m6ipguz8ydn31kzm65x X-Rspamd-Server: rspam03 X-HE-Tag: 1701755936-796643 X-HE-Meta: U2FsdGVkX1/t4RQgID/S4laPbD0bW9nxotnZAkP5O0o42bQ9G116GmKcbuXFXdIv+JePL1RcOMuQ1kEBtiCLMCVbNVFgughPeFm9AnvTfoLWt0ee5M9pWvA29YOMeuPkcGYX+XNKAzOB1XByaNYGjWYUjbt6ses1Ir02zGRprR+FvoK++596MQ7xixV1iIY+yW5W8exX0lCO3EN2J6d2BImQ+p8WbDeo+uswqA0i0CCm5Dbj8harbOE2sffYc4LLSpDvvBlpGBc7l2gVub/xmJy4QAd+gK7U48Kwv3tEqmJZSH8d+ArliW8TTm3O/sBebby0aYxsw5e8qxyPpJJCg8EO3NpOmxKok/QkE2kTjx0dOUHaJpEFVApoyYmQp/sL83GaQlzVd7bomrTE7RIxowkjW8Ni87Euf90bl5xkw5wsFxwqtUTkiJRZlAEdhisGv3URIbRSZOhcyZ93ypAzNP9nBSSRgAFg6HyuubpBsP9dhai7X/ryk6xSKnMh37IItn9OlViPfuGJYJx+QZjJIGWfaCHK6+iabBA1KpfMFmG/upfF9/sYpuy+vEUVrI4bBVUmkNLdp0HqAdPkO+NdN24DfoTYxQeTXwTi2RmquBdbsqrxCI/LFY5CjmHoURwAD9UvmPhr1nyYJhNyUSei9Q96gCfIiwiZOq/F49BuiqN7ywEKl1Y1/SLYNAzgDHiTYnkSwrkN4rRgtD9V2wyANn1spIEwmewKYXo28A3G3JyBf3mWrtNbv0I9Ln5vFIpi1ypvhbG3BDa3a9MvbWzmBeLjEXOxqU5FSX6FxrVMr3fTcFpbkqcQ+lw+lxWbsvy0VEfK80YnLtybr3jozi/zuLv7ch6Eqf7j10aBjx+66y/ZC6Xkh5hzw6lkGLWt7kPzybBAVykDGPfAPWtAOB4m4xhvaPO5Zr/MubRiOAqAFLzJx2qcu/SoH2Iwgu2gZ3sQQNHDOPi+xJa7uJSfZS4 5UqPPc1A UZ4PQ3xtL3La6NEKMaB25IMSY/h4lcCPUA1PYlzI0RPMJfH2qXYVLACQBxe/WoQc3Eehn9FBWtrMQSICKGGBTTyrZCoBfiZv2AqyX+IDR93VWAMrFHK8riRWTrKHrmejzBSLWq/yDpbBSpvXae3/dkzlW+wsVTKffB5/q6bMGeCwrEtNQw65uwDinB03z5s22vsP/JSoPGryksoboLhBGtkNS/WZzqIADOvd99sprIcxASYcfOJRUU6i004q3SvDsT8KJhb1tXAWwzRC3NXXVlOjV9534ZXofesEuK9q2Wo4Fhjo= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Using memfd_pin_user_pages() will ensure that the pages are pinned correctly using FOLL_PIN. And, this also ensures that we don't accidentally break features such as memory hotunplug as it would not allow pinning pages in the movable zone. Using this new API also simplifies the code as we no longer have to deal with extracting individual pages from their mappings. As a result, we can drop some of the local variables such as page, hpage, mapping, etc. v2: - Adjust to the change in signature of pin_user_pages_fd() by passing in file * instead of fd. v3: - Limit the changes in this patch only to those that are required for using pin_user_pages_fd() - Slightly improve the commit message v4: - Adjust to the change in name of the API (memfd_pin_user_pages) Cc: David Hildenbrand Cc: Daniel Vetter Cc: Mike Kravetz Cc: Hugh Dickins Cc: Peter Xu Cc: Jason Gunthorpe Cc: Gerd Hoffmann Cc: Dongwon Kim Cc: Junxiao Chang Signed-off-by: Vivek Kasireddy --- drivers/dma-buf/udmabuf.c | 62 +++++++++++++++------------------------ 1 file changed, 23 insertions(+), 39 deletions(-) diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index 1d1cc5e7e613..887dc287a23c 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -156,7 +156,8 @@ static void release_udmabuf(struct dma_buf *buf) put_sg_table(dev, ubuf->sg, DMA_BIDIRECTIONAL); for (pg = 0; pg < ubuf->pagecount; pg++) - put_page(ubuf->pages[pg]); + unpin_user_page(ubuf->pages[pg]); + kfree(ubuf->subpgoff); kfree(ubuf->pages); kfree(ubuf); @@ -217,15 +218,13 @@ static long udmabuf_create(struct miscdevice *device, { DEFINE_DMA_BUF_EXPORT_INFO(exp_info); struct file *memfd = NULL; - struct address_space *mapping = NULL; struct udmabuf *ubuf; struct dma_buf *buf; - pgoff_t pgoff, pgcnt, pgidx, pgbuf = 0, pglimit; - struct page *page, *hpage = NULL; - struct folio *folio; + pgoff_t pgcnt, pgbuf = 0, pglimit, nr_pages; pgoff_t mapidx, chunkoff, maxchunks; struct hstate *hpstate; - int seals, ret = -EINVAL; + long ret = -EINVAL; + int seals; u32 i, flags; ubuf = kzalloc(sizeof(*ubuf), GFP_KERNEL); @@ -259,8 +258,7 @@ static long udmabuf_create(struct miscdevice *device, memfd = fget(list[i].memfd); if (!memfd) goto err; - mapping = memfd->f_mapping; - if (!shmem_mapping(mapping) && !is_file_hugepages(memfd)) + if (!shmem_file(memfd) && !is_file_hugepages(memfd)) goto err; seals = memfd_fcntl(memfd, F_GET_SEALS, 0); if (seals == -EINVAL) @@ -269,7 +267,7 @@ static long udmabuf_create(struct miscdevice *device, if ((seals & SEALS_WANTED) != SEALS_WANTED || (seals & SEALS_DENIED) != 0) goto err; - pgoff = list[i].offset >> PAGE_SHIFT; + mapidx = list[i].offset >> PAGE_SHIFT; pgcnt = list[i].size >> PAGE_SHIFT; if (is_file_hugepages(memfd)) { if (!ubuf->subpgoff) { @@ -288,42 +286,27 @@ static long udmabuf_create(struct miscdevice *device, ~huge_page_mask(hpstate)) >> PAGE_SHIFT; maxchunks = huge_page_size(hpstate) >> PAGE_SHIFT; } - for (pgidx = 0; pgidx < pgcnt; pgidx++) { + + do { + nr_pages = shmem_file(memfd) ? pgcnt : 1; + ret = memfd_pin_user_pages(memfd, mapidx, nr_pages, + ubuf->pages + pgbuf); + if (ret < 0) + goto err; + if (is_file_hugepages(memfd)) { - if (!hpage) { - folio = __filemap_get_folio(mapping, mapidx, - FGP_ACCESSED, 0); - hpage = IS_ERR(folio) ? NULL: &folio->page; - if (!hpage) { - ret = -EINVAL; - goto err; - } - } - get_page(hpage); - ubuf->pages[pgbuf] = hpage; - ubuf->subpgoff[pgbuf++] = chunkoff << PAGE_SHIFT; + ubuf->subpgoff[pgbuf] = chunkoff << PAGE_SHIFT; if (++chunkoff == maxchunks) { - put_page(hpage); - hpage = NULL; chunkoff = 0; mapidx += pages_per_huge_page(hpstate); } - } else { - mapidx = pgoff + pgidx; - page = shmem_read_mapping_page(mapping, mapidx); - if (IS_ERR(page)) { - ret = PTR_ERR(page); - goto err; - } - ubuf->pages[pgbuf++] = page; } - } + pgbuf += nr_pages; + pgcnt -= nr_pages; + } while (pgcnt > 0); + fput(memfd); memfd = NULL; - if (hpage) { - put_page(hpage); - hpage = NULL; - } } exp_info.ops = &udmabuf_ops; @@ -344,8 +327,9 @@ static long udmabuf_create(struct miscdevice *device, return dma_buf_fd(buf, flags); err: - while (pgbuf > 0) - put_page(ubuf->pages[--pgbuf]); + while (pgbuf-- > 0) + if (ubuf->pages[pgbuf]) + unpin_user_page(ubuf->pages[pgbuf]); if (memfd) fput(memfd); kfree(ubuf->subpgoff); From patchwork Tue Dec 5 05:35:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Kasireddy, Vivek" X-Patchwork-Id: 13479380 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id F2899C4167B for ; Tue, 5 Dec 2023 05:59:06 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 5F9B76B0081; Tue, 5 Dec 2023 00:59:00 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 5351D6B0082; Tue, 5 Dec 2023 00:59:00 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 3D5A46B0085; Tue, 5 Dec 2023 00:59:00 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0010.hostedemail.com [216.40.44.10]) by kanga.kvack.org (Postfix) with ESMTP id 176646B0082 for ; Tue, 5 Dec 2023 00:59:00 -0500 (EST) Received: from smtpin11.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay05.hostedemail.com (Postfix) with ESMTP id EBE1A40194 for ; Tue, 5 Dec 2023 05:58:59 +0000 (UTC) X-FDA: 81531711198.11.C89F5C2 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.12]) by imf29.hostedemail.com (Postfix) with ESMTP id C7FC012000A for ; Tue, 5 Dec 2023 05:58:57 +0000 (UTC) Authentication-Results: imf29.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b=km94V8Er; spf=pass (imf29.hostedemail.com: domain of vivek.kasireddy@intel.com designates 198.175.65.12 as permitted sender) smtp.mailfrom=vivek.kasireddy@intel.com; dmarc=pass (policy=none) header.from=intel.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1701755938; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=h3emmYlObQz4YBWvxea89j9SxvY/uMNOIgA3BV8wvNU=; b=19f9IMsdcvHemYeSbQmKOEcQ+Zi/K2l4I6HORayg4dFop5E79uALr3hqQd/lnAAiL9uJt8 V9qCa9bwQELVf5461+aja+p8swjaKH7xuXwBWpisdUP8dC5zPfIE7zWmhHQgSYyHrbOpqa /nCdENIhxKHsKGSKj7Byu1AJNS3wHNU= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1701755938; a=rsa-sha256; cv=none; b=b0OuC1FJtcBSdFe38pSdcNVgX/l4sYIZzrHiFWmPJgBO5en+L9e6/7oKouDCyq4TO2axwl 9DLrjDmQAxNIrJrZZmm4duzS94Gt9G8aIc2M6RJd5WfcG911ij+Hhrr84/67NR6rjjzo6u uWG5bvKL9a8GHjuOSGu1v5jNGJMuLLE= ARC-Authentication-Results: i=1; imf29.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b=km94V8Er; spf=pass (imf29.hostedemail.com: domain of vivek.kasireddy@intel.com designates 198.175.65.12 as permitted sender) smtp.mailfrom=vivek.kasireddy@intel.com; dmarc=pass (policy=none) header.from=intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1701755938; x=1733291938; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=r39C9fURv/tYjjTgfRvVfOiacLkGBXJF65fG2x4l+b0=; b=km94V8ErJ2txyd6r2ht1omm0XCzZ/cATa0TZBtmpJvEx0Sydcbxjz+bn AIfy9LKP3j7d2OrzOh78ttSwoVlO5Y9E8sqMFnpLXtlSVHPSkqRK8Vbo/ mLHHWrca0N58T7AnF2GiYcixcBnQG8ForCc+cMj4VrhFL9ZCVbwev4sNy 9aw5INI8zO1LgZgsIVmX32sd9fK+lw9vyueC1gHi1WvcHI1Vh9VuLEI2d gVFkDLeQ8ZD7OrUeWTz1qOOyxKD3Wju+/FMMZy9YYbfcD0QSFKthyIbNo hfpMH2HI5VUIqU0mUwrUJUDLb+Ge2N/XQbEkOrhmWsSynhrs7zXvwj4xz Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10914"; a="906332" X-IronPort-AV: E=Sophos;i="6.04,251,1695711600"; d="scan'208";a="906332" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orvoesa104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Dec 2023 21:58:52 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10914"; a="888807737" X-IronPort-AV: E=Sophos;i="6.04,251,1695711600"; d="scan'208";a="888807737" Received: from vkasired-desk2.fm.intel.com ([10.105.128.132]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Dec 2023 21:58:50 -0800 From: Vivek Kasireddy To: dri-devel@lists.freedesktop.org, linux-mm@kvack.org Cc: Vivek Kasireddy , Shuah Khan , David Hildenbrand , Daniel Vetter , Mike Kravetz , Hugh Dickins , Peter Xu , Jason Gunthorpe , Gerd Hoffmann , Dongwon Kim , Junxiao Chang Subject: [PATCH v6 5/5] selftests/dma-buf/udmabuf: Add tests to verify data after page migration Date: Mon, 4 Dec 2023 21:35:09 -0800 Message-Id: <20231205053509.2342169-6-vivek.kasireddy@intel.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20231205053509.2342169-1-vivek.kasireddy@intel.com> References: <20231205053509.2342169-1-vivek.kasireddy@intel.com> MIME-Version: 1.0 X-Rspamd-Queue-Id: C7FC012000A X-Rspam-User: X-Stat-Signature: 4qsc6nj3koeg9ysc1u6hyh5k1hsy4zxy X-Rspamd-Server: rspam03 X-HE-Tag: 1701755937-125357 X-HE-Meta: U2FsdGVkX1+NqTpdn2Xyu3jVQ1CGGEo4xZmOHUlih2jXsWKEYrcfxcnP/bfAWWfp8VOoE5DfTe/fhq0+98T8UTGpHS0hTmf/+aehmxelRh/BFHmkXn3oaazlNkQExHkUrbQ19sXivtiqIzcbH4m9xwMynT2IE7bchdsdUkZe4PQzLtQebaOdOEFPgsSbeT7UCLYdjgcbcn5E7ti5McmKlK6G/2DW0bBWS4hUlUBdJ2HjKELL/YkY9fZ5Kqr/etkSZYA3UGoFm6L5sr5X8ABDEfcee67eOjBMCxYUGMWNj0MBn05uSdSmNV6RRojk6CX2F0hEr0R+hsjoIvyik5bxpoHki/TXsj+bKRIPHoC3jWXTH3d4/YgkS5WHaJbXrxQ8OBTYiGVKc5U/FPEWLM8bSYjzPx+xXMXaE3yxqGrbEShVj0+Y8bPWdi+O7fBPz1b8gVMilS+6c4RbMdLkLJy5+SBrxqn8CF3vKU3njLbyXn2jiSEtBJkAiTfkCzRl1LLjYm+RaVD09RfwJlE2ciD2CrHoWm8fxoXdJX/881x9JqLpXhPEVQa7vIyGLcD0jv+xtZEFRvcNf8gjcEL8/YiYH5kbJElO3FXcWV+emJY8Tkz3aL1Y33xW96iCnBikt+yxq76u9k1U5mOdz+hHG0jx7zXplyt18eM+uhHN139qB889tE/3P/7Vd03sA7vb9+cFJGbgFMfYhUC9tMOvNRiamn5Lh/qkXzHPmzXTgJ7UP0DlFqkR4huV8ZNmBIB5fGNL/a+d7sOVbXgASW0J4HtUtWtPRFsJal//sFw8tZ1c7HcdQZ83gcBxsVESzcSHPPx3LPD0dxwopxsPogW7ijyYWdaiTsTMx+mBx6YdyLczDAnNzuGAsdvPQ7jYZrxhBwxr2Hhp9baePzz4A/RGTyPpcjfFmI+h8UfCl1VsHElyuub/71nN9jUkyqh1f/aWfMWQRSA/M12m/fCB6E9WegB 5aHUTqGn 0LyXaLwBjZoBpcxVR54dGpOFyHDq84xER3/6G3PVFgwuZ8SMz7toxd+DokScfDu11EjN9znElP88i25gl9Y1fEGWWcpuzO+IQN8h8Dok5AlwV6i5PWo4xyw3/nM5yjO1oWcYxJd0oedk8usf9JaK6swIvSJXLGgOfEkjSEguWjdAnQ88DCupXOE98d8FxAIlo+PgUbrI9DAcHck4uPXq9xWUvOdAVeXoVoyxQ7XmM3sMWvsVP+PwCc4tXhZV66A1XVwYwUM1i+mjLODNE460N5SiJ7qCmm1H6Nc2sJDGT/Gfn2ljRcywMQlsa5Q== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Since the memfd pages associated with a udmabuf may be migrated as part of udmabuf create, we need to verify the data coherency after successful migration. The new tests added in this patch try to do just that using 4k sized pages and also 2 MB sized huge pages for the memfd. Successful completion of the tests would mean that there is no disconnect between the memfd pages and the ones associated with a udmabuf. And, these tests can also be augmented in the future to test newer udmabuf features (such as handling memfd hole punch). Cc: Shuah Khan Cc: David Hildenbrand Cc: Daniel Vetter Cc: Mike Kravetz Cc: Hugh Dickins Cc: Peter Xu Cc: Jason Gunthorpe Cc: Gerd Hoffmann Cc: Dongwon Kim Cc: Junxiao Chang Based-on-patch-by: Mike Kravetz Signed-off-by: Vivek Kasireddy --- .../selftests/drivers/dma-buf/udmabuf.c | 151 +++++++++++++++++- 1 file changed, 147 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/drivers/dma-buf/udmabuf.c b/tools/testing/selftests/drivers/dma-buf/udmabuf.c index c812080e304e..d76c813fe652 100644 --- a/tools/testing/selftests/drivers/dma-buf/udmabuf.c +++ b/tools/testing/selftests/drivers/dma-buf/udmabuf.c @@ -9,26 +9,132 @@ #include #include #include +#include #include #include +#include #include #include #define TEST_PREFIX "drivers/dma-buf/udmabuf" #define NUM_PAGES 4 +#define NUM_ENTRIES 4 +#define MEMFD_SIZE 1024 /* in pages */ -static int memfd_create(const char *name, unsigned int flags) +static unsigned int page_size; + +static int create_memfd_with_seals(off64_t size, bool hpage) +{ + int memfd, ret; + unsigned int flags = MFD_ALLOW_SEALING; + + if (hpage) + flags |= MFD_HUGETLB; + + memfd = memfd_create("udmabuf-test", flags); + if (memfd < 0) { + printf("%s: [skip,no-memfd]\n", TEST_PREFIX); + exit(77); + } + + ret = fcntl(memfd, F_ADD_SEALS, F_SEAL_SHRINK); + if (ret < 0) { + printf("%s: [skip,fcntl-add-seals]\n", TEST_PREFIX); + exit(77); + } + + ret = ftruncate(memfd, size); + if (ret == -1) { + printf("%s: [FAIL,memfd-truncate]\n", TEST_PREFIX); + exit(1); + } + + return memfd; +} + +static int create_udmabuf_list(int devfd, int memfd, off64_t memfd_size) +{ + struct udmabuf_create_list *list; + int ubuf_fd, i; + + list = malloc(sizeof(struct udmabuf_create_list) + + sizeof(struct udmabuf_create_item) * NUM_ENTRIES); + if (!list) { + printf("%s: [FAIL, udmabuf-malloc]\n", TEST_PREFIX); + exit(1); + } + + for (i = 0; i < NUM_ENTRIES; i++) { + list->list[i].memfd = memfd; + list->list[i].offset = i * (memfd_size / NUM_ENTRIES); + list->list[i].size = getpagesize() * NUM_PAGES; + } + + list->count = NUM_ENTRIES; + list->flags = UDMABUF_FLAGS_CLOEXEC; + ubuf_fd = ioctl(devfd, UDMABUF_CREATE_LIST, list); + free(list); + if (ubuf_fd < 0) { + printf("%s: [FAIL, udmabuf-create]\n", TEST_PREFIX); + exit(1); + } + + return ubuf_fd; +} + +static void write_to_memfd(void *addr, off64_t size, char chr) +{ + int i; + + for (i = 0; i < size / page_size; i++) { + *((char *)addr + (i * page_size)) = chr; + } +} + +static void *mmap_fd(int fd, off64_t size) { - return syscall(__NR_memfd_create, name, flags); + void *addr; + + addr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + if (addr == MAP_FAILED) { + printf("%s: ubuf_fd mmap fail\n", TEST_PREFIX); + exit(1); + } + + return addr; +} + +static int compare_chunks(void *addr1, void *addr2, off64_t memfd_size) +{ + off64_t off; + int i = 0, j, k = 0, ret = 0; + char char1, char2; + + while (i < NUM_ENTRIES) { + off = i * (memfd_size / NUM_ENTRIES); + for (j = 0; j < NUM_PAGES; j++, k++) { + char1 = *((char *)addr1 + off + (j * getpagesize())); + char2 = *((char *)addr2 + (k * getpagesize())); + if (char1 != char2) { + ret = -1; + goto err; + } + } + i++; + } +err: + munmap(addr1, memfd_size); + munmap(addr2, NUM_ENTRIES * NUM_PAGES * getpagesize()); + return ret; } int main(int argc, char *argv[]) { struct udmabuf_create create; int devfd, memfd, buf, ret; - off_t size; - void *mem; + off64_t size; + void *addr1, *addr2; devfd = open("/dev/udmabuf", O_RDWR); if (devfd < 0) { @@ -90,6 +196,9 @@ int main(int argc, char *argv[]) } /* should work */ + page_size = getpagesize(); + addr1 = mmap_fd(memfd, size); + write_to_memfd(addr1, size, 'a'); create.memfd = memfd; create.offset = 0; create.size = size; @@ -98,6 +207,40 @@ int main(int argc, char *argv[]) printf("%s: [FAIL,test-4]\n", TEST_PREFIX); exit(1); } + munmap(addr1, size); + close(buf); + close(memfd); + + /* should work (migration of 4k size pages)*/ + size = MEMFD_SIZE * page_size; + memfd = create_memfd_with_seals(size, false); + addr1 = mmap_fd(memfd, size); + write_to_memfd(addr1, size, 'a'); + buf = create_udmabuf_list(devfd, memfd, size); + addr2 = mmap_fd(buf, NUM_PAGES * NUM_ENTRIES * getpagesize()); + write_to_memfd(addr1, size, 'b'); + ret = compare_chunks(addr1, addr2, size); + if (ret < 0) { + printf("%s: [FAIL,test-5]\n", TEST_PREFIX); + exit(1); + } + close(buf); + close(memfd); + + /* should work (migration of 2MB size huge pages)*/ + page_size = getpagesize() * 512; /* 2 MB */ + size = MEMFD_SIZE * page_size; + memfd = create_memfd_with_seals(size, true); + addr1 = mmap_fd(memfd, size); + write_to_memfd(addr1, size, 'a'); + buf = create_udmabuf_list(devfd, memfd, size); + addr2 = mmap_fd(buf, NUM_PAGES * NUM_ENTRIES * getpagesize()); + write_to_memfd(addr1, size, 'b'); + ret = compare_chunks(addr1, addr2, size); + if (ret < 0) { + printf("%s: [FAIL,test-6]\n", TEST_PREFIX); + exit(1); + } fprintf(stderr, "%s: ok\n", TEST_PREFIX); close(buf);