| b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | From a16c129c9dfae01921faaed98587d318459d5cfc Mon Sep 17 00:00:00 2001 |
| 2 | From: Zhao Qiang <qiang.zhao@nxp.com> |
| 3 | Date: Wed, 30 May 2018 17:09:02 +0800 |
| 4 | Subject: [PATCH] sdk/qbman: fix issue in qman_delete_cgr_safe() |
| 5 | |
| 6 | The wait_for_completion() call in qman_delete_cgr_safe() |
| 7 | was triggering a scheduling while atomic bug, replacing the |
| 8 | kthread with a smp_call_function_single() call to fix it. |
| 9 | |
| 10 | Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com> |
| 11 | Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com> |
| 12 | --- |
| 13 | drivers/staging/fsl_qbman/qman_high.c | 29 ++++++----------------------- |
| 14 | 1 file changed, 6 insertions(+), 23 deletions(-) |
| 15 | |
| 16 | --- a/drivers/staging/fsl_qbman/qman_high.c |
| 17 | +++ b/drivers/staging/fsl_qbman/qman_high.c |
| 18 | @@ -3075,36 +3075,19 @@ struct cgr_comp { |
| 19 | struct completion completion; |
| 20 | }; |
| 21 | |
| 22 | -static int qman_delete_cgr_thread(void *p) |
| 23 | +static void qman_delete_cgr_smp_call(void *p) |
| 24 | { |
| 25 | - struct cgr_comp *cgr_comp = (struct cgr_comp *)p; |
| 26 | - int res; |
| 27 | - |
| 28 | - res = qman_delete_cgr((struct qman_cgr *)cgr_comp->cgr); |
| 29 | - complete(&cgr_comp->completion); |
| 30 | - |
| 31 | - return res; |
| 32 | + qman_delete_cgr((struct qman_cgr *)p); |
| 33 | } |
| 34 | |
| 35 | void qman_delete_cgr_safe(struct qman_cgr *cgr) |
| 36 | { |
| 37 | - struct task_struct *thread; |
| 38 | - struct cgr_comp cgr_comp; |
| 39 | - |
| 40 | preempt_disable(); |
| 41 | if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id()) { |
| 42 | - init_completion(&cgr_comp.completion); |
| 43 | - cgr_comp.cgr = cgr; |
| 44 | - thread = kthread_create(qman_delete_cgr_thread, &cgr_comp, |
| 45 | - "cgr_del"); |
| 46 | - |
| 47 | - if (likely(!IS_ERR(thread))) { |
| 48 | - kthread_bind(thread, qman_cgr_cpus[cgr->cgrid]); |
| 49 | - wake_up_process(thread); |
| 50 | - wait_for_completion(&cgr_comp.completion); |
| 51 | - preempt_enable(); |
| 52 | - return; |
| 53 | - } |
| 54 | + smp_call_function_single(qman_cgr_cpus[cgr->cgrid], |
| 55 | + qman_delete_cgr_smp_call, cgr, true); |
| 56 | + preempt_enable(); |
| 57 | + return; |
| 58 | } |
| 59 | qman_delete_cgr(cgr); |
| 60 | preempt_enable(); |