static struct fiops_ioc *fiops_select_ioc(struct fiops_data *fiopsd) { struct fiops_ioc *ioc; struct fiops_rb_root *service_tree = NULL; int i; struct request *rq; for (i = RT_WORKLOAD; i >= IDLE_WORKLOAD; i--) { if (!RB_EMPTY_ROOT(&fiopsd->service_tree[i].rb)) { service_tree = &fiopsd->service_tree[i]; break; } } if (!service_tree) return NULL; ioc = fiops_rb_first(service_tree); rq = rq_entry_fifo(ioc->fifo.next); /* * we are the only async task and sync requests are in flight, delay a * moment. If there are other tasks coming, sync tasks have no chance * to be starved, don't delay */ if (!rq_is_sync(rq) && fiopsd->in_flight[1] != 0 && service_tree->count == 1) { fiops_log_ioc(fiopsd, ioc, "postpone async, in_flight async %d sync %d", fiopsd->in_flight[0], fiopsd->in_flight[1]); return NULL; } return ioc; }
static void fiops_update_min_vios(struct fiops_rb_root *service_tree) { struct fiops_ioc *ioc; ioc = fiops_rb_first(service_tree); if (!ioc) return; service_tree->min_vios = max_vios(service_tree->min_vios, ioc->vios); }
static int fiops_forced_dispatch(struct fiops_data *fiopsd) { struct fiops_ioc *ioc; int dispatched = 0; int i; for (i = RT_WORKLOAD; i >= IDLE_WORKLOAD; i--) { while (!RB_EMPTY_ROOT(&fiopsd->service_tree[i].rb)) { ioc = fiops_rb_first(&fiopsd->service_tree[i]); while (!list_empty(&ioc->fifo)) { fiops_dispatch_request(fiopsd, ioc); dispatched++; } if (fiops_ioc_on_rr(ioc)) fiops_del_ioc_rr(fiopsd, ioc); } } return dispatched; }