diff options
Diffstat (limited to 'drivers/infiniband')
31 files changed, 2263 insertions, 782 deletions
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index eaec8d7a3b73..e90f2b2eabd7 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <net/addrconf.h> | 45 | #include <net/addrconf.h> |
46 | #include <net/ip6_route.h> | 46 | #include <net/ip6_route.h> |
47 | #include <rdma/ib_addr.h> | 47 | #include <rdma/ib_addr.h> |
48 | #include <rdma/ib.h> | ||
48 | 49 | ||
49 | MODULE_AUTHOR("Sean Hefty"); | 50 | MODULE_AUTHOR("Sean Hefty"); |
50 | MODULE_DESCRIPTION("IB Address Translation"); | 51 | MODULE_DESCRIPTION("IB Address Translation"); |
@@ -70,6 +71,21 @@ static LIST_HEAD(req_list); | |||
70 | static DECLARE_DELAYED_WORK(work, process_req); | 71 | static DECLARE_DELAYED_WORK(work, process_req); |
71 | static struct workqueue_struct *addr_wq; | 72 | static struct workqueue_struct *addr_wq; |
72 | 73 | ||
74 | int rdma_addr_size(struct sockaddr *addr) | ||
75 | { | ||
76 | switch (addr->sa_family) { | ||
77 | case AF_INET: | ||
78 | return sizeof(struct sockaddr_in); | ||
79 | case AF_INET6: | ||
80 | return sizeof(struct sockaddr_in6); | ||
81 | case AF_IB: | ||
82 | return sizeof(struct sockaddr_ib); | ||
83 | default: | ||
84 | return 0; | ||
85 | } | ||
86 | } | ||
87 | EXPORT_SYMBOL(rdma_addr_size); | ||
88 | |||
73 | void rdma_addr_register_client(struct rdma_addr_client *client) | 89 | void rdma_addr_register_client(struct rdma_addr_client *client) |
74 | { | 90 | { |
75 | atomic_set(&client->refcount, 1); | 91 | atomic_set(&client->refcount, 1); |
@@ -369,12 +385,12 @@ int rdma_resolve_ip(struct rdma_addr_client *client, | |||
369 | goto err; | 385 | goto err; |
370 | } | 386 | } |
371 | 387 | ||
372 | memcpy(src_in, src_addr, ip_addr_size(src_addr)); | 388 | memcpy(src_in, src_addr, rdma_addr_size(src_addr)); |
373 | } else { | 389 | } else { |
374 | src_in->sa_family = dst_addr->sa_family; | 390 | src_in->sa_family = dst_addr->sa_family; |
375 | } | 391 | } |
376 | 392 | ||
377 | memcpy(dst_in, dst_addr, ip_addr_size(dst_addr)); | 393 | memcpy(dst_in, dst_addr, rdma_addr_size(dst_addr)); |
378 | req->addr = addr; | 394 | req->addr = addr; |
379 | req->callback = callback; | 395 | req->callback = callback; |
380 | req->context = context; | 396 | req->context = context; |
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 34fbc2f60a09..f1c279fabe64 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <rdma/rdma_cm.h> | 50 | #include <rdma/rdma_cm.h> |
51 | #include <rdma/rdma_cm_ib.h> | 51 | #include <rdma/rdma_cm_ib.h> |
52 | #include <rdma/rdma_netlink.h> | 52 | #include <rdma/rdma_netlink.h> |
53 | #include <rdma/ib.h> | ||
53 | #include <rdma/ib_cache.h> | 54 | #include <rdma/ib_cache.h> |
54 | #include <rdma/ib_cm.h> | 55 | #include <rdma/ib_cm.h> |
55 | #include <rdma/ib_sa.h> | 56 | #include <rdma/ib_sa.h> |
@@ -79,7 +80,6 @@ static LIST_HEAD(dev_list); | |||
79 | static LIST_HEAD(listen_any_list); | 80 | static LIST_HEAD(listen_any_list); |
80 | static DEFINE_MUTEX(lock); | 81 | static DEFINE_MUTEX(lock); |
81 | static struct workqueue_struct *cma_wq; | 82 | static struct workqueue_struct *cma_wq; |
82 | static DEFINE_IDR(sdp_ps); | ||
83 | static DEFINE_IDR(tcp_ps); | 83 | static DEFINE_IDR(tcp_ps); |
84 | static DEFINE_IDR(udp_ps); | 84 | static DEFINE_IDR(udp_ps); |
85 | static DEFINE_IDR(ipoib_ps); | 85 | static DEFINE_IDR(ipoib_ps); |
@@ -195,24 +195,7 @@ struct cma_hdr { | |||
195 | union cma_ip_addr dst_addr; | 195 | union cma_ip_addr dst_addr; |
196 | }; | 196 | }; |
197 | 197 | ||
198 | struct sdp_hh { | ||
199 | u8 bsdh[16]; | ||
200 | u8 sdp_version; /* Major version: 7:4 */ | ||
201 | u8 ip_version; /* IP version: 7:4 */ | ||
202 | u8 sdp_specific1[10]; | ||
203 | __be16 port; | ||
204 | __be16 sdp_specific2; | ||
205 | union cma_ip_addr src_addr; | ||
206 | union cma_ip_addr dst_addr; | ||
207 | }; | ||
208 | |||
209 | struct sdp_hah { | ||
210 | u8 bsdh[16]; | ||
211 | u8 sdp_version; | ||
212 | }; | ||
213 | |||
214 | #define CMA_VERSION 0x00 | 198 | #define CMA_VERSION 0x00 |
215 | #define SDP_MAJ_VERSION 0x2 | ||
216 | 199 | ||
217 | static int cma_comp(struct rdma_id_private *id_priv, enum rdma_cm_state comp) | 200 | static int cma_comp(struct rdma_id_private *id_priv, enum rdma_cm_state comp) |
218 | { | 201 | { |
@@ -261,21 +244,6 @@ static inline void cma_set_ip_ver(struct cma_hdr *hdr, u8 ip_ver) | |||
261 | hdr->ip_version = (ip_ver << 4) | (hdr->ip_version & 0xF); | 244 | hdr->ip_version = (ip_ver << 4) | (hdr->ip_version & 0xF); |
262 | } | 245 | } |
263 | 246 | ||
264 | static inline u8 sdp_get_majv(u8 sdp_version) | ||
265 | { | ||
266 | return sdp_version >> 4; | ||
267 | } | ||
268 | |||
269 | static inline u8 sdp_get_ip_ver(struct sdp_hh *hh) | ||
270 | { | ||
271 | return hh->ip_version >> 4; | ||
272 | } | ||
273 | |||
274 | static inline void sdp_set_ip_ver(struct sdp_hh *hh, u8 ip_ver) | ||
275 | { | ||
276 | hh->ip_version = (ip_ver << 4) | (hh->ip_version & 0xF); | ||
277 | } | ||
278 | |||
279 | static void cma_attach_to_dev(struct rdma_id_private *id_priv, | 247 | static void cma_attach_to_dev(struct rdma_id_private *id_priv, |
280 | struct cma_device *cma_dev) | 248 | struct cma_device *cma_dev) |
281 | { | 249 | { |
@@ -310,16 +278,40 @@ static void cma_release_dev(struct rdma_id_private *id_priv) | |||
310 | mutex_unlock(&lock); | 278 | mutex_unlock(&lock); |
311 | } | 279 | } |
312 | 280 | ||
313 | static int cma_set_qkey(struct rdma_id_private *id_priv) | 281 | static inline struct sockaddr *cma_src_addr(struct rdma_id_private *id_priv) |
282 | { | ||
283 | return (struct sockaddr *) &id_priv->id.route.addr.src_addr; | ||
284 | } | ||
285 | |||
286 | static inline struct sockaddr *cma_dst_addr(struct rdma_id_private *id_priv) | ||
287 | { | ||
288 | return (struct sockaddr *) &id_priv->id.route.addr.dst_addr; | ||
289 | } | ||
290 | |||
291 | static inline unsigned short cma_family(struct rdma_id_private *id_priv) | ||
292 | { | ||
293 | return id_priv->id.route.addr.src_addr.ss_family; | ||
294 | } | ||
295 | |||
296 | static int cma_set_qkey(struct rdma_id_private *id_priv, u32 qkey) | ||
314 | { | 297 | { |
315 | struct ib_sa_mcmember_rec rec; | 298 | struct ib_sa_mcmember_rec rec; |
316 | int ret = 0; | 299 | int ret = 0; |
317 | 300 | ||
318 | if (id_priv->qkey) | 301 | if (id_priv->qkey) { |
302 | if (qkey && id_priv->qkey != qkey) | ||
303 | return -EINVAL; | ||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | if (qkey) { | ||
308 | id_priv->qkey = qkey; | ||
319 | return 0; | 309 | return 0; |
310 | } | ||
320 | 311 | ||
321 | switch (id_priv->id.ps) { | 312 | switch (id_priv->id.ps) { |
322 | case RDMA_PS_UDP: | 313 | case RDMA_PS_UDP: |
314 | case RDMA_PS_IB: | ||
323 | id_priv->qkey = RDMA_UDP_QKEY; | 315 | id_priv->qkey = RDMA_UDP_QKEY; |
324 | break; | 316 | break; |
325 | case RDMA_PS_IPOIB: | 317 | case RDMA_PS_IPOIB: |
@@ -358,6 +350,27 @@ static int find_gid_port(struct ib_device *device, union ib_gid *gid, u8 port_nu | |||
358 | return -EADDRNOTAVAIL; | 350 | return -EADDRNOTAVAIL; |
359 | } | 351 | } |
360 | 352 | ||
353 | static void cma_translate_ib(struct sockaddr_ib *sib, struct rdma_dev_addr *dev_addr) | ||
354 | { | ||
355 | dev_addr->dev_type = ARPHRD_INFINIBAND; | ||
356 | rdma_addr_set_sgid(dev_addr, (union ib_gid *) &sib->sib_addr); | ||
357 | ib_addr_set_pkey(dev_addr, ntohs(sib->sib_pkey)); | ||
358 | } | ||
359 | |||
360 | static int cma_translate_addr(struct sockaddr *addr, struct rdma_dev_addr *dev_addr) | ||
361 | { | ||
362 | int ret; | ||
363 | |||
364 | if (addr->sa_family != AF_IB) { | ||
365 | ret = rdma_translate_ip(addr, dev_addr); | ||
366 | } else { | ||
367 | cma_translate_ib((struct sockaddr_ib *) addr, dev_addr); | ||
368 | ret = 0; | ||
369 | } | ||
370 | |||
371 | return ret; | ||
372 | } | ||
373 | |||
361 | static int cma_acquire_dev(struct rdma_id_private *id_priv) | 374 | static int cma_acquire_dev(struct rdma_id_private *id_priv) |
362 | { | 375 | { |
363 | struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr; | 376 | struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr; |
@@ -401,6 +414,61 @@ out: | |||
401 | return ret; | 414 | return ret; |
402 | } | 415 | } |
403 | 416 | ||
417 | /* | ||
418 | * Select the source IB device and address to reach the destination IB address. | ||
419 | */ | ||
420 | static int cma_resolve_ib_dev(struct rdma_id_private *id_priv) | ||
421 | { | ||
422 | struct cma_device *cma_dev, *cur_dev; | ||
423 | struct sockaddr_ib *addr; | ||
424 | union ib_gid gid, sgid, *dgid; | ||
425 | u16 pkey, index; | ||
426 | u8 port, p; | ||
427 | int i; | ||
428 | |||
429 | cma_dev = NULL; | ||
430 | addr = (struct sockaddr_ib *) cma_dst_addr(id_priv); | ||
431 | dgid = (union ib_gid *) &addr->sib_addr; | ||
432 | pkey = ntohs(addr->sib_pkey); | ||
433 | |||
434 | list_for_each_entry(cur_dev, &dev_list, list) { | ||
435 | if (rdma_node_get_transport(cur_dev->device->node_type) != RDMA_TRANSPORT_IB) | ||
436 | continue; | ||
437 | |||
438 | for (p = 1; p <= cur_dev->device->phys_port_cnt; ++p) { | ||
439 | if (ib_find_cached_pkey(cur_dev->device, p, pkey, &index)) | ||
440 | continue; | ||
441 | |||
442 | for (i = 0; !ib_get_cached_gid(cur_dev->device, p, i, &gid); i++) { | ||
443 | if (!memcmp(&gid, dgid, sizeof(gid))) { | ||
444 | cma_dev = cur_dev; | ||
445 | sgid = gid; | ||
446 | port = p; | ||
447 | goto found; | ||
448 | } | ||
449 | |||
450 | if (!cma_dev && (gid.global.subnet_prefix == | ||
451 | dgid->global.subnet_prefix)) { | ||
452 | cma_dev = cur_dev; | ||
453 | sgid = gid; | ||
454 | port = p; | ||
455 | } | ||
456 | } | ||
457 | } | ||
458 | } | ||
459 | |||
460 | if (!cma_dev) | ||
461 | return -ENODEV; | ||
462 | |||
463 | found: | ||
464 | cma_attach_to_dev(id_priv, cma_dev); | ||
465 | id_priv->id.port_num = port; | ||
466 | addr = (struct sockaddr_ib *) cma_src_addr(id_priv); | ||
467 | memcpy(&addr->sib_addr, &sgid, sizeof sgid); | ||
468 | cma_translate_ib(addr, &id_priv->id.route.addr.dev_addr); | ||
469 | return 0; | ||
470 | } | ||
471 | |||
404 | static void cma_deref_id(struct rdma_id_private *id_priv) | 472 | static void cma_deref_id(struct rdma_id_private *id_priv) |
405 | { | 473 | { |
406 | if (atomic_dec_and_test(&id_priv->refcount)) | 474 | if (atomic_dec_and_test(&id_priv->refcount)) |
@@ -630,7 +698,7 @@ static int cma_ib_init_qp_attr(struct rdma_id_private *id_priv, | |||
630 | *qp_attr_mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT; | 698 | *qp_attr_mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT; |
631 | 699 | ||
632 | if (id_priv->id.qp_type == IB_QPT_UD) { | 700 | if (id_priv->id.qp_type == IB_QPT_UD) { |
633 | ret = cma_set_qkey(id_priv); | 701 | ret = cma_set_qkey(id_priv, 0); |
634 | if (ret) | 702 | if (ret) |
635 | return ret; | 703 | return ret; |
636 | 704 | ||
@@ -679,26 +747,30 @@ EXPORT_SYMBOL(rdma_init_qp_attr); | |||
679 | 747 | ||
680 | static inline int cma_zero_addr(struct sockaddr *addr) | 748 | static inline int cma_zero_addr(struct sockaddr *addr) |
681 | { | 749 | { |
682 | struct in6_addr *ip6; | 750 | switch (addr->sa_family) { |
683 | 751 | case AF_INET: | |
684 | if (addr->sa_family == AF_INET) | 752 | return ipv4_is_zeronet(((struct sockaddr_in *)addr)->sin_addr.s_addr); |
685 | return ipv4_is_zeronet( | 753 | case AF_INET6: |
686 | ((struct sockaddr_in *)addr)->sin_addr.s_addr); | 754 | return ipv6_addr_any(&((struct sockaddr_in6 *) addr)->sin6_addr); |
687 | else { | 755 | case AF_IB: |
688 | ip6 = &((struct sockaddr_in6 *) addr)->sin6_addr; | 756 | return ib_addr_any(&((struct sockaddr_ib *) addr)->sib_addr); |
689 | return (ip6->s6_addr32[0] | ip6->s6_addr32[1] | | 757 | default: |
690 | ip6->s6_addr32[2] | ip6->s6_addr32[3]) == 0; | 758 | return 0; |
691 | } | 759 | } |
692 | } | 760 | } |
693 | 761 | ||
694 | static inline int cma_loopback_addr(struct sockaddr *addr) | 762 | static inline int cma_loopback_addr(struct sockaddr *addr) |
695 | { | 763 | { |
696 | if (addr->sa_family == AF_INET) | 764 | switch (addr->sa_family) { |
697 | return ipv4_is_loopback( | 765 | case AF_INET: |
698 | ((struct sockaddr_in *) addr)->sin_addr.s_addr); | 766 | return ipv4_is_loopback(((struct sockaddr_in *) addr)->sin_addr.s_addr); |
699 | else | 767 | case AF_INET6: |
700 | return ipv6_addr_loopback( | 768 | return ipv6_addr_loopback(&((struct sockaddr_in6 *) addr)->sin6_addr); |
701 | &((struct sockaddr_in6 *) addr)->sin6_addr); | 769 | case AF_IB: |
770 | return ib_addr_loopback(&((struct sockaddr_ib *) addr)->sib_addr); | ||
771 | default: | ||
772 | return 0; | ||
773 | } | ||
702 | } | 774 | } |
703 | 775 | ||
704 | static inline int cma_any_addr(struct sockaddr *addr) | 776 | static inline int cma_any_addr(struct sockaddr *addr) |
@@ -715,18 +787,31 @@ static int cma_addr_cmp(struct sockaddr *src, struct sockaddr *dst) | |||
715 | case AF_INET: | 787 | case AF_INET: |
716 | return ((struct sockaddr_in *) src)->sin_addr.s_addr != | 788 | return ((struct sockaddr_in *) src)->sin_addr.s_addr != |
717 | ((struct sockaddr_in *) dst)->sin_addr.s_addr; | 789 | ((struct sockaddr_in *) dst)->sin_addr.s_addr; |
718 | default: | 790 | case AF_INET6: |
719 | return ipv6_addr_cmp(&((struct sockaddr_in6 *) src)->sin6_addr, | 791 | return ipv6_addr_cmp(&((struct sockaddr_in6 *) src)->sin6_addr, |
720 | &((struct sockaddr_in6 *) dst)->sin6_addr); | 792 | &((struct sockaddr_in6 *) dst)->sin6_addr); |
793 | default: | ||
794 | return ib_addr_cmp(&((struct sockaddr_ib *) src)->sib_addr, | ||
795 | &((struct sockaddr_ib *) dst)->sib_addr); | ||
721 | } | 796 | } |
722 | } | 797 | } |
723 | 798 | ||
724 | static inline __be16 cma_port(struct sockaddr *addr) | 799 | static __be16 cma_port(struct sockaddr *addr) |
725 | { | 800 | { |
726 | if (addr->sa_family == AF_INET) | 801 | struct sockaddr_ib *sib; |
802 | |||
803 | switch (addr->sa_family) { | ||
804 | case AF_INET: | ||
727 | return ((struct sockaddr_in *) addr)->sin_port; | 805 | return ((struct sockaddr_in *) addr)->sin_port; |
728 | else | 806 | case AF_INET6: |
729 | return ((struct sockaddr_in6 *) addr)->sin6_port; | 807 | return ((struct sockaddr_in6 *) addr)->sin6_port; |
808 | case AF_IB: | ||
809 | sib = (struct sockaddr_ib *) addr; | ||
810 | return htons((u16) (be64_to_cpu(sib->sib_sid) & | ||
811 | be64_to_cpu(sib->sib_sid_mask))); | ||
812 | default: | ||
813 | return 0; | ||
814 | } | ||
730 | } | 815 | } |
731 | 816 | ||
732 | static inline int cma_any_port(struct sockaddr *addr) | 817 | static inline int cma_any_port(struct sockaddr *addr) |
@@ -734,83 +819,92 @@ static inline int cma_any_port(struct sockaddr *addr) | |||
734 | return !cma_port(addr); | 819 | return !cma_port(addr); |
735 | } | 820 | } |
736 | 821 | ||
737 | static int cma_get_net_info(void *hdr, enum rdma_port_space ps, | 822 | static void cma_save_ib_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id, |
738 | u8 *ip_ver, __be16 *port, | 823 | struct ib_sa_path_rec *path) |
739 | union cma_ip_addr **src, union cma_ip_addr **dst) | ||
740 | { | 824 | { |
741 | switch (ps) { | 825 | struct sockaddr_ib *listen_ib, *ib; |
742 | case RDMA_PS_SDP: | ||
743 | if (sdp_get_majv(((struct sdp_hh *) hdr)->sdp_version) != | ||
744 | SDP_MAJ_VERSION) | ||
745 | return -EINVAL; | ||
746 | 826 | ||
747 | *ip_ver = sdp_get_ip_ver(hdr); | 827 | listen_ib = (struct sockaddr_ib *) &listen_id->route.addr.src_addr; |
748 | *port = ((struct sdp_hh *) hdr)->port; | 828 | ib = (struct sockaddr_ib *) &id->route.addr.src_addr; |
749 | *src = &((struct sdp_hh *) hdr)->src_addr; | 829 | ib->sib_family = listen_ib->sib_family; |
750 | *dst = &((struct sdp_hh *) hdr)->dst_addr; | 830 | ib->sib_pkey = path->pkey; |
751 | break; | 831 | ib->sib_flowinfo = path->flow_label; |
752 | default: | 832 | memcpy(&ib->sib_addr, &path->sgid, 16); |
753 | if (((struct cma_hdr *) hdr)->cma_version != CMA_VERSION) | 833 | ib->sib_sid = listen_ib->sib_sid; |
754 | return -EINVAL; | 834 | ib->sib_sid_mask = cpu_to_be64(0xffffffffffffffffULL); |
835 | ib->sib_scope_id = listen_ib->sib_scope_id; | ||
755 | 836 | ||
756 | *ip_ver = cma_get_ip_ver(hdr); | 837 | ib = (struct sockaddr_ib *) &id->route.addr.dst_addr; |
757 | *port = ((struct cma_hdr *) hdr)->port; | 838 | ib->sib_family = listen_ib->sib_family; |
758 | *src = &((struct cma_hdr *) hdr)->src_addr; | 839 | ib->sib_pkey = path->pkey; |
759 | *dst = &((struct cma_hdr *) hdr)->dst_addr; | 840 | ib->sib_flowinfo = path->flow_label; |
760 | break; | 841 | memcpy(&ib->sib_addr, &path->dgid, 16); |
761 | } | ||
762 | |||
763 | if (*ip_ver != 4 && *ip_ver != 6) | ||
764 | return -EINVAL; | ||
765 | return 0; | ||
766 | } | 842 | } |
767 | 843 | ||
768 | static void cma_save_net_info(struct rdma_addr *addr, | 844 | static void cma_save_ip4_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id, |
769 | struct rdma_addr *listen_addr, | 845 | struct cma_hdr *hdr) |
770 | u8 ip_ver, __be16 port, | ||
771 | union cma_ip_addr *src, union cma_ip_addr *dst) | ||
772 | { | 846 | { |
773 | struct sockaddr_in *listen4, *ip4; | 847 | struct sockaddr_in *listen4, *ip4; |
848 | |||
849 | listen4 = (struct sockaddr_in *) &listen_id->route.addr.src_addr; | ||
850 | ip4 = (struct sockaddr_in *) &id->route.addr.src_addr; | ||
851 | ip4->sin_family = listen4->sin_family; | ||
852 | ip4->sin_addr.s_addr = hdr->dst_addr.ip4.addr; | ||
853 | ip4->sin_port = listen4->sin_port; | ||
854 | |||
855 | ip4 = (struct sockaddr_in *) &id->route.addr.dst_addr; | ||
856 | ip4->sin_family = listen4->sin_family; | ||
857 | ip4->sin_addr.s_addr = hdr->src_addr.ip4.addr; | ||
858 | ip4->sin_port = hdr->port; | ||
859 | } | ||
860 | |||
861 | static void cma_save_ip6_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id, | ||
862 | struct cma_hdr *hdr) | ||
863 | { | ||
774 | struct sockaddr_in6 *listen6, *ip6; | 864 | struct sockaddr_in6 *listen6, *ip6; |
775 | 865 | ||
776 | switch (ip_ver) { | 866 | listen6 = (struct sockaddr_in6 *) &listen_id->route.addr.src_addr; |
867 | ip6 = (struct sockaddr_in6 *) &id->route.addr.src_addr; | ||
868 | ip6->sin6_family = listen6->sin6_family; | ||
869 | ip6->sin6_addr = hdr->dst_addr.ip6; | ||
870 | ip6->sin6_port = listen6->sin6_port; | ||
871 | |||
872 | ip6 = (struct sockaddr_in6 *) &id->route.addr.dst_addr; | ||
873 | ip6->sin6_family = listen6->sin6_family; | ||
874 | ip6->sin6_addr = hdr->src_addr.ip6; | ||
875 | ip6->sin6_port = hdr->port; | ||
876 | } | ||
877 | |||
878 | static int cma_save_net_info(struct rdma_cm_id *id, struct rdma_cm_id *listen_id, | ||
879 | struct ib_cm_event *ib_event) | ||
880 | { | ||
881 | struct cma_hdr *hdr; | ||
882 | |||
883 | if (listen_id->route.addr.src_addr.ss_family == AF_IB) { | ||
884 | cma_save_ib_info(id, listen_id, ib_event->param.req_rcvd.primary_path); | ||
885 | return 0; | ||
886 | } | ||
887 | |||
888 | hdr = ib_event->private_data; | ||
889 | if (hdr->cma_version != CMA_VERSION) | ||
890 | return -EINVAL; | ||
891 | |||
892 | switch (cma_get_ip_ver(hdr)) { | ||
777 | case 4: | 893 | case 4: |
778 | listen4 = (struct sockaddr_in *) &listen_addr->src_addr; | 894 | cma_save_ip4_info(id, listen_id, hdr); |
779 | ip4 = (struct sockaddr_in *) &addr->src_addr; | ||
780 | ip4->sin_family = listen4->sin_family; | ||
781 | ip4->sin_addr.s_addr = dst->ip4.addr; | ||
782 | ip4->sin_port = listen4->sin_port; | ||
783 | |||
784 | ip4 = (struct sockaddr_in *) &addr->dst_addr; | ||
785 | ip4->sin_family = listen4->sin_family; | ||
786 | ip4->sin_addr.s_addr = src->ip4.addr; | ||
787 | ip4->sin_port = port; | ||
788 | break; | 895 | break; |
789 | case 6: | 896 | case 6: |
790 | listen6 = (struct sockaddr_in6 *) &listen_addr->src_addr; | 897 | cma_save_ip6_info(id, listen_id, hdr); |
791 | ip6 = (struct sockaddr_in6 *) &addr->src_addr; | ||
792 | ip6->sin6_family = listen6->sin6_family; | ||
793 | ip6->sin6_addr = dst->ip6; | ||
794 | ip6->sin6_port = listen6->sin6_port; | ||
795 | |||
796 | ip6 = (struct sockaddr_in6 *) &addr->dst_addr; | ||
797 | ip6->sin6_family = listen6->sin6_family; | ||
798 | ip6->sin6_addr = src->ip6; | ||
799 | ip6->sin6_port = port; | ||
800 | break; | 898 | break; |
801 | default: | 899 | default: |
802 | break; | 900 | return -EINVAL; |
803 | } | 901 | } |
902 | return 0; | ||
804 | } | 903 | } |
805 | 904 | ||
806 | static inline int cma_user_data_offset(enum rdma_port_space ps) | 905 | static inline int cma_user_data_offset(struct rdma_id_private *id_priv) |
807 | { | 906 | { |
808 | switch (ps) { | 907 | return cma_family(id_priv) == AF_IB ? 0 : sizeof(struct cma_hdr); |
809 | case RDMA_PS_SDP: | ||
810 | return 0; | ||
811 | default: | ||
812 | return sizeof(struct cma_hdr); | ||
813 | } | ||
814 | } | 908 | } |
815 | 909 | ||
816 | static void cma_cancel_route(struct rdma_id_private *id_priv) | 910 | static void cma_cancel_route(struct rdma_id_private *id_priv) |
@@ -861,8 +955,7 @@ static void cma_cancel_operation(struct rdma_id_private *id_priv, | |||
861 | cma_cancel_route(id_priv); | 955 | cma_cancel_route(id_priv); |
862 | break; | 956 | break; |
863 | case RDMA_CM_LISTEN: | 957 | case RDMA_CM_LISTEN: |
864 | if (cma_any_addr((struct sockaddr *) &id_priv->id.route.addr.src_addr) | 958 | if (cma_any_addr(cma_src_addr(id_priv)) && !id_priv->cma_dev) |
865 | && !id_priv->cma_dev) | ||
866 | cma_cancel_listens(id_priv); | 959 | cma_cancel_listens(id_priv); |
867 | break; | 960 | break; |
868 | default: | 961 | default: |
@@ -977,16 +1070,6 @@ reject: | |||
977 | return ret; | 1070 | return ret; |
978 | } | 1071 | } |
979 | 1072 | ||
980 | static int cma_verify_rep(struct rdma_id_private *id_priv, void *data) | ||
981 | { | ||
982 | if (id_priv->id.ps == RDMA_PS_SDP && | ||
983 | sdp_get_majv(((struct sdp_hah *) data)->sdp_version) != | ||
984 | SDP_MAJ_VERSION) | ||
985 | return -EINVAL; | ||
986 | |||
987 | return 0; | ||
988 | } | ||
989 | |||
990 | static void cma_set_rep_event_data(struct rdma_cm_event *event, | 1073 | static void cma_set_rep_event_data(struct rdma_cm_event *event, |
991 | struct ib_cm_rep_event_param *rep_data, | 1074 | struct ib_cm_rep_event_param *rep_data, |
992 | void *private_data) | 1075 | void *private_data) |
@@ -1021,15 +1104,13 @@ static int cma_ib_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) | |||
1021 | event.status = -ETIMEDOUT; | 1104 | event.status = -ETIMEDOUT; |
1022 | break; | 1105 | break; |
1023 | case IB_CM_REP_RECEIVED: | 1106 | case IB_CM_REP_RECEIVED: |
1024 | event.status = cma_verify_rep(id_priv, ib_event->private_data); | 1107 | if (id_priv->id.qp) { |
1025 | if (event.status) | ||
1026 | event.event = RDMA_CM_EVENT_CONNECT_ERROR; | ||
1027 | else if (id_priv->id.qp && id_priv->id.ps != RDMA_PS_SDP) { | ||
1028 | event.status = cma_rep_recv(id_priv); | 1108 | event.status = cma_rep_recv(id_priv); |
1029 | event.event = event.status ? RDMA_CM_EVENT_CONNECT_ERROR : | 1109 | event.event = event.status ? RDMA_CM_EVENT_CONNECT_ERROR : |
1030 | RDMA_CM_EVENT_ESTABLISHED; | 1110 | RDMA_CM_EVENT_ESTABLISHED; |
1031 | } else | 1111 | } else { |
1032 | event.event = RDMA_CM_EVENT_CONNECT_RESPONSE; | 1112 | event.event = RDMA_CM_EVENT_CONNECT_RESPONSE; |
1113 | } | ||
1033 | cma_set_rep_event_data(&event, &ib_event->param.rep_rcvd, | 1114 | cma_set_rep_event_data(&event, &ib_event->param.rep_rcvd, |
1034 | ib_event->private_data); | 1115 | ib_event->private_data); |
1035 | break; | 1116 | break; |
@@ -1085,22 +1166,16 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id, | |||
1085 | struct rdma_id_private *id_priv; | 1166 | struct rdma_id_private *id_priv; |
1086 | struct rdma_cm_id *id; | 1167 | struct rdma_cm_id *id; |
1087 | struct rdma_route *rt; | 1168 | struct rdma_route *rt; |
1088 | union cma_ip_addr *src, *dst; | ||
1089 | __be16 port; | ||
1090 | u8 ip_ver; | ||
1091 | int ret; | 1169 | int ret; |
1092 | 1170 | ||
1093 | if (cma_get_net_info(ib_event->private_data, listen_id->ps, | ||
1094 | &ip_ver, &port, &src, &dst)) | ||
1095 | return NULL; | ||
1096 | |||
1097 | id = rdma_create_id(listen_id->event_handler, listen_id->context, | 1171 | id = rdma_create_id(listen_id->event_handler, listen_id->context, |
1098 | listen_id->ps, ib_event->param.req_rcvd.qp_type); | 1172 | listen_id->ps, ib_event->param.req_rcvd.qp_type); |
1099 | if (IS_ERR(id)) | 1173 | if (IS_ERR(id)) |
1100 | return NULL; | 1174 | return NULL; |
1101 | 1175 | ||
1102 | cma_save_net_info(&id->route.addr, &listen_id->route.addr, | 1176 | id_priv = container_of(id, struct rdma_id_private, id); |
1103 | ip_ver, port, src, dst); | 1177 | if (cma_save_net_info(id, listen_id, ib_event)) |
1178 | goto err; | ||
1104 | 1179 | ||
1105 | rt = &id->route; | 1180 | rt = &id->route; |
1106 | rt->num_paths = ib_event->param.req_rcvd.alternate_path ? 2 : 1; | 1181 | rt->num_paths = ib_event->param.req_rcvd.alternate_path ? 2 : 1; |
@@ -1113,19 +1188,17 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id, | |||
1113 | if (rt->num_paths == 2) | 1188 | if (rt->num_paths == 2) |
1114 | rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path; | 1189 | rt->path_rec[1] = *ib_event->param.req_rcvd.alternate_path; |
1115 | 1190 | ||
1116 | if (cma_any_addr((struct sockaddr *) &rt->addr.src_addr)) { | 1191 | if (cma_any_addr(cma_src_addr(id_priv))) { |
1117 | rt->addr.dev_addr.dev_type = ARPHRD_INFINIBAND; | 1192 | rt->addr.dev_addr.dev_type = ARPHRD_INFINIBAND; |
1118 | rdma_addr_set_sgid(&rt->addr.dev_addr, &rt->path_rec[0].sgid); | 1193 | rdma_addr_set_sgid(&rt->addr.dev_addr, &rt->path_rec[0].sgid); |
1119 | ib_addr_set_pkey(&rt->addr.dev_addr, be16_to_cpu(rt->path_rec[0].pkey)); | 1194 | ib_addr_set_pkey(&rt->addr.dev_addr, be16_to_cpu(rt->path_rec[0].pkey)); |
1120 | } else { | 1195 | } else { |
1121 | ret = rdma_translate_ip((struct sockaddr *) &rt->addr.src_addr, | 1196 | ret = cma_translate_addr(cma_src_addr(id_priv), &rt->addr.dev_addr); |
1122 | &rt->addr.dev_addr); | ||
1123 | if (ret) | 1197 | if (ret) |
1124 | goto err; | 1198 | goto err; |
1125 | } | 1199 | } |
1126 | rdma_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid); | 1200 | rdma_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid); |
1127 | 1201 | ||
1128 | id_priv = container_of(id, struct rdma_id_private, id); | ||
1129 | id_priv->state = RDMA_CM_CONNECT; | 1202 | id_priv->state = RDMA_CM_CONNECT; |
1130 | return id_priv; | 1203 | return id_priv; |
1131 | 1204 | ||
@@ -1139,9 +1212,6 @@ static struct rdma_id_private *cma_new_udp_id(struct rdma_cm_id *listen_id, | |||
1139 | { | 1212 | { |
1140 | struct rdma_id_private *id_priv; | 1213 | struct rdma_id_private *id_priv; |
1141 | struct rdma_cm_id *id; | 1214 | struct rdma_cm_id *id; |
1142 | union cma_ip_addr *src, *dst; | ||
1143 | __be16 port; | ||
1144 | u8 ip_ver; | ||
1145 | int ret; | 1215 | int ret; |
1146 | 1216 | ||
1147 | id = rdma_create_id(listen_id->event_handler, listen_id->context, | 1217 | id = rdma_create_id(listen_id->event_handler, listen_id->context, |
@@ -1149,22 +1219,16 @@ static struct rdma_id_private *cma_new_udp_id(struct rdma_cm_id *listen_id, | |||
1149 | if (IS_ERR(id)) | 1219 | if (IS_ERR(id)) |
1150 | return NULL; | 1220 | return NULL; |
1151 | 1221 | ||
1152 | 1222 | id_priv = container_of(id, struct rdma_id_private, id); | |
1153 | if (cma_get_net_info(ib_event->private_data, listen_id->ps, | 1223 | if (cma_save_net_info(id, listen_id, ib_event)) |
1154 | &ip_ver, &port, &src, &dst)) | ||
1155 | goto err; | 1224 | goto err; |
1156 | 1225 | ||
1157 | cma_save_net_info(&id->route.addr, &listen_id->route.addr, | ||
1158 | ip_ver, port, src, dst); | ||
1159 | |||
1160 | if (!cma_any_addr((struct sockaddr *) &id->route.addr.src_addr)) { | 1226 | if (!cma_any_addr((struct sockaddr *) &id->route.addr.src_addr)) { |
1161 | ret = rdma_translate_ip((struct sockaddr *) &id->route.addr.src_addr, | 1227 | ret = cma_translate_addr(cma_src_addr(id_priv), &id->route.addr.dev_addr); |
1162 | &id->route.addr.dev_addr); | ||
1163 | if (ret) | 1228 | if (ret) |
1164 | goto err; | 1229 | goto err; |
1165 | } | 1230 | } |
1166 | 1231 | ||
1167 | id_priv = container_of(id, struct rdma_id_private, id); | ||
1168 | id_priv->state = RDMA_CM_CONNECT; | 1232 | id_priv->state = RDMA_CM_CONNECT; |
1169 | return id_priv; | 1233 | return id_priv; |
1170 | err: | 1234 | err: |
@@ -1210,7 +1274,7 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) | |||
1210 | return -ECONNABORTED; | 1274 | return -ECONNABORTED; |
1211 | 1275 | ||
1212 | memset(&event, 0, sizeof event); | 1276 | memset(&event, 0, sizeof event); |
1213 | offset = cma_user_data_offset(listen_id->id.ps); | 1277 | offset = cma_user_data_offset(listen_id); |
1214 | event.event = RDMA_CM_EVENT_CONNECT_REQUEST; | 1278 | event.event = RDMA_CM_EVENT_CONNECT_REQUEST; |
1215 | if (ib_event->event == IB_CM_SIDR_REQ_RECEIVED) { | 1279 | if (ib_event->event == IB_CM_SIDR_REQ_RECEIVED) { |
1216 | conn_id = cma_new_udp_id(&listen_id->id, ib_event); | 1280 | conn_id = cma_new_udp_id(&listen_id->id, ib_event); |
@@ -1272,58 +1336,44 @@ err1: | |||
1272 | return ret; | 1336 | return ret; |
1273 | } | 1337 | } |
1274 | 1338 | ||
1275 | static __be64 cma_get_service_id(enum rdma_port_space ps, struct sockaddr *addr) | 1339 | __be64 rdma_get_service_id(struct rdma_cm_id *id, struct sockaddr *addr) |
1276 | { | 1340 | { |
1277 | return cpu_to_be64(((u64)ps << 16) + be16_to_cpu(cma_port(addr))); | 1341 | if (addr->sa_family == AF_IB) |
1342 | return ((struct sockaddr_ib *) addr)->sib_sid; | ||
1343 | |||
1344 | return cpu_to_be64(((u64)id->ps << 16) + be16_to_cpu(cma_port(addr))); | ||
1278 | } | 1345 | } |
1346 | EXPORT_SYMBOL(rdma_get_service_id); | ||
1279 | 1347 | ||
1280 | static void cma_set_compare_data(enum rdma_port_space ps, struct sockaddr *addr, | 1348 | static void cma_set_compare_data(enum rdma_port_space ps, struct sockaddr *addr, |
1281 | struct ib_cm_compare_data *compare) | 1349 | struct ib_cm_compare_data *compare) |
1282 | { | 1350 | { |
1283 | struct cma_hdr *cma_data, *cma_mask; | 1351 | struct cma_hdr *cma_data, *cma_mask; |
1284 | struct sdp_hh *sdp_data, *sdp_mask; | ||
1285 | __be32 ip4_addr; | 1352 | __be32 ip4_addr; |
1286 | struct in6_addr ip6_addr; | 1353 | struct in6_addr ip6_addr; |
1287 | 1354 | ||
1288 | memset(compare, 0, sizeof *compare); | 1355 | memset(compare, 0, sizeof *compare); |
1289 | cma_data = (void *) compare->data; | 1356 | cma_data = (void *) compare->data; |
1290 | cma_mask = (void *) compare->mask; | 1357 | cma_mask = (void *) compare->mask; |
1291 | sdp_data = (void *) compare->data; | ||
1292 | sdp_mask = (void *) compare->mask; | ||
1293 | 1358 | ||
1294 | switch (addr->sa_family) { | 1359 | switch (addr->sa_family) { |
1295 | case AF_INET: | 1360 | case AF_INET: |
1296 | ip4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; | 1361 | ip4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; |
1297 | if (ps == RDMA_PS_SDP) { | 1362 | cma_set_ip_ver(cma_data, 4); |
1298 | sdp_set_ip_ver(sdp_data, 4); | 1363 | cma_set_ip_ver(cma_mask, 0xF); |
1299 | sdp_set_ip_ver(sdp_mask, 0xF); | 1364 | if (!cma_any_addr(addr)) { |
1300 | sdp_data->dst_addr.ip4.addr = ip4_addr; | 1365 | cma_data->dst_addr.ip4.addr = ip4_addr; |
1301 | sdp_mask->dst_addr.ip4.addr = htonl(~0); | 1366 | cma_mask->dst_addr.ip4.addr = htonl(~0); |
1302 | } else { | ||
1303 | cma_set_ip_ver(cma_data, 4); | ||
1304 | cma_set_ip_ver(cma_mask, 0xF); | ||
1305 | if (!cma_any_addr(addr)) { | ||
1306 | cma_data->dst_addr.ip4.addr = ip4_addr; | ||
1307 | cma_mask->dst_addr.ip4.addr = htonl(~0); | ||
1308 | } | ||
1309 | } | 1367 | } |
1310 | break; | 1368 | break; |
1311 | case AF_INET6: | 1369 | case AF_INET6: |
1312 | ip6_addr = ((struct sockaddr_in6 *) addr)->sin6_addr; | 1370 | ip6_addr = ((struct sockaddr_in6 *) addr)->sin6_addr; |
1313 | if (ps == RDMA_PS_SDP) { | 1371 | cma_set_ip_ver(cma_data, 6); |
1314 | sdp_set_ip_ver(sdp_data, 6); | 1372 | cma_set_ip_ver(cma_mask, 0xF); |
1315 | sdp_set_ip_ver(sdp_mask, 0xF); | 1373 | if (!cma_any_addr(addr)) { |
1316 | sdp_data->dst_addr.ip6 = ip6_addr; | 1374 | cma_data->dst_addr.ip6 = ip6_addr; |
1317 | memset(&sdp_mask->dst_addr.ip6, 0xFF, | 1375 | memset(&cma_mask->dst_addr.ip6, 0xFF, |
1318 | sizeof sdp_mask->dst_addr.ip6); | 1376 | sizeof cma_mask->dst_addr.ip6); |
1319 | } else { | ||
1320 | cma_set_ip_ver(cma_data, 6); | ||
1321 | cma_set_ip_ver(cma_mask, 0xF); | ||
1322 | if (!cma_any_addr(addr)) { | ||
1323 | cma_data->dst_addr.ip6 = ip6_addr; | ||
1324 | memset(&cma_mask->dst_addr.ip6, 0xFF, | ||
1325 | sizeof cma_mask->dst_addr.ip6); | ||
1326 | } | ||
1327 | } | 1377 | } |
1328 | break; | 1378 | break; |
1329 | default: | 1379 | default: |
@@ -1347,9 +1397,9 @@ static int cma_iw_handler(struct iw_cm_id *iw_id, struct iw_cm_event *iw_event) | |||
1347 | event.event = RDMA_CM_EVENT_DISCONNECTED; | 1397 | event.event = RDMA_CM_EVENT_DISCONNECTED; |
1348 | break; | 1398 | break; |
1349 | case IW_CM_EVENT_CONNECT_REPLY: | 1399 | case IW_CM_EVENT_CONNECT_REPLY: |
1350 | sin = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr; | 1400 | sin = (struct sockaddr_in *) cma_src_addr(id_priv); |
1351 | *sin = iw_event->local_addr; | 1401 | *sin = iw_event->local_addr; |
1352 | sin = (struct sockaddr_in *) &id_priv->id.route.addr.dst_addr; | 1402 | sin = (struct sockaddr_in *) cma_dst_addr(id_priv); |
1353 | *sin = iw_event->remote_addr; | 1403 | *sin = iw_event->remote_addr; |
1354 | switch (iw_event->status) { | 1404 | switch (iw_event->status) { |
1355 | case 0: | 1405 | case 0: |
@@ -1447,9 +1497,9 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, | |||
1447 | cm_id->context = conn_id; | 1497 | cm_id->context = conn_id; |
1448 | cm_id->cm_handler = cma_iw_handler; | 1498 | cm_id->cm_handler = cma_iw_handler; |
1449 | 1499 | ||
1450 | sin = (struct sockaddr_in *) &new_cm_id->route.addr.src_addr; | 1500 | sin = (struct sockaddr_in *) cma_src_addr(conn_id); |
1451 | *sin = iw_event->local_addr; | 1501 | *sin = iw_event->local_addr; |
1452 | sin = (struct sockaddr_in *) &new_cm_id->route.addr.dst_addr; | 1502 | sin = (struct sockaddr_in *) cma_dst_addr(conn_id); |
1453 | *sin = iw_event->remote_addr; | 1503 | *sin = iw_event->remote_addr; |
1454 | 1504 | ||
1455 | ret = ib_query_device(conn_id->id.device, &attr); | 1505 | ret = ib_query_device(conn_id->id.device, &attr); |
@@ -1506,8 +1556,8 @@ static int cma_ib_listen(struct rdma_id_private *id_priv) | |||
1506 | 1556 | ||
1507 | id_priv->cm_id.ib = id; | 1557 | id_priv->cm_id.ib = id; |
1508 | 1558 | ||
1509 | addr = (struct sockaddr *) &id_priv->id.route.addr.src_addr; | 1559 | addr = cma_src_addr(id_priv); |
1510 | svc_id = cma_get_service_id(id_priv->id.ps, addr); | 1560 | svc_id = rdma_get_service_id(&id_priv->id, addr); |
1511 | if (cma_any_addr(addr) && !id_priv->afonly) | 1561 | if (cma_any_addr(addr) && !id_priv->afonly) |
1512 | ret = ib_cm_listen(id_priv->cm_id.ib, svc_id, 0, NULL); | 1562 | ret = ib_cm_listen(id_priv->cm_id.ib, svc_id, 0, NULL); |
1513 | else { | 1563 | else { |
@@ -1537,7 +1587,7 @@ static int cma_iw_listen(struct rdma_id_private *id_priv, int backlog) | |||
1537 | 1587 | ||
1538 | id_priv->cm_id.iw = id; | 1588 | id_priv->cm_id.iw = id; |
1539 | 1589 | ||
1540 | sin = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr; | 1590 | sin = (struct sockaddr_in *) cma_src_addr(id_priv); |
1541 | id_priv->cm_id.iw->local_addr = *sin; | 1591 | id_priv->cm_id.iw->local_addr = *sin; |
1542 | 1592 | ||
1543 | ret = iw_cm_listen(id_priv->cm_id.iw, backlog); | 1593 | ret = iw_cm_listen(id_priv->cm_id.iw, backlog); |
@@ -1567,6 +1617,10 @@ static void cma_listen_on_dev(struct rdma_id_private *id_priv, | |||
1567 | struct rdma_cm_id *id; | 1617 | struct rdma_cm_id *id; |
1568 | int ret; | 1618 | int ret; |
1569 | 1619 | ||
1620 | if (cma_family(id_priv) == AF_IB && | ||
1621 | rdma_node_get_transport(cma_dev->device->node_type) != RDMA_TRANSPORT_IB) | ||
1622 | return; | ||
1623 | |||
1570 | id = rdma_create_id(cma_listen_handler, id_priv, id_priv->id.ps, | 1624 | id = rdma_create_id(cma_listen_handler, id_priv, id_priv->id.ps, |
1571 | id_priv->id.qp_type); | 1625 | id_priv->id.qp_type); |
1572 | if (IS_ERR(id)) | 1626 | if (IS_ERR(id)) |
@@ -1575,8 +1629,8 @@ static void cma_listen_on_dev(struct rdma_id_private *id_priv, | |||
1575 | dev_id_priv = container_of(id, struct rdma_id_private, id); | 1629 | dev_id_priv = container_of(id, struct rdma_id_private, id); |
1576 | 1630 | ||
1577 | dev_id_priv->state = RDMA_CM_ADDR_BOUND; | 1631 | dev_id_priv->state = RDMA_CM_ADDR_BOUND; |
1578 | memcpy(&id->route.addr.src_addr, &id_priv->id.route.addr.src_addr, | 1632 | memcpy(cma_src_addr(dev_id_priv), cma_src_addr(id_priv), |
1579 | ip_addr_size((struct sockaddr *) &id_priv->id.route.addr.src_addr)); | 1633 | rdma_addr_size(cma_src_addr(id_priv))); |
1580 | 1634 | ||
1581 | cma_attach_to_dev(dev_id_priv, cma_dev); | 1635 | cma_attach_to_dev(dev_id_priv, cma_dev); |
1582 | list_add_tail(&dev_id_priv->listen_list, &id_priv->listen_list); | 1636 | list_add_tail(&dev_id_priv->listen_list, &id_priv->listen_list); |
@@ -1634,31 +1688,39 @@ static void cma_query_handler(int status, struct ib_sa_path_rec *path_rec, | |||
1634 | static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms, | 1688 | static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms, |
1635 | struct cma_work *work) | 1689 | struct cma_work *work) |
1636 | { | 1690 | { |
1637 | struct rdma_addr *addr = &id_priv->id.route.addr; | 1691 | struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr; |
1638 | struct ib_sa_path_rec path_rec; | 1692 | struct ib_sa_path_rec path_rec; |
1639 | ib_sa_comp_mask comp_mask; | 1693 | ib_sa_comp_mask comp_mask; |
1640 | struct sockaddr_in6 *sin6; | 1694 | struct sockaddr_in6 *sin6; |
1695 | struct sockaddr_ib *sib; | ||
1641 | 1696 | ||
1642 | memset(&path_rec, 0, sizeof path_rec); | 1697 | memset(&path_rec, 0, sizeof path_rec); |
1643 | rdma_addr_get_sgid(&addr->dev_addr, &path_rec.sgid); | 1698 | rdma_addr_get_sgid(dev_addr, &path_rec.sgid); |
1644 | rdma_addr_get_dgid(&addr->dev_addr, &path_rec.dgid); | 1699 | rdma_addr_get_dgid(dev_addr, &path_rec.dgid); |
1645 | path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(&addr->dev_addr)); | 1700 | path_rec.pkey = cpu_to_be16(ib_addr_get_pkey(dev_addr)); |
1646 | path_rec.numb_path = 1; | 1701 | path_rec.numb_path = 1; |
1647 | path_rec.reversible = 1; | 1702 | path_rec.reversible = 1; |
1648 | path_rec.service_id = cma_get_service_id(id_priv->id.ps, | 1703 | path_rec.service_id = rdma_get_service_id(&id_priv->id, cma_dst_addr(id_priv)); |
1649 | (struct sockaddr *) &addr->dst_addr); | ||
1650 | 1704 | ||
1651 | comp_mask = IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID | | 1705 | comp_mask = IB_SA_PATH_REC_DGID | IB_SA_PATH_REC_SGID | |
1652 | IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH | | 1706 | IB_SA_PATH_REC_PKEY | IB_SA_PATH_REC_NUMB_PATH | |
1653 | IB_SA_PATH_REC_REVERSIBLE | IB_SA_PATH_REC_SERVICE_ID; | 1707 | IB_SA_PATH_REC_REVERSIBLE | IB_SA_PATH_REC_SERVICE_ID; |
1654 | 1708 | ||
1655 | if (addr->src_addr.ss_family == AF_INET) { | 1709 | switch (cma_family(id_priv)) { |
1710 | case AF_INET: | ||
1656 | path_rec.qos_class = cpu_to_be16((u16) id_priv->tos); | 1711 | path_rec.qos_class = cpu_to_be16((u16) id_priv->tos); |
1657 | comp_mask |= IB_SA_PATH_REC_QOS_CLASS; | 1712 | comp_mask |= IB_SA_PATH_REC_QOS_CLASS; |
1658 | } else { | 1713 | break; |
1659 | sin6 = (struct sockaddr_in6 *) &addr->src_addr; | 1714 | case AF_INET6: |
1715 | sin6 = (struct sockaddr_in6 *) cma_src_addr(id_priv); | ||
1660 | path_rec.traffic_class = (u8) (be32_to_cpu(sin6->sin6_flowinfo) >> 20); | 1716 | path_rec.traffic_class = (u8) (be32_to_cpu(sin6->sin6_flowinfo) >> 20); |
1661 | comp_mask |= IB_SA_PATH_REC_TRAFFIC_CLASS; | 1717 | comp_mask |= IB_SA_PATH_REC_TRAFFIC_CLASS; |
1718 | break; | ||
1719 | case AF_IB: | ||
1720 | sib = (struct sockaddr_ib *) cma_src_addr(id_priv); | ||
1721 | path_rec.traffic_class = (u8) (be32_to_cpu(sib->sib_flowinfo) >> 20); | ||
1722 | comp_mask |= IB_SA_PATH_REC_TRAFFIC_CLASS; | ||
1723 | break; | ||
1662 | } | 1724 | } |
1663 | 1725 | ||
1664 | id_priv->query_id = ib_sa_path_rec_get(&sa_client, id_priv->id.device, | 1726 | id_priv->query_id = ib_sa_path_rec_get(&sa_client, id_priv->id.device, |
@@ -1800,14 +1862,9 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv) | |||
1800 | struct rdma_addr *addr = &route->addr; | 1862 | struct rdma_addr *addr = &route->addr; |
1801 | struct cma_work *work; | 1863 | struct cma_work *work; |
1802 | int ret; | 1864 | int ret; |
1803 | struct sockaddr_in *src_addr = (struct sockaddr_in *)&route->addr.src_addr; | ||
1804 | struct sockaddr_in *dst_addr = (struct sockaddr_in *)&route->addr.dst_addr; | ||
1805 | struct net_device *ndev = NULL; | 1865 | struct net_device *ndev = NULL; |
1806 | u16 vid; | 1866 | u16 vid; |
1807 | 1867 | ||
1808 | if (src_addr->sin_family != dst_addr->sin_family) | ||
1809 | return -EINVAL; | ||
1810 | |||
1811 | work = kzalloc(sizeof *work, GFP_KERNEL); | 1868 | work = kzalloc(sizeof *work, GFP_KERNEL); |
1812 | if (!work) | 1869 | if (!work) |
1813 | return -ENOMEM; | 1870 | return -ENOMEM; |
@@ -1913,28 +1970,57 @@ err: | |||
1913 | } | 1970 | } |
1914 | EXPORT_SYMBOL(rdma_resolve_route); | 1971 | EXPORT_SYMBOL(rdma_resolve_route); |
1915 | 1972 | ||
1973 | static void cma_set_loopback(struct sockaddr *addr) | ||
1974 | { | ||
1975 | switch (addr->sa_family) { | ||
1976 | case AF_INET: | ||
1977 | ((struct sockaddr_in *) addr)->sin_addr.s_addr = htonl(INADDR_LOOPBACK); | ||
1978 | break; | ||
1979 | case AF_INET6: | ||
1980 | ipv6_addr_set(&((struct sockaddr_in6 *) addr)->sin6_addr, | ||
1981 | 0, 0, 0, htonl(1)); | ||
1982 | break; | ||
1983 | default: | ||
1984 | ib_addr_set(&((struct sockaddr_ib *) addr)->sib_addr, | ||
1985 | 0, 0, 0, htonl(1)); | ||
1986 | break; | ||
1987 | } | ||
1988 | } | ||
1989 | |||
1916 | static int cma_bind_loopback(struct rdma_id_private *id_priv) | 1990 | static int cma_bind_loopback(struct rdma_id_private *id_priv) |
1917 | { | 1991 | { |
1918 | struct cma_device *cma_dev; | 1992 | struct cma_device *cma_dev, *cur_dev; |
1919 | struct ib_port_attr port_attr; | 1993 | struct ib_port_attr port_attr; |
1920 | union ib_gid gid; | 1994 | union ib_gid gid; |
1921 | u16 pkey; | 1995 | u16 pkey; |
1922 | int ret; | 1996 | int ret; |
1923 | u8 p; | 1997 | u8 p; |
1924 | 1998 | ||
1999 | cma_dev = NULL; | ||
1925 | mutex_lock(&lock); | 2000 | mutex_lock(&lock); |
1926 | if (list_empty(&dev_list)) { | 2001 | list_for_each_entry(cur_dev, &dev_list, list) { |
2002 | if (cma_family(id_priv) == AF_IB && | ||
2003 | rdma_node_get_transport(cur_dev->device->node_type) != RDMA_TRANSPORT_IB) | ||
2004 | continue; | ||
2005 | |||
2006 | if (!cma_dev) | ||
2007 | cma_dev = cur_dev; | ||
2008 | |||
2009 | for (p = 1; p <= cur_dev->device->phys_port_cnt; ++p) { | ||
2010 | if (!ib_query_port(cur_dev->device, p, &port_attr) && | ||
2011 | port_attr.state == IB_PORT_ACTIVE) { | ||
2012 | cma_dev = cur_dev; | ||
2013 | goto port_found; | ||
2014 | } | ||
2015 | } | ||
2016 | } | ||
2017 | |||
2018 | if (!cma_dev) { | ||
1927 | ret = -ENODEV; | 2019 | ret = -ENODEV; |
1928 | goto out; | 2020 | goto out; |
1929 | } | 2021 | } |
1930 | list_for_each_entry(cma_dev, &dev_list, list) | ||
1931 | for (p = 1; p <= cma_dev->device->phys_port_cnt; ++p) | ||
1932 | if (!ib_query_port(cma_dev->device, p, &port_attr) && | ||
1933 | port_attr.state == IB_PORT_ACTIVE) | ||
1934 | goto port_found; | ||
1935 | 2022 | ||
1936 | p = 1; | 2023 | p = 1; |
1937 | cma_dev = list_entry(dev_list.next, struct cma_device, list); | ||
1938 | 2024 | ||
1939 | port_found: | 2025 | port_found: |
1940 | ret = ib_get_cached_gid(cma_dev->device, p, 0, &gid); | 2026 | ret = ib_get_cached_gid(cma_dev->device, p, 0, &gid); |
@@ -1953,6 +2039,7 @@ port_found: | |||
1953 | ib_addr_set_pkey(&id_priv->id.route.addr.dev_addr, pkey); | 2039 | ib_addr_set_pkey(&id_priv->id.route.addr.dev_addr, pkey); |
1954 | id_priv->id.port_num = p; | 2040 | id_priv->id.port_num = p; |
1955 | cma_attach_to_dev(id_priv, cma_dev); | 2041 | cma_attach_to_dev(id_priv, cma_dev); |
2042 | cma_set_loopback(cma_src_addr(id_priv)); | ||
1956 | out: | 2043 | out: |
1957 | mutex_unlock(&lock); | 2044 | mutex_unlock(&lock); |
1958 | return ret; | 2045 | return ret; |
@@ -1980,8 +2067,7 @@ static void addr_handler(int status, struct sockaddr *src_addr, | |||
1980 | event.event = RDMA_CM_EVENT_ADDR_ERROR; | 2067 | event.event = RDMA_CM_EVENT_ADDR_ERROR; |
1981 | event.status = status; | 2068 | event.status = status; |
1982 | } else { | 2069 | } else { |
1983 | memcpy(&id_priv->id.route.addr.src_addr, src_addr, | 2070 | memcpy(cma_src_addr(id_priv), src_addr, rdma_addr_size(src_addr)); |
1984 | ip_addr_size(src_addr)); | ||
1985 | event.event = RDMA_CM_EVENT_ADDR_RESOLVED; | 2071 | event.event = RDMA_CM_EVENT_ADDR_RESOLVED; |
1986 | } | 2072 | } |
1987 | 2073 | ||
@@ -2000,7 +2086,6 @@ out: | |||
2000 | static int cma_resolve_loopback(struct rdma_id_private *id_priv) | 2086 | static int cma_resolve_loopback(struct rdma_id_private *id_priv) |
2001 | { | 2087 | { |
2002 | struct cma_work *work; | 2088 | struct cma_work *work; |
2003 | struct sockaddr *src, *dst; | ||
2004 | union ib_gid gid; | 2089 | union ib_gid gid; |
2005 | int ret; | 2090 | int ret; |
2006 | 2091 | ||
@@ -2017,18 +2102,36 @@ static int cma_resolve_loopback(struct rdma_id_private *id_priv) | |||
2017 | rdma_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid); | 2102 | rdma_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid); |
2018 | rdma_addr_set_dgid(&id_priv->id.route.addr.dev_addr, &gid); | 2103 | rdma_addr_set_dgid(&id_priv->id.route.addr.dev_addr, &gid); |
2019 | 2104 | ||
2020 | src = (struct sockaddr *) &id_priv->id.route.addr.src_addr; | 2105 | work->id = id_priv; |
2021 | if (cma_zero_addr(src)) { | 2106 | INIT_WORK(&work->work, cma_work_handler); |
2022 | dst = (struct sockaddr *) &id_priv->id.route.addr.dst_addr; | 2107 | work->old_state = RDMA_CM_ADDR_QUERY; |
2023 | if ((src->sa_family = dst->sa_family) == AF_INET) { | 2108 | work->new_state = RDMA_CM_ADDR_RESOLVED; |
2024 | ((struct sockaddr_in *)src)->sin_addr = | 2109 | work->event.event = RDMA_CM_EVENT_ADDR_RESOLVED; |
2025 | ((struct sockaddr_in *)dst)->sin_addr; | 2110 | queue_work(cma_wq, &work->work); |
2026 | } else { | 2111 | return 0; |
2027 | ((struct sockaddr_in6 *)src)->sin6_addr = | 2112 | err: |
2028 | ((struct sockaddr_in6 *)dst)->sin6_addr; | 2113 | kfree(work); |
2029 | } | 2114 | return ret; |
2115 | } | ||
2116 | |||
2117 | static int cma_resolve_ib_addr(struct rdma_id_private *id_priv) | ||
2118 | { | ||
2119 | struct cma_work *work; | ||
2120 | int ret; | ||
2121 | |||
2122 | work = kzalloc(sizeof *work, GFP_KERNEL); | ||
2123 | if (!work) | ||
2124 | return -ENOMEM; | ||
2125 | |||
2126 | if (!id_priv->cma_dev) { | ||
2127 | ret = cma_resolve_ib_dev(id_priv); | ||
2128 | if (ret) | ||
2129 | goto err; | ||
2030 | } | 2130 | } |
2031 | 2131 | ||
2132 | rdma_addr_set_dgid(&id_priv->id.route.addr.dev_addr, (union ib_gid *) | ||
2133 | &(((struct sockaddr_ib *) &id_priv->id.route.addr.dst_addr)->sib_addr)); | ||
2134 | |||
2032 | work->id = id_priv; | 2135 | work->id = id_priv; |
2033 | INIT_WORK(&work->work, cma_work_handler); | 2136 | INIT_WORK(&work->work, cma_work_handler); |
2034 | work->old_state = RDMA_CM_ADDR_QUERY; | 2137 | work->old_state = RDMA_CM_ADDR_QUERY; |
@@ -2046,9 +2149,13 @@ static int cma_bind_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, | |||
2046 | { | 2149 | { |
2047 | if (!src_addr || !src_addr->sa_family) { | 2150 | if (!src_addr || !src_addr->sa_family) { |
2048 | src_addr = (struct sockaddr *) &id->route.addr.src_addr; | 2151 | src_addr = (struct sockaddr *) &id->route.addr.src_addr; |
2049 | if ((src_addr->sa_family = dst_addr->sa_family) == AF_INET6) { | 2152 | src_addr->sa_family = dst_addr->sa_family; |
2153 | if (dst_addr->sa_family == AF_INET6) { | ||
2050 | ((struct sockaddr_in6 *) src_addr)->sin6_scope_id = | 2154 | ((struct sockaddr_in6 *) src_addr)->sin6_scope_id = |
2051 | ((struct sockaddr_in6 *) dst_addr)->sin6_scope_id; | 2155 | ((struct sockaddr_in6 *) dst_addr)->sin6_scope_id; |
2156 | } else if (dst_addr->sa_family == AF_IB) { | ||
2157 | ((struct sockaddr_ib *) src_addr)->sib_pkey = | ||
2158 | ((struct sockaddr_ib *) dst_addr)->sib_pkey; | ||
2052 | } | 2159 | } |
2053 | } | 2160 | } |
2054 | return rdma_bind_addr(id, src_addr); | 2161 | return rdma_bind_addr(id, src_addr); |
@@ -2067,17 +2174,25 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, | |||
2067 | return ret; | 2174 | return ret; |
2068 | } | 2175 | } |
2069 | 2176 | ||
2177 | if (cma_family(id_priv) != dst_addr->sa_family) | ||
2178 | return -EINVAL; | ||
2179 | |||
2070 | if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY)) | 2180 | if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY)) |
2071 | return -EINVAL; | 2181 | return -EINVAL; |
2072 | 2182 | ||
2073 | atomic_inc(&id_priv->refcount); | 2183 | atomic_inc(&id_priv->refcount); |
2074 | memcpy(&id->route.addr.dst_addr, dst_addr, ip_addr_size(dst_addr)); | 2184 | memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr)); |
2075 | if (cma_any_addr(dst_addr)) | 2185 | if (cma_any_addr(dst_addr)) { |
2076 | ret = cma_resolve_loopback(id_priv); | 2186 | ret = cma_resolve_loopback(id_priv); |
2077 | else | 2187 | } else { |
2078 | ret = rdma_resolve_ip(&addr_client, (struct sockaddr *) &id->route.addr.src_addr, | 2188 | if (dst_addr->sa_family == AF_IB) { |
2079 | dst_addr, &id->route.addr.dev_addr, | 2189 | ret = cma_resolve_ib_addr(id_priv); |
2080 | timeout_ms, addr_handler, id_priv); | 2190 | } else { |
2191 | ret = rdma_resolve_ip(&addr_client, cma_src_addr(id_priv), | ||
2192 | dst_addr, &id->route.addr.dev_addr, | ||
2193 | timeout_ms, addr_handler, id_priv); | ||
2194 | } | ||
2195 | } | ||
2081 | if (ret) | 2196 | if (ret) |
2082 | goto err; | 2197 | goto err; |
2083 | 2198 | ||
@@ -2097,7 +2212,7 @@ int rdma_set_reuseaddr(struct rdma_cm_id *id, int reuse) | |||
2097 | 2212 | ||
2098 | id_priv = container_of(id, struct rdma_id_private, id); | 2213 | id_priv = container_of(id, struct rdma_id_private, id); |
2099 | spin_lock_irqsave(&id_priv->lock, flags); | 2214 | spin_lock_irqsave(&id_priv->lock, flags); |
2100 | if (id_priv->state == RDMA_CM_IDLE) { | 2215 | if (reuse || id_priv->state == RDMA_CM_IDLE) { |
2101 | id_priv->reuseaddr = reuse; | 2216 | id_priv->reuseaddr = reuse; |
2102 | ret = 0; | 2217 | ret = 0; |
2103 | } else { | 2218 | } else { |
@@ -2131,10 +2246,29 @@ EXPORT_SYMBOL(rdma_set_afonly); | |||
2131 | static void cma_bind_port(struct rdma_bind_list *bind_list, | 2246 | static void cma_bind_port(struct rdma_bind_list *bind_list, |
2132 | struct rdma_id_private *id_priv) | 2247 | struct rdma_id_private *id_priv) |
2133 | { | 2248 | { |
2134 | struct sockaddr_in *sin; | 2249 | struct sockaddr *addr; |
2250 | struct sockaddr_ib *sib; | ||
2251 | u64 sid, mask; | ||
2252 | __be16 port; | ||
2135 | 2253 | ||
2136 | sin = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr; | 2254 | addr = cma_src_addr(id_priv); |
2137 | sin->sin_port = htons(bind_list->port); | 2255 | port = htons(bind_list->port); |
2256 | |||
2257 | switch (addr->sa_family) { | ||
2258 | case AF_INET: | ||
2259 | ((struct sockaddr_in *) addr)->sin_port = port; | ||
2260 | break; | ||
2261 | case AF_INET6: | ||
2262 | ((struct sockaddr_in6 *) addr)->sin6_port = port; | ||
2263 | break; | ||
2264 | case AF_IB: | ||
2265 | sib = (struct sockaddr_ib *) addr; | ||
2266 | sid = be64_to_cpu(sib->sib_sid); | ||
2267 | mask = be64_to_cpu(sib->sib_sid_mask); | ||
2268 | sib->sib_sid = cpu_to_be64((sid & mask) | (u64) ntohs(port)); | ||
2269 | sib->sib_sid_mask = cpu_to_be64(~0ULL); | ||
2270 | break; | ||
2271 | } | ||
2138 | id_priv->bind_list = bind_list; | 2272 | id_priv->bind_list = bind_list; |
2139 | hlist_add_head(&id_priv->node, &bind_list->owners); | 2273 | hlist_add_head(&id_priv->node, &bind_list->owners); |
2140 | } | 2274 | } |
@@ -2205,7 +2339,7 @@ static int cma_check_port(struct rdma_bind_list *bind_list, | |||
2205 | struct rdma_id_private *cur_id; | 2339 | struct rdma_id_private *cur_id; |
2206 | struct sockaddr *addr, *cur_addr; | 2340 | struct sockaddr *addr, *cur_addr; |
2207 | 2341 | ||
2208 | addr = (struct sockaddr *) &id_priv->id.route.addr.src_addr; | 2342 | addr = cma_src_addr(id_priv); |
2209 | hlist_for_each_entry(cur_id, &bind_list->owners, node) { | 2343 | hlist_for_each_entry(cur_id, &bind_list->owners, node) { |
2210 | if (id_priv == cur_id) | 2344 | if (id_priv == cur_id) |
2211 | continue; | 2345 | continue; |
@@ -2214,7 +2348,7 @@ static int cma_check_port(struct rdma_bind_list *bind_list, | |||
2214 | cur_id->reuseaddr) | 2348 | cur_id->reuseaddr) |
2215 | continue; | 2349 | continue; |
2216 | 2350 | ||
2217 | cur_addr = (struct sockaddr *) &cur_id->id.route.addr.src_addr; | 2351 | cur_addr = cma_src_addr(cur_id); |
2218 | if (id_priv->afonly && cur_id->afonly && | 2352 | if (id_priv->afonly && cur_id->afonly && |
2219 | (addr->sa_family != cur_addr->sa_family)) | 2353 | (addr->sa_family != cur_addr->sa_family)) |
2220 | continue; | 2354 | continue; |
@@ -2234,7 +2368,7 @@ static int cma_use_port(struct idr *ps, struct rdma_id_private *id_priv) | |||
2234 | unsigned short snum; | 2368 | unsigned short snum; |
2235 | int ret; | 2369 | int ret; |
2236 | 2370 | ||
2237 | snum = ntohs(cma_port((struct sockaddr *) &id_priv->id.route.addr.src_addr)); | 2371 | snum = ntohs(cma_port(cma_src_addr(id_priv))); |
2238 | if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) | 2372 | if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) |
2239 | return -EACCES; | 2373 | return -EACCES; |
2240 | 2374 | ||
@@ -2261,33 +2395,67 @@ static int cma_bind_listen(struct rdma_id_private *id_priv) | |||
2261 | return ret; | 2395 | return ret; |
2262 | } | 2396 | } |
2263 | 2397 | ||
2264 | static int cma_get_port(struct rdma_id_private *id_priv) | 2398 | static struct idr *cma_select_inet_ps(struct rdma_id_private *id_priv) |
2265 | { | 2399 | { |
2266 | struct idr *ps; | ||
2267 | int ret; | ||
2268 | |||
2269 | switch (id_priv->id.ps) { | 2400 | switch (id_priv->id.ps) { |
2270 | case RDMA_PS_SDP: | ||
2271 | ps = &sdp_ps; | ||
2272 | break; | ||
2273 | case RDMA_PS_TCP: | 2401 | case RDMA_PS_TCP: |
2274 | ps = &tcp_ps; | 2402 | return &tcp_ps; |
2275 | break; | ||
2276 | case RDMA_PS_UDP: | 2403 | case RDMA_PS_UDP: |
2277 | ps = &udp_ps; | 2404 | return &udp_ps; |
2278 | break; | ||
2279 | case RDMA_PS_IPOIB: | 2405 | case RDMA_PS_IPOIB: |
2280 | ps = &ipoib_ps; | 2406 | return &ipoib_ps; |
2281 | break; | ||
2282 | case RDMA_PS_IB: | 2407 | case RDMA_PS_IB: |
2283 | ps = &ib_ps; | 2408 | return &ib_ps; |
2284 | break; | ||
2285 | default: | 2409 | default: |
2286 | return -EPROTONOSUPPORT; | 2410 | return NULL; |
2411 | } | ||
2412 | } | ||
2413 | |||
2414 | static struct idr *cma_select_ib_ps(struct rdma_id_private *id_priv) | ||
2415 | { | ||
2416 | struct idr *ps = NULL; | ||
2417 | struct sockaddr_ib *sib; | ||
2418 | u64 sid_ps, mask, sid; | ||
2419 | |||
2420 | sib = (struct sockaddr_ib *) cma_src_addr(id_priv); | ||
2421 | mask = be64_to_cpu(sib->sib_sid_mask) & RDMA_IB_IP_PS_MASK; | ||
2422 | sid = be64_to_cpu(sib->sib_sid) & mask; | ||
2423 | |||
2424 | if ((id_priv->id.ps == RDMA_PS_IB) && (sid == (RDMA_IB_IP_PS_IB & mask))) { | ||
2425 | sid_ps = RDMA_IB_IP_PS_IB; | ||
2426 | ps = &ib_ps; | ||
2427 | } else if (((id_priv->id.ps == RDMA_PS_IB) || (id_priv->id.ps == RDMA_PS_TCP)) && | ||
2428 | (sid == (RDMA_IB_IP_PS_TCP & mask))) { | ||
2429 | sid_ps = RDMA_IB_IP_PS_TCP; | ||
2430 | ps = &tcp_ps; | ||
2431 | } else if (((id_priv->id.ps == RDMA_PS_IB) || (id_priv->id.ps == RDMA_PS_UDP)) && | ||
2432 | (sid == (RDMA_IB_IP_PS_UDP & mask))) { | ||
2433 | sid_ps = RDMA_IB_IP_PS_UDP; | ||
2434 | ps = &udp_ps; | ||
2287 | } | 2435 | } |
2288 | 2436 | ||
2437 | if (ps) { | ||
2438 | sib->sib_sid = cpu_to_be64(sid_ps | ntohs(cma_port((struct sockaddr *) sib))); | ||
2439 | sib->sib_sid_mask = cpu_to_be64(RDMA_IB_IP_PS_MASK | | ||
2440 | be64_to_cpu(sib->sib_sid_mask)); | ||
2441 | } | ||
2442 | return ps; | ||
2443 | } | ||
2444 | |||
2445 | static int cma_get_port(struct rdma_id_private *id_priv) | ||
2446 | { | ||
2447 | struct idr *ps; | ||
2448 | int ret; | ||
2449 | |||
2450 | if (cma_family(id_priv) != AF_IB) | ||
2451 | ps = cma_select_inet_ps(id_priv); | ||
2452 | else | ||
2453 | ps = cma_select_ib_ps(id_priv); | ||
2454 | if (!ps) | ||
2455 | return -EPROTONOSUPPORT; | ||
2456 | |||
2289 | mutex_lock(&lock); | 2457 | mutex_lock(&lock); |
2290 | if (cma_any_port((struct sockaddr *) &id_priv->id.route.addr.src_addr)) | 2458 | if (cma_any_port(cma_src_addr(id_priv))) |
2291 | ret = cma_alloc_any_port(ps, id_priv); | 2459 | ret = cma_alloc_any_port(ps, id_priv); |
2292 | else | 2460 | else |
2293 | ret = cma_use_port(ps, id_priv); | 2461 | ret = cma_use_port(ps, id_priv); |
@@ -2322,8 +2490,8 @@ int rdma_listen(struct rdma_cm_id *id, int backlog) | |||
2322 | 2490 | ||
2323 | id_priv = container_of(id, struct rdma_id_private, id); | 2491 | id_priv = container_of(id, struct rdma_id_private, id); |
2324 | if (id_priv->state == RDMA_CM_IDLE) { | 2492 | if (id_priv->state == RDMA_CM_IDLE) { |
2325 | ((struct sockaddr *) &id->route.addr.src_addr)->sa_family = AF_INET; | 2493 | id->route.addr.src_addr.ss_family = AF_INET; |
2326 | ret = rdma_bind_addr(id, (struct sockaddr *) &id->route.addr.src_addr); | 2494 | ret = rdma_bind_addr(id, cma_src_addr(id_priv)); |
2327 | if (ret) | 2495 | if (ret) |
2328 | return ret; | 2496 | return ret; |
2329 | } | 2497 | } |
@@ -2370,7 +2538,8 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) | |||
2370 | struct rdma_id_private *id_priv; | 2538 | struct rdma_id_private *id_priv; |
2371 | int ret; | 2539 | int ret; |
2372 | 2540 | ||
2373 | if (addr->sa_family != AF_INET && addr->sa_family != AF_INET6) | 2541 | if (addr->sa_family != AF_INET && addr->sa_family != AF_INET6 && |
2542 | addr->sa_family != AF_IB) | ||
2374 | return -EAFNOSUPPORT; | 2543 | return -EAFNOSUPPORT; |
2375 | 2544 | ||
2376 | id_priv = container_of(id, struct rdma_id_private, id); | 2545 | id_priv = container_of(id, struct rdma_id_private, id); |
@@ -2382,7 +2551,7 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) | |||
2382 | goto err1; | 2551 | goto err1; |
2383 | 2552 | ||
2384 | if (!cma_any_addr(addr)) { | 2553 | if (!cma_any_addr(addr)) { |
2385 | ret = rdma_translate_ip(addr, &id->route.addr.dev_addr); | 2554 | ret = cma_translate_addr(addr, &id->route.addr.dev_addr); |
2386 | if (ret) | 2555 | if (ret) |
2387 | goto err1; | 2556 | goto err1; |
2388 | 2557 | ||
@@ -2391,7 +2560,7 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) | |||
2391 | goto err1; | 2560 | goto err1; |
2392 | } | 2561 | } |
2393 | 2562 | ||
2394 | memcpy(&id->route.addr.src_addr, addr, ip_addr_size(addr)); | 2563 | memcpy(cma_src_addr(id_priv), addr, rdma_addr_size(addr)); |
2395 | if (!(id_priv->options & (1 << CMA_OPTION_AFONLY))) { | 2564 | if (!(id_priv->options & (1 << CMA_OPTION_AFONLY))) { |
2396 | if (addr->sa_family == AF_INET) | 2565 | if (addr->sa_family == AF_INET) |
2397 | id_priv->afonly = 1; | 2566 | id_priv->afonly = 1; |
@@ -2414,62 +2583,32 @@ err1: | |||
2414 | } | 2583 | } |
2415 | EXPORT_SYMBOL(rdma_bind_addr); | 2584 | EXPORT_SYMBOL(rdma_bind_addr); |
2416 | 2585 | ||
2417 | static int cma_format_hdr(void *hdr, enum rdma_port_space ps, | 2586 | static int cma_format_hdr(void *hdr, struct rdma_id_private *id_priv) |
2418 | struct rdma_route *route) | ||
2419 | { | 2587 | { |
2420 | struct cma_hdr *cma_hdr; | 2588 | struct cma_hdr *cma_hdr; |
2421 | struct sdp_hh *sdp_hdr; | ||
2422 | 2589 | ||
2423 | if (route->addr.src_addr.ss_family == AF_INET) { | 2590 | cma_hdr = hdr; |
2591 | cma_hdr->cma_version = CMA_VERSION; | ||
2592 | if (cma_family(id_priv) == AF_INET) { | ||
2424 | struct sockaddr_in *src4, *dst4; | 2593 | struct sockaddr_in *src4, *dst4; |
2425 | 2594 | ||
2426 | src4 = (struct sockaddr_in *) &route->addr.src_addr; | 2595 | src4 = (struct sockaddr_in *) cma_src_addr(id_priv); |
2427 | dst4 = (struct sockaddr_in *) &route->addr.dst_addr; | 2596 | dst4 = (struct sockaddr_in *) cma_dst_addr(id_priv); |
2428 | 2597 | ||
2429 | switch (ps) { | 2598 | cma_set_ip_ver(cma_hdr, 4); |
2430 | case RDMA_PS_SDP: | 2599 | cma_hdr->src_addr.ip4.addr = src4->sin_addr.s_addr; |
2431 | sdp_hdr = hdr; | 2600 | cma_hdr->dst_addr.ip4.addr = dst4->sin_addr.s_addr; |
2432 | if (sdp_get_majv(sdp_hdr->sdp_version) != SDP_MAJ_VERSION) | 2601 | cma_hdr->port = src4->sin_port; |
2433 | return -EINVAL; | 2602 | } else if (cma_family(id_priv) == AF_INET6) { |
2434 | sdp_set_ip_ver(sdp_hdr, 4); | ||
2435 | sdp_hdr->src_addr.ip4.addr = src4->sin_addr.s_addr; | ||
2436 | sdp_hdr->dst_addr.ip4.addr = dst4->sin_addr.s_addr; | ||
2437 | sdp_hdr->port = src4->sin_port; | ||
2438 | break; | ||
2439 | default: | ||
2440 | cma_hdr = hdr; | ||
2441 | cma_hdr->cma_version = CMA_VERSION; | ||
2442 | cma_set_ip_ver(cma_hdr, 4); | ||
2443 | cma_hdr->src_addr.ip4.addr = src4->sin_addr.s_addr; | ||
2444 | cma_hdr->dst_addr.ip4.addr = dst4->sin_addr.s_addr; | ||
2445 | cma_hdr->port = src4->sin_port; | ||
2446 | break; | ||
2447 | } | ||
2448 | } else { | ||
2449 | struct sockaddr_in6 *src6, *dst6; | 2603 | struct sockaddr_in6 *src6, *dst6; |
2450 | 2604 | ||
2451 | src6 = (struct sockaddr_in6 *) &route->addr.src_addr; | 2605 | src6 = (struct sockaddr_in6 *) cma_src_addr(id_priv); |
2452 | dst6 = (struct sockaddr_in6 *) &route->addr.dst_addr; | 2606 | dst6 = (struct sockaddr_in6 *) cma_dst_addr(id_priv); |
2453 | 2607 | ||
2454 | switch (ps) { | 2608 | cma_set_ip_ver(cma_hdr, 6); |
2455 | case RDMA_PS_SDP: | 2609 | cma_hdr->src_addr.ip6 = src6->sin6_addr; |
2456 | sdp_hdr = hdr; | 2610 | cma_hdr->dst_addr.ip6 = dst6->sin6_addr; |
2457 | if (sdp_get_majv(sdp_hdr->sdp_version) != SDP_MAJ_VERSION) | 2611 | cma_hdr->port = src6->sin6_port; |
2458 | return -EINVAL; | ||
2459 | sdp_set_ip_ver(sdp_hdr, 6); | ||
2460 | sdp_hdr->src_addr.ip6 = src6->sin6_addr; | ||
2461 | sdp_hdr->dst_addr.ip6 = dst6->sin6_addr; | ||
2462 | sdp_hdr->port = src6->sin6_port; | ||
2463 | break; | ||
2464 | default: | ||
2465 | cma_hdr = hdr; | ||
2466 | cma_hdr->cma_version = CMA_VERSION; | ||
2467 | cma_set_ip_ver(cma_hdr, 6); | ||
2468 | cma_hdr->src_addr.ip6 = src6->sin6_addr; | ||
2469 | cma_hdr->dst_addr.ip6 = dst6->sin6_addr; | ||
2470 | cma_hdr->port = src6->sin6_port; | ||
2471 | break; | ||
2472 | } | ||
2473 | } | 2612 | } |
2474 | return 0; | 2613 | return 0; |
2475 | } | 2614 | } |
@@ -2499,15 +2638,10 @@ static int cma_sidr_rep_handler(struct ib_cm_id *cm_id, | |||
2499 | event.status = ib_event->param.sidr_rep_rcvd.status; | 2638 | event.status = ib_event->param.sidr_rep_rcvd.status; |
2500 | break; | 2639 | break; |
2501 | } | 2640 | } |
2502 | ret = cma_set_qkey(id_priv); | 2641 | ret = cma_set_qkey(id_priv, rep->qkey); |
2503 | if (ret) { | 2642 | if (ret) { |
2504 | event.event = RDMA_CM_EVENT_ADDR_ERROR; | 2643 | event.event = RDMA_CM_EVENT_ADDR_ERROR; |
2505 | event.status = -EINVAL; | 2644 | event.status = ret; |
2506 | break; | ||
2507 | } | ||
2508 | if (id_priv->qkey != rep->qkey) { | ||
2509 | event.event = RDMA_CM_EVENT_UNREACHABLE; | ||
2510 | event.status = -EINVAL; | ||
2511 | break; | 2645 | break; |
2512 | } | 2646 | } |
2513 | ib_init_ah_from_path(id_priv->id.device, id_priv->id.port_num, | 2647 | ib_init_ah_from_path(id_priv->id.device, id_priv->id.port_num, |
@@ -2542,27 +2676,31 @@ static int cma_resolve_ib_udp(struct rdma_id_private *id_priv, | |||
2542 | struct rdma_conn_param *conn_param) | 2676 | struct rdma_conn_param *conn_param) |
2543 | { | 2677 | { |
2544 | struct ib_cm_sidr_req_param req; | 2678 | struct ib_cm_sidr_req_param req; |
2545 | struct rdma_route *route; | ||
2546 | struct ib_cm_id *id; | 2679 | struct ib_cm_id *id; |
2547 | int ret; | 2680 | int offset, ret; |
2548 | 2681 | ||
2549 | req.private_data_len = sizeof(struct cma_hdr) + | 2682 | offset = cma_user_data_offset(id_priv); |
2550 | conn_param->private_data_len; | 2683 | req.private_data_len = offset + conn_param->private_data_len; |
2551 | if (req.private_data_len < conn_param->private_data_len) | 2684 | if (req.private_data_len < conn_param->private_data_len) |
2552 | return -EINVAL; | 2685 | return -EINVAL; |
2553 | 2686 | ||
2554 | req.private_data = kzalloc(req.private_data_len, GFP_ATOMIC); | 2687 | if (req.private_data_len) { |
2555 | if (!req.private_data) | 2688 | req.private_data = kzalloc(req.private_data_len, GFP_ATOMIC); |
2556 | return -ENOMEM; | 2689 | if (!req.private_data) |
2690 | return -ENOMEM; | ||
2691 | } else { | ||
2692 | req.private_data = NULL; | ||
2693 | } | ||
2557 | 2694 | ||
2558 | if (conn_param->private_data && conn_param->private_data_len) | 2695 | if (conn_param->private_data && conn_param->private_data_len) |
2559 | memcpy((void *) req.private_data + sizeof(struct cma_hdr), | 2696 | memcpy((void *) req.private_data + offset, |
2560 | conn_param->private_data, conn_param->private_data_len); | 2697 | conn_param->private_data, conn_param->private_data_len); |
2561 | 2698 | ||
2562 | route = &id_priv->id.route; | 2699 | if (req.private_data) { |
2563 | ret = cma_format_hdr((void *) req.private_data, id_priv->id.ps, route); | 2700 | ret = cma_format_hdr((void *) req.private_data, id_priv); |
2564 | if (ret) | 2701 | if (ret) |
2565 | goto out; | 2702 | goto out; |
2703 | } | ||
2566 | 2704 | ||
2567 | id = ib_create_cm_id(id_priv->id.device, cma_sidr_rep_handler, | 2705 | id = ib_create_cm_id(id_priv->id.device, cma_sidr_rep_handler, |
2568 | id_priv); | 2706 | id_priv); |
@@ -2572,9 +2710,8 @@ static int cma_resolve_ib_udp(struct rdma_id_private *id_priv, | |||
2572 | } | 2710 | } |
2573 | id_priv->cm_id.ib = id; | 2711 | id_priv->cm_id.ib = id; |
2574 | 2712 | ||
2575 | req.path = route->path_rec; | 2713 | req.path = id_priv->id.route.path_rec; |
2576 | req.service_id = cma_get_service_id(id_priv->id.ps, | 2714 | req.service_id = rdma_get_service_id(&id_priv->id, cma_dst_addr(id_priv)); |
2577 | (struct sockaddr *) &route->addr.dst_addr); | ||
2578 | req.timeout_ms = 1 << (CMA_CM_RESPONSE_TIMEOUT - 8); | 2715 | req.timeout_ms = 1 << (CMA_CM_RESPONSE_TIMEOUT - 8); |
2579 | req.max_cm_retries = CMA_MAX_CM_RETRIES; | 2716 | req.max_cm_retries = CMA_MAX_CM_RETRIES; |
2580 | 2717 | ||
@@ -2598,14 +2735,18 @@ static int cma_connect_ib(struct rdma_id_private *id_priv, | |||
2598 | int offset, ret; | 2735 | int offset, ret; |
2599 | 2736 | ||
2600 | memset(&req, 0, sizeof req); | 2737 | memset(&req, 0, sizeof req); |
2601 | offset = cma_user_data_offset(id_priv->id.ps); | 2738 | offset = cma_user_data_offset(id_priv); |
2602 | req.private_data_len = offset + conn_param->private_data_len; | 2739 | req.private_data_len = offset + conn_param->private_data_len; |
2603 | if (req.private_data_len < conn_param->private_data_len) | 2740 | if (req.private_data_len < conn_param->private_data_len) |
2604 | return -EINVAL; | 2741 | return -EINVAL; |
2605 | 2742 | ||
2606 | private_data = kzalloc(req.private_data_len, GFP_ATOMIC); | 2743 | if (req.private_data_len) { |
2607 | if (!private_data) | 2744 | private_data = kzalloc(req.private_data_len, GFP_ATOMIC); |
2608 | return -ENOMEM; | 2745 | if (!private_data) |
2746 | return -ENOMEM; | ||
2747 | } else { | ||
2748 | private_data = NULL; | ||
2749 | } | ||
2609 | 2750 | ||
2610 | if (conn_param->private_data && conn_param->private_data_len) | 2751 | if (conn_param->private_data && conn_param->private_data_len) |
2611 | memcpy(private_data + offset, conn_param->private_data, | 2752 | memcpy(private_data + offset, conn_param->private_data, |
@@ -2619,17 +2760,18 @@ static int cma_connect_ib(struct rdma_id_private *id_priv, | |||
2619 | id_priv->cm_id.ib = id; | 2760 | id_priv->cm_id.ib = id; |
2620 | 2761 | ||
2621 | route = &id_priv->id.route; | 2762 | route = &id_priv->id.route; |
2622 | ret = cma_format_hdr(private_data, id_priv->id.ps, route); | 2763 | if (private_data) { |
2623 | if (ret) | 2764 | ret = cma_format_hdr(private_data, id_priv); |
2624 | goto out; | 2765 | if (ret) |
2625 | req.private_data = private_data; | 2766 | goto out; |
2767 | req.private_data = private_data; | ||
2768 | } | ||
2626 | 2769 | ||
2627 | req.primary_path = &route->path_rec[0]; | 2770 | req.primary_path = &route->path_rec[0]; |
2628 | if (route->num_paths == 2) | 2771 | if (route->num_paths == 2) |
2629 | req.alternate_path = &route->path_rec[1]; | 2772 | req.alternate_path = &route->path_rec[1]; |
2630 | 2773 | ||
2631 | req.service_id = cma_get_service_id(id_priv->id.ps, | 2774 | req.service_id = rdma_get_service_id(&id_priv->id, cma_dst_addr(id_priv)); |
2632 | (struct sockaddr *) &route->addr.dst_addr); | ||
2633 | req.qp_num = id_priv->qp_num; | 2775 | req.qp_num = id_priv->qp_num; |
2634 | req.qp_type = id_priv->id.qp_type; | 2776 | req.qp_type = id_priv->id.qp_type; |
2635 | req.starting_psn = id_priv->seq_num; | 2777 | req.starting_psn = id_priv->seq_num; |
@@ -2668,10 +2810,10 @@ static int cma_connect_iw(struct rdma_id_private *id_priv, | |||
2668 | 2810 | ||
2669 | id_priv->cm_id.iw = cm_id; | 2811 | id_priv->cm_id.iw = cm_id; |
2670 | 2812 | ||
2671 | sin = (struct sockaddr_in*) &id_priv->id.route.addr.src_addr; | 2813 | sin = (struct sockaddr_in *) cma_src_addr(id_priv); |
2672 | cm_id->local_addr = *sin; | 2814 | cm_id->local_addr = *sin; |
2673 | 2815 | ||
2674 | sin = (struct sockaddr_in*) &id_priv->id.route.addr.dst_addr; | 2816 | sin = (struct sockaddr_in *) cma_dst_addr(id_priv); |
2675 | cm_id->remote_addr = *sin; | 2817 | cm_id->remote_addr = *sin; |
2676 | 2818 | ||
2677 | ret = cma_modify_qp_rtr(id_priv, conn_param); | 2819 | ret = cma_modify_qp_rtr(id_priv, conn_param); |
@@ -2789,7 +2931,7 @@ static int cma_accept_iw(struct rdma_id_private *id_priv, | |||
2789 | } | 2931 | } |
2790 | 2932 | ||
2791 | static int cma_send_sidr_rep(struct rdma_id_private *id_priv, | 2933 | static int cma_send_sidr_rep(struct rdma_id_private *id_priv, |
2792 | enum ib_cm_sidr_status status, | 2934 | enum ib_cm_sidr_status status, u32 qkey, |
2793 | const void *private_data, int private_data_len) | 2935 | const void *private_data, int private_data_len) |
2794 | { | 2936 | { |
2795 | struct ib_cm_sidr_rep_param rep; | 2937 | struct ib_cm_sidr_rep_param rep; |
@@ -2798,7 +2940,7 @@ static int cma_send_sidr_rep(struct rdma_id_private *id_priv, | |||
2798 | memset(&rep, 0, sizeof rep); | 2940 | memset(&rep, 0, sizeof rep); |
2799 | rep.status = status; | 2941 | rep.status = status; |
2800 | if (status == IB_SIDR_SUCCESS) { | 2942 | if (status == IB_SIDR_SUCCESS) { |
2801 | ret = cma_set_qkey(id_priv); | 2943 | ret = cma_set_qkey(id_priv, qkey); |
2802 | if (ret) | 2944 | if (ret) |
2803 | return ret; | 2945 | return ret; |
2804 | rep.qp_num = id_priv->qp_num; | 2946 | rep.qp_num = id_priv->qp_num; |
@@ -2832,11 +2974,12 @@ int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param) | |||
2832 | if (id->qp_type == IB_QPT_UD) { | 2974 | if (id->qp_type == IB_QPT_UD) { |
2833 | if (conn_param) | 2975 | if (conn_param) |
2834 | ret = cma_send_sidr_rep(id_priv, IB_SIDR_SUCCESS, | 2976 | ret = cma_send_sidr_rep(id_priv, IB_SIDR_SUCCESS, |
2977 | conn_param->qkey, | ||
2835 | conn_param->private_data, | 2978 | conn_param->private_data, |
2836 | conn_param->private_data_len); | 2979 | conn_param->private_data_len); |
2837 | else | 2980 | else |
2838 | ret = cma_send_sidr_rep(id_priv, IB_SIDR_SUCCESS, | 2981 | ret = cma_send_sidr_rep(id_priv, IB_SIDR_SUCCESS, |
2839 | NULL, 0); | 2982 | 0, NULL, 0); |
2840 | } else { | 2983 | } else { |
2841 | if (conn_param) | 2984 | if (conn_param) |
2842 | ret = cma_accept_ib(id_priv, conn_param); | 2985 | ret = cma_accept_ib(id_priv, conn_param); |
@@ -2897,7 +3040,7 @@ int rdma_reject(struct rdma_cm_id *id, const void *private_data, | |||
2897 | switch (rdma_node_get_transport(id->device->node_type)) { | 3040 | switch (rdma_node_get_transport(id->device->node_type)) { |
2898 | case RDMA_TRANSPORT_IB: | 3041 | case RDMA_TRANSPORT_IB: |
2899 | if (id->qp_type == IB_QPT_UD) | 3042 | if (id->qp_type == IB_QPT_UD) |
2900 | ret = cma_send_sidr_rep(id_priv, IB_SIDR_REJECT, | 3043 | ret = cma_send_sidr_rep(id_priv, IB_SIDR_REJECT, 0, |
2901 | private_data, private_data_len); | 3044 | private_data, private_data_len); |
2902 | else | 3045 | else |
2903 | ret = ib_send_cm_rej(id_priv->cm_id.ib, | 3046 | ret = ib_send_cm_rej(id_priv->cm_id.ib, |
@@ -2958,6 +3101,8 @@ static int cma_ib_mc_handler(int status, struct ib_sa_multicast *multicast) | |||
2958 | cma_disable_callback(id_priv, RDMA_CM_ADDR_RESOLVED)) | 3101 | cma_disable_callback(id_priv, RDMA_CM_ADDR_RESOLVED)) |
2959 | return 0; | 3102 | return 0; |
2960 | 3103 | ||
3104 | if (!status) | ||
3105 | status = cma_set_qkey(id_priv, be32_to_cpu(multicast->rec.qkey)); | ||
2961 | mutex_lock(&id_priv->qp_mutex); | 3106 | mutex_lock(&id_priv->qp_mutex); |
2962 | if (!status && id_priv->id.qp) | 3107 | if (!status && id_priv->id.qp) |
2963 | status = ib_attach_mcast(id_priv->id.qp, &multicast->rec.mgid, | 3108 | status = ib_attach_mcast(id_priv->id.qp, &multicast->rec.mgid, |
@@ -3004,6 +3149,8 @@ static void cma_set_mgid(struct rdma_id_private *id_priv, | |||
3004 | 0xFF10A01B)) { | 3149 | 0xFF10A01B)) { |
3005 | /* IPv6 address is an SA assigned MGID. */ | 3150 | /* IPv6 address is an SA assigned MGID. */ |
3006 | memcpy(mgid, &sin6->sin6_addr, sizeof *mgid); | 3151 | memcpy(mgid, &sin6->sin6_addr, sizeof *mgid); |
3152 | } else if (addr->sa_family == AF_IB) { | ||
3153 | memcpy(mgid, &((struct sockaddr_ib *) addr)->sib_addr, sizeof *mgid); | ||
3007 | } else if ((addr->sa_family == AF_INET6)) { | 3154 | } else if ((addr->sa_family == AF_INET6)) { |
3008 | ipv6_ib_mc_map(&sin6->sin6_addr, dev_addr->broadcast, mc_map); | 3155 | ipv6_ib_mc_map(&sin6->sin6_addr, dev_addr->broadcast, mc_map); |
3009 | if (id_priv->id.ps == RDMA_PS_UDP) | 3156 | if (id_priv->id.ps == RDMA_PS_UDP) |
@@ -3031,9 +3178,12 @@ static int cma_join_ib_multicast(struct rdma_id_private *id_priv, | |||
3031 | if (ret) | 3178 | if (ret) |
3032 | return ret; | 3179 | return ret; |
3033 | 3180 | ||
3181 | ret = cma_set_qkey(id_priv, 0); | ||
3182 | if (ret) | ||
3183 | return ret; | ||
3184 | |||
3034 | cma_set_mgid(id_priv, (struct sockaddr *) &mc->addr, &rec.mgid); | 3185 | cma_set_mgid(id_priv, (struct sockaddr *) &mc->addr, &rec.mgid); |
3035 | if (id_priv->id.ps == RDMA_PS_UDP) | 3186 | rec.qkey = cpu_to_be32(id_priv->qkey); |
3036 | rec.qkey = cpu_to_be32(RDMA_UDP_QKEY); | ||
3037 | rdma_addr_get_sgid(dev_addr, &rec.port_gid); | 3187 | rdma_addr_get_sgid(dev_addr, &rec.port_gid); |
3038 | rec.pkey = cpu_to_be16(ib_addr_get_pkey(dev_addr)); | 3188 | rec.pkey = cpu_to_be16(ib_addr_get_pkey(dev_addr)); |
3039 | rec.join_state = 1; | 3189 | rec.join_state = 1; |
@@ -3170,7 +3320,7 @@ int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr, | |||
3170 | if (!mc) | 3320 | if (!mc) |
3171 | return -ENOMEM; | 3321 | return -ENOMEM; |
3172 | 3322 | ||
3173 | memcpy(&mc->addr, addr, ip_addr_size(addr)); | 3323 | memcpy(&mc->addr, addr, rdma_addr_size(addr)); |
3174 | mc->context = context; | 3324 | mc->context = context; |
3175 | mc->id_priv = id_priv; | 3325 | mc->id_priv = id_priv; |
3176 | 3326 | ||
@@ -3215,7 +3365,7 @@ void rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr) | |||
3215 | id_priv = container_of(id, struct rdma_id_private, id); | 3365 | id_priv = container_of(id, struct rdma_id_private, id); |
3216 | spin_lock_irq(&id_priv->lock); | 3366 | spin_lock_irq(&id_priv->lock); |
3217 | list_for_each_entry(mc, &id_priv->mc_list, list) { | 3367 | list_for_each_entry(mc, &id_priv->mc_list, list) { |
3218 | if (!memcmp(&mc->addr, addr, ip_addr_size(addr))) { | 3368 | if (!memcmp(&mc->addr, addr, rdma_addr_size(addr))) { |
3219 | list_del(&mc->list); | 3369 | list_del(&mc->list); |
3220 | spin_unlock_irq(&id_priv->lock); | 3370 | spin_unlock_irq(&id_priv->lock); |
3221 | 3371 | ||
@@ -3436,33 +3586,16 @@ static int cma_get_id_stats(struct sk_buff *skb, struct netlink_callback *cb) | |||
3436 | id_stats->bound_dev_if = | 3586 | id_stats->bound_dev_if = |
3437 | id->route.addr.dev_addr.bound_dev_if; | 3587 | id->route.addr.dev_addr.bound_dev_if; |
3438 | 3588 | ||
3439 | if (id->route.addr.src_addr.ss_family == AF_INET) { | 3589 | if (ibnl_put_attr(skb, nlh, |
3440 | if (ibnl_put_attr(skb, nlh, | 3590 | rdma_addr_size(cma_src_addr(id_priv)), |
3441 | sizeof(struct sockaddr_in), | 3591 | cma_src_addr(id_priv), |
3442 | &id->route.addr.src_addr, | 3592 | RDMA_NL_RDMA_CM_ATTR_SRC_ADDR)) |
3443 | RDMA_NL_RDMA_CM_ATTR_SRC_ADDR)) { | 3593 | goto out; |
3444 | goto out; | 3594 | if (ibnl_put_attr(skb, nlh, |
3445 | } | 3595 | rdma_addr_size(cma_src_addr(id_priv)), |
3446 | if (ibnl_put_attr(skb, nlh, | 3596 | cma_dst_addr(id_priv), |
3447 | sizeof(struct sockaddr_in), | 3597 | RDMA_NL_RDMA_CM_ATTR_DST_ADDR)) |
3448 | &id->route.addr.dst_addr, | 3598 | goto out; |
3449 | RDMA_NL_RDMA_CM_ATTR_DST_ADDR)) { | ||
3450 | goto out; | ||
3451 | } | ||
3452 | } else if (id->route.addr.src_addr.ss_family == AF_INET6) { | ||
3453 | if (ibnl_put_attr(skb, nlh, | ||
3454 | sizeof(struct sockaddr_in6), | ||
3455 | &id->route.addr.src_addr, | ||
3456 | RDMA_NL_RDMA_CM_ATTR_SRC_ADDR)) { | ||
3457 | goto out; | ||
3458 | } | ||
3459 | if (ibnl_put_attr(skb, nlh, | ||
3460 | sizeof(struct sockaddr_in6), | ||
3461 | &id->route.addr.dst_addr, | ||
3462 | RDMA_NL_RDMA_CM_ATTR_DST_ADDR)) { | ||
3463 | goto out; | ||
3464 | } | ||
3465 | } | ||
3466 | 3599 | ||
3467 | id_stats->pid = id_priv->owner; | 3600 | id_stats->pid = id_priv->owner; |
3468 | id_stats->port_space = id->ps; | 3601 | id_stats->port_space = id->ps; |
@@ -3527,7 +3660,6 @@ static void __exit cma_cleanup(void) | |||
3527 | rdma_addr_unregister_client(&addr_client); | 3660 | rdma_addr_unregister_client(&addr_client); |
3528 | ib_sa_unregister_client(&sa_client); | 3661 | ib_sa_unregister_client(&sa_client); |
3529 | destroy_workqueue(cma_wq); | 3662 | destroy_workqueue(cma_wq); |
3530 | idr_destroy(&sdp_ps); | ||
3531 | idr_destroy(&tcp_ps); | 3663 | idr_destroy(&tcp_ps); |
3532 | idr_destroy(&udp_ps); | 3664 | idr_destroy(&udp_ps); |
3533 | idr_destroy(&ipoib_ps); | 3665 | idr_destroy(&ipoib_ps); |
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 934f45e79e5e..9838ca484389 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c | |||
@@ -652,6 +652,12 @@ void ib_sa_unpack_path(void *attribute, struct ib_sa_path_rec *rec) | |||
652 | } | 652 | } |
653 | EXPORT_SYMBOL(ib_sa_unpack_path); | 653 | EXPORT_SYMBOL(ib_sa_unpack_path); |
654 | 654 | ||
655 | void ib_sa_pack_path(struct ib_sa_path_rec *rec, void *attribute) | ||
656 | { | ||
657 | ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table), rec, attribute); | ||
658 | } | ||
659 | EXPORT_SYMBOL(ib_sa_pack_path); | ||
660 | |||
655 | static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query, | 661 | static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query, |
656 | int status, | 662 | int status, |
657 | struct ib_sa_mad *mad) | 663 | struct ib_sa_mad *mad) |
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 246fdc151652..d9b78c4d0aad 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c | |||
@@ -545,8 +545,10 @@ static int add_port(struct ib_device *device, int port_num, | |||
545 | 545 | ||
546 | p->gid_group.name = "gids"; | 546 | p->gid_group.name = "gids"; |
547 | p->gid_group.attrs = alloc_group_attrs(show_port_gid, attr.gid_tbl_len); | 547 | p->gid_group.attrs = alloc_group_attrs(show_port_gid, attr.gid_tbl_len); |
548 | if (!p->gid_group.attrs) | 548 | if (!p->gid_group.attrs) { |
549 | ret = -ENOMEM; | ||
549 | goto err_remove_pma; | 550 | goto err_remove_pma; |
551 | } | ||
550 | 552 | ||
551 | ret = sysfs_create_group(&p->kobj, &p->gid_group); | 553 | ret = sysfs_create_group(&p->kobj, &p->gid_group); |
552 | if (ret) | 554 | if (ret) |
@@ -555,8 +557,10 @@ static int add_port(struct ib_device *device, int port_num, | |||
555 | p->pkey_group.name = "pkeys"; | 557 | p->pkey_group.name = "pkeys"; |
556 | p->pkey_group.attrs = alloc_group_attrs(show_port_pkey, | 558 | p->pkey_group.attrs = alloc_group_attrs(show_port_pkey, |
557 | attr.pkey_tbl_len); | 559 | attr.pkey_tbl_len); |
558 | if (!p->pkey_group.attrs) | 560 | if (!p->pkey_group.attrs) { |
561 | ret = -ENOMEM; | ||
559 | goto err_remove_gid; | 562 | goto err_remove_gid; |
563 | } | ||
560 | 564 | ||
561 | ret = sysfs_create_group(&p->kobj, &p->pkey_group); | 565 | ret = sysfs_create_group(&p->kobj, &p->pkey_group); |
562 | if (ret) | 566 | if (ret) |
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index 5ca44cd9b00c..b0f189be543b 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c | |||
@@ -47,6 +47,8 @@ | |||
47 | #include <rdma/ib_marshall.h> | 47 | #include <rdma/ib_marshall.h> |
48 | #include <rdma/rdma_cm.h> | 48 | #include <rdma/rdma_cm.h> |
49 | #include <rdma/rdma_cm_ib.h> | 49 | #include <rdma/rdma_cm_ib.h> |
50 | #include <rdma/ib_addr.h> | ||
51 | #include <rdma/ib.h> | ||
50 | 52 | ||
51 | MODULE_AUTHOR("Sean Hefty"); | 53 | MODULE_AUTHOR("Sean Hefty"); |
52 | MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access"); | 54 | MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access"); |
@@ -510,10 +512,10 @@ static ssize_t ucma_destroy_id(struct ucma_file *file, const char __user *inbuf, | |||
510 | return ret; | 512 | return ret; |
511 | } | 513 | } |
512 | 514 | ||
513 | static ssize_t ucma_bind_addr(struct ucma_file *file, const char __user *inbuf, | 515 | static ssize_t ucma_bind_ip(struct ucma_file *file, const char __user *inbuf, |
514 | int in_len, int out_len) | 516 | int in_len, int out_len) |
515 | { | 517 | { |
516 | struct rdma_ucm_bind_addr cmd; | 518 | struct rdma_ucm_bind_ip cmd; |
517 | struct ucma_context *ctx; | 519 | struct ucma_context *ctx; |
518 | int ret; | 520 | int ret; |
519 | 521 | ||
@@ -529,24 +531,75 @@ static ssize_t ucma_bind_addr(struct ucma_file *file, const char __user *inbuf, | |||
529 | return ret; | 531 | return ret; |
530 | } | 532 | } |
531 | 533 | ||
534 | static ssize_t ucma_bind(struct ucma_file *file, const char __user *inbuf, | ||
535 | int in_len, int out_len) | ||
536 | { | ||
537 | struct rdma_ucm_bind cmd; | ||
538 | struct sockaddr *addr; | ||
539 | struct ucma_context *ctx; | ||
540 | int ret; | ||
541 | |||
542 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | ||
543 | return -EFAULT; | ||
544 | |||
545 | addr = (struct sockaddr *) &cmd.addr; | ||
546 | if (cmd.reserved || !cmd.addr_size || (cmd.addr_size != rdma_addr_size(addr))) | ||
547 | return -EINVAL; | ||
548 | |||
549 | ctx = ucma_get_ctx(file, cmd.id); | ||
550 | if (IS_ERR(ctx)) | ||
551 | return PTR_ERR(ctx); | ||
552 | |||
553 | ret = rdma_bind_addr(ctx->cm_id, addr); | ||
554 | ucma_put_ctx(ctx); | ||
555 | return ret; | ||
556 | } | ||
557 | |||
558 | static ssize_t ucma_resolve_ip(struct ucma_file *file, | ||
559 | const char __user *inbuf, | ||
560 | int in_len, int out_len) | ||
561 | { | ||
562 | struct rdma_ucm_resolve_ip cmd; | ||
563 | struct ucma_context *ctx; | ||
564 | int ret; | ||
565 | |||
566 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | ||
567 | return -EFAULT; | ||
568 | |||
569 | ctx = ucma_get_ctx(file, cmd.id); | ||
570 | if (IS_ERR(ctx)) | ||
571 | return PTR_ERR(ctx); | ||
572 | |||
573 | ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr, | ||
574 | (struct sockaddr *) &cmd.dst_addr, | ||
575 | cmd.timeout_ms); | ||
576 | ucma_put_ctx(ctx); | ||
577 | return ret; | ||
578 | } | ||
579 | |||
532 | static ssize_t ucma_resolve_addr(struct ucma_file *file, | 580 | static ssize_t ucma_resolve_addr(struct ucma_file *file, |
533 | const char __user *inbuf, | 581 | const char __user *inbuf, |
534 | int in_len, int out_len) | 582 | int in_len, int out_len) |
535 | { | 583 | { |
536 | struct rdma_ucm_resolve_addr cmd; | 584 | struct rdma_ucm_resolve_addr cmd; |
585 | struct sockaddr *src, *dst; | ||
537 | struct ucma_context *ctx; | 586 | struct ucma_context *ctx; |
538 | int ret; | 587 | int ret; |
539 | 588 | ||
540 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | 589 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) |
541 | return -EFAULT; | 590 | return -EFAULT; |
542 | 591 | ||
592 | src = (struct sockaddr *) &cmd.src_addr; | ||
593 | dst = (struct sockaddr *) &cmd.dst_addr; | ||
594 | if (cmd.reserved || (cmd.src_size && (cmd.src_size != rdma_addr_size(src))) || | ||
595 | !cmd.dst_size || (cmd.dst_size != rdma_addr_size(dst))) | ||
596 | return -EINVAL; | ||
597 | |||
543 | ctx = ucma_get_ctx(file, cmd.id); | 598 | ctx = ucma_get_ctx(file, cmd.id); |
544 | if (IS_ERR(ctx)) | 599 | if (IS_ERR(ctx)) |
545 | return PTR_ERR(ctx); | 600 | return PTR_ERR(ctx); |
546 | 601 | ||
547 | ret = rdma_resolve_addr(ctx->cm_id, (struct sockaddr *) &cmd.src_addr, | 602 | ret = rdma_resolve_addr(ctx->cm_id, src, dst, cmd.timeout_ms); |
548 | (struct sockaddr *) &cmd.dst_addr, | ||
549 | cmd.timeout_ms); | ||
550 | ucma_put_ctx(ctx); | 603 | ucma_put_ctx(ctx); |
551 | return ret; | 604 | return ret; |
552 | } | 605 | } |
@@ -649,7 +702,7 @@ static ssize_t ucma_query_route(struct ucma_file *file, | |||
649 | const char __user *inbuf, | 702 | const char __user *inbuf, |
650 | int in_len, int out_len) | 703 | int in_len, int out_len) |
651 | { | 704 | { |
652 | struct rdma_ucm_query_route cmd; | 705 | struct rdma_ucm_query cmd; |
653 | struct rdma_ucm_query_route_resp resp; | 706 | struct rdma_ucm_query_route_resp resp; |
654 | struct ucma_context *ctx; | 707 | struct ucma_context *ctx; |
655 | struct sockaddr *addr; | 708 | struct sockaddr *addr; |
@@ -709,7 +762,162 @@ out: | |||
709 | return ret; | 762 | return ret; |
710 | } | 763 | } |
711 | 764 | ||
712 | static void ucma_copy_conn_param(struct rdma_conn_param *dst, | 765 | static void ucma_query_device_addr(struct rdma_cm_id *cm_id, |
766 | struct rdma_ucm_query_addr_resp *resp) | ||
767 | { | ||
768 | if (!cm_id->device) | ||
769 | return; | ||
770 | |||
771 | resp->node_guid = (__force __u64) cm_id->device->node_guid; | ||
772 | resp->port_num = cm_id->port_num; | ||
773 | resp->pkey = (__force __u16) cpu_to_be16( | ||
774 | ib_addr_get_pkey(&cm_id->route.addr.dev_addr)); | ||
775 | } | ||
776 | |||
777 | static ssize_t ucma_query_addr(struct ucma_context *ctx, | ||
778 | void __user *response, int out_len) | ||
779 | { | ||
780 | struct rdma_ucm_query_addr_resp resp; | ||
781 | struct sockaddr *addr; | ||
782 | int ret = 0; | ||
783 | |||
784 | if (out_len < sizeof(resp)) | ||
785 | return -ENOSPC; | ||
786 | |||
787 | memset(&resp, 0, sizeof resp); | ||
788 | |||
789 | addr = (struct sockaddr *) &ctx->cm_id->route.addr.src_addr; | ||
790 | resp.src_size = rdma_addr_size(addr); | ||
791 | memcpy(&resp.src_addr, addr, resp.src_size); | ||
792 | |||
793 | addr = (struct sockaddr *) &ctx->cm_id->route.addr.dst_addr; | ||
794 | resp.dst_size = rdma_addr_size(addr); | ||
795 | memcpy(&resp.dst_addr, addr, resp.dst_size); | ||
796 | |||
797 | ucma_query_device_addr(ctx->cm_id, &resp); | ||
798 | |||
799 | if (copy_to_user(response, &resp, sizeof(resp))) | ||
800 | ret = -EFAULT; | ||
801 | |||
802 | return ret; | ||
803 | } | ||
804 | |||
805 | static ssize_t ucma_query_path(struct ucma_context *ctx, | ||
806 | void __user *response, int out_len) | ||
807 | { | ||
808 | struct rdma_ucm_query_path_resp *resp; | ||
809 | int i, ret = 0; | ||
810 | |||
811 | if (out_len < sizeof(*resp)) | ||
812 | return -ENOSPC; | ||
813 | |||
814 | resp = kzalloc(out_len, GFP_KERNEL); | ||
815 | if (!resp) | ||
816 | return -ENOMEM; | ||
817 | |||
818 | resp->num_paths = ctx->cm_id->route.num_paths; | ||
819 | for (i = 0, out_len -= sizeof(*resp); | ||
820 | i < resp->num_paths && out_len > sizeof(struct ib_path_rec_data); | ||
821 | i++, out_len -= sizeof(struct ib_path_rec_data)) { | ||
822 | |||
823 | resp->path_data[i].flags = IB_PATH_GMP | IB_PATH_PRIMARY | | ||
824 | IB_PATH_BIDIRECTIONAL; | ||
825 | ib_sa_pack_path(&ctx->cm_id->route.path_rec[i], | ||
826 | &resp->path_data[i].path_rec); | ||
827 | } | ||
828 | |||
829 | if (copy_to_user(response, resp, | ||
830 | sizeof(*resp) + (i * sizeof(struct ib_path_rec_data)))) | ||
831 | ret = -EFAULT; | ||
832 | |||
833 | kfree(resp); | ||
834 | return ret; | ||
835 | } | ||
836 | |||
837 | static ssize_t ucma_query_gid(struct ucma_context *ctx, | ||
838 | void __user *response, int out_len) | ||
839 | { | ||
840 | struct rdma_ucm_query_addr_resp resp; | ||
841 | struct sockaddr_ib *addr; | ||
842 | int ret = 0; | ||
843 | |||
844 | if (out_len < sizeof(resp)) | ||
845 | return -ENOSPC; | ||
846 | |||
847 | memset(&resp, 0, sizeof resp); | ||
848 | |||
849 | ucma_query_device_addr(ctx->cm_id, &resp); | ||
850 | |||
851 | addr = (struct sockaddr_ib *) &resp.src_addr; | ||
852 | resp.src_size = sizeof(*addr); | ||
853 | if (ctx->cm_id->route.addr.src_addr.ss_family == AF_IB) { | ||
854 | memcpy(addr, &ctx->cm_id->route.addr.src_addr, resp.src_size); | ||
855 | } else { | ||
856 | addr->sib_family = AF_IB; | ||
857 | addr->sib_pkey = (__force __be16) resp.pkey; | ||
858 | rdma_addr_get_sgid(&ctx->cm_id->route.addr.dev_addr, | ||
859 | (union ib_gid *) &addr->sib_addr); | ||
860 | addr->sib_sid = rdma_get_service_id(ctx->cm_id, (struct sockaddr *) | ||
861 | &ctx->cm_id->route.addr.src_addr); | ||
862 | } | ||
863 | |||
864 | addr = (struct sockaddr_ib *) &resp.dst_addr; | ||
865 | resp.dst_size = sizeof(*addr); | ||
866 | if (ctx->cm_id->route.addr.dst_addr.ss_family == AF_IB) { | ||
867 | memcpy(addr, &ctx->cm_id->route.addr.dst_addr, resp.dst_size); | ||
868 | } else { | ||
869 | addr->sib_family = AF_IB; | ||
870 | addr->sib_pkey = (__force __be16) resp.pkey; | ||
871 | rdma_addr_get_dgid(&ctx->cm_id->route.addr.dev_addr, | ||
872 | (union ib_gid *) &addr->sib_addr); | ||
873 | addr->sib_sid = rdma_get_service_id(ctx->cm_id, (struct sockaddr *) | ||
874 | &ctx->cm_id->route.addr.dst_addr); | ||
875 | } | ||
876 | |||
877 | if (copy_to_user(response, &resp, sizeof(resp))) | ||
878 | ret = -EFAULT; | ||
879 | |||
880 | return ret; | ||
881 | } | ||
882 | |||
883 | static ssize_t ucma_query(struct ucma_file *file, | ||
884 | const char __user *inbuf, | ||
885 | int in_len, int out_len) | ||
886 | { | ||
887 | struct rdma_ucm_query cmd; | ||
888 | struct ucma_context *ctx; | ||
889 | void __user *response; | ||
890 | int ret; | ||
891 | |||
892 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | ||
893 | return -EFAULT; | ||
894 | |||
895 | response = (void __user *)(unsigned long) cmd.response; | ||
896 | ctx = ucma_get_ctx(file, cmd.id); | ||
897 | if (IS_ERR(ctx)) | ||
898 | return PTR_ERR(ctx); | ||
899 | |||
900 | switch (cmd.option) { | ||
901 | case RDMA_USER_CM_QUERY_ADDR: | ||
902 | ret = ucma_query_addr(ctx, response, out_len); | ||
903 | break; | ||
904 | case RDMA_USER_CM_QUERY_PATH: | ||
905 | ret = ucma_query_path(ctx, response, out_len); | ||
906 | break; | ||
907 | case RDMA_USER_CM_QUERY_GID: | ||
908 | ret = ucma_query_gid(ctx, response, out_len); | ||
909 | break; | ||
910 | default: | ||
911 | ret = -ENOSYS; | ||
912 | break; | ||
913 | } | ||
914 | |||
915 | ucma_put_ctx(ctx); | ||
916 | return ret; | ||
917 | } | ||
918 | |||
919 | static void ucma_copy_conn_param(struct rdma_cm_id *id, | ||
920 | struct rdma_conn_param *dst, | ||
713 | struct rdma_ucm_conn_param *src) | 921 | struct rdma_ucm_conn_param *src) |
714 | { | 922 | { |
715 | dst->private_data = src->private_data; | 923 | dst->private_data = src->private_data; |
@@ -721,6 +929,7 @@ static void ucma_copy_conn_param(struct rdma_conn_param *dst, | |||
721 | dst->rnr_retry_count = src->rnr_retry_count; | 929 | dst->rnr_retry_count = src->rnr_retry_count; |
722 | dst->srq = src->srq; | 930 | dst->srq = src->srq; |
723 | dst->qp_num = src->qp_num; | 931 | dst->qp_num = src->qp_num; |
932 | dst->qkey = (id->route.addr.src_addr.ss_family == AF_IB) ? src->qkey : 0; | ||
724 | } | 933 | } |
725 | 934 | ||
726 | static ssize_t ucma_connect(struct ucma_file *file, const char __user *inbuf, | 935 | static ssize_t ucma_connect(struct ucma_file *file, const char __user *inbuf, |
@@ -741,7 +950,7 @@ static ssize_t ucma_connect(struct ucma_file *file, const char __user *inbuf, | |||
741 | if (IS_ERR(ctx)) | 950 | if (IS_ERR(ctx)) |
742 | return PTR_ERR(ctx); | 951 | return PTR_ERR(ctx); |
743 | 952 | ||
744 | ucma_copy_conn_param(&conn_param, &cmd.conn_param); | 953 | ucma_copy_conn_param(ctx->cm_id, &conn_param, &cmd.conn_param); |
745 | ret = rdma_connect(ctx->cm_id, &conn_param); | 954 | ret = rdma_connect(ctx->cm_id, &conn_param); |
746 | ucma_put_ctx(ctx); | 955 | ucma_put_ctx(ctx); |
747 | return ret; | 956 | return ret; |
@@ -784,7 +993,7 @@ static ssize_t ucma_accept(struct ucma_file *file, const char __user *inbuf, | |||
784 | return PTR_ERR(ctx); | 993 | return PTR_ERR(ctx); |
785 | 994 | ||
786 | if (cmd.conn_param.valid) { | 995 | if (cmd.conn_param.valid) { |
787 | ucma_copy_conn_param(&conn_param, &cmd.conn_param); | 996 | ucma_copy_conn_param(ctx->cm_id, &conn_param, &cmd.conn_param); |
788 | mutex_lock(&file->mut); | 997 | mutex_lock(&file->mut); |
789 | ret = rdma_accept(ctx->cm_id, &conn_param); | 998 | ret = rdma_accept(ctx->cm_id, &conn_param); |
790 | if (!ret) | 999 | if (!ret) |
@@ -1020,23 +1229,23 @@ static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf, | |||
1020 | return ret; | 1229 | return ret; |
1021 | } | 1230 | } |
1022 | 1231 | ||
1023 | static ssize_t ucma_join_multicast(struct ucma_file *file, | 1232 | static ssize_t ucma_process_join(struct ucma_file *file, |
1024 | const char __user *inbuf, | 1233 | struct rdma_ucm_join_mcast *cmd, int out_len) |
1025 | int in_len, int out_len) | ||
1026 | { | 1234 | { |
1027 | struct rdma_ucm_join_mcast cmd; | ||
1028 | struct rdma_ucm_create_id_resp resp; | 1235 | struct rdma_ucm_create_id_resp resp; |
1029 | struct ucma_context *ctx; | 1236 | struct ucma_context *ctx; |
1030 | struct ucma_multicast *mc; | 1237 | struct ucma_multicast *mc; |
1238 | struct sockaddr *addr; | ||
1031 | int ret; | 1239 | int ret; |
1032 | 1240 | ||
1033 | if (out_len < sizeof(resp)) | 1241 | if (out_len < sizeof(resp)) |
1034 | return -ENOSPC; | 1242 | return -ENOSPC; |
1035 | 1243 | ||
1036 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | 1244 | addr = (struct sockaddr *) &cmd->addr; |
1037 | return -EFAULT; | 1245 | if (cmd->reserved || !cmd->addr_size || (cmd->addr_size != rdma_addr_size(addr))) |
1246 | return -EINVAL; | ||
1038 | 1247 | ||
1039 | ctx = ucma_get_ctx(file, cmd.id); | 1248 | ctx = ucma_get_ctx(file, cmd->id); |
1040 | if (IS_ERR(ctx)) | 1249 | if (IS_ERR(ctx)) |
1041 | return PTR_ERR(ctx); | 1250 | return PTR_ERR(ctx); |
1042 | 1251 | ||
@@ -1047,14 +1256,14 @@ static ssize_t ucma_join_multicast(struct ucma_file *file, | |||
1047 | goto err1; | 1256 | goto err1; |
1048 | } | 1257 | } |
1049 | 1258 | ||
1050 | mc->uid = cmd.uid; | 1259 | mc->uid = cmd->uid; |
1051 | memcpy(&mc->addr, &cmd.addr, sizeof cmd.addr); | 1260 | memcpy(&mc->addr, addr, cmd->addr_size); |
1052 | ret = rdma_join_multicast(ctx->cm_id, (struct sockaddr *) &mc->addr, mc); | 1261 | ret = rdma_join_multicast(ctx->cm_id, (struct sockaddr *) &mc->addr, mc); |
1053 | if (ret) | 1262 | if (ret) |
1054 | goto err2; | 1263 | goto err2; |
1055 | 1264 | ||
1056 | resp.id = mc->id; | 1265 | resp.id = mc->id; |
1057 | if (copy_to_user((void __user *)(unsigned long)cmd.response, | 1266 | if (copy_to_user((void __user *)(unsigned long) cmd->response, |
1058 | &resp, sizeof(resp))) { | 1267 | &resp, sizeof(resp))) { |
1059 | ret = -EFAULT; | 1268 | ret = -EFAULT; |
1060 | goto err3; | 1269 | goto err3; |
@@ -1079,6 +1288,38 @@ err1: | |||
1079 | return ret; | 1288 | return ret; |
1080 | } | 1289 | } |
1081 | 1290 | ||
1291 | static ssize_t ucma_join_ip_multicast(struct ucma_file *file, | ||
1292 | const char __user *inbuf, | ||
1293 | int in_len, int out_len) | ||
1294 | { | ||
1295 | struct rdma_ucm_join_ip_mcast cmd; | ||
1296 | struct rdma_ucm_join_mcast join_cmd; | ||
1297 | |||
1298 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | ||
1299 | return -EFAULT; | ||
1300 | |||
1301 | join_cmd.response = cmd.response; | ||
1302 | join_cmd.uid = cmd.uid; | ||
1303 | join_cmd.id = cmd.id; | ||
1304 | join_cmd.addr_size = rdma_addr_size((struct sockaddr *) &cmd.addr); | ||
1305 | join_cmd.reserved = 0; | ||
1306 | memcpy(&join_cmd.addr, &cmd.addr, join_cmd.addr_size); | ||
1307 | |||
1308 | return ucma_process_join(file, &join_cmd, out_len); | ||
1309 | } | ||
1310 | |||
1311 | static ssize_t ucma_join_multicast(struct ucma_file *file, | ||
1312 | const char __user *inbuf, | ||
1313 | int in_len, int out_len) | ||
1314 | { | ||
1315 | struct rdma_ucm_join_mcast cmd; | ||
1316 | |||
1317 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | ||
1318 | return -EFAULT; | ||
1319 | |||
1320 | return ucma_process_join(file, &cmd, out_len); | ||
1321 | } | ||
1322 | |||
1082 | static ssize_t ucma_leave_multicast(struct ucma_file *file, | 1323 | static ssize_t ucma_leave_multicast(struct ucma_file *file, |
1083 | const char __user *inbuf, | 1324 | const char __user *inbuf, |
1084 | int in_len, int out_len) | 1325 | int in_len, int out_len) |
@@ -1221,25 +1462,29 @@ file_put: | |||
1221 | static ssize_t (*ucma_cmd_table[])(struct ucma_file *file, | 1462 | static ssize_t (*ucma_cmd_table[])(struct ucma_file *file, |
1222 | const char __user *inbuf, | 1463 | const char __user *inbuf, |
1223 | int in_len, int out_len) = { | 1464 | int in_len, int out_len) = { |
1224 | [RDMA_USER_CM_CMD_CREATE_ID] = ucma_create_id, | 1465 | [RDMA_USER_CM_CMD_CREATE_ID] = ucma_create_id, |
1225 | [RDMA_USER_CM_CMD_DESTROY_ID] = ucma_destroy_id, | 1466 | [RDMA_USER_CM_CMD_DESTROY_ID] = ucma_destroy_id, |
1226 | [RDMA_USER_CM_CMD_BIND_ADDR] = ucma_bind_addr, | 1467 | [RDMA_USER_CM_CMD_BIND_IP] = ucma_bind_ip, |
1227 | [RDMA_USER_CM_CMD_RESOLVE_ADDR] = ucma_resolve_addr, | 1468 | [RDMA_USER_CM_CMD_RESOLVE_IP] = ucma_resolve_ip, |
1228 | [RDMA_USER_CM_CMD_RESOLVE_ROUTE]= ucma_resolve_route, | 1469 | [RDMA_USER_CM_CMD_RESOLVE_ROUTE] = ucma_resolve_route, |
1229 | [RDMA_USER_CM_CMD_QUERY_ROUTE] = ucma_query_route, | 1470 | [RDMA_USER_CM_CMD_QUERY_ROUTE] = ucma_query_route, |
1230 | [RDMA_USER_CM_CMD_CONNECT] = ucma_connect, | 1471 | [RDMA_USER_CM_CMD_CONNECT] = ucma_connect, |
1231 | [RDMA_USER_CM_CMD_LISTEN] = ucma_listen, | 1472 | [RDMA_USER_CM_CMD_LISTEN] = ucma_listen, |
1232 | [RDMA_USER_CM_CMD_ACCEPT] = ucma_accept, | 1473 | [RDMA_USER_CM_CMD_ACCEPT] = ucma_accept, |
1233 | [RDMA_USER_CM_CMD_REJECT] = ucma_reject, | 1474 | [RDMA_USER_CM_CMD_REJECT] = ucma_reject, |
1234 | [RDMA_USER_CM_CMD_DISCONNECT] = ucma_disconnect, | 1475 | [RDMA_USER_CM_CMD_DISCONNECT] = ucma_disconnect, |
1235 | [RDMA_USER_CM_CMD_INIT_QP_ATTR] = ucma_init_qp_attr, | 1476 | [RDMA_USER_CM_CMD_INIT_QP_ATTR] = ucma_init_qp_attr, |
1236 | [RDMA_USER_CM_CMD_GET_EVENT] = ucma_get_event, | 1477 | [RDMA_USER_CM_CMD_GET_EVENT] = ucma_get_event, |
1237 | [RDMA_USER_CM_CMD_GET_OPTION] = NULL, | 1478 | [RDMA_USER_CM_CMD_GET_OPTION] = NULL, |
1238 | [RDMA_USER_CM_CMD_SET_OPTION] = ucma_set_option, | 1479 | [RDMA_USER_CM_CMD_SET_OPTION] = ucma_set_option, |
1239 | [RDMA_USER_CM_CMD_NOTIFY] = ucma_notify, | 1480 | [RDMA_USER_CM_CMD_NOTIFY] = ucma_notify, |
1240 | [RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast, | 1481 | [RDMA_USER_CM_CMD_JOIN_IP_MCAST] = ucma_join_ip_multicast, |
1241 | [RDMA_USER_CM_CMD_LEAVE_MCAST] = ucma_leave_multicast, | 1482 | [RDMA_USER_CM_CMD_LEAVE_MCAST] = ucma_leave_multicast, |
1242 | [RDMA_USER_CM_CMD_MIGRATE_ID] = ucma_migrate_id | 1483 | [RDMA_USER_CM_CMD_MIGRATE_ID] = ucma_migrate_id, |
1484 | [RDMA_USER_CM_CMD_QUERY] = ucma_query, | ||
1485 | [RDMA_USER_CM_CMD_BIND] = ucma_bind, | ||
1486 | [RDMA_USER_CM_CMD_RESOLVE_ADDR] = ucma_resolve_addr, | ||
1487 | [RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast | ||
1243 | }; | 1488 | }; |
1244 | 1489 | ||
1245 | static ssize_t ucma_write(struct file *filp, const char __user *buf, | 1490 | static ssize_t ucma_write(struct file *filp, const char __user *buf, |
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index a7d00f6b3bc1..b3c07b0c9f26 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -334,7 +334,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, | |||
334 | 334 | ||
335 | resp.num_comp_vectors = file->device->num_comp_vectors; | 335 | resp.num_comp_vectors = file->device->num_comp_vectors; |
336 | 336 | ||
337 | ret = get_unused_fd(); | 337 | ret = get_unused_fd_flags(O_CLOEXEC); |
338 | if (ret < 0) | 338 | if (ret < 0) |
339 | goto err_free; | 339 | goto err_free; |
340 | resp.async_fd = ret; | 340 | resp.async_fd = ret; |
@@ -1184,7 +1184,7 @@ ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file, | |||
1184 | if (copy_from_user(&cmd, buf, sizeof cmd)) | 1184 | if (copy_from_user(&cmd, buf, sizeof cmd)) |
1185 | return -EFAULT; | 1185 | return -EFAULT; |
1186 | 1186 | ||
1187 | ret = get_unused_fd(); | 1187 | ret = get_unused_fd_flags(O_CLOEXEC); |
1188 | if (ret < 0) | 1188 | if (ret < 0) |
1189 | return ret; | 1189 | return ret; |
1190 | resp.fd = ret; | 1190 | resp.fd = ret; |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c index e5649e8b215d..b57c0befd962 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_qp.c +++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c | |||
@@ -883,7 +883,8 @@ u16 iwch_rqes_posted(struct iwch_qp *qhp) | |||
883 | { | 883 | { |
884 | union t3_wr *wqe = qhp->wq.queue; | 884 | union t3_wr *wqe = qhp->wq.queue; |
885 | u16 count = 0; | 885 | u16 count = 0; |
886 | while ((count+1) != 0 && fw_riwrh_opcode((struct fw_riwrh *)wqe) == T3_WR_RCV) { | 886 | |
887 | while (count < USHRT_MAX && fw_riwrh_opcode((struct fw_riwrh *)wqe) == T3_WR_RCV) { | ||
887 | count++; | 888 | count++; |
888 | wqe++; | 889 | wqe++; |
889 | } | 890 | } |
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c index f8a62918a88d..8f43093edace 100644 --- a/drivers/infiniband/hw/ehca/ehca_main.c +++ b/drivers/infiniband/hw/ehca/ehca_main.c | |||
@@ -211,6 +211,7 @@ static int ehca_create_slab_caches(void) | |||
211 | if (!ctblk_cache) { | 211 | if (!ctblk_cache) { |
212 | ehca_gen_err("Cannot create ctblk SLAB cache."); | 212 | ehca_gen_err("Cannot create ctblk SLAB cache."); |
213 | ehca_cleanup_small_qp_cache(); | 213 | ehca_cleanup_small_qp_cache(); |
214 | ret = -ENOMEM; | ||
214 | goto create_slab_caches6; | 215 | goto create_slab_caches6; |
215 | } | 216 | } |
216 | #endif | 217 | #endif |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h index 48970af23679..d540180a8e42 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma.h | |||
@@ -42,8 +42,6 @@ | |||
42 | #define OCRDMA_ROCE_DEV_VERSION "1.0.0" | 42 | #define OCRDMA_ROCE_DEV_VERSION "1.0.0" |
43 | #define OCRDMA_NODE_DESC "Emulex OneConnect RoCE HCA" | 43 | #define OCRDMA_NODE_DESC "Emulex OneConnect RoCE HCA" |
44 | 44 | ||
45 | #define ocrdma_err(format, arg...) printk(KERN_ERR format, ##arg) | ||
46 | |||
47 | #define OCRDMA_MAX_AH 512 | 45 | #define OCRDMA_MAX_AH 512 |
48 | 46 | ||
49 | #define OCRDMA_UVERBS(CMD_NAME) (1ull << IB_USER_VERBS_CMD_##CMD_NAME) | 47 | #define OCRDMA_UVERBS(CMD_NAME) (1ull << IB_USER_VERBS_CMD_##CMD_NAME) |
@@ -97,7 +95,6 @@ struct ocrdma_queue_info { | |||
97 | u16 id; /* qid, where to ring the doorbell. */ | 95 | u16 id; /* qid, where to ring the doorbell. */ |
98 | u16 head, tail; | 96 | u16 head, tail; |
99 | bool created; | 97 | bool created; |
100 | atomic_t used; /* Number of valid elements in the queue */ | ||
101 | }; | 98 | }; |
102 | 99 | ||
103 | struct ocrdma_eq { | 100 | struct ocrdma_eq { |
@@ -198,7 +195,6 @@ struct ocrdma_cq { | |||
198 | struct ocrdma_ucontext *ucontext; | 195 | struct ocrdma_ucontext *ucontext; |
199 | dma_addr_t pa; | 196 | dma_addr_t pa; |
200 | u32 len; | 197 | u32 len; |
201 | atomic_t use_cnt; | ||
202 | 198 | ||
203 | /* head of all qp's sq and rq for which cqes need to be flushed | 199 | /* head of all qp's sq and rq for which cqes need to be flushed |
204 | * by the software. | 200 | * by the software. |
@@ -210,7 +206,6 @@ struct ocrdma_pd { | |||
210 | struct ib_pd ibpd; | 206 | struct ib_pd ibpd; |
211 | struct ocrdma_dev *dev; | 207 | struct ocrdma_dev *dev; |
212 | struct ocrdma_ucontext *uctx; | 208 | struct ocrdma_ucontext *uctx; |
213 | atomic_t use_cnt; | ||
214 | u32 id; | 209 | u32 id; |
215 | int num_dpp_qp; | 210 | int num_dpp_qp; |
216 | u32 dpp_page; | 211 | u32 dpp_page; |
@@ -241,16 +236,16 @@ struct ocrdma_srq { | |||
241 | struct ib_srq ibsrq; | 236 | struct ib_srq ibsrq; |
242 | struct ocrdma_dev *dev; | 237 | struct ocrdma_dev *dev; |
243 | u8 __iomem *db; | 238 | u8 __iomem *db; |
239 | struct ocrdma_qp_hwq_info rq; | ||
240 | u64 *rqe_wr_id_tbl; | ||
241 | u32 *idx_bit_fields; | ||
242 | u32 bit_fields_len; | ||
243 | |||
244 | /* provide synchronization to multiple context(s) posting rqe */ | 244 | /* provide synchronization to multiple context(s) posting rqe */ |
245 | spinlock_t q_lock ____cacheline_aligned; | 245 | spinlock_t q_lock ____cacheline_aligned; |
246 | 246 | ||
247 | struct ocrdma_qp_hwq_info rq; | ||
248 | struct ocrdma_pd *pd; | 247 | struct ocrdma_pd *pd; |
249 | atomic_t use_cnt; | ||
250 | u32 id; | 248 | u32 id; |
251 | u64 *rqe_wr_id_tbl; | ||
252 | u32 *idx_bit_fields; | ||
253 | u32 bit_fields_len; | ||
254 | }; | 249 | }; |
255 | 250 | ||
256 | struct ocrdma_qp { | 251 | struct ocrdma_qp { |
@@ -258,8 +253,6 @@ struct ocrdma_qp { | |||
258 | struct ocrdma_dev *dev; | 253 | struct ocrdma_dev *dev; |
259 | 254 | ||
260 | u8 __iomem *sq_db; | 255 | u8 __iomem *sq_db; |
261 | /* provide synchronization to multiple context(s) posting wqe, rqe */ | ||
262 | spinlock_t q_lock ____cacheline_aligned; | ||
263 | struct ocrdma_qp_hwq_info sq; | 256 | struct ocrdma_qp_hwq_info sq; |
264 | struct { | 257 | struct { |
265 | uint64_t wrid; | 258 | uint64_t wrid; |
@@ -269,6 +262,9 @@ struct ocrdma_qp { | |||
269 | uint8_t rsvd[3]; | 262 | uint8_t rsvd[3]; |
270 | } *wqe_wr_id_tbl; | 263 | } *wqe_wr_id_tbl; |
271 | u32 max_inline_data; | 264 | u32 max_inline_data; |
265 | |||
266 | /* provide synchronization to multiple context(s) posting wqe, rqe */ | ||
267 | spinlock_t q_lock ____cacheline_aligned; | ||
272 | struct ocrdma_cq *sq_cq; | 268 | struct ocrdma_cq *sq_cq; |
273 | /* list maintained per CQ to flush SQ errors */ | 269 | /* list maintained per CQ to flush SQ errors */ |
274 | struct list_head sq_entry; | 270 | struct list_head sq_entry; |
@@ -296,10 +292,6 @@ struct ocrdma_qp { | |||
296 | u8 *ird_q_va; | 292 | u8 *ird_q_va; |
297 | }; | 293 | }; |
298 | 294 | ||
299 | #define OCRDMA_GET_NUM_POSTED_SHIFT_VAL(qp) \ | ||
300 | (((qp->dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) && \ | ||
301 | (qp->id < 64)) ? 24 : 16) | ||
302 | |||
303 | struct ocrdma_hw_mr { | 295 | struct ocrdma_hw_mr { |
304 | struct ocrdma_dev *dev; | 296 | struct ocrdma_dev *dev; |
305 | u32 lkey; | 297 | u32 lkey; |
@@ -390,4 +382,43 @@ static inline struct ocrdma_srq *get_ocrdma_srq(struct ib_srq *ibsrq) | |||
390 | return container_of(ibsrq, struct ocrdma_srq, ibsrq); | 382 | return container_of(ibsrq, struct ocrdma_srq, ibsrq); |
391 | } | 383 | } |
392 | 384 | ||
385 | |||
386 | static inline int ocrdma_get_num_posted_shift(struct ocrdma_qp *qp) | ||
387 | { | ||
388 | return ((qp->dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY && | ||
389 | qp->id < 64) ? 24 : 16); | ||
390 | } | ||
391 | |||
392 | static inline int is_cqe_valid(struct ocrdma_cq *cq, struct ocrdma_cqe *cqe) | ||
393 | { | ||
394 | int cqe_valid; | ||
395 | cqe_valid = le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_VALID; | ||
396 | return ((cqe_valid == cq->phase) ? 1 : 0); | ||
397 | } | ||
398 | |||
399 | static inline int is_cqe_for_sq(struct ocrdma_cqe *cqe) | ||
400 | { | ||
401 | return (le32_to_cpu(cqe->flags_status_srcqpn) & | ||
402 | OCRDMA_CQE_QTYPE) ? 0 : 1; | ||
403 | } | ||
404 | |||
405 | static inline int is_cqe_invalidated(struct ocrdma_cqe *cqe) | ||
406 | { | ||
407 | return (le32_to_cpu(cqe->flags_status_srcqpn) & | ||
408 | OCRDMA_CQE_INVALIDATE) ? 1 : 0; | ||
409 | } | ||
410 | |||
411 | static inline int is_cqe_imm(struct ocrdma_cqe *cqe) | ||
412 | { | ||
413 | return (le32_to_cpu(cqe->flags_status_srcqpn) & | ||
414 | OCRDMA_CQE_IMM) ? 1 : 0; | ||
415 | } | ||
416 | |||
417 | static inline int is_cqe_wr_imm(struct ocrdma_cqe *cqe) | ||
418 | { | ||
419 | return (le32_to_cpu(cqe->flags_status_srcqpn) & | ||
420 | OCRDMA_CQE_WRITE_IMM) ? 1 : 0; | ||
421 | } | ||
422 | |||
423 | |||
393 | #endif | 424 | #endif |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c index 71942af4fce9..0965278dd2ed 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c | |||
@@ -128,7 +128,6 @@ static inline struct ocrdma_mqe *ocrdma_get_mqe(struct ocrdma_dev *dev) | |||
128 | static inline void ocrdma_mq_inc_head(struct ocrdma_dev *dev) | 128 | static inline void ocrdma_mq_inc_head(struct ocrdma_dev *dev) |
129 | { | 129 | { |
130 | dev->mq.sq.head = (dev->mq.sq.head + 1) & (OCRDMA_MQ_LEN - 1); | 130 | dev->mq.sq.head = (dev->mq.sq.head + 1) & (OCRDMA_MQ_LEN - 1); |
131 | atomic_inc(&dev->mq.sq.used); | ||
132 | } | 131 | } |
133 | 132 | ||
134 | static inline void *ocrdma_get_mqe_rsp(struct ocrdma_dev *dev) | 133 | static inline void *ocrdma_get_mqe_rsp(struct ocrdma_dev *dev) |
@@ -564,32 +563,19 @@ static int ocrdma_mbx_create_mq(struct ocrdma_dev *dev, | |||
564 | memset(cmd, 0, sizeof(*cmd)); | 563 | memset(cmd, 0, sizeof(*cmd)); |
565 | num_pages = PAGES_4K_SPANNED(mq->va, mq->size); | 564 | num_pages = PAGES_4K_SPANNED(mq->va, mq->size); |
566 | 565 | ||
567 | if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { | 566 | ocrdma_init_mch(&cmd->req, OCRDMA_CMD_CREATE_MQ_EXT, |
568 | ocrdma_init_mch(&cmd->req, OCRDMA_CMD_CREATE_MQ, | 567 | OCRDMA_SUBSYS_COMMON, sizeof(*cmd)); |
569 | OCRDMA_SUBSYS_COMMON, sizeof(*cmd)); | 568 | cmd->req.rsvd_version = 1; |
570 | cmd->v0.pages = num_pages; | 569 | cmd->cqid_pages = num_pages; |
571 | cmd->v0.async_cqid_valid = OCRDMA_CREATE_MQ_ASYNC_CQ_VALID; | 570 | cmd->cqid_pages |= (cq->id << OCRDMA_CREATE_MQ_CQ_ID_SHIFT); |
572 | cmd->v0.async_cqid_valid = (cq->id << 1); | 571 | cmd->async_cqid_valid = OCRDMA_CREATE_MQ_ASYNC_CQ_VALID; |
573 | cmd->v0.cqid_ringsize |= (ocrdma_encoded_q_len(mq->len) << | 572 | cmd->async_event_bitmap = Bit(20); |
574 | OCRDMA_CREATE_MQ_RING_SIZE_SHIFT); | 573 | cmd->async_cqid_ringsize = cq->id; |
575 | cmd->v0.cqid_ringsize |= | 574 | cmd->async_cqid_ringsize |= (ocrdma_encoded_q_len(mq->len) << |
576 | (cq->id << OCRDMA_CREATE_MQ_V0_CQ_ID_SHIFT); | 575 | OCRDMA_CREATE_MQ_RING_SIZE_SHIFT); |
577 | cmd->v0.valid = OCRDMA_CREATE_MQ_VALID; | 576 | cmd->valid = OCRDMA_CREATE_MQ_VALID; |
578 | pa = &cmd->v0.pa[0]; | 577 | pa = &cmd->pa[0]; |
579 | } else { | 578 | |
580 | ocrdma_init_mch(&cmd->req, OCRDMA_CMD_CREATE_MQ_EXT, | ||
581 | OCRDMA_SUBSYS_COMMON, sizeof(*cmd)); | ||
582 | cmd->req.rsvd_version = 1; | ||
583 | cmd->v1.cqid_pages = num_pages; | ||
584 | cmd->v1.cqid_pages |= (cq->id << OCRDMA_CREATE_MQ_CQ_ID_SHIFT); | ||
585 | cmd->v1.async_cqid_valid = OCRDMA_CREATE_MQ_ASYNC_CQ_VALID; | ||
586 | cmd->v1.async_event_bitmap = Bit(20); | ||
587 | cmd->v1.async_cqid_ringsize = cq->id; | ||
588 | cmd->v1.async_cqid_ringsize |= (ocrdma_encoded_q_len(mq->len) << | ||
589 | OCRDMA_CREATE_MQ_RING_SIZE_SHIFT); | ||
590 | cmd->v1.valid = OCRDMA_CREATE_MQ_VALID; | ||
591 | pa = &cmd->v1.pa[0]; | ||
592 | } | ||
593 | ocrdma_build_q_pages(pa, num_pages, mq->dma, PAGE_SIZE_4K); | 579 | ocrdma_build_q_pages(pa, num_pages, mq->dma, PAGE_SIZE_4K); |
594 | status = be_roce_mcc_cmd(dev->nic_info.netdev, | 580 | status = be_roce_mcc_cmd(dev->nic_info.netdev, |
595 | cmd, sizeof(*cmd), NULL, NULL); | 581 | cmd, sizeof(*cmd), NULL, NULL); |
@@ -745,7 +731,7 @@ static void ocrdma_dispatch_ibevent(struct ocrdma_dev *dev, | |||
745 | qp_event = 0; | 731 | qp_event = 0; |
746 | srq_event = 0; | 732 | srq_event = 0; |
747 | dev_event = 0; | 733 | dev_event = 0; |
748 | ocrdma_err("%s() unknown type=0x%x\n", __func__, type); | 734 | pr_err("%s() unknown type=0x%x\n", __func__, type); |
749 | break; | 735 | break; |
750 | } | 736 | } |
751 | 737 | ||
@@ -775,8 +761,8 @@ static void ocrdma_process_acqe(struct ocrdma_dev *dev, void *ae_cqe) | |||
775 | if (evt_code == OCRDMA_ASYNC_EVE_CODE) | 761 | if (evt_code == OCRDMA_ASYNC_EVE_CODE) |
776 | ocrdma_dispatch_ibevent(dev, cqe); | 762 | ocrdma_dispatch_ibevent(dev, cqe); |
777 | else | 763 | else |
778 | ocrdma_err("%s(%d) invalid evt code=0x%x\n", | 764 | pr_err("%s(%d) invalid evt code=0x%x\n", __func__, |
779 | __func__, dev->id, evt_code); | 765 | dev->id, evt_code); |
780 | } | 766 | } |
781 | 767 | ||
782 | static void ocrdma_process_mcqe(struct ocrdma_dev *dev, struct ocrdma_mcqe *cqe) | 768 | static void ocrdma_process_mcqe(struct ocrdma_dev *dev, struct ocrdma_mcqe *cqe) |
@@ -790,8 +776,8 @@ static void ocrdma_process_mcqe(struct ocrdma_dev *dev, struct ocrdma_mcqe *cqe) | |||
790 | dev->mqe_ctx.cmd_done = true; | 776 | dev->mqe_ctx.cmd_done = true; |
791 | wake_up(&dev->mqe_ctx.cmd_wait); | 777 | wake_up(&dev->mqe_ctx.cmd_wait); |
792 | } else | 778 | } else |
793 | ocrdma_err("%s() cqe for invalid tag0x%x.expected=0x%x\n", | 779 | pr_err("%s() cqe for invalid tag0x%x.expected=0x%x\n", |
794 | __func__, cqe->tag_lo, dev->mqe_ctx.tag); | 780 | __func__, cqe->tag_lo, dev->mqe_ctx.tag); |
795 | } | 781 | } |
796 | 782 | ||
797 | static int ocrdma_mq_cq_handler(struct ocrdma_dev *dev, u16 cq_id) | 783 | static int ocrdma_mq_cq_handler(struct ocrdma_dev *dev, u16 cq_id) |
@@ -810,7 +796,7 @@ static int ocrdma_mq_cq_handler(struct ocrdma_dev *dev, u16 cq_id) | |||
810 | else if (cqe->valid_ae_cmpl_cons & OCRDMA_MCQE_CMPL_MASK) | 796 | else if (cqe->valid_ae_cmpl_cons & OCRDMA_MCQE_CMPL_MASK) |
811 | ocrdma_process_mcqe(dev, cqe); | 797 | ocrdma_process_mcqe(dev, cqe); |
812 | else | 798 | else |
813 | ocrdma_err("%s() cqe->compl is not set.\n", __func__); | 799 | pr_err("%s() cqe->compl is not set.\n", __func__); |
814 | memset(cqe, 0, sizeof(struct ocrdma_mcqe)); | 800 | memset(cqe, 0, sizeof(struct ocrdma_mcqe)); |
815 | ocrdma_mcq_inc_tail(dev); | 801 | ocrdma_mcq_inc_tail(dev); |
816 | } | 802 | } |
@@ -869,7 +855,7 @@ static void ocrdma_qp_cq_handler(struct ocrdma_dev *dev, u16 cq_idx) | |||
869 | 855 | ||
870 | cq = dev->cq_tbl[cq_idx]; | 856 | cq = dev->cq_tbl[cq_idx]; |
871 | if (cq == NULL) { | 857 | if (cq == NULL) { |
872 | ocrdma_err("%s%d invalid id=0x%x\n", __func__, dev->id, cq_idx); | 858 | pr_err("%s%d invalid id=0x%x\n", __func__, dev->id, cq_idx); |
873 | return; | 859 | return; |
874 | } | 860 | } |
875 | spin_lock_irqsave(&cq->cq_lock, flags); | 861 | spin_lock_irqsave(&cq->cq_lock, flags); |
@@ -971,7 +957,7 @@ static int ocrdma_mbx_cmd(struct ocrdma_dev *dev, struct ocrdma_mqe *mqe) | |||
971 | rsp = ocrdma_get_mqe_rsp(dev); | 957 | rsp = ocrdma_get_mqe_rsp(dev); |
972 | ocrdma_copy_le32_to_cpu(mqe, rsp, (sizeof(*mqe))); | 958 | ocrdma_copy_le32_to_cpu(mqe, rsp, (sizeof(*mqe))); |
973 | if (cqe_status || ext_status) { | 959 | if (cqe_status || ext_status) { |
974 | ocrdma_err | 960 | pr_err |
975 | ("%s() opcode=0x%x, cqe_status=0x%x, ext_status=0x%x\n", | 961 | ("%s() opcode=0x%x, cqe_status=0x%x, ext_status=0x%x\n", |
976 | __func__, | 962 | __func__, |
977 | (rsp->u.rsp.subsys_op & OCRDMA_MBX_RSP_OPCODE_MASK) >> | 963 | (rsp->u.rsp.subsys_op & OCRDMA_MBX_RSP_OPCODE_MASK) >> |
@@ -1353,8 +1339,8 @@ int ocrdma_mbx_create_cq(struct ocrdma_dev *dev, struct ocrdma_cq *cq, | |||
1353 | if (dpp_cq) | 1339 | if (dpp_cq) |
1354 | return -EINVAL; | 1340 | return -EINVAL; |
1355 | if (entries > dev->attr.max_cqe) { | 1341 | if (entries > dev->attr.max_cqe) { |
1356 | ocrdma_err("%s(%d) max_cqe=0x%x, requester_cqe=0x%x\n", | 1342 | pr_err("%s(%d) max_cqe=0x%x, requester_cqe=0x%x\n", |
1357 | __func__, dev->id, dev->attr.max_cqe, entries); | 1343 | __func__, dev->id, dev->attr.max_cqe, entries); |
1358 | return -EINVAL; | 1344 | return -EINVAL; |
1359 | } | 1345 | } |
1360 | if (dpp_cq && (dev->nic_info.dev_family != OCRDMA_GEN2_FAMILY)) | 1346 | if (dpp_cq && (dev->nic_info.dev_family != OCRDMA_GEN2_FAMILY)) |
@@ -1621,7 +1607,7 @@ int ocrdma_reg_mr(struct ocrdma_dev *dev, | |||
1621 | status = ocrdma_mbx_reg_mr(dev, hwmr, pdid, | 1607 | status = ocrdma_mbx_reg_mr(dev, hwmr, pdid, |
1622 | cur_pbl_cnt, hwmr->pbe_size, last); | 1608 | cur_pbl_cnt, hwmr->pbe_size, last); |
1623 | if (status) { | 1609 | if (status) { |
1624 | ocrdma_err("%s() status=%d\n", __func__, status); | 1610 | pr_err("%s() status=%d\n", __func__, status); |
1625 | return status; | 1611 | return status; |
1626 | } | 1612 | } |
1627 | /* if there is no more pbls to register then exit. */ | 1613 | /* if there is no more pbls to register then exit. */ |
@@ -1644,7 +1630,7 @@ int ocrdma_reg_mr(struct ocrdma_dev *dev, | |||
1644 | break; | 1630 | break; |
1645 | } | 1631 | } |
1646 | if (status) | 1632 | if (status) |
1647 | ocrdma_err("%s() err. status=%d\n", __func__, status); | 1633 | pr_err("%s() err. status=%d\n", __func__, status); |
1648 | 1634 | ||
1649 | return status; | 1635 | return status; |
1650 | } | 1636 | } |
@@ -1841,8 +1827,8 @@ static int ocrdma_set_create_qp_sq_cmd(struct ocrdma_create_qp_req *cmd, | |||
1841 | status = ocrdma_build_q_conf(&max_wqe_allocated, | 1827 | status = ocrdma_build_q_conf(&max_wqe_allocated, |
1842 | dev->attr.wqe_size, &hw_pages, &hw_page_size); | 1828 | dev->attr.wqe_size, &hw_pages, &hw_page_size); |
1843 | if (status) { | 1829 | if (status) { |
1844 | ocrdma_err("%s() req. max_send_wr=0x%x\n", __func__, | 1830 | pr_err("%s() req. max_send_wr=0x%x\n", __func__, |
1845 | max_wqe_allocated); | 1831 | max_wqe_allocated); |
1846 | return -EINVAL; | 1832 | return -EINVAL; |
1847 | } | 1833 | } |
1848 | qp->sq.max_cnt = max_wqe_allocated; | 1834 | qp->sq.max_cnt = max_wqe_allocated; |
@@ -1891,8 +1877,8 @@ static int ocrdma_set_create_qp_rq_cmd(struct ocrdma_create_qp_req *cmd, | |||
1891 | status = ocrdma_build_q_conf(&max_rqe_allocated, dev->attr.rqe_size, | 1877 | status = ocrdma_build_q_conf(&max_rqe_allocated, dev->attr.rqe_size, |
1892 | &hw_pages, &hw_page_size); | 1878 | &hw_pages, &hw_page_size); |
1893 | if (status) { | 1879 | if (status) { |
1894 | ocrdma_err("%s() req. max_recv_wr=0x%x\n", __func__, | 1880 | pr_err("%s() req. max_recv_wr=0x%x\n", __func__, |
1895 | attrs->cap.max_recv_wr + 1); | 1881 | attrs->cap.max_recv_wr + 1); |
1896 | return status; | 1882 | return status; |
1897 | } | 1883 | } |
1898 | qp->rq.max_cnt = max_rqe_allocated; | 1884 | qp->rq.max_cnt = max_rqe_allocated; |
@@ -1900,7 +1886,7 @@ static int ocrdma_set_create_qp_rq_cmd(struct ocrdma_create_qp_req *cmd, | |||
1900 | 1886 | ||
1901 | qp->rq.va = dma_alloc_coherent(&pdev->dev, len, &pa, GFP_KERNEL); | 1887 | qp->rq.va = dma_alloc_coherent(&pdev->dev, len, &pa, GFP_KERNEL); |
1902 | if (!qp->rq.va) | 1888 | if (!qp->rq.va) |
1903 | return status; | 1889 | return -ENOMEM; |
1904 | memset(qp->rq.va, 0, len); | 1890 | memset(qp->rq.va, 0, len); |
1905 | qp->rq.pa = pa; | 1891 | qp->rq.pa = pa; |
1906 | qp->rq.len = len; | 1892 | qp->rq.len = len; |
@@ -2087,10 +2073,10 @@ mbx_err: | |||
2087 | if (qp->rq.va) | 2073 | if (qp->rq.va) |
2088 | dma_free_coherent(&pdev->dev, qp->rq.len, qp->rq.va, qp->rq.pa); | 2074 | dma_free_coherent(&pdev->dev, qp->rq.len, qp->rq.va, qp->rq.pa); |
2089 | rq_err: | 2075 | rq_err: |
2090 | ocrdma_err("%s(%d) rq_err\n", __func__, dev->id); | 2076 | pr_err("%s(%d) rq_err\n", __func__, dev->id); |
2091 | dma_free_coherent(&pdev->dev, qp->sq.len, qp->sq.va, qp->sq.pa); | 2077 | dma_free_coherent(&pdev->dev, qp->sq.len, qp->sq.va, qp->sq.pa); |
2092 | sq_err: | 2078 | sq_err: |
2093 | ocrdma_err("%s(%d) sq_err\n", __func__, dev->id); | 2079 | pr_err("%s(%d) sq_err\n", __func__, dev->id); |
2094 | kfree(cmd); | 2080 | kfree(cmd); |
2095 | return status; | 2081 | return status; |
2096 | } | 2082 | } |
@@ -2127,7 +2113,7 @@ int ocrdma_resolve_dgid(struct ocrdma_dev *dev, union ib_gid *dgid, | |||
2127 | else if (rdma_link_local_addr(&in6)) | 2113 | else if (rdma_link_local_addr(&in6)) |
2128 | rdma_get_ll_mac(&in6, mac_addr); | 2114 | rdma_get_ll_mac(&in6, mac_addr); |
2129 | else { | 2115 | else { |
2130 | ocrdma_err("%s() fail to resolve mac_addr.\n", __func__); | 2116 | pr_err("%s() fail to resolve mac_addr.\n", __func__); |
2131 | return -EINVAL; | 2117 | return -EINVAL; |
2132 | } | 2118 | } |
2133 | return 0; | 2119 | return 0; |
@@ -2362,8 +2348,8 @@ int ocrdma_mbx_create_srq(struct ocrdma_srq *srq, | |||
2362 | dev->attr.rqe_size, | 2348 | dev->attr.rqe_size, |
2363 | &hw_pages, &hw_page_size); | 2349 | &hw_pages, &hw_page_size); |
2364 | if (status) { | 2350 | if (status) { |
2365 | ocrdma_err("%s() req. max_wr=0x%x\n", __func__, | 2351 | pr_err("%s() req. max_wr=0x%x\n", __func__, |
2366 | srq_attr->attr.max_wr); | 2352 | srq_attr->attr.max_wr); |
2367 | status = -EINVAL; | 2353 | status = -EINVAL; |
2368 | goto ret; | 2354 | goto ret; |
2369 | } | 2355 | } |
@@ -2614,7 +2600,7 @@ mq_err: | |||
2614 | ocrdma_destroy_qp_eqs(dev); | 2600 | ocrdma_destroy_qp_eqs(dev); |
2615 | qpeq_err: | 2601 | qpeq_err: |
2616 | ocrdma_destroy_eq(dev, &dev->meq); | 2602 | ocrdma_destroy_eq(dev, &dev->meq); |
2617 | ocrdma_err("%s() status=%d\n", __func__, status); | 2603 | pr_err("%s() status=%d\n", __func__, status); |
2618 | return status; | 2604 | return status; |
2619 | } | 2605 | } |
2620 | 2606 | ||
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c index 48928c8e7774..ded416f1adea 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c | |||
@@ -378,7 +378,7 @@ static int ocrdma_alloc_resources(struct ocrdma_dev *dev) | |||
378 | spin_lock_init(&dev->flush_q_lock); | 378 | spin_lock_init(&dev->flush_q_lock); |
379 | return 0; | 379 | return 0; |
380 | alloc_err: | 380 | alloc_err: |
381 | ocrdma_err("%s(%d) error.\n", __func__, dev->id); | 381 | pr_err("%s(%d) error.\n", __func__, dev->id); |
382 | return -ENOMEM; | 382 | return -ENOMEM; |
383 | } | 383 | } |
384 | 384 | ||
@@ -396,7 +396,7 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info) | |||
396 | 396 | ||
397 | dev = (struct ocrdma_dev *)ib_alloc_device(sizeof(struct ocrdma_dev)); | 397 | dev = (struct ocrdma_dev *)ib_alloc_device(sizeof(struct ocrdma_dev)); |
398 | if (!dev) { | 398 | if (!dev) { |
399 | ocrdma_err("Unable to allocate ib device\n"); | 399 | pr_err("Unable to allocate ib device\n"); |
400 | return NULL; | 400 | return NULL; |
401 | } | 401 | } |
402 | dev->mbx_cmd = kzalloc(sizeof(struct ocrdma_mqe_emb_cmd), GFP_KERNEL); | 402 | dev->mbx_cmd = kzalloc(sizeof(struct ocrdma_mqe_emb_cmd), GFP_KERNEL); |
@@ -437,7 +437,7 @@ init_err: | |||
437 | idr_err: | 437 | idr_err: |
438 | kfree(dev->mbx_cmd); | 438 | kfree(dev->mbx_cmd); |
439 | ib_dealloc_device(&dev->ibdev); | 439 | ib_dealloc_device(&dev->ibdev); |
440 | ocrdma_err("%s() leaving. ret=%d\n", __func__, status); | 440 | pr_err("%s() leaving. ret=%d\n", __func__, status); |
441 | return NULL; | 441 | return NULL; |
442 | } | 442 | } |
443 | 443 | ||
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h index c75cbdfa87e7..36b062da2aea 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h | |||
@@ -608,16 +608,8 @@ enum { | |||
608 | OCRDMA_CREATE_MQ_ASYNC_CQ_VALID = Bit(0) | 608 | OCRDMA_CREATE_MQ_ASYNC_CQ_VALID = Bit(0) |
609 | }; | 609 | }; |
610 | 610 | ||
611 | struct ocrdma_create_mq_v0 { | 611 | struct ocrdma_create_mq_req { |
612 | u32 pages; | 612 | struct ocrdma_mbx_hdr req; |
613 | u32 cqid_ringsize; | ||
614 | u32 valid; | ||
615 | u32 async_cqid_valid; | ||
616 | u32 rsvd; | ||
617 | struct ocrdma_pa pa[8]; | ||
618 | } __packed; | ||
619 | |||
620 | struct ocrdma_create_mq_v1 { | ||
621 | u32 cqid_pages; | 613 | u32 cqid_pages; |
622 | u32 async_event_bitmap; | 614 | u32 async_event_bitmap; |
623 | u32 async_cqid_ringsize; | 615 | u32 async_cqid_ringsize; |
@@ -627,14 +619,6 @@ struct ocrdma_create_mq_v1 { | |||
627 | struct ocrdma_pa pa[8]; | 619 | struct ocrdma_pa pa[8]; |
628 | } __packed; | 620 | } __packed; |
629 | 621 | ||
630 | struct ocrdma_create_mq_req { | ||
631 | struct ocrdma_mbx_hdr req; | ||
632 | union { | ||
633 | struct ocrdma_create_mq_v0 v0; | ||
634 | struct ocrdma_create_mq_v1 v1; | ||
635 | }; | ||
636 | } __packed; | ||
637 | |||
638 | struct ocrdma_create_mq_rsp { | 622 | struct ocrdma_create_mq_rsp { |
639 | struct ocrdma_mbx_rsp rsp; | 623 | struct ocrdma_mbx_rsp rsp; |
640 | u32 id; | 624 | u32 id; |
@@ -1550,21 +1534,6 @@ struct ocrdma_cqe { | |||
1550 | u32 flags_status_srcqpn; /* w3 */ | 1534 | u32 flags_status_srcqpn; /* w3 */ |
1551 | } __packed; | 1535 | } __packed; |
1552 | 1536 | ||
1553 | #define is_cqe_valid(cq, cqe) \ | ||
1554 | (((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_VALID)\ | ||
1555 | == cq->phase) ? 1 : 0) | ||
1556 | #define is_cqe_for_sq(cqe) \ | ||
1557 | ((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_QTYPE) ? 0 : 1) | ||
1558 | #define is_cqe_for_rq(cqe) \ | ||
1559 | ((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_QTYPE) ? 1 : 0) | ||
1560 | #define is_cqe_invalidated(cqe) \ | ||
1561 | ((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_INVALIDATE) ? \ | ||
1562 | 1 : 0) | ||
1563 | #define is_cqe_imm(cqe) \ | ||
1564 | ((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_IMM) ? 1 : 0) | ||
1565 | #define is_cqe_wr_imm(cqe) \ | ||
1566 | ((le32_to_cpu(cqe->flags_status_srcqpn) & OCRDMA_CQE_WRITE_IMM) ? 1 : 0) | ||
1567 | |||
1568 | struct ocrdma_sge { | 1537 | struct ocrdma_sge { |
1569 | u32 addr_hi; | 1538 | u32 addr_hi; |
1570 | u32 addr_lo; | 1539 | u32 addr_lo; |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index b29a4246ef41..dcfbab177faa 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c | |||
@@ -114,8 +114,8 @@ int ocrdma_query_port(struct ib_device *ibdev, | |||
114 | 114 | ||
115 | dev = get_ocrdma_dev(ibdev); | 115 | dev = get_ocrdma_dev(ibdev); |
116 | if (port > 1) { | 116 | if (port > 1) { |
117 | ocrdma_err("%s(%d) invalid_port=0x%x\n", __func__, | 117 | pr_err("%s(%d) invalid_port=0x%x\n", __func__, |
118 | dev->id, port); | 118 | dev->id, port); |
119 | return -EINVAL; | 119 | return -EINVAL; |
120 | } | 120 | } |
121 | netdev = dev->nic_info.netdev; | 121 | netdev = dev->nic_info.netdev; |
@@ -155,8 +155,7 @@ int ocrdma_modify_port(struct ib_device *ibdev, u8 port, int mask, | |||
155 | 155 | ||
156 | dev = get_ocrdma_dev(ibdev); | 156 | dev = get_ocrdma_dev(ibdev); |
157 | if (port > 1) { | 157 | if (port > 1) { |
158 | ocrdma_err("%s(%d) invalid_port=0x%x\n", __func__, | 158 | pr_err("%s(%d) invalid_port=0x%x\n", __func__, dev->id, port); |
159 | dev->id, port); | ||
160 | return -EINVAL; | 159 | return -EINVAL; |
161 | } | 160 | } |
162 | return 0; | 161 | return 0; |
@@ -398,7 +397,6 @@ struct ib_pd *ocrdma_alloc_pd(struct ib_device *ibdev, | |||
398 | kfree(pd); | 397 | kfree(pd); |
399 | return ERR_PTR(status); | 398 | return ERR_PTR(status); |
400 | } | 399 | } |
401 | atomic_set(&pd->use_cnt, 0); | ||
402 | 400 | ||
403 | if (udata && context) { | 401 | if (udata && context) { |
404 | status = ocrdma_copy_pd_uresp(pd, context, udata); | 402 | status = ocrdma_copy_pd_uresp(pd, context, udata); |
@@ -419,12 +417,6 @@ int ocrdma_dealloc_pd(struct ib_pd *ibpd) | |||
419 | int status; | 417 | int status; |
420 | u64 usr_db; | 418 | u64 usr_db; |
421 | 419 | ||
422 | if (atomic_read(&pd->use_cnt)) { | ||
423 | ocrdma_err("%s(%d) pd=0x%x is in use.\n", | ||
424 | __func__, dev->id, pd->id); | ||
425 | status = -EFAULT; | ||
426 | goto dealloc_err; | ||
427 | } | ||
428 | status = ocrdma_mbx_dealloc_pd(dev, pd); | 420 | status = ocrdma_mbx_dealloc_pd(dev, pd); |
429 | if (pd->uctx) { | 421 | if (pd->uctx) { |
430 | u64 dpp_db = dev->nic_info.dpp_unmapped_addr + | 422 | u64 dpp_db = dev->nic_info.dpp_unmapped_addr + |
@@ -436,7 +428,6 @@ int ocrdma_dealloc_pd(struct ib_pd *ibpd) | |||
436 | ocrdma_del_mmap(pd->uctx, usr_db, dev->nic_info.db_page_size); | 428 | ocrdma_del_mmap(pd->uctx, usr_db, dev->nic_info.db_page_size); |
437 | } | 429 | } |
438 | kfree(pd); | 430 | kfree(pd); |
439 | dealloc_err: | ||
440 | return status; | 431 | return status; |
441 | } | 432 | } |
442 | 433 | ||
@@ -450,8 +441,8 @@ static struct ocrdma_mr *ocrdma_alloc_lkey(struct ib_pd *ibpd, | |||
450 | struct ocrdma_dev *dev = pd->dev; | 441 | struct ocrdma_dev *dev = pd->dev; |
451 | 442 | ||
452 | if (acc & IB_ACCESS_REMOTE_WRITE && !(acc & IB_ACCESS_LOCAL_WRITE)) { | 443 | if (acc & IB_ACCESS_REMOTE_WRITE && !(acc & IB_ACCESS_LOCAL_WRITE)) { |
453 | ocrdma_err("%s(%d) leaving err, invalid access rights\n", | 444 | pr_err("%s(%d) leaving err, invalid access rights\n", |
454 | __func__, dev->id); | 445 | __func__, dev->id); |
455 | return ERR_PTR(-EINVAL); | 446 | return ERR_PTR(-EINVAL); |
456 | } | 447 | } |
457 | 448 | ||
@@ -474,7 +465,6 @@ static struct ocrdma_mr *ocrdma_alloc_lkey(struct ib_pd *ibpd, | |||
474 | return ERR_PTR(-ENOMEM); | 465 | return ERR_PTR(-ENOMEM); |
475 | } | 466 | } |
476 | mr->pd = pd; | 467 | mr->pd = pd; |
477 | atomic_inc(&pd->use_cnt); | ||
478 | mr->ibmr.lkey = mr->hwmr.lkey; | 468 | mr->ibmr.lkey = mr->hwmr.lkey; |
479 | if (mr->hwmr.remote_wr || mr->hwmr.remote_rd) | 469 | if (mr->hwmr.remote_wr || mr->hwmr.remote_rd) |
480 | mr->ibmr.rkey = mr->hwmr.lkey; | 470 | mr->ibmr.rkey = mr->hwmr.lkey; |
@@ -664,7 +654,6 @@ struct ib_mr *ocrdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len, | |||
664 | if (status) | 654 | if (status) |
665 | goto mbx_err; | 655 | goto mbx_err; |
666 | mr->pd = pd; | 656 | mr->pd = pd; |
667 | atomic_inc(&pd->use_cnt); | ||
668 | mr->ibmr.lkey = mr->hwmr.lkey; | 657 | mr->ibmr.lkey = mr->hwmr.lkey; |
669 | if (mr->hwmr.remote_wr || mr->hwmr.remote_rd) | 658 | if (mr->hwmr.remote_wr || mr->hwmr.remote_rd) |
670 | mr->ibmr.rkey = mr->hwmr.lkey; | 659 | mr->ibmr.rkey = mr->hwmr.lkey; |
@@ -689,7 +678,6 @@ int ocrdma_dereg_mr(struct ib_mr *ib_mr) | |||
689 | if (mr->hwmr.fr_mr == 0) | 678 | if (mr->hwmr.fr_mr == 0) |
690 | ocrdma_free_mr_pbl_tbl(dev, &mr->hwmr); | 679 | ocrdma_free_mr_pbl_tbl(dev, &mr->hwmr); |
691 | 680 | ||
692 | atomic_dec(&mr->pd->use_cnt); | ||
693 | /* it could be user registered memory. */ | 681 | /* it could be user registered memory. */ |
694 | if (mr->umem) | 682 | if (mr->umem) |
695 | ib_umem_release(mr->umem); | 683 | ib_umem_release(mr->umem); |
@@ -714,8 +702,8 @@ static int ocrdma_copy_cq_uresp(struct ocrdma_cq *cq, struct ib_udata *udata, | |||
714 | uresp.phase_change = cq->phase_change ? 1 : 0; | 702 | uresp.phase_change = cq->phase_change ? 1 : 0; |
715 | status = ib_copy_to_udata(udata, &uresp, sizeof(uresp)); | 703 | status = ib_copy_to_udata(udata, &uresp, sizeof(uresp)); |
716 | if (status) { | 704 | if (status) { |
717 | ocrdma_err("%s(%d) copy error cqid=0x%x.\n", | 705 | pr_err("%s(%d) copy error cqid=0x%x.\n", |
718 | __func__, cq->dev->id, cq->id); | 706 | __func__, cq->dev->id, cq->id); |
719 | goto err; | 707 | goto err; |
720 | } | 708 | } |
721 | uctx = get_ocrdma_ucontext(ib_ctx); | 709 | uctx = get_ocrdma_ucontext(ib_ctx); |
@@ -752,7 +740,6 @@ struct ib_cq *ocrdma_create_cq(struct ib_device *ibdev, int entries, int vector, | |||
752 | 740 | ||
753 | spin_lock_init(&cq->cq_lock); | 741 | spin_lock_init(&cq->cq_lock); |
754 | spin_lock_init(&cq->comp_handler_lock); | 742 | spin_lock_init(&cq->comp_handler_lock); |
755 | atomic_set(&cq->use_cnt, 0); | ||
756 | INIT_LIST_HEAD(&cq->sq_head); | 743 | INIT_LIST_HEAD(&cq->sq_head); |
757 | INIT_LIST_HEAD(&cq->rq_head); | 744 | INIT_LIST_HEAD(&cq->rq_head); |
758 | cq->dev = dev; | 745 | cq->dev = dev; |
@@ -799,9 +786,6 @@ int ocrdma_destroy_cq(struct ib_cq *ibcq) | |||
799 | struct ocrdma_cq *cq = get_ocrdma_cq(ibcq); | 786 | struct ocrdma_cq *cq = get_ocrdma_cq(ibcq); |
800 | struct ocrdma_dev *dev = cq->dev; | 787 | struct ocrdma_dev *dev = cq->dev; |
801 | 788 | ||
802 | if (atomic_read(&cq->use_cnt)) | ||
803 | return -EINVAL; | ||
804 | |||
805 | status = ocrdma_mbx_destroy_cq(dev, cq); | 789 | status = ocrdma_mbx_destroy_cq(dev, cq); |
806 | 790 | ||
807 | if (cq->ucontext) { | 791 | if (cq->ucontext) { |
@@ -837,57 +821,56 @@ static int ocrdma_check_qp_params(struct ib_pd *ibpd, struct ocrdma_dev *dev, | |||
837 | if (attrs->qp_type != IB_QPT_GSI && | 821 | if (attrs->qp_type != IB_QPT_GSI && |
838 | attrs->qp_type != IB_QPT_RC && | 822 | attrs->qp_type != IB_QPT_RC && |
839 | attrs->qp_type != IB_QPT_UD) { | 823 | attrs->qp_type != IB_QPT_UD) { |
840 | ocrdma_err("%s(%d) unsupported qp type=0x%x requested\n", | 824 | pr_err("%s(%d) unsupported qp type=0x%x requested\n", |
841 | __func__, dev->id, attrs->qp_type); | 825 | __func__, dev->id, attrs->qp_type); |
842 | return -EINVAL; | 826 | return -EINVAL; |
843 | } | 827 | } |
844 | if (attrs->cap.max_send_wr > dev->attr.max_wqe) { | 828 | if (attrs->cap.max_send_wr > dev->attr.max_wqe) { |
845 | ocrdma_err("%s(%d) unsupported send_wr=0x%x requested\n", | 829 | pr_err("%s(%d) unsupported send_wr=0x%x requested\n", |
846 | __func__, dev->id, attrs->cap.max_send_wr); | 830 | __func__, dev->id, attrs->cap.max_send_wr); |
847 | ocrdma_err("%s(%d) supported send_wr=0x%x\n", | 831 | pr_err("%s(%d) supported send_wr=0x%x\n", |
848 | __func__, dev->id, dev->attr.max_wqe); | 832 | __func__, dev->id, dev->attr.max_wqe); |
849 | return -EINVAL; | 833 | return -EINVAL; |
850 | } | 834 | } |
851 | if (!attrs->srq && (attrs->cap.max_recv_wr > dev->attr.max_rqe)) { | 835 | if (!attrs->srq && (attrs->cap.max_recv_wr > dev->attr.max_rqe)) { |
852 | ocrdma_err("%s(%d) unsupported recv_wr=0x%x requested\n", | 836 | pr_err("%s(%d) unsupported recv_wr=0x%x requested\n", |
853 | __func__, dev->id, attrs->cap.max_recv_wr); | 837 | __func__, dev->id, attrs->cap.max_recv_wr); |
854 | ocrdma_err("%s(%d) supported recv_wr=0x%x\n", | 838 | pr_err("%s(%d) supported recv_wr=0x%x\n", |
855 | __func__, dev->id, dev->attr.max_rqe); | 839 | __func__, dev->id, dev->attr.max_rqe); |
856 | return -EINVAL; | 840 | return -EINVAL; |
857 | } | 841 | } |
858 | if (attrs->cap.max_inline_data > dev->attr.max_inline_data) { | 842 | if (attrs->cap.max_inline_data > dev->attr.max_inline_data) { |
859 | ocrdma_err("%s(%d) unsupported inline data size=0x%x" | 843 | pr_err("%s(%d) unsupported inline data size=0x%x requested\n", |
860 | " requested\n", __func__, dev->id, | 844 | __func__, dev->id, attrs->cap.max_inline_data); |
861 | attrs->cap.max_inline_data); | 845 | pr_err("%s(%d) supported inline data size=0x%x\n", |
862 | ocrdma_err("%s(%d) supported inline data size=0x%x\n", | 846 | __func__, dev->id, dev->attr.max_inline_data); |
863 | __func__, dev->id, dev->attr.max_inline_data); | ||
864 | return -EINVAL; | 847 | return -EINVAL; |
865 | } | 848 | } |
866 | if (attrs->cap.max_send_sge > dev->attr.max_send_sge) { | 849 | if (attrs->cap.max_send_sge > dev->attr.max_send_sge) { |
867 | ocrdma_err("%s(%d) unsupported send_sge=0x%x requested\n", | 850 | pr_err("%s(%d) unsupported send_sge=0x%x requested\n", |
868 | __func__, dev->id, attrs->cap.max_send_sge); | 851 | __func__, dev->id, attrs->cap.max_send_sge); |
869 | ocrdma_err("%s(%d) supported send_sge=0x%x\n", | 852 | pr_err("%s(%d) supported send_sge=0x%x\n", |
870 | __func__, dev->id, dev->attr.max_send_sge); | 853 | __func__, dev->id, dev->attr.max_send_sge); |
871 | return -EINVAL; | 854 | return -EINVAL; |
872 | } | 855 | } |
873 | if (attrs->cap.max_recv_sge > dev->attr.max_recv_sge) { | 856 | if (attrs->cap.max_recv_sge > dev->attr.max_recv_sge) { |
874 | ocrdma_err("%s(%d) unsupported recv_sge=0x%x requested\n", | 857 | pr_err("%s(%d) unsupported recv_sge=0x%x requested\n", |
875 | __func__, dev->id, attrs->cap.max_recv_sge); | 858 | __func__, dev->id, attrs->cap.max_recv_sge); |
876 | ocrdma_err("%s(%d) supported recv_sge=0x%x\n", | 859 | pr_err("%s(%d) supported recv_sge=0x%x\n", |
877 | __func__, dev->id, dev->attr.max_recv_sge); | 860 | __func__, dev->id, dev->attr.max_recv_sge); |
878 | return -EINVAL; | 861 | return -EINVAL; |
879 | } | 862 | } |
880 | /* unprivileged user space cannot create special QP */ | 863 | /* unprivileged user space cannot create special QP */ |
881 | if (ibpd->uobject && attrs->qp_type == IB_QPT_GSI) { | 864 | if (ibpd->uobject && attrs->qp_type == IB_QPT_GSI) { |
882 | ocrdma_err | 865 | pr_err |
883 | ("%s(%d) Userspace can't create special QPs of type=0x%x\n", | 866 | ("%s(%d) Userspace can't create special QPs of type=0x%x\n", |
884 | __func__, dev->id, attrs->qp_type); | 867 | __func__, dev->id, attrs->qp_type); |
885 | return -EINVAL; | 868 | return -EINVAL; |
886 | } | 869 | } |
887 | /* allow creating only one GSI type of QP */ | 870 | /* allow creating only one GSI type of QP */ |
888 | if (attrs->qp_type == IB_QPT_GSI && dev->gsi_qp_created) { | 871 | if (attrs->qp_type == IB_QPT_GSI && dev->gsi_qp_created) { |
889 | ocrdma_err("%s(%d) GSI special QPs already created.\n", | 872 | pr_err("%s(%d) GSI special QPs already created.\n", |
890 | __func__, dev->id); | 873 | __func__, dev->id); |
891 | return -EINVAL; | 874 | return -EINVAL; |
892 | } | 875 | } |
893 | /* verify consumer QPs are not trying to use GSI QP's CQ */ | 876 | /* verify consumer QPs are not trying to use GSI QP's CQ */ |
@@ -896,8 +879,8 @@ static int ocrdma_check_qp_params(struct ib_pd *ibpd, struct ocrdma_dev *dev, | |||
896 | (dev->gsi_sqcq == get_ocrdma_cq(attrs->recv_cq)) || | 879 | (dev->gsi_sqcq == get_ocrdma_cq(attrs->recv_cq)) || |
897 | (dev->gsi_rqcq == get_ocrdma_cq(attrs->send_cq)) || | 880 | (dev->gsi_rqcq == get_ocrdma_cq(attrs->send_cq)) || |
898 | (dev->gsi_rqcq == get_ocrdma_cq(attrs->recv_cq))) { | 881 | (dev->gsi_rqcq == get_ocrdma_cq(attrs->recv_cq))) { |
899 | ocrdma_err("%s(%d) Consumer QP cannot use GSI CQs.\n", | 882 | pr_err("%s(%d) Consumer QP cannot use GSI CQs.\n", |
900 | __func__, dev->id); | 883 | __func__, dev->id); |
901 | return -EINVAL; | 884 | return -EINVAL; |
902 | } | 885 | } |
903 | } | 886 | } |
@@ -949,7 +932,7 @@ static int ocrdma_copy_qp_uresp(struct ocrdma_qp *qp, | |||
949 | } | 932 | } |
950 | status = ib_copy_to_udata(udata, &uresp, sizeof(uresp)); | 933 | status = ib_copy_to_udata(udata, &uresp, sizeof(uresp)); |
951 | if (status) { | 934 | if (status) { |
952 | ocrdma_err("%s(%d) user copy error.\n", __func__, dev->id); | 935 | pr_err("%s(%d) user copy error.\n", __func__, dev->id); |
953 | goto err; | 936 | goto err; |
954 | } | 937 | } |
955 | status = ocrdma_add_mmap(pd->uctx, uresp.sq_page_addr[0], | 938 | status = ocrdma_add_mmap(pd->uctx, uresp.sq_page_addr[0], |
@@ -1023,15 +1006,6 @@ static void ocrdma_set_qp_init_params(struct ocrdma_qp *qp, | |||
1023 | qp->state = OCRDMA_QPS_RST; | 1006 | qp->state = OCRDMA_QPS_RST; |
1024 | } | 1007 | } |
1025 | 1008 | ||
1026 | static void ocrdma_set_qp_use_cnt(struct ocrdma_qp *qp, struct ocrdma_pd *pd) | ||
1027 | { | ||
1028 | atomic_inc(&pd->use_cnt); | ||
1029 | atomic_inc(&qp->sq_cq->use_cnt); | ||
1030 | atomic_inc(&qp->rq_cq->use_cnt); | ||
1031 | if (qp->srq) | ||
1032 | atomic_inc(&qp->srq->use_cnt); | ||
1033 | qp->ibqp.qp_num = qp->id; | ||
1034 | } | ||
1035 | 1009 | ||
1036 | static void ocrdma_store_gsi_qp_cq(struct ocrdma_dev *dev, | 1010 | static void ocrdma_store_gsi_qp_cq(struct ocrdma_dev *dev, |
1037 | struct ib_qp_init_attr *attrs) | 1011 | struct ib_qp_init_attr *attrs) |
@@ -1099,7 +1073,7 @@ struct ib_qp *ocrdma_create_qp(struct ib_pd *ibpd, | |||
1099 | goto cpy_err; | 1073 | goto cpy_err; |
1100 | } | 1074 | } |
1101 | ocrdma_store_gsi_qp_cq(dev, attrs); | 1075 | ocrdma_store_gsi_qp_cq(dev, attrs); |
1102 | ocrdma_set_qp_use_cnt(qp, pd); | 1076 | qp->ibqp.qp_num = qp->id; |
1103 | mutex_unlock(&dev->dev_lock); | 1077 | mutex_unlock(&dev->dev_lock); |
1104 | return &qp->ibqp; | 1078 | return &qp->ibqp; |
1105 | 1079 | ||
@@ -1112,7 +1086,7 @@ mbx_err: | |||
1112 | kfree(qp->wqe_wr_id_tbl); | 1086 | kfree(qp->wqe_wr_id_tbl); |
1113 | kfree(qp->rqe_wr_id_tbl); | 1087 | kfree(qp->rqe_wr_id_tbl); |
1114 | kfree(qp); | 1088 | kfree(qp); |
1115 | ocrdma_err("%s(%d) error=%d\n", __func__, dev->id, status); | 1089 | pr_err("%s(%d) error=%d\n", __func__, dev->id, status); |
1116 | gen_err: | 1090 | gen_err: |
1117 | return ERR_PTR(status); | 1091 | return ERR_PTR(status); |
1118 | } | 1092 | } |
@@ -1162,10 +1136,10 @@ int ocrdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, | |||
1162 | spin_unlock_irqrestore(&qp->q_lock, flags); | 1136 | spin_unlock_irqrestore(&qp->q_lock, flags); |
1163 | 1137 | ||
1164 | if (!ib_modify_qp_is_ok(old_qps, new_qps, ibqp->qp_type, attr_mask)) { | 1138 | if (!ib_modify_qp_is_ok(old_qps, new_qps, ibqp->qp_type, attr_mask)) { |
1165 | ocrdma_err("%s(%d) invalid attribute mask=0x%x specified for " | 1139 | pr_err("%s(%d) invalid attribute mask=0x%x specified for\n" |
1166 | "qpn=0x%x of type=0x%x old_qps=0x%x, new_qps=0x%x\n", | 1140 | "qpn=0x%x of type=0x%x old_qps=0x%x, new_qps=0x%x\n", |
1167 | __func__, dev->id, attr_mask, qp->id, ibqp->qp_type, | 1141 | __func__, dev->id, attr_mask, qp->id, ibqp->qp_type, |
1168 | old_qps, new_qps); | 1142 | old_qps, new_qps); |
1169 | goto param_err; | 1143 | goto param_err; |
1170 | } | 1144 | } |
1171 | 1145 | ||
@@ -1475,11 +1449,6 @@ int ocrdma_destroy_qp(struct ib_qp *ibqp) | |||
1475 | 1449 | ||
1476 | ocrdma_del_flush_qp(qp); | 1450 | ocrdma_del_flush_qp(qp); |
1477 | 1451 | ||
1478 | atomic_dec(&qp->pd->use_cnt); | ||
1479 | atomic_dec(&qp->sq_cq->use_cnt); | ||
1480 | atomic_dec(&qp->rq_cq->use_cnt); | ||
1481 | if (qp->srq) | ||
1482 | atomic_dec(&qp->srq->use_cnt); | ||
1483 | kfree(qp->wqe_wr_id_tbl); | 1452 | kfree(qp->wqe_wr_id_tbl); |
1484 | kfree(qp->rqe_wr_id_tbl); | 1453 | kfree(qp->rqe_wr_id_tbl); |
1485 | kfree(qp); | 1454 | kfree(qp); |
@@ -1565,14 +1534,12 @@ struct ib_srq *ocrdma_create_srq(struct ib_pd *ibpd, | |||
1565 | goto arm_err; | 1534 | goto arm_err; |
1566 | } | 1535 | } |
1567 | 1536 | ||
1568 | atomic_set(&srq->use_cnt, 0); | ||
1569 | if (udata) { | 1537 | if (udata) { |
1570 | status = ocrdma_copy_srq_uresp(srq, udata); | 1538 | status = ocrdma_copy_srq_uresp(srq, udata); |
1571 | if (status) | 1539 | if (status) |
1572 | goto arm_err; | 1540 | goto arm_err; |
1573 | } | 1541 | } |
1574 | 1542 | ||
1575 | atomic_inc(&pd->use_cnt); | ||
1576 | return &srq->ibsrq; | 1543 | return &srq->ibsrq; |
1577 | 1544 | ||
1578 | arm_err: | 1545 | arm_err: |
@@ -1618,18 +1585,12 @@ int ocrdma_destroy_srq(struct ib_srq *ibsrq) | |||
1618 | 1585 | ||
1619 | srq = get_ocrdma_srq(ibsrq); | 1586 | srq = get_ocrdma_srq(ibsrq); |
1620 | dev = srq->dev; | 1587 | dev = srq->dev; |
1621 | if (atomic_read(&srq->use_cnt)) { | ||
1622 | ocrdma_err("%s(%d) err, srq=0x%x in use\n", | ||
1623 | __func__, dev->id, srq->id); | ||
1624 | return -EAGAIN; | ||
1625 | } | ||
1626 | 1588 | ||
1627 | status = ocrdma_mbx_destroy_srq(dev, srq); | 1589 | status = ocrdma_mbx_destroy_srq(dev, srq); |
1628 | 1590 | ||
1629 | if (srq->pd->uctx) | 1591 | if (srq->pd->uctx) |
1630 | ocrdma_del_mmap(srq->pd->uctx, (u64) srq->rq.pa, srq->rq.len); | 1592 | ocrdma_del_mmap(srq->pd->uctx, (u64) srq->rq.pa, srq->rq.len); |
1631 | 1593 | ||
1632 | atomic_dec(&srq->pd->use_cnt); | ||
1633 | kfree(srq->idx_bit_fields); | 1594 | kfree(srq->idx_bit_fields); |
1634 | kfree(srq->rqe_wr_id_tbl); | 1595 | kfree(srq->rqe_wr_id_tbl); |
1635 | kfree(srq); | 1596 | kfree(srq); |
@@ -1677,9 +1638,9 @@ static int ocrdma_build_inline_sges(struct ocrdma_qp *qp, | |||
1677 | { | 1638 | { |
1678 | if (wr->send_flags & IB_SEND_INLINE) { | 1639 | if (wr->send_flags & IB_SEND_INLINE) { |
1679 | if (wr->sg_list[0].length > qp->max_inline_data) { | 1640 | if (wr->sg_list[0].length > qp->max_inline_data) { |
1680 | ocrdma_err("%s() supported_len=0x%x," | 1641 | pr_err("%s() supported_len=0x%x,\n" |
1681 | " unspported len req=0x%x\n", __func__, | 1642 | " unspported len req=0x%x\n", __func__, |
1682 | qp->max_inline_data, wr->sg_list[0].length); | 1643 | qp->max_inline_data, wr->sg_list[0].length); |
1683 | return -EINVAL; | 1644 | return -EINVAL; |
1684 | } | 1645 | } |
1685 | memcpy(sge, | 1646 | memcpy(sge, |
@@ -1773,12 +1734,14 @@ int ocrdma_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
1773 | spin_lock_irqsave(&qp->q_lock, flags); | 1734 | spin_lock_irqsave(&qp->q_lock, flags); |
1774 | if (qp->state != OCRDMA_QPS_RTS && qp->state != OCRDMA_QPS_SQD) { | 1735 | if (qp->state != OCRDMA_QPS_RTS && qp->state != OCRDMA_QPS_SQD) { |
1775 | spin_unlock_irqrestore(&qp->q_lock, flags); | 1736 | spin_unlock_irqrestore(&qp->q_lock, flags); |
1737 | *bad_wr = wr; | ||
1776 | return -EINVAL; | 1738 | return -EINVAL; |
1777 | } | 1739 | } |
1778 | 1740 | ||
1779 | while (wr) { | 1741 | while (wr) { |
1780 | if (ocrdma_hwq_free_cnt(&qp->sq) == 0 || | 1742 | if (ocrdma_hwq_free_cnt(&qp->sq) == 0 || |
1781 | wr->num_sge > qp->sq.max_sges) { | 1743 | wr->num_sge > qp->sq.max_sges) { |
1744 | *bad_wr = wr; | ||
1782 | status = -ENOMEM; | 1745 | status = -ENOMEM; |
1783 | break; | 1746 | break; |
1784 | } | 1747 | } |
@@ -1856,7 +1819,7 @@ int ocrdma_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
1856 | 1819 | ||
1857 | static void ocrdma_ring_rq_db(struct ocrdma_qp *qp) | 1820 | static void ocrdma_ring_rq_db(struct ocrdma_qp *qp) |
1858 | { | 1821 | { |
1859 | u32 val = qp->rq.dbid | (1 << OCRDMA_GET_NUM_POSTED_SHIFT_VAL(qp)); | 1822 | u32 val = qp->rq.dbid | (1 << ocrdma_get_num_posted_shift(qp)); |
1860 | 1823 | ||
1861 | iowrite32(val, qp->rq_db); | 1824 | iowrite32(val, qp->rq_db); |
1862 | } | 1825 | } |
@@ -2094,8 +2057,8 @@ static void ocrdma_update_wc(struct ocrdma_qp *qp, struct ib_wc *ibwc, | |||
2094 | break; | 2057 | break; |
2095 | default: | 2058 | default: |
2096 | ibwc->status = IB_WC_GENERAL_ERR; | 2059 | ibwc->status = IB_WC_GENERAL_ERR; |
2097 | ocrdma_err("%s() invalid opcode received = 0x%x\n", | 2060 | pr_err("%s() invalid opcode received = 0x%x\n", |
2098 | __func__, hdr->cw & OCRDMA_WQE_OPCODE_MASK); | 2061 | __func__, hdr->cw & OCRDMA_WQE_OPCODE_MASK); |
2099 | break; | 2062 | break; |
2100 | }; | 2063 | }; |
2101 | } | 2064 | } |
diff --git a/drivers/infiniband/hw/qib/Kconfig b/drivers/infiniband/hw/qib/Kconfig index 1e603a375069..d03ca4c1ff25 100644 --- a/drivers/infiniband/hw/qib/Kconfig +++ b/drivers/infiniband/hw/qib/Kconfig | |||
@@ -5,3 +5,11 @@ config INFINIBAND_QIB | |||
5 | This is a low-level driver for Intel PCIe QLE InfiniBand host | 5 | This is a low-level driver for Intel PCIe QLE InfiniBand host |
6 | channel adapters. This driver does not support the Intel | 6 | channel adapters. This driver does not support the Intel |
7 | HyperTransport card (model QHT7140). | 7 | HyperTransport card (model QHT7140). |
8 | |||
9 | config INFINIBAND_QIB_DCA | ||
10 | bool "QIB DCA support" | ||
11 | depends on INFINIBAND_QIB && DCA && SMP && GENERIC_HARDIRQS && !(INFINIBAND_QIB=y && DCA=m) | ||
12 | default y | ||
13 | ---help--- | ||
14 | Setting this enables DCA support on some Intel chip sets | ||
15 | with the iba7322 HCA. | ||
diff --git a/drivers/infiniband/hw/qib/Makefile b/drivers/infiniband/hw/qib/Makefile index f12d7bb8b39f..57f8103e51f8 100644 --- a/drivers/infiniband/hw/qib/Makefile +++ b/drivers/infiniband/hw/qib/Makefile | |||
@@ -13,3 +13,4 @@ ib_qib-$(CONFIG_PCI_MSI) += qib_iba6120.o | |||
13 | 13 | ||
14 | ib_qib-$(CONFIG_X86_64) += qib_wc_x86_64.o | 14 | ib_qib-$(CONFIG_X86_64) += qib_wc_x86_64.o |
15 | ib_qib-$(CONFIG_PPC64) += qib_wc_ppc64.o | 15 | ib_qib-$(CONFIG_PPC64) += qib_wc_ppc64.o |
16 | ib_qib-$(CONFIG_DEBUG_FS) += qib_debugfs.o | ||
diff --git a/drivers/infiniband/hw/qib/qib.h b/drivers/infiniband/hw/qib/qib.h index 4d11575c2010..5453e2b36567 100644 --- a/drivers/infiniband/hw/qib/qib.h +++ b/drivers/infiniband/hw/qib/qib.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef _QIB_KERNEL_H | 1 | #ifndef _QIB_KERNEL_H |
2 | #define _QIB_KERNEL_H | 2 | #define _QIB_KERNEL_H |
3 | /* | 3 | /* |
4 | * Copyright (c) 2012 Intel Corporation. All rights reserved. | 4 | * Copyright (c) 2012, 2013 Intel Corporation. All rights reserved. |
5 | * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved. | 5 | * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved. |
6 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | 6 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. |
7 | * | 7 | * |
@@ -51,6 +51,7 @@ | |||
51 | #include <linux/completion.h> | 51 | #include <linux/completion.h> |
52 | #include <linux/kref.h> | 52 | #include <linux/kref.h> |
53 | #include <linux/sched.h> | 53 | #include <linux/sched.h> |
54 | #include <linux/kthread.h> | ||
54 | 55 | ||
55 | #include "qib_common.h" | 56 | #include "qib_common.h" |
56 | #include "qib_verbs.h" | 57 | #include "qib_verbs.h" |
@@ -114,6 +115,11 @@ struct qib_eep_log_mask { | |||
114 | /* | 115 | /* |
115 | * Below contains all data related to a single context (formerly called port). | 116 | * Below contains all data related to a single context (formerly called port). |
116 | */ | 117 | */ |
118 | |||
119 | #ifdef CONFIG_DEBUG_FS | ||
120 | struct qib_opcode_stats_perctx; | ||
121 | #endif | ||
122 | |||
117 | struct qib_ctxtdata { | 123 | struct qib_ctxtdata { |
118 | void **rcvegrbuf; | 124 | void **rcvegrbuf; |
119 | dma_addr_t *rcvegrbuf_phys; | 125 | dma_addr_t *rcvegrbuf_phys; |
@@ -154,6 +160,8 @@ struct qib_ctxtdata { | |||
154 | */ | 160 | */ |
155 | /* instead of calculating it */ | 161 | /* instead of calculating it */ |
156 | unsigned ctxt; | 162 | unsigned ctxt; |
163 | /* local node of context */ | ||
164 | int node_id; | ||
157 | /* non-zero if ctxt is being shared. */ | 165 | /* non-zero if ctxt is being shared. */ |
158 | u16 subctxt_cnt; | 166 | u16 subctxt_cnt; |
159 | /* non-zero if ctxt is being shared. */ | 167 | /* non-zero if ctxt is being shared. */ |
@@ -222,12 +230,15 @@ struct qib_ctxtdata { | |||
222 | u8 redirect_seq_cnt; | 230 | u8 redirect_seq_cnt; |
223 | /* ctxt rcvhdrq head offset */ | 231 | /* ctxt rcvhdrq head offset */ |
224 | u32 head; | 232 | u32 head; |
225 | u32 pkt_count; | ||
226 | /* lookaside fields */ | 233 | /* lookaside fields */ |
227 | struct qib_qp *lookaside_qp; | 234 | struct qib_qp *lookaside_qp; |
228 | u32 lookaside_qpn; | 235 | u32 lookaside_qpn; |
229 | /* QPs waiting for context processing */ | 236 | /* QPs waiting for context processing */ |
230 | struct list_head qp_wait_list; | 237 | struct list_head qp_wait_list; |
238 | #ifdef CONFIG_DEBUG_FS | ||
239 | /* verbs stats per CTX */ | ||
240 | struct qib_opcode_stats_perctx *opstats; | ||
241 | #endif | ||
231 | }; | 242 | }; |
232 | 243 | ||
233 | struct qib_sge_state; | 244 | struct qib_sge_state; |
@@ -428,9 +439,19 @@ struct qib_verbs_txreq { | |||
428 | #define ACTIVITY_TIMER 5 | 439 | #define ACTIVITY_TIMER 5 |
429 | 440 | ||
430 | #define MAX_NAME_SIZE 64 | 441 | #define MAX_NAME_SIZE 64 |
442 | |||
443 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
444 | struct qib_irq_notify; | ||
445 | #endif | ||
446 | |||
431 | struct qib_msix_entry { | 447 | struct qib_msix_entry { |
432 | struct msix_entry msix; | 448 | struct msix_entry msix; |
433 | void *arg; | 449 | void *arg; |
450 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
451 | int dca; | ||
452 | int rcv; | ||
453 | struct qib_irq_notify *notifier; | ||
454 | #endif | ||
434 | char name[MAX_NAME_SIZE]; | 455 | char name[MAX_NAME_SIZE]; |
435 | cpumask_var_t mask; | 456 | cpumask_var_t mask; |
436 | }; | 457 | }; |
@@ -828,6 +849,9 @@ struct qib_devdata { | |||
828 | struct qib_ctxtdata *); | 849 | struct qib_ctxtdata *); |
829 | void (*f_writescratch)(struct qib_devdata *, u32); | 850 | void (*f_writescratch)(struct qib_devdata *, u32); |
830 | int (*f_tempsense_rd)(struct qib_devdata *, int regnum); | 851 | int (*f_tempsense_rd)(struct qib_devdata *, int regnum); |
852 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
853 | int (*f_notify_dca)(struct qib_devdata *, unsigned long event); | ||
854 | #endif | ||
831 | 855 | ||
832 | char *boardname; /* human readable board info */ | 856 | char *boardname; /* human readable board info */ |
833 | 857 | ||
@@ -1075,6 +1099,10 @@ struct qib_devdata { | |||
1075 | u16 psxmitwait_check_rate; | 1099 | u16 psxmitwait_check_rate; |
1076 | /* high volume overflow errors defered to tasklet */ | 1100 | /* high volume overflow errors defered to tasklet */ |
1077 | struct tasklet_struct error_tasklet; | 1101 | struct tasklet_struct error_tasklet; |
1102 | /* per device cq worker */ | ||
1103 | struct kthread_worker *worker; | ||
1104 | |||
1105 | int assigned_node_id; /* NUMA node closest to HCA */ | ||
1078 | }; | 1106 | }; |
1079 | 1107 | ||
1080 | /* hol_state values */ | 1108 | /* hol_state values */ |
@@ -1154,7 +1182,7 @@ int qib_create_rcvhdrq(struct qib_devdata *, struct qib_ctxtdata *); | |||
1154 | int qib_setup_eagerbufs(struct qib_ctxtdata *); | 1182 | int qib_setup_eagerbufs(struct qib_ctxtdata *); |
1155 | void qib_set_ctxtcnt(struct qib_devdata *); | 1183 | void qib_set_ctxtcnt(struct qib_devdata *); |
1156 | int qib_create_ctxts(struct qib_devdata *dd); | 1184 | int qib_create_ctxts(struct qib_devdata *dd); |
1157 | struct qib_ctxtdata *qib_create_ctxtdata(struct qib_pportdata *, u32); | 1185 | struct qib_ctxtdata *qib_create_ctxtdata(struct qib_pportdata *, u32, int); |
1158 | void qib_init_pportdata(struct qib_pportdata *, struct qib_devdata *, u8, u8); | 1186 | void qib_init_pportdata(struct qib_pportdata *, struct qib_devdata *, u8, u8); |
1159 | void qib_free_ctxtdata(struct qib_devdata *, struct qib_ctxtdata *); | 1187 | void qib_free_ctxtdata(struct qib_devdata *, struct qib_ctxtdata *); |
1160 | 1188 | ||
@@ -1445,6 +1473,7 @@ extern unsigned qib_n_krcv_queues; | |||
1445 | extern unsigned qib_sdma_fetch_arb; | 1473 | extern unsigned qib_sdma_fetch_arb; |
1446 | extern unsigned qib_compat_ddr_negotiate; | 1474 | extern unsigned qib_compat_ddr_negotiate; |
1447 | extern int qib_special_trigger; | 1475 | extern int qib_special_trigger; |
1476 | extern unsigned qib_numa_aware; | ||
1448 | 1477 | ||
1449 | extern struct mutex qib_mutex; | 1478 | extern struct mutex qib_mutex; |
1450 | 1479 | ||
@@ -1474,27 +1503,23 @@ extern struct mutex qib_mutex; | |||
1474 | * first to avoid possible serial port delays from printk. | 1503 | * first to avoid possible serial port delays from printk. |
1475 | */ | 1504 | */ |
1476 | #define qib_early_err(dev, fmt, ...) \ | 1505 | #define qib_early_err(dev, fmt, ...) \ |
1477 | do { \ | 1506 | dev_err(dev, fmt, ##__VA_ARGS__) |
1478 | dev_err(dev, fmt, ##__VA_ARGS__); \ | ||
1479 | } while (0) | ||
1480 | 1507 | ||
1481 | #define qib_dev_err(dd, fmt, ...) \ | 1508 | #define qib_dev_err(dd, fmt, ...) \ |
1482 | do { \ | 1509 | dev_err(&(dd)->pcidev->dev, "%s: " fmt, \ |
1483 | dev_err(&(dd)->pcidev->dev, "%s: " fmt, \ | 1510 | qib_get_unit_name((dd)->unit), ##__VA_ARGS__) |
1484 | qib_get_unit_name((dd)->unit), ##__VA_ARGS__); \ | 1511 | |
1485 | } while (0) | 1512 | #define qib_dev_warn(dd, fmt, ...) \ |
1513 | dev_warn(&(dd)->pcidev->dev, "%s: " fmt, \ | ||
1514 | qib_get_unit_name((dd)->unit), ##__VA_ARGS__) | ||
1486 | 1515 | ||
1487 | #define qib_dev_porterr(dd, port, fmt, ...) \ | 1516 | #define qib_dev_porterr(dd, port, fmt, ...) \ |
1488 | do { \ | 1517 | dev_err(&(dd)->pcidev->dev, "%s: IB%u:%u " fmt, \ |
1489 | dev_err(&(dd)->pcidev->dev, "%s: IB%u:%u " fmt, \ | 1518 | qib_get_unit_name((dd)->unit), (dd)->unit, (port), \ |
1490 | qib_get_unit_name((dd)->unit), (dd)->unit, (port), \ | 1519 | ##__VA_ARGS__) |
1491 | ##__VA_ARGS__); \ | ||
1492 | } while (0) | ||
1493 | 1520 | ||
1494 | #define qib_devinfo(pcidev, fmt, ...) \ | 1521 | #define qib_devinfo(pcidev, fmt, ...) \ |
1495 | do { \ | 1522 | dev_info(&(pcidev)->dev, fmt, ##__VA_ARGS__) |
1496 | dev_info(&(pcidev)->dev, fmt, ##__VA_ARGS__); \ | ||
1497 | } while (0) | ||
1498 | 1523 | ||
1499 | /* | 1524 | /* |
1500 | * this is used for formatting hw error messages... | 1525 | * this is used for formatting hw error messages... |
diff --git a/drivers/infiniband/hw/qib/qib_common.h b/drivers/infiniband/hw/qib/qib_common.h index d39e0183ff82..4f255b723ffd 100644 --- a/drivers/infiniband/hw/qib/qib_common.h +++ b/drivers/infiniband/hw/qib/qib_common.h | |||
@@ -279,7 +279,7 @@ struct qib_base_info { | |||
279 | * may not be implemented; the user code must deal with this if it | 279 | * may not be implemented; the user code must deal with this if it |
280 | * cares, or it must abort after initialization reports the difference. | 280 | * cares, or it must abort after initialization reports the difference. |
281 | */ | 281 | */ |
282 | #define QIB_USER_SWMINOR 11 | 282 | #define QIB_USER_SWMINOR 12 |
283 | 283 | ||
284 | #define QIB_USER_SWVERSION ((QIB_USER_SWMAJOR << 16) | QIB_USER_SWMINOR) | 284 | #define QIB_USER_SWVERSION ((QIB_USER_SWMAJOR << 16) | QIB_USER_SWMINOR) |
285 | 285 | ||
diff --git a/drivers/infiniband/hw/qib/qib_cq.c b/drivers/infiniband/hw/qib/qib_cq.c index 5246aa486bbe..ab4e11cfab15 100644 --- a/drivers/infiniband/hw/qib/qib_cq.c +++ b/drivers/infiniband/hw/qib/qib_cq.c | |||
@@ -1,4 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2013 Intel Corporation. All rights reserved. | ||
2 | * Copyright (c) 2006, 2007, 2008, 2010 QLogic Corporation. All rights reserved. | 3 | * Copyright (c) 2006, 2007, 2008, 2010 QLogic Corporation. All rights reserved. |
3 | * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. | 4 | * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. |
4 | * | 5 | * |
@@ -34,8 +35,10 @@ | |||
34 | #include <linux/err.h> | 35 | #include <linux/err.h> |
35 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
36 | #include <linux/vmalloc.h> | 37 | #include <linux/vmalloc.h> |
38 | #include <linux/kthread.h> | ||
37 | 39 | ||
38 | #include "qib_verbs.h" | 40 | #include "qib_verbs.h" |
41 | #include "qib.h" | ||
39 | 42 | ||
40 | /** | 43 | /** |
41 | * qib_cq_enter - add a new entry to the completion queue | 44 | * qib_cq_enter - add a new entry to the completion queue |
@@ -102,13 +105,18 @@ void qib_cq_enter(struct qib_cq *cq, struct ib_wc *entry, int solicited) | |||
102 | if (cq->notify == IB_CQ_NEXT_COMP || | 105 | if (cq->notify == IB_CQ_NEXT_COMP || |
103 | (cq->notify == IB_CQ_SOLICITED && | 106 | (cq->notify == IB_CQ_SOLICITED && |
104 | (solicited || entry->status != IB_WC_SUCCESS))) { | 107 | (solicited || entry->status != IB_WC_SUCCESS))) { |
105 | cq->notify = IB_CQ_NONE; | 108 | struct kthread_worker *worker; |
106 | cq->triggered++; | ||
107 | /* | 109 | /* |
108 | * This will cause send_complete() to be called in | 110 | * This will cause send_complete() to be called in |
109 | * another thread. | 111 | * another thread. |
110 | */ | 112 | */ |
111 | queue_work(qib_cq_wq, &cq->comptask); | 113 | smp_rmb(); |
114 | worker = cq->dd->worker; | ||
115 | if (likely(worker)) { | ||
116 | cq->notify = IB_CQ_NONE; | ||
117 | cq->triggered++; | ||
118 | queue_kthread_work(worker, &cq->comptask); | ||
119 | } | ||
112 | } | 120 | } |
113 | 121 | ||
114 | spin_unlock_irqrestore(&cq->lock, flags); | 122 | spin_unlock_irqrestore(&cq->lock, flags); |
@@ -163,7 +171,7 @@ bail: | |||
163 | return npolled; | 171 | return npolled; |
164 | } | 172 | } |
165 | 173 | ||
166 | static void send_complete(struct work_struct *work) | 174 | static void send_complete(struct kthread_work *work) |
167 | { | 175 | { |
168 | struct qib_cq *cq = container_of(work, struct qib_cq, comptask); | 176 | struct qib_cq *cq = container_of(work, struct qib_cq, comptask); |
169 | 177 | ||
@@ -287,11 +295,12 @@ struct ib_cq *qib_create_cq(struct ib_device *ibdev, int entries, | |||
287 | * The number of entries should be >= the number requested or return | 295 | * The number of entries should be >= the number requested or return |
288 | * an error. | 296 | * an error. |
289 | */ | 297 | */ |
298 | cq->dd = dd_from_dev(dev); | ||
290 | cq->ibcq.cqe = entries; | 299 | cq->ibcq.cqe = entries; |
291 | cq->notify = IB_CQ_NONE; | 300 | cq->notify = IB_CQ_NONE; |
292 | cq->triggered = 0; | 301 | cq->triggered = 0; |
293 | spin_lock_init(&cq->lock); | 302 | spin_lock_init(&cq->lock); |
294 | INIT_WORK(&cq->comptask, send_complete); | 303 | init_kthread_work(&cq->comptask, send_complete); |
295 | wc->head = 0; | 304 | wc->head = 0; |
296 | wc->tail = 0; | 305 | wc->tail = 0; |
297 | cq->queue = wc; | 306 | cq->queue = wc; |
@@ -323,7 +332,7 @@ int qib_destroy_cq(struct ib_cq *ibcq) | |||
323 | struct qib_ibdev *dev = to_idev(ibcq->device); | 332 | struct qib_ibdev *dev = to_idev(ibcq->device); |
324 | struct qib_cq *cq = to_icq(ibcq); | 333 | struct qib_cq *cq = to_icq(ibcq); |
325 | 334 | ||
326 | flush_work(&cq->comptask); | 335 | flush_kthread_work(&cq->comptask); |
327 | spin_lock(&dev->n_cqs_lock); | 336 | spin_lock(&dev->n_cqs_lock); |
328 | dev->n_cqs_allocated--; | 337 | dev->n_cqs_allocated--; |
329 | spin_unlock(&dev->n_cqs_lock); | 338 | spin_unlock(&dev->n_cqs_lock); |
@@ -483,3 +492,49 @@ bail_free: | |||
483 | bail: | 492 | bail: |
484 | return ret; | 493 | return ret; |
485 | } | 494 | } |
495 | |||
496 | int qib_cq_init(struct qib_devdata *dd) | ||
497 | { | ||
498 | int ret = 0; | ||
499 | int cpu; | ||
500 | struct task_struct *task; | ||
501 | |||
502 | if (dd->worker) | ||
503 | return 0; | ||
504 | dd->worker = kzalloc(sizeof(*dd->worker), GFP_KERNEL); | ||
505 | if (!dd->worker) | ||
506 | return -ENOMEM; | ||
507 | init_kthread_worker(dd->worker); | ||
508 | task = kthread_create_on_node( | ||
509 | kthread_worker_fn, | ||
510 | dd->worker, | ||
511 | dd->assigned_node_id, | ||
512 | "qib_cq%d", dd->unit); | ||
513 | if (IS_ERR(task)) | ||
514 | goto task_fail; | ||
515 | cpu = cpumask_first(cpumask_of_node(dd->assigned_node_id)); | ||
516 | kthread_bind(task, cpu); | ||
517 | wake_up_process(task); | ||
518 | out: | ||
519 | return ret; | ||
520 | task_fail: | ||
521 | ret = PTR_ERR(task); | ||
522 | kfree(dd->worker); | ||
523 | dd->worker = NULL; | ||
524 | goto out; | ||
525 | } | ||
526 | |||
527 | void qib_cq_exit(struct qib_devdata *dd) | ||
528 | { | ||
529 | struct kthread_worker *worker; | ||
530 | |||
531 | worker = dd->worker; | ||
532 | if (!worker) | ||
533 | return; | ||
534 | /* blocks future queuing from send_complete() */ | ||
535 | dd->worker = NULL; | ||
536 | smp_wmb(); | ||
537 | flush_kthread_worker(worker); | ||
538 | kthread_stop(worker->task); | ||
539 | kfree(worker); | ||
540 | } | ||
diff --git a/drivers/infiniband/hw/qib/qib_debugfs.c b/drivers/infiniband/hw/qib/qib_debugfs.c new file mode 100644 index 000000000000..799a0c3bffc4 --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_debugfs.c | |||
@@ -0,0 +1,283 @@ | |||
1 | #ifdef CONFIG_DEBUG_FS | ||
2 | /* | ||
3 | * Copyright (c) 2013 Intel Corporation. All rights reserved. | ||
4 | * | ||
5 | * This software is available to you under a choice of one of two | ||
6 | * licenses. You may choose to be licensed under the terms of the GNU | ||
7 | * General Public License (GPL) Version 2, available from the file | ||
8 | * COPYING in the main directory of this source tree, or the | ||
9 | * OpenIB.org BSD license below: | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or | ||
12 | * without modification, are permitted provided that the following | ||
13 | * conditions are met: | ||
14 | * | ||
15 | * - Redistributions of source code must retain the above | ||
16 | * copyright notice, this list of conditions and the following | ||
17 | * disclaimer. | ||
18 | * | ||
19 | * - Redistributions in binary form must reproduce the above | ||
20 | * copyright notice, this list of conditions and the following | ||
21 | * disclaimer in the documentation and/or other materials | ||
22 | * provided with the distribution. | ||
23 | * | ||
24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
25 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
26 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
27 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
28 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
29 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
30 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
31 | * SOFTWARE. | ||
32 | */ | ||
33 | #include <linux/debugfs.h> | ||
34 | #include <linux/seq_file.h> | ||
35 | #include <linux/kernel.h> | ||
36 | #include <linux/export.h> | ||
37 | |||
38 | #include "qib.h" | ||
39 | #include "qib_verbs.h" | ||
40 | #include "qib_debugfs.h" | ||
41 | |||
42 | static struct dentry *qib_dbg_root; | ||
43 | |||
44 | #define DEBUGFS_FILE(name) \ | ||
45 | static const struct seq_operations _##name##_seq_ops = { \ | ||
46 | .start = _##name##_seq_start, \ | ||
47 | .next = _##name##_seq_next, \ | ||
48 | .stop = _##name##_seq_stop, \ | ||
49 | .show = _##name##_seq_show \ | ||
50 | }; \ | ||
51 | static int _##name##_open(struct inode *inode, struct file *s) \ | ||
52 | { \ | ||
53 | struct seq_file *seq; \ | ||
54 | int ret; \ | ||
55 | ret = seq_open(s, &_##name##_seq_ops); \ | ||
56 | if (ret) \ | ||
57 | return ret; \ | ||
58 | seq = s->private_data; \ | ||
59 | seq->private = inode->i_private; \ | ||
60 | return 0; \ | ||
61 | } \ | ||
62 | static const struct file_operations _##name##_file_ops = { \ | ||
63 | .owner = THIS_MODULE, \ | ||
64 | .open = _##name##_open, \ | ||
65 | .read = seq_read, \ | ||
66 | .llseek = seq_lseek, \ | ||
67 | .release = seq_release \ | ||
68 | }; | ||
69 | |||
70 | #define DEBUGFS_FILE_CREATE(name) \ | ||
71 | do { \ | ||
72 | struct dentry *ent; \ | ||
73 | ent = debugfs_create_file(#name , 0400, ibd->qib_ibdev_dbg, \ | ||
74 | ibd, &_##name##_file_ops); \ | ||
75 | if (!ent) \ | ||
76 | pr_warn("create of " #name " failed\n"); \ | ||
77 | } while (0) | ||
78 | |||
79 | static void *_opcode_stats_seq_start(struct seq_file *s, loff_t *pos) | ||
80 | { | ||
81 | struct qib_opcode_stats_perctx *opstats; | ||
82 | |||
83 | if (*pos >= ARRAY_SIZE(opstats->stats)) | ||
84 | return NULL; | ||
85 | return pos; | ||
86 | } | ||
87 | |||
88 | static void *_opcode_stats_seq_next(struct seq_file *s, void *v, loff_t *pos) | ||
89 | { | ||
90 | struct qib_opcode_stats_perctx *opstats; | ||
91 | |||
92 | ++*pos; | ||
93 | if (*pos >= ARRAY_SIZE(opstats->stats)) | ||
94 | return NULL; | ||
95 | return pos; | ||
96 | } | ||
97 | |||
98 | |||
99 | static void _opcode_stats_seq_stop(struct seq_file *s, void *v) | ||
100 | { | ||
101 | /* nothing allocated */ | ||
102 | } | ||
103 | |||
104 | static int _opcode_stats_seq_show(struct seq_file *s, void *v) | ||
105 | { | ||
106 | loff_t *spos = v; | ||
107 | loff_t i = *spos, j; | ||
108 | u64 n_packets = 0, n_bytes = 0; | ||
109 | struct qib_ibdev *ibd = (struct qib_ibdev *)s->private; | ||
110 | struct qib_devdata *dd = dd_from_dev(ibd); | ||
111 | |||
112 | for (j = 0; j < dd->first_user_ctxt; j++) { | ||
113 | if (!dd->rcd[j]) | ||
114 | continue; | ||
115 | n_packets += dd->rcd[j]->opstats->stats[i].n_packets; | ||
116 | n_bytes += dd->rcd[j]->opstats->stats[i].n_bytes; | ||
117 | } | ||
118 | if (!n_packets && !n_bytes) | ||
119 | return SEQ_SKIP; | ||
120 | seq_printf(s, "%02llx %llu/%llu\n", i, | ||
121 | (unsigned long long) n_packets, | ||
122 | (unsigned long long) n_bytes); | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | DEBUGFS_FILE(opcode_stats) | ||
128 | |||
129 | static void *_ctx_stats_seq_start(struct seq_file *s, loff_t *pos) | ||
130 | { | ||
131 | struct qib_ibdev *ibd = (struct qib_ibdev *)s->private; | ||
132 | struct qib_devdata *dd = dd_from_dev(ibd); | ||
133 | |||
134 | if (!*pos) | ||
135 | return SEQ_START_TOKEN; | ||
136 | if (*pos >= dd->first_user_ctxt) | ||
137 | return NULL; | ||
138 | return pos; | ||
139 | } | ||
140 | |||
141 | static void *_ctx_stats_seq_next(struct seq_file *s, void *v, loff_t *pos) | ||
142 | { | ||
143 | struct qib_ibdev *ibd = (struct qib_ibdev *)s->private; | ||
144 | struct qib_devdata *dd = dd_from_dev(ibd); | ||
145 | |||
146 | if (v == SEQ_START_TOKEN) | ||
147 | return pos; | ||
148 | |||
149 | ++*pos; | ||
150 | if (*pos >= dd->first_user_ctxt) | ||
151 | return NULL; | ||
152 | return pos; | ||
153 | } | ||
154 | |||
155 | static void _ctx_stats_seq_stop(struct seq_file *s, void *v) | ||
156 | { | ||
157 | /* nothing allocated */ | ||
158 | } | ||
159 | |||
160 | static int _ctx_stats_seq_show(struct seq_file *s, void *v) | ||
161 | { | ||
162 | loff_t *spos; | ||
163 | loff_t i, j; | ||
164 | u64 n_packets = 0; | ||
165 | struct qib_ibdev *ibd = (struct qib_ibdev *)s->private; | ||
166 | struct qib_devdata *dd = dd_from_dev(ibd); | ||
167 | |||
168 | if (v == SEQ_START_TOKEN) { | ||
169 | seq_puts(s, "Ctx:npkts\n"); | ||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | spos = v; | ||
174 | i = *spos; | ||
175 | |||
176 | if (!dd->rcd[i]) | ||
177 | return SEQ_SKIP; | ||
178 | |||
179 | for (j = 0; j < ARRAY_SIZE(dd->rcd[i]->opstats->stats); j++) | ||
180 | n_packets += dd->rcd[i]->opstats->stats[j].n_packets; | ||
181 | |||
182 | if (!n_packets) | ||
183 | return SEQ_SKIP; | ||
184 | |||
185 | seq_printf(s, " %llu:%llu\n", i, n_packets); | ||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | DEBUGFS_FILE(ctx_stats) | ||
190 | |||
191 | static void *_qp_stats_seq_start(struct seq_file *s, loff_t *pos) | ||
192 | { | ||
193 | struct qib_qp_iter *iter; | ||
194 | loff_t n = *pos; | ||
195 | |||
196 | iter = qib_qp_iter_init(s->private); | ||
197 | if (!iter) | ||
198 | return NULL; | ||
199 | |||
200 | while (n--) { | ||
201 | if (qib_qp_iter_next(iter)) { | ||
202 | kfree(iter); | ||
203 | return NULL; | ||
204 | } | ||
205 | } | ||
206 | |||
207 | return iter; | ||
208 | } | ||
209 | |||
210 | static void *_qp_stats_seq_next(struct seq_file *s, void *iter_ptr, | ||
211 | loff_t *pos) | ||
212 | { | ||
213 | struct qib_qp_iter *iter = iter_ptr; | ||
214 | |||
215 | (*pos)++; | ||
216 | |||
217 | if (qib_qp_iter_next(iter)) { | ||
218 | kfree(iter); | ||
219 | return NULL; | ||
220 | } | ||
221 | |||
222 | return iter; | ||
223 | } | ||
224 | |||
225 | static void _qp_stats_seq_stop(struct seq_file *s, void *iter_ptr) | ||
226 | { | ||
227 | /* nothing for now */ | ||
228 | } | ||
229 | |||
230 | static int _qp_stats_seq_show(struct seq_file *s, void *iter_ptr) | ||
231 | { | ||
232 | struct qib_qp_iter *iter = iter_ptr; | ||
233 | |||
234 | if (!iter) | ||
235 | return 0; | ||
236 | |||
237 | qib_qp_iter_print(s, iter); | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | DEBUGFS_FILE(qp_stats) | ||
243 | |||
244 | void qib_dbg_ibdev_init(struct qib_ibdev *ibd) | ||
245 | { | ||
246 | char name[10]; | ||
247 | |||
248 | snprintf(name, sizeof(name), "qib%d", dd_from_dev(ibd)->unit); | ||
249 | ibd->qib_ibdev_dbg = debugfs_create_dir(name, qib_dbg_root); | ||
250 | if (!ibd->qib_ibdev_dbg) { | ||
251 | pr_warn("create of %s failed\n", name); | ||
252 | return; | ||
253 | } | ||
254 | DEBUGFS_FILE_CREATE(opcode_stats); | ||
255 | DEBUGFS_FILE_CREATE(ctx_stats); | ||
256 | DEBUGFS_FILE_CREATE(qp_stats); | ||
257 | return; | ||
258 | } | ||
259 | |||
260 | void qib_dbg_ibdev_exit(struct qib_ibdev *ibd) | ||
261 | { | ||
262 | if (!qib_dbg_root) | ||
263 | goto out; | ||
264 | debugfs_remove_recursive(ibd->qib_ibdev_dbg); | ||
265 | out: | ||
266 | ibd->qib_ibdev_dbg = NULL; | ||
267 | } | ||
268 | |||
269 | void qib_dbg_init(void) | ||
270 | { | ||
271 | qib_dbg_root = debugfs_create_dir(QIB_DRV_NAME, NULL); | ||
272 | if (!qib_dbg_root) | ||
273 | pr_warn("init of debugfs failed\n"); | ||
274 | } | ||
275 | |||
276 | void qib_dbg_exit(void) | ||
277 | { | ||
278 | debugfs_remove_recursive(qib_dbg_root); | ||
279 | qib_dbg_root = NULL; | ||
280 | } | ||
281 | |||
282 | #endif | ||
283 | |||
diff --git a/drivers/infiniband/hw/qib/qib_debugfs.h b/drivers/infiniband/hw/qib/qib_debugfs.h new file mode 100644 index 000000000000..7ae983a91b8b --- /dev/null +++ b/drivers/infiniband/hw/qib/qib_debugfs.h | |||
@@ -0,0 +1,45 @@ | |||
1 | #ifndef _QIB_DEBUGFS_H | ||
2 | #define _QIB_DEBUGFS_H | ||
3 | |||
4 | #ifdef CONFIG_DEBUG_FS | ||
5 | /* | ||
6 | * Copyright (c) 2013 Intel Corporation. All rights reserved. | ||
7 | * | ||
8 | * This software is available to you under a choice of one of two | ||
9 | * licenses. You may choose to be licensed under the terms of the GNU | ||
10 | * General Public License (GPL) Version 2, available from the file | ||
11 | * COPYING in the main directory of this source tree, or the | ||
12 | * OpenIB.org BSD license below: | ||
13 | * | ||
14 | * Redistribution and use in source and binary forms, with or | ||
15 | * without modification, are permitted provided that the following | ||
16 | * conditions are met: | ||
17 | * | ||
18 | * - Redistributions of source code must retain the above | ||
19 | * copyright notice, this list of conditions and the following | ||
20 | * disclaimer. | ||
21 | * | ||
22 | * - Redistributions in binary form must reproduce the above | ||
23 | * copyright notice, this list of conditions and the following | ||
24 | * disclaimer in the documentation and/or other materials | ||
25 | * provided with the distribution. | ||
26 | * | ||
27 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
28 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
29 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
30 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | ||
31 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | ||
32 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
33 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
34 | * SOFTWARE. | ||
35 | */ | ||
36 | |||
37 | struct qib_ibdev; | ||
38 | void qib_dbg_ibdev_init(struct qib_ibdev *ibd); | ||
39 | void qib_dbg_ibdev_exit(struct qib_ibdev *ibd); | ||
40 | void qib_dbg_init(void); | ||
41 | void qib_dbg_exit(void); | ||
42 | |||
43 | #endif | ||
44 | |||
45 | #endif /* _QIB_DEBUGFS_H */ | ||
diff --git a/drivers/infiniband/hw/qib/qib_driver.c b/drivers/infiniband/hw/qib/qib_driver.c index 216092477dfc..5bee08f16d74 100644 --- a/drivers/infiniband/hw/qib/qib_driver.c +++ b/drivers/infiniband/hw/qib/qib_driver.c | |||
@@ -558,7 +558,6 @@ move_along: | |||
558 | } | 558 | } |
559 | 559 | ||
560 | rcd->head = l; | 560 | rcd->head = l; |
561 | rcd->pkt_count += i; | ||
562 | 561 | ||
563 | /* | 562 | /* |
564 | * Iterate over all QPs waiting to respond. | 563 | * Iterate over all QPs waiting to respond. |
diff --git a/drivers/infiniband/hw/qib/qib_file_ops.c b/drivers/infiniband/hw/qib/qib_file_ops.c index b56c9428f3c5..df3808a38381 100644 --- a/drivers/infiniband/hw/qib/qib_file_ops.c +++ b/drivers/infiniband/hw/qib/qib_file_ops.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2012 Intel Corporation. All rights reserved. | 2 | * Copyright (c) 2012, 2013 Intel Corporation. All rights reserved. |
3 | * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved. | 3 | * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved. |
4 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. | 4 | * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved. |
5 | * | 5 | * |
@@ -1155,6 +1155,49 @@ static unsigned int qib_poll(struct file *fp, struct poll_table_struct *pt) | |||
1155 | return pollflag; | 1155 | return pollflag; |
1156 | } | 1156 | } |
1157 | 1157 | ||
1158 | static void assign_ctxt_affinity(struct file *fp, struct qib_devdata *dd) | ||
1159 | { | ||
1160 | struct qib_filedata *fd = fp->private_data; | ||
1161 | const unsigned int weight = cpumask_weight(¤t->cpus_allowed); | ||
1162 | const struct cpumask *local_mask = cpumask_of_pcibus(dd->pcidev->bus); | ||
1163 | int local_cpu; | ||
1164 | |||
1165 | /* | ||
1166 | * If process has NOT already set it's affinity, select and | ||
1167 | * reserve a processor for it on the local NUMA node. | ||
1168 | */ | ||
1169 | if ((weight >= qib_cpulist_count) && | ||
1170 | (cpumask_weight(local_mask) <= qib_cpulist_count)) { | ||
1171 | for_each_cpu(local_cpu, local_mask) | ||
1172 | if (!test_and_set_bit(local_cpu, qib_cpulist)) { | ||
1173 | fd->rec_cpu_num = local_cpu; | ||
1174 | return; | ||
1175 | } | ||
1176 | } | ||
1177 | |||
1178 | /* | ||
1179 | * If process has NOT already set it's affinity, select and | ||
1180 | * reserve a processor for it, as a rendevous for all | ||
1181 | * users of the driver. If they don't actually later | ||
1182 | * set affinity to this cpu, or set it to some other cpu, | ||
1183 | * it just means that sooner or later we don't recommend | ||
1184 | * a cpu, and let the scheduler do it's best. | ||
1185 | */ | ||
1186 | if (weight >= qib_cpulist_count) { | ||
1187 | int cpu; | ||
1188 | cpu = find_first_zero_bit(qib_cpulist, | ||
1189 | qib_cpulist_count); | ||
1190 | if (cpu == qib_cpulist_count) | ||
1191 | qib_dev_err(dd, | ||
1192 | "no cpus avail for affinity PID %u\n", | ||
1193 | current->pid); | ||
1194 | else { | ||
1195 | __set_bit(cpu, qib_cpulist); | ||
1196 | fd->rec_cpu_num = cpu; | ||
1197 | } | ||
1198 | } | ||
1199 | } | ||
1200 | |||
1158 | /* | 1201 | /* |
1159 | * Check that userland and driver are compatible for subcontexts. | 1202 | * Check that userland and driver are compatible for subcontexts. |
1160 | */ | 1203 | */ |
@@ -1259,12 +1302,20 @@ bail: | |||
1259 | static int setup_ctxt(struct qib_pportdata *ppd, int ctxt, | 1302 | static int setup_ctxt(struct qib_pportdata *ppd, int ctxt, |
1260 | struct file *fp, const struct qib_user_info *uinfo) | 1303 | struct file *fp, const struct qib_user_info *uinfo) |
1261 | { | 1304 | { |
1305 | struct qib_filedata *fd = fp->private_data; | ||
1262 | struct qib_devdata *dd = ppd->dd; | 1306 | struct qib_devdata *dd = ppd->dd; |
1263 | struct qib_ctxtdata *rcd; | 1307 | struct qib_ctxtdata *rcd; |
1264 | void *ptmp = NULL; | 1308 | void *ptmp = NULL; |
1265 | int ret; | 1309 | int ret; |
1310 | int numa_id; | ||
1311 | |||
1312 | assign_ctxt_affinity(fp, dd); | ||
1266 | 1313 | ||
1267 | rcd = qib_create_ctxtdata(ppd, ctxt); | 1314 | numa_id = qib_numa_aware ? ((fd->rec_cpu_num != -1) ? |
1315 | cpu_to_node(fd->rec_cpu_num) : | ||
1316 | numa_node_id()) : dd->assigned_node_id; | ||
1317 | |||
1318 | rcd = qib_create_ctxtdata(ppd, ctxt, numa_id); | ||
1268 | 1319 | ||
1269 | /* | 1320 | /* |
1270 | * Allocate memory for use in qib_tid_update() at open to | 1321 | * Allocate memory for use in qib_tid_update() at open to |
@@ -1296,6 +1347,9 @@ static int setup_ctxt(struct qib_pportdata *ppd, int ctxt, | |||
1296 | goto bail; | 1347 | goto bail; |
1297 | 1348 | ||
1298 | bailerr: | 1349 | bailerr: |
1350 | if (fd->rec_cpu_num != -1) | ||
1351 | __clear_bit(fd->rec_cpu_num, qib_cpulist); | ||
1352 | |||
1299 | dd->rcd[ctxt] = NULL; | 1353 | dd->rcd[ctxt] = NULL; |
1300 | kfree(rcd); | 1354 | kfree(rcd); |
1301 | kfree(ptmp); | 1355 | kfree(ptmp); |
@@ -1485,6 +1539,57 @@ static int qib_open(struct inode *in, struct file *fp) | |||
1485 | return fp->private_data ? 0 : -ENOMEM; | 1539 | return fp->private_data ? 0 : -ENOMEM; |
1486 | } | 1540 | } |
1487 | 1541 | ||
1542 | static int find_hca(unsigned int cpu, int *unit) | ||
1543 | { | ||
1544 | int ret = 0, devmax, npresent, nup, ndev; | ||
1545 | |||
1546 | *unit = -1; | ||
1547 | |||
1548 | devmax = qib_count_units(&npresent, &nup); | ||
1549 | if (!npresent) { | ||
1550 | ret = -ENXIO; | ||
1551 | goto done; | ||
1552 | } | ||
1553 | if (!nup) { | ||
1554 | ret = -ENETDOWN; | ||
1555 | goto done; | ||
1556 | } | ||
1557 | for (ndev = 0; ndev < devmax; ndev++) { | ||
1558 | struct qib_devdata *dd = qib_lookup(ndev); | ||
1559 | if (dd) { | ||
1560 | if (pcibus_to_node(dd->pcidev->bus) < 0) { | ||
1561 | ret = -EINVAL; | ||
1562 | goto done; | ||
1563 | } | ||
1564 | if (cpu_to_node(cpu) == | ||
1565 | pcibus_to_node(dd->pcidev->bus)) { | ||
1566 | *unit = ndev; | ||
1567 | goto done; | ||
1568 | } | ||
1569 | } | ||
1570 | } | ||
1571 | done: | ||
1572 | return ret; | ||
1573 | } | ||
1574 | |||
1575 | static int do_qib_user_sdma_queue_create(struct file *fp) | ||
1576 | { | ||
1577 | struct qib_filedata *fd = fp->private_data; | ||
1578 | struct qib_ctxtdata *rcd = fd->rcd; | ||
1579 | struct qib_devdata *dd = rcd->dd; | ||
1580 | |||
1581 | if (dd->flags & QIB_HAS_SEND_DMA) | ||
1582 | |||
1583 | fd->pq = qib_user_sdma_queue_create(&dd->pcidev->dev, | ||
1584 | dd->unit, | ||
1585 | rcd->ctxt, | ||
1586 | fd->subctxt); | ||
1587 | if (!fd->pq) | ||
1588 | return -ENOMEM; | ||
1589 | |||
1590 | return 0; | ||
1591 | } | ||
1592 | |||
1488 | /* | 1593 | /* |
1489 | * Get ctxt early, so can set affinity prior to memory allocation. | 1594 | * Get ctxt early, so can set affinity prior to memory allocation. |
1490 | */ | 1595 | */ |
@@ -1517,61 +1622,36 @@ static int qib_assign_ctxt(struct file *fp, const struct qib_user_info *uinfo) | |||
1517 | if (qib_compatible_subctxts(swmajor, swminor) && | 1622 | if (qib_compatible_subctxts(swmajor, swminor) && |
1518 | uinfo->spu_subctxt_cnt) { | 1623 | uinfo->spu_subctxt_cnt) { |
1519 | ret = find_shared_ctxt(fp, uinfo); | 1624 | ret = find_shared_ctxt(fp, uinfo); |
1520 | if (ret) { | 1625 | if (ret > 0) { |
1521 | if (ret > 0) | 1626 | ret = do_qib_user_sdma_queue_create(fp); |
1522 | ret = 0; | 1627 | if (!ret) |
1523 | goto done_chk_sdma; | 1628 | assign_ctxt_affinity(fp, (ctxt_fp(fp))->dd); |
1629 | goto done_ok; | ||
1524 | } | 1630 | } |
1525 | } | 1631 | } |
1526 | 1632 | ||
1527 | i_minor = iminor(file_inode(fp)) - QIB_USER_MINOR_BASE; | 1633 | i_minor = iminor(file_inode(fp)) - QIB_USER_MINOR_BASE; |
1528 | if (i_minor) | 1634 | if (i_minor) |
1529 | ret = find_free_ctxt(i_minor - 1, fp, uinfo); | 1635 | ret = find_free_ctxt(i_minor - 1, fp, uinfo); |
1530 | else | 1636 | else { |
1637 | int unit; | ||
1638 | const unsigned int cpu = cpumask_first(¤t->cpus_allowed); | ||
1639 | const unsigned int weight = | ||
1640 | cpumask_weight(¤t->cpus_allowed); | ||
1641 | |||
1642 | if (weight == 1 && !test_bit(cpu, qib_cpulist)) | ||
1643 | if (!find_hca(cpu, &unit) && unit >= 0) | ||
1644 | if (!find_free_ctxt(unit, fp, uinfo)) { | ||
1645 | ret = 0; | ||
1646 | goto done_chk_sdma; | ||
1647 | } | ||
1531 | ret = get_a_ctxt(fp, uinfo, alg); | 1648 | ret = get_a_ctxt(fp, uinfo, alg); |
1532 | |||
1533 | done_chk_sdma: | ||
1534 | if (!ret) { | ||
1535 | struct qib_filedata *fd = fp->private_data; | ||
1536 | const struct qib_ctxtdata *rcd = fd->rcd; | ||
1537 | const struct qib_devdata *dd = rcd->dd; | ||
1538 | unsigned int weight; | ||
1539 | |||
1540 | if (dd->flags & QIB_HAS_SEND_DMA) { | ||
1541 | fd->pq = qib_user_sdma_queue_create(&dd->pcidev->dev, | ||
1542 | dd->unit, | ||
1543 | rcd->ctxt, | ||
1544 | fd->subctxt); | ||
1545 | if (!fd->pq) | ||
1546 | ret = -ENOMEM; | ||
1547 | } | ||
1548 | |||
1549 | /* | ||
1550 | * If process has NOT already set it's affinity, select and | ||
1551 | * reserve a processor for it, as a rendezvous for all | ||
1552 | * users of the driver. If they don't actually later | ||
1553 | * set affinity to this cpu, or set it to some other cpu, | ||
1554 | * it just means that sooner or later we don't recommend | ||
1555 | * a cpu, and let the scheduler do it's best. | ||
1556 | */ | ||
1557 | weight = cpumask_weight(tsk_cpus_allowed(current)); | ||
1558 | if (!ret && weight >= qib_cpulist_count) { | ||
1559 | int cpu; | ||
1560 | cpu = find_first_zero_bit(qib_cpulist, | ||
1561 | qib_cpulist_count); | ||
1562 | if (cpu != qib_cpulist_count) { | ||
1563 | __set_bit(cpu, qib_cpulist); | ||
1564 | fd->rec_cpu_num = cpu; | ||
1565 | } | ||
1566 | } else if (weight == 1 && | ||
1567 | test_bit(cpumask_first(tsk_cpus_allowed(current)), | ||
1568 | qib_cpulist)) | ||
1569 | qib_devinfo(dd->pcidev, | ||
1570 | "%s PID %u affinity set to cpu %d; already allocated\n", | ||
1571 | current->comm, current->pid, | ||
1572 | cpumask_first(tsk_cpus_allowed(current))); | ||
1573 | } | 1649 | } |
1574 | 1650 | ||
1651 | done_chk_sdma: | ||
1652 | if (!ret) | ||
1653 | ret = do_qib_user_sdma_queue_create(fp); | ||
1654 | done_ok: | ||
1575 | mutex_unlock(&qib_mutex); | 1655 | mutex_unlock(&qib_mutex); |
1576 | 1656 | ||
1577 | done: | 1657 | done: |
diff --git a/drivers/infiniband/hw/qib/qib_iba6120.c b/drivers/infiniband/hw/qib/qib_iba6120.c index 0232ae56b1fa..84e593d6007b 100644 --- a/drivers/infiniband/hw/qib/qib_iba6120.c +++ b/drivers/infiniband/hw/qib/qib_iba6120.c | |||
@@ -3464,6 +3464,13 @@ static int qib_6120_tempsense_rd(struct qib_devdata *dd, int regnum) | |||
3464 | return -ENXIO; | 3464 | return -ENXIO; |
3465 | } | 3465 | } |
3466 | 3466 | ||
3467 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
3468 | static int qib_6120_notify_dca(struct qib_devdata *dd, unsigned long event) | ||
3469 | { | ||
3470 | return 0; | ||
3471 | } | ||
3472 | #endif | ||
3473 | |||
3467 | /* Dummy function, as 6120 boards never disable EEPROM Write */ | 3474 | /* Dummy function, as 6120 boards never disable EEPROM Write */ |
3468 | static int qib_6120_eeprom_wen(struct qib_devdata *dd, int wen) | 3475 | static int qib_6120_eeprom_wen(struct qib_devdata *dd, int wen) |
3469 | { | 3476 | { |
@@ -3539,6 +3546,9 @@ struct qib_devdata *qib_init_iba6120_funcs(struct pci_dev *pdev, | |||
3539 | dd->f_xgxs_reset = qib_6120_xgxs_reset; | 3546 | dd->f_xgxs_reset = qib_6120_xgxs_reset; |
3540 | dd->f_writescratch = writescratch; | 3547 | dd->f_writescratch = writescratch; |
3541 | dd->f_tempsense_rd = qib_6120_tempsense_rd; | 3548 | dd->f_tempsense_rd = qib_6120_tempsense_rd; |
3549 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
3550 | dd->f_notify_dca = qib_6120_notify_dca; | ||
3551 | #endif | ||
3542 | /* | 3552 | /* |
3543 | * Do remaining pcie setup and save pcie values in dd. | 3553 | * Do remaining pcie setup and save pcie values in dd. |
3544 | * Any error printing is already done by the init code. | 3554 | * Any error printing is already done by the init code. |
diff --git a/drivers/infiniband/hw/qib/qib_iba7220.c b/drivers/infiniband/hw/qib/qib_iba7220.c index 64d0ecb90cdc..454c2e7668fe 100644 --- a/drivers/infiniband/hw/qib/qib_iba7220.c +++ b/drivers/infiniband/hw/qib/qib_iba7220.c | |||
@@ -4513,6 +4513,13 @@ bail: | |||
4513 | return ret; | 4513 | return ret; |
4514 | } | 4514 | } |
4515 | 4515 | ||
4516 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
4517 | static int qib_7220_notify_dca(struct qib_devdata *dd, unsigned long event) | ||
4518 | { | ||
4519 | return 0; | ||
4520 | } | ||
4521 | #endif | ||
4522 | |||
4516 | /* Dummy function, as 7220 boards never disable EEPROM Write */ | 4523 | /* Dummy function, as 7220 boards never disable EEPROM Write */ |
4517 | static int qib_7220_eeprom_wen(struct qib_devdata *dd, int wen) | 4524 | static int qib_7220_eeprom_wen(struct qib_devdata *dd, int wen) |
4518 | { | 4525 | { |
@@ -4587,6 +4594,9 @@ struct qib_devdata *qib_init_iba7220_funcs(struct pci_dev *pdev, | |||
4587 | dd->f_xgxs_reset = qib_7220_xgxs_reset; | 4594 | dd->f_xgxs_reset = qib_7220_xgxs_reset; |
4588 | dd->f_writescratch = writescratch; | 4595 | dd->f_writescratch = writescratch; |
4589 | dd->f_tempsense_rd = qib_7220_tempsense_rd; | 4596 | dd->f_tempsense_rd = qib_7220_tempsense_rd; |
4597 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
4598 | dd->f_notify_dca = qib_7220_notify_dca; | ||
4599 | #endif | ||
4590 | /* | 4600 | /* |
4591 | * Do remaining pcie setup and save pcie values in dd. | 4601 | * Do remaining pcie setup and save pcie values in dd. |
4592 | * Any error printing is already done by the init code. | 4602 | * Any error printing is already done by the init code. |
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index 3f6b21e9dc11..f7c4b44b1f93 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c | |||
@@ -44,6 +44,9 @@ | |||
44 | #include <linux/module.h> | 44 | #include <linux/module.h> |
45 | #include <rdma/ib_verbs.h> | 45 | #include <rdma/ib_verbs.h> |
46 | #include <rdma/ib_smi.h> | 46 | #include <rdma/ib_smi.h> |
47 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
48 | #include <linux/dca.h> | ||
49 | #endif | ||
47 | 50 | ||
48 | #include "qib.h" | 51 | #include "qib.h" |
49 | #include "qib_7322_regs.h" | 52 | #include "qib_7322_regs.h" |
@@ -519,6 +522,14 @@ static const u8 qib_7322_physportstate[0x20] = { | |||
519 | [0x17] = IB_PHYSPORTSTATE_CFG_TRAIN | 522 | [0x17] = IB_PHYSPORTSTATE_CFG_TRAIN |
520 | }; | 523 | }; |
521 | 524 | ||
525 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
526 | struct qib_irq_notify { | ||
527 | int rcv; | ||
528 | void *arg; | ||
529 | struct irq_affinity_notify notify; | ||
530 | }; | ||
531 | #endif | ||
532 | |||
522 | struct qib_chip_specific { | 533 | struct qib_chip_specific { |
523 | u64 __iomem *cregbase; | 534 | u64 __iomem *cregbase; |
524 | u64 *cntrs; | 535 | u64 *cntrs; |
@@ -546,6 +557,12 @@ struct qib_chip_specific { | |||
546 | u32 lastbuf_for_pio; | 557 | u32 lastbuf_for_pio; |
547 | u32 stay_in_freeze; | 558 | u32 stay_in_freeze; |
548 | u32 recovery_ports_initted; | 559 | u32 recovery_ports_initted; |
560 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
561 | u32 dca_ctrl; | ||
562 | int rhdr_cpu[18]; | ||
563 | int sdma_cpu[2]; | ||
564 | u64 dca_rcvhdr_ctrl[5]; /* B, C, D, E, F */ | ||
565 | #endif | ||
549 | struct qib_msix_entry *msix_entries; | 566 | struct qib_msix_entry *msix_entries; |
550 | unsigned long *sendchkenable; | 567 | unsigned long *sendchkenable; |
551 | unsigned long *sendgrhchk; | 568 | unsigned long *sendgrhchk; |
@@ -573,7 +590,7 @@ struct vendor_txdds_ent { | |||
573 | static void write_tx_serdes_param(struct qib_pportdata *, struct txdds_ent *); | 590 | static void write_tx_serdes_param(struct qib_pportdata *, struct txdds_ent *); |
574 | 591 | ||
575 | #define TXDDS_TABLE_SZ 16 /* number of entries per speed in onchip table */ | 592 | #define TXDDS_TABLE_SZ 16 /* number of entries per speed in onchip table */ |
576 | #define TXDDS_EXTRA_SZ 13 /* number of extra tx settings entries */ | 593 | #define TXDDS_EXTRA_SZ 18 /* number of extra tx settings entries */ |
577 | #define TXDDS_MFG_SZ 2 /* number of mfg tx settings entries */ | 594 | #define TXDDS_MFG_SZ 2 /* number of mfg tx settings entries */ |
578 | #define SERDES_CHANS 4 /* yes, it's obvious, but one less magic number */ | 595 | #define SERDES_CHANS 4 /* yes, it's obvious, but one less magic number */ |
579 | 596 | ||
@@ -642,28 +659,76 @@ static struct { | |||
642 | irq_handler_t handler; | 659 | irq_handler_t handler; |
643 | int lsb; | 660 | int lsb; |
644 | int port; /* 0 if not port-specific, else port # */ | 661 | int port; /* 0 if not port-specific, else port # */ |
662 | int dca; | ||
645 | } irq_table[] = { | 663 | } irq_table[] = { |
646 | { "", qib_7322intr, -1, 0 }, | 664 | { "", qib_7322intr, -1, 0, 0 }, |
647 | { " (buf avail)", qib_7322bufavail, | 665 | { " (buf avail)", qib_7322bufavail, |
648 | SYM_LSB(IntStatus, SendBufAvail), 0 }, | 666 | SYM_LSB(IntStatus, SendBufAvail), 0, 0}, |
649 | { " (sdma 0)", sdma_intr, | 667 | { " (sdma 0)", sdma_intr, |
650 | SYM_LSB(IntStatus, SDmaInt_0), 1 }, | 668 | SYM_LSB(IntStatus, SDmaInt_0), 1, 1 }, |
651 | { " (sdma 1)", sdma_intr, | 669 | { " (sdma 1)", sdma_intr, |
652 | SYM_LSB(IntStatus, SDmaInt_1), 2 }, | 670 | SYM_LSB(IntStatus, SDmaInt_1), 2, 1 }, |
653 | { " (sdmaI 0)", sdma_idle_intr, | 671 | { " (sdmaI 0)", sdma_idle_intr, |
654 | SYM_LSB(IntStatus, SDmaIdleInt_0), 1 }, | 672 | SYM_LSB(IntStatus, SDmaIdleInt_0), 1, 1}, |
655 | { " (sdmaI 1)", sdma_idle_intr, | 673 | { " (sdmaI 1)", sdma_idle_intr, |
656 | SYM_LSB(IntStatus, SDmaIdleInt_1), 2 }, | 674 | SYM_LSB(IntStatus, SDmaIdleInt_1), 2, 1}, |
657 | { " (sdmaP 0)", sdma_progress_intr, | 675 | { " (sdmaP 0)", sdma_progress_intr, |
658 | SYM_LSB(IntStatus, SDmaProgressInt_0), 1 }, | 676 | SYM_LSB(IntStatus, SDmaProgressInt_0), 1, 1 }, |
659 | { " (sdmaP 1)", sdma_progress_intr, | 677 | { " (sdmaP 1)", sdma_progress_intr, |
660 | SYM_LSB(IntStatus, SDmaProgressInt_1), 2 }, | 678 | SYM_LSB(IntStatus, SDmaProgressInt_1), 2, 1 }, |
661 | { " (sdmaC 0)", sdma_cleanup_intr, | 679 | { " (sdmaC 0)", sdma_cleanup_intr, |
662 | SYM_LSB(IntStatus, SDmaCleanupDone_0), 1 }, | 680 | SYM_LSB(IntStatus, SDmaCleanupDone_0), 1, 0 }, |
663 | { " (sdmaC 1)", sdma_cleanup_intr, | 681 | { " (sdmaC 1)", sdma_cleanup_intr, |
664 | SYM_LSB(IntStatus, SDmaCleanupDone_1), 2 }, | 682 | SYM_LSB(IntStatus, SDmaCleanupDone_1), 2 , 0}, |
665 | }; | 683 | }; |
666 | 684 | ||
685 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
686 | |||
687 | static const struct dca_reg_map { | ||
688 | int shadow_inx; | ||
689 | int lsb; | ||
690 | u64 mask; | ||
691 | u16 regno; | ||
692 | } dca_rcvhdr_reg_map[] = { | ||
693 | { 0, SYM_LSB(DCACtrlB, RcvHdrq0DCAOPH), | ||
694 | ~SYM_MASK(DCACtrlB, RcvHdrq0DCAOPH) , KREG_IDX(DCACtrlB) }, | ||
695 | { 0, SYM_LSB(DCACtrlB, RcvHdrq1DCAOPH), | ||
696 | ~SYM_MASK(DCACtrlB, RcvHdrq1DCAOPH) , KREG_IDX(DCACtrlB) }, | ||
697 | { 0, SYM_LSB(DCACtrlB, RcvHdrq2DCAOPH), | ||
698 | ~SYM_MASK(DCACtrlB, RcvHdrq2DCAOPH) , KREG_IDX(DCACtrlB) }, | ||
699 | { 0, SYM_LSB(DCACtrlB, RcvHdrq3DCAOPH), | ||
700 | ~SYM_MASK(DCACtrlB, RcvHdrq3DCAOPH) , KREG_IDX(DCACtrlB) }, | ||
701 | { 1, SYM_LSB(DCACtrlC, RcvHdrq4DCAOPH), | ||
702 | ~SYM_MASK(DCACtrlC, RcvHdrq4DCAOPH) , KREG_IDX(DCACtrlC) }, | ||
703 | { 1, SYM_LSB(DCACtrlC, RcvHdrq5DCAOPH), | ||
704 | ~SYM_MASK(DCACtrlC, RcvHdrq5DCAOPH) , KREG_IDX(DCACtrlC) }, | ||
705 | { 1, SYM_LSB(DCACtrlC, RcvHdrq6DCAOPH), | ||
706 | ~SYM_MASK(DCACtrlC, RcvHdrq6DCAOPH) , KREG_IDX(DCACtrlC) }, | ||
707 | { 1, SYM_LSB(DCACtrlC, RcvHdrq7DCAOPH), | ||
708 | ~SYM_MASK(DCACtrlC, RcvHdrq7DCAOPH) , KREG_IDX(DCACtrlC) }, | ||
709 | { 2, SYM_LSB(DCACtrlD, RcvHdrq8DCAOPH), | ||
710 | ~SYM_MASK(DCACtrlD, RcvHdrq8DCAOPH) , KREG_IDX(DCACtrlD) }, | ||
711 | { 2, SYM_LSB(DCACtrlD, RcvHdrq9DCAOPH), | ||
712 | ~SYM_MASK(DCACtrlD, RcvHdrq9DCAOPH) , KREG_IDX(DCACtrlD) }, | ||
713 | { 2, SYM_LSB(DCACtrlD, RcvHdrq10DCAOPH), | ||
714 | ~SYM_MASK(DCACtrlD, RcvHdrq10DCAOPH) , KREG_IDX(DCACtrlD) }, | ||
715 | { 2, SYM_LSB(DCACtrlD, RcvHdrq11DCAOPH), | ||
716 | ~SYM_MASK(DCACtrlD, RcvHdrq11DCAOPH) , KREG_IDX(DCACtrlD) }, | ||
717 | { 3, SYM_LSB(DCACtrlE, RcvHdrq12DCAOPH), | ||
718 | ~SYM_MASK(DCACtrlE, RcvHdrq12DCAOPH) , KREG_IDX(DCACtrlE) }, | ||
719 | { 3, SYM_LSB(DCACtrlE, RcvHdrq13DCAOPH), | ||
720 | ~SYM_MASK(DCACtrlE, RcvHdrq13DCAOPH) , KREG_IDX(DCACtrlE) }, | ||
721 | { 3, SYM_LSB(DCACtrlE, RcvHdrq14DCAOPH), | ||
722 | ~SYM_MASK(DCACtrlE, RcvHdrq14DCAOPH) , KREG_IDX(DCACtrlE) }, | ||
723 | { 3, SYM_LSB(DCACtrlE, RcvHdrq15DCAOPH), | ||
724 | ~SYM_MASK(DCACtrlE, RcvHdrq15DCAOPH) , KREG_IDX(DCACtrlE) }, | ||
725 | { 4, SYM_LSB(DCACtrlF, RcvHdrq16DCAOPH), | ||
726 | ~SYM_MASK(DCACtrlF, RcvHdrq16DCAOPH) , KREG_IDX(DCACtrlF) }, | ||
727 | { 4, SYM_LSB(DCACtrlF, RcvHdrq17DCAOPH), | ||
728 | ~SYM_MASK(DCACtrlF, RcvHdrq17DCAOPH) , KREG_IDX(DCACtrlF) }, | ||
729 | }; | ||
730 | #endif | ||
731 | |||
667 | /* ibcctrl bits */ | 732 | /* ibcctrl bits */ |
668 | #define QLOGIC_IB_IBCC_LINKINITCMD_DISABLE 1 | 733 | #define QLOGIC_IB_IBCC_LINKINITCMD_DISABLE 1 |
669 | /* cycle through TS1/TS2 till OK */ | 734 | /* cycle through TS1/TS2 till OK */ |
@@ -686,6 +751,13 @@ static void write_7322_init_portregs(struct qib_pportdata *); | |||
686 | static void setup_7322_link_recovery(struct qib_pportdata *, u32); | 751 | static void setup_7322_link_recovery(struct qib_pportdata *, u32); |
687 | static void check_7322_rxe_status(struct qib_pportdata *); | 752 | static void check_7322_rxe_status(struct qib_pportdata *); |
688 | static u32 __iomem *qib_7322_getsendbuf(struct qib_pportdata *, u64, u32 *); | 753 | static u32 __iomem *qib_7322_getsendbuf(struct qib_pportdata *, u64, u32 *); |
754 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
755 | static void qib_setup_dca(struct qib_devdata *dd); | ||
756 | static void setup_dca_notifier(struct qib_devdata *dd, | ||
757 | struct qib_msix_entry *m); | ||
758 | static void reset_dca_notifier(struct qib_devdata *dd, | ||
759 | struct qib_msix_entry *m); | ||
760 | #endif | ||
689 | 761 | ||
690 | /** | 762 | /** |
691 | * qib_read_ureg32 - read 32-bit virtualized per-context register | 763 | * qib_read_ureg32 - read 32-bit virtualized per-context register |
@@ -2558,6 +2630,162 @@ static void qib_setup_7322_setextled(struct qib_pportdata *ppd, u32 on) | |||
2558 | qib_write_kreg_port(ppd, krp_rcvpktledcnt, ledblink); | 2630 | qib_write_kreg_port(ppd, krp_rcvpktledcnt, ledblink); |
2559 | } | 2631 | } |
2560 | 2632 | ||
2633 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
2634 | |||
2635 | static int qib_7322_notify_dca(struct qib_devdata *dd, unsigned long event) | ||
2636 | { | ||
2637 | switch (event) { | ||
2638 | case DCA_PROVIDER_ADD: | ||
2639 | if (dd->flags & QIB_DCA_ENABLED) | ||
2640 | break; | ||
2641 | if (!dca_add_requester(&dd->pcidev->dev)) { | ||
2642 | qib_devinfo(dd->pcidev, "DCA enabled\n"); | ||
2643 | dd->flags |= QIB_DCA_ENABLED; | ||
2644 | qib_setup_dca(dd); | ||
2645 | } | ||
2646 | break; | ||
2647 | case DCA_PROVIDER_REMOVE: | ||
2648 | if (dd->flags & QIB_DCA_ENABLED) { | ||
2649 | dca_remove_requester(&dd->pcidev->dev); | ||
2650 | dd->flags &= ~QIB_DCA_ENABLED; | ||
2651 | dd->cspec->dca_ctrl = 0; | ||
2652 | qib_write_kreg(dd, KREG_IDX(DCACtrlA), | ||
2653 | dd->cspec->dca_ctrl); | ||
2654 | } | ||
2655 | break; | ||
2656 | } | ||
2657 | return 0; | ||
2658 | } | ||
2659 | |||
2660 | static void qib_update_rhdrq_dca(struct qib_ctxtdata *rcd, int cpu) | ||
2661 | { | ||
2662 | struct qib_devdata *dd = rcd->dd; | ||
2663 | struct qib_chip_specific *cspec = dd->cspec; | ||
2664 | |||
2665 | if (!(dd->flags & QIB_DCA_ENABLED)) | ||
2666 | return; | ||
2667 | if (cspec->rhdr_cpu[rcd->ctxt] != cpu) { | ||
2668 | const struct dca_reg_map *rmp; | ||
2669 | |||
2670 | cspec->rhdr_cpu[rcd->ctxt] = cpu; | ||
2671 | rmp = &dca_rcvhdr_reg_map[rcd->ctxt]; | ||
2672 | cspec->dca_rcvhdr_ctrl[rmp->shadow_inx] &= rmp->mask; | ||
2673 | cspec->dca_rcvhdr_ctrl[rmp->shadow_inx] |= | ||
2674 | (u64) dca3_get_tag(&dd->pcidev->dev, cpu) << rmp->lsb; | ||
2675 | qib_devinfo(dd->pcidev, | ||
2676 | "Ctxt %d cpu %d dca %llx\n", rcd->ctxt, cpu, | ||
2677 | (long long) cspec->dca_rcvhdr_ctrl[rmp->shadow_inx]); | ||
2678 | qib_write_kreg(dd, rmp->regno, | ||
2679 | cspec->dca_rcvhdr_ctrl[rmp->shadow_inx]); | ||
2680 | cspec->dca_ctrl |= SYM_MASK(DCACtrlA, RcvHdrqDCAEnable); | ||
2681 | qib_write_kreg(dd, KREG_IDX(DCACtrlA), cspec->dca_ctrl); | ||
2682 | } | ||
2683 | } | ||
2684 | |||
2685 | static void qib_update_sdma_dca(struct qib_pportdata *ppd, int cpu) | ||
2686 | { | ||
2687 | struct qib_devdata *dd = ppd->dd; | ||
2688 | struct qib_chip_specific *cspec = dd->cspec; | ||
2689 | unsigned pidx = ppd->port - 1; | ||
2690 | |||
2691 | if (!(dd->flags & QIB_DCA_ENABLED)) | ||
2692 | return; | ||
2693 | if (cspec->sdma_cpu[pidx] != cpu) { | ||
2694 | cspec->sdma_cpu[pidx] = cpu; | ||
2695 | cspec->dca_rcvhdr_ctrl[4] &= ~(ppd->hw_pidx ? | ||
2696 | SYM_MASK(DCACtrlF, SendDma1DCAOPH) : | ||
2697 | SYM_MASK(DCACtrlF, SendDma0DCAOPH)); | ||
2698 | cspec->dca_rcvhdr_ctrl[4] |= | ||
2699 | (u64) dca3_get_tag(&dd->pcidev->dev, cpu) << | ||
2700 | (ppd->hw_pidx ? | ||
2701 | SYM_LSB(DCACtrlF, SendDma1DCAOPH) : | ||
2702 | SYM_LSB(DCACtrlF, SendDma0DCAOPH)); | ||
2703 | qib_devinfo(dd->pcidev, | ||
2704 | "sdma %d cpu %d dca %llx\n", ppd->hw_pidx, cpu, | ||
2705 | (long long) cspec->dca_rcvhdr_ctrl[4]); | ||
2706 | qib_write_kreg(dd, KREG_IDX(DCACtrlF), | ||
2707 | cspec->dca_rcvhdr_ctrl[4]); | ||
2708 | cspec->dca_ctrl |= ppd->hw_pidx ? | ||
2709 | SYM_MASK(DCACtrlA, SendDMAHead1DCAEnable) : | ||
2710 | SYM_MASK(DCACtrlA, SendDMAHead0DCAEnable); | ||
2711 | qib_write_kreg(dd, KREG_IDX(DCACtrlA), cspec->dca_ctrl); | ||
2712 | } | ||
2713 | } | ||
2714 | |||
2715 | static void qib_setup_dca(struct qib_devdata *dd) | ||
2716 | { | ||
2717 | struct qib_chip_specific *cspec = dd->cspec; | ||
2718 | int i; | ||
2719 | |||
2720 | for (i = 0; i < ARRAY_SIZE(cspec->rhdr_cpu); i++) | ||
2721 | cspec->rhdr_cpu[i] = -1; | ||
2722 | for (i = 0; i < ARRAY_SIZE(cspec->sdma_cpu); i++) | ||
2723 | cspec->sdma_cpu[i] = -1; | ||
2724 | cspec->dca_rcvhdr_ctrl[0] = | ||
2725 | (1ULL << SYM_LSB(DCACtrlB, RcvHdrq0DCAXfrCnt)) | | ||
2726 | (1ULL << SYM_LSB(DCACtrlB, RcvHdrq1DCAXfrCnt)) | | ||
2727 | (1ULL << SYM_LSB(DCACtrlB, RcvHdrq2DCAXfrCnt)) | | ||
2728 | (1ULL << SYM_LSB(DCACtrlB, RcvHdrq3DCAXfrCnt)); | ||
2729 | cspec->dca_rcvhdr_ctrl[1] = | ||
2730 | (1ULL << SYM_LSB(DCACtrlC, RcvHdrq4DCAXfrCnt)) | | ||
2731 | (1ULL << SYM_LSB(DCACtrlC, RcvHdrq5DCAXfrCnt)) | | ||
2732 | (1ULL << SYM_LSB(DCACtrlC, RcvHdrq6DCAXfrCnt)) | | ||
2733 | (1ULL << SYM_LSB(DCACtrlC, RcvHdrq7DCAXfrCnt)); | ||
2734 | cspec->dca_rcvhdr_ctrl[2] = | ||
2735 | (1ULL << SYM_LSB(DCACtrlD, RcvHdrq8DCAXfrCnt)) | | ||
2736 | (1ULL << SYM_LSB(DCACtrlD, RcvHdrq9DCAXfrCnt)) | | ||
2737 | (1ULL << SYM_LSB(DCACtrlD, RcvHdrq10DCAXfrCnt)) | | ||
2738 | (1ULL << SYM_LSB(DCACtrlD, RcvHdrq11DCAXfrCnt)); | ||
2739 | cspec->dca_rcvhdr_ctrl[3] = | ||
2740 | (1ULL << SYM_LSB(DCACtrlE, RcvHdrq12DCAXfrCnt)) | | ||
2741 | (1ULL << SYM_LSB(DCACtrlE, RcvHdrq13DCAXfrCnt)) | | ||
2742 | (1ULL << SYM_LSB(DCACtrlE, RcvHdrq14DCAXfrCnt)) | | ||
2743 | (1ULL << SYM_LSB(DCACtrlE, RcvHdrq15DCAXfrCnt)); | ||
2744 | cspec->dca_rcvhdr_ctrl[4] = | ||
2745 | (1ULL << SYM_LSB(DCACtrlF, RcvHdrq16DCAXfrCnt)) | | ||
2746 | (1ULL << SYM_LSB(DCACtrlF, RcvHdrq17DCAXfrCnt)); | ||
2747 | for (i = 0; i < ARRAY_SIZE(cspec->sdma_cpu); i++) | ||
2748 | qib_write_kreg(dd, KREG_IDX(DCACtrlB) + i, | ||
2749 | cspec->dca_rcvhdr_ctrl[i]); | ||
2750 | for (i = 0; i < cspec->num_msix_entries; i++) | ||
2751 | setup_dca_notifier(dd, &cspec->msix_entries[i]); | ||
2752 | } | ||
2753 | |||
2754 | static void qib_irq_notifier_notify(struct irq_affinity_notify *notify, | ||
2755 | const cpumask_t *mask) | ||
2756 | { | ||
2757 | struct qib_irq_notify *n = | ||
2758 | container_of(notify, struct qib_irq_notify, notify); | ||
2759 | int cpu = cpumask_first(mask); | ||
2760 | |||
2761 | if (n->rcv) { | ||
2762 | struct qib_ctxtdata *rcd = (struct qib_ctxtdata *)n->arg; | ||
2763 | qib_update_rhdrq_dca(rcd, cpu); | ||
2764 | } else { | ||
2765 | struct qib_pportdata *ppd = (struct qib_pportdata *)n->arg; | ||
2766 | qib_update_sdma_dca(ppd, cpu); | ||
2767 | } | ||
2768 | } | ||
2769 | |||
2770 | static void qib_irq_notifier_release(struct kref *ref) | ||
2771 | { | ||
2772 | struct qib_irq_notify *n = | ||
2773 | container_of(ref, struct qib_irq_notify, notify.kref); | ||
2774 | struct qib_devdata *dd; | ||
2775 | |||
2776 | if (n->rcv) { | ||
2777 | struct qib_ctxtdata *rcd = (struct qib_ctxtdata *)n->arg; | ||
2778 | dd = rcd->dd; | ||
2779 | } else { | ||
2780 | struct qib_pportdata *ppd = (struct qib_pportdata *)n->arg; | ||
2781 | dd = ppd->dd; | ||
2782 | } | ||
2783 | qib_devinfo(dd->pcidev, | ||
2784 | "release on HCA notify 0x%p n 0x%p\n", ref, n); | ||
2785 | kfree(n); | ||
2786 | } | ||
2787 | #endif | ||
2788 | |||
2561 | /* | 2789 | /* |
2562 | * Disable MSIx interrupt if enabled, call generic MSIx code | 2790 | * Disable MSIx interrupt if enabled, call generic MSIx code |
2563 | * to cleanup, and clear pending MSIx interrupts. | 2791 | * to cleanup, and clear pending MSIx interrupts. |
@@ -2575,6 +2803,9 @@ static void qib_7322_nomsix(struct qib_devdata *dd) | |||
2575 | 2803 | ||
2576 | dd->cspec->num_msix_entries = 0; | 2804 | dd->cspec->num_msix_entries = 0; |
2577 | for (i = 0; i < n; i++) { | 2805 | for (i = 0; i < n; i++) { |
2806 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
2807 | reset_dca_notifier(dd, &dd->cspec->msix_entries[i]); | ||
2808 | #endif | ||
2578 | irq_set_affinity_hint( | 2809 | irq_set_affinity_hint( |
2579 | dd->cspec->msix_entries[i].msix.vector, NULL); | 2810 | dd->cspec->msix_entries[i].msix.vector, NULL); |
2580 | free_cpumask_var(dd->cspec->msix_entries[i].mask); | 2811 | free_cpumask_var(dd->cspec->msix_entries[i].mask); |
@@ -2602,6 +2833,15 @@ static void qib_setup_7322_cleanup(struct qib_devdata *dd) | |||
2602 | { | 2833 | { |
2603 | int i; | 2834 | int i; |
2604 | 2835 | ||
2836 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
2837 | if (dd->flags & QIB_DCA_ENABLED) { | ||
2838 | dca_remove_requester(&dd->pcidev->dev); | ||
2839 | dd->flags &= ~QIB_DCA_ENABLED; | ||
2840 | dd->cspec->dca_ctrl = 0; | ||
2841 | qib_write_kreg(dd, KREG_IDX(DCACtrlA), dd->cspec->dca_ctrl); | ||
2842 | } | ||
2843 | #endif | ||
2844 | |||
2605 | qib_7322_free_irq(dd); | 2845 | qib_7322_free_irq(dd); |
2606 | kfree(dd->cspec->cntrs); | 2846 | kfree(dd->cspec->cntrs); |
2607 | kfree(dd->cspec->sendchkenable); | 2847 | kfree(dd->cspec->sendchkenable); |
@@ -3068,6 +3308,53 @@ static irqreturn_t sdma_cleanup_intr(int irq, void *data) | |||
3068 | return IRQ_HANDLED; | 3308 | return IRQ_HANDLED; |
3069 | } | 3309 | } |
3070 | 3310 | ||
3311 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
3312 | |||
3313 | static void reset_dca_notifier(struct qib_devdata *dd, struct qib_msix_entry *m) | ||
3314 | { | ||
3315 | if (!m->dca) | ||
3316 | return; | ||
3317 | qib_devinfo(dd->pcidev, | ||
3318 | "Disabling notifier on HCA %d irq %d\n", | ||
3319 | dd->unit, | ||
3320 | m->msix.vector); | ||
3321 | irq_set_affinity_notifier( | ||
3322 | m->msix.vector, | ||
3323 | NULL); | ||
3324 | m->notifier = NULL; | ||
3325 | } | ||
3326 | |||
3327 | static void setup_dca_notifier(struct qib_devdata *dd, struct qib_msix_entry *m) | ||
3328 | { | ||
3329 | struct qib_irq_notify *n; | ||
3330 | |||
3331 | if (!m->dca) | ||
3332 | return; | ||
3333 | n = kzalloc(sizeof(*n), GFP_KERNEL); | ||
3334 | if (n) { | ||
3335 | int ret; | ||
3336 | |||
3337 | m->notifier = n; | ||
3338 | n->notify.irq = m->msix.vector; | ||
3339 | n->notify.notify = qib_irq_notifier_notify; | ||
3340 | n->notify.release = qib_irq_notifier_release; | ||
3341 | n->arg = m->arg; | ||
3342 | n->rcv = m->rcv; | ||
3343 | qib_devinfo(dd->pcidev, | ||
3344 | "set notifier irq %d rcv %d notify %p\n", | ||
3345 | n->notify.irq, n->rcv, &n->notify); | ||
3346 | ret = irq_set_affinity_notifier( | ||
3347 | n->notify.irq, | ||
3348 | &n->notify); | ||
3349 | if (ret) { | ||
3350 | m->notifier = NULL; | ||
3351 | kfree(n); | ||
3352 | } | ||
3353 | } | ||
3354 | } | ||
3355 | |||
3356 | #endif | ||
3357 | |||
3071 | /* | 3358 | /* |
3072 | * Set up our chip-specific interrupt handler. | 3359 | * Set up our chip-specific interrupt handler. |
3073 | * The interrupt type has already been setup, so | 3360 | * The interrupt type has already been setup, so |
@@ -3149,6 +3436,9 @@ try_intx: | |||
3149 | void *arg; | 3436 | void *arg; |
3150 | u64 val; | 3437 | u64 val; |
3151 | int lsb, reg, sh; | 3438 | int lsb, reg, sh; |
3439 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
3440 | int dca = 0; | ||
3441 | #endif | ||
3152 | 3442 | ||
3153 | dd->cspec->msix_entries[msixnum]. | 3443 | dd->cspec->msix_entries[msixnum]. |
3154 | name[sizeof(dd->cspec->msix_entries[msixnum].name) - 1] | 3444 | name[sizeof(dd->cspec->msix_entries[msixnum].name) - 1] |
@@ -3161,6 +3451,9 @@ try_intx: | |||
3161 | arg = dd->pport + irq_table[i].port - 1; | 3451 | arg = dd->pport + irq_table[i].port - 1; |
3162 | } else | 3452 | } else |
3163 | arg = dd; | 3453 | arg = dd; |
3454 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
3455 | dca = irq_table[i].dca; | ||
3456 | #endif | ||
3164 | lsb = irq_table[i].lsb; | 3457 | lsb = irq_table[i].lsb; |
3165 | handler = irq_table[i].handler; | 3458 | handler = irq_table[i].handler; |
3166 | snprintf(dd->cspec->msix_entries[msixnum].name, | 3459 | snprintf(dd->cspec->msix_entries[msixnum].name, |
@@ -3178,6 +3471,9 @@ try_intx: | |||
3178 | continue; | 3471 | continue; |
3179 | if (qib_krcvq01_no_msi && ctxt < 2) | 3472 | if (qib_krcvq01_no_msi && ctxt < 2) |
3180 | continue; | 3473 | continue; |
3474 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
3475 | dca = 1; | ||
3476 | #endif | ||
3181 | lsb = QIB_I_RCVAVAIL_LSB + ctxt; | 3477 | lsb = QIB_I_RCVAVAIL_LSB + ctxt; |
3182 | handler = qib_7322pintr; | 3478 | handler = qib_7322pintr; |
3183 | snprintf(dd->cspec->msix_entries[msixnum].name, | 3479 | snprintf(dd->cspec->msix_entries[msixnum].name, |
@@ -3203,6 +3499,11 @@ try_intx: | |||
3203 | goto try_intx; | 3499 | goto try_intx; |
3204 | } | 3500 | } |
3205 | dd->cspec->msix_entries[msixnum].arg = arg; | 3501 | dd->cspec->msix_entries[msixnum].arg = arg; |
3502 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
3503 | dd->cspec->msix_entries[msixnum].dca = dca; | ||
3504 | dd->cspec->msix_entries[msixnum].rcv = | ||
3505 | handler == qib_7322pintr; | ||
3506 | #endif | ||
3206 | if (lsb >= 0) { | 3507 | if (lsb >= 0) { |
3207 | reg = lsb / IBA7322_REDIRECT_VEC_PER_REG; | 3508 | reg = lsb / IBA7322_REDIRECT_VEC_PER_REG; |
3208 | sh = (lsb % IBA7322_REDIRECT_VEC_PER_REG) * | 3509 | sh = (lsb % IBA7322_REDIRECT_VEC_PER_REG) * |
@@ -6885,6 +7186,9 @@ struct qib_devdata *qib_init_iba7322_funcs(struct pci_dev *pdev, | |||
6885 | dd->f_sdma_init_early = qib_7322_sdma_init_early; | 7186 | dd->f_sdma_init_early = qib_7322_sdma_init_early; |
6886 | dd->f_writescratch = writescratch; | 7187 | dd->f_writescratch = writescratch; |
6887 | dd->f_tempsense_rd = qib_7322_tempsense_rd; | 7188 | dd->f_tempsense_rd = qib_7322_tempsense_rd; |
7189 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
7190 | dd->f_notify_dca = qib_7322_notify_dca; | ||
7191 | #endif | ||
6888 | /* | 7192 | /* |
6889 | * Do remaining PCIe setup and save PCIe values in dd. | 7193 | * Do remaining PCIe setup and save PCIe values in dd. |
6890 | * Any error printing is already done by the init code. | 7194 | * Any error printing is already done by the init code. |
@@ -6921,7 +7225,7 @@ struct qib_devdata *qib_init_iba7322_funcs(struct pci_dev *pdev, | |||
6921 | actual_cnt -= dd->num_pports; | 7225 | actual_cnt -= dd->num_pports; |
6922 | 7226 | ||
6923 | tabsize = actual_cnt; | 7227 | tabsize = actual_cnt; |
6924 | dd->cspec->msix_entries = kmalloc(tabsize * | 7228 | dd->cspec->msix_entries = kzalloc(tabsize * |
6925 | sizeof(struct qib_msix_entry), GFP_KERNEL); | 7229 | sizeof(struct qib_msix_entry), GFP_KERNEL); |
6926 | if (!dd->cspec->msix_entries) { | 7230 | if (!dd->cspec->msix_entries) { |
6927 | qib_dev_err(dd, "No memory for MSIx table\n"); | 7231 | qib_dev_err(dd, "No memory for MSIx table\n"); |
@@ -6941,7 +7245,13 @@ struct qib_devdata *qib_init_iba7322_funcs(struct pci_dev *pdev, | |||
6941 | 7245 | ||
6942 | /* clear diagctrl register, in case diags were running and crashed */ | 7246 | /* clear diagctrl register, in case diags were running and crashed */ |
6943 | qib_write_kreg(dd, kr_hwdiagctrl, 0); | 7247 | qib_write_kreg(dd, kr_hwdiagctrl, 0); |
6944 | 7248 | #ifdef CONFIG_INFINIBAND_QIB_DCA | |
7249 | if (!dca_add_requester(&pdev->dev)) { | ||
7250 | qib_devinfo(dd->pcidev, "DCA enabled\n"); | ||
7251 | dd->flags |= QIB_DCA_ENABLED; | ||
7252 | qib_setup_dca(dd); | ||
7253 | } | ||
7254 | #endif | ||
6945 | goto bail; | 7255 | goto bail; |
6946 | 7256 | ||
6947 | bail_cleanup: | 7257 | bail_cleanup: |
@@ -7156,15 +7466,20 @@ static const struct txdds_ent txdds_extra_sdr[TXDDS_EXTRA_SZ] = { | |||
7156 | { 0, 0, 0, 1 }, /* QMH7342 backplane settings */ | 7466 | { 0, 0, 0, 1 }, /* QMH7342 backplane settings */ |
7157 | { 0, 0, 0, 2 }, /* QMH7342 backplane settings */ | 7467 | { 0, 0, 0, 2 }, /* QMH7342 backplane settings */ |
7158 | { 0, 0, 0, 2 }, /* QMH7342 backplane settings */ | 7468 | { 0, 0, 0, 2 }, /* QMH7342 backplane settings */ |
7159 | { 0, 0, 0, 11 }, /* QME7342 backplane settings */ | ||
7160 | { 0, 0, 0, 11 }, /* QME7342 backplane settings */ | ||
7161 | { 0, 0, 0, 11 }, /* QME7342 backplane settings */ | ||
7162 | { 0, 0, 0, 11 }, /* QME7342 backplane settings */ | ||
7163 | { 0, 0, 0, 11 }, /* QME7342 backplane settings */ | ||
7164 | { 0, 0, 0, 11 }, /* QME7342 backplane settings */ | ||
7165 | { 0, 0, 0, 11 }, /* QME7342 backplane settings */ | ||
7166 | { 0, 0, 0, 3 }, /* QMH7342 backplane settings */ | 7469 | { 0, 0, 0, 3 }, /* QMH7342 backplane settings */ |
7167 | { 0, 0, 0, 4 }, /* QMH7342 backplane settings */ | 7470 | { 0, 0, 0, 4 }, /* QMH7342 backplane settings */ |
7471 | { 0, 1, 4, 15 }, /* QME7342 backplane settings 1.0 */ | ||
7472 | { 0, 1, 3, 15 }, /* QME7342 backplane settings 1.0 */ | ||
7473 | { 0, 1, 0, 12 }, /* QME7342 backplane settings 1.0 */ | ||
7474 | { 0, 1, 0, 11 }, /* QME7342 backplane settings 1.0 */ | ||
7475 | { 0, 1, 0, 9 }, /* QME7342 backplane settings 1.0 */ | ||
7476 | { 0, 1, 0, 14 }, /* QME7342 backplane settings 1.0 */ | ||
7477 | { 0, 1, 2, 15 }, /* QME7342 backplane settings 1.0 */ | ||
7478 | { 0, 1, 0, 11 }, /* QME7342 backplane settings 1.1 */ | ||
7479 | { 0, 1, 0, 7 }, /* QME7342 backplane settings 1.1 */ | ||
7480 | { 0, 1, 0, 9 }, /* QME7342 backplane settings 1.1 */ | ||
7481 | { 0, 1, 0, 6 }, /* QME7342 backplane settings 1.1 */ | ||
7482 | { 0, 1, 0, 8 }, /* QME7342 backplane settings 1.1 */ | ||
7168 | }; | 7483 | }; |
7169 | 7484 | ||
7170 | static const struct txdds_ent txdds_extra_ddr[TXDDS_EXTRA_SZ] = { | 7485 | static const struct txdds_ent txdds_extra_ddr[TXDDS_EXTRA_SZ] = { |
@@ -7173,15 +7488,20 @@ static const struct txdds_ent txdds_extra_ddr[TXDDS_EXTRA_SZ] = { | |||
7173 | { 0, 0, 0, 7 }, /* QMH7342 backplane settings */ | 7488 | { 0, 0, 0, 7 }, /* QMH7342 backplane settings */ |
7174 | { 0, 0, 0, 8 }, /* QMH7342 backplane settings */ | 7489 | { 0, 0, 0, 8 }, /* QMH7342 backplane settings */ |
7175 | { 0, 0, 0, 8 }, /* QMH7342 backplane settings */ | 7490 | { 0, 0, 0, 8 }, /* QMH7342 backplane settings */ |
7176 | { 0, 0, 0, 13 }, /* QME7342 backplane settings */ | ||
7177 | { 0, 0, 0, 13 }, /* QME7342 backplane settings */ | ||
7178 | { 0, 0, 0, 13 }, /* QME7342 backplane settings */ | ||
7179 | { 0, 0, 0, 13 }, /* QME7342 backplane settings */ | ||
7180 | { 0, 0, 0, 13 }, /* QME7342 backplane settings */ | ||
7181 | { 0, 0, 0, 13 }, /* QME7342 backplane settings */ | ||
7182 | { 0, 0, 0, 13 }, /* QME7342 backplane settings */ | ||
7183 | { 0, 0, 0, 9 }, /* QMH7342 backplane settings */ | 7491 | { 0, 0, 0, 9 }, /* QMH7342 backplane settings */ |
7184 | { 0, 0, 0, 10 }, /* QMH7342 backplane settings */ | 7492 | { 0, 0, 0, 10 }, /* QMH7342 backplane settings */ |
7493 | { 0, 1, 4, 15 }, /* QME7342 backplane settings 1.0 */ | ||
7494 | { 0, 1, 3, 15 }, /* QME7342 backplane settings 1.0 */ | ||
7495 | { 0, 1, 0, 12 }, /* QME7342 backplane settings 1.0 */ | ||
7496 | { 0, 1, 0, 11 }, /* QME7342 backplane settings 1.0 */ | ||
7497 | { 0, 1, 0, 9 }, /* QME7342 backplane settings 1.0 */ | ||
7498 | { 0, 1, 0, 14 }, /* QME7342 backplane settings 1.0 */ | ||
7499 | { 0, 1, 2, 15 }, /* QME7342 backplane settings 1.0 */ | ||
7500 | { 0, 1, 0, 11 }, /* QME7342 backplane settings 1.1 */ | ||
7501 | { 0, 1, 0, 7 }, /* QME7342 backplane settings 1.1 */ | ||
7502 | { 0, 1, 0, 9 }, /* QME7342 backplane settings 1.1 */ | ||
7503 | { 0, 1, 0, 6 }, /* QME7342 backplane settings 1.1 */ | ||
7504 | { 0, 1, 0, 8 }, /* QME7342 backplane settings 1.1 */ | ||
7185 | }; | 7505 | }; |
7186 | 7506 | ||
7187 | static const struct txdds_ent txdds_extra_qdr[TXDDS_EXTRA_SZ] = { | 7507 | static const struct txdds_ent txdds_extra_qdr[TXDDS_EXTRA_SZ] = { |
@@ -7190,15 +7510,20 @@ static const struct txdds_ent txdds_extra_qdr[TXDDS_EXTRA_SZ] = { | |||
7190 | { 0, 1, 0, 5 }, /* QMH7342 backplane settings */ | 7510 | { 0, 1, 0, 5 }, /* QMH7342 backplane settings */ |
7191 | { 0, 1, 0, 6 }, /* QMH7342 backplane settings */ | 7511 | { 0, 1, 0, 6 }, /* QMH7342 backplane settings */ |
7192 | { 0, 1, 0, 8 }, /* QMH7342 backplane settings */ | 7512 | { 0, 1, 0, 8 }, /* QMH7342 backplane settings */ |
7193 | { 0, 1, 12, 10 }, /* QME7342 backplane setting */ | ||
7194 | { 0, 1, 12, 11 }, /* QME7342 backplane setting */ | ||
7195 | { 0, 1, 12, 12 }, /* QME7342 backplane setting */ | ||
7196 | { 0, 1, 12, 14 }, /* QME7342 backplane setting */ | ||
7197 | { 0, 1, 12, 6 }, /* QME7342 backplane setting */ | ||
7198 | { 0, 1, 12, 7 }, /* QME7342 backplane setting */ | ||
7199 | { 0, 1, 12, 8 }, /* QME7342 backplane setting */ | ||
7200 | { 0, 1, 0, 10 }, /* QMH7342 backplane settings */ | 7513 | { 0, 1, 0, 10 }, /* QMH7342 backplane settings */ |
7201 | { 0, 1, 0, 12 }, /* QMH7342 backplane settings */ | 7514 | { 0, 1, 0, 12 }, /* QMH7342 backplane settings */ |
7515 | { 0, 1, 4, 15 }, /* QME7342 backplane settings 1.0 */ | ||
7516 | { 0, 1, 3, 15 }, /* QME7342 backplane settings 1.0 */ | ||
7517 | { 0, 1, 0, 12 }, /* QME7342 backplane settings 1.0 */ | ||
7518 | { 0, 1, 0, 11 }, /* QME7342 backplane settings 1.0 */ | ||
7519 | { 0, 1, 0, 9 }, /* QME7342 backplane settings 1.0 */ | ||
7520 | { 0, 1, 0, 14 }, /* QME7342 backplane settings 1.0 */ | ||
7521 | { 0, 1, 2, 15 }, /* QME7342 backplane settings 1.0 */ | ||
7522 | { 0, 1, 0, 11 }, /* QME7342 backplane settings 1.1 */ | ||
7523 | { 0, 1, 0, 7 }, /* QME7342 backplane settings 1.1 */ | ||
7524 | { 0, 1, 0, 9 }, /* QME7342 backplane settings 1.1 */ | ||
7525 | { 0, 1, 0, 6 }, /* QME7342 backplane settings 1.1 */ | ||
7526 | { 0, 1, 0, 8 }, /* QME7342 backplane settings 1.1 */ | ||
7202 | }; | 7527 | }; |
7203 | 7528 | ||
7204 | static const struct txdds_ent txdds_extra_mfg[TXDDS_MFG_SZ] = { | 7529 | static const struct txdds_ent txdds_extra_mfg[TXDDS_MFG_SZ] = { |
diff --git a/drivers/infiniband/hw/qib/qib_init.c b/drivers/infiniband/hw/qib/qib_init.c index 173f805790da..fdae42973056 100644 --- a/drivers/infiniband/hw/qib/qib_init.c +++ b/drivers/infiniband/hw/qib/qib_init.c | |||
@@ -39,10 +39,17 @@ | |||
39 | #include <linux/idr.h> | 39 | #include <linux/idr.h> |
40 | #include <linux/module.h> | 40 | #include <linux/module.h> |
41 | #include <linux/printk.h> | 41 | #include <linux/printk.h> |
42 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
43 | #include <linux/dca.h> | ||
44 | #endif | ||
42 | 45 | ||
43 | #include "qib.h" | 46 | #include "qib.h" |
44 | #include "qib_common.h" | 47 | #include "qib_common.h" |
45 | #include "qib_mad.h" | 48 | #include "qib_mad.h" |
49 | #ifdef CONFIG_DEBUG_FS | ||
50 | #include "qib_debugfs.h" | ||
51 | #include "qib_verbs.h" | ||
52 | #endif | ||
46 | 53 | ||
47 | #undef pr_fmt | 54 | #undef pr_fmt |
48 | #define pr_fmt(fmt) QIB_DRV_NAME ": " fmt | 55 | #define pr_fmt(fmt) QIB_DRV_NAME ": " fmt |
@@ -64,6 +71,11 @@ ushort qib_cfgctxts; | |||
64 | module_param_named(cfgctxts, qib_cfgctxts, ushort, S_IRUGO); | 71 | module_param_named(cfgctxts, qib_cfgctxts, ushort, S_IRUGO); |
65 | MODULE_PARM_DESC(cfgctxts, "Set max number of contexts to use"); | 72 | MODULE_PARM_DESC(cfgctxts, "Set max number of contexts to use"); |
66 | 73 | ||
74 | unsigned qib_numa_aware; | ||
75 | module_param_named(numa_aware, qib_numa_aware, uint, S_IRUGO); | ||
76 | MODULE_PARM_DESC(numa_aware, | ||
77 | "0 -> PSM allocation close to HCA, 1 -> PSM allocation local to process"); | ||
78 | |||
67 | /* | 79 | /* |
68 | * If set, do not write to any regs if avoidable, hack to allow | 80 | * If set, do not write to any regs if avoidable, hack to allow |
69 | * check for deranged default register values. | 81 | * check for deranged default register values. |
@@ -89,8 +101,6 @@ unsigned qib_wc_pat = 1; /* default (1) is to use PAT, not MTRR */ | |||
89 | module_param_named(wc_pat, qib_wc_pat, uint, S_IRUGO); | 101 | module_param_named(wc_pat, qib_wc_pat, uint, S_IRUGO); |
90 | MODULE_PARM_DESC(wc_pat, "enable write-combining via PAT mechanism"); | 102 | MODULE_PARM_DESC(wc_pat, "enable write-combining via PAT mechanism"); |
91 | 103 | ||
92 | struct workqueue_struct *qib_cq_wq; | ||
93 | |||
94 | static void verify_interrupt(unsigned long); | 104 | static void verify_interrupt(unsigned long); |
95 | 105 | ||
96 | static struct idr qib_unit_table; | 106 | static struct idr qib_unit_table; |
@@ -121,6 +131,11 @@ int qib_create_ctxts(struct qib_devdata *dd) | |||
121 | { | 131 | { |
122 | unsigned i; | 132 | unsigned i; |
123 | int ret; | 133 | int ret; |
134 | int local_node_id = pcibus_to_node(dd->pcidev->bus); | ||
135 | |||
136 | if (local_node_id < 0) | ||
137 | local_node_id = numa_node_id(); | ||
138 | dd->assigned_node_id = local_node_id; | ||
124 | 139 | ||
125 | /* | 140 | /* |
126 | * Allocate full ctxtcnt array, rather than just cfgctxts, because | 141 | * Allocate full ctxtcnt array, rather than just cfgctxts, because |
@@ -143,7 +158,8 @@ int qib_create_ctxts(struct qib_devdata *dd) | |||
143 | continue; | 158 | continue; |
144 | 159 | ||
145 | ppd = dd->pport + (i % dd->num_pports); | 160 | ppd = dd->pport + (i % dd->num_pports); |
146 | rcd = qib_create_ctxtdata(ppd, i); | 161 | |
162 | rcd = qib_create_ctxtdata(ppd, i, dd->assigned_node_id); | ||
147 | if (!rcd) { | 163 | if (!rcd) { |
148 | qib_dev_err(dd, | 164 | qib_dev_err(dd, |
149 | "Unable to allocate ctxtdata for Kernel ctxt, failing\n"); | 165 | "Unable to allocate ctxtdata for Kernel ctxt, failing\n"); |
@@ -161,20 +177,33 @@ done: | |||
161 | /* | 177 | /* |
162 | * Common code for user and kernel context setup. | 178 | * Common code for user and kernel context setup. |
163 | */ | 179 | */ |
164 | struct qib_ctxtdata *qib_create_ctxtdata(struct qib_pportdata *ppd, u32 ctxt) | 180 | struct qib_ctxtdata *qib_create_ctxtdata(struct qib_pportdata *ppd, u32 ctxt, |
181 | int node_id) | ||
165 | { | 182 | { |
166 | struct qib_devdata *dd = ppd->dd; | 183 | struct qib_devdata *dd = ppd->dd; |
167 | struct qib_ctxtdata *rcd; | 184 | struct qib_ctxtdata *rcd; |
168 | 185 | ||
169 | rcd = kzalloc(sizeof(*rcd), GFP_KERNEL); | 186 | rcd = kzalloc_node(sizeof(*rcd), GFP_KERNEL, node_id); |
170 | if (rcd) { | 187 | if (rcd) { |
171 | INIT_LIST_HEAD(&rcd->qp_wait_list); | 188 | INIT_LIST_HEAD(&rcd->qp_wait_list); |
189 | rcd->node_id = node_id; | ||
172 | rcd->ppd = ppd; | 190 | rcd->ppd = ppd; |
173 | rcd->dd = dd; | 191 | rcd->dd = dd; |
174 | rcd->cnt = 1; | 192 | rcd->cnt = 1; |
175 | rcd->ctxt = ctxt; | 193 | rcd->ctxt = ctxt; |
176 | dd->rcd[ctxt] = rcd; | 194 | dd->rcd[ctxt] = rcd; |
177 | 195 | #ifdef CONFIG_DEBUG_FS | |
196 | if (ctxt < dd->first_user_ctxt) { /* N/A for PSM contexts */ | ||
197 | rcd->opstats = kzalloc_node(sizeof(*rcd->opstats), | ||
198 | GFP_KERNEL, node_id); | ||
199 | if (!rcd->opstats) { | ||
200 | kfree(rcd); | ||
201 | qib_dev_err(dd, | ||
202 | "Unable to allocate per ctxt stats buffer\n"); | ||
203 | return NULL; | ||
204 | } | ||
205 | } | ||
206 | #endif | ||
178 | dd->f_init_ctxt(rcd); | 207 | dd->f_init_ctxt(rcd); |
179 | 208 | ||
180 | /* | 209 | /* |
@@ -429,6 +458,7 @@ static int loadtime_init(struct qib_devdata *dd) | |||
429 | dd->intrchk_timer.function = verify_interrupt; | 458 | dd->intrchk_timer.function = verify_interrupt; |
430 | dd->intrchk_timer.data = (unsigned long) dd; | 459 | dd->intrchk_timer.data = (unsigned long) dd; |
431 | 460 | ||
461 | ret = qib_cq_init(dd); | ||
432 | done: | 462 | done: |
433 | return ret; | 463 | return ret; |
434 | } | 464 | } |
@@ -944,6 +974,10 @@ void qib_free_ctxtdata(struct qib_devdata *dd, struct qib_ctxtdata *rcd) | |||
944 | vfree(rcd->subctxt_uregbase); | 974 | vfree(rcd->subctxt_uregbase); |
945 | vfree(rcd->subctxt_rcvegrbuf); | 975 | vfree(rcd->subctxt_rcvegrbuf); |
946 | vfree(rcd->subctxt_rcvhdr_base); | 976 | vfree(rcd->subctxt_rcvhdr_base); |
977 | #ifdef CONFIG_DEBUG_FS | ||
978 | kfree(rcd->opstats); | ||
979 | rcd->opstats = NULL; | ||
980 | #endif | ||
947 | kfree(rcd); | 981 | kfree(rcd); |
948 | } | 982 | } |
949 | 983 | ||
@@ -1033,7 +1067,6 @@ done: | |||
1033 | dd->f_set_armlaunch(dd, 1); | 1067 | dd->f_set_armlaunch(dd, 1); |
1034 | } | 1068 | } |
1035 | 1069 | ||
1036 | |||
1037 | void qib_free_devdata(struct qib_devdata *dd) | 1070 | void qib_free_devdata(struct qib_devdata *dd) |
1038 | { | 1071 | { |
1039 | unsigned long flags; | 1072 | unsigned long flags; |
@@ -1043,6 +1076,9 @@ void qib_free_devdata(struct qib_devdata *dd) | |||
1043 | list_del(&dd->list); | 1076 | list_del(&dd->list); |
1044 | spin_unlock_irqrestore(&qib_devs_lock, flags); | 1077 | spin_unlock_irqrestore(&qib_devs_lock, flags); |
1045 | 1078 | ||
1079 | #ifdef CONFIG_DEBUG_FS | ||
1080 | qib_dbg_ibdev_exit(&dd->verbs_dev); | ||
1081 | #endif | ||
1046 | ib_dealloc_device(&dd->verbs_dev.ibdev); | 1082 | ib_dealloc_device(&dd->verbs_dev.ibdev); |
1047 | } | 1083 | } |
1048 | 1084 | ||
@@ -1066,6 +1102,10 @@ struct qib_devdata *qib_alloc_devdata(struct pci_dev *pdev, size_t extra) | |||
1066 | goto bail; | 1102 | goto bail; |
1067 | } | 1103 | } |
1068 | 1104 | ||
1105 | #ifdef CONFIG_DEBUG_FS | ||
1106 | qib_dbg_ibdev_init(&dd->verbs_dev); | ||
1107 | #endif | ||
1108 | |||
1069 | idr_preload(GFP_KERNEL); | 1109 | idr_preload(GFP_KERNEL); |
1070 | spin_lock_irqsave(&qib_devs_lock, flags); | 1110 | spin_lock_irqsave(&qib_devs_lock, flags); |
1071 | 1111 | ||
@@ -1081,6 +1121,9 @@ struct qib_devdata *qib_alloc_devdata(struct pci_dev *pdev, size_t extra) | |||
1081 | if (ret < 0) { | 1121 | if (ret < 0) { |
1082 | qib_early_err(&pdev->dev, | 1122 | qib_early_err(&pdev->dev, |
1083 | "Could not allocate unit ID: error %d\n", -ret); | 1123 | "Could not allocate unit ID: error %d\n", -ret); |
1124 | #ifdef CONFIG_DEBUG_FS | ||
1125 | qib_dbg_ibdev_exit(&dd->verbs_dev); | ||
1126 | #endif | ||
1084 | ib_dealloc_device(&dd->verbs_dev.ibdev); | 1127 | ib_dealloc_device(&dd->verbs_dev.ibdev); |
1085 | dd = ERR_PTR(ret); | 1128 | dd = ERR_PTR(ret); |
1086 | goto bail; | 1129 | goto bail; |
@@ -1158,6 +1201,35 @@ struct pci_driver qib_driver = { | |||
1158 | .err_handler = &qib_pci_err_handler, | 1201 | .err_handler = &qib_pci_err_handler, |
1159 | }; | 1202 | }; |
1160 | 1203 | ||
1204 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
1205 | |||
1206 | static int qib_notify_dca(struct notifier_block *, unsigned long, void *); | ||
1207 | static struct notifier_block dca_notifier = { | ||
1208 | .notifier_call = qib_notify_dca, | ||
1209 | .next = NULL, | ||
1210 | .priority = 0 | ||
1211 | }; | ||
1212 | |||
1213 | static int qib_notify_dca_device(struct device *device, void *data) | ||
1214 | { | ||
1215 | struct qib_devdata *dd = dev_get_drvdata(device); | ||
1216 | unsigned long event = *(unsigned long *)data; | ||
1217 | |||
1218 | return dd->f_notify_dca(dd, event); | ||
1219 | } | ||
1220 | |||
1221 | static int qib_notify_dca(struct notifier_block *nb, unsigned long event, | ||
1222 | void *p) | ||
1223 | { | ||
1224 | int rval; | ||
1225 | |||
1226 | rval = driver_for_each_device(&qib_driver.driver, NULL, | ||
1227 | &event, qib_notify_dca_device); | ||
1228 | return rval ? NOTIFY_BAD : NOTIFY_DONE; | ||
1229 | } | ||
1230 | |||
1231 | #endif | ||
1232 | |||
1161 | /* | 1233 | /* |
1162 | * Do all the generic driver unit- and chip-independent memory | 1234 | * Do all the generic driver unit- and chip-independent memory |
1163 | * allocation and initialization. | 1235 | * allocation and initialization. |
@@ -1170,22 +1242,22 @@ static int __init qlogic_ib_init(void) | |||
1170 | if (ret) | 1242 | if (ret) |
1171 | goto bail; | 1243 | goto bail; |
1172 | 1244 | ||
1173 | qib_cq_wq = create_singlethread_workqueue("qib_cq"); | ||
1174 | if (!qib_cq_wq) { | ||
1175 | ret = -ENOMEM; | ||
1176 | goto bail_dev; | ||
1177 | } | ||
1178 | |||
1179 | /* | 1245 | /* |
1180 | * These must be called before the driver is registered with | 1246 | * These must be called before the driver is registered with |
1181 | * the PCI subsystem. | 1247 | * the PCI subsystem. |
1182 | */ | 1248 | */ |
1183 | idr_init(&qib_unit_table); | 1249 | idr_init(&qib_unit_table); |
1184 | 1250 | ||
1251 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
1252 | dca_register_notify(&dca_notifier); | ||
1253 | #endif | ||
1254 | #ifdef CONFIG_DEBUG_FS | ||
1255 | qib_dbg_init(); | ||
1256 | #endif | ||
1185 | ret = pci_register_driver(&qib_driver); | 1257 | ret = pci_register_driver(&qib_driver); |
1186 | if (ret < 0) { | 1258 | if (ret < 0) { |
1187 | pr_err("Unable to register driver: error %d\n", -ret); | 1259 | pr_err("Unable to register driver: error %d\n", -ret); |
1188 | goto bail_unit; | 1260 | goto bail_dev; |
1189 | } | 1261 | } |
1190 | 1262 | ||
1191 | /* not fatal if it doesn't work */ | 1263 | /* not fatal if it doesn't work */ |
@@ -1193,10 +1265,14 @@ static int __init qlogic_ib_init(void) | |||
1193 | pr_err("Unable to register ipathfs\n"); | 1265 | pr_err("Unable to register ipathfs\n"); |
1194 | goto bail; /* all OK */ | 1266 | goto bail; /* all OK */ |
1195 | 1267 | ||
1196 | bail_unit: | ||
1197 | idr_destroy(&qib_unit_table); | ||
1198 | destroy_workqueue(qib_cq_wq); | ||
1199 | bail_dev: | 1268 | bail_dev: |
1269 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
1270 | dca_unregister_notify(&dca_notifier); | ||
1271 | #endif | ||
1272 | #ifdef CONFIG_DEBUG_FS | ||
1273 | qib_dbg_exit(); | ||
1274 | #endif | ||
1275 | idr_destroy(&qib_unit_table); | ||
1200 | qib_dev_cleanup(); | 1276 | qib_dev_cleanup(); |
1201 | bail: | 1277 | bail: |
1202 | return ret; | 1278 | return ret; |
@@ -1217,9 +1293,13 @@ static void __exit qlogic_ib_cleanup(void) | |||
1217 | "Unable to cleanup counter filesystem: error %d\n", | 1293 | "Unable to cleanup counter filesystem: error %d\n", |
1218 | -ret); | 1294 | -ret); |
1219 | 1295 | ||
1296 | #ifdef CONFIG_INFINIBAND_QIB_DCA | ||
1297 | dca_unregister_notify(&dca_notifier); | ||
1298 | #endif | ||
1220 | pci_unregister_driver(&qib_driver); | 1299 | pci_unregister_driver(&qib_driver); |
1221 | 1300 | #ifdef CONFIG_DEBUG_FS | |
1222 | destroy_workqueue(qib_cq_wq); | 1301 | qib_dbg_exit(); |
1302 | #endif | ||
1223 | 1303 | ||
1224 | qib_cpulist_count = 0; | 1304 | qib_cpulist_count = 0; |
1225 | kfree(qib_cpulist); | 1305 | kfree(qib_cpulist); |
@@ -1311,6 +1391,7 @@ static void cleanup_device_data(struct qib_devdata *dd) | |||
1311 | } | 1391 | } |
1312 | kfree(tmp); | 1392 | kfree(tmp); |
1313 | kfree(dd->boardname); | 1393 | kfree(dd->boardname); |
1394 | qib_cq_exit(dd); | ||
1314 | } | 1395 | } |
1315 | 1396 | ||
1316 | /* | 1397 | /* |
@@ -1483,6 +1564,7 @@ static void qib_remove_one(struct pci_dev *pdev) | |||
1483 | int qib_create_rcvhdrq(struct qib_devdata *dd, struct qib_ctxtdata *rcd) | 1564 | int qib_create_rcvhdrq(struct qib_devdata *dd, struct qib_ctxtdata *rcd) |
1484 | { | 1565 | { |
1485 | unsigned amt; | 1566 | unsigned amt; |
1567 | int old_node_id; | ||
1486 | 1568 | ||
1487 | if (!rcd->rcvhdrq) { | 1569 | if (!rcd->rcvhdrq) { |
1488 | dma_addr_t phys_hdrqtail; | 1570 | dma_addr_t phys_hdrqtail; |
@@ -1492,9 +1574,13 @@ int qib_create_rcvhdrq(struct qib_devdata *dd, struct qib_ctxtdata *rcd) | |||
1492 | sizeof(u32), PAGE_SIZE); | 1574 | sizeof(u32), PAGE_SIZE); |
1493 | gfp_flags = (rcd->ctxt >= dd->first_user_ctxt) ? | 1575 | gfp_flags = (rcd->ctxt >= dd->first_user_ctxt) ? |
1494 | GFP_USER : GFP_KERNEL; | 1576 | GFP_USER : GFP_KERNEL; |
1577 | |||
1578 | old_node_id = dev_to_node(&dd->pcidev->dev); | ||
1579 | set_dev_node(&dd->pcidev->dev, rcd->node_id); | ||
1495 | rcd->rcvhdrq = dma_alloc_coherent( | 1580 | rcd->rcvhdrq = dma_alloc_coherent( |
1496 | &dd->pcidev->dev, amt, &rcd->rcvhdrq_phys, | 1581 | &dd->pcidev->dev, amt, &rcd->rcvhdrq_phys, |
1497 | gfp_flags | __GFP_COMP); | 1582 | gfp_flags | __GFP_COMP); |
1583 | set_dev_node(&dd->pcidev->dev, old_node_id); | ||
1498 | 1584 | ||
1499 | if (!rcd->rcvhdrq) { | 1585 | if (!rcd->rcvhdrq) { |
1500 | qib_dev_err(dd, | 1586 | qib_dev_err(dd, |
@@ -1510,9 +1596,11 @@ int qib_create_rcvhdrq(struct qib_devdata *dd, struct qib_ctxtdata *rcd) | |||
1510 | } | 1596 | } |
1511 | 1597 | ||
1512 | if (!(dd->flags & QIB_NODMA_RTAIL)) { | 1598 | if (!(dd->flags & QIB_NODMA_RTAIL)) { |
1599 | set_dev_node(&dd->pcidev->dev, rcd->node_id); | ||
1513 | rcd->rcvhdrtail_kvaddr = dma_alloc_coherent( | 1600 | rcd->rcvhdrtail_kvaddr = dma_alloc_coherent( |
1514 | &dd->pcidev->dev, PAGE_SIZE, &phys_hdrqtail, | 1601 | &dd->pcidev->dev, PAGE_SIZE, &phys_hdrqtail, |
1515 | gfp_flags); | 1602 | gfp_flags); |
1603 | set_dev_node(&dd->pcidev->dev, old_node_id); | ||
1516 | if (!rcd->rcvhdrtail_kvaddr) | 1604 | if (!rcd->rcvhdrtail_kvaddr) |
1517 | goto bail_free; | 1605 | goto bail_free; |
1518 | rcd->rcvhdrqtailaddr_phys = phys_hdrqtail; | 1606 | rcd->rcvhdrqtailaddr_phys = phys_hdrqtail; |
@@ -1556,6 +1644,7 @@ int qib_setup_eagerbufs(struct qib_ctxtdata *rcd) | |||
1556 | unsigned e, egrcnt, egrperchunk, chunk, egrsize, egroff; | 1644 | unsigned e, egrcnt, egrperchunk, chunk, egrsize, egroff; |
1557 | size_t size; | 1645 | size_t size; |
1558 | gfp_t gfp_flags; | 1646 | gfp_t gfp_flags; |
1647 | int old_node_id; | ||
1559 | 1648 | ||
1560 | /* | 1649 | /* |
1561 | * GFP_USER, but without GFP_FS, so buffer cache can be | 1650 | * GFP_USER, but without GFP_FS, so buffer cache can be |
@@ -1574,25 +1663,29 @@ int qib_setup_eagerbufs(struct qib_ctxtdata *rcd) | |||
1574 | size = rcd->rcvegrbuf_size; | 1663 | size = rcd->rcvegrbuf_size; |
1575 | if (!rcd->rcvegrbuf) { | 1664 | if (!rcd->rcvegrbuf) { |
1576 | rcd->rcvegrbuf = | 1665 | rcd->rcvegrbuf = |
1577 | kzalloc(chunk * sizeof(rcd->rcvegrbuf[0]), | 1666 | kzalloc_node(chunk * sizeof(rcd->rcvegrbuf[0]), |
1578 | GFP_KERNEL); | 1667 | GFP_KERNEL, rcd->node_id); |
1579 | if (!rcd->rcvegrbuf) | 1668 | if (!rcd->rcvegrbuf) |
1580 | goto bail; | 1669 | goto bail; |
1581 | } | 1670 | } |
1582 | if (!rcd->rcvegrbuf_phys) { | 1671 | if (!rcd->rcvegrbuf_phys) { |
1583 | rcd->rcvegrbuf_phys = | 1672 | rcd->rcvegrbuf_phys = |
1584 | kmalloc(chunk * sizeof(rcd->rcvegrbuf_phys[0]), | 1673 | kmalloc_node(chunk * sizeof(rcd->rcvegrbuf_phys[0]), |
1585 | GFP_KERNEL); | 1674 | GFP_KERNEL, rcd->node_id); |
1586 | if (!rcd->rcvegrbuf_phys) | 1675 | if (!rcd->rcvegrbuf_phys) |
1587 | goto bail_rcvegrbuf; | 1676 | goto bail_rcvegrbuf; |
1588 | } | 1677 | } |
1589 | for (e = 0; e < rcd->rcvegrbuf_chunks; e++) { | 1678 | for (e = 0; e < rcd->rcvegrbuf_chunks; e++) { |
1590 | if (rcd->rcvegrbuf[e]) | 1679 | if (rcd->rcvegrbuf[e]) |
1591 | continue; | 1680 | continue; |
1681 | |||
1682 | old_node_id = dev_to_node(&dd->pcidev->dev); | ||
1683 | set_dev_node(&dd->pcidev->dev, rcd->node_id); | ||
1592 | rcd->rcvegrbuf[e] = | 1684 | rcd->rcvegrbuf[e] = |
1593 | dma_alloc_coherent(&dd->pcidev->dev, size, | 1685 | dma_alloc_coherent(&dd->pcidev->dev, size, |
1594 | &rcd->rcvegrbuf_phys[e], | 1686 | &rcd->rcvegrbuf_phys[e], |
1595 | gfp_flags); | 1687 | gfp_flags); |
1688 | set_dev_node(&dd->pcidev->dev, old_node_id); | ||
1596 | if (!rcd->rcvegrbuf[e]) | 1689 | if (!rcd->rcvegrbuf[e]) |
1597 | goto bail_rcvegrbuf_phys; | 1690 | goto bail_rcvegrbuf_phys; |
1598 | } | 1691 | } |
diff --git a/drivers/infiniband/hw/qib/qib_qp.c b/drivers/infiniband/hw/qib/qib_qp.c index a6a2cc2ba260..3cca55b51e54 100644 --- a/drivers/infiniband/hw/qib/qib_qp.c +++ b/drivers/infiniband/hw/qib/qib_qp.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2012 Intel Corporation. All rights reserved. | 2 | * Copyright (c) 2012, 2013 Intel Corporation. All rights reserved. |
3 | * Copyright (c) 2006 - 2012 QLogic Corporation. * All rights reserved. | 3 | * Copyright (c) 2006 - 2012 QLogic Corporation. * All rights reserved. |
4 | * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. | 4 | * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. |
5 | * | 5 | * |
@@ -35,6 +35,9 @@ | |||
35 | #include <linux/err.h> | 35 | #include <linux/err.h> |
36 | #include <linux/vmalloc.h> | 36 | #include <linux/vmalloc.h> |
37 | #include <linux/jhash.h> | 37 | #include <linux/jhash.h> |
38 | #ifdef CONFIG_DEBUG_FS | ||
39 | #include <linux/seq_file.h> | ||
40 | #endif | ||
38 | 41 | ||
39 | #include "qib.h" | 42 | #include "qib.h" |
40 | 43 | ||
@@ -222,8 +225,8 @@ static void insert_qp(struct qib_ibdev *dev, struct qib_qp *qp) | |||
222 | unsigned long flags; | 225 | unsigned long flags; |
223 | unsigned n = qpn_hash(dev, qp->ibqp.qp_num); | 226 | unsigned n = qpn_hash(dev, qp->ibqp.qp_num); |
224 | 227 | ||
225 | spin_lock_irqsave(&dev->qpt_lock, flags); | ||
226 | atomic_inc(&qp->refcount); | 228 | atomic_inc(&qp->refcount); |
229 | spin_lock_irqsave(&dev->qpt_lock, flags); | ||
227 | 230 | ||
228 | if (qp->ibqp.qp_num == 0) | 231 | if (qp->ibqp.qp_num == 0) |
229 | rcu_assign_pointer(ibp->qp0, qp); | 232 | rcu_assign_pointer(ibp->qp0, qp); |
@@ -235,7 +238,6 @@ static void insert_qp(struct qib_ibdev *dev, struct qib_qp *qp) | |||
235 | } | 238 | } |
236 | 239 | ||
237 | spin_unlock_irqrestore(&dev->qpt_lock, flags); | 240 | spin_unlock_irqrestore(&dev->qpt_lock, flags); |
238 | synchronize_rcu(); | ||
239 | } | 241 | } |
240 | 242 | ||
241 | /* | 243 | /* |
@@ -247,36 +249,39 @@ static void remove_qp(struct qib_ibdev *dev, struct qib_qp *qp) | |||
247 | struct qib_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num); | 249 | struct qib_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num); |
248 | unsigned n = qpn_hash(dev, qp->ibqp.qp_num); | 250 | unsigned n = qpn_hash(dev, qp->ibqp.qp_num); |
249 | unsigned long flags; | 251 | unsigned long flags; |
252 | int removed = 1; | ||
250 | 253 | ||
251 | spin_lock_irqsave(&dev->qpt_lock, flags); | 254 | spin_lock_irqsave(&dev->qpt_lock, flags); |
252 | 255 | ||
253 | if (rcu_dereference_protected(ibp->qp0, | 256 | if (rcu_dereference_protected(ibp->qp0, |
254 | lockdep_is_held(&dev->qpt_lock)) == qp) { | 257 | lockdep_is_held(&dev->qpt_lock)) == qp) { |
255 | atomic_dec(&qp->refcount); | ||
256 | rcu_assign_pointer(ibp->qp0, NULL); | 258 | rcu_assign_pointer(ibp->qp0, NULL); |
257 | } else if (rcu_dereference_protected(ibp->qp1, | 259 | } else if (rcu_dereference_protected(ibp->qp1, |
258 | lockdep_is_held(&dev->qpt_lock)) == qp) { | 260 | lockdep_is_held(&dev->qpt_lock)) == qp) { |
259 | atomic_dec(&qp->refcount); | ||
260 | rcu_assign_pointer(ibp->qp1, NULL); | 261 | rcu_assign_pointer(ibp->qp1, NULL); |
261 | } else { | 262 | } else { |
262 | struct qib_qp *q; | 263 | struct qib_qp *q; |
263 | struct qib_qp __rcu **qpp; | 264 | struct qib_qp __rcu **qpp; |
264 | 265 | ||
266 | removed = 0; | ||
265 | qpp = &dev->qp_table[n]; | 267 | qpp = &dev->qp_table[n]; |
266 | for (; (q = rcu_dereference_protected(*qpp, | 268 | for (; (q = rcu_dereference_protected(*qpp, |
267 | lockdep_is_held(&dev->qpt_lock))) != NULL; | 269 | lockdep_is_held(&dev->qpt_lock))) != NULL; |
268 | qpp = &q->next) | 270 | qpp = &q->next) |
269 | if (q == qp) { | 271 | if (q == qp) { |
270 | atomic_dec(&qp->refcount); | ||
271 | rcu_assign_pointer(*qpp, | 272 | rcu_assign_pointer(*qpp, |
272 | rcu_dereference_protected(qp->next, | 273 | rcu_dereference_protected(qp->next, |
273 | lockdep_is_held(&dev->qpt_lock))); | 274 | lockdep_is_held(&dev->qpt_lock))); |
275 | removed = 1; | ||
274 | break; | 276 | break; |
275 | } | 277 | } |
276 | } | 278 | } |
277 | 279 | ||
278 | spin_unlock_irqrestore(&dev->qpt_lock, flags); | 280 | spin_unlock_irqrestore(&dev->qpt_lock, flags); |
279 | synchronize_rcu(); | 281 | if (removed) { |
282 | synchronize_rcu(); | ||
283 | atomic_dec(&qp->refcount); | ||
284 | } | ||
280 | } | 285 | } |
281 | 286 | ||
282 | /** | 287 | /** |
@@ -334,26 +339,25 @@ struct qib_qp *qib_lookup_qpn(struct qib_ibport *ibp, u32 qpn) | |||
334 | { | 339 | { |
335 | struct qib_qp *qp = NULL; | 340 | struct qib_qp *qp = NULL; |
336 | 341 | ||
342 | rcu_read_lock(); | ||
337 | if (unlikely(qpn <= 1)) { | 343 | if (unlikely(qpn <= 1)) { |
338 | rcu_read_lock(); | ||
339 | if (qpn == 0) | 344 | if (qpn == 0) |
340 | qp = rcu_dereference(ibp->qp0); | 345 | qp = rcu_dereference(ibp->qp0); |
341 | else | 346 | else |
342 | qp = rcu_dereference(ibp->qp1); | 347 | qp = rcu_dereference(ibp->qp1); |
348 | if (qp) | ||
349 | atomic_inc(&qp->refcount); | ||
343 | } else { | 350 | } else { |
344 | struct qib_ibdev *dev = &ppd_from_ibp(ibp)->dd->verbs_dev; | 351 | struct qib_ibdev *dev = &ppd_from_ibp(ibp)->dd->verbs_dev; |
345 | unsigned n = qpn_hash(dev, qpn); | 352 | unsigned n = qpn_hash(dev, qpn); |
346 | 353 | ||
347 | rcu_read_lock(); | ||
348 | for (qp = rcu_dereference(dev->qp_table[n]); qp; | 354 | for (qp = rcu_dereference(dev->qp_table[n]); qp; |
349 | qp = rcu_dereference(qp->next)) | 355 | qp = rcu_dereference(qp->next)) |
350 | if (qp->ibqp.qp_num == qpn) | 356 | if (qp->ibqp.qp_num == qpn) { |
357 | atomic_inc(&qp->refcount); | ||
351 | break; | 358 | break; |
359 | } | ||
352 | } | 360 | } |
353 | if (qp) | ||
354 | if (unlikely(!atomic_inc_not_zero(&qp->refcount))) | ||
355 | qp = NULL; | ||
356 | |||
357 | rcu_read_unlock(); | 361 | rcu_read_unlock(); |
358 | return qp; | 362 | return qp; |
359 | } | 363 | } |
@@ -1286,3 +1290,94 @@ void qib_get_credit(struct qib_qp *qp, u32 aeth) | |||
1286 | } | 1290 | } |
1287 | } | 1291 | } |
1288 | } | 1292 | } |
1293 | |||
1294 | #ifdef CONFIG_DEBUG_FS | ||
1295 | |||
1296 | struct qib_qp_iter { | ||
1297 | struct qib_ibdev *dev; | ||
1298 | struct qib_qp *qp; | ||
1299 | int n; | ||
1300 | }; | ||
1301 | |||
1302 | struct qib_qp_iter *qib_qp_iter_init(struct qib_ibdev *dev) | ||
1303 | { | ||
1304 | struct qib_qp_iter *iter; | ||
1305 | |||
1306 | iter = kzalloc(sizeof(*iter), GFP_KERNEL); | ||
1307 | if (!iter) | ||
1308 | return NULL; | ||
1309 | |||
1310 | iter->dev = dev; | ||
1311 | if (qib_qp_iter_next(iter)) { | ||
1312 | kfree(iter); | ||
1313 | return NULL; | ||
1314 | } | ||
1315 | |||
1316 | return iter; | ||
1317 | } | ||
1318 | |||
1319 | int qib_qp_iter_next(struct qib_qp_iter *iter) | ||
1320 | { | ||
1321 | struct qib_ibdev *dev = iter->dev; | ||
1322 | int n = iter->n; | ||
1323 | int ret = 1; | ||
1324 | struct qib_qp *pqp = iter->qp; | ||
1325 | struct qib_qp *qp; | ||
1326 | |||
1327 | rcu_read_lock(); | ||
1328 | for (; n < dev->qp_table_size; n++) { | ||
1329 | if (pqp) | ||
1330 | qp = rcu_dereference(pqp->next); | ||
1331 | else | ||
1332 | qp = rcu_dereference(dev->qp_table[n]); | ||
1333 | pqp = qp; | ||
1334 | if (qp) { | ||
1335 | if (iter->qp) | ||
1336 | atomic_dec(&iter->qp->refcount); | ||
1337 | atomic_inc(&qp->refcount); | ||
1338 | rcu_read_unlock(); | ||
1339 | iter->qp = qp; | ||
1340 | iter->n = n; | ||
1341 | return 0; | ||
1342 | } | ||
1343 | } | ||
1344 | rcu_read_unlock(); | ||
1345 | if (iter->qp) | ||
1346 | atomic_dec(&iter->qp->refcount); | ||
1347 | return ret; | ||
1348 | } | ||
1349 | |||
1350 | static const char * const qp_type_str[] = { | ||
1351 | "SMI", "GSI", "RC", "UC", "UD", | ||
1352 | }; | ||
1353 | |||
1354 | void qib_qp_iter_print(struct seq_file *s, struct qib_qp_iter *iter) | ||
1355 | { | ||
1356 | struct qib_swqe *wqe; | ||
1357 | struct qib_qp *qp = iter->qp; | ||
1358 | |||
1359 | wqe = get_swqe_ptr(qp, qp->s_last); | ||
1360 | seq_printf(s, | ||
1361 | "N %d QP%u %s %u %u %u f=%x %u %u %u %u %u PSN %x %x %x %x %x (%u %u %u %u %u %u) QP%u LID %x\n", | ||
1362 | iter->n, | ||
1363 | qp->ibqp.qp_num, | ||
1364 | qp_type_str[qp->ibqp.qp_type], | ||
1365 | qp->state, | ||
1366 | wqe->wr.opcode, | ||
1367 | qp->s_hdrwords, | ||
1368 | qp->s_flags, | ||
1369 | atomic_read(&qp->s_dma_busy), | ||
1370 | !list_empty(&qp->iowait), | ||
1371 | qp->timeout, | ||
1372 | wqe->ssn, | ||
1373 | qp->s_lsn, | ||
1374 | qp->s_last_psn, | ||
1375 | qp->s_psn, qp->s_next_psn, | ||
1376 | qp->s_sending_psn, qp->s_sending_hpsn, | ||
1377 | qp->s_last, qp->s_acked, qp->s_cur, | ||
1378 | qp->s_tail, qp->s_head, qp->s_size, | ||
1379 | qp->remote_qpn, | ||
1380 | qp->remote_ah_attr.dlid); | ||
1381 | } | ||
1382 | |||
1383 | #endif | ||
diff --git a/drivers/infiniband/hw/qib/qib_verbs.c b/drivers/infiniband/hw/qib/qib_verbs.c index 904c384aa361..092b0bb1bb78 100644 --- a/drivers/infiniband/hw/qib/qib_verbs.c +++ b/drivers/infiniband/hw/qib/qib_verbs.c | |||
@@ -645,9 +645,11 @@ void qib_ib_rcv(struct qib_ctxtdata *rcd, void *rhdr, void *data, u32 tlen) | |||
645 | } else | 645 | } else |
646 | goto drop; | 646 | goto drop; |
647 | 647 | ||
648 | opcode = be32_to_cpu(ohdr->bth[0]) >> 24; | 648 | opcode = (be32_to_cpu(ohdr->bth[0]) >> 24) & 0x7f; |
649 | ibp->opstats[opcode & 0x7f].n_bytes += tlen; | 649 | #ifdef CONFIG_DEBUG_FS |
650 | ibp->opstats[opcode & 0x7f].n_packets++; | 650 | rcd->opstats->stats[opcode].n_bytes += tlen; |
651 | rcd->opstats->stats[opcode].n_packets++; | ||
652 | #endif | ||
651 | 653 | ||
652 | /* Get the destination QP number. */ | 654 | /* Get the destination QP number. */ |
653 | qp_num = be32_to_cpu(ohdr->bth[1]) & QIB_QPN_MASK; | 655 | qp_num = be32_to_cpu(ohdr->bth[1]) & QIB_QPN_MASK; |
diff --git a/drivers/infiniband/hw/qib/qib_verbs.h b/drivers/infiniband/hw/qib/qib_verbs.h index aff8b2c17886..012e2c7575ad 100644 --- a/drivers/infiniband/hw/qib/qib_verbs.h +++ b/drivers/infiniband/hw/qib/qib_verbs.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2012 Intel Corporation. All rights reserved. | 2 | * Copyright (c) 2012, 2013 Intel Corporation. All rights reserved. |
3 | * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved. | 3 | * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved. |
4 | * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. | 4 | * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved. |
5 | * | 5 | * |
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/interrupt.h> | 41 | #include <linux/interrupt.h> |
42 | #include <linux/kref.h> | 42 | #include <linux/kref.h> |
43 | #include <linux/workqueue.h> | 43 | #include <linux/workqueue.h> |
44 | #include <linux/kthread.h> | ||
44 | #include <linux/completion.h> | 45 | #include <linux/completion.h> |
45 | #include <rdma/ib_pack.h> | 46 | #include <rdma/ib_pack.h> |
46 | #include <rdma/ib_user_verbs.h> | 47 | #include <rdma/ib_user_verbs.h> |
@@ -267,7 +268,8 @@ struct qib_cq_wc { | |||
267 | */ | 268 | */ |
268 | struct qib_cq { | 269 | struct qib_cq { |
269 | struct ib_cq ibcq; | 270 | struct ib_cq ibcq; |
270 | struct work_struct comptask; | 271 | struct kthread_work comptask; |
272 | struct qib_devdata *dd; | ||
271 | spinlock_t lock; /* protect changes in this struct */ | 273 | spinlock_t lock; /* protect changes in this struct */ |
272 | u8 notify; | 274 | u8 notify; |
273 | u8 triggered; | 275 | u8 triggered; |
@@ -658,6 +660,10 @@ struct qib_opcode_stats { | |||
658 | u64 n_bytes; /* total number of bytes */ | 660 | u64 n_bytes; /* total number of bytes */ |
659 | }; | 661 | }; |
660 | 662 | ||
663 | struct qib_opcode_stats_perctx { | ||
664 | struct qib_opcode_stats stats[128]; | ||
665 | }; | ||
666 | |||
661 | struct qib_ibport { | 667 | struct qib_ibport { |
662 | struct qib_qp __rcu *qp0; | 668 | struct qib_qp __rcu *qp0; |
663 | struct qib_qp __rcu *qp1; | 669 | struct qib_qp __rcu *qp1; |
@@ -724,7 +730,6 @@ struct qib_ibport { | |||
724 | u8 vl_high_limit; | 730 | u8 vl_high_limit; |
725 | u8 sl_to_vl[16]; | 731 | u8 sl_to_vl[16]; |
726 | 732 | ||
727 | struct qib_opcode_stats opstats[128]; | ||
728 | }; | 733 | }; |
729 | 734 | ||
730 | 735 | ||
@@ -768,6 +773,10 @@ struct qib_ibdev { | |||
768 | spinlock_t n_srqs_lock; | 773 | spinlock_t n_srqs_lock; |
769 | u32 n_mcast_grps_allocated; /* number of mcast groups allocated */ | 774 | u32 n_mcast_grps_allocated; /* number of mcast groups allocated */ |
770 | spinlock_t n_mcast_grps_lock; | 775 | spinlock_t n_mcast_grps_lock; |
776 | #ifdef CONFIG_DEBUG_FS | ||
777 | /* per HCA debugfs */ | ||
778 | struct dentry *qib_ibdev_dbg; | ||
779 | #endif | ||
771 | }; | 780 | }; |
772 | 781 | ||
773 | struct qib_verbs_counters { | 782 | struct qib_verbs_counters { |
@@ -832,8 +841,6 @@ static inline int qib_send_ok(struct qib_qp *qp) | |||
832 | !(qp->s_flags & QIB_S_ANY_WAIT_SEND)); | 841 | !(qp->s_flags & QIB_S_ANY_WAIT_SEND)); |
833 | } | 842 | } |
834 | 843 | ||
835 | extern struct workqueue_struct *qib_cq_wq; | ||
836 | |||
837 | /* | 844 | /* |
838 | * This must be called with s_lock held. | 845 | * This must be called with s_lock held. |
839 | */ | 846 | */ |
@@ -910,6 +917,18 @@ void qib_init_qpn_table(struct qib_devdata *dd, struct qib_qpn_table *qpt); | |||
910 | 917 | ||
911 | void qib_free_qpn_table(struct qib_qpn_table *qpt); | 918 | void qib_free_qpn_table(struct qib_qpn_table *qpt); |
912 | 919 | ||
920 | #ifdef CONFIG_DEBUG_FS | ||
921 | |||
922 | struct qib_qp_iter; | ||
923 | |||
924 | struct qib_qp_iter *qib_qp_iter_init(struct qib_ibdev *dev); | ||
925 | |||
926 | int qib_qp_iter_next(struct qib_qp_iter *iter); | ||
927 | |||
928 | void qib_qp_iter_print(struct seq_file *s, struct qib_qp_iter *iter); | ||
929 | |||
930 | #endif | ||
931 | |||
913 | void qib_get_credit(struct qib_qp *qp, u32 aeth); | 932 | void qib_get_credit(struct qib_qp *qp, u32 aeth); |
914 | 933 | ||
915 | unsigned qib_pkt_delay(u32 plen, u8 snd_mult, u8 rcv_mult); | 934 | unsigned qib_pkt_delay(u32 plen, u8 snd_mult, u8 rcv_mult); |
@@ -972,6 +991,10 @@ int qib_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr); | |||
972 | 991 | ||
973 | int qib_destroy_srq(struct ib_srq *ibsrq); | 992 | int qib_destroy_srq(struct ib_srq *ibsrq); |
974 | 993 | ||
994 | int qib_cq_init(struct qib_devdata *dd); | ||
995 | |||
996 | void qib_cq_exit(struct qib_devdata *dd); | ||
997 | |||
975 | void qib_cq_enter(struct qib_cq *cq, struct ib_wc *entry, int sig); | 998 | void qib_cq_enter(struct qib_cq *cq, struct ib_wc *entry, int sig); |
976 | 999 | ||
977 | int qib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry); | 1000 | int qib_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *entry); |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 7ccf3284dda3..9d8b46eafdb2 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
@@ -53,8 +53,8 @@ | |||
53 | 53 | ||
54 | #define DRV_NAME "ib_srp" | 54 | #define DRV_NAME "ib_srp" |
55 | #define PFX DRV_NAME ": " | 55 | #define PFX DRV_NAME ": " |
56 | #define DRV_VERSION "0.2" | 56 | #define DRV_VERSION "1.0" |
57 | #define DRV_RELDATE "November 1, 2005" | 57 | #define DRV_RELDATE "July 1, 2013" |
58 | 58 | ||
59 | MODULE_AUTHOR("Roland Dreier"); | 59 | MODULE_AUTHOR("Roland Dreier"); |
60 | MODULE_DESCRIPTION("InfiniBand SCSI RDMA Protocol initiator " | 60 | MODULE_DESCRIPTION("InfiniBand SCSI RDMA Protocol initiator " |
@@ -231,14 +231,16 @@ static int srp_create_target_ib(struct srp_target_port *target) | |||
231 | return -ENOMEM; | 231 | return -ENOMEM; |
232 | 232 | ||
233 | recv_cq = ib_create_cq(target->srp_host->srp_dev->dev, | 233 | recv_cq = ib_create_cq(target->srp_host->srp_dev->dev, |
234 | srp_recv_completion, NULL, target, SRP_RQ_SIZE, 0); | 234 | srp_recv_completion, NULL, target, SRP_RQ_SIZE, |
235 | target->comp_vector); | ||
235 | if (IS_ERR(recv_cq)) { | 236 | if (IS_ERR(recv_cq)) { |
236 | ret = PTR_ERR(recv_cq); | 237 | ret = PTR_ERR(recv_cq); |
237 | goto err; | 238 | goto err; |
238 | } | 239 | } |
239 | 240 | ||
240 | send_cq = ib_create_cq(target->srp_host->srp_dev->dev, | 241 | send_cq = ib_create_cq(target->srp_host->srp_dev->dev, |
241 | srp_send_completion, NULL, target, SRP_SQ_SIZE, 0); | 242 | srp_send_completion, NULL, target, SRP_SQ_SIZE, |
243 | target->comp_vector); | ||
242 | if (IS_ERR(send_cq)) { | 244 | if (IS_ERR(send_cq)) { |
243 | ret = PTR_ERR(send_cq); | 245 | ret = PTR_ERR(send_cq); |
244 | goto err_recv_cq; | 246 | goto err_recv_cq; |
@@ -542,11 +544,11 @@ static void srp_remove_work(struct work_struct *work) | |||
542 | 544 | ||
543 | WARN_ON_ONCE(target->state != SRP_TARGET_REMOVED); | 545 | WARN_ON_ONCE(target->state != SRP_TARGET_REMOVED); |
544 | 546 | ||
547 | srp_remove_target(target); | ||
548 | |||
545 | spin_lock(&target->srp_host->target_lock); | 549 | spin_lock(&target->srp_host->target_lock); |
546 | list_del(&target->list); | 550 | list_del(&target->list); |
547 | spin_unlock(&target->srp_host->target_lock); | 551 | spin_unlock(&target->srp_host->target_lock); |
548 | |||
549 | srp_remove_target(target); | ||
550 | } | 552 | } |
551 | 553 | ||
552 | static void srp_rport_delete(struct srp_rport *rport) | 554 | static void srp_rport_delete(struct srp_rport *rport) |
@@ -1744,18 +1746,25 @@ static int srp_abort(struct scsi_cmnd *scmnd) | |||
1744 | { | 1746 | { |
1745 | struct srp_target_port *target = host_to_target(scmnd->device->host); | 1747 | struct srp_target_port *target = host_to_target(scmnd->device->host); |
1746 | struct srp_request *req = (struct srp_request *) scmnd->host_scribble; | 1748 | struct srp_request *req = (struct srp_request *) scmnd->host_scribble; |
1749 | int ret; | ||
1747 | 1750 | ||
1748 | shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n"); | 1751 | shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n"); |
1749 | 1752 | ||
1750 | if (!req || !srp_claim_req(target, req, scmnd)) | 1753 | if (!req || !srp_claim_req(target, req, scmnd)) |
1751 | return FAILED; | 1754 | return FAILED; |
1752 | srp_send_tsk_mgmt(target, req->index, scmnd->device->lun, | 1755 | if (srp_send_tsk_mgmt(target, req->index, scmnd->device->lun, |
1753 | SRP_TSK_ABORT_TASK); | 1756 | SRP_TSK_ABORT_TASK) == 0 || |
1757 | target->transport_offline) | ||
1758 | ret = SUCCESS; | ||
1759 | else if (target->transport_offline) | ||
1760 | ret = FAST_IO_FAIL; | ||
1761 | else | ||
1762 | ret = FAILED; | ||
1754 | srp_free_req(target, req, scmnd, 0); | 1763 | srp_free_req(target, req, scmnd, 0); |
1755 | scmnd->result = DID_ABORT << 16; | 1764 | scmnd->result = DID_ABORT << 16; |
1756 | scmnd->scsi_done(scmnd); | 1765 | scmnd->scsi_done(scmnd); |
1757 | 1766 | ||
1758 | return SUCCESS; | 1767 | return ret; |
1759 | } | 1768 | } |
1760 | 1769 | ||
1761 | static int srp_reset_device(struct scsi_cmnd *scmnd) | 1770 | static int srp_reset_device(struct scsi_cmnd *scmnd) |
@@ -1891,6 +1900,14 @@ static ssize_t show_local_ib_device(struct device *dev, | |||
1891 | return sprintf(buf, "%s\n", target->srp_host->srp_dev->dev->name); | 1900 | return sprintf(buf, "%s\n", target->srp_host->srp_dev->dev->name); |
1892 | } | 1901 | } |
1893 | 1902 | ||
1903 | static ssize_t show_comp_vector(struct device *dev, | ||
1904 | struct device_attribute *attr, char *buf) | ||
1905 | { | ||
1906 | struct srp_target_port *target = host_to_target(class_to_shost(dev)); | ||
1907 | |||
1908 | return sprintf(buf, "%d\n", target->comp_vector); | ||
1909 | } | ||
1910 | |||
1894 | static ssize_t show_cmd_sg_entries(struct device *dev, | 1911 | static ssize_t show_cmd_sg_entries(struct device *dev, |
1895 | struct device_attribute *attr, char *buf) | 1912 | struct device_attribute *attr, char *buf) |
1896 | { | 1913 | { |
@@ -1917,6 +1934,7 @@ static DEVICE_ATTR(req_lim, S_IRUGO, show_req_lim, NULL); | |||
1917 | static DEVICE_ATTR(zero_req_lim, S_IRUGO, show_zero_req_lim, NULL); | 1934 | static DEVICE_ATTR(zero_req_lim, S_IRUGO, show_zero_req_lim, NULL); |
1918 | static DEVICE_ATTR(local_ib_port, S_IRUGO, show_local_ib_port, NULL); | 1935 | static DEVICE_ATTR(local_ib_port, S_IRUGO, show_local_ib_port, NULL); |
1919 | static DEVICE_ATTR(local_ib_device, S_IRUGO, show_local_ib_device, NULL); | 1936 | static DEVICE_ATTR(local_ib_device, S_IRUGO, show_local_ib_device, NULL); |
1937 | static DEVICE_ATTR(comp_vector, S_IRUGO, show_comp_vector, NULL); | ||
1920 | static DEVICE_ATTR(cmd_sg_entries, S_IRUGO, show_cmd_sg_entries, NULL); | 1938 | static DEVICE_ATTR(cmd_sg_entries, S_IRUGO, show_cmd_sg_entries, NULL); |
1921 | static DEVICE_ATTR(allow_ext_sg, S_IRUGO, show_allow_ext_sg, NULL); | 1939 | static DEVICE_ATTR(allow_ext_sg, S_IRUGO, show_allow_ext_sg, NULL); |
1922 | 1940 | ||
@@ -1931,6 +1949,7 @@ static struct device_attribute *srp_host_attrs[] = { | |||
1931 | &dev_attr_zero_req_lim, | 1949 | &dev_attr_zero_req_lim, |
1932 | &dev_attr_local_ib_port, | 1950 | &dev_attr_local_ib_port, |
1933 | &dev_attr_local_ib_device, | 1951 | &dev_attr_local_ib_device, |
1952 | &dev_attr_comp_vector, | ||
1934 | &dev_attr_cmd_sg_entries, | 1953 | &dev_attr_cmd_sg_entries, |
1935 | &dev_attr_allow_ext_sg, | 1954 | &dev_attr_allow_ext_sg, |
1936 | NULL | 1955 | NULL |
@@ -1946,6 +1965,7 @@ static struct scsi_host_template srp_template = { | |||
1946 | .eh_abort_handler = srp_abort, | 1965 | .eh_abort_handler = srp_abort, |
1947 | .eh_device_reset_handler = srp_reset_device, | 1966 | .eh_device_reset_handler = srp_reset_device, |
1948 | .eh_host_reset_handler = srp_reset_host, | 1967 | .eh_host_reset_handler = srp_reset_host, |
1968 | .skip_settle_delay = true, | ||
1949 | .sg_tablesize = SRP_DEF_SG_TABLESIZE, | 1969 | .sg_tablesize = SRP_DEF_SG_TABLESIZE, |
1950 | .can_queue = SRP_CMD_SQ_SIZE, | 1970 | .can_queue = SRP_CMD_SQ_SIZE, |
1951 | .this_id = -1, | 1971 | .this_id = -1, |
@@ -2001,6 +2021,36 @@ static struct class srp_class = { | |||
2001 | .dev_release = srp_release_dev | 2021 | .dev_release = srp_release_dev |
2002 | }; | 2022 | }; |
2003 | 2023 | ||
2024 | /** | ||
2025 | * srp_conn_unique() - check whether the connection to a target is unique | ||
2026 | */ | ||
2027 | static bool srp_conn_unique(struct srp_host *host, | ||
2028 | struct srp_target_port *target) | ||
2029 | { | ||
2030 | struct srp_target_port *t; | ||
2031 | bool ret = false; | ||
2032 | |||
2033 | if (target->state == SRP_TARGET_REMOVED) | ||
2034 | goto out; | ||
2035 | |||
2036 | ret = true; | ||
2037 | |||
2038 | spin_lock(&host->target_lock); | ||
2039 | list_for_each_entry(t, &host->target_list, list) { | ||
2040 | if (t != target && | ||
2041 | target->id_ext == t->id_ext && | ||
2042 | target->ioc_guid == t->ioc_guid && | ||
2043 | target->initiator_ext == t->initiator_ext) { | ||
2044 | ret = false; | ||
2045 | break; | ||
2046 | } | ||
2047 | } | ||
2048 | spin_unlock(&host->target_lock); | ||
2049 | |||
2050 | out: | ||
2051 | return ret; | ||
2052 | } | ||
2053 | |||
2004 | /* | 2054 | /* |
2005 | * Target ports are added by writing | 2055 | * Target ports are added by writing |
2006 | * | 2056 | * |
@@ -2023,6 +2073,7 @@ enum { | |||
2023 | SRP_OPT_CMD_SG_ENTRIES = 1 << 9, | 2073 | SRP_OPT_CMD_SG_ENTRIES = 1 << 9, |
2024 | SRP_OPT_ALLOW_EXT_SG = 1 << 10, | 2074 | SRP_OPT_ALLOW_EXT_SG = 1 << 10, |
2025 | SRP_OPT_SG_TABLESIZE = 1 << 11, | 2075 | SRP_OPT_SG_TABLESIZE = 1 << 11, |
2076 | SRP_OPT_COMP_VECTOR = 1 << 12, | ||
2026 | SRP_OPT_ALL = (SRP_OPT_ID_EXT | | 2077 | SRP_OPT_ALL = (SRP_OPT_ID_EXT | |
2027 | SRP_OPT_IOC_GUID | | 2078 | SRP_OPT_IOC_GUID | |
2028 | SRP_OPT_DGID | | 2079 | SRP_OPT_DGID | |
@@ -2043,6 +2094,7 @@ static const match_table_t srp_opt_tokens = { | |||
2043 | { SRP_OPT_CMD_SG_ENTRIES, "cmd_sg_entries=%u" }, | 2094 | { SRP_OPT_CMD_SG_ENTRIES, "cmd_sg_entries=%u" }, |
2044 | { SRP_OPT_ALLOW_EXT_SG, "allow_ext_sg=%u" }, | 2095 | { SRP_OPT_ALLOW_EXT_SG, "allow_ext_sg=%u" }, |
2045 | { SRP_OPT_SG_TABLESIZE, "sg_tablesize=%u" }, | 2096 | { SRP_OPT_SG_TABLESIZE, "sg_tablesize=%u" }, |
2097 | { SRP_OPT_COMP_VECTOR, "comp_vector=%u" }, | ||
2046 | { SRP_OPT_ERR, NULL } | 2098 | { SRP_OPT_ERR, NULL } |
2047 | }; | 2099 | }; |
2048 | 2100 | ||
@@ -2198,6 +2250,14 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) | |||
2198 | target->sg_tablesize = token; | 2250 | target->sg_tablesize = token; |
2199 | break; | 2251 | break; |
2200 | 2252 | ||
2253 | case SRP_OPT_COMP_VECTOR: | ||
2254 | if (match_int(args, &token) || token < 0) { | ||
2255 | pr_warn("bad comp_vector parameter '%s'\n", p); | ||
2256 | goto out; | ||
2257 | } | ||
2258 | target->comp_vector = token; | ||
2259 | break; | ||
2260 | |||
2201 | default: | 2261 | default: |
2202 | pr_warn("unknown parameter or missing value '%s' in target creation request\n", | 2262 | pr_warn("unknown parameter or missing value '%s' in target creation request\n", |
2203 | p); | 2263 | p); |
@@ -2257,6 +2317,16 @@ static ssize_t srp_create_target(struct device *dev, | |||
2257 | if (ret) | 2317 | if (ret) |
2258 | goto err; | 2318 | goto err; |
2259 | 2319 | ||
2320 | if (!srp_conn_unique(target->srp_host, target)) { | ||
2321 | shost_printk(KERN_INFO, target->scsi_host, | ||
2322 | PFX "Already connected to target port with id_ext=%016llx;ioc_guid=%016llx;initiator_ext=%016llx\n", | ||
2323 | be64_to_cpu(target->id_ext), | ||
2324 | be64_to_cpu(target->ioc_guid), | ||
2325 | be64_to_cpu(target->initiator_ext)); | ||
2326 | ret = -EEXIST; | ||
2327 | goto err; | ||
2328 | } | ||
2329 | |||
2260 | if (!host->srp_dev->fmr_pool && !target->allow_ext_sg && | 2330 | if (!host->srp_dev->fmr_pool && !target->allow_ext_sg && |
2261 | target->cmd_sg_cnt < target->sg_tablesize) { | 2331 | target->cmd_sg_cnt < target->sg_tablesize) { |
2262 | pr_warn("No FMR pool and no external indirect descriptors, limiting sg_tablesize to cmd_sg_cnt\n"); | 2332 | pr_warn("No FMR pool and no external indirect descriptors, limiting sg_tablesize to cmd_sg_cnt\n"); |
@@ -2507,6 +2577,8 @@ static void srp_remove_one(struct ib_device *device) | |||
2507 | struct srp_target_port *target; | 2577 | struct srp_target_port *target; |
2508 | 2578 | ||
2509 | srp_dev = ib_get_client_data(device, &srp_client); | 2579 | srp_dev = ib_get_client_data(device, &srp_client); |
2580 | if (!srp_dev) | ||
2581 | return; | ||
2510 | 2582 | ||
2511 | list_for_each_entry_safe(host, tmp_host, &srp_dev->dev_list, list) { | 2583 | list_for_each_entry_safe(host, tmp_host, &srp_dev->dev_list, list) { |
2512 | device_unregister(&host->dev); | 2584 | device_unregister(&host->dev); |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h index 66fbedda4571..e641088c14dc 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.h +++ b/drivers/infiniband/ulp/srp/ib_srp.h | |||
@@ -156,6 +156,7 @@ struct srp_target_port { | |||
156 | char target_name[32]; | 156 | char target_name[32]; |
157 | unsigned int scsi_id; | 157 | unsigned int scsi_id; |
158 | unsigned int sg_tablesize; | 158 | unsigned int sg_tablesize; |
159 | int comp_vector; | ||
159 | 160 | ||
160 | struct ib_sa_path_rec path; | 161 | struct ib_sa_path_rec path; |
161 | __be16 orig_dgid[8]; | 162 | __be16 orig_dgid[8]; |