task->arg       = arg;
        task->func      = func;
        snprintf(task->name, sizeof(task->name), "%s", name);
+       task->destroyed = false;
 
        tasklet_init(&task->tasklet, rxe_do_task, (unsigned long)task);
 
 
 void rxe_cleanup_task(struct rxe_task *task)
 {
+       unsigned long flags;
+       bool idle;
+
+       /*
+        * Mark the task, then wait for it to finish. It might be
+        * running in a non-tasklet (direct call) context.
+        */
+       task->destroyed = true;
+
+       do {
+               spin_lock_irqsave(&task->state_lock, flags);
+               idle = (task->state == TASK_STATE_START);
+               spin_unlock_irqrestore(&task->state_lock, flags);
+       } while (!idle);
+
        tasklet_kill(&task->tasklet);
 }
 
 void rxe_run_task(struct rxe_task *task, int sched)
 {
+       if (task->destroyed)
+               return;
+
        if (sched)
                tasklet_schedule(&task->tasklet);
        else