]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/vhost/scsi.c
Merge tag 'icc-5.4-rc5' of https://git.linaro.org/people/georgi.djakov/linux into...
[linux.git] / drivers / vhost / scsi.c
index 618fb646101768ebfb5ddd71166d6420d42e3caa..a9caf1bc3c3ef29542530f379d8cc13bd273f30f 100644 (file)
 #define VHOST_SCSI_PREALLOC_UPAGES 2048
 #define VHOST_SCSI_PREALLOC_PROT_SGLS 2048
 
+/* Max number of requests before requeueing the job.
+ * Using this limit prevents one virtqueue from starving others with
+ * request.
+ */
+#define VHOST_SCSI_WEIGHT 256
+
 struct vhost_scsi_inflight {
        /* Wait for the flush operation to finish */
        struct completion comp;
@@ -912,7 +918,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
        struct iov_iter in_iter, prot_iter, data_iter;
        u64 tag;
        u32 exp_data_len, data_direction;
-       int ret, prot_bytes;
+       int ret, prot_bytes, c = 0;
        u16 lun;
        u8 task_attr;
        bool t10_pi = vhost_has_feature(vq, VIRTIO_SCSI_F_T10_PI);
@@ -932,7 +938,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
 
        vhost_disable_notify(&vs->dev, vq);
 
-       for (;;) {
+       do {
                ret = vhost_scsi_get_desc(vs, vq, &vc);
                if (ret)
                        goto err;
@@ -1112,7 +1118,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
                        break;
                else if (ret == -EIO)
                        vhost_scsi_send_bad_target(vs, vq, vc.head, vc.out);
-       }
+       } while (likely(!vhost_exceeds_weight(vq, ++c, 0)));
 out:
        mutex_unlock(&vq->mutex);
 }
@@ -1171,7 +1177,7 @@ vhost_scsi_ctl_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
        } v_req;
        struct vhost_scsi_ctx vc;
        size_t typ_size;
-       int ret;
+       int ret, c = 0;
 
        mutex_lock(&vq->mutex);
        /*
@@ -1185,7 +1191,7 @@ vhost_scsi_ctl_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
 
        vhost_disable_notify(&vs->dev, vq);
 
-       for (;;) {
+       do {
                ret = vhost_scsi_get_desc(vs, vq, &vc);
                if (ret)
                        goto err;
@@ -1264,7 +1270,7 @@ vhost_scsi_ctl_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
                        break;
                else if (ret == -EIO)
                        vhost_scsi_send_bad_target(vs, vq, vc.head, vc.out);
-       }
+       } while (likely(!vhost_exceeds_weight(vq, ++c, 0)));
 out:
        mutex_unlock(&vq->mutex);
 }
@@ -1443,7 +1449,6 @@ vhost_scsi_set_endpoint(struct vhost_scsi *vs,
                        tpg->tv_tpg_vhost_count++;
                        tpg->vhost_scsi = vs;
                        vs_tpg[tpg->tport_tpgt] = tpg;
-                       smp_mb__after_atomic();
                        match = true;
                }
                mutex_unlock(&tpg->tv_tpg_mutex);
@@ -1622,7 +1627,8 @@ static int vhost_scsi_open(struct inode *inode, struct file *f)
                vqs[i] = &vs->vqs[i].vq;
                vs->vqs[i].vq.handle_kick = vhost_scsi_handle_kick;
        }
-       vhost_dev_init(&vs->dev, vqs, VHOST_SCSI_MAX_VQ, UIO_MAXIOV);
+       vhost_dev_init(&vs->dev, vqs, VHOST_SCSI_MAX_VQ, UIO_MAXIOV,
+                      VHOST_SCSI_WEIGHT, 0);
 
        vhost_scsi_init_inflight(vs, NULL);