Linux wireless drivers development
 help / color / mirror / Atom feed
From: Kavita Kavita <kavita.kavita@oss.qualcomm.com>
To: Carlos Llamas <cmllamas@google.com>
Cc: johannes@sipsolutions.net, linux-wireless@vger.kernel.org
Subject: Re: [PATCH wireless-next v2] wifi: cfg80211: fix regulatory.db async firmware request blocking __usermodehelper_disable()
Date: Tue, 14 Jul 2026 11:31:54 +0530	[thread overview]
Message-ID: <5703dd0b-b2b8-4652-985b-a1034ef936d2@oss.qualcomm.com> (raw)
In-Reply-To: <akQDnwSpBb-yTuLA@google.com>



On 6/30/2026 11:27 PM, Carlos Llamas wrote:
> On Tue, Jun 30, 2026 at 04:53:45PM +0000, Carlos Llamas wrote:
>> On Mon, Jun 29, 2026 at 12:01:59PM +0530, Kavita Kavita wrote:
>>> cfg80211 schedules an asynchronous request_firmware() work item for
>>> regulatory.db via request_firmware_work_func(). When the direct
>>> firmware load fails, _request_firmware() falls back to the sysfs
>>> fallback path via firmware_fallback_sysfs(), which blocks indefinitely
>>> in wait_for_completion_killable_timeout() waiting for userspace to
>>> supply the firmware through the sysfs interface.
>>>
>>> While this work item is pending, any caller of
>>> __usermodehelper_disable() will deadlock attempting to acquire the
>>> usermodehelper rwsem for writing, since the sysfs firmware fallback
>>> path holds the rwsem for reading and is blocked waiting for userspace
>>> response that can never arrive while usermode helpers are being
>>> disabled.
>>>
>>> Observed call traces where system suspend blocked due to regulatory.db
>>> async firmware request:
>>>
>>>   kworker/6:3 (pid 194) holding usermodehelper rwsem read lock, blocked
>>>    waiting for userspace firmware response:
>>>      wait_for_completion_killable_timeout+0x48
>>>      firmware_fallback_sysfs+0x270
>>>      _request_firmware+0x790
>>>      request_firmware_work_func+0x44
>>>      process_one_work[jt]+0x59c
>>>      worker_thread+0x260
>>>      kthread+0x150
>>>      ret_from_fork+0x10
>>>
>>>   Caller blocked in __usermodehelper_disable() during system suspend:
>>>      rwsem_down_write_slowpath+0x768
>>>      down_write+0x98
>>>      __usermodehelper_disable+0x3c
>>>      freeze_processes+0x18
>>>      pm_suspend+0x320
>>>      state_store+0x104
>>>      kernfs_fop_write_iter[jt]+0x168
>>>      vfs_write+0x270
>>>      ksys_write+0x78
>>>
>>> Any service or kernel subsystem invoking __usermodehelper_disable() is
>>> susceptible to this hang as long as the regulatory.db sysfs fallback
>>> request remains outstanding.
>>>
>>> Fix this by replacing the unconditional uevent-based load with a
>>> two-step approach. First, attempt a synchronous load via
>>> request_firmware_direct() at init time. This is fast and
>>> non-blocking, if the file is present in standard paths it is loaded
>>> immediately with no delay. If not found, the load is deferred to
>>> wiphy_regulatory_register() and triggered via
>>> firmware_request_nowait_nowarn() only when the first non-self-managed
>>> wiphy registers.
>>>
>>> For self-managed drivers (REGULATORY_WIPHY_SELF_MANAGED), the hang is
>>> avoided because wiphy_regulatory_register() handles them separately
>>> and the deferred load path is never reached, so the file load is not
>>> attempted at all. For this case, regulatory information is obtained
>>> from driver/firmware during wiphy registration. For non-self-managed
>>> drivers, the file is required and is expected to be present. The
>>> deferred load via firmware_request_nowait_nowarn() is triggered only
>>> when the first such wiphy registers. This ensures the database is
>>> loaded only when it is actually needed, avoiding the sysfs fallback
>>> path on systems where the file is absent at init time.
>>>
>>> Also refactor regdb_fw_cb() into two functions: regdb_load() which
>>> validates and stores the firmware image, and regdb_fw_cb_restore()
>>> which is the async callback that calls restore_regulatory_settings()
>>> to replay all pending regulatory requests (country hints from core,
>>> user, driver and country IE) that arrived while the database was not
>>> yet available.
>>>
>>> NOTE:
>>> This issue was observed on Android platforms where regulatory.db is
>>> absent.
>>> Steps to reproduce on Android platforms:
>>>   1. Power off the device completely.
>>>   2. Connect the charger; the device enters off-mode charging.
>>>   3. While in off-mode charging, short press the power key.
>>
>> Can you confirm that you see this with !FW_LOADER_USER_HELPER_FALLBACK?
>> IIUC, this is disabled in Android and shouldn't trigger this path?



Yes, FW_LOADER_USER_HELPER_FALLBACK is disabled by default. However, on our
platforms, force_sysfs_fallback is explicitly set to 1 through a vendor init script,
which causes the udev fallback path to be used.


> 
> Also, you mentioned this happend while on "off-mode charging". So maybe
> don't set force_sysfs_fallback and attempt to load cfg8011 module here?




Well, this is one workaround. However, we cannot simply disable force_sysfs_fallback.
It is required for our firmware loading use cases in both off-mode charging and
normal boot modes.

The main purpose of this patch is to avoid attempting to load regulatory.db when
it is not needed.


> 
> Anyway, this is orthogonal to this patch. It seems that holding the lock
> (read) with a long timeout (60sec?) _and_ trigger a suspend right after
> will fall under this trap as you mentioned. It seems a fairly easy thing
> to reproduce on vanilla distros I would think?



Yes, the issue is easy to reproduce. However, we have not tested it on vanilla
distros.



> 
> --
> Carlos Llamas


  reply	other threads:[~2026-07-14  6:02 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-29  6:31 [PATCH wireless-next v2] wifi: cfg80211: fix regulatory.db async firmware request blocking __usermodehelper_disable() Kavita Kavita
2026-06-30 16:53 ` Carlos Llamas
2026-06-30 17:57   ` Carlos Llamas
2026-07-14  6:01     ` Kavita Kavita [this message]
2026-07-20  4:56 ` Kavita Kavita
2026-07-21 22:05   ` Johannes Berg

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=5703dd0b-b2b8-4652-985b-a1034ef936d2@oss.qualcomm.com \
    --to=kavita.kavita@oss.qualcomm.com \
    --cc=cmllamas@google.com \
    --cc=johannes@sipsolutions.net \
    --cc=linux-wireless@vger.kernel.org \
    /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