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

drivers: udc: follow-up, fix race conditions in nRF USBD and Kinetis UDC drivers #53489

Merged
merged 7 commits into from
Jan 11, 2023

Conversation

jfischer-no
Copy link
Collaborator

follow-up on #38679 , fix race conditions in nRF USBD and Kinetis UDC drivers

Immediately return NULL if endpoint configuration is not available.

Signed-off-by: Johann Fischer <[email protected]>
@jfischer-no jfischer-no added area: Drivers area: USB Universal Serial Bus Experimental Experimental features not enabled by default labels Jan 4, 2023
desowin
desowin previously approved these changes Jan 5, 2023
Copy link

@desowin desowin left a comment

Choose a reason for hiding this comment

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

I disagree on the way you use asserts. The actual changes however are really needed and thus I approve.

Comment on lines 54 to 57
if (unlikely(ep_cfg == NULL)) {
__ASSERT(false, "ep 0x%02x is not available", ep);
return true;
}
Copy link

Choose a reason for hiding this comment

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

I don't like such concepts. I'd prefer to replace it with __ASSERT(ep_cfg != NULL, "ep 0x%02x is not available", ep);. The thing is, if this is called with invalid ep, then the code is already known to be wrong and continuting execution is going no good. It is better if it just crashes with NULL pointer dereference if the code is wrong and asserts are disabled instead of masking the issue (which essentially makes debugging harder and allows bugs to go unnoticed for long time - or even worse, worked around in higher layers).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It is better if it just crashes with NULL pointer dereference if the code is wrong and asserts are disabled instead of masking the issue...

That actually makes perfect sense in this case. I will change it.

Comment on lines 67 to 66
if (unlikely(ep_cfg == NULL)) {
__ASSERT(false, "ep 0x%02x is not available", ep);
} else {
ep_cfg->stat.busy = busy;
}
}
Copy link

Choose a reason for hiding this comment

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

I would definitely prefer __ASSERT(ep_cfg != NULL, "ep 0x%02x is not available", ep); followed by unconditional ep_cfg->stat.busy = busy;. This way if asserts are disabled the code will simply fail writing to NULL pointer and will make the issue obvious (which will save a lot of time debugging it later).

LOG_DBG("ep 0x%02x buf busy", cfg->addr);
if (unlikely(usbfsotg_bd_is_busy(bd))) {
LOG_ERR("ep 0x%02x buf busy", cfg->addr);
__ASSERT_NO_MSG(false);
Copy link

Choose a reason for hiding this comment

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

Why assert here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That checks controller buffer flag, here the buffer should not be owned by the controller.

Copy link

Choose a reason for hiding this comment

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

Then I would prefer the assert to be moved before the if, e.g. __ASSERT_NO_MSG(!usbfsotg_bd_is_busy(bd));

@jfischer-no jfischer-no added the DNM This PR should not be merged (Do Not Merge) label Jan 5, 2023
Add helper functions to set and check endpoint busy state.

Signed-off-by: Johann Fischer <[email protected]>
Periodic enqeueu of buffers can cause a attempt to start
a new transfer to host even though an IN endpoint is already busy.
Use busy state flags to explicitly mark an endpoint busy.

Signed-off-by: Johann Fischer <[email protected]>
Pending state flag was only used by the UDC nRF USBD driver.
With the introduction of busy state flag it is no longer needed
and can be removed.

Signed-off-by: Johann Fischer <[email protected]>
Periodic enqeueu of buffers can cause a attempt to start
a new transfer even though an endpoint is already busy.

Split usbfsotg_xfer_start() into two function, one to start
next transfer and another to continue the transfers, and use
busy state flags to explicitly mark an endpoint busy.

Signed-off-by: Johann Fischer <[email protected]>
Remove workaround for the UDC enqueue bug in experimental
CDC ACM implementation.

Signed-off-by: Johann Fischer <[email protected]>
The description was still from the early stages of development.

Signed-off-by: Johann Fischer <[email protected]>
@jfischer-no jfischer-no removed the DNM This PR should not be merged (Do Not Merge) label Jan 9, 2023
LOG_DBG("ep 0x%02x buf busy", cfg->addr);
if (unlikely(usbfsotg_bd_is_busy(bd))) {
LOG_ERR("ep 0x%02x buf busy", cfg->addr);
__ASSERT_NO_MSG(false);
Copy link

Choose a reason for hiding this comment

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

Then I would prefer the assert to be moved before the if, e.g. __ASSERT_NO_MSG(!usbfsotg_bd_is_busy(bd));

@carlescufi carlescufi merged commit b5bfd3b into zephyrproject-rtos:main Jan 11, 2023
@jfischer-no jfischer-no deleted the pr-udc-follow-up branch January 11, 2023 16:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Drivers area: USB Universal Serial Bus Experimental Experimental features not enabled by default
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants