Skip to content

Commit ba6b035

Browse files
author
Stanislaw Gruszka
committed
accel/ivpu: Abort pending rx ipc on reset
Waking up process, which wait for particular condition, will go to sleep again on wake_up() if the condition is not met. Add abort flag to wake up IPC receivers, which will finish with -ECANCELED error. This is only needed for reset, run time power management prevent to suspend VPU when there is pending IPC processing or pending job. Reviewed-by: Karol Wachowski <karol.wachowski@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20231028155936.1183342-5-stanislaw.gruszka@linux.intel.com
1 parent 57c7e3e commit ba6b035

File tree

3 files changed

+20
-4
lines changed

3 files changed

+20
-4
lines changed

drivers/accel/ivpu/ivpu_ipc.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ ivpu_ipc_consumer_add(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
148148
cons->channel = channel;
149149
cons->tx_vpu_addr = 0;
150150
cons->request_id = 0;
151+
cons->aborted = false;
151152
spin_lock_init(&cons->rx_msg_lock);
152153
INIT_LIST_HEAD(&cons->rx_msg_list);
153154
init_waitqueue_head(&cons->rx_msg_wq);
@@ -169,7 +170,8 @@ void ivpu_ipc_consumer_del(struct ivpu_device *vdev, struct ivpu_ipc_consumer *c
169170
spin_lock_irq(&cons->rx_msg_lock);
170171
list_for_each_entry_safe(rx_msg, r, &cons->rx_msg_list, link) {
171172
list_del(&rx_msg->link);
172-
ivpu_ipc_rx_mark_free(vdev, rx_msg->ipc_hdr, rx_msg->jsm_msg);
173+
if (!cons->aborted)
174+
ivpu_ipc_rx_mark_free(vdev, rx_msg->ipc_hdr, rx_msg->jsm_msg);
173175
atomic_dec(&ipc->rx_msg_count);
174176
kfree(rx_msg);
175177
}
@@ -210,7 +212,7 @@ static int ivpu_ipc_rx_need_wakeup(struct ivpu_ipc_consumer *cons)
210212
ret |= (kthread_should_stop() || kthread_should_park());
211213

212214
spin_lock_irq(&cons->rx_msg_lock);
213-
ret |= !list_empty(&cons->rx_msg_list);
215+
ret |= !list_empty(&cons->rx_msg_list) || cons->aborted;
214216
spin_unlock_irq(&cons->rx_msg_lock);
215217

216218
return ret;
@@ -244,6 +246,12 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
244246
return -EAGAIN;
245247
}
246248
list_del(&rx_msg->link);
249+
if (cons->aborted) {
250+
spin_unlock_irq(&cons->rx_msg_lock);
251+
ret = -ECANCELED;
252+
goto out;
253+
}
254+
247255
spin_unlock_irq(&cons->rx_msg_lock);
248256

249257
if (ipc_buf)
@@ -261,6 +269,7 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
261269
}
262270

263271
ivpu_ipc_rx_mark_free(vdev, rx_msg->ipc_hdr, rx_msg->jsm_msg);
272+
out:
264273
atomic_dec(&ipc->rx_msg_count);
265274
kfree(rx_msg);
266275

@@ -522,8 +531,12 @@ void ivpu_ipc_disable(struct ivpu_device *vdev)
522531
mutex_unlock(&ipc->lock);
523532

524533
spin_lock_irqsave(&ipc->cons_list_lock, flags);
525-
list_for_each_entry_safe(cons, c, &ipc->cons_list, link)
534+
list_for_each_entry_safe(cons, c, &ipc->cons_list, link) {
535+
spin_lock(&cons->rx_msg_lock);
536+
cons->aborted = true;
537+
spin_unlock(&cons->rx_msg_lock);
526538
wake_up(&cons->rx_msg_wq);
539+
}
527540
spin_unlock_irqrestore(&ipc->cons_list_lock, flags);
528541
}
529542

@@ -532,6 +545,7 @@ void ivpu_ipc_reset(struct ivpu_device *vdev)
532545
struct ivpu_ipc_info *ipc = vdev->ipc;
533546

534547
mutex_lock(&ipc->lock);
548+
drm_WARN_ON(&vdev->drm, ipc->on);
535549

536550
memset(ivpu_bo_vaddr(ipc->mem_tx), 0, ivpu_bo_size(ipc->mem_tx));
537551
memset(ivpu_bo_vaddr(ipc->mem_rx), 0, ivpu_bo_size(ipc->mem_rx));

drivers/accel/ivpu/ivpu_ipc.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ struct ivpu_ipc_consumer {
4747
u32 channel;
4848
u32 tx_vpu_addr;
4949
u32 request_id;
50+
bool aborted;
5051

51-
spinlock_t rx_msg_lock; /* Protects rx_msg_list */
52+
spinlock_t rx_msg_lock; /* Protects rx_msg_list and aborted */
5253
struct list_head rx_msg_list;
5354
wait_queue_head_t rx_msg_wq;
5455
};

drivers/accel/ivpu/ivpu_job.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,7 @@ static int ivpu_job_done_thread(void *arg)
578578
ivpu_ipc_consumer_add(vdev, &cons, VPU_IPC_CHAN_JOB_RET);
579579

580580
while (!kthread_should_stop()) {
581+
cons.aborted = false;
581582
timeout = ivpu_tdr_timeout_ms ? ivpu_tdr_timeout_ms : vdev->timeout.tdr;
582583
jobs_submitted = !xa_empty(&vdev->submitted_jobs_xa);
583584
ret = ivpu_ipc_receive(vdev, &cons, NULL, &jsm_msg, timeout);

0 commit comments

Comments
 (0)