aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/cxgb4/cm.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
index e8edfeea84f9..4ee10547a4e4 100644
--- a/drivers/infiniband/hw/cxgb4/cm.c
+++ b/drivers/infiniband/hw/cxgb4/cm.c
@@ -342,6 +342,23 @@ static struct c4iw_ep *get_ep_from_tid(struct c4iw_dev *dev, unsigned int tid)
342 return ep; 342 return ep;
343} 343}
344 344
345/*
346 * Atomically lookup the ep ptr given the stid and grab a reference on the ep.
347 */
348static struct c4iw_listen_ep *get_ep_from_stid(struct c4iw_dev *dev,
349 unsigned int stid)
350{
351 struct c4iw_listen_ep *ep;
352 unsigned long flags;
353
354 spin_lock_irqsave(&dev->lock, flags);
355 ep = idr_find(&dev->stid_idr, stid);
356 if (ep)
357 c4iw_get_ep(&ep->com);
358 spin_unlock_irqrestore(&dev->lock, flags);
359 return ep;
360}
361
345void _c4iw_free_ep(struct kref *kref) 362void _c4iw_free_ep(struct kref *kref)
346{ 363{
347 struct c4iw_ep *ep; 364 struct c4iw_ep *ep;
@@ -2306,9 +2323,8 @@ fail:
2306static int pass_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb) 2323static int pass_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
2307{ 2324{
2308 struct cpl_pass_open_rpl *rpl = cplhdr(skb); 2325 struct cpl_pass_open_rpl *rpl = cplhdr(skb);
2309 struct tid_info *t = dev->rdev.lldi.tids;
2310 unsigned int stid = GET_TID(rpl); 2326 unsigned int stid = GET_TID(rpl);
2311 struct c4iw_listen_ep *ep = lookup_stid(t, stid); 2327 struct c4iw_listen_ep *ep = get_ep_from_stid(dev, stid);
2312 2328
2313 if (!ep) { 2329 if (!ep) {
2314 PDBG("%s stid %d lookup failure!\n", __func__, stid); 2330 PDBG("%s stid %d lookup failure!\n", __func__, stid);
@@ -2317,7 +2333,7 @@ static int pass_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
2317 PDBG("%s ep %p status %d error %d\n", __func__, ep, 2333 PDBG("%s ep %p status %d error %d\n", __func__, ep,
2318 rpl->status, status2errno(rpl->status)); 2334 rpl->status, status2errno(rpl->status));
2319 c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status)); 2335 c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status));
2320 2336 c4iw_put_ep(&ep->com);
2321out: 2337out:
2322 return 0; 2338 return 0;
2323} 2339}
@@ -2325,12 +2341,12 @@ out:
2325static int close_listsrv_rpl(struct c4iw_dev *dev, struct sk_buff *skb) 2341static int close_listsrv_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
2326{ 2342{
2327 struct cpl_close_listsvr_rpl *rpl = cplhdr(skb); 2343 struct cpl_close_listsvr_rpl *rpl = cplhdr(skb);
2328 struct tid_info *t = dev->rdev.lldi.tids;
2329 unsigned int stid = GET_TID(rpl); 2344 unsigned int stid = GET_TID(rpl);
2330 struct c4iw_listen_ep *ep = lookup_stid(t, stid); 2345 struct c4iw_listen_ep *ep = get_ep_from_stid(dev, stid);
2331 2346
2332 PDBG("%s ep %p\n", __func__, ep); 2347 PDBG("%s ep %p\n", __func__, ep);
2333 c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status)); 2348 c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status));
2349 c4iw_put_ep(&ep->com);
2334 return 0; 2350 return 0;
2335} 2351}
2336 2352
@@ -2490,7 +2506,7 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
2490 unsigned short hdrs; 2506 unsigned short hdrs;
2491 u8 tos = PASS_OPEN_TOS_G(ntohl(req->tos_stid)); 2507 u8 tos = PASS_OPEN_TOS_G(ntohl(req->tos_stid));
2492 2508
2493 parent_ep = lookup_stid(t, stid); 2509 parent_ep = (struct c4iw_ep *)get_ep_from_stid(dev, stid);
2494 if (!parent_ep) { 2510 if (!parent_ep) {
2495 PDBG("%s connect request on invalid stid %d\n", __func__, stid); 2511 PDBG("%s connect request on invalid stid %d\n", __func__, stid);
2496 goto reject; 2512 goto reject;
@@ -2618,6 +2634,8 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
2618 goto out; 2634 goto out;
2619reject: 2635reject:
2620 reject_cr(dev, hwtid, skb); 2636 reject_cr(dev, hwtid, skb);
2637 if (parent_ep)
2638 c4iw_put_ep(&parent_ep->com);
2621out: 2639out:
2622 return 0; 2640 return 0;
2623} 2641}
@@ -3868,7 +3886,7 @@ static int rx_pkt(struct c4iw_dev *dev, struct sk_buff *skb)
3868 struct cpl_pass_accept_req *req = (void *)(rss + 1); 3886 struct cpl_pass_accept_req *req = (void *)(rss + 1);
3869 struct l2t_entry *e; 3887 struct l2t_entry *e;
3870 struct dst_entry *dst; 3888 struct dst_entry *dst;
3871 struct c4iw_ep *lep; 3889 struct c4iw_ep *lep = NULL;
3872 u16 window; 3890 u16 window;
3873 struct port_info *pi; 3891 struct port_info *pi;
3874 struct net_device *pdev; 3892 struct net_device *pdev;
@@ -3893,7 +3911,7 @@ static int rx_pkt(struct c4iw_dev *dev, struct sk_buff *skb)
3893 */ 3911 */
3894 stid = (__force int) cpu_to_be32((__force u32) rss->hash_val); 3912 stid = (__force int) cpu_to_be32((__force u32) rss->hash_val);
3895 3913
3896 lep = (struct c4iw_ep *)lookup_stid(dev->rdev.lldi.tids, stid); 3914 lep = (struct c4iw_ep *)get_ep_from_stid(dev, stid);
3897 if (!lep) { 3915 if (!lep) {
3898 PDBG("%s connect request on invalid stid %d\n", __func__, stid); 3916 PDBG("%s connect request on invalid stid %d\n", __func__, stid);
3899 goto reject; 3917 goto reject;
@@ -3994,6 +4012,8 @@ static int rx_pkt(struct c4iw_dev *dev, struct sk_buff *skb)
3994free_dst: 4012free_dst:
3995 dst_release(dst); 4013 dst_release(dst);
3996reject: 4014reject:
4015 if (lep)
4016 c4iw_put_ep(&lep->com);
3997 return 0; 4017 return 0;
3998} 4018}
3999 4019