diff options
author | Steven Luong <sluong@cisco.com> | 2019-10-02 07:33:48 -0700 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2019-10-07 09:56:50 +0000 |
commit | 61b8ba69f7a9540ed00576504528ce439f0286f5 (patch) | |
tree | 233bfc21956bb8620250f2ddea0a7bd0cee01052 | |
parent | 0471cdbd3fe04a88a8b70b5f0eff0c378e19abf7 (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
-rw-r--r-- | src/vnet/devices/virtio/vhost_user.c | 22 | ||||
-rw-r--r-- | src/vnet/devices/virtio/vhost_user.h | 3 |
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 a18313b2038..c61828eb6c0 100644 --- a/src/vnet/devices/virtio/vhost_user.c +++ b/src/vnet/devices/virtio/vhost_user.c @@ -557,6 +557,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; @@ -600,6 +618,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 7dadfed2334..7ebea9336af 100644 --- a/src/vnet/devices/virtio/vhost_user.h +++ b/src/vnet/devices/virtio/vhost_user.h @@ -237,6 +237,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; |