Skip to content

Commit 5aa1959

Browse files
committed
Merge branch 'ionic-fixes'
Shannon Nelson says: ==================== ionic: bug fixes Fix a thread race in rx_mode, remove unnecessary log message, fix dynamic coalescing issues, and count all csum_none cases. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 0506c93 + f07f981 commit 5aa1959

File tree

4 files changed

+132
-127
lines changed

4 files changed

+132
-127
lines changed

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

Lines changed: 96 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ static const u8 ionic_qtype_versions[IONIC_QTYPE_MAX] = {
2929
*/
3030
};
3131

32-
static void ionic_lif_rx_mode(struct ionic_lif *lif, unsigned int rx_mode);
32+
static void ionic_lif_rx_mode(struct ionic_lif *lif);
3333
static int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr);
3434
static int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr);
3535
static void ionic_link_status_check(struct ionic_lif *lif);
@@ -53,7 +53,19 @@ static void ionic_dim_work(struct work_struct *work)
5353
cur_moder = net_dim_get_rx_moderation(dim->mode, dim->profile_ix);
5454
qcq = container_of(dim, struct ionic_qcq, dim);
5555
new_coal = ionic_coal_usec_to_hw(qcq->q.lif->ionic, cur_moder.usec);
56-
qcq->intr.dim_coal_hw = new_coal ? new_coal : 1;
56+
new_coal = new_coal ? new_coal : 1;
57+
58+
if (qcq->intr.dim_coal_hw != new_coal) {
59+
unsigned int qi = qcq->cq.bound_q->index;
60+
struct ionic_lif *lif = qcq->q.lif;
61+
62+
qcq->intr.dim_coal_hw = new_coal;
63+
64+
ionic_intr_coal_init(lif->ionic->idev.intr_ctrl,
65+
lif->rxqcqs[qi]->intr.index,
66+
qcq->intr.dim_coal_hw);
67+
}
68+
5769
dim->state = DIM_START_MEASURE;
5870
}
5971

@@ -77,7 +89,7 @@ static void ionic_lif_deferred_work(struct work_struct *work)
7789

7890
switch (w->type) {
7991
case IONIC_DW_TYPE_RX_MODE:
80-
ionic_lif_rx_mode(lif, w->rx_mode);
92+
ionic_lif_rx_mode(lif);
8193
break;
8294
case IONIC_DW_TYPE_RX_ADDR_ADD:
8395
ionic_lif_addr_add(lif, w->addr);
@@ -1301,10 +1313,8 @@ static int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr)
13011313
return 0;
13021314
}
13031315

1304-
static int ionic_lif_addr(struct ionic_lif *lif, const u8 *addr, bool add,
1305-
bool can_sleep)
1316+
static int ionic_lif_addr(struct ionic_lif *lif, const u8 *addr, bool add)
13061317
{
1307-
struct ionic_deferred_work *work;
13081318
unsigned int nmfilters;
13091319
unsigned int nufilters;
13101320

@@ -1330,97 +1340,46 @@ static int ionic_lif_addr(struct ionic_lif *lif, const u8 *addr, bool add,
13301340
lif->nucast--;
13311341
}
13321342

1333-
if (!can_sleep) {
1334-
work = kzalloc(sizeof(*work), GFP_ATOMIC);
1335-
if (!work)
1336-
return -ENOMEM;
1337-
work->type = add ? IONIC_DW_TYPE_RX_ADDR_ADD :
1338-
IONIC_DW_TYPE_RX_ADDR_DEL;
1339-
memcpy(work->addr, addr, ETH_ALEN);
1340-
netdev_dbg(lif->netdev, "deferred: rx_filter %s %pM\n",
1341-
add ? "add" : "del", addr);
1342-
ionic_lif_deferred_enqueue(&lif->deferred, work);
1343-
} else {
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-
}
1343+
netdev_dbg(lif->netdev, "rx_filter %s %pM\n",
1344+
add ? "add" : "del", addr);
1345+
if (add)
1346+
return ionic_lif_addr_add(lif, addr);
1347+
else
1348+
return ionic_lif_addr_del(lif, addr);
13511349

13521350
return 0;
13531351
}
13541352

13551353
static int ionic_addr_add(struct net_device *netdev, const u8 *addr)
13561354
{
1357-
return ionic_lif_addr(netdev_priv(netdev), addr, ADD_ADDR, CAN_SLEEP);
1358-
}
1359-
1360-
static int ionic_ndo_addr_add(struct net_device *netdev, const u8 *addr)
1361-
{
1362-
return ionic_lif_addr(netdev_priv(netdev), addr, ADD_ADDR, CAN_NOT_SLEEP);
1355+
return ionic_lif_addr(netdev_priv(netdev), addr, ADD_ADDR);
13631356
}
13641357

13651358
static int ionic_addr_del(struct net_device *netdev, const u8 *addr)
13661359
{
1367-
return ionic_lif_addr(netdev_priv(netdev), addr, DEL_ADDR, CAN_SLEEP);
1360+
return ionic_lif_addr(netdev_priv(netdev), addr, DEL_ADDR);
13681361
}
13691362

1370-
static int ionic_ndo_addr_del(struct net_device *netdev, const u8 *addr)
1363+
static void ionic_lif_rx_mode(struct ionic_lif *lif)
13711364
{
1372-
return ionic_lif_addr(netdev_priv(netdev), addr, DEL_ADDR, CAN_NOT_SLEEP);
1373-
}
1374-
1375-
static void ionic_lif_rx_mode(struct ionic_lif *lif, unsigned int rx_mode)
1376-
{
1377-
struct ionic_admin_ctx ctx = {
1378-
.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
1379-
.cmd.rx_mode_set = {
1380-
.opcode = IONIC_CMD_RX_MODE_SET,
1381-
.lif_index = cpu_to_le16(lif->index),
1382-
.rx_mode = cpu_to_le16(rx_mode),
1383-
},
1384-
};
1365+
struct net_device *netdev = lif->netdev;
1366+
unsigned int nfilters;
1367+
unsigned int nd_flags;
13851368
char buf[128];
1386-
int err;
1369+
u16 rx_mode;
13871370
int i;
13881371
#define REMAIN(__x) (sizeof(buf) - (__x))
13891372

1390-
i = scnprintf(buf, sizeof(buf), "rx_mode 0x%04x -> 0x%04x:",
1391-
lif->rx_mode, rx_mode);
1392-
if (rx_mode & IONIC_RX_MODE_F_UNICAST)
1393-
i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_UNICAST");
1394-
if (rx_mode & IONIC_RX_MODE_F_MULTICAST)
1395-
i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_MULTICAST");
1396-
if (rx_mode & IONIC_RX_MODE_F_BROADCAST)
1397-
i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_BROADCAST");
1398-
if (rx_mode & IONIC_RX_MODE_F_PROMISC)
1399-
i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_PROMISC");
1400-
if (rx_mode & IONIC_RX_MODE_F_ALLMULTI)
1401-
i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_ALLMULTI");
1402-
netdev_dbg(lif->netdev, "lif%d %s\n", lif->index, buf);
1403-
1404-
err = ionic_adminq_post_wait(lif, &ctx);
1405-
if (err)
1406-
netdev_warn(lif->netdev, "set rx_mode 0x%04x failed: %d\n",
1407-
rx_mode, err);
1408-
else
1409-
lif->rx_mode = rx_mode;
1410-
}
1373+
mutex_lock(&lif->config_lock);
14111374

1412-
static void ionic_set_rx_mode(struct net_device *netdev, bool can_sleep)
1413-
{
1414-
struct ionic_lif *lif = netdev_priv(netdev);
1415-
struct ionic_deferred_work *work;
1416-
unsigned int nfilters;
1417-
unsigned int rx_mode;
1375+
/* grab the flags once for local use */
1376+
nd_flags = netdev->flags;
14181377

14191378
rx_mode = IONIC_RX_MODE_F_UNICAST;
1420-
rx_mode |= (netdev->flags & IFF_MULTICAST) ? IONIC_RX_MODE_F_MULTICAST : 0;
1421-
rx_mode |= (netdev->flags & IFF_BROADCAST) ? IONIC_RX_MODE_F_BROADCAST : 0;
1422-
rx_mode |= (netdev->flags & IFF_PROMISC) ? IONIC_RX_MODE_F_PROMISC : 0;
1423-
rx_mode |= (netdev->flags & IFF_ALLMULTI) ? IONIC_RX_MODE_F_ALLMULTI : 0;
1379+
rx_mode |= (nd_flags & IFF_MULTICAST) ? IONIC_RX_MODE_F_MULTICAST : 0;
1380+
rx_mode |= (nd_flags & IFF_BROADCAST) ? IONIC_RX_MODE_F_BROADCAST : 0;
1381+
rx_mode |= (nd_flags & IFF_PROMISC) ? IONIC_RX_MODE_F_PROMISC : 0;
1382+
rx_mode |= (nd_flags & IFF_ALLMULTI) ? IONIC_RX_MODE_F_ALLMULTI : 0;
14241383

14251384
/* sync unicast addresses
14261385
* next check to see if we're in an overflow state
@@ -1429,49 +1388,83 @@ static void ionic_set_rx_mode(struct net_device *netdev, bool can_sleep)
14291388
* we remove our overflow flag and check the netdev flags
14301389
* to see if we can disable NIC PROMISC
14311390
*/
1432-
if (can_sleep)
1433-
__dev_uc_sync(netdev, ionic_addr_add, ionic_addr_del);
1434-
else
1435-
__dev_uc_sync(netdev, ionic_ndo_addr_add, ionic_ndo_addr_del);
1391+
__dev_uc_sync(netdev, ionic_addr_add, ionic_addr_del);
14361392
nfilters = le32_to_cpu(lif->identity->eth.max_ucast_filters);
14371393
if (netdev_uc_count(netdev) + 1 > nfilters) {
14381394
rx_mode |= IONIC_RX_MODE_F_PROMISC;
14391395
lif->uc_overflow = true;
14401396
} else if (lif->uc_overflow) {
14411397
lif->uc_overflow = false;
1442-
if (!(netdev->flags & IFF_PROMISC))
1398+
if (!(nd_flags & IFF_PROMISC))
14431399
rx_mode &= ~IONIC_RX_MODE_F_PROMISC;
14441400
}
14451401

14461402
/* same for multicast */
1447-
if (can_sleep)
1448-
__dev_mc_sync(netdev, ionic_addr_add, ionic_addr_del);
1449-
else
1450-
__dev_mc_sync(netdev, ionic_ndo_addr_add, ionic_ndo_addr_del);
1403+
__dev_mc_sync(netdev, ionic_addr_add, ionic_addr_del);
14511404
nfilters = le32_to_cpu(lif->identity->eth.max_mcast_filters);
14521405
if (netdev_mc_count(netdev) > nfilters) {
14531406
rx_mode |= IONIC_RX_MODE_F_ALLMULTI;
14541407
lif->mc_overflow = true;
14551408
} else if (lif->mc_overflow) {
14561409
lif->mc_overflow = false;
1457-
if (!(netdev->flags & IFF_ALLMULTI))
1410+
if (!(nd_flags & IFF_ALLMULTI))
14581411
rx_mode &= ~IONIC_RX_MODE_F_ALLMULTI;
14591412
}
14601413

1414+
i = scnprintf(buf, sizeof(buf), "rx_mode 0x%04x -> 0x%04x:",
1415+
lif->rx_mode, rx_mode);
1416+
if (rx_mode & IONIC_RX_MODE_F_UNICAST)
1417+
i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_UNICAST");
1418+
if (rx_mode & IONIC_RX_MODE_F_MULTICAST)
1419+
i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_MULTICAST");
1420+
if (rx_mode & IONIC_RX_MODE_F_BROADCAST)
1421+
i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_BROADCAST");
1422+
if (rx_mode & IONIC_RX_MODE_F_PROMISC)
1423+
i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_PROMISC");
1424+
if (rx_mode & IONIC_RX_MODE_F_ALLMULTI)
1425+
i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_ALLMULTI");
1426+
if (rx_mode & IONIC_RX_MODE_F_RDMA_SNIFFER)
1427+
i += scnprintf(&buf[i], REMAIN(i), " RX_MODE_F_RDMA_SNIFFER");
1428+
netdev_dbg(netdev, "lif%d %s\n", lif->index, buf);
1429+
14611430
if (lif->rx_mode != rx_mode) {
1462-
if (!can_sleep) {
1463-
work = kzalloc(sizeof(*work), GFP_ATOMIC);
1464-
if (!work) {
1465-
netdev_err(lif->netdev, "rxmode change dropped\n");
1466-
return;
1467-
}
1468-
work->type = IONIC_DW_TYPE_RX_MODE;
1469-
work->rx_mode = rx_mode;
1470-
netdev_dbg(lif->netdev, "deferred: rx_mode\n");
1471-
ionic_lif_deferred_enqueue(&lif->deferred, work);
1472-
} else {
1473-
ionic_lif_rx_mode(lif, rx_mode);
1431+
struct ionic_admin_ctx ctx = {
1432+
.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
1433+
.cmd.rx_mode_set = {
1434+
.opcode = IONIC_CMD_RX_MODE_SET,
1435+
.lif_index = cpu_to_le16(lif->index),
1436+
},
1437+
};
1438+
int err;
1439+
1440+
ctx.cmd.rx_mode_set.rx_mode = cpu_to_le16(rx_mode);
1441+
err = ionic_adminq_post_wait(lif, &ctx);
1442+
if (err)
1443+
netdev_warn(netdev, "set rx_mode 0x%04x failed: %d\n",
1444+
rx_mode, err);
1445+
else
1446+
lif->rx_mode = rx_mode;
1447+
}
1448+
1449+
mutex_unlock(&lif->config_lock);
1450+
}
1451+
1452+
static void ionic_set_rx_mode(struct net_device *netdev, bool can_sleep)
1453+
{
1454+
struct ionic_lif *lif = netdev_priv(netdev);
1455+
struct ionic_deferred_work *work;
1456+
1457+
if (!can_sleep) {
1458+
work = kzalloc(sizeof(*work), GFP_ATOMIC);
1459+
if (!work) {
1460+
netdev_err(lif->netdev, "rxmode change dropped\n");
1461+
return;
14741462
}
1463+
work->type = IONIC_DW_TYPE_RX_MODE;
1464+
netdev_dbg(lif->netdev, "deferred: rx_mode\n");
1465+
ionic_lif_deferred_enqueue(&lif->deferred, work);
1466+
} else {
1467+
ionic_lif_rx_mode(lif);
14751468
}
14761469
}
14771470

@@ -3058,6 +3051,7 @@ void ionic_lif_deinit(struct ionic_lif *lif)
30583051
ionic_lif_qcq_deinit(lif, lif->notifyqcq);
30593052
ionic_lif_qcq_deinit(lif, lif->adminqcq);
30603053

3054+
mutex_destroy(&lif->config_lock);
30613055
mutex_destroy(&lif->queue_lock);
30623056
ionic_lif_reset(lif);
30633057
}
@@ -3185,7 +3179,7 @@ static int ionic_station_set(struct ionic_lif *lif)
31853179
*/
31863180
if (!ether_addr_equal(ctx.comp.lif_getattr.mac,
31873181
netdev->dev_addr))
3188-
ionic_lif_addr(lif, netdev->dev_addr, ADD_ADDR, CAN_SLEEP);
3182+
ionic_lif_addr(lif, netdev->dev_addr, ADD_ADDR);
31893183
} else {
31903184
/* Update the netdev mac with the device's mac */
31913185
memcpy(addr.sa_data, ctx.comp.lif_getattr.mac, netdev->addr_len);
@@ -3202,7 +3196,7 @@ static int ionic_station_set(struct ionic_lif *lif)
32023196

32033197
netdev_dbg(lif->netdev, "adding station MAC addr %pM\n",
32043198
netdev->dev_addr);
3205-
ionic_lif_addr(lif, netdev->dev_addr, ADD_ADDR, CAN_SLEEP);
3199+
ionic_lif_addr(lif, netdev->dev_addr, ADD_ADDR);
32063200

32073201
return 0;
32083202
}
@@ -3225,6 +3219,7 @@ int ionic_lif_init(struct ionic_lif *lif)
32253219

32263220
lif->hw_index = le16_to_cpu(comp.hw_index);
32273221
mutex_init(&lif->queue_lock);
3222+
mutex_init(&lif->config_lock);
32283223

32293224
/* now that we have the hw_index we can figure out our doorbell page */
32303225
lif->dbid_count = le32_to_cpu(lif->ionic->ident.dev.ndbpgs_per_lif);

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

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ struct ionic_deferred_work {
108108
struct list_head list;
109109
enum ionic_deferred_work_type type;
110110
union {
111-
unsigned int rx_mode;
112111
u8 addr[ETH_ALEN];
113112
u8 fw_status;
114113
};
@@ -179,6 +178,7 @@ struct ionic_lif {
179178
unsigned int index;
180179
unsigned int hw_index;
181180
struct mutex queue_lock; /* lock for queue structures */
181+
struct mutex config_lock; /* lock for config actions */
182182
spinlock_t adminq_lock; /* lock for AdminQ operations */
183183
struct ionic_qcq *adminqcq;
184184
struct ionic_qcq *notifyqcq;
@@ -199,7 +199,7 @@ struct ionic_lif {
199199
unsigned int nrxq_descs;
200200
u32 rx_copybreak;
201201
u64 rxq_features;
202-
unsigned int rx_mode;
202+
u16 rx_mode;
203203
u64 hw_features;
204204
bool registered;
205205
bool mc_overflow;
@@ -302,7 +302,7 @@ int ionic_lif_identify(struct ionic *ionic, u8 lif_type,
302302
int ionic_lif_size(struct ionic *ionic);
303303

304304
#if IS_ENABLED(CONFIG_PTP_1588_CLOCK)
305-
int ionic_lif_hwstamp_replay(struct ionic_lif *lif);
305+
void ionic_lif_hwstamp_replay(struct ionic_lif *lif);
306306
int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr);
307307
int ionic_lif_hwstamp_get(struct ionic_lif *lif, struct ifreq *ifr);
308308
ktime_t ionic_lif_phc_ktime(struct ionic_lif *lif, u64 counter);
@@ -311,10 +311,7 @@ void ionic_lif_unregister_phc(struct ionic_lif *lif);
311311
void ionic_lif_alloc_phc(struct ionic_lif *lif);
312312
void ionic_lif_free_phc(struct ionic_lif *lif);
313313
#else
314-
static inline int ionic_lif_hwstamp_replay(struct ionic_lif *lif)
315-
{
316-
return -EOPNOTSUPP;
317-
}
314+
static inline void ionic_lif_hwstamp_replay(struct ionic_lif *lif) {}
318315

319316
static inline int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
320317
{

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,9 @@ int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
188188
struct hwtstamp_config config;
189189
int err;
190190

191+
if (!lif->phc || !lif->phc->ptp)
192+
return -EOPNOTSUPP;
193+
191194
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
192195
return -EFAULT;
193196

@@ -203,15 +206,16 @@ int ionic_lif_hwstamp_set(struct ionic_lif *lif, struct ifreq *ifr)
203206
return 0;
204207
}
205208

206-
int ionic_lif_hwstamp_replay(struct ionic_lif *lif)
209+
void ionic_lif_hwstamp_replay(struct ionic_lif *lif)
207210
{
208211
int err;
209212

213+
if (!lif->phc || !lif->phc->ptp)
214+
return;
215+
210216
err = ionic_lif_hwstamp_set_ts_config(lif, NULL);
211217
if (err)
212218
netdev_info(lif->netdev, "hwstamp replay failed: %d\n", err);
213-
214-
return err;
215219
}
216220

217221
int ionic_lif_hwstamp_get(struct ionic_lif *lif, struct ifreq *ifr)

0 commit comments

Comments
 (0)