turing-machines / BMC-Firmware

Turing-pi BMC firmware
GNU General Public License v2.0
215 stars 26 forks source link

Request: USB routing API should support priorities #158

Open CFSworks opened 7 months ago

CFSworks commented 7 months ago

Is your feature request related to a problem? Please describe. I have a workload that makes use of the USB 2.0 port on my board. As the workload may move "randomly" between nodes (depending on CPU/RAM availability, etc.) I have it claim the USB port with tpi usb ... on initialization. This works well, but can interfere with BMC<->node flashing operations: if the workload happens to reinitialize while I'm flashing a different node, bmcd will naively grant the USB reconnection request.

Describe the solution you'd like I propose 2 different "priorities" for API-driven USB routing changes: Request and Demand.

bmcd shall track not only the USB connection that is established, but also the type of API call that made the connection. The USB connection is at all times in one of 3 states:

When a Demand comes in, bmcd will always apply the demanded change, and will transition to either the Demanded state (in case of connection demands) or Idle state (in case of disconnection demands).

When a Request comes in, bmcd will only grant the request if the connection is currently in the Idle or Requested state. If the connection is Demanded, it will return with an error code. (There is one exception to this: if the requested connectivity is the same as the demanded connectivity, the result is a "successful no-op" -- the API server returns success but no change to the USB state occurs.)

For backwards-compatibility, the default is Request for node (host mode)->USB 2.0 port connections. The default is Demand for all others (including bmcd-initiated USB connections).

Describe alternatives you've considered A simpler alternative would be to disable(/read-only) the USB API altogether while node flashing is in progress, but I also make use of msd mode and the bmcd cannot readily know when I'm done with it.

Happy to discuss alternatives.

CFSworks commented 7 months ago

On second thought: This can be generalized to any number of priority levels (not just "Request"/"Demand") through the following rules:

svenrademakers commented 7 months ago

I agree that we should do something about mutually exclusive operations. Other areas of the API, such as power, suffer from the same problem. e.g., a flashing operation can be interrupted by powering off the nodes using the KEY_1 button. Currently, subsequent requests are behaving more or less blocking until the node install is finished. (This is more an effect than enforced behavior. Incoming requests are blocked on TCP level during a file transfer).

I like the priority system idea, But would a more simplistic approach not suffice already? I expect that 95% of all boards are operated by a single user. Some, like you, have an additional script running, So let's say occasionally, we have at most 2/3 clients competing for exclusive access.

If we just go for non-blocking requests: