From: "Bryan O'Sullivan" <bos@pathscale.com>
To: akpm@osdl.org, rdreier@cisco.com, mst@mellanox.co.il
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
openib-general@openib.org
Subject: [PATCH 5 of 39] IB/ipath - fix shared receive queues for RC
Date: Thu, 29 Jun 2006 14:40:56 -0700 [thread overview]
Message-ID: <e4f29a4e0c0fedcbe3c8.1151617256@eng-12.pathscale.com> (raw)
In-Reply-To: <patchbomb.1151617251@eng-12.pathscale.com>
Signed-off-by: Ralph Campbell <ralph.campbell@qlogic.com>
Signed-off-by: Bryan O'Sullivan <bryan.osullivan@qlogic.com>
diff -r c93c2b42d279 -r e4f29a4e0c0f drivers/infiniband/hw/ipath/ipath_rc.c
--- a/drivers/infiniband/hw/ipath/ipath_rc.c Thu Jun 29 14:33:25 2006 -0700
+++ b/drivers/infiniband/hw/ipath/ipath_rc.c Thu Jun 29 14:33:25 2006 -0700
@@ -257,7 +257,7 @@ int ipath_make_rc_req(struct ipath_qp *q
break;
case IB_WR_RDMA_WRITE:
- if (newreq)
+ if (newreq && qp->s_lsn != (u32) -1)
qp->s_lsn++;
/* FALLTHROUGH */
case IB_WR_RDMA_WRITE_WITH_IMM:
@@ -283,8 +283,7 @@ int ipath_make_rc_req(struct ipath_qp *q
else {
qp->s_state =
OP(RDMA_WRITE_ONLY_WITH_IMMEDIATE);
- /* Immediate data comes
- * after RETH */
+ /* Immediate data comes after RETH */
ohdr->u.rc.imm_data = wqe->wr.imm_data;
hwords += 1;
if (wqe->wr.send_flags & IB_SEND_SOLICITED)
@@ -304,7 +303,8 @@ int ipath_make_rc_req(struct ipath_qp *q
qp->s_state = OP(RDMA_READ_REQUEST);
hwords += sizeof(ohdr->u.rc.reth) / 4;
if (newreq) {
- qp->s_lsn++;
+ if (qp->s_lsn != (u32) -1)
+ qp->s_lsn++;
/*
* Adjust s_next_psn to count the
* expected number of responses.
@@ -335,7 +335,8 @@ int ipath_make_rc_req(struct ipath_qp *q
wqe->wr.wr.atomic.compare_add);
hwords += sizeof(struct ib_atomic_eth) / 4;
if (newreq) {
- qp->s_lsn++;
+ if (qp->s_lsn != (u32) -1)
+ qp->s_lsn++;
wqe->lpsn = wqe->psn;
}
if (++qp->s_cur == qp->s_size)
@@ -553,6 +554,88 @@ static void send_rc_ack(struct ipath_qp
}
/**
+ * reset_psn - reset the QP state to send starting from PSN
+ * @qp: the QP
+ * @psn: the packet sequence number to restart at
+ *
+ * This is called from ipath_rc_rcv() to process an incoming RC ACK
+ * for the given QP.
+ * Called at interrupt level with the QP s_lock held.
+ */
+static void reset_psn(struct ipath_qp *qp, u32 psn)
+{
+ u32 n = qp->s_last;
+ struct ipath_swqe *wqe = get_swqe_ptr(qp, n);
+ u32 opcode;
+
+ qp->s_cur = n;
+
+ /*
+ * If we are starting the request from the beginning,
+ * let the normal send code handle initialization.
+ */
+ if (ipath_cmp24(psn, wqe->psn) <= 0) {
+ qp->s_state = OP(SEND_LAST);
+ goto done;
+ }
+
+ /* Find the work request opcode corresponding to the given PSN. */
+ opcode = wqe->wr.opcode;
+ for (;;) {
+ int diff;
+
+ if (++n == qp->s_size)
+ n = 0;
+ if (n == qp->s_tail)
+ break;
+ wqe = get_swqe_ptr(qp, n);
+ diff = ipath_cmp24(psn, wqe->psn);
+ if (diff < 0)
+ break;
+ qp->s_cur = n;
+ /*
+ * If we are starting the request from the beginning,
+ * let the normal send code handle initialization.
+ */
+ if (diff == 0) {
+ qp->s_state = OP(SEND_LAST);
+ goto done;
+ }
+ opcode = wqe->wr.opcode;
+ }
+
+ /*
+ * Set the state to restart in the middle of a request.
+ * Don't change the s_sge, s_cur_sge, or s_cur_size.
+ * See ipath_do_rc_send().
+ */
+ switch (opcode) {
+ case IB_WR_SEND:
+ case IB_WR_SEND_WITH_IMM:
+ qp->s_state = OP(RDMA_READ_RESPONSE_FIRST);
+ break;
+
+ case IB_WR_RDMA_WRITE:
+ case IB_WR_RDMA_WRITE_WITH_IMM:
+ qp->s_state = OP(RDMA_READ_RESPONSE_LAST);
+ break;
+
+ case IB_WR_RDMA_READ:
+ qp->s_state = OP(RDMA_READ_RESPONSE_MIDDLE);
+ break;
+
+ default:
+ /*
+ * This case shouldn't happen since its only
+ * one PSN per req.
+ */
+ qp->s_state = OP(SEND_LAST);
+ }
+done:
+ qp->s_psn = psn;
+}
+
+/**
* ipath_restart_rc - back up requester to resend the last un-ACKed request
* @qp: the QP to restart
* @psn: packet sequence number for the request
@@ -564,7 +647,6 @@ void ipath_restart_rc(struct ipath_qp *q
{
struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last);
struct ipath_ibdev *dev;
- u32 n;
/*
* If there are no requests pending, we are done.
@@ -606,130 +688,13 @@ void ipath_restart_rc(struct ipath_qp *q
else
dev->n_rc_resends += (int)qp->s_psn - (int)psn;
- /*
- * If we are starting the request from the beginning, let the normal
- * send code handle initialization.
- */
- qp->s_cur = qp->s_last;
- if (ipath_cmp24(psn, wqe->psn) <= 0) {
- qp->s_state = OP(SEND_LAST);
- qp->s_psn = wqe->psn;
- } else {
- n = qp->s_cur;
- for (;;) {
- if (++n == qp->s_size)
- n = 0;
- if (n == qp->s_tail) {
- if (ipath_cmp24(psn, qp->s_next_psn) >= 0) {
- qp->s_cur = n;
- wqe = get_swqe_ptr(qp, n);
- }
- break;
- }
- wqe = get_swqe_ptr(qp, n);
- if (ipath_cmp24(psn, wqe->psn) < 0)
- break;
- qp->s_cur = n;
- }
- qp->s_psn = psn;
-
- /*
- * Reset the state to restart in the middle of a request.
- * Don't change the s_sge, s_cur_sge, or s_cur_size.
- * See ipath_do_rc_send().
- */
- switch (wqe->wr.opcode) {
- case IB_WR_SEND:
- case IB_WR_SEND_WITH_IMM:
- qp->s_state = OP(RDMA_READ_RESPONSE_FIRST);
- break;
-
- case IB_WR_RDMA_WRITE:
- case IB_WR_RDMA_WRITE_WITH_IMM:
- qp->s_state = OP(RDMA_READ_RESPONSE_LAST);
- break;
-
- case IB_WR_RDMA_READ:
- qp->s_state =
- OP(RDMA_READ_RESPONSE_MIDDLE);
- break;
-
- default:
- /*
- * This case shouldn't happen since its only
- * one PSN per req.
- */
- qp->s_state = OP(SEND_LAST);
- }
- }
+ reset_psn(qp, psn);
done:
tasklet_hi_schedule(&qp->s_task);
bail:
return;
-}
-
-/**
- * reset_psn - reset the QP state to send starting from PSN
- * @qp: the QP
- * @psn: the packet sequence number to restart at
- *
- * This is called from ipath_rc_rcv_resp() to process an incoming RC ACK
- * for the given QP.
- * Called at interrupt level with the QP s_lock held.
- */
-static void reset_psn(struct ipath_qp *qp, u32 psn)
-{
- struct ipath_swqe *wqe;
- u32 n;
-
- n = qp->s_cur;
- wqe = get_swqe_ptr(qp, n);
- for (;;) {
- if (++n == qp->s_size)
- n = 0;
- if (n == qp->s_tail) {
- if (ipath_cmp24(psn, qp->s_next_psn) >= 0) {
- qp->s_cur = n;
- wqe = get_swqe_ptr(qp, n);
- }
- break;
- }
- wqe = get_swqe_ptr(qp, n);
- if (ipath_cmp24(psn, wqe->psn) < 0)
- break;
- qp->s_cur = n;
- }
- qp->s_psn = psn;
-
- /*
- * Set the state to restart in the middle of a
- * request. Don't change the s_sge, s_cur_sge, or
- * s_cur_size. See ipath_do_rc_send().
- */
- switch (wqe->wr.opcode) {
- case IB_WR_SEND:
- case IB_WR_SEND_WITH_IMM:
- qp->s_state = OP(RDMA_READ_RESPONSE_FIRST);
- break;
-
- case IB_WR_RDMA_WRITE:
- case IB_WR_RDMA_WRITE_WITH_IMM:
- qp->s_state = OP(RDMA_READ_RESPONSE_LAST);
- break;
-
- case IB_WR_RDMA_READ:
- qp->s_state = OP(RDMA_READ_RESPONSE_MIDDLE);
- break;
-
- default:
- /*
- * This case shouldn't happen since its only
- * one PSN per req.
- */
- qp->s_state = OP(SEND_LAST);
- }
}
/**
@@ -738,7 +703,7 @@ static void reset_psn(struct ipath_qp *q
* @psn: the packet sequence number of the ACK
* @opcode: the opcode of the request that resulted in the ACK
*
- * This is called from ipath_rc_rcv() to process an incoming RC ACK
+ * This is called from ipath_rc_rcv_resp() to process an incoming RC ACK
* for the given QP.
* Called at interrupt level with the QP s_lock held.
* Returns 1 if OK, 0 if current operation should be aborted (NAK).
@@ -877,22 +842,12 @@ static int do_rc_ack(struct ipath_qp *qp
if (qp->s_last == qp->s_tail)
goto bail;
- /* The last valid PSN seen is the previous request's. */
- qp->s_last_psn = wqe->psn - 1;
+ /* The last valid PSN is the previous PSN. */
+ qp->s_last_psn = psn - 1;
dev->n_rc_resends += (int)qp->s_psn - (int)psn;
- /*
- * If we are starting the request from the beginning, let
- * the normal send code handle initialization.
- */
- qp->s_cur = qp->s_last;
- wqe = get_swqe_ptr(qp, qp->s_cur);
- if (ipath_cmp24(psn, wqe->psn) <= 0) {
- qp->s_state = OP(SEND_LAST);
- qp->s_psn = wqe->psn;
- } else
- reset_psn(qp, psn);
+ reset_psn(qp, psn);
qp->s_rnr_timeout =
ib_ipath_rnr_table[(aeth >> IPS_AETH_CREDIT_SHIFT) &
@@ -1070,9 +1025,10 @@ static inline void ipath_rc_rcv_resp(str
&dev->pending[dev->pending_index]);
spin_unlock(&dev->pending_lock);
/*
- * Update the RDMA receive state but do the copy w/o holding the
- * locks and blocking interrupts. XXX Yet another place that
- * affects relaxed RDMA order since we don't want s_sge modified.
+ * Update the RDMA receive state but do the copy w/o
+ * holding the locks and blocking interrupts.
+ * XXX Yet another place that affects relaxed RDMA order
+ * since we don't want s_sge modified.
*/
qp->s_len -= pmtu;
qp->s_last_psn = psn;
@@ -1119,9 +1075,12 @@ static inline void ipath_rc_rcv_resp(str
if (do_rc_ack(qp, aeth, psn, OP(RDMA_READ_RESPONSE_LAST))) {
/*
* Change the state so we contimue
- * processing new requests.
+ * processing new requests and wake up the
+ * tasklet if there are posted sends.
*/
qp->s_state = OP(SEND_LAST);
+ if (qp->s_tail != qp->s_head)
+ tasklet_hi_schedule(&qp->s_task);
}
goto ack_done;
}
next prev parent reply other threads:[~2006-06-29 21:40 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 ` Bryan O'Sullivan [this message]
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 ` [PATCH 21 of 39] IB/ipath - fixed bug 9776 for real. The problem was that I was updating Bryan O'Sullivan
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=e4f29a4e0c0fedcbe3c8.1151617256@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;
as well as URLs for NNTP newsgroup(s).