Bluetooth: controller: Fix race in create connection cancel
Fix race conditional when create connection cancel is called and actually a connection did get setup while initiator is being stopped. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
34451a9970
commit
77cfd3cf52
4 changed files with 27 additions and 3 deletions
|
@ -59,6 +59,7 @@ struct lll_conn {
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
uint8_t initiated:1;
|
uint8_t initiated:1;
|
||||||
|
uint8_t cancelled:1;
|
||||||
} master;
|
} master;
|
||||||
#if defined(CONFIG_BT_PERIPHERAL)
|
#if defined(CONFIG_BT_PERIPHERAL)
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -12,7 +12,7 @@ struct lll_scan {
|
||||||
* check ull_conn_setup how it access the connection LLL
|
* check ull_conn_setup how it access the connection LLL
|
||||||
* context.
|
* context.
|
||||||
*/
|
*/
|
||||||
struct lll_conn *conn;
|
struct lll_conn *volatile conn;
|
||||||
|
|
||||||
uint8_t adv_addr[BDADDR_SIZE];
|
uint8_t adv_addr[BDADDR_SIZE];
|
||||||
uint32_t conn_win_offset_us;
|
uint32_t conn_win_offset_us;
|
||||||
|
|
|
@ -140,7 +140,9 @@ static int prepare_cb(struct lll_prepare_param *p)
|
||||||
/* Check if stopped (on connection establishment race between LLL and
|
/* Check if stopped (on connection establishment race between LLL and
|
||||||
* ULL.
|
* ULL.
|
||||||
*/
|
*/
|
||||||
if (unlikely(lll->conn && lll->conn->master.initiated)) {
|
if (unlikely(lll->conn &&
|
||||||
|
(lll->conn->master.initiated ||
|
||||||
|
lll->conn->master.cancelled))) {
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = lll_hfclock_off();
|
err = lll_hfclock_off();
|
||||||
|
@ -779,7 +781,7 @@ static inline int isr_rx_pdu(struct lll_scan *lll, struct pdu_adv *pdu_adv_rx,
|
||||||
if (0) {
|
if (0) {
|
||||||
#if defined(CONFIG_BT_CENTRAL)
|
#if defined(CONFIG_BT_CENTRAL)
|
||||||
/* Initiator */
|
/* Initiator */
|
||||||
} else if (lll->conn &&
|
} else if (lll->conn && !lll->conn->master.cancelled &&
|
||||||
isr_scan_init_check(lll, pdu_adv_rx, rl_idx)) {
|
isr_scan_init_check(lll, pdu_adv_rx, rl_idx)) {
|
||||||
struct lll_conn *lll_conn;
|
struct lll_conn *lll_conn;
|
||||||
struct node_rx_ftr *ftr;
|
struct node_rx_ftr *ftr;
|
||||||
|
|
|
@ -222,6 +222,7 @@ uint8_t ll_create_connection(uint16_t scan_interval, uint16_t scan_window,
|
||||||
conn_lll->data_chan_use = 0;
|
conn_lll->data_chan_use = 0;
|
||||||
conn_lll->role = 0;
|
conn_lll->role = 0;
|
||||||
conn_lll->master.initiated = 0;
|
conn_lll->master.initiated = 0;
|
||||||
|
conn_lll->master.cancelled = 0;
|
||||||
/* FIXME: END: Move to ULL? */
|
/* FIXME: END: Move to ULL? */
|
||||||
#if defined(CONFIG_BT_CTLR_CONN_META)
|
#if defined(CONFIG_BT_CTLR_CONN_META)
|
||||||
memset(&conn_lll->conn_meta, 0, sizeof(conn_lll->conn_meta));
|
memset(&conn_lll->conn_meta, 0, sizeof(conn_lll->conn_meta));
|
||||||
|
@ -428,8 +429,28 @@ uint8_t ll_connect_disable(void **rx)
|
||||||
scan_lll = &scan->lll;
|
scan_lll = &scan->lll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if initiator active */
|
||||||
conn_lll = scan_lll->conn;
|
conn_lll = scan_lll->conn;
|
||||||
if (!conn_lll) {
|
if (!conn_lll) {
|
||||||
|
/* Scanning not associated with initiation of a connection or
|
||||||
|
* connection setup already complete (was set to NULL in
|
||||||
|
* ull_master_setup), but HCI event not processed by host.
|
||||||
|
*/
|
||||||
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Indicate to LLL that a cancellation is requested */
|
||||||
|
conn_lll->master.cancelled = 1U;
|
||||||
|
cpu_dmb();
|
||||||
|
|
||||||
|
/* Check if connection was established under race condition, i.e.
|
||||||
|
* before the cancelled flag was set.
|
||||||
|
*/
|
||||||
|
conn_lll = scan_lll->conn;
|
||||||
|
if (!conn_lll) {
|
||||||
|
/* Connection setup completed on race condition with cancelled
|
||||||
|
* flag, before it was set.
|
||||||
|
*/
|
||||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue