Skip to content

Commit 04b5d02

Browse files
Steve WiseRoland Dreier
authored andcommitted
RDMA/cxgb3: Handle EEH events
- wrap calls into cxgb3 and fail them if we're in the middle of a PCI EEH event. - correctly unwind and release endpoint and other resources when we are in an EEH event. - dispatch IB_EVENT_DEVICE_FATAL event when cxgb3 notifies iw_cxgb3 of a fatal error. Signed-off-by: Steve Wise <swise@opengridcomputing.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
1 parent 5d80f8e commit 04b5d02

File tree

6 files changed

+92
-34
lines changed

6 files changed

+92
-34
lines changed

drivers/infiniband/hw/cxgb3/cxio_hal.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ static int cxio_hal_clear_qp_ctx(struct cxio_rdev *rdev_p, u32 qpid)
152152
sge_cmd = qpid << 8 | 3;
153153
wqe->sge_cmd = cpu_to_be64(sge_cmd);
154154
skb->priority = CPL_PRIORITY_CONTROL;
155-
return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb));
155+
return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb);
156156
}
157157

158158
int cxio_create_cq(struct cxio_rdev *rdev_p, struct t3_cq *cq)
@@ -571,7 +571,7 @@ static int cxio_hal_init_ctrl_qp(struct cxio_rdev *rdev_p)
571571
(unsigned long long) rdev_p->ctrl_qp.dma_addr,
572572
rdev_p->ctrl_qp.workq, 1 << T3_CTRL_QP_SIZE_LOG2);
573573
skb->priority = CPL_PRIORITY_CONTROL;
574-
return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb));
574+
return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb);
575575
err:
576576
kfree_skb(skb);
577577
return err;
@@ -701,7 +701,7 @@ static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry,
701701
u32 stag_idx;
702702
u32 wptr;
703703

704-
if (rdev_p->flags)
704+
if (cxio_fatal_error(rdev_p))
705705
return -EIO;
706706

707707
stag_state = stag_state > 0;
@@ -858,7 +858,7 @@ int cxio_rdma_init(struct cxio_rdev *rdev_p, struct t3_rdma_init_attr *attr)
858858
wqe->qp_dma_size = cpu_to_be32(attr->qp_dma_size);
859859
wqe->irs = cpu_to_be32(attr->irs);
860860
skb->priority = 0; /* 0=>ToeQ; 1=>CtrlQ */
861-
return (cxgb3_ofld_send(rdev_p->t3cdev_p, skb));
861+
return iwch_cxgb3_ofld_send(rdev_p->t3cdev_p, skb);
862862
}
863863

864864
void cxio_register_ev_cb(cxio_hal_ev_callback_func_t ev_cb)
@@ -1041,9 +1041,9 @@ void cxio_rdev_close(struct cxio_rdev *rdev_p)
10411041
cxio_hal_pblpool_destroy(rdev_p);
10421042
cxio_hal_rqtpool_destroy(rdev_p);
10431043
list_del(&rdev_p->entry);
1044-
rdev_p->t3cdev_p->ulp = NULL;
10451044
cxio_hal_destroy_ctrl_qp(rdev_p);
10461045
cxio_hal_destroy_resource(rdev_p->rscp);
1046+
rdev_p->t3cdev_p->ulp = NULL;
10471047
}
10481048
}
10491049

drivers/infiniband/hw/cxgb3/cxio_hal.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ struct cxio_rdev {
115115
#define CXIO_ERROR_FATAL 1
116116
};
117117

118+
static inline int cxio_fatal_error(struct cxio_rdev *rdev_p)
119+
{
120+
return rdev_p->flags & CXIO_ERROR_FATAL;
121+
}
122+
118123
static inline int cxio_num_stags(struct cxio_rdev *rdev_p)
119124
{
120125
return min((int)T3_MAX_NUM_STAG, (int)((rdev_p->rnic_info.tpt_top - rdev_p->rnic_info.tpt_base) >> 5));
@@ -188,6 +193,7 @@ void cxio_count_scqes(struct t3_cq *cq, struct t3_wq *wq, int *count);
188193
void cxio_flush_hw_cq(struct t3_cq *cq);
189194
int cxio_poll_cq(struct t3_wq *wq, struct t3_cq *cq, struct t3_cqe *cqe,
190195
u8 *cqe_flushed, u64 *cookie, u32 *credit);
196+
int iwch_cxgb3_ofld_send(struct t3cdev *tdev, struct sk_buff *skb);
191197

192198
#define MOD "iw_cxgb3: "
193199
#define PDBG(fmt, args...) pr_debug(MOD fmt, ## args)

drivers/infiniband/hw/cxgb3/iwch.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,19 @@ static void close_rnic_dev(struct t3cdev *tdev)
165165
static void iwch_err_handler(struct t3cdev *tdev, u32 status, u32 error)
166166
{
167167
struct cxio_rdev *rdev = tdev->ulp;
168+
struct iwch_dev *rnicp = rdev_to_iwch_dev(rdev);
169+
struct ib_event event;
168170

169-
if (status == OFFLOAD_STATUS_DOWN)
171+
if (status == OFFLOAD_STATUS_DOWN) {
170172
rdev->flags = CXIO_ERROR_FATAL;
171173

172-
return;
174+
event.device = &rnicp->ibdev;
175+
event.event = IB_EVENT_DEVICE_FATAL;
176+
event.element.port_num = 0;
177+
ib_dispatch_event(&event);
178+
}
173179

180+
return;
174181
}
175182

176183
static int __init iwch_init_module(void)

drivers/infiniband/hw/cxgb3/iwch.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ static inline struct iwch_dev *to_iwch_dev(struct ib_device *ibdev)
117117
return container_of(ibdev, struct iwch_dev, ibdev);
118118
}
119119

120+
static inline struct iwch_dev *rdev_to_iwch_dev(struct cxio_rdev *rdev)
121+
{
122+
return container_of(rdev, struct iwch_dev, rdev);
123+
}
124+
120125
static inline int t3b_device(const struct iwch_dev *rhp)
121126
{
122127
return rhp->rdev.t3cdev_p->type == T3B;

drivers/infiniband/hw/cxgb3/iwch_cm.c

Lines changed: 65 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,38 @@ static void stop_ep_timer(struct iwch_ep *ep)
139139
put_ep(&ep->com);
140140
}
141141

142+
int iwch_l2t_send(struct t3cdev *tdev, struct sk_buff *skb, struct l2t_entry *l2e)
143+
{
144+
int error = 0;
145+
struct cxio_rdev *rdev;
146+
147+
rdev = (struct cxio_rdev *)tdev->ulp;
148+
if (cxio_fatal_error(rdev)) {
149+
kfree_skb(skb);
150+
return -EIO;
151+
}
152+
error = l2t_send(tdev, skb, l2e);
153+
if (error)
154+
kfree_skb(skb);
155+
return error;
156+
}
157+
158+
int iwch_cxgb3_ofld_send(struct t3cdev *tdev, struct sk_buff *skb)
159+
{
160+
int error = 0;
161+
struct cxio_rdev *rdev;
162+
163+
rdev = (struct cxio_rdev *)tdev->ulp;
164+
if (cxio_fatal_error(rdev)) {
165+
kfree_skb(skb);
166+
return -EIO;
167+
}
168+
error = cxgb3_ofld_send(tdev, skb);
169+
if (error)
170+
kfree_skb(skb);
171+
return error;
172+
}
173+
142174
static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb)
143175
{
144176
struct cpl_tid_release *req;
@@ -150,7 +182,7 @@ static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb)
150182
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
151183
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, hwtid));
152184
skb->priority = CPL_PRIORITY_SETUP;
153-
cxgb3_ofld_send(tdev, skb);
185+
iwch_cxgb3_ofld_send(tdev, skb);
154186
return;
155187
}
156188

@@ -172,8 +204,7 @@ int iwch_quiesce_tid(struct iwch_ep *ep)
172204
req->val = cpu_to_be64(1 << S_TCB_RX_QUIESCE);
173205

174206
skb->priority = CPL_PRIORITY_DATA;
175-
cxgb3_ofld_send(ep->com.tdev, skb);
176-
return 0;
207+
return iwch_cxgb3_ofld_send(ep->com.tdev, skb);
177208
}
178209

179210
int iwch_resume_tid(struct iwch_ep *ep)
@@ -194,8 +225,7 @@ int iwch_resume_tid(struct iwch_ep *ep)
194225
req->val = 0;
195226

196227
skb->priority = CPL_PRIORITY_DATA;
197-
cxgb3_ofld_send(ep->com.tdev, skb);
198-
return 0;
228+
return iwch_cxgb3_ofld_send(ep->com.tdev, skb);
199229
}
200230

201231
static void set_emss(struct iwch_ep *ep, u16 opt)
@@ -382,7 +412,7 @@ static void abort_arp_failure(struct t3cdev *dev, struct sk_buff *skb)
382412

383413
PDBG("%s t3cdev %p\n", __func__, dev);
384414
req->cmd = CPL_ABORT_NO_RST;
385-
cxgb3_ofld_send(dev, skb);
415+
iwch_cxgb3_ofld_send(dev, skb);
386416
}
387417

388418
static int send_halfclose(struct iwch_ep *ep, gfp_t gfp)
@@ -402,8 +432,7 @@ static int send_halfclose(struct iwch_ep *ep, gfp_t gfp)
402432
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_CLOSE_CON));
403433
req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
404434
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_CON_REQ, ep->hwtid));
405-
l2t_send(ep->com.tdev, skb, ep->l2t);
406-
return 0;
435+
return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
407436
}
408437

409438
static int send_abort(struct iwch_ep *ep, struct sk_buff *skb, gfp_t gfp)
@@ -424,8 +453,7 @@ static int send_abort(struct iwch_ep *ep, struct sk_buff *skb, gfp_t gfp)
424453
req->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
425454
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ABORT_REQ, ep->hwtid));
426455
req->cmd = CPL_ABORT_SEND_RST;
427-
l2t_send(ep->com.tdev, skb, ep->l2t);
428-
return 0;
456+
return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
429457
}
430458

431459
static int send_connect(struct iwch_ep *ep)
@@ -469,8 +497,7 @@ static int send_connect(struct iwch_ep *ep)
469497
req->opt0l = htonl(opt0l);
470498
req->params = 0;
471499
req->opt2 = htonl(opt2);
472-
l2t_send(ep->com.tdev, skb, ep->l2t);
473-
return 0;
500+
return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
474501
}
475502

476503
static void send_mpa_req(struct iwch_ep *ep, struct sk_buff *skb)
@@ -527,7 +554,7 @@ static void send_mpa_req(struct iwch_ep *ep, struct sk_buff *skb)
527554
req->sndseq = htonl(ep->snd_seq);
528555
BUG_ON(ep->mpa_skb);
529556
ep->mpa_skb = skb;
530-
l2t_send(ep->com.tdev, skb, ep->l2t);
557+
iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
531558
start_ep_timer(ep);
532559
state_set(&ep->com, MPA_REQ_SENT);
533560
return;
@@ -578,8 +605,7 @@ static int send_mpa_reject(struct iwch_ep *ep, const void *pdata, u8 plen)
578605
req->sndseq = htonl(ep->snd_seq);
579606
BUG_ON(ep->mpa_skb);
580607
ep->mpa_skb = skb;
581-
l2t_send(ep->com.tdev, skb, ep->l2t);
582-
return 0;
608+
return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
583609
}
584610

585611
static int send_mpa_reply(struct iwch_ep *ep, const void *pdata, u8 plen)
@@ -630,8 +656,7 @@ static int send_mpa_reply(struct iwch_ep *ep, const void *pdata, u8 plen)
630656
req->sndseq = htonl(ep->snd_seq);
631657
ep->mpa_skb = skb;
632658
state_set(&ep->com, MPA_REP_SENT);
633-
l2t_send(ep->com.tdev, skb, ep->l2t);
634-
return 0;
659+
return iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
635660
}
636661

637662
static int act_establish(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
@@ -795,7 +820,7 @@ static int update_rx_credits(struct iwch_ep *ep, u32 credits)
795820
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RX_DATA_ACK, ep->hwtid));
796821
req->credit_dack = htonl(V_RX_CREDITS(credits) | V_RX_FORCE_ACK(1));
797822
skb->priority = CPL_PRIORITY_ACK;
798-
cxgb3_ofld_send(ep->com.tdev, skb);
823+
iwch_cxgb3_ofld_send(ep->com.tdev, skb);
799824
return credits;
800825
}
801826

@@ -1203,8 +1228,7 @@ static int listen_start(struct iwch_listen_ep *ep)
12031228
req->opt1 = htonl(V_CONN_POLICY(CPL_CONN_POLICY_ASK));
12041229

12051230
skb->priority = 1;
1206-
cxgb3_ofld_send(ep->com.tdev, skb);
1207-
return 0;
1231+
return iwch_cxgb3_ofld_send(ep->com.tdev, skb);
12081232
}
12091233

12101234
static int pass_open_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
@@ -1237,8 +1261,7 @@ static int listen_stop(struct iwch_listen_ep *ep)
12371261
req->cpu_idx = 0;
12381262
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ, ep->stid));
12391263
skb->priority = 1;
1240-
cxgb3_ofld_send(ep->com.tdev, skb);
1241-
return 0;
1264+
return iwch_cxgb3_ofld_send(ep->com.tdev, skb);
12421265
}
12431266

12441267
static int close_listsrv_rpl(struct t3cdev *tdev, struct sk_buff *skb,
@@ -1286,7 +1309,7 @@ static void accept_cr(struct iwch_ep *ep, __be32 peer_ip, struct sk_buff *skb)
12861309
rpl->opt2 = htonl(opt2);
12871310
rpl->rsvd = rpl->opt2; /* workaround for HW bug */
12881311
skb->priority = CPL_PRIORITY_SETUP;
1289-
l2t_send(ep->com.tdev, skb, ep->l2t);
1312+
iwch_l2t_send(ep->com.tdev, skb, ep->l2t);
12901313

12911314
return;
12921315
}
@@ -1315,7 +1338,7 @@ static void reject_cr(struct t3cdev *tdev, u32 hwtid, __be32 peer_ip,
13151338
rpl->opt0l_status = htonl(CPL_PASS_OPEN_REJECT);
13161339
rpl->opt2 = 0;
13171340
rpl->rsvd = rpl->opt2;
1318-
cxgb3_ofld_send(tdev, skb);
1341+
iwch_cxgb3_ofld_send(tdev, skb);
13191342
}
13201343
}
13211344

@@ -1613,7 +1636,7 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
16131636
rpl->wr.wr_lo = htonl(V_WR_TID(ep->hwtid));
16141637
OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid));
16151638
rpl->cmd = CPL_ABORT_NO_RST;
1616-
cxgb3_ofld_send(ep->com.tdev, rpl_skb);
1639+
iwch_cxgb3_ofld_send(ep->com.tdev, rpl_skb);
16171640
out:
16181641
if (release)
16191642
release_ep_resources(ep);
@@ -2017,8 +2040,11 @@ int iwch_destroy_listen(struct iw_cm_id *cm_id)
20172040
ep->com.rpl_done = 0;
20182041
ep->com.rpl_err = 0;
20192042
err = listen_stop(ep);
2043+
if (err)
2044+
goto done;
20202045
wait_event(ep->com.waitq, ep->com.rpl_done);
20212046
cxgb3_free_stid(ep->com.tdev, ep->stid);
2047+
done:
20222048
err = ep->com.rpl_err;
20232049
cm_id->rem_ref(cm_id);
20242050
put_ep(&ep->com);
@@ -2030,12 +2056,22 @@ int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, gfp_t gfp)
20302056
int ret=0;
20312057
unsigned long flags;
20322058
int close = 0;
2059+
int fatal = 0;
2060+
struct t3cdev *tdev;
2061+
struct cxio_rdev *rdev;
20332062

20342063
spin_lock_irqsave(&ep->com.lock, flags);
20352064

20362065
PDBG("%s ep %p state %s, abrupt %d\n", __func__, ep,
20372066
states[ep->com.state], abrupt);
20382067

2068+
tdev = (struct t3cdev *)ep->com.tdev;
2069+
rdev = (struct cxio_rdev *)tdev->ulp;
2070+
if (cxio_fatal_error(rdev)) {
2071+
fatal = 1;
2072+
close_complete_upcall(ep);
2073+
ep->com.state = DEAD;
2074+
}
20392075
switch (ep->com.state) {
20402076
case MPA_REQ_WAIT:
20412077
case MPA_REQ_SENT:
@@ -2075,7 +2111,11 @@ int iwch_ep_disconnect(struct iwch_ep *ep, int abrupt, gfp_t gfp)
20752111
ret = send_abort(ep, NULL, gfp);
20762112
else
20772113
ret = send_halfclose(ep, gfp);
2114+
if (ret)
2115+
fatal = 1;
20782116
}
2117+
if (fatal)
2118+
release_ep_resources(ep);
20792119
return ret;
20802120
}
20812121

drivers/infiniband/hw/cxgb3/iwch_qp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,7 @@ int iwch_post_zb_read(struct iwch_qp *qhp)
751751
wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid)|
752752
V_FW_RIWR_LEN(flit_cnt));
753753
skb->priority = CPL_PRIORITY_DATA;
754-
return cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb);
754+
return iwch_cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb);
755755
}
756756

757757
/*
@@ -783,7 +783,7 @@ int iwch_post_terminate(struct iwch_qp *qhp, struct respQ_msg_t *rsp_msg)
783783
V_FW_RIWR_FLAGS(T3_COMPLETION_FLAG | T3_NOTIFY_FLAG));
784784
wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid));
785785
skb->priority = CPL_PRIORITY_DATA;
786-
return cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb);
786+
return iwch_cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb);
787787
}
788788

789789
/*

0 commit comments

Comments
 (0)