From patchwork Mon May 26 09:12:52 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sughosh Ganu X-Patchwork-Id: 892610 Delivered-To: patch@linaro.org Received: by 2002:a5d:6e53:0:b0:3a3:61c9:c5d4 with SMTP id j19csp1103917wrz; Mon, 26 May 2025 02:14:00 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCXoaoCHbo5/cGaaWiPnwyNg1t9njg0wbRdGW4TUV7nT3tlm9O8/U10Luq68LTSr+548HBfE7w==@linaro.org X-Google-Smtp-Source: AGHT+IEfuU5YlgI1ypEuaNGyoW3wovHnV/XvNuYeyJaMQyqh79Ytw8XmV9oFIlB94l+ZBh2LkKTg X-Received: by 2002:a17:907:7f8a:b0:ad5:1d16:27e2 with SMTP id a640c23a62f3a-ad85b0a5295mr744652466b.31.1748250840446; Mon, 26 May 2025 02:14:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1748250840; cv=none; d=google.com; s=arc-20240605; b=TwliA3GijxZ2gLUDe1fT0m8aE+/WTW4oklhhFE7nd8Q+IvpP9GfiAlsb8871BQjVS7 cGXhqVs0udXFwnnOiqafKKGsiuneyH7RrmQKGjI+QkCjdUs1UDDXORSeQqB5ERNktk+A LLXEs9j4fi1vWrXKrRLgng2F+40GOZNNKlir0TgRSkVnlBQUqKDytH4unfunFJxrR40E jPxQ3St1OhqyrIWmpRnc+LGpPYKLjW7Y8ayU3Pxu0FfXyGS8BgVN/CMbmCowXEClhLWz 4zo5blqRzpJuCDscKrJFn0TE5dHZdPqr3cQ29Mxw8v2vAJ7/ekNkIe9B6ggqsY5r2zxb ChIw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from; bh=sDpYhdIrVlCUIej0oOZ5ORkp92oxY9DYTl1TuWSouec=; fh=OQsgrM7lYcbKid/8QRKDrRnr3aZuZ+FGeYy6ua/5St0=; b=hkftN9uiiWIZqzH5DOkkupq4dbMNHuOcThKCe2fXYJJGHSZR7sGsp7sDutC2Bvy+1j u8Y5KiY9FMmfop4viWY9fj4LiOfxin5o0vw/d9EUVvnxVu3Q+hYHCESRU1kKHpGXqXsC SlsRVOE9sLQry4A5zD9WQ9yLUb2GKp4xnVsDRL473n1ri7/c7RUtbqyGjzZ959G7zq5U ChiCY/63aAOUKRXWlmolEE7Tvjc/ZKmrbKFzg/bQjJSt4ZTS1XsxzeTQCtUIe+yUH7Dq GnV8hq/oQA+TuZrXp979csqQQXow0KD7HPCC7Sfdft3LQBzok91ZiwT3rY+sMtTDRg9m Zudg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id a640c23a62f3a-ad52d4df1f3si1627700266b.482.2025.05.26.02.14.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 May 2025 02:14:00 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 84FA782DBC; Mon, 26 May 2025 11:13:34 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Received: by phobos.denx.de (Postfix, from userid 109) id CE0EA82D4E; Mon, 26 May 2025 11:13:33 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE,SPF_SOFTFAIL autolearn=no autolearn_force=no version=3.4.2 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by phobos.denx.de (Postfix) with ESMTP id 8BC8483043 for ; Mon, 26 May 2025 11:13:31 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=fail smtp.mailfrom=sughosh.ganu@linaro.org Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 75DCC153B; Mon, 26 May 2025 02:13:15 -0700 (PDT) Received: from a079122.blr.arm.com (a079122.arm.com [10.164.21.38]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id BEA563F673; Mon, 26 May 2025 02:13:27 -0700 (PDT) From: Sughosh Ganu To: u-boot@lists.denx.de Cc: Ilias Apalodimas , Tom Rini , Casey Connolly , Neil Armstrong , Mark Kettenis , Weijie Gao , Heinrich Schuchardt , Simon Glass , Sughosh Ganu Subject: [PATCH v3 5/6] lmb: use a single function to check for allocation and reservation requests Date: Mon, 26 May 2025 14:42:52 +0530 Message-Id: <20250526091253.400802-6-sughosh.ganu@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250526091253.400802-1-sughosh.ganu@linaro.org> References: <20250526091253.400802-1-sughosh.ganu@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean The functions that handle allocation requests check if a region of memory overlaps with a used region. This is done through lmb_overlaps_region(). Similar checks are done for reservation requests made to the LMB module, where the caller asks specifically for a particular region of memory. These checks are being done through lmb_can_reserve_region(). There are subtle differences in the checking needed for allocation requests, as against reservation requests. In the former, it is only needed to be checked if a region is overlapping with an existing used region, and return as soon as an overlap is found. For reservation request checks, because U-Boot allows for re-use of in-use regions with a particular memory attribute, this check has to iterate through all the regions that might overlap with the requested region, and then check that the necessary conditions are met to allow for the overlap. Combine these two checks in a single function, lmb_overlap_checks() as both lmb_overlaps_region() and lmb_can_reserve_region() are pretty similar otherwise. Signed-off-by: Sughosh Ganu Reviewed-by: Ilias Apalodimas --- Changes since V2: * New patch based on suggestion from Ilias lib/lmb.c | 84 +++++++++++++++++++++++++++---------------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/lib/lmb.c b/lib/lmb.c index 9986b38168a..fa6bdac2b3e 100644 --- a/lib/lmb.c +++ b/lib/lmb.c @@ -317,8 +317,34 @@ static long _lmb_free(struct alist *lmb_rgn_lst, phys_addr_t base, rgn[i].flags); } -static long lmb_overlaps_region(struct alist *lmb_rgn_lst, phys_addr_t base, - phys_size_t size) +/** + * lmb_overlap_checks() - perform checks to see if region can be allocated or reserved + * @lmb_rgn_lst: list of LMB regions + * @base: base address of region to be checked + * @size: size of region to be checked + * @flags: flag of the region to be checked (only for reservation requests) + * @alloc: if checks are to be done for allocation or reservation request + * + * Check if the region passed to the function overlaps with any one of + * the regions of the passed lmb region list. + * + * If the @alloc flag is set to true, this check stops as soon an + * overlapping region is found. The function can also be called to + * check if a reservation request can be satisfied, by setting + * @alloc to false. In that case, the function then iterates through + * all the regions in the list passed to ensure that the requested + * region does not overlap with any existing regions. An overlap is + * allowed only when the flag of the requested region and the existing + * region is LMB_NONE. + * + * Return: index of the overlapping region, -1 if no overlap is found + * + * When the function is called for a reservation request check, -1 will + * also be returned when there is an allowed overlap, i.e. requested + * region and existing regions have flags as LMB_NONE. + */ +static long lmb_overlap_checks(struct alist *lmb_rgn_lst, phys_addr_t base, + phys_size_t size, u32 flags, bool alloc) { unsigned long i; struct lmb_region *rgn = lmb_rgn_lst->data; @@ -326,9 +352,12 @@ static long lmb_overlaps_region(struct alist *lmb_rgn_lst, phys_addr_t base, for (i = 0; i < lmb_rgn_lst->count; i++) { phys_addr_t rgnbase = rgn[i].base; phys_size_t rgnsize = rgn[i].size; + u32 rgnflags = rgn[i].flags; - if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) - break; + if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) { + if (alloc || flags != LMB_NONE || flags != rgnflags) + break; + } } return (i < lmb_rgn_lst->count) ? i : -1; @@ -390,7 +419,8 @@ phys_addr_t io_lmb_alloc(struct lmb *io_lmb, phys_size_t size, ulong align) base = ALIGN_DOWN(lmbbase + lmbsize - size, align); while (base && lmbbase <= base) { - rgn = lmb_overlaps_region(&io_lmb->used_mem, base, size); + rgn = lmb_overlap_checks(&io_lmb->used_mem, base, size, + LMB_NOOVERWRITE, true); if (rgn < 0) { /* This area isn't reserved, take it */ if (lmb_add_region_flags(&io_lmb->used_mem, base, @@ -488,45 +518,12 @@ void lmb_dump_all(void) #endif } -/** - * lmb_can_reserve_region() - check if the region can be reserved - * @base: base address of region to be reserved - * @size: size of region to be reserved - * @flags: flag of the region to be reserved - * - * Go through all the reserved regions and ensure that the requested - * region does not overlap with any existing regions. An overlap is - * allowed only when the flag of the request region and the existing - * region is LMB_NONE. - * - * Return: true if region can be reserved, false otherwise - */ -static bool lmb_can_reserve_region(phys_addr_t base, phys_size_t size, - u32 flags) -{ - uint i; - struct lmb_region *lmb_reserved = lmb.used_mem.data; - - for (i = 0; i < lmb.used_mem.count; i++) { - u32 rgnflags = lmb_reserved[i].flags; - phys_addr_t rgnbase = lmb_reserved[i].base; - phys_size_t rgnsize = lmb_reserved[i].size; - - if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) { - if (flags != LMB_NONE || flags != rgnflags) - return false; - } - } - - return true; -} - static long lmb_reserve(phys_addr_t base, phys_size_t size, u32 flags) { long ret = 0; struct alist *lmb_rgn_lst = &lmb.used_mem; - if (!lmb_can_reserve_region(base, size, flags)) + if (lmb_overlap_checks(lmb_rgn_lst, base, size, flags, false) != -1) return -EEXIST; ret = lmb_add_region_flags(lmb_rgn_lst, base, size, flags); @@ -698,7 +695,8 @@ static int _lmb_alloc_base(phys_size_t size, ulong align, } while (base && lmbbase <= base) { - rgn = lmb_overlaps_region(&lmb.used_mem, base, size); + rgn = lmb_overlap_checks(&lmb.used_mem, base, size, + LMB_NOOVERWRITE, true); if (rgn < 0) { /* This area isn't reserved, take it */ if (lmb_add_region_flags(&lmb.used_mem, base, @@ -733,7 +731,8 @@ static int _lmb_alloc_addr(phys_addr_t base, phys_size_t size, u32 flags) struct lmb_region *lmb_memory = lmb.available_mem.data; /* Check if the requested address is in one of the memory regions */ - rgn = lmb_overlaps_region(&lmb.available_mem, base, size); + rgn = lmb_overlap_checks(&lmb.available_mem, base, size, + LMB_NOOVERWRITE, true); if (rgn >= 0) { /* * Check if the requested end address is in the same memory @@ -788,7 +787,8 @@ phys_size_t lmb_get_free_size(phys_addr_t addr) struct lmb_region *lmb_memory = lmb.available_mem.data; /* check if the requested address is in the memory regions */ - rgn = lmb_overlaps_region(&lmb.available_mem, addr, 1); + rgn = lmb_overlap_checks(&lmb.available_mem, addr, 1, LMB_NOOVERWRITE, + true); if (rgn >= 0) { for (i = 0; i < lmb.used_mem.count; i++) { if (addr < lmb_used[i].base) {