aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/cxgbe
diff options
context:
space:
mode:
authorNavdeep Parhar <np@FreeBSD.org>2017-03-15 19:10:04 +0000
committerNavdeep Parhar <np@FreeBSD.org>2017-03-15 19:10:04 +0000
commit94036cfff000da537f842ad8708c9c042df6a966 (patch)
tree394236eed3e596607329d992dd2e484074f5118a /sys/dev/cxgbe
parent4c0fdc5a3d80e4a9dce5800d6d4c2f7fc60fcd87 (diff)
downloadsrc-94036cfff000da537f842ad8708c9c042df6a966.tar.gz
src-94036cfff000da537f842ad8708c9c042df6a966.zip
cxgbe/iw_cxgbe: Use the socket and not the toepcb to reach for the
inpcb. t4_tom detaches the inpcb from the toepcb as soon as the hardware is done with the connection (in final_cpl_received) but the socket is around as long as the cm_id and the rest of iWARP state is. This fixes an intermittent NULL dereference during abort. Submitted by: KrishnamRaju ErapaRaju @ Chelsio MFC after: 3 days Sponsored by: Chelsio Communications
Notes
Notes: svn path=/head/; revision=315325
Diffstat (limited to 'sys/dev/cxgbe')
-rw-r--r--sys/dev/cxgbe/iw_cxgbe/qp.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/sys/dev/cxgbe/iw_cxgbe/qp.c b/sys/dev/cxgbe/iw_cxgbe/qp.c
index 4bfd02806d77..3bc1a96aee13 100644
--- a/sys/dev/cxgbe/iw_cxgbe/qp.c
+++ b/sys/dev/cxgbe/iw_cxgbe/qp.c
@@ -64,7 +64,7 @@ struct cpl_set_tcb_rpl;
#include "iw_cxgbe.h"
#include "user.h"
-static void creds(struct toepcb *toep, size_t wrsize);
+static int creds(struct toepcb *toep, struct inpcb *inp, size_t wrsize);
static void set_state(struct c4iw_qp *qhp, enum c4iw_qp_state state)
@@ -961,6 +961,7 @@ static inline void build_term_codes(struct t4_cqe *err_cqe, u8 *layer_type,
static void post_terminate(struct c4iw_qp *qhp, struct t4_cqe *err_cqe,
gfp_t gfp)
{
+ int ret;
struct fw_ri_wr *wqe;
struct terminate_message *term;
struct wrqe *wr;
@@ -991,7 +992,11 @@ static void post_terminate(struct c4iw_qp *qhp, struct t4_cqe *err_cqe,
term->ecode = qhp->attr.ecode;
} else
build_term_codes(err_cqe, &term->layer_etype, &term->ecode);
- creds(toep, sizeof(*wqe));
+ ret = creds(toep, inp, sizeof(*wqe));
+ if (ret) {
+ free_wrqe(wr);
+ return;
+ }
t4_wrq_tx(qhp->rhp->rdev.adap, wr);
}
@@ -1094,7 +1099,11 @@ rdma_fini(struct c4iw_dev *rhp, struct c4iw_qp *qhp, struct c4iw_ep *ep)
c4iw_init_wr_wait(&ep->com.wr_wait);
- creds(toep, sizeof(*wqe));
+ ret = creds(toep, inp, sizeof(*wqe));
+ if (ret) {
+ free_wrqe(wr);
+ return ret;
+ }
t4_wrq_tx(sc, wr);
ret = c4iw_wait_for_reply(rdev, &ep->com.wr_wait, ep->hwtid,
@@ -1127,13 +1136,17 @@ static void build_rtr_msg(u8 p2p_type, struct fw_ri_init *init)
}
}
-static void
-creds(struct toepcb *toep, size_t wrsize)
+static int
+creds(struct toepcb *toep, struct inpcb *inp, size_t wrsize)
{
struct ofld_tx_sdesc *txsd;
CTR3(KTR_IW_CXGBE, "%s:creB %p %u", __func__, toep , wrsize);
- INP_WLOCK(toep->inp);
+ INP_WLOCK(inp);
+ if ((inp->inp_flags & (INP_DROPPED | INP_TIMEWAIT)) != 0) {
+ INP_WUNLOCK(inp);
+ return (EINVAL);
+ }
txsd = &toep->txsd[toep->txsd_pidx];
txsd->tx_credits = howmany(wrsize, 16);
txsd->plen = 0;
@@ -1143,9 +1156,10 @@ creds(struct toepcb *toep, size_t wrsize)
if (__predict_false(++toep->txsd_pidx == toep->txsd_total))
toep->txsd_pidx = 0;
toep->txsd_avail--;
- INP_WUNLOCK(toep->inp);
+ INP_WUNLOCK(inp);
CTR5(KTR_IW_CXGBE, "%s:creE %p %u %u %u", __func__, toep ,
txsd->tx_credits, toep->tx_credits, toep->txsd_pidx);
+ return (0);
}
static int rdma_init(struct c4iw_dev *rhp, struct c4iw_qp *qhp)
@@ -1216,7 +1230,11 @@ static int rdma_init(struct c4iw_dev *rhp, struct c4iw_qp *qhp)
c4iw_init_wr_wait(&ep->com.wr_wait);
- creds(toep, sizeof(*wqe));
+ ret = creds(toep, inp, sizeof(*wqe));
+ if (ret) {
+ free_wrqe(wr);
+ return ret;
+ }
t4_wrq_tx(sc, wr);
ret = c4iw_wait_for_reply(rdev, &ep->com.wr_wait, ep->hwtid,