/* * row_dispatch_requests() - selects the next request to dispatch * @q: requests queue * @force: flag indicating if forced dispatch * * Return 0 if no requests were moved to the dispatch queue. * 1 otherwise * */ static int row_dispatch_requests(struct request_queue *q, int force) { struct row_data *rd = (struct row_data *)q->elevator->elevator_data; int ret = 0, currq, ioprio_class_to_serve, start_idx, end_idx; if (force && hrtimer_active(&rd->rd_idle_data.hr_timer)) { if (hrtimer_try_to_cancel(&rd->rd_idle_data.hr_timer) >= 0) { row_log(rd->dispatch_queue, "Canceled delayed work on %d - forced dispatch", rd->rd_idle_data.idling_queue_idx); rd->rd_idle_data.idling_queue_idx = ROWQ_MAX_PRIO; } } if (rd->pending_urgent_rq) { row_log(rd->dispatch_queue, "dispatching urgent request"); row_dispatch_insert(rd, rd->pending_urgent_rq); ret = 1; goto done; } ioprio_class_to_serve = row_get_ioprio_class_to_serve(rd, force); row_log(rd->dispatch_queue, "Dispatching from %d priority class", ioprio_class_to_serve); switch (ioprio_class_to_serve) { case IOPRIO_CLASS_NONE: rd->last_served_ioprio_class = IOPRIO_CLASS_NONE; goto done; case IOPRIO_CLASS_RT: start_idx = ROWQ_HIGH_PRIO_IDX; end_idx = ROWQ_REG_PRIO_IDX; break; case IOPRIO_CLASS_BE: start_idx = ROWQ_REG_PRIO_IDX; end_idx = ROWQ_LOW_PRIO_IDX; break; case IOPRIO_CLASS_IDLE: start_idx = ROWQ_LOW_PRIO_IDX; end_idx = ROWQ_MAX_PRIO; break; default: pr_err("%s(): Invalid I/O priority class", __func__); goto done; } currq = row_get_next_queue(q, rd, start_idx, end_idx); /* Dispatch */ if (currq >= 0) { row_dispatch_insert(rd, rq_entry_fifo(rd->row_queues[currq].fifo.next)); ret = 1; } done: return ret; }
/* * row_choose_queue() - choose the next queue to dispatch from * @rd: pointer to struct row_data * * Updates rd->curr_queue. Returns 1 if there are requests to * dispatch, 0 if there are no requests in scheduler * */ static int row_choose_queue(struct row_data *rd) { int prev_curr_queue = rd->curr_queue; if (!(rd->nr_reqs[0] + rd->nr_reqs[1])) return 0; row_get_next_queue(rd); /* * Loop over all queues to find the next queue that is not empty. * Stop when you get back to curr_queue */ while (list_empty(&rd->row_queues[rd->curr_queue].rqueue.fifo) && rd->curr_queue != prev_curr_queue) { /* Mark rqueue as unserved */ row_mark_rowq_unserved(rd, rd->curr_queue); row_get_next_queue(rd); } return 1; }