From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A3214C432BE for ; Tue, 17 Aug 2021 06:40:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8644B60F11 for ; Tue, 17 Aug 2021 06:40:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238198AbhHQGk5 (ORCPT ); Tue, 17 Aug 2021 02:40:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60888 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238083AbhHQGkw (ORCPT ); Tue, 17 Aug 2021 02:40:52 -0400 Received: from mail-qv1-xf35.google.com (mail-qv1-xf35.google.com [IPv6:2607:f8b0:4864:20::f35]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BD540C0613CF for ; Mon, 16 Aug 2021 23:40:19 -0700 (PDT) Received: by mail-qv1-xf35.google.com with SMTP id v1so10628571qva.7 for ; Mon, 16 Aug 2021 23:40:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cRkVjx/m/ZP7wkwJ5qI8rhrUyfQCjzhFVvmz8cSCxP8=; b=C4sWBdDJSqae8vspARx7nMdpN9luHOk1ZD82qZKykB2/7MsViI7uiTMrzvX2Zl36Dj enP1WWEKt6sU1HOqS4NCdTvhjHQ+FhlxV3eMX88J6KOxK10UE5uNON8cP+oQrnChPPUy 3kPaVtzqqKp1goVEQs35IDXUsWXvGnGHBniOh/L8g7JcGRsSRHvU5lxm14W7XD71VU2l YtGBx8s6btNknpi1AbRiQNvHUTIjt/MUrtS00syNZNHTTHcz1cr235EbtWXlrZvTIVww EhTgDxx+AiZvridZc5HfiZcOJ6ss/2cUMRzpFSwKFQjSvKfhbX2m4GyIDldsjE10NW0I PTDg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cRkVjx/m/ZP7wkwJ5qI8rhrUyfQCjzhFVvmz8cSCxP8=; b=in05UE1yDVFs966I2Ms5EHcAHc0hRkKEMRgI6a8rWiVyFN2CWMbIEzlquzvqplblzl 8AgJqknOoazPsf9jbsSiiHn9lgDdEzKW7IUipIEu+Ebrd24M/oENHIWFcK2aLZ/rSYQz Tqq+HTM9Al53bBro2FTjR8Ud13QAzmC069OSF5c5wCUNBkL0mK5kE6389igyeYQT89+g 3wPQOYZyyouxtMYW7RDLXMfAIWvKNwu9cZTtFMk2lXeGWluE+3Sieh2Z4MKMNP8QCiv+ nIDMXJIhmC5ZNuck0L0KPuSdYUxX3vYZeEB0ftIG0qEC12Jv0HKn8sWLP1FWNdnxlZtS 716A== X-Gm-Message-State: AOAM530V86g5JVHQe9BWA2rVbAe4ueC3NNZOrhrPHqkPIKbiMXaE2ula H8hThxLdbSGt+vHG9143Ld8= X-Google-Smtp-Source: ABdhPJxZIN9TyTwGCKgnZWtPJJoU1+X6lork2N9mz88vCS2jS4XhogUfJMEmDiNcbzyWFLmWpIDKKA== X-Received: by 2002:a0c:fe02:: with SMTP id x2mr1756234qvr.12.1629182418924; Mon, 16 Aug 2021 23:40:18 -0700 (PDT) Received: from LeoBras.redhat.com ([2804:431:c7f0:30b2:5c9e:50:88f3:269a]) by smtp.gmail.com with ESMTPSA id c11sm526938qth.29.2021.08.16.23.40.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Aug 2021 23:40:18 -0700 (PDT) From: Leonardo Bras To: Michael Ellerman , Benjamin Herrenschmidt , Paul Mackerras , Leonardo Bras , Alexey Kardashevskiy , Frederic Barrat , David Gibson , Nicolin Chen , kernel test robot Cc: linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 02/11] powerpc/kernel/iommu: Add new iommu_table_in_use() helper Date: Tue, 17 Aug 2021 03:39:20 -0300 Message-Id: <20210817063929.38701-3-leobras.c@gmail.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210817063929.38701-1-leobras.c@gmail.com> References: <20210817063929.38701-1-leobras.c@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Having a function to check if the iommu table has any allocation helps deciding if a tbl can be reset for using a new DMA window. It should be enough to replace all instances of !bitmap_empty(tbl...). iommu_table_in_use() skips reserved memory, so we don't need to worry about releasing it before testing. This causes iommu_table_release_pages() to become unnecessary, given it is only used to remove reserved memory for testing. Also, only allow storing reserved memory values in tbl if they are valid in the table, so there is no need to check it in the new helper. Signed-off-by: Leonardo Bras Reviewed-by: Alexey Kardashevskiy --- arch/powerpc/include/asm/iommu.h | 1 + arch/powerpc/kernel/iommu.c | 61 ++++++++++++++++---------------- 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h index deef7c94d7b6..bf3b84128525 100644 --- a/arch/powerpc/include/asm/iommu.h +++ b/arch/powerpc/include/asm/iommu.h @@ -154,6 +154,7 @@ extern int iommu_tce_table_put(struct iommu_table *tbl); */ extern struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid, unsigned long res_start, unsigned long res_end); +bool iommu_table_in_use(struct iommu_table *tbl); #define IOMMU_TABLE_GROUP_MAX_TABLES 2 diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 2af89a5e379f..ed98ad63633e 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -690,32 +690,24 @@ static void iommu_table_reserve_pages(struct iommu_table *tbl, if (tbl->it_offset == 0) set_bit(0, tbl->it_map); - tbl->it_reserved_start = res_start; - tbl->it_reserved_end = res_end; - - /* Check if res_start..res_end isn't empty and overlaps the table */ - if (res_start && res_end && - (tbl->it_offset + tbl->it_size < res_start || - res_end < tbl->it_offset)) - return; + if (res_start < tbl->it_offset) + res_start = tbl->it_offset; - for (i = tbl->it_reserved_start; i < tbl->it_reserved_end; ++i) - set_bit(i - tbl->it_offset, tbl->it_map); -} + if (res_end > (tbl->it_offset + tbl->it_size)) + res_end = tbl->it_offset + tbl->it_size; -static void iommu_table_release_pages(struct iommu_table *tbl) -{ - int i; + /* Check if res_start..res_end is a valid range in the table */ + if (res_start >= res_end) { + tbl->it_reserved_start = tbl->it_offset; + tbl->it_reserved_end = tbl->it_offset; + return; + } - /* - * In case we have reserved the first bit, we should not emit - * the warning below. - */ - if (tbl->it_offset == 0) - clear_bit(0, tbl->it_map); + tbl->it_reserved_start = res_start; + tbl->it_reserved_end = res_end; for (i = tbl->it_reserved_start; i < tbl->it_reserved_end; ++i) - clear_bit(i - tbl->it_offset, tbl->it_map); + set_bit(i - tbl->it_offset, tbl->it_map); } /* @@ -779,6 +771,22 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid, return tbl; } +bool iommu_table_in_use(struct iommu_table *tbl) +{ + unsigned long start = 0, end; + + /* ignore reserved bit0 */ + if (tbl->it_offset == 0) + start = 1; + end = tbl->it_reserved_start - tbl->it_offset; + if (find_next_bit(tbl->it_map, end, start) != end) + return true; + + start = tbl->it_reserved_end - tbl->it_offset; + end = tbl->it_size; + return find_next_bit(tbl->it_map, end, start) != end; +} + static void iommu_table_free(struct kref *kref) { struct iommu_table *tbl; @@ -795,10 +803,8 @@ static void iommu_table_free(struct kref *kref) iommu_debugfs_del(tbl); - iommu_table_release_pages(tbl); - /* verify that table contains no entries */ - if (!bitmap_empty(tbl->it_map, tbl->it_size)) + if (iommu_table_in_use(tbl)) pr_warn("%s: Unexpected TCEs\n", __func__); /* free bitmap */ @@ -1099,14 +1105,9 @@ int iommu_take_ownership(struct iommu_table *tbl) for (i = 0; i < tbl->nr_pools; i++) spin_lock_nest_lock(&tbl->pools[i].lock, &tbl->large_pool.lock); - iommu_table_release_pages(tbl); - - if (!bitmap_empty(tbl->it_map, tbl->it_size)) { + if (iommu_table_in_use(tbl)) { pr_err("iommu_tce: it_map is not empty"); ret = -EBUSY; - /* Undo iommu_table_release_pages, i.e. restore bit#0, etc */ - iommu_table_reserve_pages(tbl, tbl->it_reserved_start, - tbl->it_reserved_end); } else { memset(tbl->it_map, 0xff, sz); } -- 2.32.0