Commit 26922c0e authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'ionic-error-recovery-fixes'



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: default avatarDavid S. Miller <davem@davemloft.net>
parents 6fcd4224 a4674f34
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -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);
}
+33 −19
Original line number Diff line number Diff line
@@ -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;
@@ -318,20 +320,22 @@ static void ionic_qcqs_free(struct ionic_lif *lif)
		lif->adminqcq = NULL;
	}

	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;
	}

	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,
				      struct ionic_qcq *n_qcq)
@@ -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);
@@ -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,
@@ -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;
	}
}

@@ -1552,6 +1561,7 @@ 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) {
			if (err != -ETIMEDOUT)
				ionic_qcq_disable(lif->txqcqs[i].qcq);
			goto err_out;
		}
@@ -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;
+10 −2
Original line number Diff line number Diff line
@@ -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;
@@ -360,7 +365,10 @@ try_again:
		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;