diff options
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/cm.c | 36 |
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 | */ | ||
| 348 | static 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 | |||
| 345 | void _c4iw_free_ep(struct kref *kref) | 362 | void _c4iw_free_ep(struct kref *kref) |
| 346 | { | 363 | { |
| 347 | struct c4iw_ep *ep; | 364 | struct c4iw_ep *ep; |
| @@ -2306,9 +2323,8 @@ fail: | |||
| 2306 | static int pass_open_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | 2323 | static 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); | |
| 2321 | out: | 2337 | out: |
| 2322 | return 0; | 2338 | return 0; |
| 2323 | } | 2339 | } |
| @@ -2325,12 +2341,12 @@ out: | |||
| 2325 | static int close_listsrv_rpl(struct c4iw_dev *dev, struct sk_buff *skb) | 2341 | static 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; |
| 2619 | reject: | 2635 | reject: |
| 2620 | reject_cr(dev, hwtid, skb); | 2636 | reject_cr(dev, hwtid, skb); |
| 2637 | if (parent_ep) | ||
| 2638 | c4iw_put_ep(&parent_ep->com); | ||
| 2621 | out: | 2639 | out: |
| 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) | |||
| 3994 | free_dst: | 4012 | free_dst: |
| 3995 | dst_release(dst); | 4013 | dst_release(dst); |
| 3996 | reject: | 4014 | reject: |
| 4015 | if (lep) | ||
| 4016 | c4iw_put_ep(&lep->com); | ||
| 3997 | return 0; | 4017 | return 0; |
| 3998 | } | 4018 | } |
| 3999 | 4019 | ||
