public inbox for stable@vger.kernel.org
 help / color / mirror / Atom feed
From: Wesley Cheng <wesley.cheng@oss.qualcomm.com>
To: Guan-Yu Lin <guanyulin@google.com>
Cc: gregkh@linuxfoundation.org, mathias.nyman@intel.com,
	perex@perex.cz, tiwai@suse.com, quic_wcheng@quicinc.com,
	broonie@kernel.org, arnd@arndb.de, christophe.jaillet@wanadoo.fr,
	xiaopei01@kylinos.cn, linux-usb@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org,
	stable@vger.kernel.org, Hailong Liu <hailong.liu@oppo.com>
Subject: Re: [PATCH v2 1/2] usb: offload: move device locking to callers in offload.c
Date: Wed, 18 Mar 2026 17:24:12 -0700	[thread overview]
Message-ID: <4e551ffa-1952-42a9-8f92-d77445134cb9@oss.qualcomm.com> (raw)
In-Reply-To: <CAOuDEK3b4BtHVYhLH_NkE1fP1-9ncqvAq6VedBzWLm=D_YDHQg@mail.gmail.com>



On 3/18/2026 4:21 PM, Guan-Yu Lin wrote:
> On Tue, Mar 17, 2026 at 4:17 PM Wesley Cheng
> <wesley.cheng@oss.qualcomm.com> wrote:
>>
>> On 3/8/2026 7:22 PM, Guan-Yu Lin wrote:
>>>
>>> @@ -27,31 +28,25 @@ int usb_offload_get(struct usb_device *udev)
>>>    {
>>>        int ret;
>>>
>>> -     usb_lock_device(udev);
>>> -     if (udev->state == USB_STATE_NOTATTACHED) {
>>> -             usb_unlock_device(udev);
>>> +     device_lock_assert(&udev->dev);
>>> +
>>> +     if (udev->state == USB_STATE_NOTATTACHED)
>>>                return -ENODEV;
>>> -     }
> 
> Could be removed. Since the udev is in USB_STATE_NOTATTACHED. I expect
> the data structure being cleaned afterwards, so actually counter value
> might not be important at this moment.
> 
>>>
>>>        if (udev->state == USB_STATE_SUSPENDED ||
>>> -                udev->offload_at_suspend) {
>>> -             usb_unlock_device(udev);
>>> +         udev->offload_at_suspend)
>>>                return -EBUSY;
>>> -     }
>>>
> 
> This check is still required. Because the suspend/resume process
> depends on the counter value, we can't modify the counter value while
> the device is suspended. If we do so, we will have an unbalanced
> suspend resume operation.
> 
> However, we might only need to check for udev->offload_at_suspend (if
> we ensure the device is active when we want to incremant the counter):
> 1. If the offload_usage_count is 0, we won't decrement counts at this moment.
> 2. If the offload_usage_count is not 0, the offload_at_suspend flag
> will be true anyway.
> 
>>
>> Do we really need to be explicitly checking for the usb device state before
>> we touch the offload_usage count?  In the end, its a reference count that
>> determines how many consumers are active for a specific interrupter, so my
>> question revolves around if we need to have such strict checks.
>>
> 
> Please find the explanation for each check above.
> 
>>>        /*
>>>         * offload_usage could only be modified when the device is active, since
>>>         * it will alter the suspend flow of the device.
>>>         */
>>>        ret = usb_autoresume_device(udev);
>>> -     if (ret < 0) {
>>> -             usb_unlock_device(udev);
>>> +     if (ret < 0)
>>>                return ret;
>>> -     }
>>>
>>
>> IMO this should be handled already by the class driver, and if not, what is
>> the harm?
>>
> 
> We can only increment the usage count when the device is active. For
> counter decrement, the device could be in any state.
> 
> My initial design is to resume the device and then modify the usage
> count. Another option is to check only whether the USB device is
> active via pm_runtime_get_if_active, and leave the device-resuming
> effort to the class driver. Do you think this is the better approach?
> 

I think I prefer the active check over RPM versus forcing a device resume.

>>>        udev->offload_usage++;
>>>        usb_autosuspend_device(udev);
>>> -     usb_unlock_device(udev);
>>>
>>>        return ret;
>>>    }
>>> @@ -64,6 +59,7 @@ EXPORT_SYMBOL_GPL(usb_offload_get);
>>>     * The inverse operation of usb_offload_get, which drops the offload_usage of
>>>     * a USB device. This information allows the USB driver to adjust its power
>>>     * management policy based on offload activity.
>>> + * The caller must hold @udev's device lock.
>>>     *
>>>     * Return: 0 on success. A negative error code otherwise.
>>>     */
>>> @@ -71,33 +67,27 @@ int usb_offload_put(struct usb_device *udev)
>>>    {
>>>        int ret;
>>>
>>> -     usb_lock_device(udev);
>>> -     if (udev->state == USB_STATE_NOTATTACHED) {
>>> -             usb_unlock_device(udev);
>>> +     device_lock_assert(&udev->dev);
>>> +
>>> +     if (udev->state == USB_STATE_NOTATTACHED)
>>>                return -ENODEV;
>>> -     }
>>>
>>>        if (udev->state == USB_STATE_SUSPENDED ||
>>> -                udev->offload_at_suspend) {
>>> -             usb_unlock_device(udev);
>>> +         udev->offload_at_suspend)
>>>                return -EBUSY;
>>> -     }
>>>
>>
>> During your testing, did you ever run into any unbalanced counter issues
>> due to the above early exit conditions?
>>
>> I guess these are all just questions to see if we can remove the need to
>> lock the udev mutex, and move to a local mutex for the offload framework.
>> That would address the locking concerns being brought up by Greg, etc...
>>
>> Thanks
>> Wesley Cheng
>>
> 
> While developing the initial patch set, I did encounter the counter imbalance.
> 
> Following the discussion, we could move the device resume effort to
> the class driver. This way we only need to check if the device is
> active before manipulating the offload usage counter, which doesn't
> require a device lock. Is there any concern with this approach?
> 

I think that is what I was getting to.  Now, instead of having to rely on 
the udev lock, you can protect the counter using a local mutex, which 
should avoid the deadlock mentioned by Oppo.  You can avoid also having the 
class driver worry about locking requirements, etc..

Thanks
Wesley Cheng


  reply	other threads:[~2026-03-19  0:24 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20260309022205.28136-1-guanyulin@google.com>
2026-03-09  2:22 ` [PATCH v2 1/2] usb: offload: move device locking to callers in offload.c Guan-Yu Lin
2026-03-11 12:26   ` Greg KH
2026-03-12 17:23     ` Guan-Yu Lin
2026-03-17 21:17   ` Wesley Cheng
2026-03-18 23:21     ` Guan-Yu Lin
2026-03-19  0:24       ` Wesley Cheng [this message]
2026-03-09  2:22 ` [PATCH v2 2/2] ALSA: usb: qcom: manage offload device usage Guan-Yu Lin
2026-03-11 12:31   ` Greg KH
2026-03-12 17:24     ` Guan-Yu Lin
2026-03-17 20:45       ` Guan-Yu Lin
2026-03-18  5:58         ` Greg KH
2026-03-18 23:29           ` Guan-Yu Lin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4e551ffa-1952-42a9-8f92-d77445134cb9@oss.qualcomm.com \
    --to=wesley.cheng@oss.qualcomm.com \
    --cc=arnd@arndb.de \
    --cc=broonie@kernel.org \
    --cc=christophe.jaillet@wanadoo.fr \
    --cc=gregkh@linuxfoundation.org \
    --cc=guanyulin@google.com \
    --cc=hailong.liu@oppo.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mathias.nyman@intel.com \
    --cc=perex@perex.cz \
    --cc=quic_wcheng@quicinc.com \
    --cc=stable@vger.kernel.org \
    --cc=tiwai@suse.com \
    --cc=xiaopei01@kylinos.cn \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox