Skip to content

Fix the clock counter imbalance issues on Coresight Platform drivers - #1771

Merged
Jie Gan (jiegan0107) merged 3 commits into
qualcomm-linux:tech/debug/hwtracingfrom
jiegan0107:tech/debug/hwtracing
Sep 7, 2026
Merged

Fix the clock counter imbalance issues on Coresight Platform drivers#1771
Jie Gan (jiegan0107) merged 3 commits into
qualcomm-linux:tech/debug/hwtracingfrom
jiegan0107:tech/debug/hwtracing

Conversation

@jiegan0107

Copy link
Copy Markdown
  1. clk counter issue on platform remove path
  2. clk counter issue on probe fail path

…ailure

Each CoreSight platform_driver's probe() enables its clocks via
coresight_get_enable_clocks() -> devm_clk_get_optional_enabled(), which
registers a devm cleanup to run clk_disable_unprepare() on driver
detach. The probe wrapper then unconditionally calls pm_runtime_put()
regardless of whether the inner probe succeeded, so on failure this
also fires runtime_suspend() and disables the same clocks a first
time. The driver core then unwinds the failed probe and runs the devm
cleanup, disabling them a second time and underflowing the refcount:

  coresight-etm4x etm0: probe with driver coresight-etm4x failed with error -22
  ------------[ cut here ]------------
  qdss_clk already disabled
  WARNING: CPU: 1 PID: 432 at drivers/clk/clk.c:1188 clk_core_disable+0x1d0/0x218
  ...
  ------------[ cut here ]------------
  Unpreparing enabled qdss_clk
  WARNING: CPU: 0 PID: 432 at drivers/clk/clk.c:1061 clk_core_unprepare+0x248/0x268
  ...

qdss_clk is shared by every CoreSight node, so the extra disable drives
its refcount to 0 while sibling devices still expect it enabled. The
next funnel to probe then touches unclocked hardware and panics:

  SError Interrupt on CPU1, code 0x00000000be000000 -- SError
  Kernel panic - not syncing: Asynchronous SError Interrupt
  ...
   coresight_clear_self_claim_tag+0x7c/0x1e0 [coresight] (P)
   funnel_probe+0x114/0x2e0 [coresight_funnel]
   dynamic_funnel_probe+0x24/0x70 [coresight_funnel]

Use pm_runtime_put_noidle() instead of pm_runtime_put() on the failure
path so it drops the usage count without invoking runtime_suspend(),
leaving the devm cleanup as the sole disabler.

Affects catu, ctcu, etm4x, funnel, replicator, stm, tmc, tpiu and tnoc,
all of which share this probe skeleton.

Link: https://lore.kernel.org/all/20260907-fix-clk-issue-v1-1-efe81fa2b697@oss.qualcomm.com/
Fixes: 1abc1b2 ("coresight: Appropriately disable programming clocks")
Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
coresight_get_enable_clocks() enables the programming clock and the
optional AT clock through devm_clk_get_optional_enabled(), which also
registers a devm action to call clk_disable_unprepare() when the driver
detaches.

After probe, pm_runtime_put() allows the device to suspend and the
runtime suspend callback disables the same clocks. During remove the
device is left runtime suspended, so pm_runtime_disable() freezes it
with the clocks already disabled. The devm cleanup that runs afterwards
calls clk_disable_unprepare() a second time, underflowing the clock
enable refcount.

Resume the device with pm_runtime_get_sync() before tearing it down so
the clocks are enabled again and balance the devm-managed disable. Then
pm_runtime_set_suspended() and pm_runtime_put_noidle() leave the device
in a coherent runtime PM state (suspended, usage count balanced) once
the devm action has disabled the clocks.

This affects all CoreSight platform drivers that obtain their clocks
through coresight_get_enable_clocks(): catu, cpu-debug, ctcu, etm4x,
funnel, replicator, stm, tmc and tpiu.

Link: https://lore.kernel.org/all/20260710-fix-clock-refcount-unbalance-v3-1-a37a1fb17981@oss.qualcomm.com/
Fixes: 1abc1b2 ("coresight: Appropriately disable programming clocks")
Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>
Reviewed-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
…emove

coresight_get_enable_clocks() enables the programming clock through
devm_clk_get_optional_enabled(), which also registers a devm action to
call clk_disable_unprepare() when the driver detaches.

After probe, pm_runtime_put() allows the device to suspend and the
runtime suspend callback disables the clock. During remove the device is
left runtime suspended, so pm_runtime_disable() freezes it with the
clock already disabled. The devm cleanup that runs afterwards calls
clk_disable_unprepare() a second time, underflowing the clock enable
refcount.

Resume the device with pm_runtime_get_sync() before tearing it down so
the clock is enabled again and balances the devm-managed disable. Then
pm_runtime_set_suspended() and pm_runtime_put_noidle() leave the device
in a coherent runtime PM state (suspended, usage count balanced) once
the devm action has disabled the clock.

Link: https://lore.kernel.org/all/20260710-fix-clock-refcount-unbalance-v3-2-a37a1fb17981@oss.qualcomm.com/
Fixes: 1abc1b2 ("coresight: Appropriately disable programming clocks")
Reviewed-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
@qcomlnxci
qcomlnxci requested review from a team and Tingwei Zhang (quic-tingweiz) and removed request for a team September 7, 2026 06:33
@jiegan0107
Jie Gan (jiegan0107) merged commit a319052 into qualcomm-linux:tech/debug/hwtracing Sep 7, 2026
3 of 7 checks passed
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.

1 participant