CM implementation notes and data structures

The basic structures that are critical to the CM implementation are the cm_macroflow, cm_flow, cm_sched and cm_congctl. When the CM is first initialized it creates a single instance of struct cm. This structure contains a hashtable (mflowtab), which is used store all cm_macroflows. cm_macroflow is the basic container used to share congestion control state. The struct cm_mflow_key (key) stored within each cm_macroflow help match it with new cm_flows that are created. When a cm_flow is created and it does not match with any existing cm_macroflow, a new cm_macroflow is created and added to the hashtable. Each struct cm_macroflow contains the list of flows (flows) that share congestion state, the actual shared congestion state (congctl) and the scheduler state (sched) for the cm_macroflow.

Each struct cm_flow contains information about the current state of the flow as well as information needed to communicate information to the owner of the flow. The cmapp_send and cmapp_update store the function pointers that are used to store the callback functions used by the request/callback and rate-based CM APIs.

The congestion control state for a macroflow is stored in a cm_congctl structure. The structure is divided into a set of function pointers (ops) that implement the actual congestion control algorithms and set of variables (state) that store the current state of the algorithms. The CM provides cm_notify(), cm_update() and cm_query() APIs. In order to satisfy these calls, each congestion control module must also implement a notify(), update() and query() interface. Pointers to these interfaces must be provided in the cm_congctl_ops structure. In addition, the congestion control module must also provide a wakeup() interface. This function is called periodically by the congestion manager. This allows the congestion controller to perform any necessary tasks such as scheduling transmissions. Persistant state that is used by the different calls in cm_congctl_ops is stored in the cm_congctl_state structure.

The scheduler for a macroflow is stored in a cm_sched structure. Like the congestion controller, the structure is divided into a set of function pointers (ops) that actually implement the scheduler algorithms and set of variables (state) that store the current state of the algorithms. The CM provides cm_notify() and cm_query() APIs. In order to satisfy these calls, each congestion control module must also implement a notify() and query() interface. Pointers to these interfaces must be provided in the cm_congctl_ops structure. In addition, once the congestion control module has determined that a packet can be sent it must pass control to the scheduler to determine which flow can send data. The congestion control module uses the schedule() call provided by the scheduler to pass control. Finally, a scheduler must also provide a delete_flow() function that is called whenever a flow within the scheduler's macroflow is deleted. Persistent state that is used by the different calls in cm_congctl_ops is stored in the cm_sched_state structure.