Received: by 10.223.176.5 with SMTP id f5csp1825652wra; Wed, 31 Jan 2018 12:11:41 -0800 (PST) X-Google-Smtp-Source: AH8x224rLlTTSU+f0naZuBnboHry1okreuv76yvwkglHbcEUvM44MJgXefdU55/ce+AMhOhhzJlX X-Received: by 2002:a17:902:20e3:: with SMTP id v32-v6mr30346291plg.405.1517429501531; Wed, 31 Jan 2018 12:11:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517429501; cv=none; d=google.com; s=arc-20160816; b=xYE9EpWBuycBfYypa0ykgu5Ji8WIWsBdiPrRTXPIXGBAXHtoeXClGPhKiJQUOOLxW5 6gvqlJOxiYlm5c8Q6UEiDuBh+nRsZakywicFi/o36foFKhCYZrJalGgI5naZLLOF+iXJ J83+4NgN9HzGr+v/32Pi/4wcYYaqvh/AhYx33GgelXxnH3FRtZ58rw679MpuvBnFEc2+ llK0BPTdhcDqwbbomxdm9LjW+Ukyr8wTsHdf7l6L868Ztmj2mwKnoDDTtK3ACVz1DgAI /LdMJJmnWc2PKubW6GzlNhMYdh3II9TCCdBxbqj/lFwg8tFGfl8Z3bUSdoDTzrsJmZmE /INg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:references:cc:to:from:subject:dkim-signature :arc-authentication-results; bh=5zD2QBYT1YpKu8KV/2lQCPmgCHSOWkK3potDQa3qJ0M=; b=CSY86DCsT+0eJLUKcXRqJc76K66qFljIrYp+AZgYyOi1FXKvw3VY3p+oQiiP75UNGZ sa1iqo1B80jBRJ5s8Ob09CkolLN2nGePgKDTuo/1vlNNioBkbrYHtQnc1Bhk2mjlq/Ik kXWwtpR/T39s35uW0XtvMbcJPwsITSAOeMsQnaqs/DQPwhfli3r2hFQS6Y8Xa6c5RY96 2G75rffmPeAsfavpIgguD4om+J075g0Upoe0bzk8QCTX+TTCanXX53ltxmXdJAHdf7+b 1ewwmBN6Dm4eSOfQcuU1dYZnLxnTCPoac52OhV6QqM37dSTJKu6s+RUxSRj2EBZDMSLD pjyA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=blDYCDOj; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y73si1929472pgd.341.2018.01.31.12.11.25; Wed, 31 Jan 2018 12:11:41 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=blDYCDOj; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751516AbeAaULB (ORCPT + 99 others); Wed, 31 Jan 2018 15:11:01 -0500 Received: from mail-pg0-f65.google.com ([74.125.83.65]:33356 "EHLO mail-pg0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750829AbeAaUK7 (ORCPT ); Wed, 31 Jan 2018 15:10:59 -0500 Received: by mail-pg0-f65.google.com with SMTP id u1so10958620pgr.0; Wed, 31 Jan 2018 12:10:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:from:to:cc:references:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=5zD2QBYT1YpKu8KV/2lQCPmgCHSOWkK3potDQa3qJ0M=; b=blDYCDOjKE4Cg0JSKIiGqeqltj0Bakfl8YwKTKc5Xgh3sFuZwNUqolhd8HMR5F+WdQ ASpB+mo8/FN6tcgmhiW2tD71pSZPbW2n3DEnhO29yXFTccMaWj9OxyBYTZ/bmHWGI9ja tpxdHJ6mB3E8JlGCOaDAoQQlBXykgr5DoVEGn33CHwitH9A8F/U8qI47g0FHWx2YyB5m Xo3kvYpLoRdpmf1njGdhpM3qgWMQ1S5iuwGmjcemJUGnJ/qVPQol95R5atAMeyawM6XX FtJY56PFUNhCAZmZUqxsf9vH4zv4w0N+F6SnYMl62wb59CMUAQ55AHXgZyeTyXj6APxR akjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:references:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=5zD2QBYT1YpKu8KV/2lQCPmgCHSOWkK3potDQa3qJ0M=; b=O2UsH788pdMgCBv/ghEXr9JAr0+ghsv8mPMakE37PrFpP6irSAnQTQy7aC0tTLYxCY RPbV7fTprVG6F4bze0fR+1X0t3CJH05qew/7dTS44z43ICIu05KdrNoAJWc51rcUCA/K C4FGnbmGuWpemnKPoQmDebJ/0lynJe9/dyy0zWrfseSkpKxlzhUEaBGlXnfh7caCBqzf Abh7ffEG2mXxSngAkNBf39AcuEZ63nH5gTCfA6TmhudQJJEdv4V1wrwwjrDeTx4PueEA ynVVPEUoZagTiJb3aceObf3R9LJ3iPNRBRfMSq9/xlwnft4HbBWPSdnrzbPitfTwTzLz idug== X-Gm-Message-State: AKwxytdbTRuesXzQM2n2Gm3p5DE2RJovO6///UvBRFoCBDrvlDT7knbM vUCoQ6fKxnMuAvEZYN+a6kDOxrvV X-Received: by 10.101.77.146 with SMTP id p18mr26645140pgq.75.1517429458403; Wed, 31 Jan 2018 12:10:58 -0800 (PST) Received: from [192.168.1.70] (c-73-93-215-6.hsd1.ca.comcast.net. [73.93.215.6]) by smtp.gmail.com with ESMTPSA id g74sm41107057pfd.73.2018.01.31.12.10.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 31 Jan 2018 12:10:57 -0800 (PST) Subject: Re: [PATCH] of: cache phandle nodes to decrease cost of of_find_node_by_phandle() From: Frank Rowand To: Rob Herring , cpandya@codeaurora.org Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org References: <1517429142-25727-1-git-send-email-frowand.list@gmail.com> Message-ID: <2c1eca16-42bb-5a00-8f2b-a4536712ab79@gmail.com> Date: Wed, 31 Jan 2018 12:10:56 -0800 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 MIME-Version: 1.0 In-Reply-To: <1517429142-25727-1-git-send-email-frowand.list@gmail.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Rob, Chintan, This patch resolves one of the issues that Rob had raised. The space for the phandle cache is freed after boot, instead of existing until shutdown. Chintan, can you please apply this patch and see how it impacts your boot time? The portion of the patch that removes code from resolver.c will fail on 4.9 because that code does not exist yet -- you can just remove that portion of the patch. -Frank On 01/31/18 12:05, frowand.list@gmail.com wrote: > From: Frank Rowand > > Create a cache of the nodes that contain a phandle property. Use this > cache to find the node for a given phandle value instead of scanning > the devicetree to find the node. If the phandle value is not found > in the cache, of_find_node_by_phandle() will fall back to the tree > scan algorithm. > > The cache is initialized in of_core_init(). > > The cache is freed via a late_initcall_sync(). > > Signed-off-by: Frank Rowand > --- > > Some of_find_by_phandle() calls may occur before the cache is > initialized or after it is freed. For example, for the qualcomm > qcom-apq8074-dragonboard, 11 calls occur before the initialization > and 80 occur after the cache is freed (out of 516 total calls.) > > > drivers/of/base.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++--- > drivers/of/of_private.h | 5 +++ > drivers/of/resolver.c | 21 ------------ > 3 files changed, 86 insertions(+), 25 deletions(-) > > diff --git a/drivers/of/base.c b/drivers/of/base.c > index 26618ba8f92a..c3091d0e391f 100644 > --- a/drivers/of/base.c > +++ b/drivers/of/base.c > @@ -95,10 +95,14 @@ int __weak of_node_to_nid(struct device_node *np) > } > #endif > > +static void of_populate_phandle_cache(void); > + > void __init of_core_init(void) > { > struct device_node *np; > > + of_populate_phandle_cache(); > + > /* Create the kset, and register existing nodes */ > mutex_lock(&of_mutex); > of_kset = kset_create_and_add("devicetree", NULL, firmware_kobj); > @@ -990,6 +994,72 @@ int of_modalias_node(struct device_node *node, char *modalias, int len) > } > EXPORT_SYMBOL_GPL(of_modalias_node); > > +phandle live_tree_max_phandle(void) > +{ > + struct device_node *node; > + phandle max_phandle; > + unsigned long flags; > + > + raw_spin_lock_irqsave(&devtree_lock, flags); > + max_phandle = 0; > + for_each_of_allnodes(node) { > + if (node->phandle != OF_PHANDLE_ILLEGAL && > + node->phandle > max_phandle) > + max_phandle = node->phandle; > + } > + raw_spin_unlock_irqrestore(&devtree_lock, flags); > + > + return max_phandle; > +} > + > +static struct device_node **phandle_cache; > +static u32 max_phandle_cache; > + > +static int __init of_free_phandle_cache(void) > +{ > + max_phandle_cache = 0; > + kfree(phandle_cache); > + phandle_cache = NULL; > + > + return 0; > +} > +late_initcall_sync(of_free_phandle_cache); > + > +static void of_populate_phandle_cache(void) > +{ > + unsigned long flags; > + phandle max_phandle; > + u32 nodes = 0; > + struct device_node *np; > + > + if (phandle_cache) > + return; > + > + max_phandle = live_tree_max_phandle(); > + > + raw_spin_lock_irqsave(&devtree_lock, flags); > + > + for_each_of_allnodes(np) > + nodes++; > + > + /* sanity cap for malformed tree */ > + if (max_phandle > nodes) > + max_phandle = nodes; > + > + phandle_cache = kzalloc((max_phandle + 1) * sizeof(*phandle_cache), > + GFP_KERNEL); > + > + for_each_of_allnodes(np) > + if (np->phandle != OF_PHANDLE_ILLEGAL && > + np->phandle <= max_phandle && > + np->phandle) > + phandle_cache[np->phandle] = np; > + > + max_phandle_cache = max_phandle; > + > + raw_spin_unlock_irqrestore(&devtree_lock, flags); > +} > + > /** > * of_find_node_by_phandle - Find a node given a phandle > * @handle: phandle of the node to find > @@ -999,16 +1069,23 @@ int of_modalias_node(struct device_node *node, char *modalias, int len) > */ > struct device_node *of_find_node_by_phandle(phandle handle) > { > - struct device_node *np; > + struct device_node *np = NULL; > unsigned long flags; > > if (!handle) > return NULL; > > raw_spin_lock_irqsave(&devtree_lock, flags); > - for_each_of_allnodes(np) > - if (np->phandle == handle) > - break; > + > + if (handle <= max_phandle_cache) > + np = phandle_cache[handle]; > + > + if (!np || np->phandle != handle) { > + for_each_of_allnodes(np) > + if (np->phandle == handle) > + break; > + } > + > of_node_get(np); > raw_spin_unlock_irqrestore(&devtree_lock, flags); > return np; > diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h > index 92a9a3687446..77005978d60a 100644 > --- a/drivers/of/of_private.h > +++ b/drivers/of/of_private.h > @@ -135,6 +135,11 @@ extern void __of_update_property_sysfs(struct device_node *np, > extern void __of_sysfs_remove_bin_file(struct device_node *np, > struct property *prop); > > +/* illegal phandle value (set when unresolved) */ > +#define OF_PHANDLE_ILLEGAL 0xdeadbeef > + > +extern phandle live_tree_max_phandle(void); > + > /* iterators for transactions, used for overlays */ > /* forward iterator */ > #define for_each_transaction_entry(_oft, _te) \ > diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c > index cfaeef5f6cb1..0384ce8fdc3b 100644 > --- a/drivers/of/resolver.c > +++ b/drivers/of/resolver.c > @@ -22,27 +22,6 @@ > > #include "of_private.h" > > -/* illegal phandle value (set when unresolved) */ > -#define OF_PHANDLE_ILLEGAL 0xdeadbeef > - > -static phandle live_tree_max_phandle(void) > -{ > - struct device_node *node; > - phandle phandle; > - unsigned long flags; > - > - raw_spin_lock_irqsave(&devtree_lock, flags); > - phandle = 0; > - for_each_of_allnodes(node) { > - if (node->phandle != OF_PHANDLE_ILLEGAL && > - node->phandle > phandle) > - phandle = node->phandle; > - } > - raw_spin_unlock_irqrestore(&devtree_lock, flags); > - > - return phandle; > -} > - > static void adjust_overlay_phandles(struct device_node *overlay, > int phandle_delta) > { >