From patchwork Mon Aug 20 09:18:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pingfan Liu X-Patchwork-Id: 10570031 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9E309920 for ; Mon, 20 Aug 2018 09:19:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8E642291A1 for ; Mon, 20 Aug 2018 09:19:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 80FDF291BC; Mon, 20 Aug 2018 09:19:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 02AAF291A1 for ; Mon, 20 Aug 2018 09:19:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726114AbeHTMdv (ORCPT ); Mon, 20 Aug 2018 08:33:51 -0400 Received: from mail-pl0-f66.google.com ([209.85.160.66]:43285 "EHLO mail-pl0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725948AbeHTMdu (ORCPT ); Mon, 20 Aug 2018 08:33:50 -0400 Received: by mail-pl0-f66.google.com with SMTP id x6-v6so6800967plv.10; Mon, 20 Aug 2018 02:18:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xpLV1uF+iMUi2sMMOeSI6yl7Ueq8p0sOV2ipQ/5s2+Y=; b=P4PdEDE19WID9H6Eb4BMLnIgjF3CTZ0S4OOq7TTEP+4AK0RdgEDOxVVGdLtEA9vhNV eufwxf0ThDB0CggqwwUlZ9G2ery0hNdbNgqQi5vDoGZ0lym682AhZyrd5wNoeCaZpEb4 ddVt7T46IL71BcNJFe/3jJ12YhD9nKABwZzrk8wSKDDoFMmTlcagilrLEKrQ1a5XvawO zdrgOU84XuuQxwlI4Pc5lsvGDFTthb02bizxTvb2+Gv/ggNNBIU6zTRmHrOWOcInt20D 3AEItpE6AekXLRsXU7pwGtsqwRde/KcGNDxLwK09Gx6ga5H4VHbQ1y6SeBkdK0dArOSq LI/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=xpLV1uF+iMUi2sMMOeSI6yl7Ueq8p0sOV2ipQ/5s2+Y=; b=qTMPJYVx7TrMFI9k7M4n4hlYWRtI+/vpo2S7kX+gnqRotj1jmZLzCLGMCcGEausO0A 833MMUqNOe1fbrybEhRpiQAb/1oT2l2k1F9vUL9tla477nzka4l/mKo9bD2PSpdi/xtn 4btoKfJwoGAF53jmkDscL7ih2b3O9RW3XOrUmUIxpcFa6Rv5/GF9Py/MROklMne0fPcL pXXjRTZLNBZk392SkZvLOH4Mwpo9U+nEmHyq9/oPHa7QiqF7LiLPH6Y2EkYL04/yZtwg Ko2V/N4OA8i1NbR8Zgd4RGLWGabo+2nmPopOldfgYEbw5ZoAnDbRAJl6QuVVIERsIITP 1MLw== X-Gm-Message-State: AOUpUlFfTw0iKdRwN16VkQLyRHsKDGrJH1GeOznAwqYW/7uX2eF0x4df oT4X0FmBwYqj4snIvCkvvRzcvIs= X-Google-Smtp-Source: AA+uWPw6rYa5U+uR4eEBOF10NUfUqdl0wzV9i+CgbW/C3U5/qEpB+dZszxvh8Vc+azaXz/tE011fsA== X-Received: by 2002:a17:902:3a2:: with SMTP id d31-v6mr45041414pld.287.1534756739220; Mon, 20 Aug 2018 02:18:59 -0700 (PDT) Received: from mylaptop.nay.redhat.com ([209.132.188.80]) by smtp.gmail.com with ESMTPSA id u11-v6sm16166340pfd.117.2018.08.20.02.18.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 20 Aug 2018 02:18:58 -0700 (PDT) From: Pingfan Liu To: linux-pm@vger.kernel.org Cc: Pingfan Liu , Greg Kroah-Hartman , "Rafael J. Wysocki" , linux-kernel@vger.kernel.org Subject: [PATCH 1/3] drivers/base: move device_shutdown() to base/power Date: Mon, 20 Aug 2018 17:18:35 +0800 Message-Id: <1534756717-25553-2-git-send-email-kernelfans@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1534756717-25553-1-git-send-email-kernelfans@gmail.com> References: <1534756717-25553-1-git-send-email-kernelfans@gmail.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Consider the shutdown as a system state transition, i.e. something like suspend, hibernate, hence move it under the base/power. (This is a first step to unify the duplicate code logic on devices_kset and dpm_list.) Cc: Greg Kroah-Hartman Cc: "Rafael J. Wysocki" Cc: linux-kernel@vger.kernel.org Signed-off-by: Pingfan Liu --- drivers/base/core.c | 70 --------------------------------------- drivers/base/power/Makefile | 1 + drivers/base/power/shutdown.c | 76 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 70 deletions(-) create mode 100644 drivers/base/power/shutdown.c diff --git a/drivers/base/core.c b/drivers/base/core.c index 04bbcd7..7c83384 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2854,76 +2854,6 @@ int device_move(struct device *dev, struct device *new_parent, } EXPORT_SYMBOL_GPL(device_move); -/** - * device_shutdown - call ->shutdown() on each device to shutdown. - */ -void device_shutdown(void) -{ - struct device *dev, *parent; - - wait_for_device_probe(); - device_block_probing(); - - spin_lock(&devices_kset->list_lock); - /* - * Walk the devices list backward, shutting down each in turn. - * Beware that device unplug events may also start pulling - * devices offline, even as the system is shutting down. - */ - while (!list_empty(&devices_kset->list)) { - dev = list_entry(devices_kset->list.prev, struct device, - kobj.entry); - - /* - * hold reference count of device's parent to - * prevent it from being freed because parent's - * lock is to be held - */ - parent = get_device(dev->parent); - get_device(dev); - /* - * Make sure the device is off the kset list, in the - * event that dev->*->shutdown() doesn't remove it. - */ - list_del_init(&dev->kobj.entry); - spin_unlock(&devices_kset->list_lock); - - /* hold lock to avoid race with probe/release */ - if (parent) - device_lock(parent); - device_lock(dev); - - /* Don't allow any more runtime suspends */ - pm_runtime_get_noresume(dev); - pm_runtime_barrier(dev); - - if (dev->class && dev->class->shutdown_pre) { - if (initcall_debug) - dev_info(dev, "shutdown_pre\n"); - dev->class->shutdown_pre(dev); - } - if (dev->bus && dev->bus->shutdown) { - if (initcall_debug) - dev_info(dev, "shutdown\n"); - dev->bus->shutdown(dev); - } else if (dev->driver && dev->driver->shutdown) { - if (initcall_debug) - dev_info(dev, "shutdown\n"); - dev->driver->shutdown(dev); - } - - device_unlock(dev); - if (parent) - device_unlock(parent); - - put_device(dev); - put_device(parent); - - spin_lock(&devices_kset->list_lock); - } - spin_unlock(&devices_kset->list_lock); -} - /* * Device logging functions */ diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile index e1bb691..057ddbf 100644 --- a/drivers/base/power/Makefile +++ b/drivers/base/power/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 +obj-y += shutdown.o obj-$(CONFIG_PM) += sysfs.o generic_ops.o common.o qos.o runtime.o wakeirq.o obj-$(CONFIG_PM_SLEEP) += main.o wakeup.o obj-$(CONFIG_PM_TRACE_RTC) += trace.o diff --git a/drivers/base/power/shutdown.c b/drivers/base/power/shutdown.c new file mode 100644 index 0000000..c405d09 --- /dev/null +++ b/drivers/base/power/shutdown.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include + +#include "../base.h" +#include "power.h" +/** + * device_shutdown - call ->shutdown() on each device to shutdown. + */ +void device_shutdown(void) +{ + struct device *dev, *parent; + + wait_for_device_probe(); + device_block_probing(); + + spin_lock(&devices_kset->list_lock); + /* + * Walk the devices list backward, shutting down each in turn. + * Beware that device unplug events may also start pulling + * devices offline, even as the system is shutting down. + */ + while (!list_empty(&devices_kset->list)) { + dev = list_entry(devices_kset->list.prev, struct device, + kobj.entry); + + /* + * hold reference count of device's parent to + * prevent it from being freed because parent's + * lock is to be held + */ + parent = get_device(dev->parent); + get_device(dev); + /* + * Make sure the device is off the kset list, in the + * event that dev->*->shutdown() doesn't remove it. + */ + list_del_init(&dev->kobj.entry); + spin_unlock(&devices_kset->list_lock); + + /* hold lock to avoid race with probe/release */ + if (parent) + device_lock(parent); + device_lock(dev); + + /* Don't allow any more runtime suspends */ + pm_runtime_get_noresume(dev); + pm_runtime_barrier(dev); + + if (dev->class && dev->class->shutdown_pre) { + if (initcall_debug) + dev_info(dev, "shutdown_pre\n"); + dev->class->shutdown_pre(dev); + } + if (dev->bus && dev->bus->shutdown) { + if (initcall_debug) + dev_info(dev, "shutdown\n"); + dev->bus->shutdown(dev); + } else if (dev->driver && dev->driver->shutdown) { + if (initcall_debug) + dev_info(dev, "shutdown\n"); + dev->driver->shutdown(dev); + } + + device_unlock(dev); + if (parent) + device_unlock(parent); + + put_device(dev); + put_device(parent); + + spin_lock(&devices_kset->list_lock); + } + spin_unlock(&devices_kset->list_lock); +} From patchwork Mon Aug 20 09:18:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pingfan Liu X-Patchwork-Id: 10570029 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9E44B920 for ; Mon, 20 Aug 2018 09:19:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8CA6C291A1 for ; Mon, 20 Aug 2018 09:19:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 80ABE291BC; Mon, 20 Aug 2018 09:19:17 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 76657291A1 for ; Mon, 20 Aug 2018 09:19:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726547AbeHTMdy (ORCPT ); Mon, 20 Aug 2018 08:33:54 -0400 Received: from mail-pl0-f66.google.com ([209.85.160.66]:32798 "EHLO mail-pl0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725948AbeHTMdx (ORCPT ); Mon, 20 Aug 2018 08:33:53 -0400 Received: by mail-pl0-f66.google.com with SMTP id b90-v6so6817084plb.0; Mon, 20 Aug 2018 02:19:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=vjJaHpZ9XKwkwSe0ImBezzXQV41i37dC9mr7lQGnEaU=; b=SrLtqNz9wLs8LhT5vcH88i0FPNOYDht5FIGhd7wQUfYMLGnvPY4G73saMvhLLsSMTv ceehzvPuw9hMBh2pEZu5dy0WESw/ZGEPwTFZovTV3Lebvqsfrw0o+YH+I3APB4IyKr26 51FTYjoSjFCJrZ8BLbF1dH9qJxejh6CDC32lNL+fPRoazapFsOszWgC1ADs8/eUFID1m 16GSOkmjcKuRNU1kIEqFz4zaCZJ8kyzVqs/xDjMmDyzy21IfTMjZp4uT8e3l8nW0aSNS 4U+ft1i3MMs84NYwxSDAFANsJ+vxoW2JfNm5rYSwy+AsjuWwBrN9mA1z0fcF2YKmcQ85 4w4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=vjJaHpZ9XKwkwSe0ImBezzXQV41i37dC9mr7lQGnEaU=; b=aUyoYGhvlcPx6dH212BG9JDDbPEgXe9I9uRoErrSsNzipcQ7wREpCVsyHrqbi7FjUI 0ma9ofnji13ZR4yp4tJWVHhO3q06sp8aZVIgW2q1T16AT3o7KZr21UvBY1xEWTX0A6Di JJhgEfbjnxmZq/PDOcPDqqeOlRJ28YSaRAIEFG72pHllxj9L2ZxHcPHw8HzmRITeRDns vkjhmMm9hOKMrVmAVuOHD7EZDDQTIkHug1cxdXjj2v4+Ah2NEglO9wbjO40sHc4auNWP 0JQf/FAYI9cRWGNYwJdlssE0pr0+9T6qo5GYoFHX4GYIOC6QjRBwfjm8pxM+SPwLP0LE yFog== X-Gm-Message-State: AOUpUlH6CU9hqNikt42dh8Hm1ku8AzZ/hA0Tjvzr3c7TPqM66Wkc9por Fvt+ysbCVj2H0p9ZoEuioYqSftE= X-Google-Smtp-Source: AA+uWPzEYn+7E75JQOnkVqnsqSv+jZthBRl/LLfmKddSX8YrGU4yIkvUjMKtMxUqua3ztFohxvxk4A== X-Received: by 2002:a17:902:925:: with SMTP id 34-v6mr44576775plm.307.1534756742142; Mon, 20 Aug 2018 02:19:02 -0700 (PDT) Received: from mylaptop.nay.redhat.com ([209.132.188.80]) by smtp.gmail.com with ESMTPSA id u11-v6sm16166340pfd.117.2018.08.20.02.18.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 20 Aug 2018 02:19:01 -0700 (PDT) From: Pingfan Liu To: linux-pm@vger.kernel.org Cc: Pingfan Liu , Greg Kroah-Hartman , "Rafael J. Wysocki" , linux-kernel@vger.kernel.org Subject: [PATCH 2/3] PM/shutdown: device_shutdown() uses the order info in dpm_list instead of devices_kset Date: Mon, 20 Aug 2018 17:18:36 +0800 Message-Id: <1534756717-25553-3-git-send-email-kernelfans@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1534756717-25553-1-git-send-email-kernelfans@gmail.com> References: <1534756717-25553-1-git-send-email-kernelfans@gmail.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP At present, the "parent <- child" and "suppiler <- consumer" ordering info are stored duplicate in two places dpm_list and devices_kset, and corresponding, there are two sets of routines to manipulate them. The patch pushes the dpm_list and dpm_list_mtx out of CONFIG_PM, and let device_shutdown() use them to implement shutdown seq. Comparing to original code, this patch tries to simplify the code at the cost of a extra mutex if without CONFIG_PM and nothing if with CONFIG_PM. The cost on dpm_list_mtx can be ignored, since the device hot add/remove is not very frequently. Cc: Greg Kroah-Hartman Cc: "Rafael J. Wysocki" Cc: linux-kernel@vger.kernel.org Signed-off-by: Pingfan Liu --- drivers/base/power/main.c | 119 ++++++++++++------------------------------ drivers/base/power/power.h | 25 +++++---- drivers/base/power/shutdown.c | 63 +++++++++++++++++++--- include/linux/pm.h | 7 +-- 4 files changed, 104 insertions(+), 110 deletions(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 3f68e29..7b2f316 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -49,14 +49,12 @@ typedef int (*pm_callback_t)(struct device *); * dpm_list_mutex. */ -LIST_HEAD(dpm_list); static LIST_HEAD(dpm_prepared_list); static LIST_HEAD(dpm_suspended_list); static LIST_HEAD(dpm_late_early_list); static LIST_HEAD(dpm_noirq_list); struct suspend_stats suspend_stats; -static DEFINE_MUTEX(dpm_list_mtx); static pm_message_t pm_transition; static int async_error; @@ -98,59 +96,6 @@ void device_pm_sleep_init(struct device *dev) init_completion(&dev->power.completion); complete_all(&dev->power.completion); dev->power.wakeup = NULL; - INIT_LIST_HEAD(&dev->power.entry); -} - -/** - * device_pm_lock - Lock the list of active devices used by the PM core. - */ -void device_pm_lock(void) -{ - mutex_lock(&dpm_list_mtx); -} - -/** - * device_pm_unlock - Unlock the list of active devices used by the PM core. - */ -void device_pm_unlock(void) -{ - mutex_unlock(&dpm_list_mtx); -} - -/** - * device_pm_add - Add a device to the PM core's list of active devices. - * @dev: Device to add to the list. - */ -void device_pm_add(struct device *dev) -{ - pr_debug("PM: Adding info for %s:%s\n", - dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); - device_pm_check_callbacks(dev); - mutex_lock(&dpm_list_mtx); - if (dev->parent && dev->parent->power.is_prepared) - dev_warn(dev, "parent %s should not be sleeping\n", - dev_name(dev->parent)); - list_add_tail(&dev->power.entry, &dpm_list); - dev->power.in_dpm_list = true; - mutex_unlock(&dpm_list_mtx); -} - -/** - * device_pm_remove - Remove a device from the PM core's list of active devices. - * @dev: Device to be removed from the list. - */ -void device_pm_remove(struct device *dev) -{ - pr_debug("PM: Removing info for %s:%s\n", - dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); - complete_all(&dev->power.completion); - mutex_lock(&dpm_list_mtx); - list_del_init(&dev->power.entry); - dev->power.in_dpm_list = false; - mutex_unlock(&dpm_list_mtx); - device_wakeup_disable(dev); - pm_runtime_remove(dev); - device_pm_check_callbacks(dev); } /** @@ -714,7 +659,7 @@ void dpm_noirq_resume_devices(pm_message_t state) ktime_t starttime = ktime_get(); trace_suspend_resume(TPS("dpm_resume_noirq"), state.event, true); - mutex_lock(&dpm_list_mtx); + device_pm_lock(); pm_transition = state; /* @@ -734,7 +679,7 @@ void dpm_noirq_resume_devices(pm_message_t state) dev = to_device(dpm_noirq_list.next); get_device(dev); list_move_tail(&dev->power.entry, &dpm_late_early_list); - mutex_unlock(&dpm_list_mtx); + device_pm_unlock(); if (!is_async(dev)) { int error; @@ -748,10 +693,10 @@ void dpm_noirq_resume_devices(pm_message_t state) } } - mutex_lock(&dpm_list_mtx); + device_pm_lock(); put_device(dev); } - mutex_unlock(&dpm_list_mtx); + device_pm_unlock(); async_synchronize_full(); dpm_show_time(starttime, state, 0, "noirq"); trace_suspend_resume(TPS("dpm_resume_noirq"), state.event, false); @@ -871,7 +816,7 @@ void dpm_resume_early(pm_message_t state) ktime_t starttime = ktime_get(); trace_suspend_resume(TPS("dpm_resume_early"), state.event, true); - mutex_lock(&dpm_list_mtx); + device_pm_lock(); pm_transition = state; /* @@ -891,7 +836,7 @@ void dpm_resume_early(pm_message_t state) dev = to_device(dpm_late_early_list.next); get_device(dev); list_move_tail(&dev->power.entry, &dpm_suspended_list); - mutex_unlock(&dpm_list_mtx); + device_pm_unlock(); if (!is_async(dev)) { int error; @@ -904,10 +849,10 @@ void dpm_resume_early(pm_message_t state) pm_dev_err(dev, state, " early", error); } } - mutex_lock(&dpm_list_mtx); + device_pm_lock(); put_device(dev); } - mutex_unlock(&dpm_list_mtx); + device_pm_unlock(); async_synchronize_full(); dpm_show_time(starttime, state, 0, "early"); trace_suspend_resume(TPS("dpm_resume_early"), state.event, false); @@ -1039,7 +984,7 @@ void dpm_resume(pm_message_t state) trace_suspend_resume(TPS("dpm_resume"), state.event, true); might_sleep(); - mutex_lock(&dpm_list_mtx); + device_pm_lock(); pm_transition = state; async_error = 0; @@ -1057,7 +1002,7 @@ void dpm_resume(pm_message_t state) if (!is_async(dev)) { int error; - mutex_unlock(&dpm_list_mtx); + device_pm_unlock(); error = device_resume(dev, state, false); if (error) { @@ -1067,13 +1012,13 @@ void dpm_resume(pm_message_t state) pm_dev_err(dev, state, "", error); } - mutex_lock(&dpm_list_mtx); + device_pm_lock(); } if (!list_empty(&dev->power.entry)) list_move_tail(&dev->power.entry, &dpm_prepared_list); put_device(dev); } - mutex_unlock(&dpm_list_mtx); + device_pm_unlock(); async_synchronize_full(); dpm_show_time(starttime, state, 0, NULL); @@ -1140,24 +1085,24 @@ void dpm_complete(pm_message_t state) might_sleep(); INIT_LIST_HEAD(&list); - mutex_lock(&dpm_list_mtx); + device_pm_lock(); while (!list_empty(&dpm_prepared_list)) { struct device *dev = to_device(dpm_prepared_list.prev); get_device(dev); dev->power.is_prepared = false; list_move(&dev->power.entry, &list); - mutex_unlock(&dpm_list_mtx); + device_pm_unlock(); trace_device_pm_callback_start(dev, "", state.event); device_complete(dev, state); trace_device_pm_callback_end(dev, 0); - mutex_lock(&dpm_list_mtx); + device_pm_lock(); put_device(dev); } list_splice(&list, &dpm_list); - mutex_unlock(&dpm_list_mtx); + device_pm_unlock(); /* Allow device probing and trigger re-probing of deferred devices */ device_unblock_probing(); @@ -1385,7 +1330,7 @@ int dpm_noirq_suspend_devices(pm_message_t state) int error = 0; trace_suspend_resume(TPS("dpm_suspend_noirq"), state.event, true); - mutex_lock(&dpm_list_mtx); + device_pm_lock(); pm_transition = state; async_error = 0; @@ -1393,11 +1338,11 @@ int dpm_noirq_suspend_devices(pm_message_t state) struct device *dev = to_device(dpm_late_early_list.prev); get_device(dev); - mutex_unlock(&dpm_list_mtx); + device_pm_unlock(); error = device_suspend_noirq(dev); - mutex_lock(&dpm_list_mtx); + device_pm_lock(); if (error) { pm_dev_err(dev, state, " noirq", error); dpm_save_failed_dev(dev_name(dev)); @@ -1411,7 +1356,7 @@ int dpm_noirq_suspend_devices(pm_message_t state) if (async_error) break; } - mutex_unlock(&dpm_list_mtx); + device_pm_unlock(); async_synchronize_full(); if (!error) error = async_error; @@ -1586,7 +1531,7 @@ int dpm_suspend_late(pm_message_t state) int error = 0; trace_suspend_resume(TPS("dpm_suspend_late"), state.event, true); - mutex_lock(&dpm_list_mtx); + device_pm_lock(); pm_transition = state; async_error = 0; @@ -1594,11 +1539,11 @@ int dpm_suspend_late(pm_message_t state) struct device *dev = to_device(dpm_suspended_list.prev); get_device(dev); - mutex_unlock(&dpm_list_mtx); + device_pm_unlock(); error = device_suspend_late(dev); - mutex_lock(&dpm_list_mtx); + device_pm_lock(); if (!list_empty(&dev->power.entry)) list_move(&dev->power.entry, &dpm_late_early_list); @@ -1613,7 +1558,7 @@ int dpm_suspend_late(pm_message_t state) if (async_error) break; } - mutex_unlock(&dpm_list_mtx); + device_pm_unlock(); async_synchronize_full(); if (!error) error = async_error; @@ -1851,18 +1796,18 @@ int dpm_suspend(pm_message_t state) cpufreq_suspend(); - mutex_lock(&dpm_list_mtx); + device_pm_lock(); pm_transition = state; async_error = 0; while (!list_empty(&dpm_prepared_list)) { struct device *dev = to_device(dpm_prepared_list.prev); get_device(dev); - mutex_unlock(&dpm_list_mtx); + device_pm_unlock(); error = device_suspend(dev); - mutex_lock(&dpm_list_mtx); + device_pm_lock(); if (error) { pm_dev_err(dev, state, "", error); dpm_save_failed_dev(dev_name(dev)); @@ -1875,7 +1820,7 @@ int dpm_suspend(pm_message_t state) if (async_error) break; } - mutex_unlock(&dpm_list_mtx); + device_pm_unlock(); async_synchronize_full(); if (!error) error = async_error; @@ -1989,18 +1934,18 @@ int dpm_prepare(pm_message_t state) */ device_block_probing(); - mutex_lock(&dpm_list_mtx); + device_pm_lock(); while (!list_empty(&dpm_list)) { struct device *dev = to_device(dpm_list.next); get_device(dev); - mutex_unlock(&dpm_list_mtx); + device_pm_unlock(); trace_device_pm_callback_start(dev, "", state.event); error = device_prepare(dev, state); trace_device_pm_callback_end(dev, error); - mutex_lock(&dpm_list_mtx); + device_pm_lock(); if (error) { if (error == -EAGAIN) { put_device(dev); @@ -2018,7 +1963,7 @@ int dpm_prepare(pm_message_t state) list_move_tail(&dev->power.entry, &dpm_prepared_list); put_device(dev); } - mutex_unlock(&dpm_list_mtx); + device_pm_unlock(); trace_suspend_resume(TPS("dpm_prepare"), state.event, false); return error; } diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index c511def..4578d97 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h @@ -1,15 +1,31 @@ /* SPDX-License-Identifier: GPL-2.0 */ #include +extern struct mutex dpm_list_mtx; + +static inline void device_pm_lock(void) +{ + mutex_lock(&dpm_list_mtx); +} + +static inline void device_pm_unlock(void) +{ + mutex_unlock(&dpm_list_mtx); +} + static inline void device_pm_init_common(struct device *dev) { if (!dev->power.early_init) { spin_lock_init(&dev->power.lock); + INIT_LIST_HEAD(&dev->power.entry); dev->power.qos = NULL; dev->power.early_init = true; } } +extern void device_pm_add(struct device *dev); +extern void device_pm_remove(struct device *dev); + #ifdef CONFIG_PM static inline void pm_runtime_early_init(struct device *dev) @@ -104,8 +120,6 @@ static inline struct device *to_device(struct list_head *entry) } extern void device_pm_sleep_init(struct device *dev); -extern void device_pm_add(struct device *); -extern void device_pm_remove(struct device *); extern void device_pm_move_before(struct device *, struct device *); extern void device_pm_move_after(struct device *, struct device *); extern void device_pm_move_last(struct device *); @@ -120,13 +134,6 @@ static inline bool device_pm_initialized(struct device *dev) static inline void device_pm_sleep_init(struct device *dev) {} -static inline void device_pm_add(struct device *dev) {} - -static inline void device_pm_remove(struct device *dev) -{ - pm_runtime_remove(dev); -} - static inline void device_pm_move_before(struct device *deva, struct device *devb) {} static inline void device_pm_move_after(struct device *deva, diff --git a/drivers/base/power/shutdown.c b/drivers/base/power/shutdown.c index c405d09..be8e247 100644 --- a/drivers/base/power/shutdown.c +++ b/drivers/base/power/shutdown.c @@ -5,6 +5,50 @@ #include "../base.h" #include "power.h" + +LIST_HEAD(dpm_list); +DEFINE_MUTEX(dpm_list_mtx); + +/** + * device_pm_add - Add a device to the PM core's list of active devices. + * @dev: Device to add to the list. + */ +void device_pm_add(struct device *dev) +{ + pr_debug("PM: Adding info for %s:%s\n", + dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); + device_pm_check_callbacks(dev); + device_pm_lock(); +#ifdef CONFIG_PM_SLEEP + if (dev->parent && dev->parent->power.is_prepared) + dev_warn(dev, "parent %s should not be sleeping\n", + dev_name(dev->parent)); +#endif + list_add_tail(&dev->power.entry, &dpm_list); + dev->power.in_dpm_list = true; + device_pm_unlock(); +} + +/** + * device_pm_remove - Remove a device from the PM core's list of active devices. + * @dev: Device to be removed from the list. + */ +void device_pm_remove(struct device *dev) +{ + pr_debug("PM: Removing info for %s:%s\n", + dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); +#ifdef CONFIG_PM_SLEEP + complete_all(&dev->power.completion); +#endif + device_pm_lock(); + list_del_init(&dev->power.entry); + dev->power.in_dpm_list = false; + device_pm_unlock(); + device_wakeup_disable(dev); + pm_runtime_remove(dev); + device_pm_check_callbacks(dev); +} + /** * device_shutdown - call ->shutdown() on each device to shutdown. */ @@ -15,15 +59,18 @@ void device_shutdown(void) wait_for_device_probe(); device_block_probing(); - spin_lock(&devices_kset->list_lock); + /* + * only care about race with hotplug. And shutdown excludes suspend + */ + device_pm_lock(); /* * Walk the devices list backward, shutting down each in turn. * Beware that device unplug events may also start pulling * devices offline, even as the system is shutting down. */ - while (!list_empty(&devices_kset->list)) { - dev = list_entry(devices_kset->list.prev, struct device, - kobj.entry); + while (!list_empty(&dpm_list)) { + dev = list_entry(dpm_list.prev, struct device, + power.entry); /* * hold reference count of device's parent to @@ -36,8 +83,8 @@ void device_shutdown(void) * Make sure the device is off the kset list, in the * event that dev->*->shutdown() doesn't remove it. */ - list_del_init(&dev->kobj.entry); - spin_unlock(&devices_kset->list_lock); + list_del_init(&dev->power.entry); + device_pm_unlock(); /* hold lock to avoid race with probe/release */ if (parent) @@ -70,7 +117,7 @@ void device_shutdown(void) put_device(dev); put_device(parent); - spin_lock(&devices_kset->list_lock); + device_pm_lock(); } - spin_unlock(&devices_kset->list_lock); + device_pm_unlock(); } diff --git a/include/linux/pm.h b/include/linux/pm.h index e723b78..77d8a50 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -595,8 +595,8 @@ struct dev_pm_info { bool direct_complete:1; /* Owned by the PM core */ u32 driver_flags; spinlock_t lock; -#ifdef CONFIG_PM_SLEEP struct list_head entry; +#ifdef CONFIG_PM_SLEEP struct completion completion; struct wakeup_source *wakeup; bool wakeup_path:1; @@ -721,7 +721,6 @@ struct dev_pm_domain { */ #ifdef CONFIG_PM_SLEEP -extern void device_pm_lock(void); extern void dpm_resume_start(pm_message_t state); extern void dpm_resume_end(pm_message_t state); extern void dpm_noirq_resume_devices(pm_message_t state); @@ -731,7 +730,6 @@ extern void dpm_resume_early(pm_message_t state); extern void dpm_resume(pm_message_t state); extern void dpm_complete(pm_message_t state); -extern void device_pm_unlock(void); extern int dpm_suspend_end(pm_message_t state); extern int dpm_suspend_start(pm_message_t state); extern void dpm_noirq_begin(void); @@ -778,9 +776,6 @@ extern bool dev_pm_smart_suspend_and_suspended(struct device *dev); #else /* !CONFIG_PM_SLEEP */ -#define device_pm_lock() do {} while (0) -#define device_pm_unlock() do {} while (0) - static inline int dpm_suspend_start(pm_message_t state) { return 0; From patchwork Mon Aug 20 09:18:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pingfan Liu X-Patchwork-Id: 10570027 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D0D22920 for ; Mon, 20 Aug 2018 09:19:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C11F3291A1 for ; Mon, 20 Aug 2018 09:19:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B5276291BC; Mon, 20 Aug 2018 09:19:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4185C291A1 for ; Mon, 20 Aug 2018 09:19:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726608AbeHTMd5 (ORCPT ); Mon, 20 Aug 2018 08:33:57 -0400 Received: from mail-pl0-f65.google.com ([209.85.160.65]:34154 "EHLO mail-pl0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726617AbeHTMd4 (ORCPT ); Mon, 20 Aug 2018 08:33:56 -0400 Received: by mail-pl0-f65.google.com with SMTP id f6-v6so6823635plo.1; Mon, 20 Aug 2018 02:19:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=tghwBLWOV/3T54AesfMEpwuCXEdCsQ4AGc/KQoGqp0c=; b=EiclI4tXnRwVOkFQr3jMKa4vXfrSvCjB3yzLF2zftXzF7gnXhNupizk0aVE/MerhTK ezEPJYs7aw9O6Z0aThokSkf4K5nyY8BOk8XwbF3+q1fAJv1114v1ojQyPER8rb3/jVu4 QMYAQZDe4IH8eG+58d2wF07wq8v71mZm6rT4TJH4kg4AfdZ10Cz5r6V3GRhYuxgDwbKH fERAqxHkpoeJl3OsVm4cFmAkeW+VMuk2+3HTr4g8rzK7dPsLCmubKk+/htynba+A2gQ8 hNGygCdOPMXiHPN46/ads65FiavrojwHRKzl2wdXlt4s5b7XnpfRsY9XkGVv/v8X+yF5 owcA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=tghwBLWOV/3T54AesfMEpwuCXEdCsQ4AGc/KQoGqp0c=; b=XL4r7pdppaxirAQ1/p76mezEPlf8ETL13kQidEl4+V3HuJLRjdlOMPCMuEX4mGsvge Gw+qDIhe+4eCbmWwcshYKmPkDosa/SEtHeeAtDae0mnJ6OeeLaTkpDY19Lsw/CU4U+FV 4xBWZqugHPMsWeBC8aoxzXzT/nhINUV1eR7H9CXGcfVDnfjzbiAxWMxSm/+jlg6ftXgx S0BV9krAFeetyvweEe7mp/PlnInlkeyl7Yn1iX4dW1H3bmv4sB5YUu+ysm9C5vVCYZzI JE2fe2gD9A49XcUl6gDlXyXQprshqyamvcbAxWu2SciMpZvkaE2ljaIbsRSMac6wMKqq HXPw== X-Gm-Message-State: AOUpUlFlbg9eWvTK4RhdIcuErwZRN1XOzkI7EGOoie8NfTEHSPeIB51Y M/IEetgRL+g7HaNKw3zuQJmClk0= X-Google-Smtp-Source: AA+uWPyGN8Aku2pW8kUgzbanBOBapj+a7KBI2mXGngHq3+gVqqFfXfOtvx25C+3Er6bMvw3r1uqFxQ== X-Received: by 2002:a17:902:528a:: with SMTP id a10-v6mr44659742pli.199.1534756745190; Mon, 20 Aug 2018 02:19:05 -0700 (PDT) Received: from mylaptop.nay.redhat.com ([209.132.188.80]) by smtp.gmail.com with ESMTPSA id u11-v6sm16166340pfd.117.2018.08.20.02.19.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 20 Aug 2018 02:19:04 -0700 (PDT) From: Pingfan Liu To: linux-pm@vger.kernel.org Cc: Pingfan Liu , Greg Kroah-Hartman , "Rafael J. Wysocki" , linux-kernel@vger.kernel.org Subject: [PATCH 3/3] drivers/base: clean up unused devices_kset_move_*() functions Date: Mon, 20 Aug 2018 17:18:37 +0800 Message-Id: <1534756717-25553-4-git-send-email-kernelfans@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1534756717-25553-1-git-send-email-kernelfans@gmail.com> References: <1534756717-25553-1-git-send-email-kernelfans@gmail.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Now, shutdown seq is unified with PM, and there is no need to maintain the "parent <- child" or "supplier <- consumer" order in devices_kset any more, hence removing the corresponding routines Cc: Greg Kroah-Hartman Cc: "Rafael J. Wysocki" Cc: linux-kernel@vger.kernel.org Signed-off-by: Pingfan Liu --- drivers/base/base.h | 1 - drivers/base/core.c | 56 ----------------------------------------------------- 2 files changed, 57 deletions(-) diff --git a/drivers/base/base.h b/drivers/base/base.h index 7a419a7..fcb213b 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -133,7 +133,6 @@ extern void device_unblock_probing(void); /* /sys/devices directory */ extern struct kset *devices_kset; -extern void devices_kset_move_last(struct device *dev); #if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS) extern void module_add_driver(struct module *mod, struct device_driver *drv); diff --git a/drivers/base/core.c b/drivers/base/core.c index 7c83384..99fdc57 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -127,13 +127,6 @@ static int device_reorder_to_tail(struct device *dev, void *not_used) { struct device_link *link; - /* - * Devices that have not been registered yet will be put to the ends - * of the lists during the registration, so skip them here. - */ - if (device_is_registered(dev)) - devices_kset_move_last(dev); - if (device_pm_initialized(dev)) device_pm_move_last(dev); @@ -1316,52 +1309,6 @@ static DEVICE_ATTR_RO(dev); struct kset *devices_kset; /** - * devices_kset_move_before - Move device in the devices_kset's list. - * @deva: Device to move. - * @devb: Device @deva should come before. - */ -static void devices_kset_move_before(struct device *deva, struct device *devb) -{ - if (!devices_kset) - return; - pr_debug("devices_kset: Moving %s before %s\n", - dev_name(deva), dev_name(devb)); - spin_lock(&devices_kset->list_lock); - list_move_tail(&deva->kobj.entry, &devb->kobj.entry); - spin_unlock(&devices_kset->list_lock); -} - -/** - * devices_kset_move_after - Move device in the devices_kset's list. - * @deva: Device to move - * @devb: Device @deva should come after. - */ -static void devices_kset_move_after(struct device *deva, struct device *devb) -{ - if (!devices_kset) - return; - pr_debug("devices_kset: Moving %s after %s\n", - dev_name(deva), dev_name(devb)); - spin_lock(&devices_kset->list_lock); - list_move(&deva->kobj.entry, &devb->kobj.entry); - spin_unlock(&devices_kset->list_lock); -} - -/** - * devices_kset_move_last - move the device to the end of devices_kset's list. - * @dev: device to move - */ -void devices_kset_move_last(struct device *dev) -{ - if (!devices_kset) - return; - pr_debug("devices_kset: Moving %s to end of list\n", dev_name(dev)); - spin_lock(&devices_kset->list_lock); - list_move_tail(&dev->kobj.entry, &devices_kset->list); - spin_unlock(&devices_kset->list_lock); -} - -/** * device_create_file - create sysfs attribute file for device. * @dev: device. * @attr: device attribute descriptor. @@ -2834,15 +2781,12 @@ int device_move(struct device *dev, struct device *new_parent, break; case DPM_ORDER_DEV_AFTER_PARENT: device_pm_move_after(dev, new_parent); - devices_kset_move_after(dev, new_parent); break; case DPM_ORDER_PARENT_BEFORE_DEV: device_pm_move_before(new_parent, dev); - devices_kset_move_before(new_parent, dev); break; case DPM_ORDER_DEV_LAST: device_pm_move_last(dev); - devices_kset_move_last(dev); break; }