Open jori-nordic opened 3 months ago
A simple solution for this approach could be something like this:
static void attempt_tx(struct k_work *work)
{
...
err = bt_gatt_notify(...);
if (err == -ENOMEM) {
LOG_WRN("No buffers available. Skipping until resources are available");
return;
}
}
static void buf_freed_cb(...)
{
k_work_submit(&attempt_tx_work);
}
/** Assume this is provided to the BT host sometime during init */
struct bt_gatt_cb gatt_callbacks = {
...
.att_buf_freed = buf_freed_cb,
};
I don't love how racey this approach is, though, (basically a hit or miss: you could have another app starve the resources every time for another service/app like this), but it's the simplest thing I can think of now.
Some alternative ideas of how could this be done differently to make it more predictable:
@jori-nordic @alwa-nordic @jhedberg Let me know your thoughts and hopefully we can come up with an agreed solution. If you guys agree, either me or @cx-anuj-pathak could take on this endeavor.
Bluetooth WG meeting
@jori-nordic @alwa-nordic @jhedberg since you were not present in the meeting today we will postpone this topic until next week
Bluetooth WG:
Since https://github.com/zephyrproject-rtos/zephyr/pull/71697 got merged, buffer allocations can and will fail on the system workqueue.
Problem: The host owns the buffer pools for sending commands and data to the controller. The application cannot know when to schedule the allocation in order to be successful.
Proposal: Add an API, a signal or callback, that a host TX buffer has been freed. Applications can then use this callback not to allocate directly, but rather to schedule an allocation for outgoing data or commands.