On Mon 15 Feb 2016 05:40:29 PM CET, Stefan Hajnoczi wrote: > On Fri, Feb 05, 2016 at 12:59:10PM +0200, Alberto Garcia wrote: >> - With this series we set "a maximum of X operations/second for a >> period of T seconds". If would also be possible to make it "a >> maximum of X operations/second up to a total of Y operations". It >> would be equivalent (Y = X * T) but I thought the current proposal >> makes a more clear API. > > I find the diagram in the blog post clear. The QEMU code is a little > harder to understand, it seems like there are too many variables and > special cases. There are 4 core variables: > > 1. Refill rate (aka avg), e.g. 30 IOPS > 2. Max bucket level (aka max * burst_length), e.g. 5.4 million IOPS > 3. Burst rate (aka max), e.g. 3000 IOPS > 4. Current bucket level
The blog post uses the token bucket algorithm but QEMU uses the leaky bucket. They're equivalent, but one is the reverse of the other: in the former the bucket is full and the performed I/O is the water that leaks from the bucket; in the latter the bucket is empty and the performed I/O is the water that goes into the bucket. We have these 3 variables: - Leak rate (avg), 30 IOPS - Fill-up rate (max). 3000 IOPS - Fill-up time (burst_length), 30 minutes We allow I/O until the bucket is full and we disallow it afterwards. The bucket leaks at 30 IOPS so that's the reason why we get that I/O rate. We need to keep track of the bucket level (bkt->level) and make it leak at 30 IOPS. With this series we also want to limit the amount of water per second that goes into the bucket before it's full. So how do we make sure that we don't allow more than 3000 IOPS when adding water to the bucket? We actually have the same problem as in the previous paragraph, except that the I/O rate here is different. That's why we need bkt->burst_level that leaks at 3000 IOPS. It's easier to see if you think about it as a second bucket on top of the main one that leaks at 3000 IOPS. Berto