mctp_dev_release_key(key->dev, key);
        spin_unlock_irqrestore(&key->lock, flags);
 
-       hlist_del(&key->hlist);
-       hlist_del(&key->sklist);
-
-       /* unref for the lists */
-       mctp_key_unref(key);
+       if (!hlist_unhashed(&key->hlist)) {
+               hlist_del_init(&key->hlist);
+               hlist_del_init(&key->sklist);
+               /* unref for the lists */
+               mctp_key_unref(key);
+       }
 
        kfree_skb(skb);
 }
 
        ctl.tag = tag | MCTP_TAG_OWNER | MCTP_TAG_PREALLOC;
        if (copy_to_user((void __user *)arg, &ctl, sizeof(ctl))) {
-               spin_lock_irqsave(&key->lock, flags);
-               __mctp_key_remove(key, net, flags, MCTP_TRACE_KEY_DROPPED);
+               unsigned long fl2;
+               /* Unwind our key allocation: the keys list lock needs to be
+                * taken before the individual key locks, and we need a valid
+                * flags value (fl2) to pass to __mctp_key_remove, hence the
+                * second spin_lock_irqsave() rather than a plain spin_lock().
+                */
+               spin_lock_irqsave(&net->mctp.keys_lock, flags);
+               spin_lock_irqsave(&key->lock, fl2);
+               __mctp_key_remove(key, net, fl2, MCTP_TRACE_KEY_DROPPED);
                mctp_key_unref(key);
+               spin_unlock_irqrestore(&net->mctp.keys_lock, flags);
                return -EFAULT;
        }
 
 
 
        if (!key->manual_alloc) {
                spin_lock_irqsave(&net->mctp.keys_lock, flags);
-               hlist_del(&key->hlist);
-               hlist_del(&key->sklist);
+               if (!hlist_unhashed(&key->hlist)) {
+                       hlist_del_init(&key->hlist);
+                       hlist_del_init(&key->sklist);
+                       mctp_key_unref(key);
+               }
                spin_unlock_irqrestore(&net->mctp.keys_lock, flags);
-
-               /* unref for the lists */
-               mctp_key_unref(key);
        }
 
        /* and one for the local reference */