From: "Bryan O'Sullivan" <bos@pathscale.com>
To: rdreier@cisco.com
Cc: openib-general@openib.org, linux-kernel@vger.kernel.org
Subject: [PATCH 34 of 53] ipath - fix occasional hangs in SDP
Date: Fri, 12 May 2006 16:43:19 -0700 [thread overview]
Message-ID: <09077b2f476f80594b82.1147477399@eng-12.pathscale.com> (raw)
In-Reply-To: <patchbomb.1147477365@eng-12.pathscale.com>
We were updating 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.
Signed-off-by: Bryan O'Sullivan <bos@pathscale.com>
diff -r 5ddaf7c07cdf -r 09077b2f476f drivers/infiniband/hw/ipath/ipath_driver.c
--- a/drivers/infiniband/hw/ipath/ipath_driver.c Fri May 12 15:55:28 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_driver.c Fri May 12 15:55:28 2006 -0700
@@ -918,7 +918,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];
@@ -932,14 +932,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;
@@ -1050,15 +1050,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 5ddaf7c07cdf -r 09077b2f476f drivers/infiniband/hw/ipath/ipath_intr.c
--- a/drivers/infiniband/hw/ipath/ipath_intr.c Fri May 12 15:55:28 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_intr.c Fri May 12 15:55:28 2006 -0700
@@ -350,7 +350,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;
@@ -434,7 +434,7 @@ static void handle_errors(struct ipath_d
INFINIPATH_E_IBSTATUSCHANGED);
}
if (!errs)
- return;
+ return 0;
if (!noprint)
/*
@@ -558,9 +558,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() */
@@ -716,13 +714,14 @@ static void handle_urcv(struct ipath_dev
}
}
+
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);
@@ -764,9 +763,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));
@@ -783,6 +781,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 */
@@ -820,10 +820,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.
@@ -845,8 +846,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
@@ -858,18 +861,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 <<
next prev parent reply other threads:[~2006-05-13 0:01 UTC|newest]
Thread overview: 87+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-05-12 23:42 [PATCH 0 of 53] ipath driver updates for 2.6.17-rc4 Bryan O'Sullivan
2006-05-12 23:42 ` [PATCH 1 of 53] ipath - fix spinlock recursion bug Bryan O'Sullivan
2006-05-13 1:01 ` Joshua Hudson
2006-05-12 23:42 ` [PATCH 2 of 53] ipath - purge sps_lid and sps_mlid arrays, and /sys entries Bryan O'Sullivan
2006-05-12 23:42 ` [PATCH 3 of 53] ipath - report max MR and QP sizes based on table sizes Bryan O'Sullivan
2006-05-12 23:42 ` [PATCH 4 of 53] ipath - cap number of PDs that can be allocated Bryan O'Sullivan
2006-05-15 15:45 ` Roland Dreier
2006-05-15 21:06 ` Bryan O'Sullivan
2006-05-12 23:42 ` [PATCH 5 of 53] ipath - forbid creation of AHs with illegal ports Bryan O'Sullivan
2006-05-12 23:42 ` [PATCH 6 of 53] ipath - forbid creation of AH with DLID of 0 Bryan O'Sullivan
2006-05-12 23:42 ` [PATCH 7 of 53] ipath - cap maximum number of AHs Bryan O'Sullivan
2006-05-12 23:42 ` [PATCH 8 of 53] ipath - cap number of CQEs Bryan O'Sullivan
2006-05-12 23:42 ` [PATCH 9 of 53] ipath - cap number of CQs Bryan O'Sullivan
2006-05-12 23:42 ` [PATCH 10 of 53] ipath - require capabilities when creating a QP Bryan O'Sullivan
2006-05-12 23:42 ` [PATCH 11 of 53] ipath - don't modify QP if changes fail Bryan O'Sullivan
2006-05-12 23:42 ` [PATCH 12 of 53] ipath - reduce overhead of receive interrupts Bryan O'Sullivan
2006-05-12 23:42 ` [PATCH 13 of 53] ipath - limit number of SGEs and WRs per QP Bryan O'Sullivan
2006-05-12 23:42 ` [PATCH 14 of 53] ipath - forbid empty MRs Bryan O'Sullivan
2006-05-15 15:46 ` Roland Dreier
2006-05-15 21:17 ` Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 15 of 53] ipath - make some maximum values more sane Bryan O'Sullivan
2006-05-15 15:48 ` Roland Dreier
2006-05-16 22:44 ` [openib-general] " Arlin Davis
2006-05-12 23:43 ` [PATCH 16 of 53] ipath - fix reporting of driver version to userspace Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 17 of 53] ipath - fail properly if GID missing Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 18 of 53] ipath - make max mcast sizes configurable Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 19 of 53] ipath - replace uses of LIST_POISON Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 20 of 53] ipath - more sharing between RC and UC code Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 21 of 53] ipath - use phys_to_virt instead of bus_to_virt Bryan O'Sullivan
2006-05-15 15:50 ` Roland Dreier
2006-05-15 21:21 ` Bryan O'Sullivan
2006-05-15 21:28 ` Roland Dreier
2006-05-15 23:13 ` [openib-general] " Grant Grundler
2006-05-15 23:16 ` Roland Dreier
2006-05-15 23:30 ` Grant Grundler
2006-05-15 23:34 ` Roland Dreier
2006-05-16 20:05 ` Christoph Hellwig
2006-05-12 23:43 ` [PATCH 22 of 53] ipath - fix "many lost ticks" warning Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 23 of 53] ipath - [TRIVIAL] typo fixes Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 24 of 53] ipath - count dropped VL15 packets Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 25 of 53] ipath - remove some duplicated lines of code Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 26 of 53] ipath - treat PE800 rev1 and rev2 as similar Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 27 of 53] ipath - fix accounting of data packets with bad VLs Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 28 of 53] ipath - forbid setting of invalid MLID Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 29 of 53] ipath - remove redundant register read Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 30 of 53] ipath - count VL15 packet drops due to bad VL or lack of buffers Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 31 of 53] ipath - forbid sending of bad packet sizes Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 32 of 53] ipath - fix NULL dereference during cleanup Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 33 of 53] ipath - clean up some comments Bryan O'Sullivan
2006-05-12 23:43 ` Bryan O'Sullivan [this message]
2006-05-12 23:43 ` [PATCH 35 of 53] ipath - some interrelated stability and cleanliness fixes Bryan O'Sullivan
2006-05-15 15:53 ` Roland Dreier
2006-05-12 23:43 ` [PATCH 36 of 53] ipath - count local link integrity errors Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 37 of 53] ipath - name zero counter offsets consistently Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 38 of 53] ipath - SRQ compliance checks Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 39 of 53] ipath - count PE800 receive interrupts on user ports Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 40 of 53] ipath - remember to drop spinlock Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 41 of 53] ipath - disable interrupts while holding spinlock in RWQE get Bryan O'Sullivan
2006-05-15 15:55 ` Roland Dreier
2006-05-12 23:43 ` [PATCH 42 of 53] ipath - increment pointer properly when doing a diag read Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 43 of 53] ipath - fix memory leak when creating a QP fails Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 44 of 53] ipath - allow diags on any unit Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 45 of 53] ipath - fix memory leak when create of QP fails Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 46 of 53] ipath - enable GPIO interrupt on HT-460 Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 47 of 53] ipath - fix problem with lost interrupts on HT-400 Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 48 of 53] ipath - QP should ignore receive queue size if SRQ specified Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 49 of 53] ipath - NULL-terminate pci_device_id table Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 50 of 53] ipath - reduce maximum table sizes Bryan O'Sullivan
2006-05-15 16:00 ` Roland Dreier
2006-05-12 23:43 ` [PATCH 51 of 53] ipath - fix reporting of vendor ID and a few other trivial bits Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 52 of 53] ipath - register as IB device owner Bryan O'Sullivan
2006-05-12 23:43 ` [PATCH 53 of 53] ipath - add memory barrier when waiting for writes Bryan O'Sullivan
2006-05-15 15:57 ` Roland Dreier
2006-05-15 21:10 ` Bryan O'Sullivan
2006-05-15 23:01 ` ralphc
2006-05-15 23:08 ` Roland Dreier
2006-05-15 23:25 ` ralphc
2006-05-15 23:28 ` [openib-general] " Roland Dreier
2006-05-15 23:38 ` ralphc
2006-05-15 23:47 ` Roland Dreier
2006-05-15 15:02 ` [openib-general] [PATCH 0 of 53] ipath driver updates for 2.6.17-rc4 Roger Heflin
2006-05-15 15:44 ` Roland Dreier
2006-05-15 16:00 ` [openib-general] " Roger Heflin
2006-05-15 16:04 ` Roland Dreier
2006-05-15 20:11 ` Roger Heflin
2006-05-15 21:09 ` Bryan O'Sullivan
2006-05-15 21:07 ` Bryan O'Sullivan
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=09077b2f476f80594b82.1147477399@eng-12.pathscale.com \
--to=bos@pathscale.com \
--cc=linux-kernel@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
Powered by JetHome