From patchwork Fri Jan 15 09:59:20 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 59851 Delivered-To: patches@linaro.org Received: by 10.112.130.2 with SMTP id oa2csp435248lbb; Fri, 15 Jan 2016 01:59:29 -0800 (PST) X-Received: by 10.112.126.164 with SMTP id mz4mr2825810lbb.70.1452851969021; Fri, 15 Jan 2016 01:59:29 -0800 (PST) Return-Path: Received: from mail-lb0-x22a.google.com (mail-lb0-x22a.google.com. [2a00:1450:4010:c04::22a]) by mx.google.com with ESMTPS id dk7si4597724lbc.169.2016.01.15.01.59.28 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 15 Jan 2016 01:59:28 -0800 (PST) Received-SPF: pass (google.com: domain of ulf.hansson@linaro.org designates 2a00:1450:4010:c04::22a as permitted sender) client-ip=2a00:1450:4010:c04::22a; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ulf.hansson@linaro.org designates 2a00:1450:4010:c04::22a as permitted sender) smtp.mailfrom=ulf.hansson@linaro.org; dkim=pass header.i=@linaro.org Received: by mail-lb0-x22a.google.com with SMTP id bc4so311121814lbc.2 for ; Fri, 15 Jan 2016 01:59:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=yABwYK2vdgevz7mqVMaZ9WWQaE9WfXNgIvO2rlOxogM=; b=SQ1mJNjT+bNkAmNCTkOY2ILL3s+hl05zAJ/29SDSTBPE8dfHdNaAOZxHn6ojocrgo4 ymkI0Ka8mYcQeIFknkcZPM3wdYu9a+F1ZfPU/KZdqvL6iFV7gw8ZzvZMjGoY4G9lRASP ielaCCiJh8QQzfuyebJS89gG7TefkbuEUXn+I= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=yABwYK2vdgevz7mqVMaZ9WWQaE9WfXNgIvO2rlOxogM=; b=l3PwMDt7WS2En8wlvAwsnfDcetXyw7ZcYBKc54mHC9cURVVCj1Zq2woNPwvHNvgti5 mNb82bHcQQSVM6OPTygcjytHyVMHCJESVu4apsPxgPb7YbhVcoVK0ZnCprxgjtneeH2X QQI6Za2X/fO8QIYHC4BqvxcQnd3dbhGj7jJySqYf4vQZeZ2XrkPKeUrYWI0TI2R410Fj mWf93jRBp3jPjMhYZeFRD5tN9Y6WiJrelGdB4V6Ra5IQm+DrLnG8fUKX4nOGqHcP02ku 8u7dR46ctkdTFQybircEHftIi0qv4XqQR3jibPhwR7f3tKcSQmZPXwu2FwtH+YO9Gz/K hrJA== X-Gm-Message-State: ALoCoQkpHBQKj2YTLwlgrFnqEaYjZz9mubMaMopaoA6nYLkQd78Mv42t3zIT/DJYhoDqf3T8l9xmDAoCPkX9TkBPN9lyNEhOJQ== X-Received: by 10.112.145.131 with SMTP id su3mr2902349lbb.19.1452851968792; Fri, 15 Jan 2016 01:59:28 -0800 (PST) Return-Path: Received: from localhost.localdomain (c-83-233-167-104.cust.bredband2.com. [83.233.167.104]) by smtp.gmail.com with ESMTPSA id ja4sm1255995lbc.8.2016.01.15.01.59.27 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 15 Jan 2016 01:59:28 -0800 (PST) From: Ulf Hansson To: "Rafael J. Wysocki" , Kevin Hilman , Ulf Hansson , linux-pm@vger.kernel.org Cc: Len Brown , Pavel Machek , Geert Uytterhoeven , Lina Iyer , Lorenzo Pieralisi , Axel Haslam , Marc Titinger Subject: [PATCH] PM / Domains: Fix potential deadlock while adding/removing subdomains Date: Fri, 15 Jan 2016 10:59:20 +0100 Message-Id: <1452851960-22555-1-git-send-email-ulf.hansson@linaro.org> X-Mailer: git-send-email 1.9.1 We must preserve the same order of how we acquire and release the lock for genpd, as otherwise we may encounter deadlocks. The power on phase of a genpd starts by acquiring its lock. Then it walks the hierarchy of its parent domains to be able to power on these first, as per design of genpd. >From a locking perspective this means the locks of the parents becomes acquired after the lock of the subdomain. Let's fix pm_genpd_add|remove_subdomain() to maintain the same order of acquiring/releasing the genpd lock as being applied in the power on/off sequence. Signed-off-by: Ulf Hansson --- drivers/base/power/domain.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) -- 1.9.1 diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 6ac9a7f..81332a4 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -1339,8 +1339,8 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, if (!link) return -ENOMEM; + mutex_lock(&subdomain->lock); mutex_lock(&genpd->lock); - mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING); if (genpd->status == GPD_STATE_POWER_OFF && subdomain->status != GPD_STATE_POWER_OFF) { @@ -1363,8 +1363,8 @@ int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, genpd_sd_counter_inc(genpd); out: - mutex_unlock(&subdomain->lock); mutex_unlock(&genpd->lock); + mutex_unlock(&subdomain->lock); if (ret) kfree(link); return ret; @@ -1385,6 +1385,7 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, if (IS_ERR_OR_NULL(genpd) || IS_ERR_OR_NULL(subdomain)) return -EINVAL; + mutex_lock(&subdomain->lock); mutex_lock(&genpd->lock); if (!list_empty(&subdomain->slave_links) || subdomain->device_count) { @@ -1398,22 +1399,19 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, if (link->slave != subdomain) continue; - mutex_lock_nested(&subdomain->lock, SINGLE_DEPTH_NESTING); - list_del(&link->master_node); list_del(&link->slave_node); kfree(link); if (subdomain->status != GPD_STATE_POWER_OFF) genpd_sd_counter_dec(genpd); - mutex_unlock(&subdomain->lock); - ret = 0; break; } out: mutex_unlock(&genpd->lock); + mutex_unlock(&subdomain->lock); return ret; }