mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-25 18:12:57 +01:00
hyperv/vmbus: Add supportive transaction wait function.
This function supports channel revocation properly. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8611
This commit is contained in:
parent
faaba341e5
commit
a54152eaa5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=309225
@ -116,6 +116,7 @@ struct vmbus_chan_br {
|
||||
};
|
||||
|
||||
struct vmbus_channel;
|
||||
struct vmbus_xact;
|
||||
struct vmbus_xact_ctx;
|
||||
struct hyperv_guid;
|
||||
struct task;
|
||||
@ -173,6 +174,8 @@ void vmbus_chan_run_task(struct vmbus_channel *chan,
|
||||
void vmbus_chan_set_orphan(struct vmbus_channel *chan,
|
||||
struct vmbus_xact_ctx *);
|
||||
void vmbus_chan_unset_orphan(struct vmbus_channel *chan);
|
||||
const void *vmbus_chan_xact_wait(const struct vmbus_channel *chan,
|
||||
struct vmbus_xact *xact, size_t *resp_len, bool can_sleep);
|
||||
|
||||
int vmbus_chan_gpadl_connect(struct vmbus_channel *chan,
|
||||
bus_addr_t paddr, int size, uint32_t *gpadl);
|
||||
|
@ -1927,3 +1927,37 @@ vmbus_chan_unset_orphan(struct vmbus_channel *chan)
|
||||
chan->ch_orphan_xact = NULL;
|
||||
sx_xunlock(&chan->ch_orphan_lock);
|
||||
}
|
||||
|
||||
const void *
|
||||
vmbus_chan_xact_wait(const struct vmbus_channel *chan,
|
||||
struct vmbus_xact *xact, size_t *resp_len, bool can_sleep)
|
||||
{
|
||||
const void *ret;
|
||||
|
||||
if (can_sleep)
|
||||
ret = vmbus_xact_wait(xact, resp_len);
|
||||
else
|
||||
ret = vmbus_xact_busywait(xact, resp_len);
|
||||
if (vmbus_chan_is_revoked(chan)) {
|
||||
/*
|
||||
* This xact probably is interrupted, and the
|
||||
* interruption can race the reply reception,
|
||||
* so we have to make sure that there are nothing
|
||||
* left on the RX bufring, i.e. this xact will
|
||||
* not be touched, once this function returns.
|
||||
*
|
||||
* Since the hypervisor will not put more data
|
||||
* onto the RX bufring once the channel is revoked,
|
||||
* the following loop will be terminated, once all
|
||||
* data are drained by the driver's channel
|
||||
* callback.
|
||||
*/
|
||||
while (!vmbus_chan_rx_empty(chan)) {
|
||||
if (can_sleep)
|
||||
pause("chxact", 1);
|
||||
else
|
||||
DELAY(1000);
|
||||
}
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user