static int long_term_keys_show(struct seq_file *f, void *ptr)
 {
        struct hci_dev *hdev = f->private;
-       struct list_head *p, *n;
+       struct smp_ltk *ltk;
 
-       hci_dev_lock(hdev);
-       list_for_each_safe(p, n, &hdev->long_term_keys) {
-               struct smp_ltk *ltk = list_entry(p, struct smp_ltk, list);
+       rcu_read_lock();
+       list_for_each_entry_rcu(ltk, &hdev->long_term_keys, list)
                seq_printf(f, "%pMR (type %u) %u 0x%02x %u %.4x %.16llx %*phN\n",
                           <k->bdaddr, ltk->bdaddr_type, ltk->authenticated,
                           ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv),
                           __le64_to_cpu(ltk->rand), 16, ltk->val);
-       }
-       hci_dev_unlock(hdev);
+       rcu_read_unlock();
 
        return 0;
 }
 
 void hci_smp_ltks_clear(struct hci_dev *hdev)
 {
-       struct smp_ltk *k, *tmp;
+       struct smp_ltk *k;
 
-       list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
-               list_del(&k->list);
-               kfree(k);
+       list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
+               list_del_rcu(&k->list);
+               kfree_rcu(k, rcu);
        }
 }
 
 {
        struct smp_ltk *k;
 
-       list_for_each_entry(k, &hdev->long_term_keys, list) {
+       rcu_read_lock();
+       list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
                if (k->ediv != ediv || k->rand != rand)
                        continue;
 
                if (ltk_role(k->type) != role)
                        continue;
 
+               rcu_read_unlock();
                return k;
        }
+       rcu_read_unlock();
 
        return NULL;
 }
 {
        struct smp_ltk *k;
 
-       list_for_each_entry(k, &hdev->long_term_keys, list)
+       rcu_read_lock();
+       list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
                if (addr_type == k->bdaddr_type &&
                    bacmp(bdaddr, &k->bdaddr) == 0 &&
-                   ltk_role(k->type) == role)
+                   ltk_role(k->type) == role) {
+                       rcu_read_unlock();
                        return k;
+               }
+       }
+       rcu_read_unlock();
 
        return NULL;
 }
                key = kzalloc(sizeof(*key), GFP_KERNEL);
                if (!key)
                        return NULL;
-               list_add(&key->list, &hdev->long_term_keys);
+               list_add_rcu(&key->list, &hdev->long_term_keys);
        }
 
        bacpy(&key->bdaddr, bdaddr);
 
 int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type)
 {
-       struct smp_ltk *k, *tmp;
+       struct smp_ltk *k;
        int removed = 0;
 
-       list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) {
+       list_for_each_entry_rcu(k, &hdev->long_term_keys, list) {
                if (bacmp(bdaddr, &k->bdaddr) || k->bdaddr_type != bdaddr_type)
                        continue;
 
                BT_DBG("%s removing %pMR", hdev->name, bdaddr);
 
-               list_del(&k->list);
-               kfree(k);
+               list_del_rcu(&k->list);
+               kfree_rcu(k, rcu);
                removed++;
        }
 
 
        /* If pairing failed clean up any keys we might have */
        if (!complete) {
                if (smp->ltk) {
-                       list_del(&smp->ltk->list);
-                       kfree(smp->ltk);
+                       list_del_rcu(&smp->ltk->list);
+                       kfree_rcu(smp->ltk, rcu);
                }
 
                if (smp->slave_ltk) {
-                       list_del(&smp->slave_ltk->list);
-                       kfree(smp->slave_ltk);
+                       list_del_rcu(&smp->slave_ltk->list);
+                       kfree_rcu(smp->slave_ltk, rcu);
                }
 
                if (smp->remote_irk) {
 
        skb_pull(skb, sizeof(*rp));
 
-       hci_dev_lock(hdev);
        authenticated = (hcon->sec_level == BT_SECURITY_HIGH);
        ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, SMP_LTK,
                          authenticated, smp->tk, smp->enc_key_size,
        smp->ltk = ltk;
        if (!(smp->remote_key_dist & KEY_DIST_MASK))
                smp_distribute_keys(smp);
-       hci_dev_unlock(hdev);
 
        return 0;
 }