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

Commit d4f80882 authored by Ayyappan Veeraiyan's avatar Ayyappan Veeraiyan Committed by Jeff Garzik
Browse files

ixgbe: remove obsolete irq_sem, add driver state checking code



After testing we confirmed that the irq_sem can safely be
removed from ixgbe.

Add strict state checking code to various ethtool parts to
properly protect against races between various driver reset
paths.

Signed-off-by: default avatarAyyappan Veeraiyan <ayyappan.veeraiyan@intel.com>
Signed-off-by: default avatarAuke Kok <auke-jan.h.kok@intel.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 06f7525b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -174,7 +174,6 @@ struct ixgbe_adapter {
	struct vlan_group *vlgrp;
	u16 bd_number;
	u16 rx_buf_len;
	atomic_t irq_sem;
	struct work_struct reset_task;

	/* TX */
@@ -244,6 +243,7 @@ extern const char ixgbe_driver_version[];

extern int ixgbe_up(struct ixgbe_adapter *adapter);
extern void ixgbe_down(struct ixgbe_adapter *adapter);
extern void ixgbe_reinit_locked(struct ixgbe_adapter *adapter);
extern void ixgbe_reset(struct ixgbe_adapter *adapter);
extern void ixgbe_update_stats(struct ixgbe_adapter *adapter);
extern void ixgbe_set_ethtool_ops(struct net_device *netdev);
+13 −16
Original line number Diff line number Diff line
@@ -179,12 +179,10 @@ static int ixgbe_set_pauseparam(struct net_device *netdev,

	hw->fc.original_type = hw->fc.type;

	if (netif_running(adapter->netdev)) {
		ixgbe_down(adapter);
		ixgbe_up(adapter);
	} else {
	if (netif_running(netdev))
		ixgbe_reinit_locked(adapter);
	else
		ixgbe_reset(adapter);
	}

	return 0;
}
@@ -203,12 +201,10 @@ static int ixgbe_set_rx_csum(struct net_device *netdev, u32 data)
	else
		adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED;

	if (netif_running(netdev)) {
		ixgbe_down(adapter);
		ixgbe_up(adapter);
	} else {
	if (netif_running(netdev))
		ixgbe_reinit_locked(adapter);
	else
		ixgbe_reset(adapter);
	}

	return 0;
}
@@ -662,7 +658,10 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
		return 0;
	}

	if (netif_running(adapter->netdev))
	while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
		msleep(1);

	if (netif_running(netdev))
		ixgbe_down(adapter);

	/*
@@ -733,6 +732,7 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
	if (netif_running(adapter->netdev))
		ixgbe_up(adapter);

	clear_bit(__IXGBE_RESETTING, &adapter->state);
	return err;
}

@@ -820,11 +820,8 @@ static int ixgbe_nway_reset(struct net_device *netdev)
{
	struct ixgbe_adapter *adapter = netdev_priv(netdev);

	if (netif_running(netdev)) {
		ixgbe_down(adapter);
		ixgbe_reset(adapter);
		ixgbe_up(adapter);
	}
	if (netif_running(netdev))
		ixgbe_reinit_locked(adapter);

	return 0;
}
+35 −25
Original line number Diff line number Diff line
@@ -535,7 +535,9 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
		if (!test_bit(__IXGBE_DOWN, &adapter->state))
			mod_timer(&adapter->watchdog_timer, jiffies);
	}
	IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);

	if (!test_bit(__IXGBE_DOWN, &adapter->state))
		IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);

	return IRQ_HANDLED;
}
@@ -713,7 +715,6 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
	if (netif_rx_schedule_prep(netdev, &adapter->napi)) {
		/* Disable interrupts and register for poll. The flush of the
		 * posted write is intentionally left out. */
		atomic_inc(&adapter->irq_sem);
		IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0);
		__netif_rx_schedule(netdev, &adapter->napi);
	}
@@ -801,7 +802,6 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
 **/
static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter)
{
	atomic_inc(&adapter->irq_sem);
	IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0);
	IXGBE_WRITE_FLUSH(&adapter->hw);
	synchronize_irq(adapter->pdev->irq);
@@ -813,7 +813,6 @@ static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter)
 **/
static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter)
{
	if (atomic_dec_and_test(&adapter->irq_sem)) {
	if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
		IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIAC,
				(IXGBE_EIMS_ENABLE_MASK &
@@ -822,7 +821,6 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter)
			IXGBE_EIMS_ENABLE_MASK);
	IXGBE_WRITE_FLUSH(&adapter->hw);
}
}

/**
 * ixgbe_configure_msi_and_legacy - Initialize PIN (INTA...) and MSI interrupts
@@ -1040,6 +1038,7 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev,
	struct ixgbe_adapter *adapter = netdev_priv(netdev);
	u32 ctrl;

	if (!test_bit(__IXGBE_DOWN, &adapter->state))
		ixgbe_irq_disable(adapter);
	adapter->vlgrp = grp;

@@ -1051,6 +1050,7 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev,
		IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl);
	}

	if (!test_bit(__IXGBE_DOWN, &adapter->state))
		ixgbe_irq_enable(adapter);
}

@@ -1066,8 +1066,12 @@ static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
{
	struct ixgbe_adapter *adapter = netdev_priv(netdev);

	if (!test_bit(__IXGBE_DOWN, &adapter->state))
		ixgbe_irq_disable(adapter);

	vlan_group_set_device(adapter->vlgrp, vid, NULL);

	if (!test_bit(__IXGBE_DOWN, &adapter->state))
		ixgbe_irq_enable(adapter);

	/* remove VID from filter table */
@@ -1224,6 +1228,16 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
	return 0;
}

void ixgbe_reinit_locked(struct ixgbe_adapter *adapter)
{
	WARN_ON(in_interrupt());
	while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
		msleep(1);
	ixgbe_down(adapter);
	ixgbe_up(adapter);
	clear_bit(__IXGBE_RESETTING, &adapter->state);
}

int ixgbe_up(struct ixgbe_adapter *adapter)
{
	/* hardware has been reset, we need to reload some things */
@@ -1408,7 +1422,6 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
	msleep(10);

	napi_disable(&adapter->napi);
	atomic_set(&adapter->irq_sem, 0);

	ixgbe_irq_disable(adapter);

@@ -1481,6 +1494,7 @@ static int ixgbe_clean(struct napi_struct *napi, int budget)
	/* If budget not fully consumed, exit the polling mode */
	if (work_done < budget) {
		netif_rx_complete(netdev, napi);
		if (!test_bit(__IXGBE_DOWN, &adapter->state))
			ixgbe_irq_enable(adapter);
	}

@@ -1506,8 +1520,7 @@ static void ixgbe_reset_task(struct work_struct *work)

	adapter->tx_timeout_count++;

	ixgbe_down(adapter);
	ixgbe_up(adapter);
	ixgbe_reinit_locked(adapter);
}

/**
@@ -1590,7 +1603,6 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
		return -ENOMEM;
	}

	atomic_set(&adapter->irq_sem, 1);
	set_bit(__IXGBE_DOWN, &adapter->state);

	return 0;
@@ -1828,10 +1840,8 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu)

	netdev->mtu = new_mtu;

	if (netif_running(netdev)) {
		ixgbe_down(adapter);
		ixgbe_up(adapter);
	}
	if (netif_running(netdev))
		ixgbe_reinit_locked(adapter);

	return 0;
}