Commit 266deeea authored by Niklas Schnelle's avatar Niklas Schnelle Committed by David S. Miller
Browse files

s390/ism: Do not unregister clients with registered DMBs



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: 89e7d2ba ("net/ism: Add new API for client registration")
Signed-off-by: default avatarNiklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 76631ffa
Loading
Loading
Loading
Loading
+13 −10
Original line number Diff line number Diff line
@@ -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);