summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-11-16 07:20:31 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-11-16 07:20:31 +0000
commitf48579d406bbd5fbc2b29f3107c2f40217a95aae (patch)
treebcdb3d6f87c1894a581ee7f7bd9186096fdb8801
parent7488540a5bcbca28abefa9daf3c2c369cb89063b (diff)
parentb48e8f4f52338c5097588a16b21e979eb0d77e4c (diff)
downloadgraphics-android-msm-eos-android13-wear-kr3-pixel-watch.tar.gz
Merge cherrypicks of ['partner-android-review.googlesource.com/2656996'] into android13-msm-pixelwatch-5.15-eos-release.android-wear-13.0.0_r0.8android-wear-13.0.0_r0.12android-wear-13.0.0_r0.10android-msm-eos-android13-wear-kr3-pixel-watch
Change-Id: Ib3623b5713b5b95bb8d20109c9b46aaa3aa0d201
-rw-r--r--adreno_dispatch.c5
-rw-r--r--adreno_hwsched.c4
-rw-r--r--kgsl_drawobj.c101
-rw-r--r--kgsl_drawobj.h14
4 files changed, 64 insertions, 60 deletions
diff --git a/adreno_dispatch.c b/adreno_dispatch.c
index bdf5598..7b68256 100644
--- a/adreno_dispatch.c
+++ b/adreno_dispatch.c
@@ -364,11 +364,8 @@ static int dispatch_retire_syncobj(struct kgsl_drawobj *drawobj,
static int drawqueue_retire_timelineobj(struct kgsl_drawobj *drawobj,
struct adreno_context *drawctxt)
{
- struct kgsl_drawobj_timeline *timelineobj = TIMELINEOBJ(drawobj);
-
_pop_drawobj(drawctxt);
- kgsl_drawobj_timelineobj_retire(timelineobj);
-
+ kgsl_drawobj_destroy(drawobj);
return 0;
}
diff --git a/adreno_hwsched.c b/adreno_hwsched.c
index cae6a3c..7d35d15 100644
--- a/adreno_hwsched.c
+++ b/adreno_hwsched.c
@@ -197,10 +197,8 @@ static int _retire_markerobj(struct adreno_device *adreno_dev, struct kgsl_drawo
static int _retire_timelineobj(struct kgsl_drawobj *drawobj,
struct adreno_context *drawctxt)
{
- struct kgsl_drawobj_timeline *timelineobj = TIMELINEOBJ(drawobj);
-
_pop_drawobj(drawctxt);
- kgsl_drawobj_timelineobj_retire(timelineobj);
+ kgsl_drawobj_destroy(drawobj);
return 0;
}
diff --git a/kgsl_drawobj.c b/kgsl_drawobj.c
index 19d6a60..f1fdc7b 100644
--- a/kgsl_drawobj.c
+++ b/kgsl_drawobj.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
/*
@@ -280,7 +280,7 @@ static void drawobj_sync_func(struct kgsl_device *device,
kgsl_drawobj_put(&event->syncobj->base);
}
-static void drawobj_sync_timeline_fence_work(struct irq_work *work)
+static void drawobj_sync_timeline_fence_work(struct work_struct *work)
{
struct kgsl_drawobj_sync_event *event = container_of(work,
struct kgsl_drawobj_sync_event, work);
@@ -333,7 +333,7 @@ static void drawobj_sync_timeline_fence_callback(struct dma_fence *f,
* removing the fence
*/
if (drawobj_sync_expire(event->device, event))
- irq_work_queue(&event->work);
+ queue_work(kgsl_driver.lockless_workqueue, &event->work);
}
static void syncobj_destroy(struct kgsl_drawobj *drawobj)
@@ -393,12 +393,16 @@ static void syncobj_destroy(struct kgsl_drawobj *drawobj)
}
-static void timelineobj_destroy(struct kgsl_drawobj *drawobj)
+static void _drawobj_timelineobj_retire(struct kref *kref)
{
- struct kgsl_drawobj_timeline *timelineobj = TIMELINEOBJ(drawobj);
int i;
+ struct kgsl_drawobj_timeline *timelineobj = container_of(kref,
+ struct kgsl_drawobj_timeline, sig_refcount);
for (i = 0; i < timelineobj->count; i++) {
+ kgsl_timeline_signal(timelineobj->timelines[i].timeline,
+ timelineobj->timelines[i].seqno);
+
kgsl_timeline_put(timelineobj->timelines[i].timeline);
kgsl_context_put(timelineobj->timelines[i].context);
}
@@ -408,6 +412,32 @@ static void timelineobj_destroy(struct kgsl_drawobj *drawobj)
timelineobj->count = 0;
}
+static void kgsl_timelineobj_signal(struct kgsl_drawobj_timeline *timelineobj)
+{
+ kref_put(&timelineobj->sig_refcount, _drawobj_timelineobj_retire);
+}
+
+static void timelineobj_destroy(struct kgsl_drawobj *drawobj)
+{
+ struct kgsl_drawobj_timeline *timelineobj = TIMELINEOBJ(drawobj);
+ int i;
+
+ /*
+ * At this point any syncobjs blocking this timelinobj have been
+ * signaled. The timelineobj now only needs all preceding timestamps to
+ * retire before signaling the timelines. Notify timelines to keep them
+ * in sync with the timestamps as they retire.
+ */
+ for (i = 0; i < timelineobj->count; i++)
+ kgsl_timeline_add_signal(&timelineobj->timelines[i]);
+
+ /*
+ * The scheduler is done with the timelineobj. Put the initial
+ * sig_refcount to continue with the signaling process.
+ */
+ kgsl_timelineobj_signal(timelineobj);
+}
+
static void bindobj_destroy(struct kgsl_drawobj *drawobj)
{
struct kgsl_drawobj_bind *bindobj = BINDOBJ(drawobj);
@@ -547,7 +577,7 @@ static int drawobj_add_sync_timeline(struct kgsl_device *device,
event->device = device;
event->context = NULL;
event->fence = fence;
- init_irq_work(&event->work, drawobj_sync_timeline_fence_work);
+ INIT_WORK(&event->work, drawobj_sync_timeline_fence_work);
INIT_LIST_HEAD(&event->cb.node);
@@ -938,7 +968,8 @@ kgsl_drawobj_timeline_create(struct kgsl_device *device,
* Initialize the sig_refcount that triggers the timeline signal.
* This refcount goes to 0 when:
* 1) This timelineobj is popped off the context queue. This implies
- * any syncobj blocking this timelineobj was already signaled.
+ * any syncobj blocking this timelineobj was already signaled, or
+ * the context queue is cleaned up at detach time.
* 2) The cmdobjs queued on this context before this timeline object
* are retired.
*/
@@ -950,43 +981,17 @@ kgsl_drawobj_timeline_create(struct kgsl_device *device,
return timelineobj;
}
-static void _drawobj_timelineobj_retire(struct kref *kref)
-{
- struct kgsl_drawobj_timeline *timelineobj = container_of(kref,
- struct kgsl_drawobj_timeline, sig_refcount);
- struct kgsl_drawobj *drawobj = DRAWOBJ(timelineobj);
- int i;
-
- for (i = 0; i < timelineobj->count; i++)
- kgsl_timeline_signal(timelineobj->timelines[i].timeline,
- timelineobj->timelines[i].seqno);
-
- /* Now that timelines are signaled destroy the drawobj */
- kgsl_drawobj_destroy(drawobj);
-}
-
static void _timeline_signaled(struct kgsl_device *device,
struct kgsl_event_group *group, void *priv, int ret)
{
struct kgsl_drawobj_timeline *timelineobj = priv;
+ struct kgsl_drawobj *drawobj = DRAWOBJ(timelineobj);
- kref_put(&timelineobj->sig_refcount, _drawobj_timelineobj_retire);
-}
-
-void kgsl_drawobj_timelineobj_retire(struct kgsl_drawobj_timeline *timelineobj)
-{
- int i;
+ /* Put the sig_refcount we took when registering this event */
+ kgsl_timelineobj_signal(timelineobj);
- /*
- * At this point any syncobjs blocking this timelinobj have been
- * signaled. The timelineobj now only needs all preceding timestamps to
- * retire before signaling the timelines. Notify timelines to keep them
- * in sync with the timestamps as they retire.
- */
- for (i = 0; i < timelineobj->count; i++)
- kgsl_timeline_add_signal(&timelineobj->timelines[i]);
-
- kref_put(&timelineobj->sig_refcount, _drawobj_timelineobj_retire);
+ /* Put the drawobj refcount we took when registering this event */
+ kgsl_drawobj_put(drawobj);
}
int kgsl_drawobj_add_timeline(struct kgsl_device_private *dev_priv,
@@ -1063,18 +1068,30 @@ int kgsl_drawobj_add_timeline(struct kgsl_device_private *dev_priv,
timelineobj->count = cmd.count;
/*
- * Take a refcount that we put when the last queued timestamp on this
- * context is retired. Use a kgsl_event to notify us when this
- * timestamp retires.
+ * Register a kgsl_event to notify us when the last queued timestamp
+ * retires. Take a refcount on the drawobj to keep it valid for the
+ * callback, and take the sig_refcount to synchronize with the
+ * timelineobj retire. Both these refcounts are put in the callback.
*/
+ kref_get(&drawobj->refcount);
kref_get(&timelineobj->sig_refcount);
ret = kgsl_add_event(device, &context->events, queued,
_timeline_signaled, timelineobj);
if (ret)
- goto err;
+ goto event_err;
return 0;
+
+event_err:
+ /*
+ * If there was an error, put back sig_refcount and drawobj refcounts.
+ * The caller still holds initial refcounts on both and puts them in
+ * kgsl_drawobj_destroy(). Clean up the timelinelines array since we
+ * do not want to signal anything now.
+ */
+ kgsl_timelineobj_signal(timelineobj);
+ kgsl_drawobj_put(drawobj);
err:
for (i = 0; i < cmd.count; i++) {
kgsl_timeline_put(timelineobj->timelines[i].timeline);
diff --git a/kgsl_drawobj.h b/kgsl_drawobj.h
index 5f55461..138df54 100644
--- a/kgsl_drawobj.h
+++ b/kgsl_drawobj.h
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __KGSL_DRAWOBJ_H
@@ -203,8 +203,8 @@ struct kgsl_drawobj_sync_event {
struct dma_fence *fence;
/** @cb: Callback struct for KGSL_CMD_SYNCPOINT_TYPE_TIMELINE */
struct dma_fence_cb cb;
- /** @work : irq worker for KGSL_CMD_SYNCPOINT_TYPE_TIMELINE */
- struct irq_work work;
+ /** @work : work_struct for KGSL_CMD_SYNCPOINT_TYPE_TIMELINE */
+ struct work_struct work;
};
#define KGSL_DRAWOBJ_FLAGS \
@@ -345,12 +345,4 @@ int kgsl_drawobj_add_timeline(struct kgsl_device_private *dev_priv,
struct kgsl_drawobj_timeline *timelineobj,
void __user *src, u64 cmdsize);
-/**
- * kgsl_drawobj_timelineobj_retire - Retire the timeline drawobj
- * @timelineobj: Pointer to a timeline drawobject
- *
- * Retire the timelineobj when it is popped off the context queue.
- */
-void kgsl_drawobj_timelineobj_retire(struct kgsl_drawobj_timeline *timelineobj);
-
#endif /* __KGSL_DRAWOBJ_H */