s390/ism: Do not unregister clients with registered DMBs
authorNiklas Schnelle <schnelle@linux.ibm.com>
Fri, 7 Jul 2023 10:56:22 +0000 (12:56 +0200)
committerDavid S. Miller <davem@davemloft.net>
Sat, 8 Jul 2023 09:07:14 +0000 (10:07 +0100)
When ism_unregister_client() is called but the client still has DMBs
registered it returns -EBUSY and prints an error. This only happens
after the client has already been unregistered however. This is
unexpected as the unregister claims to have failed. Furthermore as this
implies a client bug a WARN() is more appropriate. Thus move the
deregistration after the check and use WARN().

Fixes: 89e7d2ba61b7 ("net/ism: Add new API for client registration")
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/s390/net/ism_drv.c

index 54091b7..6df7f37 100644 (file)
@@ -96,29 +96,32 @@ int ism_unregister_client(struct ism_client *client)
        int rc = 0;
 
        mutex_lock(&ism_dev_list.mutex);
-       mutex_lock(&clients_lock);
-       clients[client->id] = NULL;
-       if (client->id + 1 == max_client)
-               max_client--;
-       mutex_unlock(&clients_lock);
        list_for_each_entry(ism, &ism_dev_list.list, list) {
                spin_lock_irqsave(&ism->lock, flags);
                /* Stop forwarding IRQs and events */
                ism->subs[client->id] = NULL;
                for (int i = 0; i < ISM_NR_DMBS; ++i) {
                        if (ism->sba_client_arr[i] == client->id) {
-                               pr_err("%s: attempt to unregister client '%s'"
-                                      "with registered dmb(s)\n", __func__,
-                                      client->name);
+                               WARN(1, "%s: attempt to unregister '%s' with registered dmb(s)\n",
+                                    __func__, client->name);
                                rc = -EBUSY;
-                               goto out;
+                               goto err_reg_dmb;
                        }
                }
                spin_unlock_irqrestore(&ism->lock, flags);
        }
-out:
        mutex_unlock(&ism_dev_list.mutex);
 
+       mutex_lock(&clients_lock);
+       clients[client->id] = NULL;
+       if (client->id + 1 == max_client)
+               max_client--;
+       mutex_unlock(&clients_lock);
+       return rc;
+
+err_reg_dmb:
+       spin_unlock_irqrestore(&ism->lock, flags);
+       mutex_unlock(&ism_dev_list.mutex);
        return rc;
 }
 EXPORT_SYMBOL_GPL(ism_unregister_client);