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 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1B5C3C5B552 for ; Fri, 30 May 2025 10:47:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:CC:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=6PT0MJjr6h+sjKtj45n5Ffv1RGeDB0XEv19iMD9iMQI=; b=dhFf/qq4jXAf+5sZ1ud5qfJcBg 3QZWjzclDI1IkV3Oy1AVHoEFC4v16aXcQJfmkHPtP/bw/dzYrdGwdCSlsdik0GkZMaJAQ9hwKfn9i lNJJf75sOLTzdsTMgBTBTq2tOrpq44j+JT4T7jzxves994KCkc4E6c+SY4Txn2slxadJgmKIZQl8k SMYnPuNzzD7wpVD6nhts9r2L/OBkkqvvllUoAQEFp+iJOgxD/AWGu67UY2zNTrs8HJx69D+NtFHCo VmK6xwm+JxO/g/KkLkyt6ENgLQh5VJD51HwSLiwIxpL8zlxl+Z0Evj6tCxMJqH1i24ydrK5WDEOMh N9FS7ihA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1uKxGr-00000000KKu-0VIT; Fri, 30 May 2025 10:47:29 +0000 Received: from fllvem-ot03.ext.ti.com ([198.47.19.245]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1uKxDo-00000000JvL-1EYe for linux-arm-kernel@lists.infradead.org; Fri, 30 May 2025 10:44:22 +0000 Received: from lelvem-sh02.itg.ti.com ([10.180.78.226]) by fllvem-ot03.ext.ti.com (8.15.2/8.15.2) with ESMTP id 54UAiEwv3855647; Fri, 30 May 2025 05:44:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1748601854; bh=6PT0MJjr6h+sjKtj45n5Ffv1RGeDB0XEv19iMD9iMQI=; h=Date:From:To:CC:Subject:References:In-Reply-To; b=jG22c/7vTLxuFatEBkh800+/XGXG4wsKFtJdoJubj017uUYbfs6RvVmsbCcK+DX48 9QXiefzIvbpXHSFLZ49tr7cLGHWlVLLbvussUhfgQMJ6dzToSExsg6TEJB4/Mr6rRM PAsQS4uRpGCNNWvzcE407c3uG/oW6qicuImhjNsw= Received: from DLEE115.ent.ti.com (dlee115.ent.ti.com [157.170.170.26]) by lelvem-sh02.itg.ti.com (8.18.1/8.18.1) with ESMTPS id 54UAiEv02817456 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA256 bits=128 verify=FAIL); Fri, 30 May 2025 05:44:14 -0500 Received: from DLEE103.ent.ti.com (157.170.170.33) by DLEE115.ent.ti.com (157.170.170.26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Fri, 30 May 2025 05:44:13 -0500 Received: from lelvem-mr05.itg.ti.com (10.180.75.9) by DLEE103.ent.ti.com (157.170.170.33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Fri, 30 May 2025 05:44:13 -0500 Received: from localhost (lcpd911.dhcp.ti.com [172.24.227.226]) by lelvem-mr05.itg.ti.com (8.18.1/8.18.1) with ESMTP id 54UAiCng2997568; Fri, 30 May 2025 05:44:13 -0500 Date: Fri, 30 May 2025 16:14:12 +0530 From: Dhruva Gole To: Cristian Marussi , Sudeep Holla CC: Ulf Hansson , , , , , Dan Carpenter , Vincent Guittot , Vignesh Raghavendra , Subject: Re: [RFC PATCH] pmdomain: arm: scmi_pm_domain: Do lazy init as part of probe Message-ID: <20250530104412.cc73ewso5ydjhmsk@lcpd911> References: <20250530103527.2244951-1-d-gole@ti.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Disposition: inline In-Reply-To: <20250530103527.2244951-1-d-gole@ti.com> X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250530_034420_453554_7C5E222E X-CRM114-Status: GOOD ( 43.59 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org On May 30, 2025 at 16:05:27 +0530, Dhruva Gole wrote: > Optimize the SCMI power domain driver to only initialize domains that are > actually referenced in the device tree. Previously, the driver would > initialize all possible domains up to the maximum ID, which could lead to > unnecessary firmware calls and longer probe times. > > Key changes: > - Scan device tree to identify which power domains are actually referenced > - Use bitmap to track needed domains instead of initializing all > - Only perform state queries and initialization for referenced domains > - Maintain proper array sizing for power domain framework compatibility > - Keep full provider structure to support late binding > > This optimization reduces probe time and unnecessary firmware interactions > by only initializing power domains that are actually used in the system. > For example, in a system with 100 possible domains but only 3 referenced > in the device tree, we now only initialize those 3 domains instead of > all 100. > > Signed-off-by: Dhruva Gole > --- Adding Sudeep and a few others who I missed adding initially. > > Hi all, > The approach of doing a lazy init was briefly proposed in this [1] 2024 > Embedded Open Source talk. It was also brought up in the monthly ARM > SCMI meetings that take place and it didn't recieve too much opposition. > > This greatly helps to improve the boot time, and I have some data to > back this up as well. This[2] experiment was done on a TI AM62L SoC > (which is yet to make it upstream) to measure the time taken in the scmi > pm domain probe function when it does a full 0..N scmi pd init vs just > the ones being used in the device tree. > > If you have any feedback on this, please let me know. If not, I will go > ahead and post a "non-RFC" patch assuming everyone is mostly on board > with this. Also request other SCMI consumers to test this out as much as > possible to see if it breaks in any situations. > > [1] https://static.sched.com/hosted_files/eoss24/2f/ARM_SCMI_Primer_Dhruva_kamlesh.pdf > [2] https://gist.github.com/DhruvaG2000/75d6a4c31e817f56587537b022761c45 > > Applies cleanly on top of next-20250530, built and tested on top of the > same > > --- > > drivers/pmdomain/arm/scmi_pm_domain.c | 88 ++++++++++++++++++++------- > 1 file changed, 66 insertions(+), 22 deletions(-) > > diff --git a/drivers/pmdomain/arm/scmi_pm_domain.c b/drivers/pmdomain/arm/scmi_pm_domain.c > index 2a213c218126..8acbfe249ed2 100644 > --- a/drivers/pmdomain/arm/scmi_pm_domain.c > +++ b/drivers/pmdomain/arm/scmi_pm_domain.c > @@ -10,6 +10,8 @@ > #include > #include > #include > +#include > + > > static const struct scmi_power_proto_ops *power_ops; > > @@ -47,14 +49,20 @@ static int scmi_pd_power_off(struct generic_pm_domain *domain) > > static int scmi_pm_domain_probe(struct scmi_device *sdev) > { > - int num_domains, i; > struct device *dev = &sdev->dev; > - struct device_node *np = dev->of_node; > + struct device_node *np; > struct scmi_pm_domain *scmi_pd; > - struct genpd_onecell_data *scmi_pd_data; > - struct generic_pm_domain **domains; > + struct of_phandle_args args; > const struct scmi_handle *handle = sdev->handle; > struct scmi_protocol_handle *ph; > + struct genpd_onecell_data *scmi_pd_data; > + struct generic_pm_domain **domains; > + int max_id = -1; > + int index, num_domains; > + ktime_t start_time = ktime_get(); > + unsigned long *domain_ids; > + > + dev_err(dev, "Starting optimized SCMI power domain probe\n"); > > if (!handle) > return -ENODEV; > @@ -69,54 +77,90 @@ static int scmi_pm_domain_probe(struct scmi_device *sdev) > return num_domains; > } > > - scmi_pd = devm_kcalloc(dev, num_domains, sizeof(*scmi_pd), GFP_KERNEL); > - if (!scmi_pd) > + domain_ids = devm_bitmap_zalloc(dev, num_domains, GFP_KERNEL); > + if (!domain_ids) > return -ENOMEM; > > + /* Find referenced domain IDs and mark them in bitmap */ > + for_each_node_with_property(np, "power-domains") { > + index = 0; > + while (!of_parse_phandle_with_args(np, "power-domains", > + "#power-domain-cells", > + index, &args)) { > + if (args.args_count >= 1 && args.np == dev->of_node) { > + int id = args.args[0]; > + if (id < num_domains) { > + set_bit(id, domain_ids); > + max_id = max(max_id, id); > + dev_dbg(dev, "Found power domain reference %d from node %pOF\n", > + id, np); > + } > + } > + of_node_put(args.np); > + index++; > + } > + } > + > + if (max_id < 0) { > + dev_warn(dev, "No power domains referenced in device tree\n"); > + /* Create provider anyway as domains might be referenced later */ > + max_id = 0; > + } > + > + dev_warn(dev, "Highest referenced domain ID: %d\n", max_id); > + > scmi_pd_data = devm_kzalloc(dev, sizeof(*scmi_pd_data), GFP_KERNEL); > if (!scmi_pd_data) > return -ENOMEM; > > - domains = devm_kcalloc(dev, num_domains, sizeof(*domains), GFP_KERNEL); > + domains = devm_kcalloc(dev, max_id + 1, sizeof(*domains), GFP_KERNEL); > if (!domains) > return -ENOMEM; > > - for (i = 0; i < num_domains; i++, scmi_pd++) { > + scmi_pd = devm_kcalloc(dev, max_id + 1, sizeof(*scmi_pd), GFP_KERNEL); > + if (!scmi_pd) > + return -ENOMEM; > + > + /* Initialize only referenced domains */ > + for_each_set_bit(index, domain_ids, num_domains) { > u32 state; > > - if (power_ops->state_get(ph, i, &state)) { > - dev_warn(dev, "failed to get state for domain %d\n", i); > + if (power_ops->state_get(ph, index, &state)) { > + dev_err(dev, "Domain %d not available\n", index); > continue; > } > > - /* > - * Register the explicit power on request to the firmware so > - * that it is tracked as used by OSPM agent and not > - * accidentally turned off with OSPM's knowledge > - */ > - if (state == SCMI_POWER_STATE_GENERIC_ON) > - power_ops->state_set(ph, i, state); > + dev_warn(dev, "Initializing referenced domain %d\n", index); > > - scmi_pd->domain = i; > + scmi_pd->domain = index; > scmi_pd->ph = ph; > - scmi_pd->name = power_ops->name_get(ph, i); > + scmi_pd->name = power_ops->name_get(ph, index); > scmi_pd->genpd.name = scmi_pd->name; > scmi_pd->genpd.power_off = scmi_pd_power_off; > scmi_pd->genpd.power_on = scmi_pd_power_on; > scmi_pd->genpd.flags = GENPD_FLAG_ACTIVE_WAKEUP; > > + if (state == SCMI_POWER_STATE_GENERIC_ON) { > + dev_warn(dev, "Domain %d is ON, registering state\n", index); > + power_ops->state_set(ph, index, state); > + } > + > pm_genpd_init(&scmi_pd->genpd, NULL, > state == SCMI_POWER_STATE_GENERIC_OFF); > > - domains[i] = &scmi_pd->genpd; > + domains[index] = &scmi_pd->genpd; > + scmi_pd++; > } > > scmi_pd_data->domains = domains; > - scmi_pd_data->num_domains = num_domains; > + scmi_pd_data->num_domains = max_id + 1; > > dev_set_drvdata(dev, scmi_pd_data); > > - return of_genpd_add_provider_onecell(np, scmi_pd_data); > + dev_err(dev, "SCMI power domains probe completed in %lld us\n", > + ktime_us_delta(ktime_get(), start_time)); > + > + return of_genpd_add_provider_onecell(dev->of_node, scmi_pd_data); > } > > static void scmi_pm_domain_remove(struct scmi_device *sdev) > -- > 2.34.1 > -- Best regards, Dhruva Gole Texas Instruments Incorporated