diff options
| -rw-r--r-- | drivers/infiniband/core/agent.c | 29 | ||||
| -rw-r--r-- | drivers/infiniband/core/mad.c | 27 | ||||
| -rw-r--r-- | drivers/infiniband/core/multicast.c | 23 | ||||
| -rw-r--r-- | drivers/infiniband/core/sa_query.c | 25 |
4 files changed, 78 insertions, 26 deletions
diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c index ae7c2880e624..91916a8d5de4 100644 --- a/drivers/infiniband/core/agent.c +++ b/drivers/infiniband/core/agent.c | |||
| @@ -59,8 +59,8 @@ __ib_get_agent_port(struct ib_device *device, int port_num) | |||
| 59 | struct ib_agent_port_private *entry; | 59 | struct ib_agent_port_private *entry; |
| 60 | 60 | ||
| 61 | list_for_each_entry(entry, &ib_agent_port_list, port_list) { | 61 | list_for_each_entry(entry, &ib_agent_port_list, port_list) { |
| 62 | if (entry->agent[0]->device == device && | 62 | if (entry->agent[1]->device == device && |
| 63 | entry->agent[0]->port_num == port_num) | 63 | entry->agent[1]->port_num == port_num) |
| 64 | return entry; | 64 | return entry; |
| 65 | } | 65 | } |
| 66 | return NULL; | 66 | return NULL; |
| @@ -155,14 +155,16 @@ int ib_agent_port_open(struct ib_device *device, int port_num) | |||
| 155 | goto error1; | 155 | goto error1; |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | /* Obtain send only MAD agent for SMI QP */ | 158 | if (rdma_port_get_link_layer(device, port_num) == IB_LINK_LAYER_INFINIBAND) { |
| 159 | port_priv->agent[0] = ib_register_mad_agent(device, port_num, | 159 | /* Obtain send only MAD agent for SMI QP */ |
| 160 | IB_QPT_SMI, NULL, 0, | 160 | port_priv->agent[0] = ib_register_mad_agent(device, port_num, |
| 161 | &agent_send_handler, | 161 | IB_QPT_SMI, NULL, 0, |
| 162 | NULL, NULL); | 162 | &agent_send_handler, |
| 163 | if (IS_ERR(port_priv->agent[0])) { | 163 | NULL, NULL); |
| 164 | ret = PTR_ERR(port_priv->agent[0]); | 164 | if (IS_ERR(port_priv->agent[0])) { |
| 165 | goto error2; | 165 | ret = PTR_ERR(port_priv->agent[0]); |
| 166 | goto error2; | ||
| 167 | } | ||
| 166 | } | 168 | } |
| 167 | 169 | ||
| 168 | /* Obtain send only MAD agent for GSI QP */ | 170 | /* Obtain send only MAD agent for GSI QP */ |
| @@ -182,7 +184,8 @@ int ib_agent_port_open(struct ib_device *device, int port_num) | |||
| 182 | return 0; | 184 | return 0; |
| 183 | 185 | ||
| 184 | error3: | 186 | error3: |
| 185 | ib_unregister_mad_agent(port_priv->agent[0]); | 187 | if (port_priv->agent[0]) |
| 188 | ib_unregister_mad_agent(port_priv->agent[0]); | ||
| 186 | error2: | 189 | error2: |
| 187 | kfree(port_priv); | 190 | kfree(port_priv); |
| 188 | error1: | 191 | error1: |
| @@ -205,7 +208,9 @@ int ib_agent_port_close(struct ib_device *device, int port_num) | |||
| 205 | spin_unlock_irqrestore(&ib_agent_port_list_lock, flags); | 208 | spin_unlock_irqrestore(&ib_agent_port_list_lock, flags); |
| 206 | 209 | ||
| 207 | ib_unregister_mad_agent(port_priv->agent[1]); | 210 | ib_unregister_mad_agent(port_priv->agent[1]); |
| 208 | ib_unregister_mad_agent(port_priv->agent[0]); | 211 | if (port_priv->agent[0]) |
| 212 | ib_unregister_mad_agent(port_priv->agent[0]); | ||
| 213 | |||
| 209 | kfree(port_priv); | 214 | kfree(port_priv); |
| 210 | return 0; | 215 | return 0; |
| 211 | } | 216 | } |
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index ef1304f151dc..822cfdcd9f78 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
| @@ -2598,6 +2598,9 @@ static void cleanup_recv_queue(struct ib_mad_qp_info *qp_info) | |||
| 2598 | struct ib_mad_private *recv; | 2598 | struct ib_mad_private *recv; |
| 2599 | struct ib_mad_list_head *mad_list; | 2599 | struct ib_mad_list_head *mad_list; |
| 2600 | 2600 | ||
| 2601 | if (!qp_info->qp) | ||
| 2602 | return; | ||
| 2603 | |||
| 2601 | while (!list_empty(&qp_info->recv_queue.list)) { | 2604 | while (!list_empty(&qp_info->recv_queue.list)) { |
| 2602 | 2605 | ||
| 2603 | mad_list = list_entry(qp_info->recv_queue.list.next, | 2606 | mad_list = list_entry(qp_info->recv_queue.list.next, |
| @@ -2639,6 +2642,9 @@ static int ib_mad_port_start(struct ib_mad_port_private *port_priv) | |||
| 2639 | 2642 | ||
| 2640 | for (i = 0; i < IB_MAD_QPS_CORE; i++) { | 2643 | for (i = 0; i < IB_MAD_QPS_CORE; i++) { |
| 2641 | qp = port_priv->qp_info[i].qp; | 2644 | qp = port_priv->qp_info[i].qp; |
| 2645 | if (!qp) | ||
| 2646 | continue; | ||
| 2647 | |||
| 2642 | /* | 2648 | /* |
| 2643 | * PKey index for QP1 is irrelevant but | 2649 | * PKey index for QP1 is irrelevant but |
| 2644 | * one is needed for the Reset to Init transition | 2650 | * one is needed for the Reset to Init transition |
| @@ -2680,6 +2686,9 @@ static int ib_mad_port_start(struct ib_mad_port_private *port_priv) | |||
| 2680 | } | 2686 | } |
| 2681 | 2687 | ||
| 2682 | for (i = 0; i < IB_MAD_QPS_CORE; i++) { | 2688 | for (i = 0; i < IB_MAD_QPS_CORE; i++) { |
| 2689 | if (!port_priv->qp_info[i].qp) | ||
| 2690 | continue; | ||
| 2691 | |||
| 2683 | ret = ib_mad_post_receive_mads(&port_priv->qp_info[i], NULL); | 2692 | ret = ib_mad_post_receive_mads(&port_priv->qp_info[i], NULL); |
| 2684 | if (ret) { | 2693 | if (ret) { |
| 2685 | printk(KERN_ERR PFX "Couldn't post receive WRs\n"); | 2694 | printk(KERN_ERR PFX "Couldn't post receive WRs\n"); |
| @@ -2758,6 +2767,9 @@ error: | |||
| 2758 | 2767 | ||
| 2759 | static void destroy_mad_qp(struct ib_mad_qp_info *qp_info) | 2768 | static void destroy_mad_qp(struct ib_mad_qp_info *qp_info) |
| 2760 | { | 2769 | { |
| 2770 | if (!qp_info->qp) | ||
| 2771 | return; | ||
| 2772 | |||
| 2761 | ib_destroy_qp(qp_info->qp); | 2773 | ib_destroy_qp(qp_info->qp); |
| 2762 | kfree(qp_info->snoop_table); | 2774 | kfree(qp_info->snoop_table); |
| 2763 | } | 2775 | } |
| @@ -2773,6 +2785,7 @@ static int ib_mad_port_open(struct ib_device *device, | |||
| 2773 | struct ib_mad_port_private *port_priv; | 2785 | struct ib_mad_port_private *port_priv; |
| 2774 | unsigned long flags; | 2786 | unsigned long flags; |
| 2775 | char name[sizeof "ib_mad123"]; | 2787 | char name[sizeof "ib_mad123"]; |
| 2788 | int has_smi; | ||
| 2776 | 2789 | ||
| 2777 | /* Create new device info */ | 2790 | /* Create new device info */ |
| 2778 | port_priv = kzalloc(sizeof *port_priv, GFP_KERNEL); | 2791 | port_priv = kzalloc(sizeof *port_priv, GFP_KERNEL); |
| @@ -2788,7 +2801,11 @@ static int ib_mad_port_open(struct ib_device *device, | |||
| 2788 | init_mad_qp(port_priv, &port_priv->qp_info[0]); | 2801 | init_mad_qp(port_priv, &port_priv->qp_info[0]); |
| 2789 | init_mad_qp(port_priv, &port_priv->qp_info[1]); | 2802 | init_mad_qp(port_priv, &port_priv->qp_info[1]); |
| 2790 | 2803 | ||
| 2791 | cq_size = (mad_sendq_size + mad_recvq_size) * 2; | 2804 | cq_size = mad_sendq_size + mad_recvq_size; |
| 2805 | has_smi = rdma_port_get_link_layer(device, port_num) == IB_LINK_LAYER_INFINIBAND; | ||
| 2806 | if (has_smi) | ||
| 2807 | cq_size *= 2; | ||
| 2808 | |||
| 2792 | port_priv->cq = ib_create_cq(port_priv->device, | 2809 | port_priv->cq = ib_create_cq(port_priv->device, |
| 2793 | ib_mad_thread_completion_handler, | 2810 | ib_mad_thread_completion_handler, |
| 2794 | NULL, port_priv, cq_size, 0); | 2811 | NULL, port_priv, cq_size, 0); |
| @@ -2812,9 +2829,11 @@ static int ib_mad_port_open(struct ib_device *device, | |||
| 2812 | goto error5; | 2829 | goto error5; |
| 2813 | } | 2830 | } |
| 2814 | 2831 | ||
| 2815 | ret = create_mad_qp(&port_priv->qp_info[0], IB_QPT_SMI); | 2832 | if (has_smi) { |
| 2816 | if (ret) | 2833 | ret = create_mad_qp(&port_priv->qp_info[0], IB_QPT_SMI); |
| 2817 | goto error6; | 2834 | if (ret) |
| 2835 | goto error6; | ||
| 2836 | } | ||
| 2818 | ret = create_mad_qp(&port_priv->qp_info[1], IB_QPT_GSI); | 2837 | ret = create_mad_qp(&port_priv->qp_info[1], IB_QPT_GSI); |
| 2819 | if (ret) | 2838 | if (ret) |
| 2820 | goto error7; | 2839 | goto error7; |
diff --git a/drivers/infiniband/core/multicast.c b/drivers/infiniband/core/multicast.c index a519801dcfb7..68b4162fd9d2 100644 --- a/drivers/infiniband/core/multicast.c +++ b/drivers/infiniband/core/multicast.c | |||
| @@ -774,6 +774,10 @@ static void mcast_event_handler(struct ib_event_handler *handler, | |||
| 774 | int index; | 774 | int index; |
| 775 | 775 | ||
| 776 | dev = container_of(handler, struct mcast_device, event_handler); | 776 | dev = container_of(handler, struct mcast_device, event_handler); |
| 777 | if (rdma_port_get_link_layer(dev->device, event->element.port_num) != | ||
| 778 | IB_LINK_LAYER_INFINIBAND) | ||
| 779 | return; | ||
| 780 | |||
| 777 | index = event->element.port_num - dev->start_port; | 781 | index = event->element.port_num - dev->start_port; |
| 778 | 782 | ||
| 779 | switch (event->event) { | 783 | switch (event->event) { |
| @@ -796,6 +800,7 @@ static void mcast_add_one(struct ib_device *device) | |||
| 796 | struct mcast_device *dev; | 800 | struct mcast_device *dev; |
| 797 | struct mcast_port *port; | 801 | struct mcast_port *port; |
| 798 | int i; | 802 | int i; |
| 803 | int count = 0; | ||
| 799 | 804 | ||
| 800 | if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB) | 805 | if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB) |
| 801 | return; | 806 | return; |
| @@ -813,6 +818,9 @@ static void mcast_add_one(struct ib_device *device) | |||
| 813 | } | 818 | } |
| 814 | 819 | ||
| 815 | for (i = 0; i <= dev->end_port - dev->start_port; i++) { | 820 | for (i = 0; i <= dev->end_port - dev->start_port; i++) { |
| 821 | if (rdma_port_get_link_layer(device, dev->start_port + i) != | ||
| 822 | IB_LINK_LAYER_INFINIBAND) | ||
| 823 | continue; | ||
| 816 | port = &dev->port[i]; | 824 | port = &dev->port[i]; |
| 817 | port->dev = dev; | 825 | port->dev = dev; |
| 818 | port->port_num = dev->start_port + i; | 826 | port->port_num = dev->start_port + i; |
| @@ -820,6 +828,12 @@ static void mcast_add_one(struct ib_device *device) | |||
| 820 | port->table = RB_ROOT; | 828 | port->table = RB_ROOT; |
| 821 | init_completion(&port->comp); | 829 | init_completion(&port->comp); |
| 822 | atomic_set(&port->refcount, 1); | 830 | atomic_set(&port->refcount, 1); |
| 831 | ++count; | ||
| 832 | } | ||
| 833 | |||
| 834 | if (!count) { | ||
| 835 | kfree(dev); | ||
| 836 | return; | ||
| 823 | } | 837 | } |
| 824 | 838 | ||
| 825 | dev->device = device; | 839 | dev->device = device; |
| @@ -843,9 +857,12 @@ static void mcast_remove_one(struct ib_device *device) | |||
| 843 | flush_workqueue(mcast_wq); | 857 | flush_workqueue(mcast_wq); |
| 844 | 858 | ||
| 845 | for (i = 0; i <= dev->end_port - dev->start_port; i++) { | 859 | for (i = 0; i <= dev->end_port - dev->start_port; i++) { |
| 846 | port = &dev->port[i]; | 860 | if (rdma_port_get_link_layer(device, dev->start_port + i) == |
| 847 | deref_port(port); | 861 | IB_LINK_LAYER_INFINIBAND) { |
| 848 | wait_for_completion(&port->comp); | 862 | port = &dev->port[i]; |
| 863 | deref_port(port); | ||
| 864 | wait_for_completion(&port->comp); | ||
| 865 | } | ||
| 849 | } | 866 | } |
| 850 | 867 | ||
| 851 | kfree(dev); | 868 | kfree(dev); |
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 7e1ffd8ccd5c..27674c790a73 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c | |||
| @@ -416,6 +416,9 @@ static void ib_sa_event(struct ib_event_handler *handler, struct ib_event *event | |||
| 416 | struct ib_sa_port *port = | 416 | struct ib_sa_port *port = |
| 417 | &sa_dev->port[event->element.port_num - sa_dev->start_port]; | 417 | &sa_dev->port[event->element.port_num - sa_dev->start_port]; |
| 418 | 418 | ||
| 419 | if (rdma_port_get_link_layer(handler->device, port->port_num) != IB_LINK_LAYER_INFINIBAND) | ||
| 420 | return; | ||
| 421 | |||
| 419 | spin_lock_irqsave(&port->ah_lock, flags); | 422 | spin_lock_irqsave(&port->ah_lock, flags); |
| 420 | if (port->sm_ah) | 423 | if (port->sm_ah) |
| 421 | kref_put(&port->sm_ah->ref, free_sm_ah); | 424 | kref_put(&port->sm_ah->ref, free_sm_ah); |
| @@ -1007,7 +1010,7 @@ static void ib_sa_add_one(struct ib_device *device) | |||
| 1007 | e = device->phys_port_cnt; | 1010 | e = device->phys_port_cnt; |
| 1008 | } | 1011 | } |
| 1009 | 1012 | ||
| 1010 | sa_dev = kmalloc(sizeof *sa_dev + | 1013 | sa_dev = kzalloc(sizeof *sa_dev + |
| 1011 | (e - s + 1) * sizeof (struct ib_sa_port), | 1014 | (e - s + 1) * sizeof (struct ib_sa_port), |
| 1012 | GFP_KERNEL); | 1015 | GFP_KERNEL); |
| 1013 | if (!sa_dev) | 1016 | if (!sa_dev) |
| @@ -1017,9 +1020,12 @@ static void ib_sa_add_one(struct ib_device *device) | |||
| 1017 | sa_dev->end_port = e; | 1020 | sa_dev->end_port = e; |
| 1018 | 1021 | ||
| 1019 | for (i = 0; i <= e - s; ++i) { | 1022 | for (i = 0; i <= e - s; ++i) { |
| 1023 | spin_lock_init(&sa_dev->port[i].ah_lock); | ||
| 1024 | if (rdma_port_get_link_layer(device, i + 1) != IB_LINK_LAYER_INFINIBAND) | ||
| 1025 | continue; | ||
| 1026 | |||
| 1020 | sa_dev->port[i].sm_ah = NULL; | 1027 | sa_dev->port[i].sm_ah = NULL; |
| 1021 | sa_dev->port[i].port_num = i + s; | 1028 | sa_dev->port[i].port_num = i + s; |
| 1022 | spin_lock_init(&sa_dev->port[i].ah_lock); | ||
| 1023 | 1029 | ||
| 1024 | sa_dev->port[i].agent = | 1030 | sa_dev->port[i].agent = |
| 1025 | ib_register_mad_agent(device, i + s, IB_QPT_GSI, | 1031 | ib_register_mad_agent(device, i + s, IB_QPT_GSI, |
| @@ -1045,13 +1051,15 @@ static void ib_sa_add_one(struct ib_device *device) | |||
| 1045 | goto err; | 1051 | goto err; |
| 1046 | 1052 | ||
| 1047 | for (i = 0; i <= e - s; ++i) | 1053 | for (i = 0; i <= e - s; ++i) |
| 1048 | update_sm_ah(&sa_dev->port[i].update_task); | 1054 | if (rdma_port_get_link_layer(device, i + 1) == IB_LINK_LAYER_INFINIBAND) |
| 1055 | update_sm_ah(&sa_dev->port[i].update_task); | ||
| 1049 | 1056 | ||
| 1050 | return; | 1057 | return; |
| 1051 | 1058 | ||
| 1052 | err: | 1059 | err: |
| 1053 | while (--i >= 0) | 1060 | while (--i >= 0) |
| 1054 | ib_unregister_mad_agent(sa_dev->port[i].agent); | 1061 | if (rdma_port_get_link_layer(device, i + 1) == IB_LINK_LAYER_INFINIBAND) |
| 1062 | ib_unregister_mad_agent(sa_dev->port[i].agent); | ||
| 1055 | 1063 | ||
| 1056 | kfree(sa_dev); | 1064 | kfree(sa_dev); |
| 1057 | 1065 | ||
| @@ -1071,9 +1079,12 @@ static void ib_sa_remove_one(struct ib_device *device) | |||
| 1071 | flush_scheduled_work(); | 1079 | flush_scheduled_work(); |
| 1072 | 1080 | ||
| 1073 | for (i = 0; i <= sa_dev->end_port - sa_dev->start_port; ++i) { | 1081 | for (i = 0; i <= sa_dev->end_port - sa_dev->start_port; ++i) { |
| 1074 | ib_unregister_mad_agent(sa_dev->port[i].agent); | 1082 | if (rdma_port_get_link_layer(device, i + 1) == IB_LINK_LAYER_INFINIBAND) { |
| 1075 | if (sa_dev->port[i].sm_ah) | 1083 | ib_unregister_mad_agent(sa_dev->port[i].agent); |
| 1076 | kref_put(&sa_dev->port[i].sm_ah->ref, free_sm_ah); | 1084 | if (sa_dev->port[i].sm_ah) |
| 1085 | kref_put(&sa_dev->port[i].sm_ah->ref, free_sm_ah); | ||
| 1086 | } | ||
| 1087 | |||
| 1077 | } | 1088 | } |
| 1078 | 1089 | ||
| 1079 | kfree(sa_dev); | 1090 | kfree(sa_dev); |
