host: Always wake tx queues on rx of num-cmp-pkts

Prior to commit: The code assumed that a transmission could stall for
only one reason: the controller cannot accommodate any more ACL data
packets.  When the host received a num-complered-packets event, it would
only try to unstall each connection if all the controller's data buffers
were previously used.

It turns out there is a second way that a host connection can stall:
mbuf exhaustion. If the host is unable to fragment an outgoing L2CAP
packet into ACL data packets due to a lack of mbufs, the transmission
stalls.

This commit causes the host to wake up its connections every time it
receives a num-completed-packets event. It does this even if the
controller still had capacity for more ACL data packets. If a host
connection is stalled due to mbuf exhaustion, the controller will only
send the next num-completed-packets event after it has freed the mbuf
from the designated ACL fragment pool (ble_hs_hci_frag_mbuf_pool). In
other words, we are guaranteed to receive a num-completed-packets event
whenever a transmission has stalled, regardless of the cause.
This commit is contained in:
Christopher Collins
2019-04-02 08:10:19 -07:00
committed by ccollins476ad
parent 6595d33810
commit 4a82ef412e
+2 -15
View File
@@ -226,7 +226,6 @@ ble_hs_hci_evt_num_completed_pkts(uint8_t event_code, uint8_t *data, int len)
uint16_t num_pkts;
uint16_t handle;
uint8_t num_handles;
int tx_outstanding;
int off;
int i;
@@ -242,13 +241,6 @@ ble_hs_hci_evt_num_completed_pkts(uint8_t event_code, uint8_t *data, int len)
}
off++;
/* If we were previously blocked due to controller buffer exhaustion, and
* this event indicates that some buffers have been freed, then the host
* needs to resume transmitting. `tx_outstanding` keeps track of whether
* this is the case.
*/
tx_outstanding = 0;
for (i = 0; i < num_handles; i++) {
handle = get_le16(data + off);
num_pkts = get_le16(data + off + 2);
@@ -264,19 +256,14 @@ ble_hs_hci_evt_num_completed_pkts(uint8_t event_code, uint8_t *data, int len)
conn->bhc_outstanding_pkts -= num_pkts;
}
if (ble_hs_hci_avail_pkts == 0) {
tx_outstanding = 1;
}
ble_hs_hci_add_avail_pkts(num_pkts);
}
ble_hs_unlock();
}
}
if (tx_outstanding) {
ble_hs_wakeup_tx();
}
/* If any transmissions have stalled, wake them up now. */
ble_hs_wakeup_tx();
return 0;
}