static int mmc_queue_thread(void *d) { struct mmc_queue *mq = d; struct request_queue *q = mq->queue; struct mmc_context_info *cntx = &mq->card->host->context_info; current->flags |= PF_MEMALLOC; down(&mq->thread_sem); do { struct request *req; spin_lock_irq(q->queue_lock); set_current_state(TASK_INTERRUPTIBLE); req = blk_fetch_request(q); mq->asleep = false; cntx->is_waiting_last_req = false; cntx->is_new_req = false; if (!req) { /* * Dispatch queue is empty so set flags for * mmc_request_fn() to wake us up. */ if (mq->qcnt) cntx->is_waiting_last_req = true; else mq->asleep = true; } spin_unlock_irq(q->queue_lock); if (req || mq->qcnt) { set_current_state(TASK_RUNNING); mmc_blk_issue_rq(mq, req); cond_resched(); } else { if (kthread_should_stop()) { set_current_state(TASK_RUNNING); break; } up(&mq->thread_sem); schedule(); down(&mq->thread_sem); } } while (1); up(&mq->thread_sem); return 0; }
static int mmc_queue_thread(void *d) { struct mmc_queue *mq = d; struct request_queue *q = mq->queue; struct mmc_context_info *cntx = &mq->card->host->context_info; current->flags |= PF_MEMALLOC; down(&mq->thread_sem); do { struct request *req = NULL; spin_lock_irq(q->queue_lock); set_current_state(TASK_INTERRUPTIBLE); req = blk_fetch_request(q); mq->asleep = false; cntx->is_waiting_last_req = false; cntx->is_new_req = false; if (!req) { /* * Dispatch queue is empty so set flags for * mmc_request_fn() to wake us up. */ if (mq->mqrq_prev->req) cntx->is_waiting_last_req = true; else mq->asleep = true; } mq->mqrq_cur->req = req; spin_unlock_irq(q->queue_lock); if (req || mq->mqrq_prev->req) { bool req_is_special = mmc_req_is_special(req); set_current_state(TASK_RUNNING); mmc_blk_issue_rq(mq, req); cond_resched(); if (mq->flags & MMC_QUEUE_NEW_REQUEST) { mq->flags &= ~MMC_QUEUE_NEW_REQUEST; continue; /* fetch again */ } /* * Current request becomes previous request * and vice versa. * In case of special requests, current request * has been finished. Do not assign it to previous * request. */ if (req_is_special) mq->mqrq_cur->req = NULL; mq->mqrq_prev->brq.mrq.data = NULL; mq->mqrq_prev->req = NULL; swap(mq->mqrq_prev, mq->mqrq_cur); } else { if (kthread_should_stop()) { set_current_state(TASK_RUNNING); break; } up(&mq->thread_sem); schedule(); down(&mq->thread_sem); } } while (1); up(&mq->thread_sem); return 0; }