Searched hist:"4 df106db7766a56d6db67556b0072295c2d5659d" (Results 1 – 2 of 2) sorted by relevance
/openbmc/libmctp/ |
H A D | libmctp-astlpc.h | diff 4df106db7766a56d6db67556b0072295c2d5659d Tue May 16 10:45:42 CDT 2023 Frederic Barrat <fbarrat@linux.ibm.com> astlpc: Add mctp_astlpc_tx_done() API
Add the mctp_astlpc_tx_done() API to help with packet transfer performance when using the LPC binding with the Aspeed BMC. The goal of the API is to tell the caller that the Transmit buffer has been consumed by the remote side, i.e. the Rx_complete command has been received locally. It can be helpful on the host side because of the way the Aspeed BMC implements the KCS devices.
The Aspeed BMC's KCS device doesn't provide an interrupt when the ODR register is read by the remote client/host. To workaround it, the linux KCS driver for Aspeed arms a timer to periodically check (every 0.5 second in the current implementation) the state of the register and generate an "Output Buffer Empty" (OBE) event to wake up any client on the BMC, for example the mctp-demux-daemon.
Typically, the mctp-demux-daemon waits in the poll() system call and wakes up when it receives a packet. When it's coming from the LPC bus and KCS device, the remote writes a Tx_begin command in the IDR register, which does generate an interrupt. To acknowledge the packet, the mctp-demux-daemon writes a Tx_complete command in the ODR and can then dispatch the request to the proper recipient (i.e. the PLDM daemon). When it wants to send a message on the LPC bus, the mctp-demux-daemon needs to wait till the ODR register has been read by the remote. Because we don't have an interrupt to know when that happens, the mctp-demux-daemon waits in poll() and will be awaken when an OBE event is generated by a background thread processing the timer interrupt. So when the mctp-demux-daemon enters poll() with something to send on the LPC bus, if the ODR is not available immediately, it will only be sent after the timer fires. Which could take up to 0.5s with the current driver implementation.
So when the host sends a PLDM request, it is therefore crucial, for good performance, that it reads the Rx_complete command out of the ODR very quickly when it's sending a MCTP packet as to free it and make sure the mctp-demux-daemon can send the reply immediately instead of having to wait in poll(). That's where the new mctp_astlpc_tx_done() helps: immediately after sending a message, the host can call repeatedly mctp_astlpc_poll() to read the KCS device status and read the ODR as fast as possible and with the mctp_astlpc_tx_done() API, it knows when to stop. Pseudo code looks like this (ignoring that we should timeout out of the loop after a while):
mctp_message_tx() while (!mctp_astlpc_tx_done(astlpc)) { mctp_astlpc_poll(astlpc); }
Note that the API, while generic, is (so far) only useful when called from a remote LPC endpoint.
Change-Id: I5e6d62aa142fe97449ccf9c9a2ade3cf45d02bf6 Signed-off-by: Frederic Barrat <fbarrat@linux.ibm.com> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
|
H A D | astlpc.c | diff 4df106db7766a56d6db67556b0072295c2d5659d Tue May 16 10:45:42 CDT 2023 Frederic Barrat <fbarrat@linux.ibm.com> astlpc: Add mctp_astlpc_tx_done() API
Add the mctp_astlpc_tx_done() API to help with packet transfer performance when using the LPC binding with the Aspeed BMC. The goal of the API is to tell the caller that the Transmit buffer has been consumed by the remote side, i.e. the Rx_complete command has been received locally. It can be helpful on the host side because of the way the Aspeed BMC implements the KCS devices.
The Aspeed BMC's KCS device doesn't provide an interrupt when the ODR register is read by the remote client/host. To workaround it, the linux KCS driver for Aspeed arms a timer to periodically check (every 0.5 second in the current implementation) the state of the register and generate an "Output Buffer Empty" (OBE) event to wake up any client on the BMC, for example the mctp-demux-daemon.
Typically, the mctp-demux-daemon waits in the poll() system call and wakes up when it receives a packet. When it's coming from the LPC bus and KCS device, the remote writes a Tx_begin command in the IDR register, which does generate an interrupt. To acknowledge the packet, the mctp-demux-daemon writes a Tx_complete command in the ODR and can then dispatch the request to the proper recipient (i.e. the PLDM daemon). When it wants to send a message on the LPC bus, the mctp-demux-daemon needs to wait till the ODR register has been read by the remote. Because we don't have an interrupt to know when that happens, the mctp-demux-daemon waits in poll() and will be awaken when an OBE event is generated by a background thread processing the timer interrupt. So when the mctp-demux-daemon enters poll() with something to send on the LPC bus, if the ODR is not available immediately, it will only be sent after the timer fires. Which could take up to 0.5s with the current driver implementation.
So when the host sends a PLDM request, it is therefore crucial, for good performance, that it reads the Rx_complete command out of the ODR very quickly when it's sending a MCTP packet as to free it and make sure the mctp-demux-daemon can send the reply immediately instead of having to wait in poll(). That's where the new mctp_astlpc_tx_done() helps: immediately after sending a message, the host can call repeatedly mctp_astlpc_poll() to read the KCS device status and read the ODR as fast as possible and with the mctp_astlpc_tx_done() API, it knows when to stop. Pseudo code looks like this (ignoring that we should timeout out of the loop after a while):
mctp_message_tx() while (!mctp_astlpc_tx_done(astlpc)) { mctp_astlpc_poll(astlpc); }
Note that the API, while generic, is (so far) only useful when called from a remote LPC endpoint.
Change-Id: I5e6d62aa142fe97449ccf9c9a2ade3cf45d02bf6 Signed-off-by: Frederic Barrat <fbarrat@linux.ibm.com> Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
|