-
Notifications
You must be signed in to change notification settings - Fork 6.9k
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
bluetooth: buf: Add a callback for freed buffer in rx pool #81646
bluetooth: buf: Add a callback for freed buffer in rx pool #81646
Conversation
4dc4ff3
to
f9e1bef
Compare
We have gotten feedback about lack of thread safety in the Host. I think we should make sure all code we add is thread safe, or have the API documentation say exactly what to synchronize on to safely call the API, since we have committed to this. I have sketched some (compile time tested) changes at alwa-nordic@03b0d39. In the sketch, I chose to make it thread safe. I also considered that an application may collide with the driver and both will call the Apart from this, I removed the dependency injection from buf.c to iso.c and instead make iso.c call buf.c directly. I think this simplifies the code (at the cost of adding a circular dependency). |
I think we can assign single-bit values to |
Can you elaborate why we want |
Thread safe is the default, as stated in documentation. The alternative is to document the API's thread safety aspects. It may be right that this API does not have to be thread safe, I'm not arguing for or against this right now, but then the documentation of this API has to do some heavy lifting. |
Food for thought:
Without synchronization with |
If you can come up with the scenario where this function is called from multiple contexts then I'll make it thread safe. But from my understanding there is only a single user of this API. More other, only 1 callback can be set, so calling this function from different contexts means that there is misunderstanding of the purpose of this API, which in my understanding should be called once at the initialization phase. Therefore, I'd rather update the API description. |
With this I fully agree. I'll make the callback thread safe. |
I think I disagree with this suggestion precisely because it creates dependency of iso.c on buf.c. The dependency injection from buf.c to iso.c already exists. |
f9e1bef
to
a41ae5b
Compare
I don't have any scenario in mind. I am in agreement with you if we update the API documentation so the user is informed about when it's safe to call the API, and when it's safe to free the callback. I would like any assumptions we make about our own code to be documented and treated like internal API. Let's see what assumptions we need to make, if any. We could put it in code comments or create an architecture design document.
It's a good idea to document this requirement on |
b02b581
to
e203e24
Compare
tests/bluetooth/buf/src/main.c
Outdated
zassert_equal(test_vector[i].exp_type_mask, freed_buf_type, | ||
"Unexpected buffer type"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not test for equality, but just the expected bit. Extra bits should not fail this test, right? Like for hci_raw that uses the same buffer pool for all pool types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assuming the above is done, exp_type_mask
in the test vector is over-fitting to the implementation. We should get rid of exp_type_mask
and instead just check that type
bit is set in the callback-provided value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather add a dedicated test for hci_raw that checks that it passes all 3 types. Then we know exactly what each variant returns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems we want to test different things.
I want a test which accepts any implementation that follows the API specification. You want a test that fully specifies the behavior of the implementation with no wiggle room.
Both types of tests are useful. Your type is useful for enforcing strict refactoring without behavior change. My type is useful for testing multiple implementations or a re-implementation that takes advantage of the wiggle room in the specification.
Maybe we should have both tests? One test for the API, and one for each fully-specified implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then I suggest a different test where this wiggle room is not needed: 5f1f5d9
- native_sim | ||
- native_sim/native/64 | ||
integration_platforms: | ||
- native_sim |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add extra_configs here as well to make sure the config is as we expect, no matter what the default is?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, though if we check the exact returned value, this may not be needed. I added CONFIG_BT_HCI_ACL_FLOW_CONTROL=y
any way.
e930b25
to
88ca011
Compare
88ca011
to
e01cbc8
Compare
@PavelVPV there's a conflict that needs resolving - please rebase. |
This allows to combine several types in a single value. Signed-off-by: Pavel Vasilyev <[email protected]>
The Bluetooth data buffer API currently lacks a mechanism to notify when a buffer is freed in the RX pool. This limitation forces HCI drivers to adopt inefficient workarounds to manage buffer allocation. HCI drivers face two suboptimal options: - Blocking calls: Use bt_buf_get_rx with K_FOREVER, which blocks the execution context until a buffer becomes available. - Polling: Repeatedly call bt_buf_get_rx with K_NO_WAIT, which increases CPU load and reduces efficiency. This commit introduces a callback mechanism that is triggered each time a buffer is freed in the RX pool. With this feature, HCI drivers can: - Call bt_buf_get_rx with K_NO_WAIT. - Wait for the callback notification if a NULL buffer is returned, avoiding unnecessary polling. The new callback improves efficiency by enabling event-driven behavior for buffer management, reducing CPU overhead while maintaining responsiveness. Signed-off-by: Pavel Vasilyev <[email protected]>
This commit adds a unit test that checks the freed buffer callback of the bluetooth data buffer API. Signed-off-by: Pavel Vasilyev <[email protected]>
e01cbc8
to
2e32342
Compare
Done |
Because enum bt_buf_type is now a bitmap, and struct bt_buf_data.type is uint8_t, and in the foreseeable future, bt_buf_type will increase, should we consider changing struct bt_buf_data.type to uint32_t? |
The Bluetooth data buffer API currently lacks a mechanism to notify when
a buffer is freed in the RX pool. This limitation forces HCI drivers to
adopt inefficient workarounds to manage buffer allocation.
HCI drivers face two suboptimal options:
execution context until a buffer becomes available.
CPU load and reduces efficiency.
This commit introduces a callback mechanism that is triggered each time
a buffer is freed in the RX pool. With this feature, HCI drivers can:
avoiding unnecessary polling.
The new callback improves efficiency by enabling event-driven behavior
for buffer management, reducing CPU overhead while maintaining
responsiveness.