Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Queuing work during CPU idle entry wakes a kworker and sets TIF_NEED_RESCHED on a CPU entering deep sleep, violating scheduler invariants.
- [High] A race condition between atomic_inc() and queue_work() leads to a Use-After-Free (UAF) of the coresight device.
--
--- Patch [1]: [PATCH v2] coresight: Fix scheduling while atomic in coresight_put_percpu_source_ref() ---
commit c63df14eb6cc796f6fe14d3388c86e37be66c857
Author: Mohamed Ayman <[email protected]>
coresight: Fix scheduling while atomic in coresight_put_percpu_source_ref()
This commit fixes a "scheduling while atomic" panic on PREEMPT_RT by
deferring the put_device() call to a dedicated workqueue. It introduces
a put_pending atomic counter and a work_struct to queue the release
safely in process context.
> diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
> index 6d65c43d574fd..e931e6bdc84fa 100644
> --- a/drivers/hwtracing/coresight/coresight-core.c
> +++ b/drivers/hwtracing/coresight/coresight-core.c
[ ... ]
> @@ -163,16 +175,9 @@ void coresight_put_percpu_source_ref(struct coresight_device *csdev)
> if (!csdev || !coresight_is_percpu_source(csdev))
> return;
>
> - guard(raw_spinlock_irqsave)(&coresight_dev_lock);
> + atomic_inc(&csdev->put_pending);
>
> - /*
> - * TODO: coresight_device_release() is invoked to release resources when
> - * the device's refcount reaches zero. It then calls free_percpu(),
> - * which acquires pcpu_lock — a sleepable lock when PREEMPT_RT is
> - * enabled. Since the raw spinlock coresight_dev_lock is held, this can
> - * lead to a potential "scheduling while atomic" issue.
> - */
> - put_device(&csdev->dev);
> + queue_work(coresight_wq, &csdev->put_work);
[Severity: High]
Can a race condition here lead to a use-after-free of the coresight device?
If Thread A calls atomic_inc() and is preempted before calling queue_work(),
and Thread B then calls atomic_inc() and queue_work(), the worker thread
might execute coresight_put_device_work(), read the combined pending count,
and free the device before Thread A resumes.
When Thread A resumes, would it execute queue_work() using a pointer that
now resides in freed memory?
[Severity: High]
Does queuing work here violate scheduler invariants during CPU idle entry?
Since coresight_cpu_pm_notify() calls this during cpu_pm_enter() with
interrupts disabled, the CPU is already committed to sleeping. Calling
queue_work() on a bound workqueue wakes a local kworker, adding it to the
runqueue and setting TIF_NEED_RESCHED on the current CPU.
Will the CPU enter a deep hardware sleep with a runnable task on its runqueue,
delaying the execution of the kworker until an external hardware interrupt
wakes the CPU and breaking the invariant that nr_running must be 0 when
entering idle?
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.