linux-stable/drivers/interconnect
Mike Tipton de1bf25b6d interconnect: Don't access req_list while it's being manipulated
The icc_lock mutex was split into separate icc_lock and icc_bw_lock
mutexes in [1] to avoid lockdep splats. However, this didn't adequately
protect access to icc_node::req_list.

The icc_set_bw() function will eventually iterate over req_list while
only holding icc_bw_lock, but req_list can be modified while only
holding icc_lock. This causes races between icc_set_bw(), of_icc_get(),
and icc_put().

Example A:

  CPU0                               CPU1
  ----                               ----
  icc_set_bw(path_a)
    mutex_lock(&icc_bw_lock);
                                     icc_put(path_b)
                                       mutex_lock(&icc_lock);
    aggregate_requests()
      hlist_for_each_entry(r, ...
                                       hlist_del(...
        <r = invalid pointer>

Example B:

  CPU0                               CPU1
  ----                               ----
  icc_set_bw(path_a)
    mutex_lock(&icc_bw_lock);
                                     path_b = of_icc_get()
                                       of_icc_get_by_index()
                                         mutex_lock(&icc_lock);
                                         path_find()
                                           path_init()
    aggregate_requests()
      hlist_for_each_entry(r, ...
                                             hlist_add_head(...
        <r = invalid pointer>

Fix this by ensuring icc_bw_lock is always held before manipulating
icc_node::req_list. The additional places icc_bw_lock is held don't
perform any memory allocations, so we should still be safe from the
original lockdep splats that motivated the separate locks.

[1] commit af42269c35 ("interconnect: Fix locking for runpm vs reclaim")

Signed-off-by: Mike Tipton <quic_mdtipton@quicinc.com>
Fixes: af42269c35 ("interconnect: Fix locking for runpm vs reclaim")
Reviewed-by: Rob Clark <robdclark@chromium.org>
Link: https://lore.kernel.org/r/20240305225652.22872-1-quic_mdtipton@quicinc.com
Signed-off-by: Georgi Djakov <djakov@kernel.org>
2024-03-14 13:51:44 +02:00
..
imx interconnect: imx8mq: Convert to platform remove callback returning void 2023-11-22 15:57:51 +02:00
qcom interconnect: qcom: x1e80100: Remove inexistent ACV_PERF BCM 2024-03-14 13:51:25 +02:00
samsung interconnect: exynos: Convert to platform remove callback returning void 2023-11-22 15:58:25 +02:00
bulk.c interconnect: add device managed bulk API 2022-07-04 16:14:29 +03:00
core.c interconnect: Don't access req_list while it's being manipulated 2024-03-14 13:51:44 +02:00
debugfs-client.c interconnect: Add debugfs test client 2023-08-22 21:04:50 +03:00
icc-clk.c interconnect: icc-clk: Annotate struct icc_clk_provider with __counted_by 2023-08-22 01:11:09 +03:00
internal.h Merge branch 'icc-debugfs' into icc-next 2023-08-22 21:05:09 +03:00
Kconfig interconnect: add clk-based icc provider support 2023-05-18 19:02:23 +03:00
Makefile interconnect: Add debugfs test client 2023-08-22 21:04:50 +03:00
trace.h interconnect: Add basic tracepoints 2019-12-16 09:25:23 +02:00