RDMA/cxgb4: Centralize the wait logic
Signed-off-by: Steve Wise <swise@opengridcomputing.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
parent
9e8d1fa342
commit
aadc4df308
5 changed files with 72 additions and 111 deletions
|
@ -252,7 +252,7 @@ static void *alloc_ep(int size, gfp_t gfp)
|
||||||
if (epc) {
|
if (epc) {
|
||||||
kref_init(&epc->kref);
|
kref_init(&epc->kref);
|
||||||
spin_lock_init(&epc->lock);
|
spin_lock_init(&epc->lock);
|
||||||
init_waitqueue_head(&epc->waitq);
|
c4iw_init_wr_wait(&epc->wr_wait);
|
||||||
}
|
}
|
||||||
PDBG("%s alloc ep %p\n", __func__, epc);
|
PDBG("%s alloc ep %p\n", __func__, epc);
|
||||||
return epc;
|
return epc;
|
||||||
|
@ -1213,9 +1213,9 @@ static int pass_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
|
||||||
}
|
}
|
||||||
PDBG("%s ep %p status %d error %d\n", __func__, ep,
|
PDBG("%s ep %p status %d error %d\n", __func__, ep,
|
||||||
rpl->status, status2errno(rpl->status));
|
rpl->status, status2errno(rpl->status));
|
||||||
ep->com.rpl_err = status2errno(rpl->status);
|
ep->com.wr_wait.ret = status2errno(rpl->status);
|
||||||
ep->com.rpl_done = 1;
|
ep->com.wr_wait.done = 1;
|
||||||
wake_up(&ep->com.waitq);
|
wake_up(&ep->com.wr_wait.wait);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1249,9 +1249,9 @@ static int close_listsrv_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
|
||||||
struct c4iw_listen_ep *ep = lookup_stid(t, stid);
|
struct c4iw_listen_ep *ep = lookup_stid(t, stid);
|
||||||
|
|
||||||
PDBG("%s ep %p\n", __func__, ep);
|
PDBG("%s ep %p\n", __func__, ep);
|
||||||
ep->com.rpl_err = status2errno(rpl->status);
|
ep->com.wr_wait.ret = status2errno(rpl->status);
|
||||||
ep->com.rpl_done = 1;
|
ep->com.wr_wait.done = 1;
|
||||||
wake_up(&ep->com.waitq);
|
wake_up(&ep->com.wr_wait.wait);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1507,17 +1507,17 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb)
|
||||||
* in rdma connection migration (see c4iw_accept_cr()).
|
* in rdma connection migration (see c4iw_accept_cr()).
|
||||||
*/
|
*/
|
||||||
__state_set(&ep->com, CLOSING);
|
__state_set(&ep->com, CLOSING);
|
||||||
ep->com.rpl_done = 1;
|
ep->com.wr_wait.done = 1;
|
||||||
ep->com.rpl_err = -ECONNRESET;
|
ep->com.wr_wait.ret = -ECONNRESET;
|
||||||
PDBG("waking up ep %p tid %u\n", ep, ep->hwtid);
|
PDBG("waking up ep %p tid %u\n", ep, ep->hwtid);
|
||||||
wake_up(&ep->com.waitq);
|
wake_up(&ep->com.wr_wait.wait);
|
||||||
break;
|
break;
|
||||||
case MPA_REP_SENT:
|
case MPA_REP_SENT:
|
||||||
__state_set(&ep->com, CLOSING);
|
__state_set(&ep->com, CLOSING);
|
||||||
ep->com.rpl_done = 1;
|
ep->com.wr_wait.done = 1;
|
||||||
ep->com.rpl_err = -ECONNRESET;
|
ep->com.wr_wait.ret = -ECONNRESET;
|
||||||
PDBG("waking up ep %p tid %u\n", ep, ep->hwtid);
|
PDBG("waking up ep %p tid %u\n", ep, ep->hwtid);
|
||||||
wake_up(&ep->com.waitq);
|
wake_up(&ep->com.wr_wait.wait);
|
||||||
break;
|
break;
|
||||||
case FPDU_MODE:
|
case FPDU_MODE:
|
||||||
start_ep_timer(ep);
|
start_ep_timer(ep);
|
||||||
|
@ -1605,10 +1605,10 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb)
|
||||||
connect_reply_upcall(ep, -ECONNRESET);
|
connect_reply_upcall(ep, -ECONNRESET);
|
||||||
break;
|
break;
|
||||||
case MPA_REP_SENT:
|
case MPA_REP_SENT:
|
||||||
ep->com.rpl_done = 1;
|
ep->com.wr_wait.done = 1;
|
||||||
ep->com.rpl_err = -ECONNRESET;
|
ep->com.wr_wait.ret = -ECONNRESET;
|
||||||
PDBG("waking up ep %p\n", ep);
|
PDBG("waking up ep %p\n", ep);
|
||||||
wake_up(&ep->com.waitq);
|
wake_up(&ep->com.wr_wait.wait);
|
||||||
break;
|
break;
|
||||||
case MPA_REQ_RCVD:
|
case MPA_REQ_RCVD:
|
||||||
|
|
||||||
|
@ -1618,10 +1618,10 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb)
|
||||||
* rejects the CR. Also wake up anyone waiting
|
* rejects the CR. Also wake up anyone waiting
|
||||||
* in rdma connection migration (see c4iw_accept_cr()).
|
* in rdma connection migration (see c4iw_accept_cr()).
|
||||||
*/
|
*/
|
||||||
ep->com.rpl_done = 1;
|
ep->com.wr_wait.done = 1;
|
||||||
ep->com.rpl_err = -ECONNRESET;
|
ep->com.wr_wait.ret = -ECONNRESET;
|
||||||
PDBG("waking up ep %p tid %u\n", ep, ep->hwtid);
|
PDBG("waking up ep %p tid %u\n", ep, ep->hwtid);
|
||||||
wake_up(&ep->com.waitq);
|
wake_up(&ep->com.wr_wait.wait);
|
||||||
break;
|
break;
|
||||||
case MORIBUND:
|
case MORIBUND:
|
||||||
case CLOSING:
|
case CLOSING:
|
||||||
|
@ -2043,6 +2043,7 @@ int c4iw_create_listen(struct iw_cm_id *cm_id, int backlog)
|
||||||
}
|
}
|
||||||
|
|
||||||
state_set(&ep->com, LISTEN);
|
state_set(&ep->com, LISTEN);
|
||||||
|
c4iw_init_wr_wait(&ep->com.wr_wait);
|
||||||
err = cxgb4_create_server(ep->com.dev->rdev.lldi.ports[0], ep->stid,
|
err = cxgb4_create_server(ep->com.dev->rdev.lldi.ports[0], ep->stid,
|
||||||
ep->com.local_addr.sin_addr.s_addr,
|
ep->com.local_addr.sin_addr.s_addr,
|
||||||
ep->com.local_addr.sin_port,
|
ep->com.local_addr.sin_port,
|
||||||
|
@ -2051,15 +2052,8 @@ int c4iw_create_listen(struct iw_cm_id *cm_id, int backlog)
|
||||||
goto fail3;
|
goto fail3;
|
||||||
|
|
||||||
/* wait for pass_open_rpl */
|
/* wait for pass_open_rpl */
|
||||||
wait_event_timeout(ep->com.waitq, ep->com.rpl_done, C4IW_WR_TO);
|
err = c4iw_wait_for_reply(&ep->com.dev->rdev, &ep->com.wr_wait, 0, 0,
|
||||||
if (ep->com.rpl_done)
|
__func__);
|
||||||
err = ep->com.rpl_err;
|
|
||||||
else {
|
|
||||||
printk(KERN_ERR MOD "Device %s not responding!\n",
|
|
||||||
pci_name(ep->com.dev->rdev.lldi.pdev));
|
|
||||||
ep->com.dev->rdev.flags = T4_FATAL_ERROR;
|
|
||||||
err = -EIO;
|
|
||||||
}
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
cm_id->provider_data = ep;
|
cm_id->provider_data = ep;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -2083,20 +2077,12 @@ int c4iw_destroy_listen(struct iw_cm_id *cm_id)
|
||||||
|
|
||||||
might_sleep();
|
might_sleep();
|
||||||
state_set(&ep->com, DEAD);
|
state_set(&ep->com, DEAD);
|
||||||
ep->com.rpl_done = 0;
|
c4iw_init_wr_wait(&ep->com.wr_wait);
|
||||||
ep->com.rpl_err = 0;
|
|
||||||
err = listen_stop(ep);
|
err = listen_stop(ep);
|
||||||
if (err)
|
if (err)
|
||||||
goto done;
|
goto done;
|
||||||
wait_event_timeout(ep->com.waitq, ep->com.rpl_done, C4IW_WR_TO);
|
err = c4iw_wait_for_reply(&ep->com.dev->rdev, &ep->com.wr_wait, 0, 0,
|
||||||
if (ep->com.rpl_done)
|
__func__);
|
||||||
err = ep->com.rpl_err;
|
|
||||||
else {
|
|
||||||
printk(KERN_ERR MOD "Device %s not responding!\n",
|
|
||||||
pci_name(ep->com.dev->rdev.lldi.pdev));
|
|
||||||
ep->com.dev->rdev.flags = T4_FATAL_ERROR;
|
|
||||||
err = -EIO;
|
|
||||||
}
|
|
||||||
cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid, PF_INET);
|
cxgb4_free_stid(ep->com.dev->rdev.lldi.tids, ep->stid, PF_INET);
|
||||||
done:
|
done:
|
||||||
cm_id->rem_ref(cm_id);
|
cm_id->rem_ref(cm_id);
|
||||||
|
|
|
@ -64,14 +64,7 @@ static int destroy_cq(struct c4iw_rdev *rdev, struct t4_cq *cq,
|
||||||
c4iw_init_wr_wait(&wr_wait);
|
c4iw_init_wr_wait(&wr_wait);
|
||||||
ret = c4iw_ofld_send(rdev, skb);
|
ret = c4iw_ofld_send(rdev, skb);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
wait_event_timeout(wr_wait.wait, wr_wait.done, C4IW_WR_TO);
|
ret = c4iw_wait_for_reply(rdev, &wr_wait, 0, 0, __func__);
|
||||||
if (!wr_wait.done) {
|
|
||||||
printk(KERN_ERR MOD "Device %s not responding!\n",
|
|
||||||
pci_name(rdev->lldi.pdev));
|
|
||||||
rdev->flags = T4_FATAL_ERROR;
|
|
||||||
ret = -EIO;
|
|
||||||
} else
|
|
||||||
ret = wr_wait.ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
kfree(cq->sw_queue);
|
kfree(cq->sw_queue);
|
||||||
|
@ -157,14 +150,7 @@ static int create_cq(struct c4iw_rdev *rdev, struct t4_cq *cq,
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err4;
|
goto err4;
|
||||||
PDBG("%s wait_event wr_wait %p\n", __func__, &wr_wait);
|
PDBG("%s wait_event wr_wait %p\n", __func__, &wr_wait);
|
||||||
wait_event_timeout(wr_wait.wait, wr_wait.done, C4IW_WR_TO);
|
ret = c4iw_wait_for_reply(rdev, &wr_wait, 0, 0, __func__);
|
||||||
if (!wr_wait.done) {
|
|
||||||
printk(KERN_ERR MOD "Device %s not responding!\n",
|
|
||||||
pci_name(rdev->lldi.pdev));
|
|
||||||
rdev->flags = T4_FATAL_ERROR;
|
|
||||||
ret = -EIO;
|
|
||||||
} else
|
|
||||||
ret = wr_wait.ret;
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err4;
|
goto err4;
|
||||||
|
|
||||||
|
|
|
@ -79,21 +79,6 @@ static inline void *cplhdr(struct sk_buff *skb)
|
||||||
return skb->data;
|
return skb->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define C4IW_WR_TO (10*HZ)
|
|
||||||
|
|
||||||
struct c4iw_wr_wait {
|
|
||||||
wait_queue_head_t wait;
|
|
||||||
int done;
|
|
||||||
int ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void c4iw_init_wr_wait(struct c4iw_wr_wait *wr_waitp)
|
|
||||||
{
|
|
||||||
wr_waitp->ret = 0;
|
|
||||||
wr_waitp->done = 0;
|
|
||||||
init_waitqueue_head(&wr_waitp->wait);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct c4iw_resource {
|
struct c4iw_resource {
|
||||||
struct kfifo tpt_fifo;
|
struct kfifo tpt_fifo;
|
||||||
spinlock_t tpt_fifo_lock;
|
spinlock_t tpt_fifo_lock;
|
||||||
|
@ -141,6 +126,44 @@ static inline int c4iw_num_stags(struct c4iw_rdev *rdev)
|
||||||
return min((int)T4_MAX_NUM_STAG, (int)(rdev->lldi.vr->stag.size >> 5));
|
return min((int)T4_MAX_NUM_STAG, (int)(rdev->lldi.vr->stag.size >> 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define C4IW_WR_TO (10*HZ)
|
||||||
|
|
||||||
|
struct c4iw_wr_wait {
|
||||||
|
wait_queue_head_t wait;
|
||||||
|
int done;
|
||||||
|
int ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void c4iw_init_wr_wait(struct c4iw_wr_wait *wr_waitp)
|
||||||
|
{
|
||||||
|
wr_waitp->ret = 0;
|
||||||
|
wr_waitp->done = 0;
|
||||||
|
init_waitqueue_head(&wr_waitp->wait);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int c4iw_wait_for_reply(struct c4iw_rdev *rdev,
|
||||||
|
struct c4iw_wr_wait *wr_waitp,
|
||||||
|
u32 hwtid, u32 qpid,
|
||||||
|
const char *func)
|
||||||
|
{
|
||||||
|
unsigned to = C4IW_WR_TO;
|
||||||
|
do {
|
||||||
|
|
||||||
|
wait_event_timeout(wr_waitp->wait, wr_waitp->done, to);
|
||||||
|
if (!wr_waitp->done) {
|
||||||
|
printk(KERN_ERR MOD "%s - Device %s not responding - "
|
||||||
|
"tid %u qpid %u\n", func,
|
||||||
|
pci_name(rdev->lldi.pdev), hwtid, qpid);
|
||||||
|
to = to << 2;
|
||||||
|
}
|
||||||
|
} while (!wr_waitp->done);
|
||||||
|
if (wr_waitp->ret)
|
||||||
|
printk(KERN_WARNING MOD "%s: FW reply %d tid %u qpid %u\n",
|
||||||
|
pci_name(rdev->lldi.pdev), wr_waitp->ret, hwtid, qpid);
|
||||||
|
return wr_waitp->ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct c4iw_dev {
|
struct c4iw_dev {
|
||||||
struct ib_device ibdev;
|
struct ib_device ibdev;
|
||||||
struct c4iw_rdev rdev;
|
struct c4iw_rdev rdev;
|
||||||
|
@ -582,9 +605,7 @@ struct c4iw_ep_common {
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
struct sockaddr_in local_addr;
|
struct sockaddr_in local_addr;
|
||||||
struct sockaddr_in remote_addr;
|
struct sockaddr_in remote_addr;
|
||||||
wait_queue_head_t waitq;
|
struct c4iw_wr_wait wr_wait;
|
||||||
int rpl_done;
|
|
||||||
int rpl_err;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -103,14 +103,7 @@ static int write_adapter_mem(struct c4iw_rdev *rdev, u32 addr, u32 len,
|
||||||
len -= C4IW_MAX_INLINE_SIZE;
|
len -= C4IW_MAX_INLINE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
wait_event_timeout(wr_wait.wait, wr_wait.done, C4IW_WR_TO);
|
ret = c4iw_wait_for_reply(rdev, &wr_wait, 0, 0, __func__);
|
||||||
if (!wr_wait.done) {
|
|
||||||
printk(KERN_ERR MOD "Device %s not responding!\n",
|
|
||||||
pci_name(rdev->lldi.pdev));
|
|
||||||
rdev->flags = T4_FATAL_ERROR;
|
|
||||||
ret = -EIO;
|
|
||||||
} else
|
|
||||||
ret = wr_wait.ret;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -198,14 +198,7 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq,
|
||||||
ret = c4iw_ofld_send(rdev, skb);
|
ret = c4iw_ofld_send(rdev, skb);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err7;
|
goto err7;
|
||||||
wait_event_timeout(wr_wait.wait, wr_wait.done, C4IW_WR_TO);
|
ret = c4iw_wait_for_reply(rdev, &wr_wait, 0, wq->sq.qid, __func__);
|
||||||
if (!wr_wait.done) {
|
|
||||||
printk(KERN_ERR MOD "Device %s not responding!\n",
|
|
||||||
pci_name(rdev->lldi.pdev));
|
|
||||||
rdev->flags = T4_FATAL_ERROR;
|
|
||||||
ret = -EIO;
|
|
||||||
} else
|
|
||||||
ret = wr_wait.ret;
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err7;
|
goto err7;
|
||||||
|
|
||||||
|
@ -997,20 +990,8 @@ static int rdma_fini(struct c4iw_dev *rhp, struct c4iw_qp *qhp,
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
wait_event_timeout(wr_wait.wait, wr_wait.done, C4IW_WR_TO);
|
ret = c4iw_wait_for_reply(&rhp->rdev, &wr_wait, qhp->ep->hwtid,
|
||||||
if (!wr_wait.done) {
|
qhp->wq.sq.qid, __func__);
|
||||||
printk(KERN_ERR MOD "Device %s not responding!\n",
|
|
||||||
pci_name(rhp->rdev.lldi.pdev));
|
|
||||||
rhp->rdev.flags = T4_FATAL_ERROR;
|
|
||||||
ret = -EIO;
|
|
||||||
} else {
|
|
||||||
ret = wr_wait.ret;
|
|
||||||
if (ret)
|
|
||||||
printk(KERN_WARNING MOD
|
|
||||||
"%s: Abnormal close qpid %d ret %u\n",
|
|
||||||
pci_name(rhp->rdev.lldi.pdev), qhp->wq.sq.qid,
|
|
||||||
ret);
|
|
||||||
}
|
|
||||||
out:
|
out:
|
||||||
PDBG("%s ret %d\n", __func__, ret);
|
PDBG("%s ret %d\n", __func__, ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1106,14 +1087,8 @@ static int rdma_init(struct c4iw_dev *rhp, struct c4iw_qp *qhp)
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
wait_event_timeout(wr_wait.wait, wr_wait.done, C4IW_WR_TO);
|
ret = c4iw_wait_for_reply(&rhp->rdev, &wr_wait, qhp->ep->hwtid,
|
||||||
if (!wr_wait.done) {
|
qhp->wq.sq.qid, __func__);
|
||||||
printk(KERN_ERR MOD "Device %s not responding!\n",
|
|
||||||
pci_name(rhp->rdev.lldi.pdev));
|
|
||||||
rhp->rdev.flags = T4_FATAL_ERROR;
|
|
||||||
ret = -EIO;
|
|
||||||
} else
|
|
||||||
ret = wr_wait.ret;
|
|
||||||
out:
|
out:
|
||||||
PDBG("%s ret %d\n", __func__, ret);
|
PDBG("%s ret %d\n", __func__, ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Reference in a new issue