Skip to content

Commit

Permalink
OS-8000 viona ring reset can race with Rx packets
Browse files Browse the repository at this point in the history
Reviewed by: Mike Zeller <mike.zeller@joyent.com>
Reviewed by: Patrick Mooney <pmooney@pfmooney.com>
Reviewed by: Dan McDonald <danmcd@joyent.com>
Approved by: Mike Zeller <mike.zeller@joyent.com>
  • Loading branch information
rzezeski committed Oct 1, 2019
1 parent 2ae9c48 commit e4b2011
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 2 deletions.
1 change: 1 addition & 0 deletions usr/src/uts/i86pc/io/viona/viona_impl.h
Expand Up @@ -70,6 +70,7 @@ enum viona_ring_state {
VRS_SETUP = 0x1, /* addrs setup and starting worker thread */
VRS_INIT = 0x2, /* worker thread started & waiting to run */
VRS_RUN = 0x3, /* running work routine */
VRS_STOP = 0x4, /* worker is exiting */
};
enum viona_ring_state_flags {
VRSF_REQ_START = 0x1, /* start running from INIT state */
Expand Down
10 changes: 8 additions & 2 deletions usr/src/uts/i86pc/io/viona/viona_main.c
Expand Up @@ -133,8 +133,14 @@
* +-----------+
* | ^
* |---* ioctl(VNA_IOC_RING_RESET) issued |
* | (or bhyve process begins exit) |
* V |
* | (or bhyve process begins exit) ^
* |
* +-----------+ The worker thread associated with the ring is in the
* | VRS_STOP | process of exiting. All outstanding TX and RX
* +-----------+ requests are allowed to complete, but new requests
* | must be ignored.
* | ^
* | |
* +-------------------------------------------->+
*
*
Expand Down
2 changes: 2 additions & 0 deletions usr/src/uts/i86pc/io/viona/viona_ring.c
Expand Up @@ -389,6 +389,8 @@ viona_worker(void *arg)
panic("unexpected ring: %p", (void *)ring);
}

VERIFY3U(ring->vr_state, ==, VRS_STOP);

cleanup:
if (ring->vr_txdesb != NULL) {
/*
Expand Down
11 changes: 11 additions & 0 deletions usr/src/uts/i86pc/io/viona/viona_rx.c
Expand Up @@ -123,6 +123,17 @@ viona_worker_rx(viona_vring_t *ring, viona_link_t *link)
(void) cv_wait_sig(&ring->vr_cv, &ring->vr_lock);
} while (!VRING_NEED_BAIL(ring, p));

ring->vr_state = VRS_STOP;

/*
* The RX ring is stopping, before we start tearing it down it
* is imperative that we perform an RX barrier so that
* incoming packets are dropped at viona_rx_classified().
*/
mutex_exit(&ring->vr_lock);
mac_rx_barrier(link->l_mch);
mutex_enter(&ring->vr_lock);

*ring->vr_used_flags &= ~VRING_USED_F_NO_NOTIFY;
}

Expand Down
1 change: 1 addition & 0 deletions usr/src/uts/i86pc/io/viona/viona_tx.c
Expand Up @@ -283,6 +283,7 @@ viona_worker_tx(viona_vring_t *ring, viona_link_t *link)

ASSERT(MUTEX_HELD(&ring->vr_lock));

ring->vr_state = VRS_STOP;
viona_tx_wait_outstanding(ring);
}

Expand Down

0 comments on commit e4b2011

Please sign in to comment.