diff options
author | Sean Hefty <sean.hefty@intel.com> | 2007-06-18 14:03:58 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2007-07-11 00:45:31 -0400 |
commit | 2aec5c602c6a44e2a3a173339a9ab94549658e4b (patch) | |
tree | b16a5002a07d96b88ad162ac34d628b531844a6f /drivers/infiniband | |
parent | 1b844afe9e67d6cd441ae6df71051b4004f31dd2 (diff) |
IB/sa: Make sure SA queries use default P_Key
MADs sent to the SA should use the the default P_Key (0x7fff/0xffff).
There's no requirement that the default P_Key is stored at index 0 in
the local P_Key table, so add code to the sa_query module to look up
the index of the default P_Key when creating an address handle for the
SA (which is done any time the P_Key table might change), and use this
index for all SA queries.
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/core/sa_query.c | 85 |
1 files changed, 50 insertions, 35 deletions
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 9d3797fcc37e..20ab6b3e484d 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c | |||
@@ -56,6 +56,7 @@ MODULE_LICENSE("Dual BSD/GPL"); | |||
56 | struct ib_sa_sm_ah { | 56 | struct ib_sa_sm_ah { |
57 | struct ib_ah *ah; | 57 | struct ib_ah *ah; |
58 | struct kref ref; | 58 | struct kref ref; |
59 | u16 pkey_index; | ||
59 | u8 src_path_mask; | 60 | u8 src_path_mask; |
60 | }; | 61 | }; |
61 | 62 | ||
@@ -382,6 +383,13 @@ static void update_sm_ah(struct work_struct *work) | |||
382 | kref_init(&new_ah->ref); | 383 | kref_init(&new_ah->ref); |
383 | new_ah->src_path_mask = (1 << port_attr.lmc) - 1; | 384 | new_ah->src_path_mask = (1 << port_attr.lmc) - 1; |
384 | 385 | ||
386 | new_ah->pkey_index = 0; | ||
387 | if (ib_find_pkey(port->agent->device, port->port_num, | ||
388 | IB_DEFAULT_PKEY_FULL, &new_ah->pkey_index) && | ||
389 | ib_find_pkey(port->agent->device, port->port_num, | ||
390 | IB_DEFAULT_PKEY_PARTIAL, &new_ah->pkey_index)) | ||
391 | printk(KERN_ERR "Couldn't find index for default PKey\n"); | ||
392 | |||
385 | memset(&ah_attr, 0, sizeof ah_attr); | 393 | memset(&ah_attr, 0, sizeof ah_attr); |
386 | ah_attr.dlid = port_attr.sm_lid; | 394 | ah_attr.dlid = port_attr.sm_lid; |
387 | ah_attr.sl = port_attr.sm_sl; | 395 | ah_attr.sl = port_attr.sm_sl; |
@@ -512,6 +520,35 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num, | |||
512 | } | 520 | } |
513 | EXPORT_SYMBOL(ib_init_ah_from_path); | 521 | EXPORT_SYMBOL(ib_init_ah_from_path); |
514 | 522 | ||
523 | static int alloc_mad(struct ib_sa_query *query, gfp_t gfp_mask) | ||
524 | { | ||
525 | unsigned long flags; | ||
526 | |||
527 | spin_lock_irqsave(&query->port->ah_lock, flags); | ||
528 | kref_get(&query->port->sm_ah->ref); | ||
529 | query->sm_ah = query->port->sm_ah; | ||
530 | spin_unlock_irqrestore(&query->port->ah_lock, flags); | ||
531 | |||
532 | query->mad_buf = ib_create_send_mad(query->port->agent, 1, | ||
533 | query->sm_ah->pkey_index, | ||
534 | 0, IB_MGMT_SA_HDR, IB_MGMT_SA_DATA, | ||
535 | gfp_mask); | ||
536 | if (!query->mad_buf) { | ||
537 | kref_put(&query->sm_ah->ref, free_sm_ah); | ||
538 | return -ENOMEM; | ||
539 | } | ||
540 | |||
541 | query->mad_buf->ah = query->sm_ah->ah; | ||
542 | |||
543 | return 0; | ||
544 | } | ||
545 | |||
546 | static void free_mad(struct ib_sa_query *query) | ||
547 | { | ||
548 | ib_free_send_mad(query->mad_buf); | ||
549 | kref_put(&query->sm_ah->ref, free_sm_ah); | ||
550 | } | ||
551 | |||
515 | static void init_mad(struct ib_sa_mad *mad, struct ib_mad_agent *agent) | 552 | static void init_mad(struct ib_sa_mad *mad, struct ib_mad_agent *agent) |
516 | { | 553 | { |
517 | unsigned long flags; | 554 | unsigned long flags; |
@@ -548,20 +585,11 @@ retry: | |||
548 | query->mad_buf->context[0] = query; | 585 | query->mad_buf->context[0] = query; |
549 | query->id = id; | 586 | query->id = id; |
550 | 587 | ||
551 | spin_lock_irqsave(&query->port->ah_lock, flags); | ||
552 | kref_get(&query->port->sm_ah->ref); | ||
553 | query->sm_ah = query->port->sm_ah; | ||
554 | spin_unlock_irqrestore(&query->port->ah_lock, flags); | ||
555 | |||
556 | query->mad_buf->ah = query->sm_ah->ah; | ||
557 | |||
558 | ret = ib_post_send_mad(query->mad_buf, NULL); | 588 | ret = ib_post_send_mad(query->mad_buf, NULL); |
559 | if (ret) { | 589 | if (ret) { |
560 | spin_lock_irqsave(&idr_lock, flags); | 590 | spin_lock_irqsave(&idr_lock, flags); |
561 | idr_remove(&query_idr, id); | 591 | idr_remove(&query_idr, id); |
562 | spin_unlock_irqrestore(&idr_lock, flags); | 592 | spin_unlock_irqrestore(&idr_lock, flags); |
563 | |||
564 | kref_put(&query->sm_ah->ref, free_sm_ah); | ||
565 | } | 593 | } |
566 | 594 | ||
567 | /* | 595 | /* |
@@ -647,13 +675,10 @@ int ib_sa_path_rec_get(struct ib_sa_client *client, | |||
647 | if (!query) | 675 | if (!query) |
648 | return -ENOMEM; | 676 | return -ENOMEM; |
649 | 677 | ||
650 | query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0, | 678 | query->sa_query.port = port; |
651 | 0, IB_MGMT_SA_HDR, | 679 | ret = alloc_mad(&query->sa_query, gfp_mask); |
652 | IB_MGMT_SA_DATA, gfp_mask); | 680 | if (ret) |
653 | if (!query->sa_query.mad_buf) { | ||
654 | ret = -ENOMEM; | ||
655 | goto err1; | 681 | goto err1; |
656 | } | ||
657 | 682 | ||
658 | ib_sa_client_get(client); | 683 | ib_sa_client_get(client); |
659 | query->sa_query.client = client; | 684 | query->sa_query.client = client; |
@@ -665,7 +690,6 @@ int ib_sa_path_rec_get(struct ib_sa_client *client, | |||
665 | 690 | ||
666 | query->sa_query.callback = callback ? ib_sa_path_rec_callback : NULL; | 691 | query->sa_query.callback = callback ? ib_sa_path_rec_callback : NULL; |
667 | query->sa_query.release = ib_sa_path_rec_release; | 692 | query->sa_query.release = ib_sa_path_rec_release; |
668 | query->sa_query.port = port; | ||
669 | mad->mad_hdr.method = IB_MGMT_METHOD_GET; | 693 | mad->mad_hdr.method = IB_MGMT_METHOD_GET; |
670 | mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_PATH_REC); | 694 | mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_PATH_REC); |
671 | mad->sa_hdr.comp_mask = comp_mask; | 695 | mad->sa_hdr.comp_mask = comp_mask; |
@@ -683,7 +707,7 @@ int ib_sa_path_rec_get(struct ib_sa_client *client, | |||
683 | err2: | 707 | err2: |
684 | *sa_query = NULL; | 708 | *sa_query = NULL; |
685 | ib_sa_client_put(query->sa_query.client); | 709 | ib_sa_client_put(query->sa_query.client); |
686 | ib_free_send_mad(query->sa_query.mad_buf); | 710 | free_mad(&query->sa_query); |
687 | 711 | ||
688 | err1: | 712 | err1: |
689 | kfree(query); | 713 | kfree(query); |
@@ -773,13 +797,10 @@ int ib_sa_service_rec_query(struct ib_sa_client *client, | |||
773 | if (!query) | 797 | if (!query) |
774 | return -ENOMEM; | 798 | return -ENOMEM; |
775 | 799 | ||
776 | query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0, | 800 | query->sa_query.port = port; |
777 | 0, IB_MGMT_SA_HDR, | 801 | ret = alloc_mad(&query->sa_query, gfp_mask); |
778 | IB_MGMT_SA_DATA, gfp_mask); | 802 | if (ret) |
779 | if (!query->sa_query.mad_buf) { | ||
780 | ret = -ENOMEM; | ||
781 | goto err1; | 803 | goto err1; |
782 | } | ||
783 | 804 | ||
784 | ib_sa_client_get(client); | 805 | ib_sa_client_get(client); |
785 | query->sa_query.client = client; | 806 | query->sa_query.client = client; |
@@ -791,7 +812,6 @@ int ib_sa_service_rec_query(struct ib_sa_client *client, | |||
791 | 812 | ||
792 | query->sa_query.callback = callback ? ib_sa_service_rec_callback : NULL; | 813 | query->sa_query.callback = callback ? ib_sa_service_rec_callback : NULL; |
793 | query->sa_query.release = ib_sa_service_rec_release; | 814 | query->sa_query.release = ib_sa_service_rec_release; |
794 | query->sa_query.port = port; | ||
795 | mad->mad_hdr.method = method; | 815 | mad->mad_hdr.method = method; |
796 | mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_SERVICE_REC); | 816 | mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_SERVICE_REC); |
797 | mad->sa_hdr.comp_mask = comp_mask; | 817 | mad->sa_hdr.comp_mask = comp_mask; |
@@ -810,7 +830,7 @@ int ib_sa_service_rec_query(struct ib_sa_client *client, | |||
810 | err2: | 830 | err2: |
811 | *sa_query = NULL; | 831 | *sa_query = NULL; |
812 | ib_sa_client_put(query->sa_query.client); | 832 | ib_sa_client_put(query->sa_query.client); |
813 | ib_free_send_mad(query->sa_query.mad_buf); | 833 | free_mad(&query->sa_query); |
814 | 834 | ||
815 | err1: | 835 | err1: |
816 | kfree(query); | 836 | kfree(query); |
@@ -869,13 +889,10 @@ int ib_sa_mcmember_rec_query(struct ib_sa_client *client, | |||
869 | if (!query) | 889 | if (!query) |
870 | return -ENOMEM; | 890 | return -ENOMEM; |
871 | 891 | ||
872 | query->sa_query.mad_buf = ib_create_send_mad(agent, 1, 0, | 892 | query->sa_query.port = port; |
873 | 0, IB_MGMT_SA_HDR, | 893 | ret = alloc_mad(&query->sa_query, gfp_mask); |
874 | IB_MGMT_SA_DATA, gfp_mask); | 894 | if (ret) |
875 | if (!query->sa_query.mad_buf) { | ||
876 | ret = -ENOMEM; | ||
877 | goto err1; | 895 | goto err1; |
878 | } | ||
879 | 896 | ||
880 | ib_sa_client_get(client); | 897 | ib_sa_client_get(client); |
881 | query->sa_query.client = client; | 898 | query->sa_query.client = client; |
@@ -887,7 +904,6 @@ int ib_sa_mcmember_rec_query(struct ib_sa_client *client, | |||
887 | 904 | ||
888 | query->sa_query.callback = callback ? ib_sa_mcmember_rec_callback : NULL; | 905 | query->sa_query.callback = callback ? ib_sa_mcmember_rec_callback : NULL; |
889 | query->sa_query.release = ib_sa_mcmember_rec_release; | 906 | query->sa_query.release = ib_sa_mcmember_rec_release; |
890 | query->sa_query.port = port; | ||
891 | mad->mad_hdr.method = method; | 907 | mad->mad_hdr.method = method; |
892 | mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_MC_MEMBER_REC); | 908 | mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_MC_MEMBER_REC); |
893 | mad->sa_hdr.comp_mask = comp_mask; | 909 | mad->sa_hdr.comp_mask = comp_mask; |
@@ -906,7 +922,7 @@ int ib_sa_mcmember_rec_query(struct ib_sa_client *client, | |||
906 | err2: | 922 | err2: |
907 | *sa_query = NULL; | 923 | *sa_query = NULL; |
908 | ib_sa_client_put(query->sa_query.client); | 924 | ib_sa_client_put(query->sa_query.client); |
909 | ib_free_send_mad(query->sa_query.mad_buf); | 925 | free_mad(&query->sa_query); |
910 | 926 | ||
911 | err1: | 927 | err1: |
912 | kfree(query); | 928 | kfree(query); |
@@ -939,8 +955,7 @@ static void send_handler(struct ib_mad_agent *agent, | |||
939 | idr_remove(&query_idr, query->id); | 955 | idr_remove(&query_idr, query->id); |
940 | spin_unlock_irqrestore(&idr_lock, flags); | 956 | spin_unlock_irqrestore(&idr_lock, flags); |
941 | 957 | ||
942 | ib_free_send_mad(mad_send_wc->send_buf); | 958 | free_mad(query); |
943 | kref_put(&query->sm_ah->ref, free_sm_ah); | ||
944 | ib_sa_client_put(query->client); | 959 | ib_sa_client_put(query->client); |
945 | query->release(query); | 960 | query->release(query); |
946 | } | 961 | } |