Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

risc-v/mpfs: usb: fix fierce cpu polling if remote closes #186

Merged
merged 1 commit into from
Nov 30, 2023

Conversation

eenurkka
Copy link

If the remote end just closes an endpoint and no longer handles it, the system is prone to intensive cpu polling via mpfs_write_tx_fifo() especially if the device side doesn't know a thing about what the remote did.

Fix this by marking the EP as dead, which will skip all writes causing unnecessary polling. The EP is back in business if the remote end sends some data (rx) or the connection is re-established.

Summary

PX4 <-> QGroundControl ACM only connection no longer spins the CPU unnecessarily

Impact

No longer high CPU loads

Testing

Saluki-v2

@eenurkka eenurkka requested review from pussuw and jlaitine November 28, 2023 11:27
@@ -3460,11 +3487,28 @@ static int mpfs_usb_interrupt(int irq, void *context, void *arg)
{
for (i = 0; i < MPFS_USB_NENDPOINTS; i++)
{
/* Check if dead connections are back in business */

if (g_linkdead)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like the comment says, maybe it is worthwhile moving this global linkdead info to the ep (or use privep->linkdead here).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thing is that a TX ep has died, and we're checking the RX ep, which is completely different EP. Not sure there's any relation to TX/RX eps; so to say if TX EP1 has died, activity on RX EP1 or EP2 might wake it up. Need to check though.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes you are right, was not careful enough. I don't think anything in the USB standard mandates that the end point numbers for IN/OUT should be the same for the same connection. This comment can be ignored.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's possible to find out the pair, IN/OUT but not sure if it's visible in this driver level. I'll have a look, it'd be the best option, especially if there's multiple endpoints (IN, IN ,OUT OUT)..

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By tracing mpfs_allocep() I can see the eps being requested, but it's up to the higher level to pick the ones, so the driver doesn't see any IN/OUT pairs to rely on.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example, CDCACM has the following (configurable) epnos:

devinfo.epno[CDCACM_EP_INTIN_IDX] = CONFIG_CDCACM_EPINTIN;
devinfo.epno[CDCACM_EP_BULKIN_IDX] = CONFIG_CDCACM_EPBULKIN;
devinfo.epno[CDCACM_EP_BULKOUT_IDX] = CONFIG_CDCACM_EPBULKOUT;

@pussuw
Copy link

pussuw commented Nov 28, 2023

Verified that this does fix the problem, CPU load of mavlink_if2 drops from 30% to 3.5% (which is the normal level).

If the remote end just closes an endpoint and no longer handles it,
the system is prone to intensive cpu polling via mpfs_write_tx_fifo()
especially if the device side doesn't know a thing about what the
remote did.

Fix this by marking the EP as dead, which will skip all writes causing
unnecessary polling. The EP is back in business if the remote end
sends some data (rx) or the connection is re-established.

Signed-off-by: Eero Nurkkala <[email protected]>
Copy link

@pussuw pussuw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@eenurkka eenurkka merged commit daef2e4 into master Nov 30, 2023
6 of 8 checks passed
pussuw pushed a commit that referenced this pull request Aug 27, 2024
CC:  modlib/modlib_depend.c "modlib/modlib_bind.c", line 741: warning #186-D: pointless comparison of
          unsigned integer with zero
            if (rel->r_offset < 0)
                              ^

Signed-off-by: guoshichao <[email protected]>
pussuw pushed a commit that referenced this pull request Aug 28, 2024
"ioexpander/gpio.c", line 529: warning #186-D: pointless comparison of
          unsigned integer with zero
            if (pintype < GPIO_INPUT_PIN || pintype >= GPIO_NPINTYPES)
                        ^

Signed-off-by: guoshichao <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants