scsiback: don't let in-flight requests defer pending ones Running RING_FINAL_CHECK_FOR_REQUESTS from make_response is a bad idea. It means that in-flight I/O is essentially blocking continued batches. This essentially kills throughput on frontends which unplug (or even just notify) early and rightfully assume additional requests will be picked up on time, not synchronously. Derived from a similar blkback patch by Daniel Stodden (see c/s 1118:c7c14595c18b). Signed-off-by: Jan Beulich --- a/drivers/xen/scsiback/scsiback.c +++ b/drivers/xen/scsiback/scsiback.c @@ -149,7 +149,6 @@ void scsiback_do_resp_with_sense(char *s vscsiif_response_t *ring_res; struct vscsibk_info *info = pending_req->info; int notify; - int more_to_do = 1; struct scsi_sense_hdr sshdr; unsigned long flags; @@ -182,17 +181,8 @@ void scsiback_do_resp_with_sense(char *s ring_res->residual_len = resid; RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&info->ring, notify); - if (info->ring.rsp_prod_pvt == info->ring.req_cons) { - RING_FINAL_CHECK_FOR_REQUESTS(&info->ring, more_to_do); - } else if (RING_HAS_UNCONSUMED_REQUESTS(&info->ring)) { - more_to_do = 1; - } - spin_unlock_irqrestore(&info->ring_lock, flags); - if (more_to_do) - scsiback_notify_work(info); - if (notify) notify_remote_via_irq(info->irq); @@ -586,7 +576,7 @@ invalid_value: } -static int scsiback_do_cmd_fn(struct vscsibk_info *info) +static int _scsiback_do_cmd_fn(struct vscsibk_info *info) { struct vscsiif_back_ring *ring = &info->ring; vscsiif_request_t *ring_req; @@ -652,6 +642,21 @@ static int scsiback_do_cmd_fn(struct vsc return more_to_do; } +static int scsiback_do_cmd_fn(struct vscsibk_info *info) +{ + int more_to_do; + + do { + more_to_do = _scsiback_do_cmd_fn(info); + if (more_to_do) + break; + + RING_FINAL_CHECK_FOR_REQUESTS(&info->ring, more_to_do); + } while (more_to_do); + + return more_to_do; +} + int scsiback_schedule(void *data) {