Commit 09840f70 authored by Julian Wiedmann's avatar Julian Wiedmann Committed by Jakub Kicinski
Browse files

s390/qeth: reduce rtnl locking for switchdev events



call_switchdev_notifiers() doesn't require holding the RTNL lock since
commit ff5cf100 ("net: switchdev: Change notifier chain to be atomic").

We still need it for the "lost event" slow path, to avoid racing against
a concurrent .ndo_bridge_setlink().

Signed-off-by: default avatarJulian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: default avatarAlexandra Winter <wintera@linux.ibm.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent bd4bdeb4
Loading
Loading
Loading
Loading
+15 −18
Original line number Diff line number Diff line
@@ -737,8 +737,6 @@ static void qeth_l2_dev2br_an_set_cb(void *priv,
 *
 *	On enable, emits a series of address notifications for all
 *	currently registered hosts.
 *
 *	Must be called under rtnl_lock
 */
static int qeth_l2_dev2br_an_set(struct qeth_card *card, bool enable)
{
@@ -1289,16 +1287,19 @@ static void qeth_l2_dev2br_worker(struct work_struct *work)
	if (READ_ONCE(card->info.pnso_mode) == QETH_PNSO_NONE)
		goto free;

	if (data->ac_event.lost_event_mask) {
		/* Potential re-config in progress, try again later: */
		if (!rtnl_trylock()) {
			queue_delayed_work(card->event_wq, dwork,
					   msecs_to_jiffies(100));
			return;
		}
	if (!netif_device_present(card->dev))
		goto out_unlock;

	if (data->ac_event.lost_event_mask) {
		if (!netif_device_present(card->dev)) {
			rtnl_unlock();
			goto free;
		}

		QETH_DBF_MESSAGE(3,
				 "Address change notification overflow on device %x\n",
				 CARD_DEVID(card));
@@ -1328,6 +1329,8 @@ static void qeth_l2_dev2br_worker(struct work_struct *work)
					 "Address Notification resynced on device %x\n",
					 CARD_DEVID(card));
		}

		rtnl_unlock();
	} else {
		for (i = 0; i < data->ac_event.num_entries; i++) {
			struct qeth_ipacmd_addr_change_entry *entry =
@@ -1339,9 +1342,6 @@ static void qeth_l2_dev2br_worker(struct work_struct *work)
		}
	}

out_unlock:
	rtnl_unlock();

free:
	kfree(data);
}
@@ -2310,11 +2310,8 @@ static void qeth_l2_set_offline(struct qeth_card *card)
		card->state = CARD_STATE_DOWN;

	qeth_l2_set_pnso_mode(card, QETH_PNSO_NONE);
	if (priv->brport_features & BR_LEARNING_SYNC) {
		rtnl_lock();
	if (priv->brport_features & BR_LEARNING_SYNC)
		qeth_l2_dev2br_fdb_flush(card);
		rtnl_unlock();
	}
}

/* Returns zero if the command is successfully "consumed" */