/* Check if task is idle i.e. not running, not scheduled in *workqueueandnotdraining.Ifsomovetobusyto *reserveaslotindo_task()bysettingtobusyandtaking *aqpreferencetocoverthegapfromnowuntilthetaskfinishes. *statewillmoveoutofbusyiftaskreturnsanonzerovalue *indo_task().Ifstateisalreadybusyitisraisedtoarmed *toindicatetodo_taskthatadditionalpassshouldbemade *overthetask. *Context:callershouldholdtask->lock. *Returns:trueifstatetransitionedfromidletobusyelsefalse.
*/ staticbool __reserve_if_idle(struct rxe_task *task)
{
WARN_ON(rxe_read(task->qp) <= 0);
if (task->state == TASK_STATE_BUSY)
task->state = TASK_STATE_ARMED;
returnfalse;
}
/* check if task is idle or drained and not currently *scheduledintheworkqueue.Thisroutineis *calledbyrxe_cleanup_taskorrxe_disable_taskto *seeifthequeueisempty. *Context:callershouldholdtask->lock. *Returnstrueifdoneelsefalse.
*/ staticbool __is_done(struct rxe_task *task)
{ if (work_pending(&task->work)) returnfalse;
do {
ret = task->func(task->qp);
} while (ret == 0 && iterations-- > 0);
spin_lock_irqsave(&task->lock, flags); /* we're not done yet but we ran out of iterations. *yieldthecpuandreschedulethetask
*/ if (!ret) { if (task->state != TASK_STATE_DRAINING) {
task->state = TASK_STATE_IDLE;
resched = 1;
} else {
cont = 1;
} gotoexit;
}
switch (task->state) { case TASK_STATE_BUSY:
task->state = TASK_STATE_IDLE; break;
/* someone tried to schedule the task while we *wererunning,keepgoing
*/ case TASK_STATE_ARMED:
task->state = TASK_STATE_BUSY;
cont = 1; break;
case TASK_STATE_DRAINING:
task->state = TASK_STATE_DRAINED; break;
/* rxe_cleanup_task is only called from rxe_do_qp_cleanup in *processcontext.Theqpisalreadycompletedwithno *remainingreferences.Oncethequeueisdrainedthe *taskismovedtoinvalidandreturns.Theqpcleanup *codethencallsthetaskfunctionsdirectlywithout *usingthetaskstructtodrainanylatearrivingpackets *orworkrequests.
*/ void rxe_cleanup_task(struct rxe_task *task)
{ unsignedlong flags;
/* schedule the task to run later as a work queue entry. *thequeue_workcallcanbecalledholding *thelock.
*/ void rxe_sched_task(struct rxe_task *task)
{ unsignedlong flags;
WARN_ON(rxe_read(task->qp) <= 0);
spin_lock_irqsave(&task->lock, flags); if (__reserve_if_idle(task))
queue_work(rxe_wq, &task->work);
spin_unlock_irqrestore(&task->lock, flags);
}
/* rxe_disable/enable_task are only called from *rxe_modify_qpinprocesscontext.Taskismoved *tothedrainedstatebydo_task.
*/ void rxe_disable_task(struct rxe_task *task)
{ unsignedlong flags;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.