diff options
Diffstat (limited to 'drivers/hv/channel.c')
-rw-r--r-- | drivers/hv/channel.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 1161d68a1863..56dd261f7142 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c | |||
@@ -219,6 +219,21 @@ error0: | |||
219 | } | 219 | } |
220 | EXPORT_SYMBOL_GPL(vmbus_open); | 220 | EXPORT_SYMBOL_GPL(vmbus_open); |
221 | 221 | ||
222 | /* Used for Hyper-V Socket: a guest client's connect() to the host */ | ||
223 | int vmbus_send_tl_connect_request(const uuid_le *shv_guest_servie_id, | ||
224 | const uuid_le *shv_host_servie_id) | ||
225 | { | ||
226 | struct vmbus_channel_tl_connect_request conn_msg; | ||
227 | |||
228 | memset(&conn_msg, 0, sizeof(conn_msg)); | ||
229 | conn_msg.header.msgtype = CHANNELMSG_TL_CONNECT_REQUEST; | ||
230 | conn_msg.guest_endpoint_id = *shv_guest_servie_id; | ||
231 | conn_msg.host_service_id = *shv_host_servie_id; | ||
232 | |||
233 | return vmbus_post_msg(&conn_msg, sizeof(conn_msg)); | ||
234 | } | ||
235 | EXPORT_SYMBOL_GPL(vmbus_send_tl_connect_request); | ||
236 | |||
222 | /* | 237 | /* |
223 | * create_gpadl_header - Creates a gpadl for the specified buffer | 238 | * create_gpadl_header - Creates a gpadl for the specified buffer |
224 | */ | 239 | */ |
@@ -624,6 +639,7 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer, | |||
624 | u64 aligned_data = 0; | 639 | u64 aligned_data = 0; |
625 | int ret; | 640 | int ret; |
626 | bool signal = false; | 641 | bool signal = false; |
642 | bool lock = channel->acquire_ring_lock; | ||
627 | int num_vecs = ((bufferlen != 0) ? 3 : 1); | 643 | int num_vecs = ((bufferlen != 0) ? 3 : 1); |
628 | 644 | ||
629 | 645 | ||
@@ -643,7 +659,7 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer, | |||
643 | bufferlist[2].iov_len = (packetlen_aligned - packetlen); | 659 | bufferlist[2].iov_len = (packetlen_aligned - packetlen); |
644 | 660 | ||
645 | ret = hv_ringbuffer_write(&channel->outbound, bufferlist, num_vecs, | 661 | ret = hv_ringbuffer_write(&channel->outbound, bufferlist, num_vecs, |
646 | &signal); | 662 | &signal, lock); |
647 | 663 | ||
648 | /* | 664 | /* |
649 | * Signalling the host is conditional on many factors: | 665 | * Signalling the host is conditional on many factors: |
@@ -659,6 +675,9 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer, | |||
659 | * If we cannot write to the ring-buffer; signal the host | 675 | * If we cannot write to the ring-buffer; signal the host |
660 | * even if we may not have written anything. This is a rare | 676 | * even if we may not have written anything. This is a rare |
661 | * enough condition that it should not matter. | 677 | * enough condition that it should not matter. |
678 | * NOTE: in this case, the hvsock channel is an exception, because | ||
679 | * it looks the host side's hvsock implementation has a throttling | ||
680 | * mechanism which can hurt the performance otherwise. | ||
662 | */ | 681 | */ |
663 | 682 | ||
664 | if (channel->signal_policy) | 683 | if (channel->signal_policy) |
@@ -666,7 +685,8 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer, | |||
666 | else | 685 | else |
667 | kick_q = true; | 686 | kick_q = true; |
668 | 687 | ||
669 | if (((ret == 0) && kick_q && signal) || (ret)) | 688 | if (((ret == 0) && kick_q && signal) || |
689 | (ret && !is_hvsock_channel(channel))) | ||
670 | vmbus_setevent(channel); | 690 | vmbus_setevent(channel); |
671 | 691 | ||
672 | return ret; | 692 | return ret; |
@@ -719,6 +739,7 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel, | |||
719 | struct kvec bufferlist[3]; | 739 | struct kvec bufferlist[3]; |
720 | u64 aligned_data = 0; | 740 | u64 aligned_data = 0; |
721 | bool signal = false; | 741 | bool signal = false; |
742 | bool lock = channel->acquire_ring_lock; | ||
722 | 743 | ||
723 | if (pagecount > MAX_PAGE_BUFFER_COUNT) | 744 | if (pagecount > MAX_PAGE_BUFFER_COUNT) |
724 | return -EINVAL; | 745 | return -EINVAL; |
@@ -755,7 +776,8 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel, | |||
755 | bufferlist[2].iov_base = &aligned_data; | 776 | bufferlist[2].iov_base = &aligned_data; |
756 | bufferlist[2].iov_len = (packetlen_aligned - packetlen); | 777 | bufferlist[2].iov_len = (packetlen_aligned - packetlen); |
757 | 778 | ||
758 | ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal); | 779 | ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, |
780 | &signal, lock); | ||
759 | 781 | ||
760 | /* | 782 | /* |
761 | * Signalling the host is conditional on many factors: | 783 | * Signalling the host is conditional on many factors: |
@@ -818,6 +840,7 @@ int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel, | |||
818 | struct kvec bufferlist[3]; | 840 | struct kvec bufferlist[3]; |
819 | u64 aligned_data = 0; | 841 | u64 aligned_data = 0; |
820 | bool signal = false; | 842 | bool signal = false; |
843 | bool lock = channel->acquire_ring_lock; | ||
821 | 844 | ||
822 | packetlen = desc_size + bufferlen; | 845 | packetlen = desc_size + bufferlen; |
823 | packetlen_aligned = ALIGN(packetlen, sizeof(u64)); | 846 | packetlen_aligned = ALIGN(packetlen, sizeof(u64)); |
@@ -837,7 +860,8 @@ int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel, | |||
837 | bufferlist[2].iov_base = &aligned_data; | 860 | bufferlist[2].iov_base = &aligned_data; |
838 | bufferlist[2].iov_len = (packetlen_aligned - packetlen); | 861 | bufferlist[2].iov_len = (packetlen_aligned - packetlen); |
839 | 862 | ||
840 | ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal); | 863 | ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, |
864 | &signal, lock); | ||
841 | 865 | ||
842 | if (ret == 0 && signal) | 866 | if (ret == 0 && signal) |
843 | vmbus_setevent(channel); | 867 | vmbus_setevent(channel); |
@@ -862,6 +886,7 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel, | |||
862 | struct kvec bufferlist[3]; | 886 | struct kvec bufferlist[3]; |
863 | u64 aligned_data = 0; | 887 | u64 aligned_data = 0; |
864 | bool signal = false; | 888 | bool signal = false; |
889 | bool lock = channel->acquire_ring_lock; | ||
865 | u32 pfncount = NUM_PAGES_SPANNED(multi_pagebuffer->offset, | 890 | u32 pfncount = NUM_PAGES_SPANNED(multi_pagebuffer->offset, |
866 | multi_pagebuffer->len); | 891 | multi_pagebuffer->len); |
867 | 892 | ||
@@ -900,7 +925,8 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel, | |||
900 | bufferlist[2].iov_base = &aligned_data; | 925 | bufferlist[2].iov_base = &aligned_data; |
901 | bufferlist[2].iov_len = (packetlen_aligned - packetlen); | 926 | bufferlist[2].iov_len = (packetlen_aligned - packetlen); |
902 | 927 | ||
903 | ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal); | 928 | ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, |
929 | &signal, lock); | ||
904 | 930 | ||
905 | if (ret == 0 && signal) | 931 | if (ret == 0 && signal) |
906 | vmbus_setevent(channel); | 932 | vmbus_setevent(channel); |