Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp846341pxb; Thu, 25 Feb 2021 17:21:00 -0800 (PST) X-Google-Smtp-Source: ABdhPJzo5R1wvnAKjWkigH4R4JLDMOS/prAvBQ+przguSZKgNPGYfcGrJ7iQV+pfM04KcegPrl6q X-Received: by 2002:a17:906:b14b:: with SMTP id bt11mr567329ejb.162.1614302460017; Thu, 25 Feb 2021 17:21:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1614302460; cv=none; d=google.com; s=arc-20160816; b=ognZ09UM0BNIKnAAFIkMQp5/pKoejlN5H1gC5IpTQAIe+I2RmTbUMO3XQKMfIrrYF1 uaEmoGiB2BIpjT2OPYJF1Xp5rILy8TDpCtusxnrviX2RF4AaDCx7Y5k3+PInJJYomDMz AUrfG+kULp+8fEJ93gnMJ3rtgvhWt2wiBs2A06/Ul/OoSfXNc2/3L2jsakEPmAHJvjcF ZRg9kv6LKaVhFU90+hEVGNNeh8Fyv0qp3n+DAdtSklU+l48XiVptUfwj0LH2N99hOAbU JkQegoO3t/h4mhH7VmCSTQOrfHoXbjktjtzx+zBTtP/hPOxNFxcgA/Jg6siAaCnzEneD Sc2Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-language:content-transfer-encoding :in-reply-to:mime-version:user-agent:date:message-id:organization :from:references:cc:to:subject; bh=srWuu8ocZYRR0z1hh0sts5sMm5j0auYIyePaB8LVwmQ=; b=C3YiwZ+iMjKNYtmPmMq6fj83l8uxFDTtPNtAL54G0kpwwC8LnY2VrAIQzz3K3YfnvU 9RgRiY4YOXv2cSguWrBU7XzTRRqmSF/Ly5rtctqa2juacipTr+yZdyy6v8JbIlLFAdPj zIwkaUmcMewhQu9aAyFxnBxN3nXFR+EKZ9SzN2MktY9Z9I+g+9+jHpzCKt2j2vgelaNc 6MU5UwNzqUumZuJoUtZJ9k3Cy3j0K/Fak9bNiA0McdVk3NXHLMEEZJXrvbwSu9hsF3Pi 2cPj+uSaf90rCprIfRNsIZAN4GCXeFvcQS0MFvmSJvD1e8vgbropYfrQbeFJHsvVbeSd fj0A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id q21si4656093ejo.166.2021.02.25.17.20.36; Thu, 25 Feb 2021 17:21:00 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229949AbhBZBRk (ORCPT + 99 others); Thu, 25 Feb 2021 20:17:40 -0500 Received: from regular1.263xmail.com ([211.150.70.203]:51028 "EHLO regular1.263xmail.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229915AbhBZBRb (ORCPT ); Thu, 25 Feb 2021 20:17:31 -0500 Received: from localhost (unknown [192.168.167.130]) by regular1.263xmail.com (Postfix) with ESMTP id 0A1297F0; Fri, 26 Feb 2021 09:11:15 +0800 (CST) X-MAIL-GRAY: 0 X-MAIL-DELIVERY: 1 X-ADDR-CHECKED4: 1 X-ANTISPAM-LEVEL: 2 X-SKE-CHECKED: 1 X-ABS-CHECKED: 1 Received: from [172.16.12.236] (unknown [58.22.7.114]) by smtp.263.net (postfix) whith ESMTP id P21325T140438822438656S1614301874165605_; Fri, 26 Feb 2021 09:11:14 +0800 (CST) X-IP-DOMAINF: 1 X-UNIQUE-TAG: X-RL-SENDER: zhangqing@rock-chips.com X-SENDER: zhangqing@rock-chips.com X-LOGIN-NAME: zhangqing@rock-chips.com X-FST-TO: ulf.hansson@linaro.org X-SENDER-IP: 58.22.7.114 X-ATTACHMENT-NUM: 0 X-System-Flag: 0 Subject: Re: [PATCH v2] PM: runtime: Update device status before letting suppliers suspend To: "Rafael J. Wysocki" , Linux PM Cc: LKML , Ulf Hansson References: <2024466.aZ6alR0V7q@kreacher> From: "elaine.zhang" Organization: rockchip Message-ID: Date: Fri, 26 Feb 2021 09:11:13 +0800 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 MIME-Version: 1.0 In-Reply-To: <2024466.aZ6alR0V7q@kreacher> Content-Type: text/plain; charset=gbk; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi, Rafael: The patch V2 test works well. Tested-by: Elaine Zhang ?? 2021/2/26 ????2:23, Rafael J. Wysocki ะด??: > From: Rafael J. Wysocki > > Because the PM-runtime status of the device is not updated in > __rpm_callback(), attempts to suspend the suppliers of the given > device triggered by rpm_put_suppliers() called by it may fail. > > Fix this by making __rpm_callback() update the device's status to > RPM_SUSPENDED before calling rpm_put_suppliers() if the current > status of the device is RPM_SUSPENDING and the callback just invoked > by it has returned 0 (success). > > While at it, modify the code in __rpm_callback() to always check > the device's PM-runtime status under its PM lock. > > Link: https://lore.kernel.org/linux-pm/CAPDyKFqm06KDw_p8WXsM4dijDbho4bb6T4k50UqqvR1_COsp8g@mail.gmail.com/ > Fixes: 21d5c57b3726 ("PM / runtime: Use device links") > Reported-by: elaine.zhang > Diagnosed-by: Ulf Hansson > Signed-off-by: Rafael J. Wysocki > --- > > v1 -> v2: > * Initialize the "get" variable to avoid a false-positive warning from > the compiler. > > --- > drivers/base/power/runtime.c | 62 +++++++++++++++++++++++++------------------ > 1 file changed, 37 insertions(+), 25 deletions(-) > > Index: linux-pm/drivers/base/power/runtime.c > =================================================================== > --- linux-pm.orig/drivers/base/power/runtime.c > +++ linux-pm/drivers/base/power/runtime.c > @@ -325,22 +325,22 @@ static void rpm_put_suppliers(struct dev > static int __rpm_callback(int (*cb)(struct device *), struct device *dev) > __releases(&dev->power.lock) __acquires(&dev->power.lock) > { > - int retval, idx; > bool use_links = dev->power.links_count > 0; > + bool get = false; > + int retval, idx; > + bool put; > > if (dev->power.irq_safe) { > spin_unlock(&dev->power.lock); > + } else if (!use_links) { > + spin_unlock_irq(&dev->power.lock); > } else { > + get = dev->power.runtime_status == RPM_RESUMING; > + > spin_unlock_irq(&dev->power.lock); > > - /* > - * Resume suppliers if necessary. > - * > - * The device's runtime PM status cannot change until this > - * routine returns, so it is safe to read the status outside of > - * the lock. > - */ > - if (use_links && dev->power.runtime_status == RPM_RESUMING) { > + /* Resume suppliers if necessary. */ > + if (get) { > idx = device_links_read_lock(); > > retval = rpm_get_suppliers(dev); > @@ -355,24 +355,36 @@ static int __rpm_callback(int (*cb)(stru > > if (dev->power.irq_safe) { > spin_lock(&dev->power.lock); > - } else { > - /* > - * If the device is suspending and the callback has returned > - * success, drop the usage counters of the suppliers that have > - * been reference counted on its resume. > - * > - * Do that if resume fails too. > - */ > - if (use_links > - && ((dev->power.runtime_status == RPM_SUSPENDING && !retval) > - || (dev->power.runtime_status == RPM_RESUMING && retval))) { > - idx = device_links_read_lock(); > + return retval; > + } > > - fail: > - rpm_put_suppliers(dev); > + spin_lock_irq(&dev->power.lock); > > - device_links_read_unlock(idx); > - } > + if (!use_links) > + return retval; > + > + /* > + * If the device is suspending and the callback has returned success, > + * drop the usage counters of the suppliers that have been reference > + * counted on its resume. > + * > + * Do that if the resume fails too. > + */ > + put = dev->power.runtime_status == RPM_SUSPENDING && !retval; > + if (put) > + __update_runtime_status(dev, RPM_SUSPENDED); > + else > + put = get && retval; > + > + if (put) { > + spin_unlock_irq(&dev->power.lock); > + > + idx = device_links_read_lock(); > + > +fail: > + rpm_put_suppliers(dev); > + > + device_links_read_unlock(idx); > > spin_lock_irq(&dev->power.lock); > } > > > > > >