Hi all, I have been working with P4 and wanted some advice on what approach people would recommend to calculate the bandwidth utilisation (ie bytes per second) of any given interface so it could be stored in a register and then used for dynamic control plane population of set_queue_rate?
Basically I’d like to write a program that monitors the link bandwidth and then can update queue rates directly by updating tables using the control plane…ideally using something automated like a digest, or INT, so basically the queue rates could be adapted when bandwidth conditions are good versus bad etc.
Is this possible or would know where I could start ?
If you want to be pedantic (as I sometimes do), the instantaneous link utilization is always either 100% (while a packet is being transmitted), or 0% (when no packet is being transmitted).
Typically you would want some kind of measure of utilization averaged over some period of time.
Two possible ways to do that are:
use some kind of exponentially-weighted moving average. See Moving average - Wikipedia for probably more details than you might want. I have written an article on how to use integer arithmetic to help in calculating one kind of exponentially weighted moving average here, but be warned that it is not necessarily exactly what you want in your use case: https://github.com/jafingerhut/p4-guide/blob/master/docs/floating-point-operations.md
break up time into separate time intervals, e.g. the first 1 millisec, the second 1 millisec, the 3rd 1 millisec, etc., and calculate the total number of bytes transmitted in each of those intervals in separate counters. You would probably only want to use a counter value after it ended, because if you use the current time interval’s byte counter, it will typically be lower than the counter of any complete time interval.
Thanks for the advice, and I’ll have a read. In the meantime I’ll continue using counters which are read into the control plane to show packets and bytes, just wondered if there was a more automated way - but thanks for the time.
@taylort79 – as with most “can I do X in P4” kind of questions, it is extremely important to mention the architecture you plan to use for your program.
For example, some P4_16 architectures (specifically TNA and T2NA) provide a special extern, called
Lpf() that can calculate average data rate as long as you feed it the packet length. The output can then be stored in a register or exported using some other way.
Irrespective of that, there is a separate question of obtaining the accurate packet length. Again, a lot depends on the specific architecture and the target. For example, in many cases packet length might not be available in the ingress pipeline and has to be derived (e.g. from IPv4
total_length field or a similar one). Similarly, on many platforms the packet length in the egress match-action pipeline might not fully account for the modifications that were performed there and such an adjustment has to be done manually.
Last. but not least, if you talk about the Ethernet link utilization, you need to remember that at the Layer1 all frames are 20 bytes longer than what you typically see in a P4 data plane, since there are additional 8 bytes of the preamble and 12 bytes of the inter-frame gap.
Please, see this post if you have further questions.