There are three ways you can handle flow control:
- If you're overloaded, you drop data on the floor.
- If you can't provide service for a request from a higher layer, typically because your local queue is full, you return an error to that higher layer.
- You proactively notify higher layers that they need to slow down.
At the Ethernet layer, method 3 is supported through pause frames. Often higher layers don't support method 3, but instead support method 2. When a layer has a layer below it that supports method 3 but the layer above it only supports method 2, it can stop passing data to lower layers temporarily, causing method 2 to apply to higher layers.
Or, to put it more concretely, when you receive a pause frame you stop your sending engine and set a timer to restart the sending engine in the appropriate time. While the sending engine is stopped, your local queues will fill up with data from higher layers. If they get full, you return "busy" errors to the higher layers and they handle that however is appropriate.
So how does a pause frame get sent up the stack and in turn have the NIC slow down its sending traffic? The ethernet controllers I have support flow control, but I can't determine why traffic doesn't "pause". – user_ABCD – 2016-01-26T23:21:31.167
4The pause frame doesn't get sent up the stack. The low layer of the stack simply stops reading frames from the queue. When the queue gets full, higher layers detect this when their "add packet to queue" functions fail. (Read the last paragraph.) – David Schwartz – 2016-01-26T23:22:41.920
I am quite new to all this, but if I understand you correctly, what causes me to stop reading frames from the queue? Using ethtool, I can see I am receiving pause frames from the switch. But my udp application never slows down in regards to a bps. – user_ABCD – 2016-01-26T23:34:01.933
1I don't know the specific of your UDP application (and platform), but typically it's whatever mechanism would handle the case where there were no pause frames. Since you can also overload non-local, non-Ethernet links, you can't rely on pause frames for UDP transmit pacing, and usually there's no point in making two mechanisms. If your platform does propagate the information up all the way to user space, you'd typically detect it because a
sendto
on a non-blocking UDP socket would return a "would block" indication. – David Schwartz – 2016-01-26T23:38:15.360Hmmm. I am pretty sure I understand you. Is there a good way to determine if I am even handling the pause frames? Two things I currently know are I am in fact receiving pause frames (ethtool) and throughput (wireshark) never seems to change. Almost like higher layers never do anything when I receive the pause frames. – user_ABCD – 2016-01-27T21:17:36.983