diff options
Diffstat (limited to 'drivers/infiniband/core')
-rw-r--r-- | drivers/infiniband/core/iwcm.c | 1 | ||||
-rw-r--r-- | drivers/infiniband/core/mad.c | 35 | ||||
-rw-r--r-- | drivers/infiniband/core/mad_priv.h | 3 | ||||
-rw-r--r-- | drivers/infiniband/core/multicast.c | 10 | ||||
-rw-r--r-- | drivers/infiniband/core/sa_query.c | 7 | ||||
-rw-r--r-- | drivers/infiniband/core/smi.c | 8 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 10 |
7 files changed, 51 insertions, 23 deletions
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c index 8f9509e1ebf7..55d093a36ae4 100644 --- a/drivers/infiniband/core/iwcm.c +++ b/drivers/infiniband/core/iwcm.c | |||
@@ -362,6 +362,7 @@ static void destroy_cm_id(struct iw_cm_id *cm_id) | |||
362 | * In either case, must tell the provider to reject. | 362 | * In either case, must tell the provider to reject. |
363 | */ | 363 | */ |
364 | cm_id_priv->state = IW_CM_STATE_DESTROYING; | 364 | cm_id_priv->state = IW_CM_STATE_DESTROYING; |
365 | cm_id->device->iwcm->reject(cm_id, NULL, 0); | ||
365 | break; | 366 | break; |
366 | case IW_CM_STATE_CONN_SENT: | 367 | case IW_CM_STATE_CONN_SENT: |
367 | case IW_CM_STATE_DESTROYING: | 368 | case IW_CM_STATE_DESTROYING: |
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index de922a04ca2d..7522008fda86 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * Copyright (c) 2004-2007 Voltaire, Inc. All rights reserved. | 2 | * Copyright (c) 2004-2007 Voltaire, Inc. All rights reserved. |
3 | * Copyright (c) 2005 Intel Corporation. All rights reserved. | 3 | * Copyright (c) 2005 Intel Corporation. All rights reserved. |
4 | * Copyright (c) 2005 Mellanox Technologies Ltd. All rights reserved. | 4 | * Copyright (c) 2005 Mellanox Technologies Ltd. All rights reserved. |
5 | * Copyright (c) 2009 HNR Consulting. All rights reserved. | ||
5 | * | 6 | * |
6 | * This software is available to you under a choice of one of two | 7 | * This software is available to you under a choice of one of two |
7 | * licenses. You may choose to be licensed under the terms of the GNU | 8 | * licenses. You may choose to be licensed under the terms of the GNU |
@@ -45,14 +46,21 @@ MODULE_DESCRIPTION("kernel IB MAD API"); | |||
45 | MODULE_AUTHOR("Hal Rosenstock"); | 46 | MODULE_AUTHOR("Hal Rosenstock"); |
46 | MODULE_AUTHOR("Sean Hefty"); | 47 | MODULE_AUTHOR("Sean Hefty"); |
47 | 48 | ||
49 | int mad_sendq_size = IB_MAD_QP_SEND_SIZE; | ||
50 | int mad_recvq_size = IB_MAD_QP_RECV_SIZE; | ||
51 | |||
52 | module_param_named(send_queue_size, mad_sendq_size, int, 0444); | ||
53 | MODULE_PARM_DESC(send_queue_size, "Size of send queue in number of work requests"); | ||
54 | module_param_named(recv_queue_size, mad_recvq_size, int, 0444); | ||
55 | MODULE_PARM_DESC(recv_queue_size, "Size of receive queue in number of work requests"); | ||
56 | |||
48 | static struct kmem_cache *ib_mad_cache; | 57 | static struct kmem_cache *ib_mad_cache; |
49 | 58 | ||
50 | static struct list_head ib_mad_port_list; | 59 | static struct list_head ib_mad_port_list; |
51 | static u32 ib_mad_client_id = 0; | 60 | static u32 ib_mad_client_id = 0; |
52 | 61 | ||
53 | /* Port list lock */ | 62 | /* Port list lock */ |
54 | static spinlock_t ib_mad_port_list_lock; | 63 | static DEFINE_SPINLOCK(ib_mad_port_list_lock); |
55 | |||
56 | 64 | ||
57 | /* Forward declarations */ | 65 | /* Forward declarations */ |
58 | static int method_in_use(struct ib_mad_mgmt_method_table **method, | 66 | static int method_in_use(struct ib_mad_mgmt_method_table **method, |
@@ -1974,7 +1982,7 @@ static void adjust_timeout(struct ib_mad_agent_private *mad_agent_priv) | |||
1974 | unsigned long delay; | 1982 | unsigned long delay; |
1975 | 1983 | ||
1976 | if (list_empty(&mad_agent_priv->wait_list)) { | 1984 | if (list_empty(&mad_agent_priv->wait_list)) { |
1977 | cancel_delayed_work(&mad_agent_priv->timed_work); | 1985 | __cancel_delayed_work(&mad_agent_priv->timed_work); |
1978 | } else { | 1986 | } else { |
1979 | mad_send_wr = list_entry(mad_agent_priv->wait_list.next, | 1987 | mad_send_wr = list_entry(mad_agent_priv->wait_list.next, |
1980 | struct ib_mad_send_wr_private, | 1988 | struct ib_mad_send_wr_private, |
@@ -1983,7 +1991,7 @@ static void adjust_timeout(struct ib_mad_agent_private *mad_agent_priv) | |||
1983 | if (time_after(mad_agent_priv->timeout, | 1991 | if (time_after(mad_agent_priv->timeout, |
1984 | mad_send_wr->timeout)) { | 1992 | mad_send_wr->timeout)) { |
1985 | mad_agent_priv->timeout = mad_send_wr->timeout; | 1993 | mad_agent_priv->timeout = mad_send_wr->timeout; |
1986 | cancel_delayed_work(&mad_agent_priv->timed_work); | 1994 | __cancel_delayed_work(&mad_agent_priv->timed_work); |
1987 | delay = mad_send_wr->timeout - jiffies; | 1995 | delay = mad_send_wr->timeout - jiffies; |
1988 | if ((long)delay <= 0) | 1996 | if ((long)delay <= 0) |
1989 | delay = 1; | 1997 | delay = 1; |
@@ -2023,7 +2031,7 @@ static void wait_for_response(struct ib_mad_send_wr_private *mad_send_wr) | |||
2023 | 2031 | ||
2024 | /* Reschedule a work item if we have a shorter timeout */ | 2032 | /* Reschedule a work item if we have a shorter timeout */ |
2025 | if (mad_agent_priv->wait_list.next == &mad_send_wr->agent_list) { | 2033 | if (mad_agent_priv->wait_list.next == &mad_send_wr->agent_list) { |
2026 | cancel_delayed_work(&mad_agent_priv->timed_work); | 2034 | __cancel_delayed_work(&mad_agent_priv->timed_work); |
2027 | queue_delayed_work(mad_agent_priv->qp_info->port_priv->wq, | 2035 | queue_delayed_work(mad_agent_priv->qp_info->port_priv->wq, |
2028 | &mad_agent_priv->timed_work, delay); | 2036 | &mad_agent_priv->timed_work, delay); |
2029 | } | 2037 | } |
@@ -2736,8 +2744,8 @@ static int create_mad_qp(struct ib_mad_qp_info *qp_info, | |||
2736 | qp_init_attr.send_cq = qp_info->port_priv->cq; | 2744 | qp_init_attr.send_cq = qp_info->port_priv->cq; |
2737 | qp_init_attr.recv_cq = qp_info->port_priv->cq; | 2745 | qp_init_attr.recv_cq = qp_info->port_priv->cq; |
2738 | qp_init_attr.sq_sig_type = IB_SIGNAL_ALL_WR; | 2746 | qp_init_attr.sq_sig_type = IB_SIGNAL_ALL_WR; |
2739 | qp_init_attr.cap.max_send_wr = IB_MAD_QP_SEND_SIZE; | 2747 | qp_init_attr.cap.max_send_wr = mad_sendq_size; |
2740 | qp_init_attr.cap.max_recv_wr = IB_MAD_QP_RECV_SIZE; | 2748 | qp_init_attr.cap.max_recv_wr = mad_recvq_size; |
2741 | qp_init_attr.cap.max_send_sge = IB_MAD_SEND_REQ_MAX_SG; | 2749 | qp_init_attr.cap.max_send_sge = IB_MAD_SEND_REQ_MAX_SG; |
2742 | qp_init_attr.cap.max_recv_sge = IB_MAD_RECV_REQ_MAX_SG; | 2750 | qp_init_attr.cap.max_recv_sge = IB_MAD_RECV_REQ_MAX_SG; |
2743 | qp_init_attr.qp_type = qp_type; | 2751 | qp_init_attr.qp_type = qp_type; |
@@ -2752,8 +2760,8 @@ static int create_mad_qp(struct ib_mad_qp_info *qp_info, | |||
2752 | goto error; | 2760 | goto error; |
2753 | } | 2761 | } |
2754 | /* Use minimum queue sizes unless the CQ is resized */ | 2762 | /* Use minimum queue sizes unless the CQ is resized */ |
2755 | qp_info->send_queue.max_active = IB_MAD_QP_SEND_SIZE; | 2763 | qp_info->send_queue.max_active = mad_sendq_size; |
2756 | qp_info->recv_queue.max_active = IB_MAD_QP_RECV_SIZE; | 2764 | qp_info->recv_queue.max_active = mad_recvq_size; |
2757 | return 0; | 2765 | return 0; |
2758 | 2766 | ||
2759 | error: | 2767 | error: |
@@ -2792,7 +2800,7 @@ static int ib_mad_port_open(struct ib_device *device, | |||
2792 | init_mad_qp(port_priv, &port_priv->qp_info[0]); | 2800 | init_mad_qp(port_priv, &port_priv->qp_info[0]); |
2793 | init_mad_qp(port_priv, &port_priv->qp_info[1]); | 2801 | init_mad_qp(port_priv, &port_priv->qp_info[1]); |
2794 | 2802 | ||
2795 | cq_size = (IB_MAD_QP_SEND_SIZE + IB_MAD_QP_RECV_SIZE) * 2; | 2803 | cq_size = (mad_sendq_size + mad_recvq_size) * 2; |
2796 | port_priv->cq = ib_create_cq(port_priv->device, | 2804 | port_priv->cq = ib_create_cq(port_priv->device, |
2797 | ib_mad_thread_completion_handler, | 2805 | ib_mad_thread_completion_handler, |
2798 | NULL, port_priv, cq_size, 0); | 2806 | NULL, port_priv, cq_size, 0); |
@@ -2984,7 +2992,11 @@ static int __init ib_mad_init_module(void) | |||
2984 | { | 2992 | { |
2985 | int ret; | 2993 | int ret; |
2986 | 2994 | ||
2987 | spin_lock_init(&ib_mad_port_list_lock); | 2995 | mad_recvq_size = min(mad_recvq_size, IB_MAD_QP_MAX_SIZE); |
2996 | mad_recvq_size = max(mad_recvq_size, IB_MAD_QP_MIN_SIZE); | ||
2997 | |||
2998 | mad_sendq_size = min(mad_sendq_size, IB_MAD_QP_MAX_SIZE); | ||
2999 | mad_sendq_size = max(mad_sendq_size, IB_MAD_QP_MIN_SIZE); | ||
2988 | 3000 | ||
2989 | ib_mad_cache = kmem_cache_create("ib_mad", | 3001 | ib_mad_cache = kmem_cache_create("ib_mad", |
2990 | sizeof(struct ib_mad_private), | 3002 | sizeof(struct ib_mad_private), |
@@ -3021,4 +3033,3 @@ static void __exit ib_mad_cleanup_module(void) | |||
3021 | 3033 | ||
3022 | module_init(ib_mad_init_module); | 3034 | module_init(ib_mad_init_module); |
3023 | module_exit(ib_mad_cleanup_module); | 3035 | module_exit(ib_mad_cleanup_module); |
3024 | |||
diff --git a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h index 05ce331733b0..9430ab4969c5 100644 --- a/drivers/infiniband/core/mad_priv.h +++ b/drivers/infiniband/core/mad_priv.h | |||
@@ -2,6 +2,7 @@ | |||
2 | * Copyright (c) 2004, 2005, Voltaire, Inc. All rights reserved. | 2 | * Copyright (c) 2004, 2005, Voltaire, Inc. All rights reserved. |
3 | * Copyright (c) 2005 Intel Corporation. All rights reserved. | 3 | * Copyright (c) 2005 Intel Corporation. All rights reserved. |
4 | * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. | 4 | * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. |
5 | * Copyright (c) 2009 HNR Consulting. All rights reserved. | ||
5 | * | 6 | * |
6 | * This software is available to you under a choice of one of two | 7 | * This software is available to you under a choice of one of two |
7 | * licenses. You may choose to be licensed under the terms of the GNU | 8 | * licenses. You may choose to be licensed under the terms of the GNU |
@@ -49,6 +50,8 @@ | |||
49 | /* QP and CQ parameters */ | 50 | /* QP and CQ parameters */ |
50 | #define IB_MAD_QP_SEND_SIZE 128 | 51 | #define IB_MAD_QP_SEND_SIZE 128 |
51 | #define IB_MAD_QP_RECV_SIZE 512 | 52 | #define IB_MAD_QP_RECV_SIZE 512 |
53 | #define IB_MAD_QP_MIN_SIZE 64 | ||
54 | #define IB_MAD_QP_MAX_SIZE 8192 | ||
52 | #define IB_MAD_SEND_REQ_MAX_SG 2 | 55 | #define IB_MAD_SEND_REQ_MAX_SG 2 |
53 | #define IB_MAD_RECV_REQ_MAX_SG 1 | 56 | #define IB_MAD_RECV_REQ_MAX_SG 1 |
54 | 57 | ||
diff --git a/drivers/infiniband/core/multicast.c b/drivers/infiniband/core/multicast.c index 107f170c57cd..8d82ba171353 100644 --- a/drivers/infiniband/core/multicast.c +++ b/drivers/infiniband/core/multicast.c | |||
@@ -106,6 +106,8 @@ struct mcast_group { | |||
106 | struct ib_sa_query *query; | 106 | struct ib_sa_query *query; |
107 | int query_id; | 107 | int query_id; |
108 | u16 pkey_index; | 108 | u16 pkey_index; |
109 | u8 leave_state; | ||
110 | int retries; | ||
109 | }; | 111 | }; |
110 | 112 | ||
111 | struct mcast_member { | 113 | struct mcast_member { |
@@ -350,6 +352,7 @@ static int send_leave(struct mcast_group *group, u8 leave_state) | |||
350 | 352 | ||
351 | rec = group->rec; | 353 | rec = group->rec; |
352 | rec.join_state = leave_state; | 354 | rec.join_state = leave_state; |
355 | group->leave_state = leave_state; | ||
353 | 356 | ||
354 | ret = ib_sa_mcmember_rec_query(&sa_client, port->dev->device, | 357 | ret = ib_sa_mcmember_rec_query(&sa_client, port->dev->device, |
355 | port->port_num, IB_SA_METHOD_DELETE, &rec, | 358 | port->port_num, IB_SA_METHOD_DELETE, &rec, |
@@ -542,7 +545,11 @@ static void leave_handler(int status, struct ib_sa_mcmember_rec *rec, | |||
542 | { | 545 | { |
543 | struct mcast_group *group = context; | 546 | struct mcast_group *group = context; |
544 | 547 | ||
545 | mcast_work_handler(&group->work); | 548 | if (status && group->retries > 0 && |
549 | !send_leave(group, group->leave_state)) | ||
550 | group->retries--; | ||
551 | else | ||
552 | mcast_work_handler(&group->work); | ||
546 | } | 553 | } |
547 | 554 | ||
548 | static struct mcast_group *acquire_group(struct mcast_port *port, | 555 | static struct mcast_group *acquire_group(struct mcast_port *port, |
@@ -565,6 +572,7 @@ static struct mcast_group *acquire_group(struct mcast_port *port, | |||
565 | if (!group) | 572 | if (!group) |
566 | return NULL; | 573 | return NULL; |
567 | 574 | ||
575 | group->retries = 3; | ||
568 | group->port = port; | 576 | group->port = port; |
569 | group->rec.mgid = *mgid; | 577 | group->rec.mgid = *mgid; |
570 | group->pkey_index = MCAST_INVALID_PKEY_INDEX; | 578 | group->pkey_index = MCAST_INVALID_PKEY_INDEX; |
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 1865049e80f7..82543716d59e 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c | |||
@@ -109,10 +109,10 @@ static struct ib_client sa_client = { | |||
109 | .remove = ib_sa_remove_one | 109 | .remove = ib_sa_remove_one |
110 | }; | 110 | }; |
111 | 111 | ||
112 | static spinlock_t idr_lock; | 112 | static DEFINE_SPINLOCK(idr_lock); |
113 | static DEFINE_IDR(query_idr); | 113 | static DEFINE_IDR(query_idr); |
114 | 114 | ||
115 | static spinlock_t tid_lock; | 115 | static DEFINE_SPINLOCK(tid_lock); |
116 | static u32 tid; | 116 | static u32 tid; |
117 | 117 | ||
118 | #define PATH_REC_FIELD(field) \ | 118 | #define PATH_REC_FIELD(field) \ |
@@ -1077,9 +1077,6 @@ static int __init ib_sa_init(void) | |||
1077 | { | 1077 | { |
1078 | int ret; | 1078 | int ret; |
1079 | 1079 | ||
1080 | spin_lock_init(&idr_lock); | ||
1081 | spin_lock_init(&tid_lock); | ||
1082 | |||
1083 | get_random_bytes(&tid, sizeof tid); | 1080 | get_random_bytes(&tid, sizeof tid); |
1084 | 1081 | ||
1085 | ret = ib_register_client(&sa_client); | 1082 | ret = ib_register_client(&sa_client); |
diff --git a/drivers/infiniband/core/smi.c b/drivers/infiniband/core/smi.c index 87236753bce9..5855e4405d9b 100644 --- a/drivers/infiniband/core/smi.c +++ b/drivers/infiniband/core/smi.c | |||
@@ -52,6 +52,10 @@ enum smi_action smi_handle_dr_smp_send(struct ib_smp *smp, | |||
52 | hop_cnt = smp->hop_cnt; | 52 | hop_cnt = smp->hop_cnt; |
53 | 53 | ||
54 | /* See section 14.2.2.2, Vol 1 IB spec */ | 54 | /* See section 14.2.2.2, Vol 1 IB spec */ |
55 | /* C14-6 -- valid hop_cnt values are from 0 to 63 */ | ||
56 | if (hop_cnt >= IB_SMP_MAX_PATH_HOPS) | ||
57 | return IB_SMI_DISCARD; | ||
58 | |||
55 | if (!ib_get_smp_direction(smp)) { | 59 | if (!ib_get_smp_direction(smp)) { |
56 | /* C14-9:1 */ | 60 | /* C14-9:1 */ |
57 | if (hop_cnt && hop_ptr == 0) { | 61 | if (hop_cnt && hop_ptr == 0) { |
@@ -133,6 +137,10 @@ enum smi_action smi_handle_dr_smp_recv(struct ib_smp *smp, u8 node_type, | |||
133 | hop_cnt = smp->hop_cnt; | 137 | hop_cnt = smp->hop_cnt; |
134 | 138 | ||
135 | /* See section 14.2.2.2, Vol 1 IB spec */ | 139 | /* See section 14.2.2.2, Vol 1 IB spec */ |
140 | /* C14-6 -- valid hop_cnt values are from 0 to 63 */ | ||
141 | if (hop_cnt >= IB_SMP_MAX_PATH_HOPS) | ||
142 | return IB_SMI_DISCARD; | ||
143 | |||
136 | if (!ib_get_smp_direction(smp)) { | 144 | if (!ib_get_smp_direction(smp)) { |
137 | /* C14-9:1 -- sender should have incremented hop_ptr */ | 145 | /* C14-9:1 -- sender should have incremented hop_ptr */ |
138 | if (hop_cnt && hop_ptr == 0) | 146 | if (hop_cnt && hop_ptr == 0) |
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index eb36a81dd09b..d3fff9e008a3 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -73,7 +73,7 @@ DEFINE_IDR(ib_uverbs_cq_idr); | |||
73 | DEFINE_IDR(ib_uverbs_qp_idr); | 73 | DEFINE_IDR(ib_uverbs_qp_idr); |
74 | DEFINE_IDR(ib_uverbs_srq_idr); | 74 | DEFINE_IDR(ib_uverbs_srq_idr); |
75 | 75 | ||
76 | static spinlock_t map_lock; | 76 | static DEFINE_SPINLOCK(map_lock); |
77 | static struct ib_uverbs_device *dev_table[IB_UVERBS_MAX_DEVICES]; | 77 | static struct ib_uverbs_device *dev_table[IB_UVERBS_MAX_DEVICES]; |
78 | static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES); | 78 | static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES); |
79 | 79 | ||
@@ -584,14 +584,16 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf, | |||
584 | 584 | ||
585 | if (hdr.command < 0 || | 585 | if (hdr.command < 0 || |
586 | hdr.command >= ARRAY_SIZE(uverbs_cmd_table) || | 586 | hdr.command >= ARRAY_SIZE(uverbs_cmd_table) || |
587 | !uverbs_cmd_table[hdr.command] || | 587 | !uverbs_cmd_table[hdr.command]) |
588 | !(file->device->ib_dev->uverbs_cmd_mask & (1ull << hdr.command))) | ||
589 | return -EINVAL; | 588 | return -EINVAL; |
590 | 589 | ||
591 | if (!file->ucontext && | 590 | if (!file->ucontext && |
592 | hdr.command != IB_USER_VERBS_CMD_GET_CONTEXT) | 591 | hdr.command != IB_USER_VERBS_CMD_GET_CONTEXT) |
593 | return -EINVAL; | 592 | return -EINVAL; |
594 | 593 | ||
594 | if (!(file->device->ib_dev->uverbs_cmd_mask & (1ull << hdr.command))) | ||
595 | return -ENOSYS; | ||
596 | |||
595 | return uverbs_cmd_table[hdr.command](file, buf + sizeof hdr, | 597 | return uverbs_cmd_table[hdr.command](file, buf + sizeof hdr, |
596 | hdr.in_words * 4, hdr.out_words * 4); | 598 | hdr.in_words * 4, hdr.out_words * 4); |
597 | } | 599 | } |
@@ -836,8 +838,6 @@ static int __init ib_uverbs_init(void) | |||
836 | { | 838 | { |
837 | int ret; | 839 | int ret; |
838 | 840 | ||
839 | spin_lock_init(&map_lock); | ||
840 | |||
841 | ret = register_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES, | 841 | ret = register_chrdev_region(IB_UVERBS_BASE_DEV, IB_UVERBS_MAX_DEVICES, |
842 | "infiniband_verbs"); | 842 | "infiniband_verbs"); |
843 | if (ret) { | 843 | if (ret) { |