Skip to content

Commit 57c7e3e

Browse files
author
Stanislaw Gruszka
committed
accel/ivpu: Stop job_done_thread on suspend
Stop job_done thread when going to suspend. Use kthread_park() instead of kthread_stop() to avoid memory allocation and potential failure on resume. Use separate function as thread wake up condition. Use spin lock to assure rx_msg_list is properly protected against concurrent access. This avoid race condition when the rx_msg_list list is modified and read in ivpu_ipc_recive() at the same time. 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-4-stanislaw.gruszka@linux.intel.com
1 parent a06eb9b commit 57c7e3e

File tree

4 files changed

+35
-6
lines changed

4 files changed

+35
-6
lines changed

drivers/accel/ivpu/ivpu_drv.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ int ivpu_boot(struct ivpu_device *vdev)
378378
enable_irq(vdev->irq);
379379
ivpu_hw_irq_enable(vdev);
380380
ivpu_ipc_enable(vdev);
381+
ivpu_job_done_thread_enable(vdev);
381382
return 0;
382383
}
383384

@@ -389,6 +390,7 @@ int ivpu_shutdown(struct ivpu_device *vdev)
389390
disable_irq(vdev->irq);
390391
ivpu_ipc_disable(vdev);
391392
ivpu_mmu_disable(vdev);
393+
ivpu_job_done_thread_disable(vdev);
392394

393395
ret = ivpu_hw_power_down(vdev);
394396
if (ret)

drivers/accel/ivpu/ivpu_ipc.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,20 @@ ivpu_ipc_send(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, struct v
202202
return ret;
203203
}
204204

205+
static int ivpu_ipc_rx_need_wakeup(struct ivpu_ipc_consumer *cons)
206+
{
207+
int ret = 0;
208+
209+
if (IS_KTHREAD())
210+
ret |= (kthread_should_stop() || kthread_should_park());
211+
212+
spin_lock_irq(&cons->rx_msg_lock);
213+
ret |= !list_empty(&cons->rx_msg_list);
214+
spin_unlock_irq(&cons->rx_msg_lock);
215+
216+
return ret;
217+
}
218+
205219
int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
206220
struct ivpu_ipc_hdr *ipc_buf,
207221
struct vpu_jsm_msg *ipc_payload, unsigned long timeout_ms)
@@ -211,8 +225,7 @@ int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
211225
int wait_ret, ret = 0;
212226

213227
wait_ret = wait_event_interruptible_timeout(cons->rx_msg_wq,
214-
(IS_KTHREAD() && kthread_should_stop()) ||
215-
!list_empty(&cons->rx_msg_list),
228+
ivpu_ipc_rx_need_wakeup(cons),
216229
msecs_to_jiffies(timeout_ms));
217230

218231
if (IS_KTHREAD() && kthread_should_stop())

drivers/accel/ivpu/ivpu_job.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,11 @@ static int ivpu_job_done_thread(void *arg)
590590
ivpu_pm_schedule_recovery(vdev);
591591
}
592592
}
593+
if (kthread_should_park()) {
594+
ivpu_dbg(vdev, JOB, "Parked %s\n", __func__);
595+
kthread_parkme();
596+
ivpu_dbg(vdev, JOB, "Unparked %s\n", __func__);
597+
}
593598
}
594599

595600
ivpu_ipc_consumer_del(vdev, &cons);
@@ -610,16 +615,23 @@ int ivpu_job_done_thread_init(struct ivpu_device *vdev)
610615
return -EIO;
611616
}
612617

613-
get_task_struct(thread);
614-
wake_up_process(thread);
615-
616618
vdev->job_done_thread = thread;
617619

618620
return 0;
619621
}
620622

621623
void ivpu_job_done_thread_fini(struct ivpu_device *vdev)
622624
{
625+
kthread_unpark(vdev->job_done_thread);
623626
kthread_stop(vdev->job_done_thread);
624-
put_task_struct(vdev->job_done_thread);
627+
}
628+
629+
void ivpu_job_done_thread_disable(struct ivpu_device *vdev)
630+
{
631+
kthread_park(vdev->job_done_thread);
632+
}
633+
634+
void ivpu_job_done_thread_enable(struct ivpu_device *vdev)
635+
{
636+
kthread_unpark(vdev->job_done_thread);
625637
}

drivers/accel/ivpu/ivpu_job.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ void ivpu_cmdq_reset_all_contexts(struct ivpu_device *vdev);
6161

6262
int ivpu_job_done_thread_init(struct ivpu_device *vdev);
6363
void ivpu_job_done_thread_fini(struct ivpu_device *vdev);
64+
void ivpu_job_done_thread_disable(struct ivpu_device *vdev);
65+
void ivpu_job_done_thread_enable(struct ivpu_device *vdev);
6466

6567
void ivpu_jobs_abort_all(struct ivpu_device *vdev);
6668

0 commit comments

Comments
 (0)