Skip to content

cpuidle/pmdomain: Correctly track state of excluded CPU clusters - #1671

Open
maulik-k-shah wants to merge 2 commits into
qualcomm-linux:tech/pm/powerfrom
maulik-k-shah:tech/pm/power
Open

cpuidle/pmdomain: Correctly track state of excluded CPU clusters#1671
maulik-k-shah wants to merge 2 commits into
qualcomm-linux:tech/pm/powerfrom
maulik-k-shah:tech/pm/power

Conversation

@maulik-k-shah

Copy link
Copy Markdown
Contributor

Merge https://lore.kernel.org/linux-arm-msm/20260811-domain_off_ss3-v1-0-6a0a0fc023f5@oss.qualcomm.com/T/#mfdbefe6efdfc0596ba81f194ef5102d6a0f7348c

This allows pmdomain to start with OFF state instead of ON state helping on monaco single core boot up.

CRs-Fixed: 4428933

psci_pd_init() always calls pm_genpd_init() with is_off=false, so a
CPU-cluster pmdomain is marked ON at creation regardless of whether any
CPU has actually powered it on yet. The pmdomain's own status tracking
(and the power-on notifier chain fired from _genpd_power_on()) is
therefore wrong from the outset for OSI mode.

A concrete example: hamoa has 3 CPU clusters, each with 4 CPUs, under a
single parent system-level pmdomain. Passing "maxcpus=4" on the kernel
command line limits boot to the first 4 CPUs, so only cluster0 is ever
actually powered on. Without this fix, cluster1 and cluster2 are still
marked ON at creation regardless, since is_off is always false. Because
none of their CPUs ever come online, neither dt_idle_attach_cpu() nor
psci_idle_cpuhp_up() ever fires for them, so nothing subsequently
drives those two domains to OFF - they stay marked ON for as long as
the system runs. When cluster0's CPUs go idle and its pmdomain is
powered off, the parent system-level pmdomain still sees cluster1 and
cluster2 as ON and therefore never selects a system-level idle state,
even though no CPU in those two clusters ever executed.

Starting the domain OFF is safe under OSI:

 - For CPUs already online by the time this driver probes,
   dt_idle_attach_cpu() explicitly checks cpu_online() and calls
   pm_runtime_get_sync() on the CPU's attach device, which resolves to
   this same pmdomain and drives a real power-on immediately. This runs
   from psci_cpuidle_probe(), a device_initcall, strictly after
   psci_idle_init_domains()'s core_initcall has already created and
   marked off every pmdomain, so there is no window where an online
   CPU's domain is left off with nothing left to turn it on.

 - For CPUs that come online later, psci_idle_cpuhp_up() (registered
   via cpuhp_setup_state_nocalls(), which never invokes the callback
   for already-online CPUs at registration time) powers the domain on
   through the normal cpuhp AP_ONLINE path.

Gate this on use_osi rather than applying it unconditionally: in
non-OSI mode psci_pd_init() sets GENPD_FLAG_ALWAYS_ON, which
independently blocks genpd_power_off() regardless of is_off, so the
domain can never really be off there and marking it is_off=true would
be misleading noise with no effect.

Link: https://lore.kernel.org/linux-arm-msm/20260811-domain_off_ss3-v1-0-6a0a0fc023f5@oss.qualcomm.com/T/#m2ca7c431b37ac9431179d8f21c3134a1823a00c7
Fixes: a65a397 ("cpuidle: psci: Add support for PM domains by using genpd")
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Maulik Shah <maulik.shah@oss.qualcomm.com>
…FF domains

pm_genpd_init() sets genpd->status from is_off but never touches state_idx,
which stays at its kzalloc'd value of 0 (dt_idle_pd_alloc()) regardless of
is_off. A domain that starts OFF without ever having gone through an actual
power-off sequence is therefore left looking like it's parked at its
shallowest idle state (state_idx=0) instead of its deepest one, even though
it is fully powered down.

This is visible on hamoa, where cluster0/1/2 each expose two idle states,
CL4 (state_idx=0) and CL5 (state_idx=1, the deepest). When CPU-cluster
genpds are initialised directly into GENPD_STATE_OFF under OSI mode
("cpuidle: psci: Start CPU-cluster pmdomain OFF when OSI is used"),
clusters whose CPUs are excluded at boot (e.g. maxcpus=4, leaving clusters
1 and 2 untouched) never go through a power-off path, so their state_idx
remains 0 instead of the deepest 1. debugfs reports this as "off-0",
meaning the domain is off but parked at idle-state 0 (CL4) rather than
"off-1", idle-state 1 (CL5):

genpd_power_off() and genpd_sync_power_off() both gate parent power-off on
every child being at its deepest state index:

  if (child->state_idx < child->state_count - 1)
      return;

so the parent's check treats these fully-off children as "not yet at
deepest state" and refuses to power off, blocking the deepest system-level
low-power mode (SS3) from ever being entered.

Without this change:

  $ cat .../power-domain-cpu-cluster1/current_state
  off-0

  $ cat /sys/kernel/debug/qcom_stats/apss
  Count: 0
  Last Entered At: 0
  Last Exited At: 0
  Accumulated Duration: 0

Fix this at the source: when a domain is initialised OFF, set its state_idx
to its deepest state (state_count - 1) instead of leaving it at 0. This
makes genpd's reported state consistent with reality for every is_off=true
caller of pm_genpd_init(), not just the PSCI CPU-cluster case, and requires
no special-casing in the parent power-off checks.

With this change, the domain correctly reports its deepest state and SS3
is entered normally:

  $ cat .../power-domain-cpu-cluster1/current_state
  off-1

  $ cat /sys/kernel/debug/qcom_stats/apss
  Count: 218
  Last Entered At: 726792712
  Last Exited At: 726950687
  Accumulated Duration: 199888773

Link: https://lore.kernel.org/linux-arm-msm/20260811-domain_off_ss3-v1-0-6a0a0fc023f5@oss.qualcomm.com/T/#m6c0e0622ef5514fba8ec7a7b41b69e5e90e21fb0
Fixes: e7d90cf ("PM: domains: Prevent power off for parent unless child is in deepest state")
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Maulik Shah <maulik.shah@oss.qualcomm.com>
@qcomlnxci
qcomlnxci requested review from a team and smankad-oss and removed request for a team August 11, 2026 10:39
@qlijarvis

Copy link
Copy Markdown

PR #1671 — validate-patch

PR: #1671

Verdict Issues Detailed Report
⚠️ 0 Full report

Final Summary

  1. Lore link present: Yes - both patches include proper Link: tags pointing to https://lore.kernel.org/linux-arm-msm/20260811-domain_off_ss3-v1-0-6a0a0fc023f5@oss.qualcomm.com/
  2. Lore link matches PR commits: Cannot verify - lore fetch returned HTTP 403 (patches posted today 2026-08-11, likely not indexed yet)
  3. Upstream patch status: ⏳ Decision Pending - patches posted today (2026-08-11), no maintainer response yet; lore thread currently inaccessible (HTTP 403)
  4. PR present in qcom-next/topics: Fail - 1/2 commit(s) are missing from both qcom-next and topics
Verdict: ⚠️ — click to expand

🔍 Patch Validation

PR: #1671 - FROMLIST: cpuidle/pmdomain fixes for CPU-cluster domain initialization
Upstream commit: https://lore.kernel.org/linux-arm-msm/20260811-domain_off_ss3-v1-0-6a0a0fc023f5@oss.qualcomm.com/
Verdict: ⚠️ PARTIAL

Commit Message

Patch 1/2: cpuidle: psci: Start CPU-cluster pmdomain OFF when OSI is used

Check Status Note
Subject matches upstream ⚠️ Cannot verify - lore fetch returned 403 (patch posted today 2026-08-11)
Body preserves rationale ⚠️ Cannot verify - lore source unavailable
Fixes tag present/correct Fixes: a65a397f2451 present with proper format
Authorship preserved ⚠️ Cannot verify - lore source unavailable; From: is Maulik Shah
Backport note (if applicable) N/A FROMLIST prefix - not a backport
Co-developed-by usage Not used
Assisted-by usage ⚠️ Assisted-by: Claude:claude-sonnet-5 present - unusual but not incorrect

Patch 2/2: pmdomain: core: Initialize state_idx to deepest state for OFF domains

Check Status Note
Subject matches upstream ⚠️ Cannot verify - lore fetch returned 403 (patch posted today 2026-08-11)
Body preserves rationale ⚠️ Cannot verify - lore source unavailable
Fixes tag present/correct Fixes: e7d90cfac551 present with proper format
Authorship preserved ⚠️ Cannot verify - lore source unavailable; From: is Maulik Shah
Backport note (if applicable) N/A FROMLIST prefix - not a backport
Co-developed-by usage Not used
Assisted-by usage ⚠️ Assisted-by: Claude:claude-sonnet-5 present - unusual but not incorrect

Diff

Patch 1/2: drivers/cpuidle/cpuidle-psci-domain.c

File Status Notes
drivers/cpuidle/cpuidle-psci-domain.c ⚠️ Cannot verify against lore - changes pm_genpd_init() call from false to use_osi with detailed comment explaining OSI-specific initialization

Patch 2/2: drivers/pmdomain/core.c

File Status Notes
drivers/pmdomain/core.c ⚠️ Cannot verify against lore - adds 2-line initialization of state_idx when is_off && state_count

Issues

  1. Lore source unavailable: Both lore.kernel.org links returned HTTP 403 errors when fetched. The patches are dated 2026-08-11 (today), suggesting they were just posted and may not be indexed yet, or there's a temporary access restriction. Cannot verify diff faithfulness to upstream source.

  2. Assisted-by trailer: Both commits include Assisted-by: Claude:claude-sonnet-5. While this is not a standard kernel trailer, it's not explicitly forbidden. The kernel documentation mentions Co-developed-by:, Reviewed-by:, Acked-by:, Tested-by:, etc., but does not define Assisted-by:. This may draw questions during upstream review.

  3. Integration presence: According to integration_presence_report.md:

    • Patch 1/2: missing from both qcom-next and topics
    • Patch 2/2: partial match in qcom-next (subject or partial tree evidence found, but full change not verified)

    For FROMLIST patches posted today, absence from qcom-next is expected. However, the "partial" match for patch 2/2 suggests similar changes may already exist in the tree, which could indicate a conflict or duplicate.

  4. Commit message structure: Both commits are well-structured with:

    • Clear problem statement
    • Concrete example with platform details (hamoa)
    • Detailed explanation of the fix
    • Before/after evidence with debugfs output
    • Proper Link: and Fixes: tags
    • Single Signed-off-by: from the author

Verdict

Cannot fully validate - The lore source is currently inaccessible (HTTP 403), preventing verification of diff faithfulness. Based on available evidence:

  • Commit message quality: Both patches have excellent, detailed commit messages with problem statement, rationale, concrete examples, and before/after evidence
  • Fixes tags: Both include proper Fixes: tags with commit SHA and subject
  • Link tags: Both include proper Link: tags pointing to lore.kernel.org
  • ⚠️ Assisted-by trailer: Non-standard trailer may need clarification during upstream review
  • ⚠️ Integration presence: Patch 2/2 shows "partial" match in qcom-next, suggesting potential conflict
  • Lore verification: Cannot verify diff content matches upstream posting

Recommendation:

  1. Wait for lore indexing: The patches were posted today (2026-08-11). Retry lore fetch in a few hours once the archive has indexed them.

  2. Clarify Assisted-by usage: Consider whether Assisted-by: Claude:claude-sonnet-5 should be included in the upstream submission. If this is for internal tracking only, it could be removed before the patches are merged to mainline.

  3. Investigate patch 2/2 partial match: The integration presence report indicates patch 2/2 has partial evidence in qcom-next. Review whether similar changes already exist to avoid conflicts or duplicates.

  4. Monitor upstream review: Since these are FROMLIST patches under active review, track the lore thread for maintainer feedback, requested changes, or acceptance signals before merging to the topic branch.

Final Summary

  1. Lore link present: Yes - both patches include proper Link: tags pointing to https://lore.kernel.org/linux-arm-msm/20260811-domain_off_ss3-v1-0-6a0a0fc023f5@oss.qualcomm.com/
  2. Lore link matches PR commits: Cannot verify - lore fetch returned HTTP 403 (patches posted today 2026-08-11, likely not indexed yet)
  3. Upstream patch status: ⏳ Decision Pending - patches posted today (2026-08-11), no maintainer response yet; lore thread currently inaccessible (HTTP 403)
  4. PR present in qcom-next/topics: Fail - patch 1/2 missing from both qcom-next and topics; patch 2/2 shows partial match in qcom-next (subject or partial tree evidence found, but full change not verified) - see integration_presence_report.md for details

Deterministic Integration Presence

Integration Presence Report

This report is generated by Jarvis before validate-patch runs.
It is the authoritative source for whether PR changes are already present
in qcom-next or in the kernel topic branches.

Kernel repo: /local/mnt/workspace/sgaud/Qgenie/image_pipeline/kernel
qcom-next ref: 8d5dbc1b17adf8fe86a41adcda686785e73f5414
topics remote: topics -> https://github.com/qualcomm-linux/kernel-topics
topics fetch: fetched

Commit Subject qcom-next topics Final
1/2 [PATCH 1/2] FROMLIST: cpuidle: psci: Start CPU-cluster pmdomain OFF missing - no subject, patch-id, or full tree-content match found missing - no subject, patch-id, or full tree-content match found missing
2/2 [PATCH 2/2] FROMLIST: pmdomain: core: Initialize state_idx to deepest partial - subject or partial tree evidence found, but full change was not verified missing - no subject, patch-id, or full tree-content match found partial

Final Status

overall_status: FAIL
present_commits: 0/2
partial_commits: 1/2
missing_commits: 1/2
topics_checked_for_commits: 2/2
final_summary: PR present in qcom-next/topics: Fail - 1/2 commit(s) are missing from both qcom-next and topics

@qlijarvis

Copy link
Copy Markdown

PR #1671 — checker-log-analyzer

PR: #1671
Checker run: https://github.com/qualcomm-linux/kernel-config/actions/runs/31483142943

Checker Result Summary
Checker Result Summary
checkpatch All commits pass style checks
dt-binding-check ⏭️ Skipped - no DT binding changes
dtb-check ⏭️ Skipped - no devicetree changes
sparse-check No sparse warnings
check-uapi-headers No UAPI changes
check-patch-compliance Link validation failed (timing issue)
tag-check All commits have valid FROMLIST: prefix

Detailed report: Full report

Checker analysis — click to expand

🤖 CI Checker Analysis (checker-log-analyzer)

PR: #1671 - FROMLIST: cpuidle: psci: Start CPU-cluster pmdomain OFF when OSI is used
Source: https://github.com/qualcomm-linux/kernel-config/actions/runs/31483142943
Target branch: tech/pm/power (kernel-topics)

Checker Result Summary
checkpatch All commits pass style checks
dt-binding-check ⏭️ Skipped - no DT binding changes
dtb-check ⏭️ Skipped - no devicetree changes
sparse-check No sparse warnings
check-uapi-headers No UAPI changes
check-patch-compliance Link validation failed (timing issue)
tag-check All commits have valid FROMLIST: prefix

❌ check-patch-compliance

Root cause: b4 fetch failed because patches were posted to lore.kernel.org immediately before CI ran, and lore had not yet indexed them.

Failure details:

Checking commit: FROMLIST: cpuidle: psci: Start CPU-cluster pmdomain OFF when OSI is used
Something seems wrong with the provided link. Please verify it
Try below command to run locally-
b4 am --single-message -C -l -3 https://lore.kernel.org/linux-arm-msm/20260811-domain_off_ss3-v1-0-6a0a0fc023f5@oss.qualcomm.com/T/#m2ca7c431b37ac9431179d8f21c3134a1823a00c7

Checking commit: FROMLIST: pmdomain: core: Initialize state_idx to deepest state for OFF domains
Something seems wrong with the provided link. Please verify it
Try below command to run locally-
b4 am --single-message -C -l -3 https://lore.kernel.org/linux-arm-msm/20260811-domain_off_ss3-v1-0-6a0a0fc023f5@oss.qualcomm.com/T/#m6c0e0622ef5514fba8ec7a7b41b69e5e90e21fb0

Analysis:

Both commits have:

  • ✅ Valid FROMLIST: prefix (required for target branch tech/pm/power)
  • ✅ Valid Link: trailer pointing to lore.kernel.org
  • ✅ Proper lore URL format with message-ID

The failure is a timing issue: the patches were posted to the mailing list on 2026-08-11 (today), and the CI ran immediately afterward. The lore.kernel.org indexer typically takes 5-15 minutes to process and make new messages available via the public-inbox API that b4 uses. When the checker tried to fetch the patches, they weren't indexed yet.

Fix:

Option 1 (Recommended): Re-trigger the CI workflow after waiting 15-30 minutes. The lore indexer will have processed the messages by then, and check-patch-compliance will pass.

Option 2: Verify the links manually by visiting them in a browser:

If the links are accessible in a browser, the patches are properly posted and the CI failure is purely a timing artifact.

Reproduce locally (after lore indexing completes):

b4 am --single-message -C -l -3 https://lore.kernel.org/linux-arm-msm/20260811-domain_off_ss3-v1-0-6a0a0fc023f5@oss.qualcomm.com/T/#m2ca7c431b37ac9431179d8f21c3134a1823a00c7
b4 am --single-message -C -l -3 https://lore.kernel.org/linux-arm-msm/20260811-domain_off_ss3-v1-0-6a0a0fc023f5@oss.qualcomm.com/T/#m6c0e0622ef5514fba8ec7a7b41b69e5e90e21fb0

✅ tag-check

Status: PASS

All commits in this PR have the required FROMLIST: prefix. Since the target branch is tech/pm/power (not qcom-next or qcom-next-staging), every commit must start with one of the approved prefixes (FROMLIST:, FROMGIT:, UPSTREAM:, BACKPORT:, QCLINUX:, PENDING:, WORKAROUND:).

Commits verified:

  1. FROMLIST: cpuidle: psci: Start CPU-cluster pmdomain OFF when OSI is used
  2. FROMLIST: pmdomain: core: Initialize state_idx to deepest state for OFF domains

Verdict

Ready to merge after re-triggering CI.

The only failure is a timing issue with check-patch-compliance attempting to fetch patches from lore.kernel.org before the indexer had processed them. All other checkers passed cleanly:

  • ✅ Code style is correct (checkpatch)
  • ✅ No sparse warnings
  • ✅ No UAPI/ABI changes
  • ✅ Proper commit prefixes for the target branch
  • ✅ Valid lore.kernel.org links in commit messages

Action required: Re-trigger the CI workflow after 15-30 minutes to allow lore.kernel.org to index the newly posted patches. No code changes needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants