Skip to content

Commit

Permalink
Merge branch 'ionic-error-recovery-fixes'
Browse files Browse the repository at this point in the history
Shannon Nelson says:

====================
ionic error recovery fixes

These are a few little patches to make error recovery a little
more safe and successful.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Mar 22, 2020
2 parents 6fcd422 + a4674f3 commit 26922c0
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 22 deletions.
8 changes: 7 additions & 1 deletion drivers/net/ethernet/pensando/ionic/ionic_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,13 @@ DEFINE_SHOW_ATTRIBUTE(netdev);

void ionic_debugfs_add_lif(struct ionic_lif *lif)
{
lif->dentry = debugfs_create_dir(lif->name, lif->ionic->dentry);
struct dentry *lif_dentry;

lif_dentry = debugfs_create_dir(lif->name, lif->ionic->dentry);
if (IS_ERR_OR_NULL(lif_dentry))
return;
lif->dentry = lif_dentry;

debugfs_create_file("netdev", 0400, lif->dentry,
lif->netdev, &netdev_fops);
}
Expand Down
52 changes: 33 additions & 19 deletions drivers/net/ethernet/pensando/ionic/ionic_lif.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,10 @@ static void ionic_lif_qcq_deinit(struct ionic_lif *lif, struct ionic_qcq *qcq)
if (qcq->flags & IONIC_QCQ_F_INTR) {
ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
IONIC_INTR_MASK_SET);
irq_set_affinity_hint(qcq->intr.vector, NULL);
devm_free_irq(dev, qcq->intr.vector, &qcq->napi);
netif_napi_del(&qcq->napi);
qcq->intr.vector = 0;
}

qcq->flags &= ~IONIC_QCQ_F_INITED;
Expand Down Expand Up @@ -318,19 +320,21 @@ static void ionic_qcqs_free(struct ionic_lif *lif)
lif->adminqcq = NULL;
}

for (i = 0; i < lif->nxqs; i++)
if (lif->rxqcqs[i].stats)
devm_kfree(dev, lif->rxqcqs[i].stats);

devm_kfree(dev, lif->rxqcqs);
lif->rxqcqs = NULL;

for (i = 0; i < lif->nxqs; i++)
if (lif->txqcqs[i].stats)
devm_kfree(dev, lif->txqcqs[i].stats);
if (lif->rxqcqs) {
for (i = 0; i < lif->nxqs; i++)
if (lif->rxqcqs[i].stats)
devm_kfree(dev, lif->rxqcqs[i].stats);
devm_kfree(dev, lif->rxqcqs);
lif->rxqcqs = NULL;
}

devm_kfree(dev, lif->txqcqs);
lif->txqcqs = NULL;
if (lif->txqcqs) {
for (i = 0; i < lif->nxqs; i++)
if (lif->txqcqs[i].stats)
devm_kfree(dev, lif->txqcqs[i].stats);
devm_kfree(dev, lif->txqcqs);
lif->txqcqs = NULL;
}
}

static void ionic_link_qcq_interrupts(struct ionic_qcq *src_qcq,
Expand Down Expand Up @@ -832,7 +836,7 @@ static int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr)

memcpy(ctx.cmd.rx_filter_add.mac.addr, addr, ETH_ALEN);
err = ionic_adminq_post_wait(lif, &ctx);
if (err)
if (err && err != -EEXIST)
return err;

return ionic_rx_filter_save(lif, 0, IONIC_RXQ_INDEX_ANY, 0, &ctx);
Expand Down Expand Up @@ -862,7 +866,7 @@ static int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr)
spin_unlock_bh(&lif->rx_filters.lock);

err = ionic_adminq_post_wait(lif, &ctx);
if (err)
if (err && err != -EEXIST)
return err;

netdev_dbg(lif->netdev, "rx_filter del ADDR %pM (id %d)\n", addr,
Expand Down Expand Up @@ -1425,10 +1429,15 @@ static void ionic_lif_rss_deinit(struct ionic_lif *lif)
static void ionic_txrx_disable(struct ionic_lif *lif)
{
unsigned int i;
int err;

for (i = 0; i < lif->nxqs; i++) {
ionic_qcq_disable(lif->txqcqs[i].qcq);
ionic_qcq_disable(lif->rxqcqs[i].qcq);
err = ionic_qcq_disable(lif->txqcqs[i].qcq);
if (err == -ETIMEDOUT)
break;
err = ionic_qcq_disable(lif->rxqcqs[i].qcq);
if (err == -ETIMEDOUT)
break;
}
}

Expand Down Expand Up @@ -1552,7 +1561,8 @@ static int ionic_txrx_enable(struct ionic_lif *lif)
ionic_rx_fill(&lif->rxqcqs[i].qcq->q);
err = ionic_qcq_enable(lif->rxqcqs[i].qcq);
if (err) {
ionic_qcq_disable(lif->txqcqs[i].qcq);
if (err != -ETIMEDOUT)
ionic_qcq_disable(lif->txqcqs[i].qcq);
goto err_out;
}
}
Expand All @@ -1561,8 +1571,12 @@ static int ionic_txrx_enable(struct ionic_lif *lif)

err_out:
while (i--) {
ionic_qcq_disable(lif->rxqcqs[i].qcq);
ionic_qcq_disable(lif->txqcqs[i].qcq);
err = ionic_qcq_disable(lif->rxqcqs[i].qcq);
if (err == -ETIMEDOUT)
break;
err = ionic_qcq_disable(lif->txqcqs[i].qcq);
if (err == -ETIMEDOUT)
break;
}

return err;
Expand Down
12 changes: 10 additions & 2 deletions drivers/net/ethernet/pensando/ionic/ionic_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,11 +243,16 @@ static void ionic_adminq_cb(struct ionic_queue *q,

static int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
{
struct ionic_queue *adminq = &lif->adminqcq->q;
struct ionic_queue *adminq;
int err = 0;

WARN_ON(in_interrupt());

if (!lif->adminqcq)
return -EIO;

adminq = &lif->adminqcq->q;

spin_lock(&lif->adminq_lock);
if (!ionic_q_has_space(adminq, 1)) {
err = -ENOSPC;
Expand Down Expand Up @@ -360,7 +365,10 @@ int ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_seconds)
done, duration / HZ, duration);

if (!done && hb) {
ionic_dev_cmd_clean(ionic);
/* It is possible (but unlikely) that FW was busy and missed a
* heartbeat check but is still alive and will process this
* request, so don't clean the dev_cmd in this case.
*/
dev_warn(ionic->dev, "DEVCMD %s (%d) failed - FW halted\n",
ionic_opcode_to_str(opcode), opcode);
return -ENXIO;
Expand Down

0 comments on commit 26922c0

Please sign in to comment.