Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755363AbbDUO14 (ORCPT ); Tue, 21 Apr 2015 10:27:56 -0400 Received: from mx1.redhat.com ([209.132.183.28]:54314 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755234AbbDUO1x (ORCPT ); Tue, 21 Apr 2015 10:27:53 -0400 From: Vitaly Kuznetsov To: "K. Y. Srinivasan" Cc: Haiyang Zhang , devel@linuxdriverproject.org, linux-kernel@vger.kernel.org, Dexuan Cui Subject: [PATCH 6/6] Drivers: hv: vmbus: do a fair round robin when selecting an outgoing channel Date: Tue, 21 Apr 2015 16:27:40 +0200 Message-Id: <1429626460-7947-7-git-send-email-vkuznets@redhat.com> In-Reply-To: <1429626460-7947-1-git-send-email-vkuznets@redhat.com> References: <1429626460-7947-1-git-send-email-vkuznets@redhat.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2747 Lines: 85 vmbus_get_outgoing_channel() implements the following algorithm for selecting an outgoing channel (despite the comment before the function saying it distributes the load equally): 1) If we have no subchannels return the primary channel; 2) If primary->next_oc is grater than primary->num_sc reset the primary->next_oc to 0 and return the primary channel; 3) Aim for the primary->next_oc subchannel, increment primary->next_oc; 4) Loop through all opened subchannels. If we see a channel which has target_cpu == current_cpu return it. If we reached the primary->next_oc'th open subchannel return it; 5) Return the primary channel. The implementation also skips the subchannel No. 0 unless it matches the current cpu as we assign i to 1 in the initialization. This is not a fair round robin as subchannels in the beginning of the list are more likely to be returned and checking for current cpu aslo creates additional complexity. Simplify the vmbus_get_outgoing_channel() function, make it do what the comment before it says. Signed-off-by: Vitaly Kuznetsov --- drivers/hv/channel_mgmt.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index daa6417..df82442 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -827,39 +827,30 @@ cleanup: struct vmbus_channel *vmbus_get_outgoing_channel(struct vmbus_channel *primary) { struct list_head *cur, *tmp; - int cur_cpu; struct vmbus_channel *cur_channel; - struct vmbus_channel *outgoing_channel = primary; - int next_channel; - int i = 1; + int i = 0; if (list_empty(&primary->sc_list)) - return outgoing_channel; + return primary; - next_channel = primary->next_oc++; - - if (next_channel > (primary->num_sc)) { + if (primary->next_oc > primary->num_sc) { primary->next_oc = 0; - return outgoing_channel; + return primary; } - cur_cpu = hv_context.vp_index[get_cpu()]; - put_cpu(); list_for_each_safe(cur, tmp, &primary->sc_list) { + i++; cur_channel = list_entry(cur, struct vmbus_channel, sc_list); if (cur_channel->state != CHANNEL_OPENED_STATE) continue; - if (cur_channel->target_vp == cur_cpu) - return cur_channel; - - if (i == next_channel) + if (i > primary->next_oc) { + primary->next_oc = i; return cur_channel; - - i++; + } } - return outgoing_channel; + return primary; } EXPORT_SYMBOL_GPL(vmbus_get_outgoing_channel); -- 1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/