lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1236196875.3140.32.camel@achroite>
Date:	Wed, 04 Mar 2009 20:01:15 +0000
From:	Ben Hutchings <bhutchings@...arflare.com>
To:	David Miller <davem@...emloft.net>
Cc:	netdev@...r.kernel.org, linux-net-drivers@...arflare.com
Subject: [PATCH 6/7] sfc: Fix search for flush completion events

When flushing queues we disable normal interrupt and event handling and
poll event queue 0 looking for flush completions.  Unfortunately the
flush event polling loop fails to move past any other type of event.
This problem has not been observed in production hardware but appears to
be a possibility.

Signed-off-by: Ben Hutchings <bhutchings@...arflare.com>
---
 drivers/net/sfc/falcon.c |   21 +++++++++------------
 1 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index efd121c..82c10f4 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -1187,31 +1187,29 @@ static void falcon_poll_flush_events(struct efx_nic *efx)
 	struct efx_channel *channel = &efx->channel[0];
 	struct efx_tx_queue *tx_queue;
 	struct efx_rx_queue *rx_queue;
-	unsigned int read_ptr, i;
+	unsigned int read_ptr = channel->eventq_read_ptr;
+	unsigned int end_ptr = (read_ptr - 1) & FALCON_EVQ_MASK;
 
-	read_ptr = channel->eventq_read_ptr;
-	for (i = 0; i < FALCON_EVQ_SIZE; ++i) {
+	do {
 		efx_qword_t *event = falcon_event(channel, read_ptr);
 		int ev_code, ev_sub_code, ev_queue;
 		bool ev_failed;
+
 		if (!falcon_event_present(event))
 			break;
 
 		ev_code = EFX_QWORD_FIELD(*event, EV_CODE);
-		if (ev_code != DRIVER_EV_DECODE)
-			continue;
-
 		ev_sub_code = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_CODE);
-		switch (ev_sub_code) {
-		case TX_DESCQ_FLS_DONE_EV_DECODE:
+		if (ev_code == DRIVER_EV_DECODE &&
+		    ev_sub_code == TX_DESCQ_FLS_DONE_EV_DECODE) {
 			ev_queue = EFX_QWORD_FIELD(*event,
 						   DRIVER_EV_TX_DESCQ_ID);
 			if (ev_queue < EFX_TX_QUEUE_COUNT) {
 				tx_queue = efx->tx_queue + ev_queue;
 				tx_queue->flushed = true;
 			}
-			break;
-		case RX_DESCQ_FLS_DONE_EV_DECODE:
+		} else if (ev_code == DRIVER_EV_DECODE &&
+			   ev_sub_code == RX_DESCQ_FLS_DONE_EV_DECODE) {
 			ev_queue = EFX_QWORD_FIELD(*event,
 						   DRIVER_EV_RX_DESCQ_ID);
 			ev_failed = EFX_QWORD_FIELD(*event,
@@ -1225,11 +1223,10 @@ static void falcon_poll_flush_events(struct efx_nic *efx)
 				else
 					rx_queue->flushed = true;
 			}
-			break;
 		}
 
 		read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK;
-	}
+	} while (read_ptr != end_ptr);
 }
 
 /* Handle tx and rx flushes at the same time, since they run in

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ