summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorJulian Wiedmann <jwi@linux.ibm.com>2020-11-17 17:15:13 +0100
committerJakub Kicinski <kuba@kernel.org>2020-11-18 17:34:18 -0800
commit09840f70b088df1ec24f9b4e345983e7d5f63628 (patch)
treee0aaa91ea7ac0bb16ede664523070471dd35d6cd /drivers
parentbd4bdeb4f29027199c68104fbdfa07ad45390cc1 (diff)
s390/qeth: reduce rtnl locking for switchdev events
call_switchdev_notifiers() doesn't require holding the RTNL lock since commit ff5cf100110c ("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: Julian Wiedmann <jwi@linux.ibm.com> Reviewed-by: Alexandra Winter <wintera@linux.ibm.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/net/qeth_l2_main.c33
1 files changed, 15 insertions, 18 deletions
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 28f6dda95736..daeb837abec3 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -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;
- /* 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) {
+ /* 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)) {
+ 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" */