mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Bryan O'Sullivan" <bos@pathscale.com>
To: akpm@osdl.org, rdreier@cisco.com, mst@mellanox.co.il
Cc: openib-general@openib.org, linux-kernel@vger.kernel.org,
	netdev@vger.kernel.org
Subject: [PATCH 21 of 39] IB/ipath - fixed bug 9776 for real. The problem was that I was updating
Date: Thu, 29 Jun 2006 14:41:12 -0700	[thread overview]
Message-ID: <1a4350d895c9a673c98e.1151617272@eng-12.pathscale.com> (raw)
In-Reply-To: <patchbomb.1151617251@eng-12.pathscale.com>

the head register multiple times in the rcvhdrq processing loop,
and setting the counter on each update.   Since that meant that
the tail register was ahead of head for all but the last update,
we would get extra interrupts.   The fix was to not write the
counter value except on the last update.

I also changed to update rcvhdrhead and rcvegrindexhead at most
every 16 packets, if there were lots of packets in the queue
(and of course, on the last packet, regardless).

I also made some small cleanups while debugging this.

With these changes, xeon/monty typically sees two openib packets
per interrupt on sdp and ipoib, opteron/monty is about 1.25 pkts/intr.

I'm seeing about 3800 Mbit/s monty/xeon, and 5000-5100 opteron/monty
with netperf sdp.  Netpipe doesn't show as good as that, peaking
at about 4400 on opteron/monty sdp.   Plain ipoib xeon is about 2100+
netperf, opteron 2900+, at 128KB

Signed-off-by: olson@eng-12.pathscale.com
Signed-off-by: Bryan O'Sullivan <bos@pathscale.com>

diff -r 8bc865893a11 -r 1a4350d895c9 drivers/infiniband/hw/ipath/ipath_driver.c
--- a/drivers/infiniband/hw/ipath/ipath_driver.c	Thu Jun 29 14:33:25 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c	Thu Jun 29 14:33:26 2006 -0700
@@ -870,7 +870,7 @@ void ipath_kreceive(struct ipath_devdata
 	const u32 maxcnt = dd->ipath_rcvhdrcnt * rsize;	/* words */
 	u32 etail = -1, l, hdrqtail;
 	struct ips_message_header *hdr;
-	u32 eflags, i, etype, tlen, pkttot = 0;
+	u32 eflags, i, etype, tlen, pkttot = 0, updegr=0;
 	static u64 totcalls;	/* stats, may eventually remove */
 	char emsg[128];
 
@@ -884,14 +884,14 @@ void ipath_kreceive(struct ipath_devdata
 	if (test_and_set_bit(0, &dd->ipath_rcv_pending))
 		goto bail;
 
-	if (dd->ipath_port0head ==
-	    (u32)le64_to_cpu(*dd->ipath_hdrqtailptr))
+	l = dd->ipath_port0head;
+	if (l == (u32)le64_to_cpu(*dd->ipath_hdrqtailptr))
 		goto done;
 
 	/* read only once at start for performance */
 	hdrqtail = (u32)le64_to_cpu(*dd->ipath_hdrqtailptr);
 
-	for (i = 0, l = dd->ipath_port0head; l != hdrqtail; i++) {
+	for (i = 0; l != hdrqtail; i++) {
 		u32 qp;
 		u8 *bthbytes;
 
@@ -1002,15 +1002,26 @@ void ipath_kreceive(struct ipath_devdata
 		l += rsize;
 		if (l >= maxcnt)
 			l = 0;
+		if (etype != RCVHQ_RCV_TYPE_EXPECTED)
+		    updegr = 1;
 		/*
-		 * update for each packet, to help prevent overflows if we
-		 * have lots of packets.
+		 * update head regs on last packet, and every 16 packets.
+		 * Reduce bus traffic, while still trying to prevent
+		 * rcvhdrq overflows, for when the queue is nearly full
 		 */
-		(void)ipath_write_ureg(dd, ur_rcvhdrhead,
-				       dd->ipath_rhdrhead_intr_off | l, 0);
-		if (etype != RCVHQ_RCV_TYPE_EXPECTED)
-			(void)ipath_write_ureg(dd, ur_rcvegrindexhead,
-					       etail, 0);
+		if (l == hdrqtail || (i && !(i&0xf))) {
+			u64 lval;
+			if (l == hdrqtail) /* want interrupt only on last */
+				lval = dd->ipath_rhdrhead_intr_off | l;
+			else
+				lval = l;
+			(void)ipath_write_ureg(dd, ur_rcvhdrhead, lval, 0);
+			if (updegr) {
+				(void)ipath_write_ureg(dd, ur_rcvegrindexhead,
+						       etail, 0);
+				updegr = 0;
+			}
+		}
 	}
 
 	pkttot += i;
diff -r 8bc865893a11 -r 1a4350d895c9 drivers/infiniband/hw/ipath/ipath_intr.c
--- a/drivers/infiniband/hw/ipath/ipath_intr.c	Thu Jun 29 14:33:25 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c	Thu Jun 29 14:33:26 2006 -0700
@@ -383,7 +383,7 @@ static unsigned handle_frequent_errors(s
 	return supp_msgs;
 }
 
-static void handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
+static int handle_errors(struct ipath_devdata *dd, ipath_err_t errs)
 {
 	char msg[512];
 	u64 ignore_this_time = 0;
@@ -480,7 +480,7 @@ static void handle_errors(struct ipath_d
 			  INFINIPATH_E_IBSTATUSCHANGED);
 	}
 	if (!errs)
-		return;
+		return 0;
 
 	if (!noprint)
 		/*
@@ -604,9 +604,7 @@ static void handle_errors(struct ipath_d
 		wake_up_interruptible(&ipath_sma_state_wait);
 	}
 
-	if (chkerrpkts)
-		/* process possible error packets in hdrq */
-		ipath_kreceive(dd);
+	return chkerrpkts;
 }
 
 /* this is separate to allow for better optimization of ipath_intr() */
@@ -765,10 +763,10 @@ irqreturn_t ipath_intr(int irq, void *da
 irqreturn_t ipath_intr(int irq, void *data, struct pt_regs *regs)
 {
 	struct ipath_devdata *dd = data;
-	u32 istat;
+	u32 istat, chk0rcv = 0;
 	ipath_err_t estat = 0;
 	irqreturn_t ret;
-	u32 p0bits;
+	u32 p0bits, oldhead;
 	static unsigned unexpected = 0;
 	static const u32 port0rbits = (1U<<INFINIPATH_I_RCVAVAIL_SHIFT) |
 		 (1U<<INFINIPATH_I_RCVURG_SHIFT);
@@ -810,9 +808,8 @@ irqreturn_t ipath_intr(int irq, void *da
 	 * interrupts.   We clear the interrupts first so that we don't
 	 * lose intr for later packets that arrive while we are processing.
 	 */
-	if (dd->ipath_port0head !=
-		(u32)le64_to_cpu(*dd->ipath_hdrqtailptr)) {
-		u32 oldhead = dd->ipath_port0head;
+	oldhead = dd->ipath_port0head;
+	if (oldhead != (u32) le64_to_cpu(*dd->ipath_hdrqtailptr)) {
 		if (dd->ipath_flags & IPATH_GPIO_INTR) {
 			ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear,
 					 (u64) (1 << 2));
@@ -830,6 +827,8 @@ irqreturn_t ipath_intr(int irq, void *da
 	}
  
 	istat = ipath_read_kreg32(dd, dd->ipath_kregs->kr_intstatus);
+	p0bits = port0rbits;
+
 	if (unlikely(!istat)) {
 		ipath_stats.sps_nullintr++;
 		ret = IRQ_NONE; /* not our interrupt, or already handled */
@@ -867,10 +866,11 @@ irqreturn_t ipath_intr(int irq, void *da
 			ipath_dev_err(dd, "Read of error status failed "
 				      "(all bits set); ignoring\n");
 		else
-			handle_errors(dd, estat);
-	}
-
-	p0bits = port0rbits;
+			if (handle_errors(dd, estat))
+				/* force calling ipath_kreceive() */
+				chk0rcv = 1;
+	}
+
 	if (istat & INFINIPATH_I_GPIO) {
 		/*
 		 * Packets are available in the port 0 rcv queue.
@@ -892,8 +892,10 @@ irqreturn_t ipath_intr(int irq, void *da
 			ipath_write_kreg(dd, dd->ipath_kregs->kr_gpio_clear,
 					 (u64) (1 << 2));
 			p0bits |= INFINIPATH_I_GPIO;
-		}
-	}
+			chk0rcv = 1;
+		}
+	}
+	chk0rcv |= istat & p0bits;
 
 	/*
 	 * clear the ones we will deal with on this round
@@ -905,18 +907,16 @@ irqreturn_t ipath_intr(int irq, void *da
 	ipath_write_kreg(dd, dd->ipath_kregs->kr_intclear, istat);
 
 	/*
-	 * we check for both transition from empty to non-empty, and urgent
-	 * packets (those with the interrupt bit set in the header), and
-	 * if enabled, the GPIO bit 2 interrupt used for port0 on some
-	 * HT-400 boards.
-	 * Do this before checking for pio buffers available, since
-	 * receives can overflow; piobuf waiters can afford a few
-	 * extra cycles, since they were waiting anyway.
-	 */
-	if (istat & p0bits) {
+	 * handle port0 receive  before checking for pio buffers available,
+	 * since receives can overflow; piobuf waiters can afford a few
+	 * extra cycles, since they were waiting anyway, and user's waiting
+	 * for receive are at the bottom.
+	 */
+	if (chk0rcv) {
 		ipath_kreceive(dd);
 		istat &= ~port0rbits;
 	}
+
 	if (istat & ((infinipath_i_rcvavail_mask <<
 		      INFINIPATH_I_RCVAVAIL_SHIFT)
 		     | (infinipath_i_rcvurg_mask <<

  parent reply	other threads:[~2006-06-29 21:53 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-06-29 21:40 [PATCH 0 of 39] ipath - bug fixes, performance enhancements, and portability improvements Bryan O'Sullivan
2006-06-29 21:40 ` [PATCH 1 of 39] IB/ipath - Name zero counter offsets so it's clear they aren't counters Bryan O'Sullivan
2006-06-29 21:40 ` [PATCH 2 of 39] IB/ipath - update copyrights and other strings to reflect new company name Bryan O'Sullivan
2006-06-29 21:40 ` [PATCH 3 of 39] IB/ipath - Share more common code between RC and UC protocols Bryan O'Sullivan
2006-06-29 21:40 ` [PATCH 4 of 39] IB/ipath - fix an indenting problem Bryan O'Sullivan
2006-06-29 21:40 ` [PATCH 5 of 39] IB/ipath - fix shared receive queues for RC Bryan O'Sullivan
2006-06-29 21:40 ` [PATCH 6 of 39] IB/ipath - Allow diags on any unit Bryan O'Sullivan
2006-06-29 21:40 ` [PATCH 7 of 39] IB/ipath - update some comments and fix typos Bryan O'Sullivan
2006-06-29 21:40 ` [PATCH 8 of 39] IB/ipath - remove some duplicate code Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 9 of 39] IB/ipath - don't allow resources to be created with illegal values Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 10 of 39] IB/ipath - fix some memory leaks on failure paths Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 11 of 39] IB/ipath - return an error for unknown multicast GID Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 12 of 39] IB/ipath - report correct device identification information in /sys Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 13 of 39] IB/ipath - enforce device resource limits Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 14 of 39] IB/ipath - removed unused field ipath_kregvirt from struct ipath_devdata Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 15 of 39] IB/ipath - print better debug info when handling 32/64-bit DMA mask problems Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 16 of 39] IB/ipath - enable freeze mode when shutting down device Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 17 of 39] IB/ipath - use more appropriate gfp flags Bryan O'Sullivan
2006-06-30  0:02   ` Andrew Morton
2006-06-29 21:41 ` [PATCH 18 of 39] IB/ipath - use vmalloc to allocate struct ipath_devdata Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 19 of 39] IB/ipath - memory management cleanups Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 20 of 39] IB/ipath - reduce overhead on receive interrupts Bryan O'Sullivan
2006-06-29 21:41 ` Bryan O'Sullivan [this message]
2006-06-29 21:41 ` [PATCH 22 of 39] IB/ipath - fix lost interrupts on HT-400 Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 23 of 39] IB/ipath - disallow send of invalid packet sizes over UD Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 24 of 39] IB/ipath - don't confuse the max message size with the MTU Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 25 of 39] IB/ipath - removed redundant statements Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 26 of 39] IB/ipath - check for valid LID and multicast LIDs Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 27 of 39] IB/ipath - fixes to performance get counters for IB compliance Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 28 of 39] IB/ipath - Fixes a bug where our delay for EEPROM no longer works due to compiler reordering Bryan O'Sullivan
2006-06-30  0:07   ` Andrew Morton
2006-06-30 21:08     ` Roland Dreier
2006-06-29 21:41 ` [PATCH 29 of 39] IB/ipath - RC receive interrupt performance changes Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 30 of 39] IB/ipath - purge sps_lid and sps_mlid arrays Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 31 of 39] IB/ipath - drop the "stats" sysfs attribute group Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 32 of 39] IB/ipath - support more models of InfiniPath hardware Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 33 of 39] IB/ipath - read/write correct sizes through diag interface Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 34 of 39] IB/ipath - fix a bug that results in addresses near 0 being written via DMA Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 35 of 39] IB/ipath - remove some #if 0 code related to lockable memory Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 36 of 39] IB/ipath - Ignore receive queue size if SRQ is specified Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 37 of 39] IB/ipath - namespace cleanup: replace ips with ipath Bryan O'Sullivan
2006-06-29 21:41 ` [PATCH 38 of 39] IB/ipath - More changes to support InfiniPath on PowerPC 970 systems Bryan O'Sullivan
2006-06-29 21:53   ` David Miller
2006-06-29 22:01     ` Bryan O'Sullivan
2006-06-29 22:04       ` David Miller
2006-07-03 22:25         ` Anton Blanchard
2006-07-04  4:55           ` Michael S. Tsirkin
2006-07-06 22:37   ` Benjamin Herrenschmidt
2006-07-06 23:34     ` Bryan O'Sullivan
2006-07-06 23:39       ` Benjamin Herrenschmidt
2006-06-29 21:41 ` [PATCH 39 of 39] IB/ipath - use streaming copy in RDMA interrupt handler to reduce packet loss Bryan O'Sullivan
2006-06-29 21:50   ` David Miller
2006-06-29 21:59     ` Bryan O'Sullivan
2006-06-29 22:03       ` David Miller
2006-06-29 23:34         ` Bryan O'Sullivan
2006-06-29 23:46           ` David Miller
2006-06-29 23:55             ` [openib-general] " Ralph Campbell
2006-06-30  0:28             ` Rick Jones
2006-06-30  0:32               ` David Miller
2006-06-30  0:44                 ` Rick Jones
2006-06-30  0:47                   ` David Miller
2006-06-30 16:31 ` [PATCH 0 of 39] ipath - bug fixes, performance enhancements,and portability improvements Michael S. Tsirkin
2006-06-30 17:00   ` Bryan O'Sullivan
2006-07-01 19:43     ` [PATCH 0 of 39] ipath - bug fixes, performanceenhancements,and " Michael S. Tsirkin
2006-07-01 22:35       ` Andrew Morton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1a4350d895c9a673c98e.1151617272@eng-12.pathscale.com \
    --to=bos@pathscale.com \
    --cc=akpm@osdl.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mst@mellanox.co.il \
    --cc=netdev@vger.kernel.org \
    --cc=openib-general@openib.org \
    --cc=rdreier@cisco.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®