Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 3094

kernel-2.6.18-238.el5.src.rpm

From: Michal Schmidt <mschmidt@redhat.com>
Date: Fri, 3 Sep 2010 19:58:12 -0400
Subject: [net] sfc: undo now unnecessary RHEL workqueue changes
Message-id: <20100903195811.7750.20435.stgit@localhost6.localdomain6>
Patchwork-id: 28131
O-Subject: [RHEL5.6 BZ556476 PATCH 5/6] sfc: undo now unnecessary RHEL workqueue
	changes
Bugzilla: 556476
RH-Acked-by: David S. Miller <davem@redhat.com>
RH-Acked-by: Thomas Graf <tgraf@redhat.com>

This reverts some workqueue changes that were originally introduced as a part
of the sfc backport. They were only necessary because we did not have
cancel_work_sync() in RHEL5 back then.

diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 3e75d68..bbb0dd0 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -1129,21 +1129,18 @@ static void efx_start_all(struct efx_nic *efx)
  * since we're holding the rtnl_lock at this point. */
 static void efx_flush_all(struct efx_nic *efx)
 {
-	/* Ensure efx_monitor() and efx_mac_work() are complete, which
-	 * are the only two consumers of efx->workqueue. Since the hardware
-	 * monitor runs on a long period, we put in some effort to cancel
-	 * the delayed work safely rather than just flushing the queue twice
-	 * (which is guaranteed to flush all the work since efx_monitor(),
-	 * and efx_mac_work() disarm if !efx->port_enabled). */
-	cancel_delayed_work_sync(&efx->monitor_work);
-	flush_workqueue(efx->workqueue);
+	struct efx_rx_queue *rx_queue;
+
+	/* Make sure the hardware monitor is stopped */
 	cancel_delayed_work_sync(&efx->monitor_work);
-	flush_workqueue(efx->workqueue);
 
-	/* efx_rx_work will disarm if !channel->enabled, so we can just
-	 * flush the refill workqueue twice as well. */
-	flush_workqueue(refill_workqueue);
-	flush_workqueue(refill_workqueue);
+	/* Ensure that all RX slow refills are complete. */
+	efx_for_each_rx_queue(rx_queue, efx)
+		cancel_delayed_work_sync(&rx_queue->work);
+
+	/* Stop scheduled port reconfigurations */
+	cancel_work_sync(&efx->mac_work);
+	cancel_work_sync(&efx->phy_work);
 }
 
 /* Quiesce hardware and software without bringing the link down.
@@ -1262,13 +1259,13 @@ static void efx_monitor(void *data)
 	EFX_TRACE(efx, "hardware monitor executing on CPU %d\n",
 		  raw_smp_processor_id());
 
-	/* Without cancel_delayed_work_sync(), we have to make sure that
-	 * we don't rearm when !port_enabled */
-	mutex_lock(&efx->mac_lock);
-	if (!efx->port_enabled) {
-		mutex_unlock(&efx->mac_lock);
-		return;
-	}
+	/* If the mac_lock is already held then it is likely a port
+	 * reconfiguration is already in place, which will likely do
+	 * most of the work of check_hw() anyway. */
+	if (!mutex_trylock(&efx->mac_lock))
+		goto out_requeue;
+	if (!efx->port_enabled)
+		goto out_unlock;
 	rc = efx->board_info.monitor(efx);
 	if (rc) {
 		EFX_ERR(efx, "Board sensor %s; shutting down PHY\n",
@@ -1279,7 +1276,9 @@ static void efx_monitor(void *data)
 	efx->phy_op->poll(efx);
 	efx->mac_op->poll(efx);
 
+out_unlock:
 	mutex_unlock(&efx->mac_lock);
+out_requeue:
 	queue_delayed_work(efx->workqueue, &efx->monitor_work.work,
 			   efx_monitor_interval);
 }
@@ -2085,8 +2084,7 @@ static void efx_pci_remove(struct pci_dev *pci_dev)
 	 * scheduled from this point because efx_stop_all() has been
 	 * called, we are no longer registered with driverlink, and
 	 * the net_device's have been removed. */
-	flush_workqueue(reset_workqueue);
-
+	cancel_work_sync(&efx->reset_work);
 
 	efx_pci_remove_main(efx);
 
@@ -2207,8 +2205,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
 		 * scheduled since efx_stop_all() has been called, and we
 		 * have not and never have been registered with either
 		 * the rtnetlink or driverlink layers. */
-		flush_workqueue(reset_workqueue);
-
+		cancel_work_sync(&efx->reset_work);
 
 		if (rc == 0) {
 			if (efx->reset_pending != RESET_TYPE_NONE) {