summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-04-19 20:12:31 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-04-19 20:12:31 +0000
commit8dfb3666c7b084c6b0f7a512c1717aa5e49129d5 (patch)
tree007e508beee761c3a61592ff97e513f18987f0c1
parenta9a9c07560b0b77bfbbb229e2908fe29e0c6271e (diff)
parent7dab4993ba9166182cc5da785e46b01fc4da8055 (diff)
downloadgs-android-gs-shusky-5.15-android15-beta.tar.gz
Merge cherrypicks of ['partner-android-review.googlesource.com/2778031'] into android14-gs-pixel-5.15-24Q3-release.android-15-beta-1_r0.8android-gs-shusky-5.15-android15-beta
Change-Id: I4c2c2efac5d0735aab243c5a5b7784e64f855c65 Signed-off-by: Coastguard Worker <android-build-coastguard-worker@google.com>
-rw-r--r--drivers/soc/google/pt/pt.c66
1 files changed, 33 insertions, 33 deletions
diff --git a/drivers/soc/google/pt/pt.c b/drivers/soc/google/pt/pt.c
index c012190ba..4dffd341e 100644
--- a/drivers/soc/google/pt/pt.c
+++ b/drivers/soc/google/pt/pt.c
@@ -110,7 +110,9 @@ struct {
/* Data for resize_callback thread */
struct task_struct *resize_thread;
+ struct pt_pts *resize_pts_in_progress; /* callback is in progress */
struct list_head resize_list; /* callback to call */
+ wait_queue_head_t resize_remove_wq; /* wait current callback return */
wait_queue_head_t resize_wq; /* wait for new callback */
} pt_internal_data;
@@ -152,10 +154,10 @@ static void pt_trace(struct pt_handle *handle, int id, bool enable)
*/
static struct pt_pts *pt_resize_list_next(u32 *size)
{
+ unsigned long flags;
struct pt_pts *pts = NULL;
- lockdep_assert_held(&pt_internal_data.sl);
-
+ spin_lock_irqsave(&pt_internal_data.sl, flags);
if (!list_empty(&pt_internal_data.resize_list)) {
pts = list_first_entry(&pt_internal_data.resize_list,
struct pt_pts, resize_list);
@@ -164,7 +166,14 @@ static struct pt_pts *pt_resize_list_next(u32 *size)
pts->resize_list.prev = NULL;
*size = pts->size;
}
+ pt_internal_data.resize_pts_in_progress = pts;
+ spin_unlock_irqrestore(&pt_internal_data.sl, flags);
+ wake_up(&pt_internal_data.resize_remove_wq);
+
+ if (pts == NULL)
+ wait_event_interruptible(pt_internal_data.resize_wq,
+ !list_empty(&pt_internal_data.resize_list));
return pts;
}
@@ -180,8 +189,8 @@ static void pt_resize_list_add(struct pt_pts *pts, u32 size)
spin_lock_irqsave(&pt_internal_data.sl, flags);
if ((pts->resize_list.next == NULL) && (pts->enabled)
&& (pts->size != size)) {
- waking = list_empty(&pt_internal_data.resize_list);
list_add(&pts->resize_list, &pt_internal_data.resize_list);
+ waking = !pt_internal_data.resize_pts_in_progress;
}
pts->size = size;
spin_unlock_irqrestore(&pt_internal_data.sl, flags);
@@ -191,7 +200,7 @@ static void pt_resize_list_add(struct pt_pts *pts, u32 size)
}
/*
- * Flush and disable pts resize callback.
+ * FLush and disable pts resize callback.
* If a resize callback is in progress, we wait for its completion.
*/
static bool pt_resize_list_disable(struct pt_pts *pts)
@@ -210,6 +219,8 @@ static bool pt_resize_list_disable(struct pt_pts *pts)
}
spin_unlock_irqrestore(&pt_internal_data.sl, flags);
+ wait_event(pt_internal_data.resize_remove_wq,
+ pt_internal_data.resize_pts_in_progress != pts);
return enabled;
}
@@ -239,37 +250,25 @@ static int pt_resize_thread(void *data)
pt_resize_callback_t resize_callback = NULL;
int id;
- while (!kthread_should_stop()) {
- spin_lock(&pt_internal_data.sl);
-
+ while (1) {
+ /*
+ * We are size snapshot from pt_resize_list_next().
+ * because pts->size can change after the return.
+ */
pts = pt_resize_list_next(&size);
- if (pts != NULL) {
- handle = pts->handle;
- resize_callback = handle->resize_callback;
- id = ((char *)pts - (char *)handle->pts) / sizeof(handle->pts[0]);
- resize_callback(handle->data, id, size);
- driver = pts->driver;
- trace_pt_resize_callback(
- handle->node->name,
- driver->properties->nodes[pts->property_index]->name, false,
- (int)size, pts->ptid);
- }
-
- spin_unlock(&pt_internal_data.sl);
-
- /* List was empty, wait to be notified by pt_resize_list_add */
- if (pts == NULL) {
- int ret;
- do {
- ret = wait_event_interruptible(
- pt_internal_data.resize_wq,
- !list_empty(&pt_internal_data.resize_list) ||
- kthread_should_stop());
- } while (!ret);
- }
+ if (pts == NULL)
+ continue;
+ handle = pts->handle;
+ resize_callback = handle->resize_callback;
+ id = ((char *)pts - (char *)handle->pts)
+ / sizeof(handle->pts[0]);
+ resize_callback(handle->data, id, size);
+
+ driver = pts->driver;
+ trace_pt_resize_callback(handle->node->name,
+ driver->properties->nodes[pts->property_index]->name,
+ false, (int)size, pts->ptid);
}
-
- return 0;
}
/*
@@ -1247,6 +1246,7 @@ static int __init pt_init(void)
INIT_LIST_HEAD(&pt_internal_data.driver_list);
INIT_LIST_HEAD(&pt_internal_data.resize_list);
init_waitqueue_head(&pt_internal_data.resize_wq);
+ init_waitqueue_head(&pt_internal_data.resize_remove_wq);
sysctl_table = &pt_internal_data.sysctl_table[0];
sysctl_table[0].procname = "dev";
sysctl_table[0].mode = 0550;