]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/misc/habanalabs/common/command_submission.c
habanalabs: change messages to debug level
[mirror_ubuntu-jammy-kernel.git] / drivers / misc / habanalabs / common / command_submission.c
CommitLineData
eff6f4a0
OG
1// SPDX-License-Identifier: GPL-2.0
2
3/*
4 * Copyright 2016-2019 HabanaLabs, Ltd.
5 * All Rights Reserved.
6 */
7
8#include <uapi/misc/habanalabs.h>
9#include "habanalabs.h"
10
11#include <linux/uaccess.h>
12#include <linux/slab.h>
13
9d127ad5
OB
14/**
15 * enum hl_cs_wait_status - cs wait status
16 * @CS_WAIT_STATUS_BUSY: cs was not completed yet
17 * @CS_WAIT_STATUS_COMPLETED: cs completed
18 * @CS_WAIT_STATUS_GONE: cs completed but fence is already gone
19 */
20enum hl_cs_wait_status {
21 CS_WAIT_STATUS_BUSY,
22 CS_WAIT_STATUS_COMPLETED,
23 CS_WAIT_STATUS_GONE
24};
25
eff6f4a0 26static void job_wq_completion(struct work_struct *work);
9d127ad5
OB
27static int _hl_cs_wait_ioctl(struct hl_device *hdev, struct hl_ctx *ctx,
28 u64 timeout_us, u64 seq,
bd2f477f 29 enum hl_cs_wait_status *status, s64 *timestamp);
eff6f4a0
OG
30static void cs_do_release(struct kref *ref);
31
b75f2250
OS
32static void hl_sob_reset(struct kref *ref)
33{
34 struct hl_hw_sob *hw_sob = container_of(ref, struct hl_hw_sob,
35 kref);
36 struct hl_device *hdev = hw_sob->hdev;
37
38 hdev->asic_funcs->reset_sob(hdev, hw_sob);
39}
40
41void hl_sob_reset_error(struct kref *ref)
42{
43 struct hl_hw_sob *hw_sob = container_of(ref, struct hl_hw_sob,
44 kref);
45 struct hl_device *hdev = hw_sob->hdev;
46
47 dev_crit(hdev->dev,
48 "SOB release shouldn't be called here, q_idx: %d, sob_id: %d\n",
49 hw_sob->q_idx, hw_sob->sob_id);
50}
51
2992c1dc
OB
52/**
53 * hl_gen_sob_mask() - Generates a sob mask to be used in a monitor arm packet
54 * @sob_base: sob base id
55 * @sob_mask: sob user mask, each bit represents a sob offset from sob base
56 * @mask: generated mask
57 *
58 * Return: 0 if given parameters are valid
59 */
60int hl_gen_sob_mask(u16 sob_base, u8 sob_mask, u8 *mask)
61{
62 int i;
63
64 if (sob_mask == 0)
65 return -EINVAL;
66
67 if (sob_mask == 0x1) {
68 *mask = ~(1 << (sob_base & 0x7));
69 } else {
70 /* find msb in order to verify sob range is valid */
71 for (i = BITS_PER_BYTE - 1 ; i >= 0 ; i--)
72 if (BIT(i) & sob_mask)
73 break;
74
75 if (i > (HL_MAX_SOBS_PER_MONITOR - (sob_base & 0x7) - 1))
76 return -EINVAL;
77
78 *mask = ~sob_mask;
79 }
80
81 return 0;
82}
83
a98d73c7 84static void hl_fence_release(struct kref *kref)
eff6f4a0 85{
a98d73c7
OB
86 struct hl_fence *fence =
87 container_of(kref, struct hl_fence, refcount);
b0b5d925
OS
88 struct hl_cs_compl *hl_cs_cmpl =
89 container_of(fence, struct hl_cs_compl, base_fence);
b75f2250
OS
90 struct hl_device *hdev = hl_cs_cmpl->hdev;
91
3292055c
OB
92 /* EBUSY means the CS was never submitted and hence we don't have
93 * an attached hw_sob object that we should handle here
94 */
95 if (fence->error == -EBUSY)
96 goto free;
97
b75f2250 98 if ((hl_cs_cmpl->type == CS_TYPE_SIGNAL) ||
5fe1c17d
OB
99 (hl_cs_cmpl->type == CS_TYPE_WAIT) ||
100 (hl_cs_cmpl->type == CS_TYPE_COLLECTIVE_WAIT)) {
b75f2250
OS
101
102 dev_dbg(hdev->dev,
103 "CS 0x%llx type %d finished, sob_id: %d, sob_val: 0x%x\n",
104 hl_cs_cmpl->cs_seq,
105 hl_cs_cmpl->type,
106 hl_cs_cmpl->hw_sob->sob_id,
107 hl_cs_cmpl->sob_val);
108
109 /*
110 * A signal CS can get completion while the corresponding wait
111 * for signal CS is on its way to the PQ. The wait for signal CS
112 * will get stuck if the signal CS incremented the SOB to its
113 * max value and there are no pending (submitted) waits on this
114 * SOB.
115 * We do the following to void this situation:
116 * 1. The wait for signal CS must get a ref for the signal CS as
117 * soon as possible in cs_ioctl_signal_wait() and put it
118 * before being submitted to the PQ but after it incremented
119 * the SOB refcnt in init_signal_wait_cs().
120 * 2. Signal/Wait for signal CS will decrement the SOB refcnt
121 * here.
122 * These two measures guarantee that the wait for signal CS will
123 * reset the SOB upon completion rather than the signal CS and
124 * hence the above scenario is avoided.
125 */
126 kref_put(&hl_cs_cmpl->hw_sob->kref, hl_sob_reset);
5fe1c17d
OB
127
128 if (hl_cs_cmpl->type == CS_TYPE_COLLECTIVE_WAIT)
129 hdev->asic_funcs->reset_sob_group(hdev,
130 hl_cs_cmpl->sob_group);
b75f2250 131 }
eff6f4a0 132
3292055c 133free:
a98d73c7 134 kfree(hl_cs_cmpl);
eff6f4a0
OG
135}
136
a98d73c7
OB
137void hl_fence_put(struct hl_fence *fence)
138{
139 if (fence)
140 kref_put(&fence->refcount, hl_fence_release);
141}
142
143void hl_fence_get(struct hl_fence *fence)
144{
145 if (fence)
146 kref_get(&fence->refcount);
147}
148
149static void hl_fence_init(struct hl_fence *fence)
150{
151 kref_init(&fence->refcount);
152 fence->error = 0;
bd2f477f 153 fence->timestamp = ktime_set(0, 0);
a98d73c7
OB
154 init_completion(&fence->completion);
155}
eff6f4a0 156
5de406c0 157void cs_get(struct hl_cs *cs)
eff6f4a0
OG
158{
159 kref_get(&cs->refcount);
160}
161
162static int cs_get_unless_zero(struct hl_cs *cs)
163{
164 return kref_get_unless_zero(&cs->refcount);
165}
166
167static void cs_put(struct hl_cs *cs)
168{
169 kref_put(&cs->refcount, cs_do_release);
170}
171
649c4592
TT
172static void cs_job_do_release(struct kref *ref)
173{
174 struct hl_cs_job *job = container_of(ref, struct hl_cs_job, refcount);
175
176 kfree(job);
177}
178
179static void cs_job_put(struct hl_cs_job *job)
180{
181 kref_put(&job->refcount, cs_job_do_release);
182}
183
cb596aee
TT
184static bool is_cb_patched(struct hl_device *hdev, struct hl_cs_job *job)
185{
186 /*
187 * Patched CB is created for external queues jobs, and for H/W queues
188 * jobs if the user CB was allocated by driver and MMU is disabled.
189 */
190 return (job->queue_type == QUEUE_TYPE_EXT ||
191 (job->queue_type == QUEUE_TYPE_HW &&
192 job->is_kernel_allocated_cb &&
193 !hdev->mmu_enable));
194}
195
eff6f4a0
OG
196/*
197 * cs_parser - parse the user command submission
198 *
199 * @hpriv : pointer to the private data of the fd
200 * @job : pointer to the job that holds the command submission info
201 *
202 * The function parses the command submission of the user. It calls the
203 * ASIC specific parser, which returns a list of memory blocks to send
204 * to the device as different command buffers
205 *
206 */
207static int cs_parser(struct hl_fpriv *hpriv, struct hl_cs_job *job)
208{
209 struct hl_device *hdev = hpriv->hdev;
210 struct hl_cs_parser parser;
211 int rc;
212
213 parser.ctx_id = job->cs->ctx->asid;
214 parser.cs_sequence = job->cs->sequence;
215 parser.job_id = job->id;
216
217 parser.hw_queue_id = job->hw_queue_id;
218 parser.job_userptr_list = &job->userptr_list;
219 parser.patched_cb = NULL;
220 parser.user_cb = job->user_cb;
221 parser.user_cb_size = job->user_cb_size;
cb596aee
TT
222 parser.queue_type = job->queue_type;
223 parser.is_kernel_allocated_cb = job->is_kernel_allocated_cb;
eff6f4a0 224 job->patched_cb = NULL;
eff6f4a0
OG
225
226 rc = hdev->asic_funcs->cs_parser(hdev, &parser);
cb596aee
TT
227
228 if (is_cb_patched(hdev, job)) {
eff6f4a0
OG
229 if (!rc) {
230 job->patched_cb = parser.patched_cb;
231 job->job_cb_size = parser.patched_cb_size;
926ba4cc 232 job->contains_dma_pkt = parser.contains_dma_pkt;
eff6f4a0
OG
233
234 spin_lock(&job->patched_cb->lock);
235 job->patched_cb->cs_cnt++;
236 spin_unlock(&job->patched_cb->lock);
237 }
238
239 /*
240 * Whether the parsing worked or not, we don't need the
241 * original CB anymore because it was already parsed and
242 * won't be accessed again for this CS
243 */
244 spin_lock(&job->user_cb->lock);
245 job->user_cb->cs_cnt--;
246 spin_unlock(&job->user_cb->lock);
247 hl_cb_put(job->user_cb);
248 job->user_cb = NULL;
240c92fd
OS
249 } else if (!rc) {
250 job->job_cb_size = job->user_cb_size;
eff6f4a0
OG
251 }
252
253 return rc;
254}
255
649c4592 256static void complete_job(struct hl_device *hdev, struct hl_cs_job *job)
eff6f4a0
OG
257{
258 struct hl_cs *cs = job->cs;
259
cb596aee 260 if (is_cb_patched(hdev, job)) {
eff6f4a0
OG
261 hl_userptr_delete_list(hdev, &job->userptr_list);
262
263 /*
264 * We might arrive here from rollback and patched CB wasn't
265 * created, so we need to check it's not NULL
266 */
267 if (job->patched_cb) {
268 spin_lock(&job->patched_cb->lock);
269 job->patched_cb->cs_cnt--;
270 spin_unlock(&job->patched_cb->lock);
271
272 hl_cb_put(job->patched_cb);
273 }
274 }
275
cb596aee
TT
276 /* For H/W queue jobs, if a user CB was allocated by driver and MMU is
277 * enabled, the user CB isn't released in cs_parser() and thus should be
278 * released here.
5fe1c17d 279 * This is also true for INT queues jobs which were allocated by driver
cb596aee 280 */
5fe1c17d
OB
281 if (job->is_kernel_allocated_cb &&
282 ((job->queue_type == QUEUE_TYPE_HW && hdev->mmu_enable) ||
283 job->queue_type == QUEUE_TYPE_INT)) {
cb596aee
TT
284 spin_lock(&job->user_cb->lock);
285 job->user_cb->cs_cnt--;
286 spin_unlock(&job->user_cb->lock);
287
288 hl_cb_put(job->user_cb);
289 }
290
eff6f4a0
OG
291 /*
292 * This is the only place where there can be multiple threads
293 * modifying the list at the same time
294 */
295 spin_lock(&cs->job_lock);
296 list_del(&job->cs_node);
297 spin_unlock(&cs->job_lock);
298
c2164773
OG
299 hl_debugfs_remove_job(hdev, job);
300
cb596aee
TT
301 if (job->queue_type == QUEUE_TYPE_EXT ||
302 job->queue_type == QUEUE_TYPE_HW)
eff6f4a0
OG
303 cs_put(cs);
304
649c4592 305 cs_job_put(job);
eff6f4a0
OG
306}
307
308static void cs_do_release(struct kref *ref)
309{
ea6ee260 310 struct hl_cs *cs = container_of(ref, struct hl_cs, refcount);
eff6f4a0
OG
311 struct hl_device *hdev = cs->ctx->hdev;
312 struct hl_cs_job *job, *tmp;
313
314 cs->completed = true;
315
316 /*
317 * Although if we reached here it means that all external jobs have
318 * finished, because each one of them took refcnt to CS, we still
649c4592 319 * need to go over the internal jobs and complete them. Otherwise, we
eff6f4a0
OG
320 * will have leaked memory and what's worse, the CS object (and
321 * potentially the CTX object) could be released, while the JOB
322 * still holds a pointer to them (but no reference).
323 */
324 list_for_each_entry_safe(job, tmp, &cs->job_list, cs_node)
649c4592 325 complete_job(hdev, job);
eff6f4a0 326
ea6ee260
TT
327 if (!cs->submitted) {
328 /* In case the wait for signal CS was submitted, the put occurs
c1d505a9
OB
329 * in init_signal_wait_cs() or collective_wait_init_cs()
330 * right before hanging on the PQ.
ea6ee260 331 */
c1d505a9
OB
332 if (cs->type == CS_TYPE_WAIT ||
333 cs->type == CS_TYPE_COLLECTIVE_WAIT)
ea6ee260 334 hl_fence_put(cs->signal_fence);
cbaa99ed 335
ea6ee260
TT
336 goto out;
337 }
75b3cb2b 338
ea6ee260 339 hdev->asic_funcs->hw_queues_lock(hdev);
75b3cb2b 340
ea6ee260
TT
341 hdev->cs_active_cnt--;
342 if (!hdev->cs_active_cnt) {
343 struct hl_device_idle_busy_ts *ts;
75b3cb2b 344
ea6ee260
TT
345 ts = &hdev->idle_busy_ts_arr[hdev->idle_busy_ts_idx++];
346 ts->busy_to_idle_ts = ktime_get();
cbaa99ed 347
ea6ee260
TT
348 if (hdev->idle_busy_ts_idx == HL_IDLE_BUSY_TS_ARR_SIZE)
349 hdev->idle_busy_ts_idx = 0;
350 } else if (hdev->cs_active_cnt < 0) {
351 dev_crit(hdev->dev, "CS active cnt %d is negative\n",
352 hdev->cs_active_cnt);
353 }
eff6f4a0 354
ea6ee260 355 hdev->asic_funcs->hw_queues_unlock(hdev);
eff6f4a0 356
ea6ee260
TT
357 /* Need to update CI for internal queues */
358 hl_int_hw_queue_update_ci(cs);
eff6f4a0 359
804a7227
TT
360 /* remove CS from CS mirror list */
361 spin_lock(&hdev->cs_mirror_lock);
ea6ee260 362 list_del_init(&cs->mirror_node);
804a7227 363 spin_unlock(&hdev->cs_mirror_lock);
eff6f4a0 364
ea6ee260
TT
365 /* Don't cancel TDR in case this CS was timedout because we might be
366 * running from the TDR context
367 */
804a7227 368 if (!cs->timedout && hdev->timeout_jiffies != MAX_SCHEDULE_TIMEOUT) {
ea6ee260
TT
369 struct hl_cs *next;
370
371 if (cs->tdr_active)
372 cancel_delayed_work_sync(&cs->work_tdr);
eff6f4a0 373
804a7227 374 spin_lock(&hdev->cs_mirror_lock);
eff6f4a0 375
ea6ee260 376 /* queue TDR for next CS */
804a7227 377 next = list_first_entry_or_null(&hdev->cs_mirror_list,
ea6ee260 378 struct hl_cs, mirror_node);
eff6f4a0 379
ea6ee260
TT
380 if (next && !next->tdr_active) {
381 next->tdr_active = true;
382 schedule_delayed_work(&next->work_tdr,
383 hdev->timeout_jiffies);
eff6f4a0 384 }
ea6ee260 385
804a7227 386 spin_unlock(&hdev->cs_mirror_lock);
eff6f4a0
OG
387 }
388
ea6ee260
TT
389out:
390 /* Must be called before hl_ctx_put because inside we use ctx to get
c2164773
OG
391 * the device
392 */
393 hl_debugfs_remove_cs(cs);
394
eff6f4a0
OG
395 hl_ctx_put(cs->ctx);
396
3292055c 397 /* We need to mark an error for not submitted because in that case
a98d73c7 398 * the hl fence release flow is different. Mainly, we don't need
3292055c
OB
399 * to handle hw_sob for signal/wait
400 */
eff6f4a0 401 if (cs->timedout)
a98d73c7 402 cs->fence->error = -ETIMEDOUT;
eff6f4a0 403 else if (cs->aborted)
a98d73c7 404 cs->fence->error = -EIO;
3292055c 405 else if (!cs->submitted)
a98d73c7 406 cs->fence->error = -EBUSY;
eff6f4a0 407
bd2f477f
OB
408 if (cs->timestamp)
409 cs->fence->timestamp = ktime_get();
a98d73c7
OB
410 complete_all(&cs->fence->completion);
411 hl_fence_put(cs->fence);
db491e4f 412
3abc99bb 413 kfree(cs->jobs_in_queue_cnt);
eff6f4a0
OG
414 kfree(cs);
415}
416
417static void cs_timedout(struct work_struct *work)
418{
419 struct hl_device *hdev;
22362aa3 420 int rc;
eff6f4a0
OG
421 struct hl_cs *cs = container_of(work, struct hl_cs,
422 work_tdr.work);
423 rc = cs_get_unless_zero(cs);
424 if (!rc)
425 return;
426
427 if ((!cs->submitted) || (cs->completed)) {
428 cs_put(cs);
429 return;
430 }
431
432 /* Mark the CS is timed out so we won't try to cancel its TDR */
433 cs->timedout = true;
434
435 hdev = cs->ctx->hdev;
eff6f4a0 436
5e5867e5
OG
437 switch (cs->type) {
438 case CS_TYPE_SIGNAL:
439 dev_err(hdev->dev,
440 "Signal command submission %llu has not finished in time!\n",
441 cs->sequence);
442 break;
443
444 case CS_TYPE_WAIT:
445 dev_err(hdev->dev,
446 "Wait command submission %llu has not finished in time!\n",
447 cs->sequence);
448 break;
449
450 case CS_TYPE_COLLECTIVE_WAIT:
451 dev_err(hdev->dev,
452 "Collective Wait command submission %llu has not finished in time!\n",
453 cs->sequence);
454 break;
455
456 default:
457 dev_err(hdev->dev,
458 "Command submission %llu has not finished in time!\n",
459 cs->sequence);
460 break;
461 }
eff6f4a0
OG
462
463 cs_put(cs);
464
465 if (hdev->reset_on_lockup)
466 hl_device_reset(hdev, false, false);
66a76401
OB
467 else
468 hdev->needs_reset = true;
eff6f4a0
OG
469}
470
471static int allocate_cs(struct hl_device *hdev, struct hl_ctx *ctx,
b75f2250 472 enum hl_cs_type cs_type, struct hl_cs **cs_new)
eff6f4a0 473{
23c15ae6 474 struct hl_cs_counters_atomic *cntr;
a98d73c7 475 struct hl_fence *other = NULL;
23c15ae6 476 struct hl_cs_compl *cs_cmpl;
eff6f4a0
OG
477 struct hl_cs *cs;
478 int rc;
479
23c15ae6
OG
480 cntr = &hdev->aggregated_cs_counters;
481
eff6f4a0
OG
482 cs = kzalloc(sizeof(*cs), GFP_ATOMIC);
483 if (!cs)
484 return -ENOMEM;
485
486 cs->ctx = ctx;
487 cs->submitted = false;
488 cs->completed = false;
b75f2250 489 cs->type = cs_type;
eff6f4a0
OG
490 INIT_LIST_HEAD(&cs->job_list);
491 INIT_DELAYED_WORK(&cs->work_tdr, cs_timedout);
492 kref_init(&cs->refcount);
493 spin_lock_init(&cs->job_lock);
494
b0b5d925
OS
495 cs_cmpl = kmalloc(sizeof(*cs_cmpl), GFP_ATOMIC);
496 if (!cs_cmpl) {
eff6f4a0
OG
497 rc = -ENOMEM;
498 goto free_cs;
499 }
500
b0b5d925 501 cs_cmpl->hdev = hdev;
b75f2250 502 cs_cmpl->type = cs->type;
b0b5d925
OS
503 spin_lock_init(&cs_cmpl->lock);
504 cs->fence = &cs_cmpl->base_fence;
eff6f4a0
OG
505
506 spin_lock(&ctx->cs_lock);
507
b0b5d925 508 cs_cmpl->cs_seq = ctx->cs_sequence;
c16d45f4
OB
509 other = ctx->cs_pending[cs_cmpl->cs_seq &
510 (hdev->asic_prop.max_pending_cs - 1)];
a98d73c7
OB
511
512 if (other && !completion_done(&other->completion)) {
975ab7b3 513 dev_dbg_ratelimited(hdev->dev,
52a1ae11 514 "Rejecting CS because of too many in-flights CS\n");
e753643d 515 atomic64_inc(&ctx->cs_counters.max_cs_in_flight_drop_cnt);
23c15ae6 516 atomic64_inc(&cntr->max_cs_in_flight_drop_cnt);
eff6f4a0
OG
517 rc = -EAGAIN;
518 goto free_fence;
519 }
520
3abc99bb
OB
521 cs->jobs_in_queue_cnt = kcalloc(hdev->asic_prop.max_queues,
522 sizeof(*cs->jobs_in_queue_cnt), GFP_ATOMIC);
523 if (!cs->jobs_in_queue_cnt) {
524 rc = -ENOMEM;
525 goto free_fence;
526 }
527
a98d73c7
OB
528 /* init hl_fence */
529 hl_fence_init(&cs_cmpl->base_fence);
eff6f4a0 530
b0b5d925 531 cs->sequence = cs_cmpl->cs_seq;
eff6f4a0 532
c16d45f4
OB
533 ctx->cs_pending[cs_cmpl->cs_seq &
534 (hdev->asic_prop.max_pending_cs - 1)] =
b0b5d925 535 &cs_cmpl->base_fence;
eff6f4a0
OG
536 ctx->cs_sequence++;
537
a98d73c7 538 hl_fence_get(&cs_cmpl->base_fence);
eff6f4a0 539
a98d73c7 540 hl_fence_put(other);
eff6f4a0
OG
541
542 spin_unlock(&ctx->cs_lock);
543
544 *cs_new = cs;
545
546 return 0;
547
548free_fence:
3abc99bb 549 spin_unlock(&ctx->cs_lock);
b0b5d925 550 kfree(cs_cmpl);
eff6f4a0
OG
551free_cs:
552 kfree(cs);
553 return rc;
554}
555
556static void cs_rollback(struct hl_device *hdev, struct hl_cs *cs)
557{
558 struct hl_cs_job *job, *tmp;
559
560 list_for_each_entry_safe(job, tmp, &cs->job_list, cs_node)
649c4592 561 complete_job(hdev, job);
eff6f4a0
OG
562}
563
564void hl_cs_rollback_all(struct hl_device *hdev)
565{
5574cb21 566 int i;
eff6f4a0
OG
567 struct hl_cs *cs, *tmp;
568
569 /* flush all completions */
5574cb21
OB
570 for (i = 0 ; i < hdev->asic_prop.completion_queues_count ; i++)
571 flush_workqueue(hdev->cq_wq[i]);
eff6f4a0
OG
572
573 /* Make sure we don't have leftovers in the H/W queues mirror list */
804a7227 574 list_for_each_entry_safe(cs, tmp, &hdev->cs_mirror_list, mirror_node) {
eff6f4a0
OG
575 cs_get(cs);
576 cs->aborted = true;
577 dev_warn_ratelimited(hdev->dev, "Killing CS %d.%llu\n",
578 cs->ctx->asid, cs->sequence);
579 cs_rollback(hdev, cs);
580 cs_put(cs);
581 }
582}
583
584static void job_wq_completion(struct work_struct *work)
585{
586 struct hl_cs_job *job = container_of(work, struct hl_cs_job,
587 finish_work);
588 struct hl_cs *cs = job->cs;
589 struct hl_device *hdev = cs->ctx->hdev;
590
591 /* job is no longer needed */
649c4592 592 complete_job(hdev, job);
eff6f4a0
OG
593}
594
cb596aee
TT
595static int validate_queue_index(struct hl_device *hdev,
596 struct hl_cs_chunk *chunk,
597 enum hl_queue_type *queue_type,
598 bool *is_kernel_allocated_cb)
eff6f4a0
OG
599{
600 struct asic_fixed_properties *asic = &hdev->asic_prop;
601 struct hw_queue_properties *hw_queue_prop;
eff6f4a0 602
3abc99bb
OB
603 /* This must be checked here to prevent out-of-bounds access to
604 * hw_queues_props array
605 */
606 if (chunk->queue_index >= asic->max_queues) {
607 dev_err(hdev->dev, "Queue index %d is invalid\n",
608 chunk->queue_index);
609 return -EINVAL;
610 }
611
eff6f4a0
OG
612 hw_queue_prop = &asic->hw_queues_props[chunk->queue_index];
613
3abc99bb 614 if (hw_queue_prop->type == QUEUE_TYPE_NA) {
eff6f4a0
OG
615 dev_err(hdev->dev, "Queue index %d is invalid\n",
616 chunk->queue_index);
cb596aee 617 return -EINVAL;
eff6f4a0
OG
618 }
619
4c172bbf
OG
620 if (hw_queue_prop->driver_only) {
621 dev_err(hdev->dev,
622 "Queue index %d is restricted for the kernel driver\n",
eff6f4a0 623 chunk->queue_index);
cb596aee 624 return -EINVAL;
df762375
TT
625 }
626
4bb1f2f3
TC
627 /* When hw queue type isn't QUEUE_TYPE_HW,
628 * USER_ALLOC_CB flag shall be referred as "don't care".
629 */
630 if (hw_queue_prop->type == QUEUE_TYPE_HW) {
631 if (chunk->cs_chunk_flags & HL_CS_CHUNK_FLAGS_USER_ALLOC_CB) {
632 if (!(hw_queue_prop->cb_alloc_flags & CB_ALLOC_USER)) {
633 dev_err(hdev->dev,
634 "Queue index %d doesn't support user CB\n",
635 chunk->queue_index);
636 return -EINVAL;
637 }
638
639 *is_kernel_allocated_cb = false;
640 } else {
641 if (!(hw_queue_prop->cb_alloc_flags &
642 CB_ALLOC_KERNEL)) {
643 dev_err(hdev->dev,
644 "Queue index %d doesn't support kernel CB\n",
645 chunk->queue_index);
646 return -EINVAL;
647 }
cb596aee 648
4bb1f2f3
TC
649 *is_kernel_allocated_cb = true;
650 }
651 } else {
652 *is_kernel_allocated_cb = !!(hw_queue_prop->cb_alloc_flags
653 & CB_ALLOC_KERNEL);
654 }
655
656 *queue_type = hw_queue_prop->type;
cb596aee
TT
657 return 0;
658}
659
660static struct hl_cb *get_cb_from_cs_chunk(struct hl_device *hdev,
661 struct hl_cb_mgr *cb_mgr,
662 struct hl_cs_chunk *chunk)
663{
664 struct hl_cb *cb;
665 u32 cb_handle;
eff6f4a0 666
eff6f4a0
OG
667 cb_handle = (u32) (chunk->cb_handle >> PAGE_SHIFT);
668
669 cb = hl_cb_get(hdev, cb_mgr, cb_handle);
670 if (!cb) {
671 dev_err(hdev->dev, "CB handle 0x%x invalid\n", cb_handle);
672 return NULL;
673 }
674
675 if ((chunk->cb_size < 8) || (chunk->cb_size > cb->size)) {
676 dev_err(hdev->dev, "CB size %u invalid\n", chunk->cb_size);
677 goto release_cb;
678 }
679
680 spin_lock(&cb->lock);
681 cb->cs_cnt++;
682 spin_unlock(&cb->lock);
683
684 return cb;
685
686release_cb:
687 hl_cb_put(cb);
688 return NULL;
689}
690
cb596aee
TT
691struct hl_cs_job *hl_cs_allocate_job(struct hl_device *hdev,
692 enum hl_queue_type queue_type, bool is_kernel_allocated_cb)
eff6f4a0
OG
693{
694 struct hl_cs_job *job;
695
696 job = kzalloc(sizeof(*job), GFP_ATOMIC);
697 if (!job)
698 return NULL;
699
649c4592 700 kref_init(&job->refcount);
cb596aee
TT
701 job->queue_type = queue_type;
702 job->is_kernel_allocated_cb = is_kernel_allocated_cb;
eff6f4a0 703
cb596aee 704 if (is_cb_patched(hdev, job))
eff6f4a0 705 INIT_LIST_HEAD(&job->userptr_list);
cb596aee
TT
706
707 if (job->queue_type == QUEUE_TYPE_EXT)
eff6f4a0 708 INIT_WORK(&job->finish_work, job_wq_completion);
eff6f4a0
OG
709
710 return job;
711}
712
6de3d769
TT
713static enum hl_cs_type hl_cs_get_cs_type(u32 cs_type_flags)
714{
715 if (cs_type_flags & HL_CS_FLAGS_SIGNAL)
716 return CS_TYPE_SIGNAL;
717 else if (cs_type_flags & HL_CS_FLAGS_WAIT)
718 return CS_TYPE_WAIT;
719 else if (cs_type_flags & HL_CS_FLAGS_COLLECTIVE_WAIT)
720 return CS_TYPE_COLLECTIVE_WAIT;
721 else
722 return CS_TYPE_DEFAULT;
723}
724
725static int hl_cs_sanity_checks(struct hl_fpriv *hpriv, union hl_cs_args *args)
eff6f4a0
OG
726{
727 struct hl_device *hdev = hpriv->hdev;
6de3d769
TT
728 struct hl_ctx *ctx = hpriv->ctx;
729 u32 cs_type_flags, num_chunks;
66a76401 730 enum hl_device_status status;
6de3d769 731 enum hl_cs_type cs_type;
eff6f4a0 732
66a76401 733 if (!hl_device_operational(hdev, &status)) {
6de3d769
TT
734 dev_warn_ratelimited(hdev->dev,
735 "Device is %s. Can't submit new CS\n",
66a76401 736 hdev->status[status]);
6de3d769
TT
737 return -EBUSY;
738 }
739
bd2f477f
OB
740 cs_type_flags = args->in.cs_flags &
741 ~(HL_CS_FLAGS_FORCE_RESTORE | HL_CS_FLAGS_TIMESTAMP);
6de3d769
TT
742
743 if (unlikely(cs_type_flags && !is_power_of_2(cs_type_flags))) {
744 dev_err(hdev->dev,
745 "CS type flags are mutually exclusive, context %d\n",
746 ctx->asid);
747 return -EINVAL;
748 }
749
750 cs_type = hl_cs_get_cs_type(cs_type_flags);
751 num_chunks = args->in.num_chunks_execute;
752
753 if (unlikely((cs_type != CS_TYPE_DEFAULT) &&
754 !hdev->supports_sync_stream)) {
755 dev_err(hdev->dev, "Sync stream CS is not supported\n");
756 return -EINVAL;
757 }
758
759 if (cs_type == CS_TYPE_DEFAULT) {
760 if (!num_chunks) {
761 dev_err(hdev->dev,
762 "Got execute CS with 0 chunks, context %d\n",
763 ctx->asid);
764 return -EINVAL;
765 }
766 } else if (num_chunks != 1) {
767 dev_err(hdev->dev,
768 "Sync stream CS mandates one chunk only, context %d\n",
769 ctx->asid);
770 return -EINVAL;
771 }
772
773 return 0;
774}
775
776static int hl_cs_copy_chunk_array(struct hl_device *hdev,
777 struct hl_cs_chunk **cs_chunk_array,
778 void __user *chunks, u32 num_chunks)
779{
780 u32 size_to_copy;
eff6f4a0
OG
781
782 if (num_chunks > HL_MAX_JOBS_PER_CS) {
783 dev_err(hdev->dev,
784 "Number of chunks can NOT be larger than %d\n",
785 HL_MAX_JOBS_PER_CS);
6de3d769 786 return -EINVAL;
eff6f4a0
OG
787 }
788
6de3d769 789 *cs_chunk_array = kmalloc_array(num_chunks, sizeof(**cs_chunk_array),
eff6f4a0 790 GFP_ATOMIC);
6de3d769
TT
791 if (!*cs_chunk_array)
792 return -ENOMEM;
eff6f4a0
OG
793
794 size_to_copy = num_chunks * sizeof(struct hl_cs_chunk);
6de3d769 795 if (copy_from_user(*cs_chunk_array, chunks, size_to_copy)) {
eff6f4a0 796 dev_err(hdev->dev, "Failed to copy cs chunk array from user\n");
6de3d769
TT
797 kfree(*cs_chunk_array);
798 return -EFAULT;
eff6f4a0
OG
799 }
800
6de3d769
TT
801 return 0;
802}
803
804static int cs_ioctl_default(struct hl_fpriv *hpriv, void __user *chunks,
bd2f477f 805 u32 num_chunks, u64 *cs_seq, bool timestamp)
6de3d769
TT
806{
807 bool int_queues_only = true;
808 struct hl_device *hdev = hpriv->hdev;
809 struct hl_cs_chunk *cs_chunk_array;
810 struct hl_cs_counters_atomic *cntr;
811 struct hl_cs_job *job;
812 struct hl_cs *cs;
813 struct hl_cb *cb;
814 int rc, i;
815
816 cntr = &hdev->aggregated_cs_counters;
817 *cs_seq = ULLONG_MAX;
818
819 rc = hl_cs_copy_chunk_array(hdev, &cs_chunk_array, chunks, num_chunks);
820 if (rc)
821 goto out;
822
eff6f4a0
OG
823 /* increment refcnt for context */
824 hl_ctx_get(hdev, hpriv->ctx);
825
b75f2250 826 rc = allocate_cs(hdev, hpriv->ctx, CS_TYPE_DEFAULT, &cs);
eff6f4a0
OG
827 if (rc) {
828 hl_ctx_put(hpriv->ctx);
829 goto free_cs_chunk_array;
830 }
831
bd2f477f 832 cs->timestamp = !!timestamp;
eff6f4a0
OG
833 *cs_seq = cs->sequence;
834
c2164773
OG
835 hl_debugfs_add_cs(cs);
836
eff6f4a0 837 /* Validate ALL the CS chunks before submitting the CS */
b41e9728 838 for (i = 0 ; i < num_chunks ; i++) {
eff6f4a0 839 struct hl_cs_chunk *chunk = &cs_chunk_array[i];
cb596aee
TT
840 enum hl_queue_type queue_type;
841 bool is_kernel_allocated_cb;
842
843 rc = validate_queue_index(hdev, chunk, &queue_type,
844 &is_kernel_allocated_cb);
db491e4f 845 if (rc) {
e753643d 846 atomic64_inc(&hpriv->ctx->cs_counters.parsing_drop_cnt);
23c15ae6 847 atomic64_inc(&cntr->parsing_drop_cnt);
cb596aee 848 goto free_cs_object;
db491e4f 849 }
eff6f4a0 850
cb596aee
TT
851 if (is_kernel_allocated_cb) {
852 cb = get_cb_from_cs_chunk(hdev, &hpriv->cb_mgr, chunk);
eff6f4a0 853 if (!cb) {
e753643d 854 atomic64_inc(
855 &hpriv->ctx->cs_counters.parsing_drop_cnt);
23c15ae6 856 atomic64_inc(&cntr->parsing_drop_cnt);
eff6f4a0
OG
857 rc = -EINVAL;
858 goto free_cs_object;
859 }
cb596aee
TT
860 } else {
861 cb = (struct hl_cb *) (uintptr_t) chunk->cb_handle;
eff6f4a0
OG
862 }
863
cb596aee
TT
864 if (queue_type == QUEUE_TYPE_EXT || queue_type == QUEUE_TYPE_HW)
865 int_queues_only = false;
866
867 job = hl_cs_allocate_job(hdev, queue_type,
868 is_kernel_allocated_cb);
eff6f4a0 869 if (!job) {
e753643d 870 atomic64_inc(
871 &hpriv->ctx->cs_counters.out_of_mem_drop_cnt);
23c15ae6 872 atomic64_inc(&cntr->out_of_mem_drop_cnt);
eff6f4a0
OG
873 dev_err(hdev->dev, "Failed to allocate a new job\n");
874 rc = -ENOMEM;
cb596aee 875 if (is_kernel_allocated_cb)
eff6f4a0 876 goto release_cb;
bd4ef372
OG
877
878 goto free_cs_object;
eff6f4a0
OG
879 }
880
881 job->id = i + 1;
882 job->cs = cs;
883 job->user_cb = cb;
884 job->user_cb_size = chunk->cb_size;
eff6f4a0
OG
885 job->hw_queue_id = chunk->queue_index;
886
887 cs->jobs_in_queue_cnt[job->hw_queue_id]++;
888
889 list_add_tail(&job->cs_node, &cs->job_list);
890
891 /*
892 * Increment CS reference. When CS reference is 0, CS is
893 * done and can be signaled to user and free all its resources
cb596aee
TT
894 * Only increment for JOB on external or H/W queues, because
895 * only for those JOBs we get completion
eff6f4a0 896 */
cb596aee
TT
897 if (job->queue_type == QUEUE_TYPE_EXT ||
898 job->queue_type == QUEUE_TYPE_HW)
eff6f4a0
OG
899 cs_get(cs);
900
c2164773
OG
901 hl_debugfs_add_job(hdev, job);
902
eff6f4a0
OG
903 rc = cs_parser(hpriv, job);
904 if (rc) {
e753643d 905 atomic64_inc(&hpriv->ctx->cs_counters.parsing_drop_cnt);
23c15ae6 906 atomic64_inc(&cntr->parsing_drop_cnt);
eff6f4a0
OG
907 dev_err(hdev->dev,
908 "Failed to parse JOB %d.%llu.%d, err %d, rejecting the CS\n",
909 cs->ctx->asid, cs->sequence, job->id, rc);
910 goto free_cs_object;
911 }
912 }
913
cb596aee 914 if (int_queues_only) {
e753643d 915 atomic64_inc(&hpriv->ctx->cs_counters.parsing_drop_cnt);
23c15ae6 916 atomic64_inc(&cntr->parsing_drop_cnt);
eff6f4a0 917 dev_err(hdev->dev,
cb596aee 918 "Reject CS %d.%llu because only internal queues jobs are present\n",
eff6f4a0
OG
919 cs->ctx->asid, cs->sequence);
920 rc = -EINVAL;
921 goto free_cs_object;
922 }
923
924 rc = hl_hw_queue_schedule_cs(cs);
925 if (rc) {
eda58bf7
OG
926 if (rc != -EAGAIN)
927 dev_err(hdev->dev,
928 "Failed to submit CS %d.%llu to H/W queues, error %d\n",
929 cs->ctx->asid, cs->sequence, rc);
eff6f4a0
OG
930 goto free_cs_object;
931 }
932
933 rc = HL_CS_STATUS_SUCCESS;
934 goto put_cs;
935
936release_cb:
937 spin_lock(&cb->lock);
938 cb->cs_cnt--;
939 spin_unlock(&cb->lock);
940 hl_cb_put(cb);
941free_cs_object:
942 cs_rollback(hdev, cs);
943 *cs_seq = ULLONG_MAX;
944 /* The path below is both for good and erroneous exits */
945put_cs:
946 /* We finished with the CS in this function, so put the ref */
947 cs_put(cs);
948free_cs_chunk_array:
949 kfree(cs_chunk_array);
950out:
951 return rc;
952}
953
6de3d769
TT
954static int hl_cs_ctx_switch(struct hl_fpriv *hpriv, union hl_cs_args *args,
955 u64 *cs_seq)
956{
957 struct hl_device *hdev = hpriv->hdev;
958 struct hl_ctx *ctx = hpriv->ctx;
959 bool need_soft_reset = false;
960 int rc = 0, do_ctx_switch;
961 void __user *chunks;
962 u32 num_chunks, tmp;
9d127ad5 963 int ret;
6de3d769
TT
964
965 do_ctx_switch = atomic_cmpxchg(&ctx->thread_ctx_switch_token, 1, 0);
966
967 if (do_ctx_switch || (args->in.cs_flags & HL_CS_FLAGS_FORCE_RESTORE)) {
968 mutex_lock(&hpriv->restore_phase_mutex);
969
970 if (do_ctx_switch) {
971 rc = hdev->asic_funcs->context_switch(hdev, ctx->asid);
972 if (rc) {
973 dev_err_ratelimited(hdev->dev,
974 "Failed to switch to context %d, rejecting CS! %d\n",
975 ctx->asid, rc);
976 /*
977 * If we timedout, or if the device is not IDLE
978 * while we want to do context-switch (-EBUSY),
979 * we need to soft-reset because QMAN is
980 * probably stuck. However, we can't call to
981 * reset here directly because of deadlock, so
982 * need to do it at the very end of this
983 * function
984 */
985 if ((rc == -ETIMEDOUT) || (rc == -EBUSY))
986 need_soft_reset = true;
987 mutex_unlock(&hpriv->restore_phase_mutex);
988 goto out;
989 }
990 }
991
992 hdev->asic_funcs->restore_phase_topology(hdev);
993
994 chunks = (void __user *) (uintptr_t) args->in.chunks_restore;
995 num_chunks = args->in.num_chunks_restore;
996
997 if (!num_chunks) {
998 dev_dbg(hdev->dev,
999 "Need to run restore phase but restore CS is empty\n");
1000 rc = 0;
1001 } else {
1002 rc = cs_ioctl_default(hpriv, chunks, num_chunks,
bd2f477f 1003 cs_seq, false);
6de3d769
TT
1004 }
1005
1006 mutex_unlock(&hpriv->restore_phase_mutex);
1007
1008 if (rc) {
1009 dev_err(hdev->dev,
1010 "Failed to submit restore CS for context %d (%d)\n",
1011 ctx->asid, rc);
1012 goto out;
1013 }
1014
1015 /* Need to wait for restore completion before execution phase */
1016 if (num_chunks) {
9d127ad5 1017 enum hl_cs_wait_status status;
6de3d769
TT
1018wait_again:
1019 ret = _hl_cs_wait_ioctl(hdev, ctx,
1020 jiffies_to_usecs(hdev->timeout_jiffies),
bd2f477f 1021 *cs_seq, &status, NULL);
9d127ad5 1022 if (ret) {
6de3d769
TT
1023 if (ret == -ERESTARTSYS) {
1024 usleep_range(100, 200);
1025 goto wait_again;
1026 }
1027
1028 dev_err(hdev->dev,
9d127ad5 1029 "Restore CS for context %d failed to complete %d\n",
6de3d769
TT
1030 ctx->asid, ret);
1031 rc = -ENOEXEC;
1032 goto out;
1033 }
1034 }
1035
1036 ctx->thread_ctx_switch_wait_token = 1;
1037
1038 } else if (!ctx->thread_ctx_switch_wait_token) {
1039 rc = hl_poll_timeout_memory(hdev,
1040 &ctx->thread_ctx_switch_wait_token, tmp, (tmp == 1),
1041 100, jiffies_to_usecs(hdev->timeout_jiffies), false);
1042
1043 if (rc == -ETIMEDOUT) {
1044 dev_err(hdev->dev,
1045 "context switch phase timeout (%d)\n", tmp);
1046 goto out;
1047 }
1048 }
1049
1050out:
1051 if ((rc == -ETIMEDOUT || rc == -EBUSY) && (need_soft_reset))
1052 hl_device_reset(hdev, false, false);
1053
1054 return rc;
1055}
1056
06f791f7
OB
1057static int cs_ioctl_extract_signal_seq(struct hl_device *hdev,
1058 struct hl_cs_chunk *chunk, u64 *signal_seq)
1059{
1060 u64 *signal_seq_arr = NULL;
1061 u32 size_to_copy, signal_seq_arr_len;
1062 int rc = 0;
1063
1064 signal_seq_arr_len = chunk->num_signal_seq_arr;
1065
1066 /* currently only one signal seq is supported */
1067 if (signal_seq_arr_len != 1) {
1068 dev_err(hdev->dev,
1069 "Wait for signal CS supports only one signal CS seq\n");
1070 return -EINVAL;
1071 }
1072
1073 signal_seq_arr = kmalloc_array(signal_seq_arr_len,
1074 sizeof(*signal_seq_arr),
1075 GFP_ATOMIC);
1076 if (!signal_seq_arr)
1077 return -ENOMEM;
1078
1079 size_to_copy = chunk->num_signal_seq_arr * sizeof(*signal_seq_arr);
1080 if (copy_from_user(signal_seq_arr,
1081 u64_to_user_ptr(chunk->signal_seq_arr),
1082 size_to_copy)) {
1083 dev_err(hdev->dev,
1084 "Failed to copy signal seq array from user\n");
1085 rc = -EFAULT;
1086 goto out;
1087 }
1088
1089 /* currently it is guaranteed to have only one signal seq */
1090 *signal_seq = signal_seq_arr[0];
1091
1092out:
1093 kfree(signal_seq_arr);
1094
1095 return rc;
1096}
1097
1098static int cs_ioctl_signal_wait_create_jobs(struct hl_device *hdev,
1099 struct hl_ctx *ctx, struct hl_cs *cs, enum hl_queue_type q_type,
1100 u32 q_idx)
1101{
1102 struct hl_cs_counters_atomic *cntr;
1103 struct hl_cs_job *job;
1104 struct hl_cb *cb;
1105 u32 cb_size;
1106
1107 cntr = &hdev->aggregated_cs_counters;
1108
1109 job = hl_cs_allocate_job(hdev, q_type, true);
1110 if (!job) {
e753643d 1111 atomic64_inc(&ctx->cs_counters.out_of_mem_drop_cnt);
06f791f7
OB
1112 atomic64_inc(&cntr->out_of_mem_drop_cnt);
1113 dev_err(hdev->dev, "Failed to allocate a new job\n");
1114 return -ENOMEM;
1115 }
1116
1117 if (cs->type == CS_TYPE_WAIT)
1118 cb_size = hdev->asic_funcs->get_wait_cb_size(hdev);
1119 else
1120 cb_size = hdev->asic_funcs->get_signal_cb_size(hdev);
1121
1122 cb = hl_cb_kernel_create(hdev, cb_size,
1123 q_type == QUEUE_TYPE_HW && hdev->mmu_enable);
1124 if (!cb) {
e753643d 1125 atomic64_inc(&ctx->cs_counters.out_of_mem_drop_cnt);
06f791f7
OB
1126 atomic64_inc(&cntr->out_of_mem_drop_cnt);
1127 kfree(job);
1128 return -EFAULT;
1129 }
1130
1131 job->id = 0;
1132 job->cs = cs;
1133 job->user_cb = cb;
1134 job->user_cb->cs_cnt++;
1135 job->user_cb_size = cb_size;
1136 job->hw_queue_id = q_idx;
1137
1138 /*
1139 * No need in parsing, user CB is the patched CB.
1140 * We call hl_cb_destroy() out of two reasons - we don't need the CB in
1141 * the CB idr anymore and to decrement its refcount as it was
1142 * incremented inside hl_cb_kernel_create().
1143 */
1144 job->patched_cb = job->user_cb;
1145 job->job_cb_size = job->user_cb_size;
1146 hl_cb_destroy(hdev, &hdev->kernel_cb_mgr, cb->id << PAGE_SHIFT);
1147
5de406c0
OB
1148 /* increment refcount as for external queues we get completion */
1149 cs_get(cs);
1150
06f791f7
OB
1151 cs->jobs_in_queue_cnt[job->hw_queue_id]++;
1152
1153 list_add_tail(&job->cs_node, &cs->job_list);
1154
1155 hl_debugfs_add_job(hdev, job);
1156
1157 return 0;
1158}
1159
b75f2250
OS
1160static int cs_ioctl_signal_wait(struct hl_fpriv *hpriv, enum hl_cs_type cs_type,
1161 void __user *chunks, u32 num_chunks,
bd2f477f 1162 u64 *cs_seq, bool timestamp)
b75f2250 1163{
b75f2250
OS
1164 struct hl_cs_chunk *cs_chunk_array, *chunk;
1165 struct hw_queue_properties *hw_queue_prop;
6de3d769 1166 struct hl_device *hdev = hpriv->hdev;
06f791f7 1167 struct hl_cs_compl *sig_waitcs_cmpl;
6de3d769
TT
1168 u32 q_idx, collective_engine_id = 0;
1169 struct hl_fence *sig_fence = NULL;
1170 struct hl_ctx *ctx = hpriv->ctx;
06f791f7 1171 enum hl_queue_type q_type;
6de3d769 1172 struct hl_cs *cs;
06f791f7 1173 u64 signal_seq;
b75f2250
OS
1174 int rc;
1175
1176 *cs_seq = ULLONG_MAX;
1177
6de3d769
TT
1178 rc = hl_cs_copy_chunk_array(hdev, &cs_chunk_array, chunks, num_chunks);
1179 if (rc)
b75f2250 1180 goto out;
b75f2250
OS
1181
1182 /* currently it is guaranteed to have only one chunk */
1183 chunk = &cs_chunk_array[0];
1cff1197
OB
1184
1185 if (chunk->queue_index >= hdev->asic_prop.max_queues) {
1186 dev_err(hdev->dev, "Queue index %d is invalid\n",
1187 chunk->queue_index);
1188 rc = -EINVAL;
1189 goto free_cs_chunk_array;
1190 }
1191
b75f2250
OS
1192 q_idx = chunk->queue_index;
1193 hw_queue_prop = &hdev->asic_prop.hw_queues_props[q_idx];
21e7a346 1194 q_type = hw_queue_prop->type;
b75f2250 1195
becce5f9
OG
1196 if (!hw_queue_prop->supports_sync_stream) {
1197 dev_err(hdev->dev,
1198 "Queue index %d does not support sync stream operations\n",
1199 q_idx);
b75f2250
OS
1200 rc = -EINVAL;
1201 goto free_cs_chunk_array;
1202 }
1203
5fe1c17d
OB
1204 if (cs_type == CS_TYPE_COLLECTIVE_WAIT) {
1205 if (!(hw_queue_prop->collective_mode == HL_COLLECTIVE_MASTER)) {
1206 dev_err(hdev->dev,
1207 "Queue index %d is invalid\n", q_idx);
1208 rc = -EINVAL;
1209 goto free_cs_chunk_array;
1210 }
1211
1212 collective_engine_id = chunk->collective_engine_id;
1213 }
1214
1215 if (cs_type == CS_TYPE_WAIT || cs_type == CS_TYPE_COLLECTIVE_WAIT) {
06f791f7
OB
1216 rc = cs_ioctl_extract_signal_seq(hdev, chunk, &signal_seq);
1217 if (rc)
b75f2250 1218 goto free_cs_chunk_array;
b75f2250 1219
b75f2250
OS
1220 sig_fence = hl_ctx_get_fence(ctx, signal_seq);
1221 if (IS_ERR(sig_fence)) {
1222 dev_err(hdev->dev,
1223 "Failed to get signal CS with seq 0x%llx\n",
1224 signal_seq);
1225 rc = PTR_ERR(sig_fence);
06f791f7 1226 goto free_cs_chunk_array;
b75f2250
OS
1227 }
1228
1229 if (!sig_fence) {
1230 /* signal CS already finished */
1231 rc = 0;
06f791f7 1232 goto free_cs_chunk_array;
b75f2250
OS
1233 }
1234
1235 sig_waitcs_cmpl =
1236 container_of(sig_fence, struct hl_cs_compl, base_fence);
1237
1238 if (sig_waitcs_cmpl->type != CS_TYPE_SIGNAL) {
1239 dev_err(hdev->dev,
1240 "CS seq 0x%llx is not of a signal CS\n",
1241 signal_seq);
a98d73c7 1242 hl_fence_put(sig_fence);
b75f2250 1243 rc = -EINVAL;
06f791f7 1244 goto free_cs_chunk_array;
b75f2250
OS
1245 }
1246
a98d73c7 1247 if (completion_done(&sig_fence->completion)) {
b75f2250 1248 /* signal CS already finished */
a98d73c7 1249 hl_fence_put(sig_fence);
b75f2250 1250 rc = 0;
06f791f7 1251 goto free_cs_chunk_array;
b75f2250
OS
1252 }
1253 }
1254
1255 /* increment refcnt for context */
1256 hl_ctx_get(hdev, ctx);
1257
1258 rc = allocate_cs(hdev, ctx, cs_type, &cs);
1259 if (rc) {
5fe1c17d
OB
1260 if (cs_type == CS_TYPE_WAIT ||
1261 cs_type == CS_TYPE_COLLECTIVE_WAIT)
a98d73c7 1262 hl_fence_put(sig_fence);
b75f2250 1263 hl_ctx_put(ctx);
06f791f7 1264 goto free_cs_chunk_array;
b75f2250
OS
1265 }
1266
bd2f477f
OB
1267 cs->timestamp = !!timestamp;
1268
b75f2250
OS
1269 /*
1270 * Save the signal CS fence for later initialization right before
1271 * hanging the wait CS on the queue.
1272 */
5fe1c17d 1273 if (cs_type == CS_TYPE_WAIT || cs_type == CS_TYPE_COLLECTIVE_WAIT)
b75f2250
OS
1274 cs->signal_fence = sig_fence;
1275
1276 hl_debugfs_add_cs(cs);
1277
1278 *cs_seq = cs->sequence;
1279
06f791f7
OB
1280 if (cs_type == CS_TYPE_WAIT || cs_type == CS_TYPE_SIGNAL)
1281 rc = cs_ioctl_signal_wait_create_jobs(hdev, ctx, cs, q_type,
1282 q_idx);
e716ad3c 1283 else if (cs_type == CS_TYPE_COLLECTIVE_WAIT)
5fe1c17d
OB
1284 rc = hdev->asic_funcs->collective_wait_create_jobs(hdev, ctx,
1285 cs, q_idx, collective_engine_id);
e716ad3c
OG
1286 else
1287 rc = -EINVAL;
a04b7cd9 1288
06f791f7 1289 if (rc)
5de406c0 1290 goto free_cs_object;
b75f2250 1291
b75f2250
OS
1292 rc = hl_hw_queue_schedule_cs(cs);
1293 if (rc) {
1294 if (rc != -EAGAIN)
1295 dev_err(hdev->dev,
1296 "Failed to submit CS %d.%llu to H/W queues, error %d\n",
1297 ctx->asid, cs->sequence, rc);
1298 goto free_cs_object;
1299 }
1300
1301 rc = HL_CS_STATUS_SUCCESS;
1302 goto put_cs;
1303
1304free_cs_object:
1305 cs_rollback(hdev, cs);
1306 *cs_seq = ULLONG_MAX;
1307 /* The path below is both for good and erroneous exits */
1308put_cs:
1309 /* We finished with the CS in this function, so put the ref */
1310 cs_put(cs);
b75f2250
OS
1311free_cs_chunk_array:
1312 kfree(cs_chunk_array);
1313out:
1314 return rc;
1315}
1316
eff6f4a0
OG
1317int hl_cs_ioctl(struct hl_fpriv *hpriv, void *data)
1318{
eff6f4a0 1319 union hl_cs_args *args = data;
b75f2250 1320 enum hl_cs_type cs_type;
eff6f4a0 1321 u64 cs_seq = ULONG_MAX;
6de3d769
TT
1322 void __user *chunks;
1323 u32 num_chunks;
1324 int rc;
b75f2250 1325
6de3d769
TT
1326 rc = hl_cs_sanity_checks(hpriv, args);
1327 if (rc)
f9e5f295 1328 goto out;
f9e5f295 1329
6de3d769
TT
1330 rc = hl_cs_ctx_switch(hpriv, args, &cs_seq);
1331 if (rc)
1718a45b 1332 goto out;
eff6f4a0 1333
6de3d769
TT
1334 cs_type = hl_cs_get_cs_type(args->in.cs_flags &
1335 ~HL_CS_FLAGS_FORCE_RESTORE);
1336 chunks = (void __user *) (uintptr_t) args->in.chunks_execute;
1337 num_chunks = args->in.num_chunks_execute;
1338
1339 switch (cs_type) {
1340 case CS_TYPE_SIGNAL:
1341 case CS_TYPE_WAIT:
1342 case CS_TYPE_COLLECTIVE_WAIT:
1343 rc = cs_ioctl_signal_wait(hpriv, cs_type, chunks, num_chunks,
bd2f477f 1344 &cs_seq, args->in.cs_flags & HL_CS_FLAGS_TIMESTAMP);
6de3d769
TT
1345 break;
1346 default:
bd2f477f
OB
1347 rc = cs_ioctl_default(hpriv, chunks, num_chunks, &cs_seq,
1348 args->in.cs_flags & HL_CS_FLAGS_TIMESTAMP);
6de3d769 1349 break;
eff6f4a0
OG
1350 }
1351
eff6f4a0
OG
1352out:
1353 if (rc != -EAGAIN) {
1354 memset(args, 0, sizeof(*args));
1355 args->out.status = rc;
1356 args->out.seq = cs_seq;
1357 }
1358
eff6f4a0
OG
1359 return rc;
1360}
1361
9d127ad5
OB
1362static int _hl_cs_wait_ioctl(struct hl_device *hdev, struct hl_ctx *ctx,
1363 u64 timeout_us, u64 seq,
bd2f477f 1364 enum hl_cs_wait_status *status, s64 *timestamp)
eff6f4a0 1365{
a98d73c7 1366 struct hl_fence *fence;
eff6f4a0 1367 unsigned long timeout;
9d127ad5
OB
1368 int rc = 0;
1369 long completion_rc;
eff6f4a0 1370
bd2f477f
OB
1371 if (timestamp)
1372 *timestamp = 0;
1373
eff6f4a0
OG
1374 if (timeout_us == MAX_SCHEDULE_TIMEOUT)
1375 timeout = timeout_us;
1376 else
1377 timeout = usecs_to_jiffies(timeout_us);
1378
1379 hl_ctx_get(hdev, ctx);
1380
1381 fence = hl_ctx_get_fence(ctx, seq);
1382 if (IS_ERR(fence)) {
1383 rc = PTR_ERR(fence);
b75f2250
OS
1384 if (rc == -EINVAL)
1385 dev_notice_ratelimited(hdev->dev,
0eab4f89 1386 "Can't wait on CS %llu because current CS is at seq %llu\n",
b75f2250 1387 seq, ctx->cs_sequence);
eff6f4a0 1388 } else if (fence) {
681a22f5 1389 if (!timeout_us)
9d127ad5 1390 completion_rc = completion_done(&fence->completion);
681a22f5 1391 else
9d127ad5
OB
1392 completion_rc =
1393 wait_for_completion_interruptible_timeout(
681a22f5 1394 &fence->completion, timeout);
a98d73c7 1395
bd2f477f 1396 if (completion_rc > 0) {
9d127ad5 1397 *status = CS_WAIT_STATUS_COMPLETED;
bd2f477f
OB
1398 if (timestamp)
1399 *timestamp = ktime_to_ns(fence->timestamp);
1400 } else {
9d127ad5 1401 *status = CS_WAIT_STATUS_BUSY;
bd2f477f 1402 }
9d127ad5 1403
eff6f4a0
OG
1404 if (fence->error == -ETIMEDOUT)
1405 rc = -ETIMEDOUT;
1406 else if (fence->error == -EIO)
1407 rc = -EIO;
a98d73c7
OB
1408
1409 hl_fence_put(fence);
b75f2250
OS
1410 } else {
1411 dev_dbg(hdev->dev,
1412 "Can't wait on seq %llu because current CS is at seq %llu (Fence is gone)\n",
1413 seq, ctx->cs_sequence);
9d127ad5 1414 *status = CS_WAIT_STATUS_GONE;
b75f2250 1415 }
eff6f4a0
OG
1416
1417 hl_ctx_put(ctx);
1418
1419 return rc;
1420}
1421
1422int hl_cs_wait_ioctl(struct hl_fpriv *hpriv, void *data)
1423{
1424 struct hl_device *hdev = hpriv->hdev;
1425 union hl_wait_cs_args *args = data;
9d127ad5 1426 enum hl_cs_wait_status status;
eff6f4a0 1427 u64 seq = args->in.seq;
bd2f477f 1428 s64 timestamp;
9d127ad5 1429 int rc;
eff6f4a0 1430
9d127ad5 1431 rc = _hl_cs_wait_ioctl(hdev, hpriv->ctx, args->in.timeout_us, seq,
bd2f477f 1432 &status, &timestamp);
eff6f4a0
OG
1433
1434 memset(args, 0, sizeof(*args));
1435
9d127ad5 1436 if (rc) {
eff6f4a0 1437 if (rc == -ERESTARTSYS) {
0eab4f89
OG
1438 dev_err_ratelimited(hdev->dev,
1439 "user process got signal while waiting for CS handle %llu\n",
1440 seq);
eff6f4a0
OG
1441 args->out.status = HL_WAIT_CS_STATUS_INTERRUPTED;
1442 rc = -EINTR;
1443 } else if (rc == -ETIMEDOUT) {
0eab4f89
OG
1444 dev_err_ratelimited(hdev->dev,
1445 "CS %llu has timed-out while user process is waiting for it\n",
1446 seq);
eff6f4a0
OG
1447 args->out.status = HL_WAIT_CS_STATUS_TIMEDOUT;
1448 } else if (rc == -EIO) {
0eab4f89
OG
1449 dev_err_ratelimited(hdev->dev,
1450 "CS %llu has been aborted while user process is waiting for it\n",
1451 seq);
eff6f4a0
OG
1452 args->out.status = HL_WAIT_CS_STATUS_ABORTED;
1453 }
1454 return rc;
1455 }
1456
bd2f477f
OB
1457 if (timestamp) {
1458 args->out.flags |= HL_WAIT_CS_STATUS_FLAG_TIMESTAMP_VLD;
1459 args->out.timestamp_nsec = timestamp;
1460 }
1461
9d127ad5
OB
1462 switch (status) {
1463 case CS_WAIT_STATUS_GONE:
1464 args->out.flags |= HL_WAIT_CS_STATUS_FLAG_GONE;
1465 fallthrough;
1466 case CS_WAIT_STATUS_COMPLETED:
eff6f4a0 1467 args->out.status = HL_WAIT_CS_STATUS_COMPLETED;
9d127ad5
OB
1468 break;
1469 case CS_WAIT_STATUS_BUSY:
1470 default:
1471 args->out.status = HL_WAIT_CS_STATUS_BUSY;
1472 break;
1473 }
eff6f4a0
OG
1474
1475 return 0;
1476}