Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4cebdcec authored by Michael Chan's avatar Michael Chan Committed by David S. Miller
Browse files

bnxt_en: Don't cancel sp_task from bnxt_close_nic().



When implementing driver reset from tx_timeout in the next patch,
bnxt_close_nic() will be called from the sp_task workqueue.  Calling
cancel_work() on sp_task will hang the workqueue.

Instead, set a new bit BNXT_STATE_IN_SP_TASK when bnxt_sp_task() is running.
bnxt_close_nic() will wait for BNXT_STATE_IN_SP_TASK to clear before
proceeding.

Signed-off-by: default avatarMichael Chan <mchan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent caefe526
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -4679,7 +4679,9 @@ int bnxt_close_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
	bnxt_tx_disable(bp);

	clear_bit(BNXT_STATE_OPEN, &bp->state);
	cancel_work_sync(&bp->sp_task);
	smp_mb__after_atomic();
	while (test_bit(BNXT_STATE_IN_SP_TASK, &bp->state))
		msleep(20);

	/* Flush rings before disabling interrupts */
	bnxt_shutdown_nic(bp, irq_re_init);
@@ -5080,8 +5082,12 @@ static void bnxt_sp_task(struct work_struct *work)
	struct bnxt *bp = container_of(work, struct bnxt, sp_task);
	int rc;

	if (!test_bit(BNXT_STATE_OPEN, &bp->state))
	set_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
	smp_mb__after_atomic();
	if (!test_bit(BNXT_STATE_OPEN, &bp->state)) {
		clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
		return;
	}

	if (test_and_clear_bit(BNXT_RX_MASK_SP_EVENT, &bp->sp_event))
		bnxt_cfg_rx_mode(bp);
@@ -5107,6 +5113,9 @@ static void bnxt_sp_task(struct work_struct *work)
	}
	if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event))
		bnxt_reset_task(bp);

	smp_mb__before_atomic();
	clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
}

static int bnxt_init_board(struct pci_dev *pdev, struct net_device *dev)
+1 −0
Original line number Diff line number Diff line
@@ -927,6 +927,7 @@ struct bnxt {

	unsigned long		state;
#define BNXT_STATE_OPEN		0
#define BNXT_STATE_IN_SP_TASK	1

	struct bnxt_irq	*irq_tbl;
	u8			mac_addr[ETH_ALEN];