/* Cancel these to avoid queueing non-chained pending work */
        hci_dev_set_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
+       /* Wait for
+        *
+        *    if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
+        *        queue_delayed_work(&hdev->{cmd,ncmd}_timer)
+        *
+        * inside RCU section to see the flag or complete scheduling.
+        */
+       synchronize_rcu();
+       /* Explicitly cancel works in case scheduled after setting the flag. */
        cancel_delayed_work(&hdev->cmd_timer);
        cancel_delayed_work(&hdev->ncmd_timer);
 
                        if (res < 0)
                                __hci_cmd_sync_cancel(hdev, -res);
 
+                       rcu_read_lock();
                        if (test_bit(HCI_RESET, &hdev->flags) ||
                            hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
                                cancel_delayed_work(&hdev->cmd_timer);
                        else
-                               schedule_delayed_work(&hdev->cmd_timer,
-                                                     HCI_CMD_TIMEOUT);
+                               queue_delayed_work(hdev->workqueue, &hdev->cmd_timer,
+                                                  HCI_CMD_TIMEOUT);
+                       rcu_read_unlock();
                } else {
                        skb_queue_head(&hdev->cmd_q, skb);
                        queue_work(hdev->workqueue, &hdev->cmd_work);
 
 {
        cancel_delayed_work(&hdev->cmd_timer);
 
+       rcu_read_lock();
        if (!test_bit(HCI_RESET, &hdev->flags)) {
                if (ncmd) {
                        cancel_delayed_work(&hdev->ncmd_timer);
                        atomic_set(&hdev->cmd_cnt, 1);
                } else {
                        if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
-                               schedule_delayed_work(&hdev->ncmd_timer,
-                                                     HCI_NCMD_TIMEOUT);
+                               queue_delayed_work(hdev->workqueue, &hdev->ncmd_timer,
+                                                  HCI_NCMD_TIMEOUT);
                }
        }
+       rcu_read_unlock();
 }
 
 static u8 hci_cc_le_read_buffer_size_v2(struct hci_dev *hdev, void *data,