Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S966699AbbDXIm2 (ORCPT ); Fri, 24 Apr 2015 04:42:28 -0400 Received: from mail-bl2on0129.outbound.protection.outlook.com ([65.55.169.129]:21088 "EHLO na01-bl2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S966633AbbDXImX convert rfc822-to-8bit (ORCPT ); Fri, 24 Apr 2015 04:42:23 -0400 Authentication-Results: spf=pass (sender IP is 206.191.229.116) smtp.mailfrom=microsoft.com; redhat.com; dkim=none (message not signed) header.d=none; From: Dexuan Cui To: Vitaly Kuznetsov , KY Srinivasan CC: Haiyang Zhang , "devel@linuxdriverproject.org" , "linux-kernel@vger.kernel.org" Subject: RE: [PATCH 6/6] Drivers: hv: vmbus: do a fair round robin when selecting an outgoing channel Thread-Topic: [PATCH 6/6] Drivers: hv: vmbus: do a fair round robin when selecting an outgoing channel Thread-Index: AQHQfD9glT+T1Ik2P0KscewofWQgI51b1oaQ Date: Fri, 24 Apr 2015 08:42:11 +0000 Message-ID: References: <1429626460-7947-1-git-send-email-vkuznets@redhat.com> <1429626460-7947-7-git-send-email-vkuznets@redhat.com> In-Reply-To: <1429626460-7947-7-git-send-email-vkuznets@redhat.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [141.251.57.196] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 8BIT MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:206.191.229.116;CTRY:US;IPV:NLI;EFV:NLI;BMV:1;SFV:NSPM;SFS:(10019020)(6009001)(438002)(199003)(164054003)(13464003)(189002)(51704005)(46406003)(24736003)(102836002)(1511001)(2656002)(19580405001)(19580395003)(6806004)(87936001)(86362001)(54356999)(86612001)(5001770100001)(2421001)(2950100001)(50466002)(33646002)(76176999)(47776003)(66066001)(50986999)(108616004)(92566002)(23726002)(86146001)(77156002)(62966003)(2900100001)(106466001)(106116001)(46102003)(97756001)(16796002)(4001450100001);DIR:OUT;SFP:1102;SCL:1;SRVR:BY1PR0301MB1319;H:064-smtp-out.microsoft.com;FPR:;SPF:Pass;MLV:sfv;A:1;MX:1;LANG:en; X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BY1PR0301MB1319; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(5002010)(5005006)(3002001);SRVR:BY1PR0301MB1319;BCL:0;PCL:0;RULEID:;SRVR:BY1PR0301MB1319; X-Forefront-PRVS: 05568D1FF7 X-OriginatorOrg: microsoft.onmicrosoft.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Apr 2015 08:42:18.0029 (UTC) X-MS-Exchange-CrossTenant-Id: 72f988bf-86f1-41af-91ab-2d7cd011db47 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=72f988bf-86f1-41af-91ab-2d7cd011db47;Ip=[206.191.229.116];Helo=[064-smtp-out.microsoft.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY1PR0301MB1319 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4068 Lines: 127 > -----Original Message----- > From: Vitaly Kuznetsov [mailto:vkuznets@redhat.com] > Sent: Tuesday, April 21, 2015 22:28 > To: KY 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 > > 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): Yeah, I also found the issue. > 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 I suppose the current algorithm is trying to make use of cache locality? KY may share more information. > additional > complexity. Simplify the vmbus_get_outgoing_channel() function, make it > do what the comment before it says. Hi Vitaly, It looks your algorithm also has an issue: Assuming primary->num_sc == 3 (SC1, SC2, SC3) 1st time: we choose SC1 and primary->next_oc is set to 1. 2nd time: we choose SC2 and primary->next_oc is set to 2. 3rd time: we choose SC3 and primary->next_oc is set to 3. 4th time and later: since i varies among 1~3 and can't be bigger than 3, we always choose the primary channel. BTW, IMO it's not easy to achieve complete fairness because vmbus_get_outgoing_channel() can run simultaneously on different CPUs (so primary->next_oc can be modified at the same time by multiple CPUs), and we believe it should be lockless. Maybe atomic_t can help(?) Thanks, -- Dexuan > > 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/