aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorSean Hefty <sean.hefty@intel.com>2007-06-18 14:03:58 -0400
committerRoland Dreier <rolandd@cisco.com>2007-07-11 00:45:31 -0400
commit2aec5c602c6a44e2a3a173339a9ab94549658e4b (patch)
treeb16a5002a07d96b88ad162ac34d628b531844a6f /drivers/infiniband
parent1b844afe9e67d6cd441ae6df71051b4004f31dd2 (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.c85
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");
56struct ib_sa_sm_ah { 56struct 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}
513EXPORT_SYMBOL(ib_init_ah_from_path); 521EXPORT_SYMBOL(ib_init_ah_from_path);
514 522
523static 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
546static 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
515static void init_mad(struct ib_sa_mad *mad, struct ib_mad_agent *agent) 552static 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,
683err2: 707err2:
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
688err1: 712err1:
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,
810err2: 830err2:
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
815err1: 835err1:
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,
906err2: 922err2:
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
911err1: 927err1:
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}