|
@@ -39,7 +39,7 @@
|
|
|
* vmbus_setevent- Trigger an event notification on the specified
|
|
|
* channel.
|
|
|
*/
|
|
|
-static void vmbus_setevent(struct vmbus_channel *channel)
|
|
|
+void vmbus_setevent(struct vmbus_channel *channel)
|
|
|
{
|
|
|
struct hv_monitor_page *monitorpage;
|
|
|
|
|
@@ -65,6 +65,7 @@ static void vmbus_setevent(struct vmbus_channel *channel)
|
|
|
vmbus_set_event(channel);
|
|
|
}
|
|
|
}
|
|
|
+EXPORT_SYMBOL_GPL(vmbus_setevent);
|
|
|
|
|
|
/*
|
|
|
* vmbus_open - Open the specified channel.
|
|
@@ -635,8 +636,6 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer,
|
|
|
u32 packetlen_aligned = ALIGN(packetlen, sizeof(u64));
|
|
|
struct kvec bufferlist[3];
|
|
|
u64 aligned_data = 0;
|
|
|
- int ret;
|
|
|
- bool signal = false;
|
|
|
bool lock = channel->acquire_ring_lock;
|
|
|
int num_vecs = ((bufferlen != 0) ? 3 : 1);
|
|
|
|
|
@@ -656,41 +655,9 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer,
|
|
|
bufferlist[2].iov_base = &aligned_data;
|
|
|
bufferlist[2].iov_len = (packetlen_aligned - packetlen);
|
|
|
|
|
|
- ret = hv_ringbuffer_write(&channel->outbound, bufferlist, num_vecs,
|
|
|
- &signal, lock, channel->signal_policy);
|
|
|
-
|
|
|
- /*
|
|
|
- * Signalling the host is conditional on many factors:
|
|
|
- * 1. The ring state changed from being empty to non-empty.
|
|
|
- * This is tracked by the variable "signal".
|
|
|
- * 2. The variable kick_q tracks if more data will be placed
|
|
|
- * on the ring. We will not signal if more data is
|
|
|
- * to be placed.
|
|
|
- *
|
|
|
- * Based on the channel signal state, we will decide
|
|
|
- * which signaling policy will be applied.
|
|
|
- *
|
|
|
- * If we cannot write to the ring-buffer; signal the host
|
|
|
- * even if we may not have written anything. This is a rare
|
|
|
- * enough condition that it should not matter.
|
|
|
- * NOTE: in this case, the hvsock channel is an exception, because
|
|
|
- * it looks the host side's hvsock implementation has a throttling
|
|
|
- * mechanism which can hurt the performance otherwise.
|
|
|
- *
|
|
|
- * KYS: Oct. 30, 2016:
|
|
|
- * It looks like Windows hosts have logic to deal with DOS attacks that
|
|
|
- * can be triggered if it receives interrupts when it is not expecting
|
|
|
- * the interrupt. The host expects interrupts only when the ring
|
|
|
- * transitions from empty to non-empty (or full to non full on the guest
|
|
|
- * to host ring).
|
|
|
- * So, base the signaling decision solely on the ring state until the
|
|
|
- * host logic is fixed.
|
|
|
- */
|
|
|
-
|
|
|
- if (((ret == 0) && signal))
|
|
|
- vmbus_setevent(channel);
|
|
|
+ return hv_ringbuffer_write(channel, bufferlist, num_vecs,
|
|
|
+ lock, kick_q);
|
|
|
|
|
|
- return ret;
|
|
|
}
|
|
|
EXPORT_SYMBOL(vmbus_sendpacket_ctl);
|
|
|
|
|
@@ -731,7 +698,6 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
|
|
|
u32 flags,
|
|
|
bool kick_q)
|
|
|
{
|
|
|
- int ret;
|
|
|
int i;
|
|
|
struct vmbus_channel_packet_page_buffer desc;
|
|
|
u32 descsize;
|
|
@@ -739,7 +705,6 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
|
|
|
u32 packetlen_aligned;
|
|
|
struct kvec bufferlist[3];
|
|
|
u64 aligned_data = 0;
|
|
|
- bool signal = false;
|
|
|
bool lock = channel->acquire_ring_lock;
|
|
|
|
|
|
if (pagecount > MAX_PAGE_BUFFER_COUNT)
|
|
@@ -777,38 +742,8 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
|
|
|
bufferlist[2].iov_base = &aligned_data;
|
|
|
bufferlist[2].iov_len = (packetlen_aligned - packetlen);
|
|
|
|
|
|
- ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3,
|
|
|
- &signal, lock, channel->signal_policy);
|
|
|
-
|
|
|
- /*
|
|
|
- * Signalling the host is conditional on many factors:
|
|
|
- * 1. The ring state changed from being empty to non-empty.
|
|
|
- * This is tracked by the variable "signal".
|
|
|
- * 2. The variable kick_q tracks if more data will be placed
|
|
|
- * on the ring. We will not signal if more data is
|
|
|
- * to be placed.
|
|
|
- *
|
|
|
- * Based on the channel signal state, we will decide
|
|
|
- * which signaling policy will be applied.
|
|
|
- *
|
|
|
- * If we cannot write to the ring-buffer; signal the host
|
|
|
- * even if we may not have written anything. This is a rare
|
|
|
- * enough condition that it should not matter.
|
|
|
- *
|
|
|
- * KYS: Oct. 30, 2016:
|
|
|
- * It looks like Windows hosts have logic to deal with DOS attacks that
|
|
|
- * can be triggered if it receives interrupts when it is not expecting
|
|
|
- * the interrupt. The host expects interrupts only when the ring
|
|
|
- * transitions from empty to non-empty (or full to non full on the guest
|
|
|
- * to host ring).
|
|
|
- * So, base the signaling decision solely on the ring state until the
|
|
|
- * host logic is fixed.
|
|
|
- */
|
|
|
-
|
|
|
- if (((ret == 0) && signal))
|
|
|
- vmbus_setevent(channel);
|
|
|
-
|
|
|
- return ret;
|
|
|
+ return hv_ringbuffer_write(channel, bufferlist, 3,
|
|
|
+ lock, kick_q);
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(vmbus_sendpacket_pagebuffer_ctl);
|
|
|
|
|
@@ -839,12 +774,10 @@ int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel,
|
|
|
u32 desc_size,
|
|
|
void *buffer, u32 bufferlen, u64 requestid)
|
|
|
{
|
|
|
- int ret;
|
|
|
u32 packetlen;
|
|
|
u32 packetlen_aligned;
|
|
|
struct kvec bufferlist[3];
|
|
|
u64 aligned_data = 0;
|
|
|
- bool signal = false;
|
|
|
bool lock = channel->acquire_ring_lock;
|
|
|
|
|
|
packetlen = desc_size + bufferlen;
|
|
@@ -865,13 +798,8 @@ int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel,
|
|
|
bufferlist[2].iov_base = &aligned_data;
|
|
|
bufferlist[2].iov_len = (packetlen_aligned - packetlen);
|
|
|
|
|
|
- ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3,
|
|
|
- &signal, lock, channel->signal_policy);
|
|
|
-
|
|
|
- if (ret == 0 && signal)
|
|
|
- vmbus_setevent(channel);
|
|
|
-
|
|
|
- return ret;
|
|
|
+ return hv_ringbuffer_write(channel, bufferlist, 3,
|
|
|
+ lock, true);
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(vmbus_sendpacket_mpb_desc);
|
|
|
|
|
@@ -883,14 +811,12 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel,
|
|
|
struct hv_multipage_buffer *multi_pagebuffer,
|
|
|
void *buffer, u32 bufferlen, u64 requestid)
|
|
|
{
|
|
|
- int ret;
|
|
|
struct vmbus_channel_packet_multipage_buffer desc;
|
|
|
u32 descsize;
|
|
|
u32 packetlen;
|
|
|
u32 packetlen_aligned;
|
|
|
struct kvec bufferlist[3];
|
|
|
u64 aligned_data = 0;
|
|
|
- bool signal = false;
|
|
|
bool lock = channel->acquire_ring_lock;
|
|
|
u32 pfncount = NUM_PAGES_SPANNED(multi_pagebuffer->offset,
|
|
|
multi_pagebuffer->len);
|
|
@@ -930,13 +856,8 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel,
|
|
|
bufferlist[2].iov_base = &aligned_data;
|
|
|
bufferlist[2].iov_len = (packetlen_aligned - packetlen);
|
|
|
|
|
|
- ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3,
|
|
|
- &signal, lock, channel->signal_policy);
|
|
|
-
|
|
|
- if (ret == 0 && signal)
|
|
|
- vmbus_setevent(channel);
|
|
|
-
|
|
|
- return ret;
|
|
|
+ return hv_ringbuffer_write(channel, bufferlist, 3,
|
|
|
+ lock, true);
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(vmbus_sendpacket_multipagebuffer);
|
|
|
|