summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Luong <sluong@cisco.com>2019-10-02 07:33:48 -0700
committerAndrew Yourtchenko <ayourtch@gmail.com>2019-10-14 11:12:37 +0000
commitd294b98c1d157c7f6db75759c9f7e4ef4de7233d (patch)
treed3c0bbae40d65453966db4f17e45225ae7d4fa93
parentd557b187f75b4c754b2bbd0f79ae52aabaab1448 (diff)
devices: vhost not reading packets from vring
In a rare event, after the vhost protocol message exchange has finished and the interface had been brought up successfully, the driver MAY still change its mind about the memory regions by sending new memory maps via SET_MEM_TABLE. Upon processing SET_MEM_TABLE, VPP invalidates the old memory regions and the descriptor tables. But it does not re-compute the new descriptor tables based on the new memory maps. Since VPP does not have the descriptor tables, it does not read the packets from the vring. In the normal working case, after SET_MEM_TABLE, the driver follows up with SET_VRING_ADDRESS which VPP computes the descriptor tables. The fix is to stash away the descriptor table addresses from SET_VRING_ADDRESS. Re-compute the new descriptor tables when processing SET_MEM_TABLE if descriptor table addresses are known. Type: fix Ticket: VPP-1784 Signed-off-by: Steven Luong <sluong@cisco.com> Change-Id: I3361f14c3a0372b8d07943eb6aa4b3a3f10708f9 (cherry picked from commit 61b8ba69f7a9540ed00576504528ce439f0286f5)
-rw-r--r--src/vnet/devices/virtio/vhost_user.c22
-rw-r--r--src/vnet/devices/virtio/vhost_user.h3
2 files changed, 25 insertions, 0 deletions
diff --git a/src/vnet/devices/virtio/vhost_user.c b/src/vnet/devices/virtio/vhost_user.c
index c06f78ce1bb..7094a00fb33 100644
--- a/src/vnet/devices/virtio/vhost_user.c
+++ b/src/vnet/devices/virtio/vhost_user.c
@@ -571,6 +571,24 @@ vhost_user_socket_read (clib_file_t * uf)
vui->nregions++;
}
+
+ /*
+ * Re-compute desc, used, and avail descriptor table if vring address
+ * is set.
+ */
+ for (q = 0; q < VHOST_VRING_MAX_N; q++)
+ {
+ if (vui->vrings[q].desc_user_addr &&
+ vui->vrings[q].used_user_addr && vui->vrings[q].avail_user_addr)
+ {
+ vui->vrings[q].desc =
+ map_user_mem (vui, vui->vrings[q].desc_user_addr);
+ vui->vrings[q].used =
+ map_user_mem (vui, vui->vrings[q].used_user_addr);
+ vui->vrings[q].avail =
+ map_user_mem (vui, vui->vrings[q].avail_user_addr);
+ }
+ }
vlib_worker_thread_barrier_release (vm);
break;
@@ -614,6 +632,10 @@ vhost_user_socket_read (clib_file_t * uf)
goto close_socket;
}
+ vui->vrings[msg.state.index].desc_user_addr = msg.addr.desc_user_addr;
+ vui->vrings[msg.state.index].used_user_addr = msg.addr.used_user_addr;
+ vui->vrings[msg.state.index].avail_user_addr = msg.addr.avail_user_addr;
+
vlib_worker_thread_barrier_sync (vm);
vui->vrings[msg.state.index].desc = desc;
vui->vrings[msg.state.index].used = used;
diff --git a/src/vnet/devices/virtio/vhost_user.h b/src/vnet/devices/virtio/vhost_user.h
index c7a4206fa1d..90669a7dfbe 100644
--- a/src/vnet/devices/virtio/vhost_user.h
+++ b/src/vnet/devices/virtio/vhost_user.h
@@ -263,6 +263,9 @@ typedef struct
vring_desc_t *desc;
vring_avail_t *avail;
vring_used_t *used;
+ uword desc_user_addr;
+ uword used_user_addr;
+ uword avail_user_addr;
f64 int_deadline;
u8 started;
u8 enabled;