diff options
| author | Sepherosa Ziehau <sephe@FreeBSD.org> | 2016-11-25 06:12:18 +0000 |
|---|---|---|
| committer | Sepherosa Ziehau <sephe@FreeBSD.org> | 2016-11-25 06:12:18 +0000 |
| commit | fd2b520f2fd84d8d6f1953877a95d4965b2102e2 (patch) | |
| tree | 4c544e0e3889206f02472ff5ed58f457086629b1 /sys/dev/hyperv/vmbus | |
| parent | ba9238f89fdde615ca46c13953b430756e673091 (diff) | |
Notes
Diffstat (limited to 'sys/dev/hyperv/vmbus')
| -rw-r--r-- | sys/dev/hyperv/vmbus/vmbus_chan.c | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/sys/dev/hyperv/vmbus/vmbus_chan.c b/sys/dev/hyperv/vmbus/vmbus_chan.c index b749fe1f63274..e1dac88c3c322 100644 --- a/sys/dev/hyperv/vmbus/vmbus_chan.c +++ b/sys/dev/hyperv/vmbus/vmbus_chan.c @@ -688,10 +688,28 @@ vmbus_chan_close_internal(struct vmbus_channel *chan) struct vmbus_softc *sc = chan->ch_vmbus; struct vmbus_msghc *mh; struct vmbus_chanmsg_chclose *req; + uint32_t old_stflags; int error; - /* TODO: stringent check */ - atomic_clear_int(&chan->ch_stflags, VMBUS_CHAN_ST_OPENED); + /* + * NOTE: + * Sub-channels are closed upon their primary channel closing, + * so they can be closed even before they are opened. + */ + for (;;) { + old_stflags = chan->ch_stflags; + if (atomic_cmpset_int(&chan->ch_stflags, old_stflags, + old_stflags & ~VMBUS_CHAN_ST_OPENED)) + break; + } + if ((old_stflags & VMBUS_CHAN_ST_OPENED) == 0) { + /* Not opened yet; done */ + if (bootverbose) { + vmbus_chan_printf(chan, "chan%u not opened\n", + chan->ch_id); + } + return; + } /* * Free this channel's sysctl tree attached to its device's |
