diff options
author | K. Y. Srinivasan <kys@microsoft.com> | 2016-07-01 19:26:35 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-08-31 07:05:41 -0400 |
commit | ccef9bcc02ee63ac171ea9f0d51e04b3e55b3a12 (patch) | |
tree | 90726ee1cfee006f7c79c459c61fc43892e3e732 | |
parent | 638fea33aee858cc665297a76f0039e95a28ce0c (diff) |
Drivers: hv: vmbus: Enable explicit signaling policy for NIC channels
For synthetic NIC channels, enable explicit signaling policy as netvsc wants to
explicitly control when the host is to be signaled.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/hv/channel.c | 18 | ||||
-rw-r--r-- | drivers/hv/channel_mgmt.c | 2 | ||||
-rw-r--r-- | drivers/hv/hyperv_vmbus.h | 3 | ||||
-rw-r--r-- | drivers/hv/ring_buffer.c | 15 |
4 files changed, 20 insertions, 18 deletions
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index e47d37d21d56..9a49505a8e06 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c | |||
@@ -650,7 +650,7 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer, | |||
650 | bufferlist[2].iov_len = (packetlen_aligned - packetlen); | 650 | bufferlist[2].iov_len = (packetlen_aligned - packetlen); |
651 | 651 | ||
652 | ret = hv_ringbuffer_write(&channel->outbound, bufferlist, num_vecs, | 652 | ret = hv_ringbuffer_write(&channel->outbound, bufferlist, num_vecs, |
653 | &signal, lock); | 653 | &signal, lock, channel->signal_policy); |
654 | 654 | ||
655 | /* | 655 | /* |
656 | * Signalling the host is conditional on many factors: | 656 | * Signalling the host is conditional on many factors: |
@@ -671,11 +671,6 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer, | |||
671 | * mechanism which can hurt the performance otherwise. | 671 | * mechanism which can hurt the performance otherwise. |
672 | */ | 672 | */ |
673 | 673 | ||
674 | if (channel->signal_policy) | ||
675 | signal = true; | ||
676 | else | ||
677 | kick_q = true; | ||
678 | |||
679 | if (((ret == 0) && kick_q && signal) || | 674 | if (((ret == 0) && kick_q && signal) || |
680 | (ret && !is_hvsock_channel(channel))) | 675 | (ret && !is_hvsock_channel(channel))) |
681 | vmbus_setevent(channel); | 676 | vmbus_setevent(channel); |
@@ -768,7 +763,7 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel, | |||
768 | bufferlist[2].iov_len = (packetlen_aligned - packetlen); | 763 | bufferlist[2].iov_len = (packetlen_aligned - packetlen); |
769 | 764 | ||
770 | ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, | 765 | ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, |
771 | &signal, lock); | 766 | &signal, lock, channel->signal_policy); |
772 | 767 | ||
773 | /* | 768 | /* |
774 | * Signalling the host is conditional on many factors: | 769 | * Signalling the host is conditional on many factors: |
@@ -786,11 +781,6 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel, | |||
786 | * enough condition that it should not matter. | 781 | * enough condition that it should not matter. |
787 | */ | 782 | */ |
788 | 783 | ||
789 | if (channel->signal_policy) | ||
790 | signal = true; | ||
791 | else | ||
792 | kick_q = true; | ||
793 | |||
794 | if (((ret == 0) && kick_q && signal) || (ret)) | 784 | if (((ret == 0) && kick_q && signal) || (ret)) |
795 | vmbus_setevent(channel); | 785 | vmbus_setevent(channel); |
796 | 786 | ||
@@ -852,7 +842,7 @@ int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel, | |||
852 | bufferlist[2].iov_len = (packetlen_aligned - packetlen); | 842 | bufferlist[2].iov_len = (packetlen_aligned - packetlen); |
853 | 843 | ||
854 | ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, | 844 | ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, |
855 | &signal, lock); | 845 | &signal, lock, channel->signal_policy); |
856 | 846 | ||
857 | if (ret == 0 && signal) | 847 | if (ret == 0 && signal) |
858 | vmbus_setevent(channel); | 848 | vmbus_setevent(channel); |
@@ -917,7 +907,7 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel, | |||
917 | bufferlist[2].iov_len = (packetlen_aligned - packetlen); | 907 | bufferlist[2].iov_len = (packetlen_aligned - packetlen); |
918 | 908 | ||
919 | ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, | 909 | ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, |
920 | &signal, lock); | 910 | &signal, lock, channel->signal_policy); |
921 | 911 | ||
922 | if (ret == 0 && signal) | 912 | if (ret == 0 && signal) |
923 | vmbus_setevent(channel); | 913 | vmbus_setevent(channel); |
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 8818b92e5912..d8b64ba45b1d 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c | |||
@@ -426,6 +426,8 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) | |||
426 | } | 426 | } |
427 | 427 | ||
428 | dev_type = hv_get_dev_type(&newchannel->offermsg.offer.if_type); | 428 | dev_type = hv_get_dev_type(&newchannel->offermsg.offer.if_type); |
429 | if (dev_type == HV_NIC) | ||
430 | set_channel_signal_state(newchannel, HV_SIGNAL_POLICY_EXPLICIT); | ||
429 | 431 | ||
430 | init_vp_index(newchannel, dev_type); | 432 | init_vp_index(newchannel, dev_type); |
431 | 433 | ||
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index dfa9fac100d8..ddcc3485520d 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h | |||
@@ -529,7 +529,8 @@ void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info); | |||
529 | 529 | ||
530 | int hv_ringbuffer_write(struct hv_ring_buffer_info *ring_info, | 530 | int hv_ringbuffer_write(struct hv_ring_buffer_info *ring_info, |
531 | struct kvec *kv_list, | 531 | struct kvec *kv_list, |
532 | u32 kv_count, bool *signal, bool lock); | 532 | u32 kv_count, bool *signal, bool lock, |
533 | enum hv_signal_policy policy); | ||
533 | 534 | ||
534 | int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, | 535 | int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, |
535 | void *buffer, u32 buflen, u32 *buffer_actual_len, | 536 | void *buffer, u32 buflen, u32 *buffer_actual_len, |
diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c index fe586bf74e17..e3edcaee7ab3 100644 --- a/drivers/hv/ring_buffer.c +++ b/drivers/hv/ring_buffer.c | |||
@@ -66,12 +66,20 @@ u32 hv_end_read(struct hv_ring_buffer_info *rbi) | |||
66 | * arrived. | 66 | * arrived. |
67 | */ | 67 | */ |
68 | 68 | ||
69 | static bool hv_need_to_signal(u32 old_write, struct hv_ring_buffer_info *rbi) | 69 | static bool hv_need_to_signal(u32 old_write, struct hv_ring_buffer_info *rbi, |
70 | enum hv_signal_policy policy) | ||
70 | { | 71 | { |
71 | virt_mb(); | 72 | virt_mb(); |
72 | if (READ_ONCE(rbi->ring_buffer->interrupt_mask)) | 73 | if (READ_ONCE(rbi->ring_buffer->interrupt_mask)) |
73 | return false; | 74 | return false; |
74 | 75 | ||
76 | /* | ||
77 | * When the client wants to control signaling, | ||
78 | * we only honour the host interrupt mask. | ||
79 | */ | ||
80 | if (policy == HV_SIGNAL_POLICY_EXPLICIT) | ||
81 | return true; | ||
82 | |||
75 | /* check interrupt_mask before read_index */ | 83 | /* check interrupt_mask before read_index */ |
76 | virt_rmb(); | 84 | virt_rmb(); |
77 | /* | 85 | /* |
@@ -264,7 +272,8 @@ void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info) | |||
264 | 272 | ||
265 | /* Write to the ring buffer. */ | 273 | /* Write to the ring buffer. */ |
266 | int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info, | 274 | int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info, |
267 | struct kvec *kv_list, u32 kv_count, bool *signal, bool lock) | 275 | struct kvec *kv_list, u32 kv_count, bool *signal, bool lock, |
276 | enum hv_signal_policy policy) | ||
268 | { | 277 | { |
269 | int i = 0; | 278 | int i = 0; |
270 | u32 bytes_avail_towrite; | 279 | u32 bytes_avail_towrite; |
@@ -326,7 +335,7 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info, | |||
326 | if (lock) | 335 | if (lock) |
327 | spin_unlock_irqrestore(&outring_info->ring_lock, flags); | 336 | spin_unlock_irqrestore(&outring_info->ring_lock, flags); |
328 | 337 | ||
329 | *signal = hv_need_to_signal(old_write, outring_info); | 338 | *signal = hv_need_to_signal(old_write, outring_info, policy); |
330 | return 0; | 339 | return 0; |
331 | } | 340 | } |
332 | 341 | ||