On 23 Dec 2022 15:51:52 +0900 Daisuke Matsuda <matsuda-dais...@fujitsu.com>
> @@ -137,15 +153,27 @@ void rxe_sched_task(struct rxe_task *task)
>       if (task->destroyed)
>               return;
>  
> -     tasklet_schedule(&task->tasklet);
> +     /*
> +      * busy-loop while qp reset is in progress.
> +      * This may be called from softirq context and thus cannot sleep.
> +      */
> +     while (atomic_read(&task->suspended))
> +             cpu_relax();
> +
> +     queue_work(task->workq, &task->work);
>  }

This busy wait particularly in softirq barely makes sense given the
flush_workqueue() below.
>  
>  void rxe_disable_task(struct rxe_task *task)
>  {
> -     tasklet_disable(&task->tasklet);
> +     /* Alternative to tasklet_disable() */
> +     atomic_inc(&task->suspended);
> +     smp_mb__after_atomic();
> +     flush_workqueue(task->workq);
>  }
>  
>  void rxe_enable_task(struct rxe_task *task)
>  {
> -     tasklet_enable(&task->tasklet);
> +     /* Alternative to tasklet_enable() */
> +     smp_mb__before_atomic();
> +     atomic_dec(&task->suspended);
>  }

Feel free to add one-line comment for why smp_mb is needed in both
cases.

Reply via email to