From patchwork Tue Dec 19 19:29:46 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Kim, Dongwon" X-Patchwork-Id: 10124115 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 DA8426019C for ; Tue, 19 Dec 2017 19:39:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C8D432924D for ; Tue, 19 Dec 2017 19:39:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BDA2529559; Tue, 19 Dec 2017 19:39:08 +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=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 674C02924D for ; Tue, 19 Dec 2017 19:39:08 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1A7BB6E378; Tue, 19 Dec 2017 19:36:58 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2CE6A6E35A for ; Tue, 19 Dec 2017 19:36:48 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 19 Dec 2017 11:36:47 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.45,428,1508828400"; d="scan'208";a="4018580" Received: from downor-z87x-ud5h.fm.intel.com ([10.1.122.11]) by orsmga007.jf.intel.com with ESMTP; 19 Dec 2017 11:36:47 -0800 From: Dongwon Kim To: linux-kernel@vger.kernel.org Subject: [RFC PATCH 30/60] hyper_dmabuf: free already mapped pages when error happens Date: Tue, 19 Dec 2017 11:29:46 -0800 Message-Id: <1513711816-2618-30-git-send-email-dongwon.kim@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1513711816-2618-1-git-send-email-dongwon.kim@intel.com> References: <1513711816-2618-1-git-send-email-dongwon.kim@intel.com> MIME-Version: 1.0 Cc: xen-devel@lists.xenproject.org, mateuszx.potrola@intel.com, dri-devel@lists.freedesktop.org, dongwon.kim@intel.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Mateusz Polrola It is needed to freeing already-mapped pages if it gets error before finishing mapping all pages. Signed-off-by: Dongwon Kim --- .../xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c | 43 +++++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c b/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c index c03e5a0..524f75c 100644 --- a/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c +++ b/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_shm.c @@ -255,7 +255,7 @@ struct page ** hyper_dmabuf_xen_map_shared_pages(int lvl3_gref, int domid, int n if (lvl3_map_ops.status) { dev_err(hyper_dmabuf_private.device, "HYPERVISOR map grant ref failed status = %d", lvl3_map_ops.status); - return NULL; + goto error_cleanup_lvl3; } else { lvl3_unmap_ops.handle = lvl3_map_ops.handle; } @@ -263,7 +263,7 @@ struct page ** hyper_dmabuf_xen_map_shared_pages(int lvl3_gref, int domid, int n /* Map all second level pages */ if (gnttab_alloc_pages(n_lvl2_grefs, lvl2_table_pages)) { dev_err(hyper_dmabuf_private.device, "Cannot allocate pages\n"); - return NULL; + goto error_cleanup_lvl3; } for (i = 0; i < n_lvl2_grefs; i++) { @@ -277,6 +277,9 @@ struct page ** hyper_dmabuf_xen_map_shared_pages(int lvl3_gref, int domid, int n if (gnttab_unmap_refs(&lvl3_unmap_ops, NULL, &lvl3_table_page, 1)) { dev_err(hyper_dmabuf_private.device, "xen: cannot unmap top level page\n"); return NULL; + } else { + /* Mark that page was unmapped */ + lvl3_unmap_ops.handle = -1; } if (gnttab_map_refs(lvl2_map_ops, NULL, lvl2_table_pages, n_lvl2_grefs)) { @@ -290,7 +293,7 @@ struct page ** hyper_dmabuf_xen_map_shared_pages(int lvl3_gref, int domid, int n dev_err(hyper_dmabuf_private.device, "HYPERVISOR map grant ref failed status = %d", lvl2_map_ops[i].status); - return NULL; + goto error_cleanup_lvl2; } else { lvl2_unmap_ops[i].handle = lvl2_map_ops[i].handle; } @@ -298,7 +301,7 @@ struct page ** hyper_dmabuf_xen_map_shared_pages(int lvl3_gref, int domid, int n if (gnttab_alloc_pages(nents, data_pages)) { dev_err(hyper_dmabuf_private.device, "Cannot allocate pages\n"); - return NULL; + goto error_cleanup_lvl2; } k = 0; @@ -343,6 +346,11 @@ struct page ** hyper_dmabuf_xen_map_shared_pages(int lvl3_gref, int domid, int n n_lvl2_grefs)) { dev_err(hyper_dmabuf_private.device, "Cannot unmap 2nd level refs\n"); return NULL; + } else { + /* Mark that pages were unmapped */ + for (i = 0; i < n_lvl2_grefs; i++) { + lvl2_unmap_ops[i].handle = -1; + } } for (i = 0; i < nents; i++) { @@ -350,7 +358,7 @@ struct page ** hyper_dmabuf_xen_map_shared_pages(int lvl3_gref, int domid, int n dev_err(hyper_dmabuf_private.device, "HYPERVISOR map grant ref failed status = %d\n", data_map_ops[i].status); - return NULL; + goto error_cleanup_data; } else { data_unmap_ops[i].handle = data_map_ops[i].handle; } @@ -369,6 +377,31 @@ struct page ** hyper_dmabuf_xen_map_shared_pages(int lvl3_gref, int domid, int n dev_dbg(hyper_dmabuf_private.device, "%s exit\n", __func__); return data_pages; + +error_cleanup_data: + gnttab_unmap_refs(data_unmap_ops, NULL, data_pages, + nents); + + gnttab_free_pages(nents, data_pages); + +error_cleanup_lvl2: + if (lvl2_unmap_ops[0].handle != -1) + gnttab_unmap_refs(lvl2_unmap_ops, NULL, lvl2_table_pages, + n_lvl2_grefs); + gnttab_free_pages(n_lvl2_grefs, lvl2_table_pages); + +error_cleanup_lvl3: + if (lvl3_unmap_ops.handle != -1) + gnttab_unmap_refs(&lvl3_unmap_ops, NULL, &lvl3_table_page, 1); + gnttab_free_pages(1, &lvl3_table_page); + + kfree(lvl2_table_pages); + kfree(lvl2_map_ops); + kfree(lvl2_unmap_ops); + kfree(data_map_ops); + + + return NULL; } int hyper_dmabuf_xen_unmap_shared_pages(void **refs_info, int nents) {