[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [PATCH 6/6] Under conditions of high load, it was possible for xenvif to queue up very large numbers of packets before pushing them all upstream in one go. This was partially ameliorated by use of the NDIS_RECEIVE_FLAGS_RESOURCES flag.


  • To: "paul@xxxxxxx" <paul@xxxxxxx>, "win-pv-devel@xxxxxxxxxxxxxxxxxxxx" <win-pv-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Martin Harvey <martin.harvey@xxxxxxxxxx>
  • Date: Fri, 23 Jul 2021 14:08:42 +0000
  • Accept-language: en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=4vBL3D+oKy5Gxs6FX3HN6m1f87FwXJYWHXAd5wwlmTI=; b=UouL/LWu4Xk5OLhyZPCUESHoOfZs0rv4YCpyJLOCbvcgL35E5zIBR28voSzUDpgKp0swoD6bV57r341kIczoSdLpsmcQEb5POut/jfG5KTuO1Y8fdqI1K2XbMXRPZDcHejxidLu9EEB/6igLXhT2+OnY1qJo8mqiywj7Pb0zCL+R4Q24aOgR0Vg3KRACsEY4SpuESzqXSLEAWtsRiwiXhqkk8y5lAOReG6ant5nZgQ+E1olJmgf9/vRMFxWOl53DZWBZADn7nldfv+1hJ/JRoMgzRJHaEASfN91mFaJPbJ9wg9qV3vNw509i5EUSXFHrgWcnJV96VUqQylBynvAU6A==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=eqIFXgTG8+m+vRn9ZzFDJpUqkJ7VPP0Xw2Bp8Vkfmk9c4Xukj3TEwL/KlFateRjDgtd30qWxadY1x4WA7c/bIeCiprPZTvf3Yy9bBKjMi3Qm+geKg46x9CtAsIeah2LaOWP3DYeXVfY7eNz/Pwp0gdpkWmWf9dhW1FD6IkfRoxciElklDW8owmrh3gpYIDwxtDIHCzGH0mjiZYwFw/r2j5xY6WiUMcaaWI0trJPwlHIRto7A21kVqvVibOqvNmOT5+hN9Mjl6sLsJHdHiCaXeVhHdf0qi8OhayN6KKJRtfFKjUERYNOYXotH/uSpxYkjJa6078myWjYzsabzhr7GXQ==
  • Authentication-results: esa2.hc3370-68.iphmx.com; dkim=pass (signature verified) header.i=@citrix.onmicrosoft.com
  • Delivery-date: Fri, 23 Jul 2021 14:08:53 +0000
  • Ironport-hdrordr: A9a23:MRAFzqs7H+RYkGprYRahVQbW7skCZ4Aji2hC6mlwRA09TyXGra GTdaUguyMc1gx/ZJh5o6H+BEGBKUmskqKdkrNhQ4tKPTOW+VdASbsDnNrfKlLbalbDH4JmpM Jdmu1FeaHN5DtB/IbHCWuDYqwdKbC8mcjC74qzvhQdLz2CKZsQkjuRYTzrdHGeMTM2fabRY6 Dsn/avyQDQHUg/X4CePD0oTuLDr9rEmNbNehgdHSMq7wGIkHeB9KP6OwLw5GZdbxp/hZMZtU TVmQ3w4auu99uhzAXH6mPV55NK3PP819p4AtCWgMR9EESotu/oXvUkZ1SxhkFynAid0idyrD AKmWZ5Ay1H0QKXQohym2q35+Cv6kd115ao8y7ovZKqm72IeBsKT+5IhYdydBzF8Ewk+PdhzY JN0GTxjesKMTrw2AD0593jURZ2jUywjFgDtcQTg3ZcOLFuNYN5nMg69ENRGpEGATn97cQdHO ZjF9uZ2fA+SyLFU5mehBgt/DTBM05DQStuC3JyyfC9wnxYmmt0wFAfw9FalnAc9IglQ50B/O jcNL90/Ys+A/P+QJgNT9vpe/HHQFAlgCi8R166MBDiDuUKKnjNo5n47PE84/yrYoUByN83lI 7aWF1VuGYucwa2YPf+k6Fj41TIWiGwTD7twsZR69xwvaD9XqPiNWmGREo1m8Wtrv0DConQWu q1OphRH/j/RFGeVbphzkn7Qd1fOHMeWMoatpIyXE+PuNvCLsnwuunSYJ/oVfLQ+PYfKyrC61 44LXbOzel7nzWWs07D8W7ssinWCz7CFLpLYdznw9Q=
  • Ironport-sdr: KFcnpPNvTQ2IUtj2BXaXlUZLRcnR/3pU2EMqNRCIQNLRHBMT9dUJHVMYroYpqQaHD2IYEbxlvr uMsdgNLd969D8qRnAyEesWQ+9MD12CAFgFIcHZN5/359TvcHcAmjdPnsKIocZYDPttemhTI9fE c0X+e6xJaxn820pO0DpFjeVDGx5HlDwvj52+919N4ntMbsKzo95EEAPFSSH1k/qRRcJguhW9Of IGr/lKpBptjSyrPgXud+41LQBecvDTBlacnsSHqlDF+GyYRBCn24W3teOOkKB8RRDdWzIxuz/9 wmogQbyHtMuAL+5++jBTRmXC
  • List-id: Developer list for the Windows PV Drivers subproject <win-pv-devel.lists.xenproject.org>
  • Thread-index: AQHXfWtk+tASUJTSVEWzWgTW/lHzzqtO86eAgAF5OeA=
  • Thread-topic: [PATCH 6/6] Under conditions of high load, it was possible for xenvif to queue up very large numbers of packets before pushing them all upstream in one go. This was partially ameliorated by use of the NDIS_RECEIVE_FLAGS_RESOURCES flag.

-----Original Message-----
From: win-pv-devel <win-pv-devel-bounces@xxxxxxxxxxxxxxxxxxxx> On Behalf Of 
Paul Durrant
Sent: 22 July 2021 13:44
To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx
Subject: Re: [PATCH 6/6] Under conditions of high load, it was possible for 
xenvif to queue up very large numbers of packets before pushing them all 
upstream in one go. This was partially ameliorated by use of the 
NDIS_RECEIVE_FLAGS_RESOURCES flag.

> I think you first ought to make a new version of
> VifReceiverQueuePacket() that can return a boolean value to say whether you 
> should queue more or not. Then XENNET can be the one > to apply the 
> backpressure (as it should be).

Ah. Okay,  think this is possibly due to a misnomer. I need to explain why I 
don't think that will work: As I understand it, the problem is that there 
aren't actually any explicit flow control signals from above. Perhaps I should 
have called it "Throttling" instead of backpressure, and at the moment, that 
throttling is internal to XenVif, because there's no way of knowing exactly how 
much stress/resource scarcity higher levels of the stack are under.

 The way it's currently implemented is:

- From Ring->PacketComplete, we allow RX_BUFFERING_MAX to be pushed upsteam per 
DPC.
- If that fails to empty Ring->PacketComplete, we immediately schedule another 
DPC, this allowing other DPC's to run first, which is assumed to give higher 
layers a chance to digest the packets pushed up, and/or free up resources when 
those packets have been completed.
- Upstream of that, we are holding Ring->PacketQueue, which gets cleared and 
moved to Ring->PacketComplete via ReceiverRingProcessPacket.
- This transfer of Ring->PacketQueue to Ring->PacketComplete will only happen 
when Ring->PacketComplete has been emptied, that subject to RX_BUFFERING_MAX 
constraints per DPC.
- We keep a conservative estimate of how large Ring->PacketQueue is growing.
- We expect that Ring->PacketQueue should be large enough as an imtermediate 
buffer to empty the entire ring, and that in cases whether throttling is 
underway, the packet queue will grow whilst waiting for PacketComplete to empty.
- We allow PacketQueue to grow up to a certain size: also RX_BUFFERING_MAX, so 
it is possible to empty the entire queue to PacketComplete and indicate all of 
PacketComplete up to NDIS in one go.
- If PacketQueue is about to grow larger than that, then we leave the PollDPC 
early, so it does not fill up the packet queue, and we allow the ring itself to 
back up.

Now, of course, the reason this works at all is because we have two DPC's: 
PollDPC and QueueDPC. The draining from the packet queue to packet complete, 
and indicate up to NDIS is in the  QueueDpc, and the filling of the packet 
queue is in the PollDPC. It is the different rates of these two DPC's that 
indicates whether the PacketQueue will fill or empty.

> I think the part below should now be split out into a separate function now; 
> it's all getting a bit long to be inline. You might also
> consider a separate DPC that just does this second part so you can just use 
> that in the case you need to defer.

> -    while (!IsListEmpty(&Ring->PacketComplete)) {
> +    while ((!IsListEmpty(&Ring->PacketComplete))
> +        && ((PushedUpstream < RX_BUFFERING_MAX) || Ring->FinalFlush)) 
> + {

I am loath to create another DPC. Refactoring is all fine, but creating another 
DPC changes the runtime behaviour.

I have omitted to upstream a patch which we have locally which has a large 
amount of stats on relative DPC rates, and also how much the two DPC's overlap 
each other (that is, execute concurrently).

Agree that we need to break ReceiverRingSwizzle into a couple of separate 
functions, one dealing with transferring PacketQueue -> PacketComplete, and one 
dealing with PacketComplete -> Indicate up to NDIS. Adding another DPC totally 
invalidates all the profiling etc I have done.

Given the proximity of the queuing / dpc logic to XenVif, and the lack of 
upstream signals from Ndis to XenNet (correct me if I am wrong), I can't see a 
way to easily push this logic up to XenNet.

Let me know if you're happy with this approach.

MH.


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.