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.