--- x/include/net/bluetooth/hci_core.h +++ y/include/net/bluetooth/hci_core.h @@ -511,6 +511,7 @@ struct hci_dev { struct sk_buff *recv_event; struct mutex req_lock; + struct mutex rx_lock; wait_queue_head_t req_wait_q; __u32 req_status; __u32 req_result; --- x/net/bluetooth/hci_core.c +++ y/net/bluetooth/hci_core.c @@ -2507,6 +2507,7 @@ struct hci_dev *hci_alloc_dev_priv(int s mutex_init(&hdev->lock); mutex_init(&hdev->req_lock); + mutex_init(&hdev->rx_lock); ida_init(&hdev->unset_handle_ida); @@ -3977,6 +3978,7 @@ static void hci_rx_work(struct work_stru BT_DBG("%s", hdev->name); + mutex_lock(&hdev->rx_lock); /* The kcov_remote functions used for collecting packet parsing * coverage information from this background thread and associate * the coverage with the syscall's thread which originally injected @@ -4043,6 +4045,7 @@ static void hci_rx_work(struct work_stru break; } } + mutex_unlock(&hdev->rx_lock); } static void hci_send_cmd_sync(struct hci_dev *hdev, struct sk_buff *skb) --- x/net/bluetooth/hci_sync.c +++ y/net/bluetooth/hci_sync.c @@ -325,9 +325,11 @@ static void hci_cmd_sync_work(struct wor int err; hci_req_sync_lock(hdev); + mutex_lock(&hdev->rx_lock); err = entry->func(hdev, entry->data); if (entry->destroy) entry->destroy(hdev, entry->data, err); + mutex_unlock(&hdev->rx_lock); hci_req_sync_unlock(hdev); }