Skip to content

Commit b13cead

Browse files
committed
Merge branch 'ionic-next'
Shannon Nelson says: ==================== ionic: queue and filter mgmt updates After a pair of simple code cleanups, we change the mac filter management to split the updates between the driver's filter list and the device's filter list so that we can keep the calls to dev_uc_sync() and dev_mc_sync() under the netif_addr_lock in ndo_set_rx_mode, and then sync the driver's list to the device later in the rx_mode work task. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 7fe2f1b + a0c007b commit b13cead

File tree

5 files changed

+285
-111
lines changed

5 files changed

+285
-111
lines changed

drivers/net/ethernet/pensando/ionic/ionic_dev.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ static void ionic_watchdog_cb(struct timer_list *t)
1515
{
1616
struct ionic *ionic = from_timer(ionic, t, watchdog_timer);
1717
struct ionic_lif *lif = ionic->lif;
18+
struct ionic_deferred_work *work;
1819
int hb;
1920

2021
mod_timer(&ionic->watchdog_timer,
@@ -31,6 +32,18 @@ static void ionic_watchdog_cb(struct timer_list *t)
3132
if (hb >= 0 &&
3233
!test_bit(IONIC_LIF_F_FW_RESET, lif->state))
3334
ionic_link_status_check_request(lif, CAN_NOT_SLEEP);
35+
36+
if (test_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state)) {
37+
work = kzalloc(sizeof(*work), GFP_ATOMIC);
38+
if (!work) {
39+
netdev_err(lif->netdev, "rxmode change dropped\n");
40+
return;
41+
}
42+
43+
work->type = IONIC_DW_TYPE_RX_MODE;
44+
netdev_dbg(lif->netdev, "deferred: rx_mode\n");
45+
ionic_lif_deferred_enqueue(&lif->deferred, work);
46+
}
3447
}
3548

3649
void ionic_init_devinfo(struct ionic *ionic)

drivers/net/ethernet/pensando/ionic/ionic_lif.c

Lines changed: 119 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,6 @@ static const u8 ionic_qtype_versions[IONIC_QTYPE_MAX] = {
3030
*/
3131
};
3232

33-
static void ionic_lif_rx_mode(struct ionic_lif *lif);
34-
static int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr);
35-
static int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr);
3633
static void ionic_link_status_check(struct ionic_lif *lif);
3734
static void ionic_lif_handle_fw_down(struct ionic_lif *lif);
3835
static void ionic_lif_handle_fw_up(struct ionic_lif *lif);
@@ -92,12 +89,6 @@ static void ionic_lif_deferred_work(struct work_struct *work)
9289
case IONIC_DW_TYPE_RX_MODE:
9390
ionic_lif_rx_mode(lif);
9491
break;
95-
case IONIC_DW_TYPE_RX_ADDR_ADD:
96-
ionic_lif_addr_add(lif, w->addr);
97-
break;
98-
case IONIC_DW_TYPE_RX_ADDR_DEL:
99-
ionic_lif_addr_del(lif, w->addr);
100-
break;
10192
case IONIC_DW_TYPE_LINK_STATUS:
10293
ionic_link_status_check(lif);
10394
break;
@@ -1078,7 +1069,11 @@ static int ionic_lif_add_hwstamp_rxfilt(struct ionic_lif *lif, u64 pkt_class)
10781069
if (err && err != -EEXIST)
10791070
return err;
10801071

1081-
return ionic_rx_filter_save(lif, 0, qid, 0, &ctx);
1072+
spin_lock_bh(&lif->rx_filters.lock);
1073+
err = ionic_rx_filter_save(lif, 0, qid, 0, &ctx, IONIC_FILTER_STATE_SYNCED);
1074+
spin_unlock_bh(&lif->rx_filters.lock);
1075+
1076+
return err;
10821077
}
10831078

10841079
int ionic_lif_set_hwstamp_rxfilt(struct ionic_lif *lif, u64 pkt_class)
@@ -1251,7 +1246,7 @@ void ionic_get_stats64(struct net_device *netdev,
12511246
ns->tx_errors = ns->tx_aborted_errors;
12521247
}
12531248

1254-
static int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr)
1249+
int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr)
12551250
{
12561251
struct ionic_admin_ctx ctx = {
12571252
.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
@@ -1261,27 +1256,82 @@ static int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr)
12611256
.match = cpu_to_le16(IONIC_RX_FILTER_MATCH_MAC),
12621257
},
12631258
};
1259+
int nfilters = le32_to_cpu(lif->identity->eth.max_ucast_filters);
1260+
bool mc = is_multicast_ether_addr(addr);
12641261
struct ionic_rx_filter *f;
1265-
int err;
1262+
int err = 0;
12661263

1267-
/* don't bother if we already have it */
12681264
spin_lock_bh(&lif->rx_filters.lock);
12691265
f = ionic_rx_filter_by_addr(lif, addr);
1266+
if (f) {
1267+
/* don't bother if we already have it and it is sync'd */
1268+
if (f->state == IONIC_FILTER_STATE_SYNCED) {
1269+
spin_unlock_bh(&lif->rx_filters.lock);
1270+
return 0;
1271+
}
1272+
1273+
/* mark preemptively as sync'd to block any parallel attempts */
1274+
f->state = IONIC_FILTER_STATE_SYNCED;
1275+
} else {
1276+
/* save as SYNCED to catch any DEL requests while processing */
1277+
memcpy(ctx.cmd.rx_filter_add.mac.addr, addr, ETH_ALEN);
1278+
err = ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx,
1279+
IONIC_FILTER_STATE_SYNCED);
1280+
}
12701281
spin_unlock_bh(&lif->rx_filters.lock);
1271-
if (f)
1272-
return 0;
1282+
if (err)
1283+
return err;
12731284

12741285
netdev_dbg(lif->netdev, "rx_filter add ADDR %pM\n", addr);
12751286

1276-
memcpy(ctx.cmd.rx_filter_add.mac.addr, addr, ETH_ALEN);
1277-
err = ionic_adminq_post_wait(lif, &ctx);
1278-
if (err && err != -EEXIST)
1279-
return err;
1287+
/* Don't bother with the write to FW if we know there's no room,
1288+
* we can try again on the next sync attempt.
1289+
*/
1290+
if ((lif->nucast + lif->nmcast) >= nfilters)
1291+
err = -ENOSPC;
1292+
else
1293+
err = ionic_adminq_post_wait(lif, &ctx);
12801294

1281-
return ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx);
1295+
spin_lock_bh(&lif->rx_filters.lock);
1296+
if (err && err != -EEXIST) {
1297+
/* set the state back to NEW so we can try again later */
1298+
f = ionic_rx_filter_by_addr(lif, addr);
1299+
if (f && f->state == IONIC_FILTER_STATE_SYNCED)
1300+
f->state = IONIC_FILTER_STATE_NEW;
1301+
1302+
spin_unlock_bh(&lif->rx_filters.lock);
1303+
1304+
if (err == -ENOSPC)
1305+
return 0;
1306+
else
1307+
return err;
1308+
}
1309+
1310+
if (mc)
1311+
lif->nmcast++;
1312+
else
1313+
lif->nucast++;
1314+
1315+
f = ionic_rx_filter_by_addr(lif, addr);
1316+
if (f && f->state == IONIC_FILTER_STATE_OLD) {
1317+
/* Someone requested a delete while we were adding
1318+
* so update the filter info with the results from the add
1319+
* and the data will be there for the delete on the next
1320+
* sync cycle.
1321+
*/
1322+
err = ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx,
1323+
IONIC_FILTER_STATE_OLD);
1324+
} else {
1325+
err = ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx,
1326+
IONIC_FILTER_STATE_SYNCED);
1327+
}
1328+
1329+
spin_unlock_bh(&lif->rx_filters.lock);
1330+
1331+
return err;
12821332
}
12831333

1284-
static int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr)
1334+
int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr)
12851335
{
12861336
struct ionic_admin_ctx ctx = {
12871337
.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
@@ -1291,6 +1341,7 @@ static int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr)
12911341
},
12921342
};
12931343
struct ionic_rx_filter *f;
1344+
int state;
12941345
int err;
12951346

12961347
spin_lock_bh(&lif->rx_filters.lock);
@@ -1303,65 +1354,37 @@ static int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr)
13031354
netdev_dbg(lif->netdev, "rx_filter del ADDR %pM (id %d)\n",
13041355
addr, f->filter_id);
13051356

1357+
state = f->state;
13061358
ctx.cmd.rx_filter_del.filter_id = cpu_to_le32(f->filter_id);
13071359
ionic_rx_filter_free(lif, f);
1308-
spin_unlock_bh(&lif->rx_filters.lock);
13091360

1310-
err = ionic_adminq_post_wait(lif, &ctx);
1311-
if (err && err != -EEXIST)
1312-
return err;
1361+
if (is_multicast_ether_addr(addr) && lif->nmcast)
1362+
lif->nmcast--;
1363+
else if (!is_multicast_ether_addr(addr) && lif->nucast)
1364+
lif->nucast--;
13131365

1314-
return 0;
1315-
}
1316-
1317-
static int ionic_lif_addr(struct ionic_lif *lif, const u8 *addr, bool add)
1318-
{
1319-
unsigned int nmfilters;
1320-
unsigned int nufilters;
1366+
spin_unlock_bh(&lif->rx_filters.lock);
13211367

1322-
if (add) {
1323-
/* Do we have space for this filter? We test the counters
1324-
* here before checking the need for deferral so that we
1325-
* can return an overflow error to the stack.
1326-
*/
1327-
nmfilters = le32_to_cpu(lif->identity->eth.max_mcast_filters);
1328-
nufilters = le32_to_cpu(lif->identity->eth.max_ucast_filters);
1329-
1330-
if ((is_multicast_ether_addr(addr) && lif->nmcast < nmfilters))
1331-
lif->nmcast++;
1332-
else if (!is_multicast_ether_addr(addr) &&
1333-
lif->nucast < nufilters)
1334-
lif->nucast++;
1335-
else
1336-
return -ENOSPC;
1337-
} else {
1338-
if (is_multicast_ether_addr(addr) && lif->nmcast)
1339-
lif->nmcast--;
1340-
else if (!is_multicast_ether_addr(addr) && lif->nucast)
1341-
lif->nucast--;
1368+
if (state != IONIC_FILTER_STATE_NEW) {
1369+
err = ionic_adminq_post_wait(lif, &ctx);
1370+
if (err && err != -EEXIST)
1371+
return err;
13421372
}
13431373

1344-
netdev_dbg(lif->netdev, "rx_filter %s %pM\n",
1345-
add ? "add" : "del", addr);
1346-
if (add)
1347-
return ionic_lif_addr_add(lif, addr);
1348-
else
1349-
return ionic_lif_addr_del(lif, addr);
1350-
13511374
return 0;
13521375
}
13531376

13541377
static int ionic_addr_add(struct net_device *netdev, const u8 *addr)
13551378
{
1356-
return ionic_lif_addr(netdev_priv(netdev), addr, ADD_ADDR);
1379+
return ionic_lif_list_addr(netdev_priv(netdev), addr, ADD_ADDR);
13571380
}
13581381

13591382
static int ionic_addr_del(struct net_device *netdev, const u8 *addr)
13601383
{
1361-
return ionic_lif_addr(netdev_priv(netdev), addr, DEL_ADDR);
1384+
return ionic_lif_list_addr(netdev_priv(netdev), addr, DEL_ADDR);
13621385
}
13631386

1364-
static void ionic_lif_rx_mode(struct ionic_lif *lif)
1387+
void ionic_lif_rx_mode(struct ionic_lif *lif)
13651388
{
13661389
struct net_device *netdev = lif->netdev;
13671390
unsigned int nfilters;
@@ -1382,32 +1405,26 @@ static void ionic_lif_rx_mode(struct ionic_lif *lif)
13821405
rx_mode |= (nd_flags & IFF_PROMISC) ? IONIC_RX_MODE_F_PROMISC : 0;
13831406
rx_mode |= (nd_flags & IFF_ALLMULTI) ? IONIC_RX_MODE_F_ALLMULTI : 0;
13841407

1385-
/* sync unicast addresses
1386-
* next check to see if we're in an overflow state
1408+
/* sync the mac filters */
1409+
ionic_rx_filter_sync(lif);
1410+
1411+
/* check for overflow state
13871412
* if so, we track that we overflowed and enable NIC PROMISC
13881413
* else if the overflow is set and not needed
13891414
* we remove our overflow flag and check the netdev flags
13901415
* to see if we can disable NIC PROMISC
13911416
*/
1392-
__dev_uc_sync(netdev, ionic_addr_add, ionic_addr_del);
13931417
nfilters = le32_to_cpu(lif->identity->eth.max_ucast_filters);
1394-
if (netdev_uc_count(netdev) + 1 > nfilters) {
1418+
if ((lif->nucast + lif->nmcast) >= nfilters) {
13951419
rx_mode |= IONIC_RX_MODE_F_PROMISC;
1420+
rx_mode |= IONIC_RX_MODE_F_ALLMULTI;
13961421
lif->uc_overflow = true;
1422+
lif->mc_overflow = true;
13971423
} else if (lif->uc_overflow) {
13981424
lif->uc_overflow = false;
1425+
lif->mc_overflow = false;
13991426
if (!(nd_flags & IFF_PROMISC))
14001427
rx_mode &= ~IONIC_RX_MODE_F_PROMISC;
1401-
}
1402-
1403-
/* same for multicast */
1404-
__dev_mc_sync(netdev, ionic_addr_add, ionic_addr_del);
1405-
nfilters = le32_to_cpu(lif->identity->eth.max_mcast_filters);
1406-
if (netdev_mc_count(netdev) > nfilters) {
1407-
rx_mode |= IONIC_RX_MODE_F_ALLMULTI;
1408-
lif->mc_overflow = true;
1409-
} else if (lif->mc_overflow) {
1410-
lif->mc_overflow = false;
14111428
if (!(nd_flags & IFF_ALLMULTI))
14121429
rx_mode &= ~IONIC_RX_MODE_F_ALLMULTI;
14131430
}
@@ -1450,28 +1467,26 @@ static void ionic_lif_rx_mode(struct ionic_lif *lif)
14501467
mutex_unlock(&lif->config_lock);
14511468
}
14521469

1453-
static void ionic_set_rx_mode(struct net_device *netdev, bool can_sleep)
1470+
static void ionic_ndo_set_rx_mode(struct net_device *netdev)
14541471
{
14551472
struct ionic_lif *lif = netdev_priv(netdev);
14561473
struct ionic_deferred_work *work;
14571474

1458-
if (!can_sleep) {
1459-
work = kzalloc(sizeof(*work), GFP_ATOMIC);
1460-
if (!work) {
1461-
netdev_err(lif->netdev, "rxmode change dropped\n");
1462-
return;
1463-
}
1464-
work->type = IONIC_DW_TYPE_RX_MODE;
1465-
netdev_dbg(lif->netdev, "deferred: rx_mode\n");
1466-
ionic_lif_deferred_enqueue(&lif->deferred, work);
1467-
} else {
1468-
ionic_lif_rx_mode(lif);
1469-
}
1470-
}
1475+
/* Sync the kernel filter list with the driver filter list */
1476+
__dev_uc_sync(netdev, ionic_addr_add, ionic_addr_del);
1477+
__dev_mc_sync(netdev, ionic_addr_add, ionic_addr_del);
14711478

1472-
static void ionic_ndo_set_rx_mode(struct net_device *netdev)
1473-
{
1474-
ionic_set_rx_mode(netdev, CAN_NOT_SLEEP);
1479+
/* Shove off the rest of the rxmode work to the work task
1480+
* which will include syncing the filters to the firmware.
1481+
*/
1482+
work = kzalloc(sizeof(*work), GFP_ATOMIC);
1483+
if (!work) {
1484+
netdev_err(lif->netdev, "rxmode change dropped\n");
1485+
return;
1486+
}
1487+
work->type = IONIC_DW_TYPE_RX_MODE;
1488+
netdev_dbg(lif->netdev, "deferred: rx_mode\n");
1489+
ionic_lif_deferred_enqueue(&lif->deferred, work);
14751490
}
14761491

14771492
static __le64 ionic_netdev_features_to_nic(netdev_features_t features)
@@ -1692,13 +1707,13 @@ static int ionic_set_mac_address(struct net_device *netdev, void *sa)
16921707
if (!is_zero_ether_addr(netdev->dev_addr)) {
16931708
netdev_info(netdev, "deleting mac addr %pM\n",
16941709
netdev->dev_addr);
1695-
ionic_addr_del(netdev, netdev->dev_addr);
1710+
ionic_lif_addr_del(netdev_priv(netdev), netdev->dev_addr);
16961711
}
16971712

16981713
eth_commit_mac_addr_change(netdev, addr);
16991714
netdev_info(netdev, "updating mac addr %pM\n", mac);
17001715

1701-
return ionic_addr_add(netdev, mac);
1716+
return ionic_lif_addr_add(netdev_priv(netdev), mac);
17021717
}
17031718

17041719
static void ionic_stop_queues_reconfig(struct ionic_lif *lif)
@@ -1804,7 +1819,12 @@ static int ionic_vlan_rx_add_vid(struct net_device *netdev, __be16 proto,
18041819
if (err)
18051820
return err;
18061821

1807-
return ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx);
1822+
spin_lock_bh(&lif->rx_filters.lock);
1823+
err = ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx,
1824+
IONIC_FILTER_STATE_SYNCED);
1825+
spin_unlock_bh(&lif->rx_filters.lock);
1826+
1827+
return err;
18081828
}
18091829

18101830
static int ionic_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto,
@@ -2107,7 +2127,7 @@ static int ionic_txrx_init(struct ionic_lif *lif)
21072127
if (lif->netdev->features & NETIF_F_RXHASH)
21082128
ionic_lif_rss_init(lif);
21092129

2110-
ionic_set_rx_mode(lif->netdev, CAN_SLEEP);
2130+
ionic_lif_rx_mode(lif);
21112131

21122132
return 0;
21132133

@@ -3195,7 +3215,7 @@ static int ionic_station_set(struct ionic_lif *lif)
31953215
*/
31963216
if (!ether_addr_equal(ctx.comp.lif_getattr.mac,
31973217
netdev->dev_addr))
3198-
ionic_lif_addr(lif, netdev->dev_addr, ADD_ADDR);
3218+
ionic_lif_addr_add(lif, netdev->dev_addr);
31993219
} else {
32003220
/* Update the netdev mac with the device's mac */
32013221
memcpy(addr.sa_data, ctx.comp.lif_getattr.mac, netdev->addr_len);
@@ -3212,7 +3232,7 @@ static int ionic_station_set(struct ionic_lif *lif)
32123232

32133233
netdev_dbg(lif->netdev, "adding station MAC addr %pM\n",
32143234
netdev->dev_addr);
3215-
ionic_lif_addr(lif, netdev->dev_addr, ADD_ADDR);
3235+
ionic_lif_addr_add(lif, netdev->dev_addr);
32163236

32173237
return 0;
32183238
}

0 commit comments

Comments
 (0)