diff options
author | K. Y. Srinivasan <kys@microsoft.com> | 2015-02-28 14:39:02 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-03-01 22:31:47 -0500 |
commit | a13e8bbe851a96a0e78c2bd599bc34082fa697cd (patch) | |
tree | 3901b34efd778528b85afd85c36cb33829c79949 /drivers/hv/channel_mgmt.c | |
parent | 96c1d0581d00f7abe033350edb021a9d947d8d81 (diff) |
Drivers: hv: vmbus: Use a round-robin algorithm for picking the outgoing channel
The current algorithm for picking an outgoing channel was not distributing
the load well. Implement a simple round-robin scheme to ensure good
distribution of the outgoing traffic.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Long Li <longli@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hv/channel_mgmt.c')
-rw-r--r-- | drivers/hv/channel_mgmt.c | 30 |
1 files changed, 15 insertions, 15 deletions
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index b1e5a5fdaf7f..611789139f9b 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c | |||
@@ -350,6 +350,7 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel) | |||
350 | } | 350 | } |
351 | 351 | ||
352 | newchannel->state = CHANNEL_OPEN_STATE; | 352 | newchannel->state = CHANNEL_OPEN_STATE; |
353 | channel->num_sc++; | ||
353 | if (channel->sc_creation_callback != NULL) | 354 | if (channel->sc_creation_callback != NULL) |
354 | /* | 355 | /* |
355 | * We need to invoke the sub-channel creation | 356 | * We need to invoke the sub-channel creation |
@@ -862,9 +863,8 @@ cleanup: | |||
862 | 863 | ||
863 | /* | 864 | /* |
864 | * Retrieve the (sub) channel on which to send an outgoing request. | 865 | * Retrieve the (sub) channel on which to send an outgoing request. |
865 | * When a primary channel has multiple sub-channels, we choose a | 866 | * When a primary channel has multiple sub-channels, we try to |
866 | * channel whose VCPU binding is closest to the VCPU on which | 867 | * distribute the load equally amongst all available channels. |
867 | * this call is being made. | ||
868 | */ | 868 | */ |
869 | struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary) | 869 | struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary) |
870 | { | 870 | { |
@@ -872,11 +872,19 @@ struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary) | |||
872 | int cur_cpu; | 872 | int cur_cpu; |
873 | struct vmbus_channel *cur_channel; | 873 | struct vmbus_channel *cur_channel; |
874 | struct vmbus_channel *outgoing_channel = primary; | 874 | struct vmbus_channel *outgoing_channel = primary; |
875 | int cpu_distance, new_cpu_distance; | 875 | int next_channel; |
876 | int i = 1; | ||
876 | 877 | ||
877 | if (list_empty(&primary->sc_list)) | 878 | if (list_empty(&primary->sc_list)) |
878 | return outgoing_channel; | 879 | return outgoing_channel; |
879 | 880 | ||
881 | next_channel = primary->next_oc++; | ||
882 | |||
883 | if (next_channel > (primary->num_sc)) { | ||
884 | primary->next_oc = 0; | ||
885 | return outgoing_channel; | ||
886 | } | ||
887 | |||
880 | cur_cpu = hv_context.vp_index[get_cpu()]; | 888 | cur_cpu = hv_context.vp_index[get_cpu()]; |
881 | put_cpu(); | 889 | put_cpu(); |
882 | list_for_each_safe(cur, tmp, &primary->sc_list) { | 890 | list_for_each_safe(cur, tmp, &primary->sc_list) { |
@@ -887,18 +895,10 @@ struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary) | |||
887 | if (cur_channel->target_vp == cur_cpu) | 895 | if (cur_channel->target_vp == cur_cpu) |
888 | return cur_channel; | 896 | return cur_channel; |
889 | 897 | ||
890 | cpu_distance = ((outgoing_channel->target_vp > cur_cpu) ? | 898 | if (i == next_channel) |
891 | (outgoing_channel->target_vp - cur_cpu) : | 899 | return cur_channel; |
892 | (cur_cpu - outgoing_channel->target_vp)); | ||
893 | |||
894 | new_cpu_distance = ((cur_channel->target_vp > cur_cpu) ? | ||
895 | (cur_channel->target_vp - cur_cpu) : | ||
896 | (cur_cpu - cur_channel->target_vp)); | ||
897 | |||
898 | if (cpu_distance < new_cpu_distance) | ||
899 | continue; | ||
900 | 900 | ||
901 | outgoing_channel = cur_channel; | 901 | i++; |
902 | } | 902 | } |
903 | 903 | ||
904 | return outgoing_channel; | 904 | return outgoing_channel; |