3 * (C) COPYRIGHT 2010-2016 ARM Limited. All rights reserved.
5 * This program is free software and is provided to you under the terms of the
6 * GNU General Public License version 2 as published by the Free Software
7 * Foundation, and any use by you of this program is subject to the terms
10 * A copy of the licence is included with the program, and can also be obtained
11 * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
12 * Boston, MA 02110-1301, USA.
20 #include <mali_kbase.h>
21 #include <mali_kbase_debug.h>
22 #include <mali_kbase_tlstream.h>
24 static struct base_jd_udata kbase_event_process(struct kbase_context *kctx, struct kbase_jd_atom *katom)
26 struct base_jd_udata data;
28 lockdep_assert_held(&kctx->jctx.lock);
30 KBASE_DEBUG_ASSERT(kctx != NULL);
31 KBASE_DEBUG_ASSERT(katom != NULL);
32 KBASE_DEBUG_ASSERT(katom->status == KBASE_JD_ATOM_STATE_COMPLETED);
36 KBASE_TIMELINE_ATOMS_IN_FLIGHT(kctx, atomic_sub_return(1, &kctx->timeline.jd_atoms_in_flight));
38 kbase_tlstream_tl_nret_atom_ctx(katom, kctx);
39 kbase_tlstream_tl_del_atom(katom);
41 katom->status = KBASE_JD_ATOM_STATE_UNUSED;
43 wake_up(&katom->completed);
48 int kbase_event_pending(struct kbase_context *ctx)
50 KBASE_DEBUG_ASSERT(ctx);
52 return (atomic_read(&ctx->event_count) != 0) ||
53 (atomic_read(&ctx->event_closed) != 0);
56 KBASE_EXPORT_TEST_API(kbase_event_pending);
58 int kbase_event_dequeue(struct kbase_context *ctx, struct base_jd_event_v2 *uevent)
60 struct kbase_jd_atom *atom;
62 KBASE_DEBUG_ASSERT(ctx);
64 mutex_lock(&ctx->event_mutex);
66 if (list_empty(&ctx->event_list)) {
67 if (!atomic_read(&ctx->event_closed)) {
68 mutex_unlock(&ctx->event_mutex);
72 /* generate the BASE_JD_EVENT_DRV_TERMINATED message on the fly */
73 mutex_unlock(&ctx->event_mutex);
74 uevent->event_code = BASE_JD_EVENT_DRV_TERMINATED;
75 memset(&uevent->udata, 0, sizeof(uevent->udata));
76 dev_dbg(ctx->kbdev->dev,
77 "event system closed, returning BASE_JD_EVENT_DRV_TERMINATED(0x%X)\n",
78 BASE_JD_EVENT_DRV_TERMINATED);
82 /* normal event processing */
83 atomic_dec(&ctx->event_count);
84 atom = list_entry(ctx->event_list.next, struct kbase_jd_atom, dep_item[0]);
85 list_del(ctx->event_list.next);
87 mutex_unlock(&ctx->event_mutex);
89 dev_dbg(ctx->kbdev->dev, "event dequeuing %p\n", (void *)atom);
90 uevent->event_code = atom->event_code;
91 uevent->atom_number = (atom - ctx->jctx.atoms);
93 if (atom->core_req & BASE_JD_REQ_EXTERNAL_RESOURCES)
94 kbase_jd_free_external_resources(atom);
96 mutex_lock(&ctx->jctx.lock);
97 uevent->udata = kbase_event_process(ctx, atom);
98 mutex_unlock(&ctx->jctx.lock);
103 KBASE_EXPORT_TEST_API(kbase_event_dequeue);
106 * kbase_event_process_noreport_worker - Worker for processing atoms that do not
107 * return an event but do have external
109 * @data: Work structure
111 static void kbase_event_process_noreport_worker(struct work_struct *data)
113 struct kbase_jd_atom *katom = container_of(data, struct kbase_jd_atom,
115 struct kbase_context *kctx = katom->kctx;
117 if (katom->core_req & BASE_JD_REQ_EXTERNAL_RESOURCES)
118 kbase_jd_free_external_resources(katom);
120 mutex_lock(&kctx->jctx.lock);
121 kbase_event_process(kctx, katom);
122 mutex_unlock(&kctx->jctx.lock);
126 * kbase_event_process_noreport - Process atoms that do not return an event
127 * @kctx: Context pointer
128 * @katom: Atom to be processed
130 * Atoms that do not have external resources will be processed immediately.
131 * Atoms that do have external resources will be processed on a workqueue, in
132 * order to avoid locking issues.
134 static void kbase_event_process_noreport(struct kbase_context *kctx,
135 struct kbase_jd_atom *katom)
137 if (katom->core_req & BASE_JD_REQ_EXTERNAL_RESOURCES) {
138 INIT_WORK(&katom->work, kbase_event_process_noreport_worker);
139 queue_work(kctx->event_workq, &katom->work);
141 kbase_event_process(kctx, katom);
146 * kbase_event_coalesce - Move pending events to the main event list
147 * @kctx: Context pointer
149 * kctx->event_list and kctx->event_coalesce_count must be protected
150 * by a lock unless this is the last thread using them
151 * (and we're about to terminate the lock).
153 * Return: The number of pending events moved to the main event list
155 static int kbase_event_coalesce(struct kbase_context *kctx)
157 const int event_count = kctx->event_coalesce_count;
159 /* Join the list of pending events onto the tail of the main list
161 list_splice_tail_init(&kctx->event_coalesce_list, &kctx->event_list);
162 kctx->event_coalesce_count = 0;
164 /* Return the number of events moved */
168 void kbase_event_post(struct kbase_context *ctx, struct kbase_jd_atom *atom)
170 if (atom->core_req & BASE_JD_REQ_EVENT_ONLY_ON_FAILURE) {
171 if (atom->event_code == BASE_JD_EVENT_DONE) {
172 /* Don't report the event */
173 kbase_event_process_noreport(ctx, atom);
178 if (atom->core_req & BASEP_JD_REQ_EVENT_NEVER) {
179 /* Don't report the event */
180 kbase_event_process_noreport(ctx, atom);
184 if (atom->core_req & BASE_JD_REQ_EVENT_COALESCE) {
185 /* Don't report the event until other event(s) have completed */
186 mutex_lock(&ctx->event_mutex);
187 list_add_tail(&atom->dep_item[0], &ctx->event_coalesce_list);
188 ++ctx->event_coalesce_count;
189 mutex_unlock(&ctx->event_mutex);
191 /* Report the event and any pending events now */
194 mutex_lock(&ctx->event_mutex);
195 event_count += kbase_event_coalesce(ctx);
196 list_add_tail(&atom->dep_item[0], &ctx->event_list);
197 atomic_add(event_count, &ctx->event_count);
198 mutex_unlock(&ctx->event_mutex);
200 kbase_event_wakeup(ctx);
203 KBASE_EXPORT_TEST_API(kbase_event_post);
205 void kbase_event_close(struct kbase_context *kctx)
207 mutex_lock(&kctx->event_mutex);
208 atomic_set(&kctx->event_closed, true);
209 mutex_unlock(&kctx->event_mutex);
210 kbase_event_wakeup(kctx);
213 int kbase_event_init(struct kbase_context *kctx)
215 KBASE_DEBUG_ASSERT(kctx);
217 INIT_LIST_HEAD(&kctx->event_list);
218 INIT_LIST_HEAD(&kctx->event_coalesce_list);
219 mutex_init(&kctx->event_mutex);
220 atomic_set(&kctx->event_count, 0);
221 kctx->event_coalesce_count = 0;
222 atomic_set(&kctx->event_closed, false);
223 kctx->event_workq = alloc_workqueue("kbase_event", WQ_MEM_RECLAIM, 1);
225 if (NULL == kctx->event_workq)
231 KBASE_EXPORT_TEST_API(kbase_event_init);
233 void kbase_event_cleanup(struct kbase_context *kctx)
237 KBASE_DEBUG_ASSERT(kctx);
238 KBASE_DEBUG_ASSERT(kctx->event_workq);
240 flush_workqueue(kctx->event_workq);
241 destroy_workqueue(kctx->event_workq);
243 /* We use kbase_event_dequeue to remove the remaining events as that
244 * deals with all the cleanup needed for the atoms.
246 * Note: use of kctx->event_list without a lock is safe because this must be the last
247 * thread using it (because we're about to terminate the lock)
249 event_count = kbase_event_coalesce(kctx);
250 atomic_add(event_count, &kctx->event_count);
252 while (!list_empty(&kctx->event_list)) {
253 struct base_jd_event_v2 event;
255 kbase_event_dequeue(kctx, &event);
259 KBASE_EXPORT_TEST_API(kbase_event_cleanup);