Commit e52e6080 authored by Tom Tucker's avatar Tom Tucker Committed by Roland Dreier

RDMA/amso1100: Add spinlocks to serialize ib_post_send/ib_post_recv

The AMSO driver was not thread-safe in the post WR code and had
code that would sleep if the WR post FIFO was full. Since these
functions can be called on interrupt level I changed the sleep to a
udelay.
Signed-off-by: default avatarTom Tucker <tom@opengridcomputing.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent ebf7a227
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
* *
*/ */
#include <linux/delay.h>
#include "c2.h" #include "c2.h"
#include "c2_vq.h" #include "c2_vq.h"
#include "c2_status.h" #include "c2_status.h"
...@@ -705,10 +707,8 @@ static inline void c2_activity(struct c2_dev *c2dev, u32 mq_index, u16 shared) ...@@ -705,10 +707,8 @@ static inline void c2_activity(struct c2_dev *c2dev, u32 mq_index, u16 shared)
* cannot get on the bus and the card and system hang in a * cannot get on the bus and the card and system hang in a
* deadlock -- thus the need for this code. [TOT] * deadlock -- thus the need for this code. [TOT]
*/ */
while (readl(c2dev->regs + PCI_BAR0_ADAPTER_HINT) & 0x80000000) { while (readl(c2dev->regs + PCI_BAR0_ADAPTER_HINT) & 0x80000000)
set_current_state(TASK_UNINTERRUPTIBLE); udelay(10);
schedule_timeout(0);
}
__raw_writel(C2_HINT_MAKE(mq_index, shared), __raw_writel(C2_HINT_MAKE(mq_index, shared),
c2dev->regs + PCI_BAR0_ADAPTER_HINT); c2dev->regs + PCI_BAR0_ADAPTER_HINT);
...@@ -766,6 +766,7 @@ int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, ...@@ -766,6 +766,7 @@ int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr,
struct c2_dev *c2dev = to_c2dev(ibqp->device); struct c2_dev *c2dev = to_c2dev(ibqp->device);
struct c2_qp *qp = to_c2qp(ibqp); struct c2_qp *qp = to_c2qp(ibqp);
union c2wr wr; union c2wr wr;
unsigned long lock_flags;
int err = 0; int err = 0;
u32 flags; u32 flags;
...@@ -881,8 +882,10 @@ int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, ...@@ -881,8 +882,10 @@ int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr,
/* /*
* Post the puppy! * Post the puppy!
*/ */
spin_lock_irqsave(&qp->lock, lock_flags);
err = qp_wr_post(&qp->sq_mq, &wr, qp, msg_size); err = qp_wr_post(&qp->sq_mq, &wr, qp, msg_size);
if (err) { if (err) {
spin_unlock_irqrestore(&qp->lock, lock_flags);
break; break;
} }
...@@ -890,6 +893,7 @@ int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, ...@@ -890,6 +893,7 @@ int c2_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr,
* Enqueue mq index to activity FIFO. * Enqueue mq index to activity FIFO.
*/ */
c2_activity(c2dev, qp->sq_mq.index, qp->sq_mq.hint_count); c2_activity(c2dev, qp->sq_mq.index, qp->sq_mq.hint_count);
spin_unlock_irqrestore(&qp->lock, lock_flags);
ib_wr = ib_wr->next; ib_wr = ib_wr->next;
} }
...@@ -905,6 +909,7 @@ int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, ...@@ -905,6 +909,7 @@ int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr,
struct c2_dev *c2dev = to_c2dev(ibqp->device); struct c2_dev *c2dev = to_c2dev(ibqp->device);
struct c2_qp *qp = to_c2qp(ibqp); struct c2_qp *qp = to_c2qp(ibqp);
union c2wr wr; union c2wr wr;
unsigned long lock_flags;
int err = 0; int err = 0;
if (qp->state > IB_QPS_RTS) if (qp->state > IB_QPS_RTS)
...@@ -945,8 +950,10 @@ int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, ...@@ -945,8 +950,10 @@ int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr,
break; break;
} }
spin_lock_irqsave(&qp->lock, lock_flags);
err = qp_wr_post(&qp->rq_mq, &wr, qp, qp->rq_mq.msg_size); err = qp_wr_post(&qp->rq_mq, &wr, qp, qp->rq_mq.msg_size);
if (err) { if (err) {
spin_unlock_irqrestore(&qp->lock, lock_flags);
break; break;
} }
...@@ -954,6 +961,7 @@ int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr, ...@@ -954,6 +961,7 @@ int c2_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *ib_wr,
* Enqueue mq index to activity FIFO * Enqueue mq index to activity FIFO
*/ */
c2_activity(c2dev, qp->rq_mq.index, qp->rq_mq.hint_count); c2_activity(c2dev, qp->rq_mq.index, qp->rq_mq.hint_count);
spin_unlock_irqrestore(&qp->lock, lock_flags);
ib_wr = ib_wr->next; ib_wr = ib_wr->next;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment