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:
Steve Wise 2010-09-10 11:15:25 -05:00 committed by Roland Dreier
parent 9e8d1fa342
commit aadc4df308
5 changed files with 72 additions and 111 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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;
}; };

View File

@ -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;
} }

View File

@ -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;