From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933054AbcASKvY (ORCPT ); Tue, 19 Jan 2016 05:51:24 -0500 Received: from mailout2.w1.samsung.com ([210.118.77.12]:29945 "EHLO mailout2.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932680AbcASKvV (ORCPT ); Tue, 19 Jan 2016 05:51:21 -0500 X-AuditID: cbfec7f5-f79b16d000005389-a7-569e15278dcf Subject: Re: [PATCH] power: genpd: fix lockdep issue for all subdomains To: linux-samsung-soc@vger.kernel.org, linux-kernel@vger.kernel.org, Ulf Hansson References: <1451903982-1598-1-git-send-email-m.szyprowski@samsung.com> Cc: Kevin Hilman , "Rafael J. Wysocki" , Anand Moon , Bartlomiej Zolnierkiewicz From: Marek Szyprowski Message-id: <569E1525.5050407@samsung.com> Date: Tue, 19 Jan 2016 11:51:17 +0100 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.5.1 MIME-version: 1.0 In-reply-to: <1451903982-1598-1-git-send-email-m.szyprowski@samsung.com> Content-type: text/plain; charset=utf-8; format=flowed Content-transfer-encoding: 7bit X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrHLMWRmVeSWpSXmKPExsVy+t/xa7rqovPCDJ48Z7fYOGM9q8XTzY+Z LC7vmsNmMeP8PiaLdRtvsVucOX2J1eL42nAHdo+ds+6ye2xa1cnmcefaHjaPLVfbWTz6tqxi 9Pi8SS6ALYrLJiU1J7MstUjfLoEr4+rtc8wFX3Qq7h/oZWtgXKPaxcjJISFgIvG1ez4zhC0m ceHeerYuRi4OIYGljBLrfy+Ecp4zStz5eJG9i5GDQ1jAXeL8PRuQBhGBbIm3M2+zg9hCQOHj 3TOZQOqZBdYwSnRvvcYCkmATMJToetvFBmLzCmhJHNw2lQ1kDouAqsTKNgWQsKhAjMTFziNM ECWCEj8m32MBKeEU8JDoOSQEEmYWMJP48vIwK4QtL7F5zVvmCYwCs5B0zEJSNgtJ2QJG5lWM oqmlyQXFSem5RnrFibnFpXnpesn5uZsYIaH+dQfj0mNWhxgFOBiVeHhfOM4NE2JNLCuuzD3E KMHBrCTCe5V7XpgQb0piZVVqUX58UWlOavEhRmkOFiVx3pm73ocICaQnlqRmp6YWpBbBZJk4 OKUaGBsPhtwNOT7v8qXCrqdqv5c5OjRsObAn/03Z85hKpwaRgxWlr15eNX+z8NZC/g6W7yds At07D9a//Vdurnt+rehxuaP3tETXW/6wK07sjH3oyLj9ybn1QXf3xJpXBF75eGLH9s/HXbxX VV7VdbrPd/Bw4clqC93ybaIumf/mfXSxTFM1Z0xelKTEUpyRaKjFXFScCACTQiOEcQIAAA== Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hello, On 2016-01-04 11:39, Marek Szyprowski wrote: > During genpd_poweron, genpd->lock is acquired recursively for each > parent (master) domain, which are separate obejcts. This confuses > lockdep, which considers every operation on genpd->lock as being done on > the same lock class. This leads to the following false positive warning: > > ============================================= > [ INFO: possible recursive locking detected ] > 4.4.0-rc4-xu3s #32 Not tainted > --------------------------------------------- > swapper/0/1 is trying to acquire lock: > (&genpd->lock){+.+...}, at: [] __genpd_poweron+0x64/0x108 > > but task is already holding lock: > (&genpd->lock){+.+...}, at: [] genpd_dev_pm_attach+0x168/0x1b8 > > other info that might help us debug this: > Possible unsafe locking scenario: > > CPU0 > ---- > lock(&genpd->lock); > lock(&genpd->lock); > > *** DEADLOCK *** > > May be due to missing lock nesting notation > > 3 locks held by swapper/0/1: > #0: (&dev->mutex){......}, at: [] __driver_attach+0x48/0x98 > #1: (&dev->mutex){......}, at: [] __driver_attach+0x58/0x98 > #2: (&genpd->lock){+.+...}, at: [] genpd_dev_pm_attach+0x168/0x1b8 > > stack backtrace: > CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.4.0-rc4-xu3s #32 > Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) > [] (unwind_backtrace) from [] (show_stack+0x10/0x14) > [] (show_stack) from [] (dump_stack+0x84/0xc4) > [] (dump_stack) from [] (__lock_acquire+0x1f88/0x215c) > [] (__lock_acquire) from [] (lock_acquire+0xa4/0xd0) > [] (lock_acquire) from [] (mutex_lock_nested+0x70/0x4d4) > [] (mutex_lock_nested) from [] (__genpd_poweron+0x64/0x108) > [] (__genpd_poweron) from [] (genpd_dev_pm_attach+0x170/0x1b8) > [] (genpd_dev_pm_attach) from [] (platform_drv_probe+0x2c/0xac) > [] (platform_drv_probe) from [] (driver_probe_device+0x208/0x2fc) > [] (driver_probe_device) from [] (__driver_attach+0x94/0x98) > [] (__driver_attach) from [] (bus_for_each_dev+0x68/0x9c) > [] (bus_for_each_dev) from [] (bus_add_driver+0x1a0/0x218) > [] (bus_add_driver) from [] (driver_register+0x78/0xf8) > [] (driver_register) from [] (exynos_drm_register_drivers+0x28/0x74) > [] (exynos_drm_register_drivers) from [] (exynos_drm_init+0x6c/0xc4) > [] (exynos_drm_init) from [] (do_one_initcall+0x90/0x1dc) > [] (do_one_initcall) from [] (kernel_init_freeable+0x158/0x1f8) > [] (kernel_init_freeable) from [] (kernel_init+0x8/0xe8) > [] (kernel_init) from [] (ret_from_fork+0x14/0x24) > > This patch replaces mutex_lock with mutex_lock_nested() and uses > recursion depth to annotate each genpd->lock operation with separate > lockdep subclass. > > Reported-by: Anand Moon > Signed-off-by: Marek Szyprowski Ulf: could you comment on this patch? > --- > drivers/base/power/domain.c | 21 +++++++++++++-------- > 1 file changed, 13 insertions(+), 8 deletions(-) > > diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c > index b803790..e02ddf6 100644 > --- a/drivers/base/power/domain.c > +++ b/drivers/base/power/domain.c > @@ -170,16 +170,15 @@ static void genpd_queue_power_off_work(struct generic_pm_domain *genpd) > queue_work(pm_wq, &genpd->power_off_work); > } > > -static int genpd_poweron(struct generic_pm_domain *genpd); > - > /** > * __genpd_poweron - Restore power to a given PM domain and its masters. > * @genpd: PM domain to power up. > + * @depth: nesting count for lockdep. > * > * Restore power to @genpd and all of its masters so that it is possible to > * resume a device belonging to it. > */ > -static int __genpd_poweron(struct generic_pm_domain *genpd) > +static int __genpd_poweron(struct generic_pm_domain *genpd, unsigned int depth) > { > struct gpd_link *link; > int ret = 0; > @@ -194,11 +193,16 @@ static int __genpd_poweron(struct generic_pm_domain *genpd) > * with it. > */ > list_for_each_entry(link, &genpd->slave_links, slave_node) { > - genpd_sd_counter_inc(link->master); > + struct generic_pm_domain *master = link->master; > + > + genpd_sd_counter_inc(master); > + > + mutex_lock_nested(&master->lock, depth + 1); > + ret = __genpd_poweron(master, depth + 1); > + mutex_unlock(&master->lock); > > - ret = genpd_poweron(link->master); > if (ret) { > - genpd_sd_counter_dec(link->master); > + genpd_sd_counter_dec(master); > goto err; > } > } > @@ -230,11 +234,12 @@ static int genpd_poweron(struct generic_pm_domain *genpd) > int ret; > > mutex_lock(&genpd->lock); > - ret = __genpd_poweron(genpd); > + ret = __genpd_poweron(genpd, 0); > mutex_unlock(&genpd->lock); > return ret; > } > > + > static int genpd_save_dev(struct generic_pm_domain *genpd, struct device *dev) > { > return GENPD_DEV_CALLBACK(genpd, int, save_state, dev); > @@ -482,7 +487,7 @@ static int pm_genpd_runtime_resume(struct device *dev) > } > > mutex_lock(&genpd->lock); > - ret = __genpd_poweron(genpd); > + ret = __genpd_poweron(genpd, 0); > mutex_unlock(&genpd->lock); > > if (ret) Best regards -- Marek Szyprowski, PhD Samsung R&D Institute Poland