aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Wang <jasowang@redhat.com>2017-02-07 02:49:50 -0500
committerMichael S. Tsirkin <mst@redhat.com>2017-02-27 13:37:27 -0500
commite3b56cdd4351f0e227d4d847eeadff4c82aef1b9 (patch)
tree45d602addb89b2cd3cf1617ecb85275dad7d3f9e
parent51be7a9a261ce18c520fb3928b168feb77522745 (diff)
vhost: try avoiding avail index access when getting descriptor
If last avail idx is not equal to cached avail idx, we're sure there's still available buffers in the virtqueue so there's no need to re-read avail idx. So let's skip this to avoid unnecessary userspace memory access and memory barrier. Pktgen test show about 3% improvement on rx pps. Signed-off-by: Jason Wang <jasowang@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-rw-r--r--drivers/vhost/vhost.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 8f99fe08de02..1f7e4e4e6f8e 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -1930,25 +1930,32 @@ int vhost_get_vq_desc(struct vhost_virtqueue *vq,
1930 1930
1931 /* Check it isn't doing very strange things with descriptor numbers. */ 1931 /* Check it isn't doing very strange things with descriptor numbers. */
1932 last_avail_idx = vq->last_avail_idx; 1932 last_avail_idx = vq->last_avail_idx;
1933 if (unlikely(vhost_get_user(vq, avail_idx, &vq->avail->idx))) {
1934 vq_err(vq, "Failed to access avail idx at %p\n",
1935 &vq->avail->idx);
1936 return -EFAULT;
1937 }
1938 vq->avail_idx = vhost16_to_cpu(vq, avail_idx);
1939 1933
1940 if (unlikely((u16)(vq->avail_idx - last_avail_idx) > vq->num)) { 1934 if (vq->avail_idx == vq->last_avail_idx) {
1941 vq_err(vq, "Guest moved used index from %u to %u", 1935 if (unlikely(vhost_get_user(vq, avail_idx, &vq->avail->idx))) {
1942 last_avail_idx, vq->avail_idx); 1936 vq_err(vq, "Failed to access avail idx at %p\n",
1943 return -EFAULT; 1937 &vq->avail->idx);
1944 } 1938 return -EFAULT;
1939 }
1940 vq->avail_idx = vhost16_to_cpu(vq, avail_idx);
1945 1941
1946 /* If there's nothing new since last we looked, return invalid. */ 1942 if (unlikely((u16)(vq->avail_idx - last_avail_idx) > vq->num)) {
1947 if (vq->avail_idx == last_avail_idx) 1943 vq_err(vq, "Guest moved used index from %u to %u",
1948 return vq->num; 1944 last_avail_idx, vq->avail_idx);
1945 return -EFAULT;
1946 }
1947
1948 /* If there's nothing new since last we looked, return
1949 * invalid.
1950 */
1951 if (vq->avail_idx == last_avail_idx)
1952 return vq->num;
1949 1953
1950 /* Only get avail ring entries after they have been exposed by guest. */ 1954 /* Only get avail ring entries after they have been
1951 smp_rmb(); 1955 * exposed by guest.
1956 */
1957 smp_rmb();
1958 }
1952 1959
1953 /* Grab the next descriptor number they're advertising, and increment 1960 /* Grab the next descriptor number they're advertising, and increment
1954 * the index we've seen. */ 1961 * the index we've seen. */