diff options
Diffstat (limited to 'drivers')
38 files changed, 1136 insertions, 348 deletions
diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c index 2bc7f5af64f4..f6d29614cb01 100644 --- a/drivers/infiniband/core/agent.c +++ b/drivers/infiniband/core/agent.c | |||
@@ -94,14 +94,14 @@ void agent_send_response(struct ib_mad *mad, struct ib_grh *grh, | |||
94 | port_priv = ib_get_agent_port(device, port_num); | 94 | port_priv = ib_get_agent_port(device, port_num); |
95 | 95 | ||
96 | if (!port_priv) { | 96 | if (!port_priv) { |
97 | printk(KERN_ERR SPFX "Unable to find port agent\n"); | 97 | dev_err(&device->dev, "Unable to find port agent\n"); |
98 | return; | 98 | return; |
99 | } | 99 | } |
100 | 100 | ||
101 | agent = port_priv->agent[qpn]; | 101 | agent = port_priv->agent[qpn]; |
102 | ah = ib_create_ah_from_wc(agent->qp->pd, wc, grh, port_num); | 102 | ah = ib_create_ah_from_wc(agent->qp->pd, wc, grh, port_num); |
103 | if (IS_ERR(ah)) { | 103 | if (IS_ERR(ah)) { |
104 | printk(KERN_ERR SPFX "ib_create_ah_from_wc error %ld\n", | 104 | dev_err(&device->dev, "ib_create_ah_from_wc error %ld\n", |
105 | PTR_ERR(ah)); | 105 | PTR_ERR(ah)); |
106 | return; | 106 | return; |
107 | } | 107 | } |
@@ -110,7 +110,7 @@ void agent_send_response(struct ib_mad *mad, struct ib_grh *grh, | |||
110 | IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA, | 110 | IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA, |
111 | GFP_KERNEL); | 111 | GFP_KERNEL); |
112 | if (IS_ERR(send_buf)) { | 112 | if (IS_ERR(send_buf)) { |
113 | printk(KERN_ERR SPFX "ib_create_send_mad error\n"); | 113 | dev_err(&device->dev, "ib_create_send_mad error\n"); |
114 | goto err1; | 114 | goto err1; |
115 | } | 115 | } |
116 | 116 | ||
@@ -125,7 +125,7 @@ void agent_send_response(struct ib_mad *mad, struct ib_grh *grh, | |||
125 | } | 125 | } |
126 | 126 | ||
127 | if (ib_post_send_mad(send_buf, NULL)) { | 127 | if (ib_post_send_mad(send_buf, NULL)) { |
128 | printk(KERN_ERR SPFX "ib_post_send_mad error\n"); | 128 | dev_err(&device->dev, "ib_post_send_mad error\n"); |
129 | goto err2; | 129 | goto err2; |
130 | } | 130 | } |
131 | return; | 131 | return; |
@@ -151,7 +151,7 @@ int ib_agent_port_open(struct ib_device *device, int port_num) | |||
151 | /* Create new device info */ | 151 | /* Create new device info */ |
152 | port_priv = kzalloc(sizeof *port_priv, GFP_KERNEL); | 152 | port_priv = kzalloc(sizeof *port_priv, GFP_KERNEL); |
153 | if (!port_priv) { | 153 | if (!port_priv) { |
154 | printk(KERN_ERR SPFX "No memory for ib_agent_port_private\n"); | 154 | dev_err(&device->dev, "No memory for ib_agent_port_private\n"); |
155 | ret = -ENOMEM; | 155 | ret = -ENOMEM; |
156 | goto error1; | 156 | goto error1; |
157 | } | 157 | } |
@@ -161,7 +161,7 @@ int ib_agent_port_open(struct ib_device *device, int port_num) | |||
161 | port_priv->agent[0] = ib_register_mad_agent(device, port_num, | 161 | port_priv->agent[0] = ib_register_mad_agent(device, port_num, |
162 | IB_QPT_SMI, NULL, 0, | 162 | IB_QPT_SMI, NULL, 0, |
163 | &agent_send_handler, | 163 | &agent_send_handler, |
164 | NULL, NULL); | 164 | NULL, NULL, 0); |
165 | if (IS_ERR(port_priv->agent[0])) { | 165 | if (IS_ERR(port_priv->agent[0])) { |
166 | ret = PTR_ERR(port_priv->agent[0]); | 166 | ret = PTR_ERR(port_priv->agent[0]); |
167 | goto error2; | 167 | goto error2; |
@@ -172,7 +172,7 @@ int ib_agent_port_open(struct ib_device *device, int port_num) | |||
172 | port_priv->agent[1] = ib_register_mad_agent(device, port_num, | 172 | port_priv->agent[1] = ib_register_mad_agent(device, port_num, |
173 | IB_QPT_GSI, NULL, 0, | 173 | IB_QPT_GSI, NULL, 0, |
174 | &agent_send_handler, | 174 | &agent_send_handler, |
175 | NULL, NULL); | 175 | NULL, NULL, 0); |
176 | if (IS_ERR(port_priv->agent[1])) { | 176 | if (IS_ERR(port_priv->agent[1])) { |
177 | ret = PTR_ERR(port_priv->agent[1]); | 177 | ret = PTR_ERR(port_priv->agent[1]); |
178 | goto error3; | 178 | goto error3; |
@@ -202,7 +202,7 @@ int ib_agent_port_close(struct ib_device *device, int port_num) | |||
202 | port_priv = __ib_get_agent_port(device, port_num); | 202 | port_priv = __ib_get_agent_port(device, port_num); |
203 | if (port_priv == NULL) { | 203 | if (port_priv == NULL) { |
204 | spin_unlock_irqrestore(&ib_agent_port_list_lock, flags); | 204 | spin_unlock_irqrestore(&ib_agent_port_list_lock, flags); |
205 | printk(KERN_ERR SPFX "Port %d not found\n", port_num); | 205 | dev_err(&device->dev, "Port %d not found\n", port_num); |
206 | return -ENODEV; | 206 | return -ENODEV; |
207 | } | 207 | } |
208 | list_del(&port_priv->port_list); | 208 | list_del(&port_priv->port_list); |
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index c3239170d8b7..e28a494e2a3a 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c | |||
@@ -3753,7 +3753,7 @@ static void cm_add_one(struct ib_device *ib_device) | |||
3753 | struct cm_port *port; | 3753 | struct cm_port *port; |
3754 | struct ib_mad_reg_req reg_req = { | 3754 | struct ib_mad_reg_req reg_req = { |
3755 | .mgmt_class = IB_MGMT_CLASS_CM, | 3755 | .mgmt_class = IB_MGMT_CLASS_CM, |
3756 | .mgmt_class_version = IB_CM_CLASS_VERSION | 3756 | .mgmt_class_version = IB_CM_CLASS_VERSION, |
3757 | }; | 3757 | }; |
3758 | struct ib_port_modify port_modify = { | 3758 | struct ib_port_modify port_modify = { |
3759 | .set_port_cap_mask = IB_PORT_CM_SUP | 3759 | .set_port_cap_mask = IB_PORT_CM_SUP |
@@ -3801,7 +3801,8 @@ static void cm_add_one(struct ib_device *ib_device) | |||
3801 | 0, | 3801 | 0, |
3802 | cm_send_handler, | 3802 | cm_send_handler, |
3803 | cm_recv_handler, | 3803 | cm_recv_handler, |
3804 | port); | 3804 | port, |
3805 | 0); | ||
3805 | if (IS_ERR(port->mad_agent)) | 3806 | if (IS_ERR(port->mad_agent)) |
3806 | goto error2; | 3807 | goto error2; |
3807 | 3808 | ||
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c index 3d2e489ab732..ff9163dc1596 100644 --- a/drivers/infiniband/core/iwcm.c +++ b/drivers/infiniband/core/iwcm.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/completion.h> | 46 | #include <linux/completion.h> |
47 | #include <linux/slab.h> | 47 | #include <linux/slab.h> |
48 | #include <linux/module.h> | 48 | #include <linux/module.h> |
49 | #include <linux/sysctl.h> | ||
49 | 50 | ||
50 | #include <rdma/iw_cm.h> | 51 | #include <rdma/iw_cm.h> |
51 | #include <rdma/ib_addr.h> | 52 | #include <rdma/ib_addr.h> |
@@ -65,6 +66,20 @@ struct iwcm_work { | |||
65 | struct list_head free_list; | 66 | struct list_head free_list; |
66 | }; | 67 | }; |
67 | 68 | ||
69 | static unsigned int default_backlog = 256; | ||
70 | |||
71 | static struct ctl_table_header *iwcm_ctl_table_hdr; | ||
72 | static struct ctl_table iwcm_ctl_table[] = { | ||
73 | { | ||
74 | .procname = "default_backlog", | ||
75 | .data = &default_backlog, | ||
76 | .maxlen = sizeof(default_backlog), | ||
77 | .mode = 0644, | ||
78 | .proc_handler = proc_dointvec, | ||
79 | }, | ||
80 | { } | ||
81 | }; | ||
82 | |||
68 | /* | 83 | /* |
69 | * The following services provide a mechanism for pre-allocating iwcm_work | 84 | * The following services provide a mechanism for pre-allocating iwcm_work |
70 | * elements. The design pre-allocates them based on the cm_id type: | 85 | * elements. The design pre-allocates them based on the cm_id type: |
@@ -425,6 +440,9 @@ int iw_cm_listen(struct iw_cm_id *cm_id, int backlog) | |||
425 | 440 | ||
426 | cm_id_priv = container_of(cm_id, struct iwcm_id_private, id); | 441 | cm_id_priv = container_of(cm_id, struct iwcm_id_private, id); |
427 | 442 | ||
443 | if (!backlog) | ||
444 | backlog = default_backlog; | ||
445 | |||
428 | ret = alloc_work_entries(cm_id_priv, backlog); | 446 | ret = alloc_work_entries(cm_id_priv, backlog); |
429 | if (ret) | 447 | if (ret) |
430 | return ret; | 448 | return ret; |
@@ -1030,11 +1048,20 @@ static int __init iw_cm_init(void) | |||
1030 | if (!iwcm_wq) | 1048 | if (!iwcm_wq) |
1031 | return -ENOMEM; | 1049 | return -ENOMEM; |
1032 | 1050 | ||
1051 | iwcm_ctl_table_hdr = register_net_sysctl(&init_net, "net/iw_cm", | ||
1052 | iwcm_ctl_table); | ||
1053 | if (!iwcm_ctl_table_hdr) { | ||
1054 | pr_err("iw_cm: couldn't register sysctl paths\n"); | ||
1055 | destroy_workqueue(iwcm_wq); | ||
1056 | return -ENOMEM; | ||
1057 | } | ||
1058 | |||
1033 | return 0; | 1059 | return 0; |
1034 | } | 1060 | } |
1035 | 1061 | ||
1036 | static void __exit iw_cm_cleanup(void) | 1062 | static void __exit iw_cm_cleanup(void) |
1037 | { | 1063 | { |
1064 | unregister_net_sysctl_table(iwcm_ctl_table_hdr); | ||
1038 | destroy_workqueue(iwcm_wq); | 1065 | destroy_workqueue(iwcm_wq); |
1039 | } | 1066 | } |
1040 | 1067 | ||
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index ab31f136d04b..74c30f4c557e 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
@@ -33,6 +33,9 @@ | |||
33 | * SOFTWARE. | 33 | * SOFTWARE. |
34 | * | 34 | * |
35 | */ | 35 | */ |
36 | |||
37 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
38 | |||
36 | #include <linux/dma-mapping.h> | 39 | #include <linux/dma-mapping.h> |
37 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
38 | #include <linux/module.h> | 41 | #include <linux/module.h> |
@@ -195,7 +198,8 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device, | |||
195 | u8 rmpp_version, | 198 | u8 rmpp_version, |
196 | ib_mad_send_handler send_handler, | 199 | ib_mad_send_handler send_handler, |
197 | ib_mad_recv_handler recv_handler, | 200 | ib_mad_recv_handler recv_handler, |
198 | void *context) | 201 | void *context, |
202 | u32 registration_flags) | ||
199 | { | 203 | { |
200 | struct ib_mad_port_private *port_priv; | 204 | struct ib_mad_port_private *port_priv; |
201 | struct ib_mad_agent *ret = ERR_PTR(-EINVAL); | 205 | struct ib_mad_agent *ret = ERR_PTR(-EINVAL); |
@@ -211,68 +215,109 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device, | |||
211 | 215 | ||
212 | /* Validate parameters */ | 216 | /* Validate parameters */ |
213 | qpn = get_spl_qp_index(qp_type); | 217 | qpn = get_spl_qp_index(qp_type); |
214 | if (qpn == -1) | 218 | if (qpn == -1) { |
219 | dev_notice(&device->dev, | ||
220 | "ib_register_mad_agent: invalid QP Type %d\n", | ||
221 | qp_type); | ||
215 | goto error1; | 222 | goto error1; |
223 | } | ||
216 | 224 | ||
217 | if (rmpp_version && rmpp_version != IB_MGMT_RMPP_VERSION) | 225 | if (rmpp_version && rmpp_version != IB_MGMT_RMPP_VERSION) { |
226 | dev_notice(&device->dev, | ||
227 | "ib_register_mad_agent: invalid RMPP Version %u\n", | ||
228 | rmpp_version); | ||
218 | goto error1; | 229 | goto error1; |
230 | } | ||
219 | 231 | ||
220 | /* Validate MAD registration request if supplied */ | 232 | /* Validate MAD registration request if supplied */ |
221 | if (mad_reg_req) { | 233 | if (mad_reg_req) { |
222 | if (mad_reg_req->mgmt_class_version >= MAX_MGMT_VERSION) | 234 | if (mad_reg_req->mgmt_class_version >= MAX_MGMT_VERSION) { |
235 | dev_notice(&device->dev, | ||
236 | "ib_register_mad_agent: invalid Class Version %u\n", | ||
237 | mad_reg_req->mgmt_class_version); | ||
223 | goto error1; | 238 | goto error1; |
224 | if (!recv_handler) | 239 | } |
240 | if (!recv_handler) { | ||
241 | dev_notice(&device->dev, | ||
242 | "ib_register_mad_agent: no recv_handler\n"); | ||
225 | goto error1; | 243 | goto error1; |
244 | } | ||
226 | if (mad_reg_req->mgmt_class >= MAX_MGMT_CLASS) { | 245 | if (mad_reg_req->mgmt_class >= MAX_MGMT_CLASS) { |
227 | /* | 246 | /* |
228 | * IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE is the only | 247 | * IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE is the only |
229 | * one in this range currently allowed | 248 | * one in this range currently allowed |
230 | */ | 249 | */ |
231 | if (mad_reg_req->mgmt_class != | 250 | if (mad_reg_req->mgmt_class != |
232 | IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) | 251 | IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) { |
252 | dev_notice(&device->dev, | ||
253 | "ib_register_mad_agent: Invalid Mgmt Class 0x%x\n", | ||
254 | mad_reg_req->mgmt_class); | ||
233 | goto error1; | 255 | goto error1; |
256 | } | ||
234 | } else if (mad_reg_req->mgmt_class == 0) { | 257 | } else if (mad_reg_req->mgmt_class == 0) { |
235 | /* | 258 | /* |
236 | * Class 0 is reserved in IBA and is used for | 259 | * Class 0 is reserved in IBA and is used for |
237 | * aliasing of IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE | 260 | * aliasing of IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE |
238 | */ | 261 | */ |
262 | dev_notice(&device->dev, | ||
263 | "ib_register_mad_agent: Invalid Mgmt Class 0\n"); | ||
239 | goto error1; | 264 | goto error1; |
240 | } else if (is_vendor_class(mad_reg_req->mgmt_class)) { | 265 | } else if (is_vendor_class(mad_reg_req->mgmt_class)) { |
241 | /* | 266 | /* |
242 | * If class is in "new" vendor range, | 267 | * If class is in "new" vendor range, |
243 | * ensure supplied OUI is not zero | 268 | * ensure supplied OUI is not zero |
244 | */ | 269 | */ |
245 | if (!is_vendor_oui(mad_reg_req->oui)) | 270 | if (!is_vendor_oui(mad_reg_req->oui)) { |
271 | dev_notice(&device->dev, | ||
272 | "ib_register_mad_agent: No OUI specified for class 0x%x\n", | ||
273 | mad_reg_req->mgmt_class); | ||
246 | goto error1; | 274 | goto error1; |
275 | } | ||
247 | } | 276 | } |
248 | /* Make sure class supplied is consistent with RMPP */ | 277 | /* Make sure class supplied is consistent with RMPP */ |
249 | if (!ib_is_mad_class_rmpp(mad_reg_req->mgmt_class)) { | 278 | if (!ib_is_mad_class_rmpp(mad_reg_req->mgmt_class)) { |
250 | if (rmpp_version) | 279 | if (rmpp_version) { |
280 | dev_notice(&device->dev, | ||
281 | "ib_register_mad_agent: RMPP version for non-RMPP class 0x%x\n", | ||
282 | mad_reg_req->mgmt_class); | ||
251 | goto error1; | 283 | goto error1; |
284 | } | ||
252 | } | 285 | } |
286 | |||
253 | /* Make sure class supplied is consistent with QP type */ | 287 | /* Make sure class supplied is consistent with QP type */ |
254 | if (qp_type == IB_QPT_SMI) { | 288 | if (qp_type == IB_QPT_SMI) { |
255 | if ((mad_reg_req->mgmt_class != | 289 | if ((mad_reg_req->mgmt_class != |
256 | IB_MGMT_CLASS_SUBN_LID_ROUTED) && | 290 | IB_MGMT_CLASS_SUBN_LID_ROUTED) && |
257 | (mad_reg_req->mgmt_class != | 291 | (mad_reg_req->mgmt_class != |
258 | IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)) | 292 | IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)) { |
293 | dev_notice(&device->dev, | ||
294 | "ib_register_mad_agent: Invalid SM QP type: class 0x%x\n", | ||
295 | mad_reg_req->mgmt_class); | ||
259 | goto error1; | 296 | goto error1; |
297 | } | ||
260 | } else { | 298 | } else { |
261 | if ((mad_reg_req->mgmt_class == | 299 | if ((mad_reg_req->mgmt_class == |
262 | IB_MGMT_CLASS_SUBN_LID_ROUTED) || | 300 | IB_MGMT_CLASS_SUBN_LID_ROUTED) || |
263 | (mad_reg_req->mgmt_class == | 301 | (mad_reg_req->mgmt_class == |
264 | IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)) | 302 | IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE)) { |
303 | dev_notice(&device->dev, | ||
304 | "ib_register_mad_agent: Invalid GS QP type: class 0x%x\n", | ||
305 | mad_reg_req->mgmt_class); | ||
265 | goto error1; | 306 | goto error1; |
307 | } | ||
266 | } | 308 | } |
267 | } else { | 309 | } else { |
268 | /* No registration request supplied */ | 310 | /* No registration request supplied */ |
269 | if (!send_handler) | 311 | if (!send_handler) |
270 | goto error1; | 312 | goto error1; |
313 | if (registration_flags & IB_MAD_USER_RMPP) | ||
314 | goto error1; | ||
271 | } | 315 | } |
272 | 316 | ||
273 | /* Validate device and port */ | 317 | /* Validate device and port */ |
274 | port_priv = ib_get_mad_port(device, port_num); | 318 | port_priv = ib_get_mad_port(device, port_num); |
275 | if (!port_priv) { | 319 | if (!port_priv) { |
320 | dev_notice(&device->dev, "ib_register_mad_agent: Invalid port\n"); | ||
276 | ret = ERR_PTR(-ENODEV); | 321 | ret = ERR_PTR(-ENODEV); |
277 | goto error1; | 322 | goto error1; |
278 | } | 323 | } |
@@ -280,6 +325,8 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device, | |||
280 | /* Verify the QP requested is supported. For example, Ethernet devices | 325 | /* Verify the QP requested is supported. For example, Ethernet devices |
281 | * will not have QP0 */ | 326 | * will not have QP0 */ |
282 | if (!port_priv->qp_info[qpn].qp) { | 327 | if (!port_priv->qp_info[qpn].qp) { |
328 | dev_notice(&device->dev, | ||
329 | "ib_register_mad_agent: QP %d not supported\n", qpn); | ||
283 | ret = ERR_PTR(-EPROTONOSUPPORT); | 330 | ret = ERR_PTR(-EPROTONOSUPPORT); |
284 | goto error1; | 331 | goto error1; |
285 | } | 332 | } |
@@ -316,6 +363,7 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device, | |||
316 | mad_agent_priv->agent.context = context; | 363 | mad_agent_priv->agent.context = context; |
317 | mad_agent_priv->agent.qp = port_priv->qp_info[qpn].qp; | 364 | mad_agent_priv->agent.qp = port_priv->qp_info[qpn].qp; |
318 | mad_agent_priv->agent.port_num = port_num; | 365 | mad_agent_priv->agent.port_num = port_num; |
366 | mad_agent_priv->agent.flags = registration_flags; | ||
319 | spin_lock_init(&mad_agent_priv->lock); | 367 | spin_lock_init(&mad_agent_priv->lock); |
320 | INIT_LIST_HEAD(&mad_agent_priv->send_list); | 368 | INIT_LIST_HEAD(&mad_agent_priv->send_list); |
321 | INIT_LIST_HEAD(&mad_agent_priv->wait_list); | 369 | INIT_LIST_HEAD(&mad_agent_priv->wait_list); |
@@ -706,7 +754,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, | |||
706 | smi_handle_dr_smp_send(smp, device->node_type, port_num) == | 754 | smi_handle_dr_smp_send(smp, device->node_type, port_num) == |
707 | IB_SMI_DISCARD) { | 755 | IB_SMI_DISCARD) { |
708 | ret = -EINVAL; | 756 | ret = -EINVAL; |
709 | printk(KERN_ERR PFX "Invalid directed route\n"); | 757 | dev_err(&device->dev, "Invalid directed route\n"); |
710 | goto out; | 758 | goto out; |
711 | } | 759 | } |
712 | 760 | ||
@@ -718,7 +766,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, | |||
718 | local = kmalloc(sizeof *local, GFP_ATOMIC); | 766 | local = kmalloc(sizeof *local, GFP_ATOMIC); |
719 | if (!local) { | 767 | if (!local) { |
720 | ret = -ENOMEM; | 768 | ret = -ENOMEM; |
721 | printk(KERN_ERR PFX "No memory for ib_mad_local_private\n"); | 769 | dev_err(&device->dev, "No memory for ib_mad_local_private\n"); |
722 | goto out; | 770 | goto out; |
723 | } | 771 | } |
724 | local->mad_priv = NULL; | 772 | local->mad_priv = NULL; |
@@ -726,7 +774,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, | |||
726 | mad_priv = kmem_cache_alloc(ib_mad_cache, GFP_ATOMIC); | 774 | mad_priv = kmem_cache_alloc(ib_mad_cache, GFP_ATOMIC); |
727 | if (!mad_priv) { | 775 | if (!mad_priv) { |
728 | ret = -ENOMEM; | 776 | ret = -ENOMEM; |
729 | printk(KERN_ERR PFX "No memory for local response MAD\n"); | 777 | dev_err(&device->dev, "No memory for local response MAD\n"); |
730 | kfree(local); | 778 | kfree(local); |
731 | goto out; | 779 | goto out; |
732 | } | 780 | } |
@@ -837,9 +885,9 @@ static int alloc_send_rmpp_list(struct ib_mad_send_wr_private *send_wr, | |||
837 | for (left = send_buf->data_len + pad; left > 0; left -= seg_size) { | 885 | for (left = send_buf->data_len + pad; left > 0; left -= seg_size) { |
838 | seg = kmalloc(sizeof (*seg) + seg_size, gfp_mask); | 886 | seg = kmalloc(sizeof (*seg) + seg_size, gfp_mask); |
839 | if (!seg) { | 887 | if (!seg) { |
840 | printk(KERN_ERR "alloc_send_rmpp_segs: RMPP mem " | 888 | dev_err(&send_buf->mad_agent->device->dev, |
841 | "alloc failed for len %zd, gfp %#x\n", | 889 | "alloc_send_rmpp_segs: RMPP mem alloc failed for len %zd, gfp %#x\n", |
842 | sizeof (*seg) + seg_size, gfp_mask); | 890 | sizeof (*seg) + seg_size, gfp_mask); |
843 | free_send_rmpp_list(send_wr); | 891 | free_send_rmpp_list(send_wr); |
844 | return -ENOMEM; | 892 | return -ENOMEM; |
845 | } | 893 | } |
@@ -862,6 +910,12 @@ static int alloc_send_rmpp_list(struct ib_mad_send_wr_private *send_wr, | |||
862 | return 0; | 910 | return 0; |
863 | } | 911 | } |
864 | 912 | ||
913 | int ib_mad_kernel_rmpp_agent(struct ib_mad_agent *agent) | ||
914 | { | ||
915 | return agent->rmpp_version && !(agent->flags & IB_MAD_USER_RMPP); | ||
916 | } | ||
917 | EXPORT_SYMBOL(ib_mad_kernel_rmpp_agent); | ||
918 | |||
865 | struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent, | 919 | struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent, |
866 | u32 remote_qpn, u16 pkey_index, | 920 | u32 remote_qpn, u16 pkey_index, |
867 | int rmpp_active, | 921 | int rmpp_active, |
@@ -878,10 +932,12 @@ struct ib_mad_send_buf * ib_create_send_mad(struct ib_mad_agent *mad_agent, | |||
878 | pad = get_pad_size(hdr_len, data_len); | 932 | pad = get_pad_size(hdr_len, data_len); |
879 | message_size = hdr_len + data_len + pad; | 933 | message_size = hdr_len + data_len + pad; |
880 | 934 | ||
881 | if ((!mad_agent->rmpp_version && | 935 | if (ib_mad_kernel_rmpp_agent(mad_agent)) { |
882 | (rmpp_active || message_size > sizeof(struct ib_mad))) || | 936 | if (!rmpp_active && message_size > sizeof(struct ib_mad)) |
883 | (!rmpp_active && message_size > sizeof(struct ib_mad))) | 937 | return ERR_PTR(-EINVAL); |
884 | return ERR_PTR(-EINVAL); | 938 | } else |
939 | if (rmpp_active || message_size > sizeof(struct ib_mad)) | ||
940 | return ERR_PTR(-EINVAL); | ||
885 | 941 | ||
886 | size = rmpp_active ? hdr_len : sizeof(struct ib_mad); | 942 | size = rmpp_active ? hdr_len : sizeof(struct ib_mad); |
887 | buf = kzalloc(sizeof *mad_send_wr + size, gfp_mask); | 943 | buf = kzalloc(sizeof *mad_send_wr + size, gfp_mask); |
@@ -1135,7 +1191,7 @@ int ib_post_send_mad(struct ib_mad_send_buf *send_buf, | |||
1135 | &mad_agent_priv->send_list); | 1191 | &mad_agent_priv->send_list); |
1136 | spin_unlock_irqrestore(&mad_agent_priv->lock, flags); | 1192 | spin_unlock_irqrestore(&mad_agent_priv->lock, flags); |
1137 | 1193 | ||
1138 | if (mad_agent_priv->agent.rmpp_version) { | 1194 | if (ib_mad_kernel_rmpp_agent(&mad_agent_priv->agent)) { |
1139 | ret = ib_send_rmpp_mad(mad_send_wr); | 1195 | ret = ib_send_rmpp_mad(mad_send_wr); |
1140 | if (ret >= 0 && ret != IB_RMPP_RESULT_CONSUMED) | 1196 | if (ret >= 0 && ret != IB_RMPP_RESULT_CONSUMED) |
1141 | ret = ib_send_mad(mad_send_wr); | 1197 | ret = ib_send_mad(mad_send_wr); |
@@ -1199,7 +1255,8 @@ EXPORT_SYMBOL(ib_redirect_mad_qp); | |||
1199 | int ib_process_mad_wc(struct ib_mad_agent *mad_agent, | 1255 | int ib_process_mad_wc(struct ib_mad_agent *mad_agent, |
1200 | struct ib_wc *wc) | 1256 | struct ib_wc *wc) |
1201 | { | 1257 | { |
1202 | printk(KERN_ERR PFX "ib_process_mad_wc() not implemented yet\n"); | 1258 | dev_err(&mad_agent->device->dev, |
1259 | "ib_process_mad_wc() not implemented yet\n"); | ||
1203 | return 0; | 1260 | return 0; |
1204 | } | 1261 | } |
1205 | EXPORT_SYMBOL(ib_process_mad_wc); | 1262 | EXPORT_SYMBOL(ib_process_mad_wc); |
@@ -1211,7 +1268,7 @@ static int method_in_use(struct ib_mad_mgmt_method_table **method, | |||
1211 | 1268 | ||
1212 | for_each_set_bit(i, mad_reg_req->method_mask, IB_MGMT_MAX_METHODS) { | 1269 | for_each_set_bit(i, mad_reg_req->method_mask, IB_MGMT_MAX_METHODS) { |
1213 | if ((*method)->agent[i]) { | 1270 | if ((*method)->agent[i]) { |
1214 | printk(KERN_ERR PFX "Method %d already in use\n", i); | 1271 | pr_err("Method %d already in use\n", i); |
1215 | return -EINVAL; | 1272 | return -EINVAL; |
1216 | } | 1273 | } |
1217 | } | 1274 | } |
@@ -1223,8 +1280,7 @@ static int allocate_method_table(struct ib_mad_mgmt_method_table **method) | |||
1223 | /* Allocate management method table */ | 1280 | /* Allocate management method table */ |
1224 | *method = kzalloc(sizeof **method, GFP_ATOMIC); | 1281 | *method = kzalloc(sizeof **method, GFP_ATOMIC); |
1225 | if (!*method) { | 1282 | if (!*method) { |
1226 | printk(KERN_ERR PFX "No memory for " | 1283 | pr_err("No memory for ib_mad_mgmt_method_table\n"); |
1227 | "ib_mad_mgmt_method_table\n"); | ||
1228 | return -ENOMEM; | 1284 | return -ENOMEM; |
1229 | } | 1285 | } |
1230 | 1286 | ||
@@ -1319,8 +1375,8 @@ static int add_nonoui_reg_req(struct ib_mad_reg_req *mad_reg_req, | |||
1319 | /* Allocate management class table for "new" class version */ | 1375 | /* Allocate management class table for "new" class version */ |
1320 | *class = kzalloc(sizeof **class, GFP_ATOMIC); | 1376 | *class = kzalloc(sizeof **class, GFP_ATOMIC); |
1321 | if (!*class) { | 1377 | if (!*class) { |
1322 | printk(KERN_ERR PFX "No memory for " | 1378 | dev_err(&agent_priv->agent.device->dev, |
1323 | "ib_mad_mgmt_class_table\n"); | 1379 | "No memory for ib_mad_mgmt_class_table\n"); |
1324 | ret = -ENOMEM; | 1380 | ret = -ENOMEM; |
1325 | goto error1; | 1381 | goto error1; |
1326 | } | 1382 | } |
@@ -1386,8 +1442,8 @@ static int add_oui_reg_req(struct ib_mad_reg_req *mad_reg_req, | |||
1386 | /* Allocate mgmt vendor class table for "new" class version */ | 1442 | /* Allocate mgmt vendor class table for "new" class version */ |
1387 | vendor = kzalloc(sizeof *vendor, GFP_ATOMIC); | 1443 | vendor = kzalloc(sizeof *vendor, GFP_ATOMIC); |
1388 | if (!vendor) { | 1444 | if (!vendor) { |
1389 | printk(KERN_ERR PFX "No memory for " | 1445 | dev_err(&agent_priv->agent.device->dev, |
1390 | "ib_mad_mgmt_vendor_class_table\n"); | 1446 | "No memory for ib_mad_mgmt_vendor_class_table\n"); |
1391 | goto error1; | 1447 | goto error1; |
1392 | } | 1448 | } |
1393 | 1449 | ||
@@ -1397,8 +1453,8 @@ static int add_oui_reg_req(struct ib_mad_reg_req *mad_reg_req, | |||
1397 | /* Allocate table for this management vendor class */ | 1453 | /* Allocate table for this management vendor class */ |
1398 | vendor_class = kzalloc(sizeof *vendor_class, GFP_ATOMIC); | 1454 | vendor_class = kzalloc(sizeof *vendor_class, GFP_ATOMIC); |
1399 | if (!vendor_class) { | 1455 | if (!vendor_class) { |
1400 | printk(KERN_ERR PFX "No memory for " | 1456 | dev_err(&agent_priv->agent.device->dev, |
1401 | "ib_mad_mgmt_vendor_class\n"); | 1457 | "No memory for ib_mad_mgmt_vendor_class\n"); |
1402 | goto error2; | 1458 | goto error2; |
1403 | } | 1459 | } |
1404 | 1460 | ||
@@ -1429,7 +1485,7 @@ static int add_oui_reg_req(struct ib_mad_reg_req *mad_reg_req, | |||
1429 | goto check_in_use; | 1485 | goto check_in_use; |
1430 | } | 1486 | } |
1431 | } | 1487 | } |
1432 | printk(KERN_ERR PFX "All OUI slots in use\n"); | 1488 | dev_err(&agent_priv->agent.device->dev, "All OUI slots in use\n"); |
1433 | goto error3; | 1489 | goto error3; |
1434 | 1490 | ||
1435 | check_in_use: | 1491 | check_in_use: |
@@ -1640,9 +1696,9 @@ find_mad_agent(struct ib_mad_port_private *port_priv, | |||
1640 | if (mad_agent->agent.recv_handler) | 1696 | if (mad_agent->agent.recv_handler) |
1641 | atomic_inc(&mad_agent->refcount); | 1697 | atomic_inc(&mad_agent->refcount); |
1642 | else { | 1698 | else { |
1643 | printk(KERN_NOTICE PFX "No receive handler for client " | 1699 | dev_notice(&port_priv->device->dev, |
1644 | "%p on port %d\n", | 1700 | "No receive handler for client %p on port %d\n", |
1645 | &mad_agent->agent, port_priv->port_num); | 1701 | &mad_agent->agent, port_priv->port_num); |
1646 | mad_agent = NULL; | 1702 | mad_agent = NULL; |
1647 | } | 1703 | } |
1648 | } | 1704 | } |
@@ -1658,8 +1714,8 @@ static int validate_mad(struct ib_mad *mad, u32 qp_num) | |||
1658 | 1714 | ||
1659 | /* Make sure MAD base version is understood */ | 1715 | /* Make sure MAD base version is understood */ |
1660 | if (mad->mad_hdr.base_version != IB_MGMT_BASE_VERSION) { | 1716 | if (mad->mad_hdr.base_version != IB_MGMT_BASE_VERSION) { |
1661 | printk(KERN_ERR PFX "MAD received with unsupported base " | 1717 | pr_err("MAD received with unsupported base version %d\n", |
1662 | "version %d\n", mad->mad_hdr.base_version); | 1718 | mad->mad_hdr.base_version); |
1663 | goto out; | 1719 | goto out; |
1664 | } | 1720 | } |
1665 | 1721 | ||
@@ -1685,6 +1741,7 @@ static int is_data_mad(struct ib_mad_agent_private *mad_agent_priv, | |||
1685 | 1741 | ||
1686 | rmpp_mad = (struct ib_rmpp_mad *)mad_hdr; | 1742 | rmpp_mad = (struct ib_rmpp_mad *)mad_hdr; |
1687 | return !mad_agent_priv->agent.rmpp_version || | 1743 | return !mad_agent_priv->agent.rmpp_version || |
1744 | !ib_mad_kernel_rmpp_agent(&mad_agent_priv->agent) || | ||
1688 | !(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & | 1745 | !(ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & |
1689 | IB_MGMT_RMPP_FLAG_ACTIVE) || | 1746 | IB_MGMT_RMPP_FLAG_ACTIVE) || |
1690 | (rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_DATA); | 1747 | (rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_DATA); |
@@ -1812,7 +1869,7 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv, | |||
1812 | 1869 | ||
1813 | INIT_LIST_HEAD(&mad_recv_wc->rmpp_list); | 1870 | INIT_LIST_HEAD(&mad_recv_wc->rmpp_list); |
1814 | list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list); | 1871 | list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list); |
1815 | if (mad_agent_priv->agent.rmpp_version) { | 1872 | if (ib_mad_kernel_rmpp_agent(&mad_agent_priv->agent)) { |
1816 | mad_recv_wc = ib_process_rmpp_recv_wc(mad_agent_priv, | 1873 | mad_recv_wc = ib_process_rmpp_recv_wc(mad_agent_priv, |
1817 | mad_recv_wc); | 1874 | mad_recv_wc); |
1818 | if (!mad_recv_wc) { | 1875 | if (!mad_recv_wc) { |
@@ -1827,23 +1884,39 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv, | |||
1827 | mad_send_wr = ib_find_send_mad(mad_agent_priv, mad_recv_wc); | 1884 | mad_send_wr = ib_find_send_mad(mad_agent_priv, mad_recv_wc); |
1828 | if (!mad_send_wr) { | 1885 | if (!mad_send_wr) { |
1829 | spin_unlock_irqrestore(&mad_agent_priv->lock, flags); | 1886 | spin_unlock_irqrestore(&mad_agent_priv->lock, flags); |
1830 | ib_free_recv_mad(mad_recv_wc); | 1887 | if (!ib_mad_kernel_rmpp_agent(&mad_agent_priv->agent) |
1831 | deref_mad_agent(mad_agent_priv); | 1888 | && ib_is_mad_class_rmpp(mad_recv_wc->recv_buf.mad->mad_hdr.mgmt_class) |
1832 | return; | 1889 | && (ib_get_rmpp_flags(&((struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad)->rmpp_hdr) |
1833 | } | 1890 | & IB_MGMT_RMPP_FLAG_ACTIVE)) { |
1834 | ib_mark_mad_done(mad_send_wr); | 1891 | /* user rmpp is in effect |
1835 | spin_unlock_irqrestore(&mad_agent_priv->lock, flags); | 1892 | * and this is an active RMPP MAD |
1893 | */ | ||
1894 | mad_recv_wc->wc->wr_id = 0; | ||
1895 | mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent, | ||
1896 | mad_recv_wc); | ||
1897 | atomic_dec(&mad_agent_priv->refcount); | ||
1898 | } else { | ||
1899 | /* not user rmpp, revert to normal behavior and | ||
1900 | * drop the mad */ | ||
1901 | ib_free_recv_mad(mad_recv_wc); | ||
1902 | deref_mad_agent(mad_agent_priv); | ||
1903 | return; | ||
1904 | } | ||
1905 | } else { | ||
1906 | ib_mark_mad_done(mad_send_wr); | ||
1907 | spin_unlock_irqrestore(&mad_agent_priv->lock, flags); | ||
1836 | 1908 | ||
1837 | /* Defined behavior is to complete response before request */ | 1909 | /* Defined behavior is to complete response before request */ |
1838 | mad_recv_wc->wc->wr_id = (unsigned long) &mad_send_wr->send_buf; | 1910 | mad_recv_wc->wc->wr_id = (unsigned long) &mad_send_wr->send_buf; |
1839 | mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent, | 1911 | mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent, |
1840 | mad_recv_wc); | 1912 | mad_recv_wc); |
1841 | atomic_dec(&mad_agent_priv->refcount); | 1913 | atomic_dec(&mad_agent_priv->refcount); |
1842 | 1914 | ||
1843 | mad_send_wc.status = IB_WC_SUCCESS; | 1915 | mad_send_wc.status = IB_WC_SUCCESS; |
1844 | mad_send_wc.vendor_err = 0; | 1916 | mad_send_wc.vendor_err = 0; |
1845 | mad_send_wc.send_buf = &mad_send_wr->send_buf; | 1917 | mad_send_wc.send_buf = &mad_send_wr->send_buf; |
1846 | ib_mad_complete_send_wr(mad_send_wr, &mad_send_wc); | 1918 | ib_mad_complete_send_wr(mad_send_wr, &mad_send_wc); |
1919 | } | ||
1847 | } else { | 1920 | } else { |
1848 | mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent, | 1921 | mad_agent_priv->agent.recv_handler(&mad_agent_priv->agent, |
1849 | mad_recv_wc); | 1922 | mad_recv_wc); |
@@ -1911,8 +1984,8 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, | |||
1911 | 1984 | ||
1912 | response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL); | 1985 | response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL); |
1913 | if (!response) { | 1986 | if (!response) { |
1914 | printk(KERN_ERR PFX "ib_mad_recv_done_handler no memory " | 1987 | dev_err(&port_priv->device->dev, |
1915 | "for response buffer\n"); | 1988 | "ib_mad_recv_done_handler no memory for response buffer\n"); |
1916 | goto out; | 1989 | goto out; |
1917 | } | 1990 | } |
1918 | 1991 | ||
@@ -2083,7 +2156,7 @@ void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr, | |||
2083 | 2156 | ||
2084 | mad_agent_priv = mad_send_wr->mad_agent_priv; | 2157 | mad_agent_priv = mad_send_wr->mad_agent_priv; |
2085 | spin_lock_irqsave(&mad_agent_priv->lock, flags); | 2158 | spin_lock_irqsave(&mad_agent_priv->lock, flags); |
2086 | if (mad_agent_priv->agent.rmpp_version) { | 2159 | if (ib_mad_kernel_rmpp_agent(&mad_agent_priv->agent)) { |
2087 | ret = ib_process_rmpp_send_wc(mad_send_wr, mad_send_wc); | 2160 | ret = ib_process_rmpp_send_wc(mad_send_wr, mad_send_wc); |
2088 | if (ret == IB_RMPP_RESULT_CONSUMED) | 2161 | if (ret == IB_RMPP_RESULT_CONSUMED) |
2089 | goto done; | 2162 | goto done; |
@@ -2176,7 +2249,8 @@ retry: | |||
2176 | ret = ib_post_send(qp_info->qp, &queued_send_wr->send_wr, | 2249 | ret = ib_post_send(qp_info->qp, &queued_send_wr->send_wr, |
2177 | &bad_send_wr); | 2250 | &bad_send_wr); |
2178 | if (ret) { | 2251 | if (ret) { |
2179 | printk(KERN_ERR PFX "ib_post_send failed: %d\n", ret); | 2252 | dev_err(&port_priv->device->dev, |
2253 | "ib_post_send failed: %d\n", ret); | ||
2180 | mad_send_wr = queued_send_wr; | 2254 | mad_send_wr = queued_send_wr; |
2181 | wc->status = IB_WC_LOC_QP_OP_ERR; | 2255 | wc->status = IB_WC_LOC_QP_OP_ERR; |
2182 | goto retry; | 2256 | goto retry; |
@@ -2248,8 +2322,9 @@ static void mad_error_handler(struct ib_mad_port_private *port_priv, | |||
2248 | IB_QP_STATE | IB_QP_CUR_STATE); | 2322 | IB_QP_STATE | IB_QP_CUR_STATE); |
2249 | kfree(attr); | 2323 | kfree(attr); |
2250 | if (ret) | 2324 | if (ret) |
2251 | printk(KERN_ERR PFX "mad_error_handler - " | 2325 | dev_err(&port_priv->device->dev, |
2252 | "ib_modify_qp to RTS : %d\n", ret); | 2326 | "mad_error_handler - ib_modify_qp to RTS : %d\n", |
2327 | ret); | ||
2253 | else | 2328 | else |
2254 | mark_sends_for_retry(qp_info); | 2329 | mark_sends_for_retry(qp_info); |
2255 | } | 2330 | } |
@@ -2408,7 +2483,8 @@ static void local_completions(struct work_struct *work) | |||
2408 | if (local->mad_priv) { | 2483 | if (local->mad_priv) { |
2409 | recv_mad_agent = local->recv_mad_agent; | 2484 | recv_mad_agent = local->recv_mad_agent; |
2410 | if (!recv_mad_agent) { | 2485 | if (!recv_mad_agent) { |
2411 | printk(KERN_ERR PFX "No receive MAD agent for local completion\n"); | 2486 | dev_err(&mad_agent_priv->agent.device->dev, |
2487 | "No receive MAD agent for local completion\n"); | ||
2412 | free_mad = 1; | 2488 | free_mad = 1; |
2413 | goto local_send_completion; | 2489 | goto local_send_completion; |
2414 | } | 2490 | } |
@@ -2476,7 +2552,7 @@ static int retry_send(struct ib_mad_send_wr_private *mad_send_wr) | |||
2476 | 2552 | ||
2477 | mad_send_wr->timeout = msecs_to_jiffies(mad_send_wr->send_buf.timeout_ms); | 2553 | mad_send_wr->timeout = msecs_to_jiffies(mad_send_wr->send_buf.timeout_ms); |
2478 | 2554 | ||
2479 | if (mad_send_wr->mad_agent_priv->agent.rmpp_version) { | 2555 | if (ib_mad_kernel_rmpp_agent(&mad_send_wr->mad_agent_priv->agent)) { |
2480 | ret = ib_retry_rmpp(mad_send_wr); | 2556 | ret = ib_retry_rmpp(mad_send_wr); |
2481 | switch (ret) { | 2557 | switch (ret) { |
2482 | case IB_RMPP_RESULT_UNHANDLED: | 2558 | case IB_RMPP_RESULT_UNHANDLED: |
@@ -2589,7 +2665,8 @@ static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info, | |||
2589 | } else { | 2665 | } else { |
2590 | mad_priv = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL); | 2666 | mad_priv = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL); |
2591 | if (!mad_priv) { | 2667 | if (!mad_priv) { |
2592 | printk(KERN_ERR PFX "No memory for receive buffer\n"); | 2668 | dev_err(&qp_info->port_priv->device->dev, |
2669 | "No memory for receive buffer\n"); | ||
2593 | ret = -ENOMEM; | 2670 | ret = -ENOMEM; |
2594 | break; | 2671 | break; |
2595 | } | 2672 | } |
@@ -2625,7 +2702,8 @@ static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info, | |||
2625 | sizeof mad_priv->header, | 2702 | sizeof mad_priv->header, |
2626 | DMA_FROM_DEVICE); | 2703 | DMA_FROM_DEVICE); |
2627 | kmem_cache_free(ib_mad_cache, mad_priv); | 2704 | kmem_cache_free(ib_mad_cache, mad_priv); |
2628 | printk(KERN_ERR PFX "ib_post_recv failed: %d\n", ret); | 2705 | dev_err(&qp_info->port_priv->device->dev, |
2706 | "ib_post_recv failed: %d\n", ret); | ||
2629 | break; | 2707 | break; |
2630 | } | 2708 | } |
2631 | } while (post); | 2709 | } while (post); |
@@ -2681,7 +2759,8 @@ static int ib_mad_port_start(struct ib_mad_port_private *port_priv) | |||
2681 | 2759 | ||
2682 | attr = kmalloc(sizeof *attr, GFP_KERNEL); | 2760 | attr = kmalloc(sizeof *attr, GFP_KERNEL); |
2683 | if (!attr) { | 2761 | if (!attr) { |
2684 | printk(KERN_ERR PFX "Couldn't kmalloc ib_qp_attr\n"); | 2762 | dev_err(&port_priv->device->dev, |
2763 | "Couldn't kmalloc ib_qp_attr\n"); | ||
2685 | return -ENOMEM; | 2764 | return -ENOMEM; |
2686 | } | 2765 | } |
2687 | 2766 | ||
@@ -2705,16 +2784,18 @@ static int ib_mad_port_start(struct ib_mad_port_private *port_priv) | |||
2705 | ret = ib_modify_qp(qp, attr, IB_QP_STATE | | 2784 | ret = ib_modify_qp(qp, attr, IB_QP_STATE | |
2706 | IB_QP_PKEY_INDEX | IB_QP_QKEY); | 2785 | IB_QP_PKEY_INDEX | IB_QP_QKEY); |
2707 | if (ret) { | 2786 | if (ret) { |
2708 | printk(KERN_ERR PFX "Couldn't change QP%d state to " | 2787 | dev_err(&port_priv->device->dev, |
2709 | "INIT: %d\n", i, ret); | 2788 | "Couldn't change QP%d state to INIT: %d\n", |
2789 | i, ret); | ||
2710 | goto out; | 2790 | goto out; |
2711 | } | 2791 | } |
2712 | 2792 | ||
2713 | attr->qp_state = IB_QPS_RTR; | 2793 | attr->qp_state = IB_QPS_RTR; |
2714 | ret = ib_modify_qp(qp, attr, IB_QP_STATE); | 2794 | ret = ib_modify_qp(qp, attr, IB_QP_STATE); |
2715 | if (ret) { | 2795 | if (ret) { |
2716 | printk(KERN_ERR PFX "Couldn't change QP%d state to " | 2796 | dev_err(&port_priv->device->dev, |
2717 | "RTR: %d\n", i, ret); | 2797 | "Couldn't change QP%d state to RTR: %d\n", |
2798 | i, ret); | ||
2718 | goto out; | 2799 | goto out; |
2719 | } | 2800 | } |
2720 | 2801 | ||
@@ -2722,16 +2803,18 @@ static int ib_mad_port_start(struct ib_mad_port_private *port_priv) | |||
2722 | attr->sq_psn = IB_MAD_SEND_Q_PSN; | 2803 | attr->sq_psn = IB_MAD_SEND_Q_PSN; |
2723 | ret = ib_modify_qp(qp, attr, IB_QP_STATE | IB_QP_SQ_PSN); | 2804 | ret = ib_modify_qp(qp, attr, IB_QP_STATE | IB_QP_SQ_PSN); |
2724 | if (ret) { | 2805 | if (ret) { |
2725 | printk(KERN_ERR PFX "Couldn't change QP%d state to " | 2806 | dev_err(&port_priv->device->dev, |
2726 | "RTS: %d\n", i, ret); | 2807 | "Couldn't change QP%d state to RTS: %d\n", |
2808 | i, ret); | ||
2727 | goto out; | 2809 | goto out; |
2728 | } | 2810 | } |
2729 | } | 2811 | } |
2730 | 2812 | ||
2731 | ret = ib_req_notify_cq(port_priv->cq, IB_CQ_NEXT_COMP); | 2813 | ret = ib_req_notify_cq(port_priv->cq, IB_CQ_NEXT_COMP); |
2732 | if (ret) { | 2814 | if (ret) { |
2733 | printk(KERN_ERR PFX "Failed to request completion " | 2815 | dev_err(&port_priv->device->dev, |
2734 | "notification: %d\n", ret); | 2816 | "Failed to request completion notification: %d\n", |
2817 | ret); | ||
2735 | goto out; | 2818 | goto out; |
2736 | } | 2819 | } |
2737 | 2820 | ||
@@ -2741,7 +2824,8 @@ static int ib_mad_port_start(struct ib_mad_port_private *port_priv) | |||
2741 | 2824 | ||
2742 | ret = ib_mad_post_receive_mads(&port_priv->qp_info[i], NULL); | 2825 | ret = ib_mad_post_receive_mads(&port_priv->qp_info[i], NULL); |
2743 | if (ret) { | 2826 | if (ret) { |
2744 | printk(KERN_ERR PFX "Couldn't post receive WRs\n"); | 2827 | dev_err(&port_priv->device->dev, |
2828 | "Couldn't post receive WRs\n"); | ||
2745 | goto out; | 2829 | goto out; |
2746 | } | 2830 | } |
2747 | } | 2831 | } |
@@ -2755,7 +2839,8 @@ static void qp_event_handler(struct ib_event *event, void *qp_context) | |||
2755 | struct ib_mad_qp_info *qp_info = qp_context; | 2839 | struct ib_mad_qp_info *qp_info = qp_context; |
2756 | 2840 | ||
2757 | /* It's worse than that! He's dead, Jim! */ | 2841 | /* It's worse than that! He's dead, Jim! */ |
2758 | printk(KERN_ERR PFX "Fatal error (%d) on MAD QP (%d)\n", | 2842 | dev_err(&qp_info->port_priv->device->dev, |
2843 | "Fatal error (%d) on MAD QP (%d)\n", | ||
2759 | event->event, qp_info->qp->qp_num); | 2844 | event->event, qp_info->qp->qp_num); |
2760 | } | 2845 | } |
2761 | 2846 | ||
@@ -2801,8 +2886,9 @@ static int create_mad_qp(struct ib_mad_qp_info *qp_info, | |||
2801 | qp_init_attr.event_handler = qp_event_handler; | 2886 | qp_init_attr.event_handler = qp_event_handler; |
2802 | qp_info->qp = ib_create_qp(qp_info->port_priv->pd, &qp_init_attr); | 2887 | qp_info->qp = ib_create_qp(qp_info->port_priv->pd, &qp_init_attr); |
2803 | if (IS_ERR(qp_info->qp)) { | 2888 | if (IS_ERR(qp_info->qp)) { |
2804 | printk(KERN_ERR PFX "Couldn't create ib_mad QP%d\n", | 2889 | dev_err(&qp_info->port_priv->device->dev, |
2805 | get_spl_qp_index(qp_type)); | 2890 | "Couldn't create ib_mad QP%d\n", |
2891 | get_spl_qp_index(qp_type)); | ||
2806 | ret = PTR_ERR(qp_info->qp); | 2892 | ret = PTR_ERR(qp_info->qp); |
2807 | goto error; | 2893 | goto error; |
2808 | } | 2894 | } |
@@ -2840,7 +2926,7 @@ static int ib_mad_port_open(struct ib_device *device, | |||
2840 | /* Create new device info */ | 2926 | /* Create new device info */ |
2841 | port_priv = kzalloc(sizeof *port_priv, GFP_KERNEL); | 2927 | port_priv = kzalloc(sizeof *port_priv, GFP_KERNEL); |
2842 | if (!port_priv) { | 2928 | if (!port_priv) { |
2843 | printk(KERN_ERR PFX "No memory for ib_mad_port_private\n"); | 2929 | dev_err(&device->dev, "No memory for ib_mad_port_private\n"); |
2844 | return -ENOMEM; | 2930 | return -ENOMEM; |
2845 | } | 2931 | } |
2846 | 2932 | ||
@@ -2860,21 +2946,21 @@ static int ib_mad_port_open(struct ib_device *device, | |||
2860 | ib_mad_thread_completion_handler, | 2946 | ib_mad_thread_completion_handler, |
2861 | NULL, port_priv, cq_size, 0); | 2947 | NULL, port_priv, cq_size, 0); |
2862 | if (IS_ERR(port_priv->cq)) { | 2948 | if (IS_ERR(port_priv->cq)) { |
2863 | printk(KERN_ERR PFX "Couldn't create ib_mad CQ\n"); | 2949 | dev_err(&device->dev, "Couldn't create ib_mad CQ\n"); |
2864 | ret = PTR_ERR(port_priv->cq); | 2950 | ret = PTR_ERR(port_priv->cq); |
2865 | goto error3; | 2951 | goto error3; |
2866 | } | 2952 | } |
2867 | 2953 | ||
2868 | port_priv->pd = ib_alloc_pd(device); | 2954 | port_priv->pd = ib_alloc_pd(device); |
2869 | if (IS_ERR(port_priv->pd)) { | 2955 | if (IS_ERR(port_priv->pd)) { |
2870 | printk(KERN_ERR PFX "Couldn't create ib_mad PD\n"); | 2956 | dev_err(&device->dev, "Couldn't create ib_mad PD\n"); |
2871 | ret = PTR_ERR(port_priv->pd); | 2957 | ret = PTR_ERR(port_priv->pd); |
2872 | goto error4; | 2958 | goto error4; |
2873 | } | 2959 | } |
2874 | 2960 | ||
2875 | port_priv->mr = ib_get_dma_mr(port_priv->pd, IB_ACCESS_LOCAL_WRITE); | 2961 | port_priv->mr = ib_get_dma_mr(port_priv->pd, IB_ACCESS_LOCAL_WRITE); |
2876 | if (IS_ERR(port_priv->mr)) { | 2962 | if (IS_ERR(port_priv->mr)) { |
2877 | printk(KERN_ERR PFX "Couldn't get ib_mad DMA MR\n"); | 2963 | dev_err(&device->dev, "Couldn't get ib_mad DMA MR\n"); |
2878 | ret = PTR_ERR(port_priv->mr); | 2964 | ret = PTR_ERR(port_priv->mr); |
2879 | goto error5; | 2965 | goto error5; |
2880 | } | 2966 | } |
@@ -2902,7 +2988,7 @@ static int ib_mad_port_open(struct ib_device *device, | |||
2902 | 2988 | ||
2903 | ret = ib_mad_port_start(port_priv); | 2989 | ret = ib_mad_port_start(port_priv); |
2904 | if (ret) { | 2990 | if (ret) { |
2905 | printk(KERN_ERR PFX "Couldn't start port\n"); | 2991 | dev_err(&device->dev, "Couldn't start port\n"); |
2906 | goto error9; | 2992 | goto error9; |
2907 | } | 2993 | } |
2908 | 2994 | ||
@@ -2946,7 +3032,7 @@ static int ib_mad_port_close(struct ib_device *device, int port_num) | |||
2946 | port_priv = __ib_get_mad_port(device, port_num); | 3032 | port_priv = __ib_get_mad_port(device, port_num); |
2947 | if (port_priv == NULL) { | 3033 | if (port_priv == NULL) { |
2948 | spin_unlock_irqrestore(&ib_mad_port_list_lock, flags); | 3034 | spin_unlock_irqrestore(&ib_mad_port_list_lock, flags); |
2949 | printk(KERN_ERR PFX "Port %d not found\n", port_num); | 3035 | dev_err(&device->dev, "Port %d not found\n", port_num); |
2950 | return -ENODEV; | 3036 | return -ENODEV; |
2951 | } | 3037 | } |
2952 | list_del_init(&port_priv->port_list); | 3038 | list_del_init(&port_priv->port_list); |
@@ -2984,14 +3070,12 @@ static void ib_mad_init_device(struct ib_device *device) | |||
2984 | 3070 | ||
2985 | for (i = start; i <= end; i++) { | 3071 | for (i = start; i <= end; i++) { |
2986 | if (ib_mad_port_open(device, i)) { | 3072 | if (ib_mad_port_open(device, i)) { |
2987 | printk(KERN_ERR PFX "Couldn't open %s port %d\n", | 3073 | dev_err(&device->dev, "Couldn't open port %d\n", i); |
2988 | device->name, i); | ||
2989 | goto error; | 3074 | goto error; |
2990 | } | 3075 | } |
2991 | if (ib_agent_port_open(device, i)) { | 3076 | if (ib_agent_port_open(device, i)) { |
2992 | printk(KERN_ERR PFX "Couldn't open %s port %d " | 3077 | dev_err(&device->dev, |
2993 | "for agents\n", | 3078 | "Couldn't open port %d for agents\n", i); |
2994 | device->name, i); | ||
2995 | goto error_agent; | 3079 | goto error_agent; |
2996 | } | 3080 | } |
2997 | } | 3081 | } |
@@ -2999,20 +3083,17 @@ static void ib_mad_init_device(struct ib_device *device) | |||
2999 | 3083 | ||
3000 | error_agent: | 3084 | error_agent: |
3001 | if (ib_mad_port_close(device, i)) | 3085 | if (ib_mad_port_close(device, i)) |
3002 | printk(KERN_ERR PFX "Couldn't close %s port %d\n", | 3086 | dev_err(&device->dev, "Couldn't close port %d\n", i); |
3003 | device->name, i); | ||
3004 | 3087 | ||
3005 | error: | 3088 | error: |
3006 | i--; | 3089 | i--; |
3007 | 3090 | ||
3008 | while (i >= start) { | 3091 | while (i >= start) { |
3009 | if (ib_agent_port_close(device, i)) | 3092 | if (ib_agent_port_close(device, i)) |
3010 | printk(KERN_ERR PFX "Couldn't close %s port %d " | 3093 | dev_err(&device->dev, |
3011 | "for agents\n", | 3094 | "Couldn't close port %d for agents\n", i); |
3012 | device->name, i); | ||
3013 | if (ib_mad_port_close(device, i)) | 3095 | if (ib_mad_port_close(device, i)) |
3014 | printk(KERN_ERR PFX "Couldn't close %s port %d\n", | 3096 | dev_err(&device->dev, "Couldn't close port %d\n", i); |
3015 | device->name, i); | ||
3016 | i--; | 3097 | i--; |
3017 | } | 3098 | } |
3018 | } | 3099 | } |
@@ -3033,12 +3114,12 @@ static void ib_mad_remove_device(struct ib_device *device) | |||
3033 | } | 3114 | } |
3034 | for (i = 0; i < num_ports; i++, cur_port++) { | 3115 | for (i = 0; i < num_ports; i++, cur_port++) { |
3035 | if (ib_agent_port_close(device, cur_port)) | 3116 | if (ib_agent_port_close(device, cur_port)) |
3036 | printk(KERN_ERR PFX "Couldn't close %s port %d " | 3117 | dev_err(&device->dev, |
3037 | "for agents\n", | 3118 | "Couldn't close port %d for agents\n", |
3038 | device->name, cur_port); | 3119 | cur_port); |
3039 | if (ib_mad_port_close(device, cur_port)) | 3120 | if (ib_mad_port_close(device, cur_port)) |
3040 | printk(KERN_ERR PFX "Couldn't close %s port %d\n", | 3121 | dev_err(&device->dev, "Couldn't close port %d\n", |
3041 | device->name, cur_port); | 3122 | cur_port); |
3042 | } | 3123 | } |
3043 | } | 3124 | } |
3044 | 3125 | ||
@@ -3064,7 +3145,7 @@ static int __init ib_mad_init_module(void) | |||
3064 | SLAB_HWCACHE_ALIGN, | 3145 | SLAB_HWCACHE_ALIGN, |
3065 | NULL); | 3146 | NULL); |
3066 | if (!ib_mad_cache) { | 3147 | if (!ib_mad_cache) { |
3067 | printk(KERN_ERR PFX "Couldn't create ib_mad cache\n"); | 3148 | pr_err("Couldn't create ib_mad cache\n"); |
3068 | ret = -ENOMEM; | 3149 | ret = -ENOMEM; |
3069 | goto error1; | 3150 | goto error1; |
3070 | } | 3151 | } |
@@ -3072,7 +3153,7 @@ static int __init ib_mad_init_module(void) | |||
3072 | INIT_LIST_HEAD(&ib_mad_port_list); | 3153 | INIT_LIST_HEAD(&ib_mad_port_list); |
3073 | 3154 | ||
3074 | if (ib_register_client(&mad_client)) { | 3155 | if (ib_register_client(&mad_client)) { |
3075 | printk(KERN_ERR PFX "Couldn't register ib_mad client\n"); | 3156 | pr_err("Couldn't register ib_mad client\n"); |
3076 | ret = -EINVAL; | 3157 | ret = -EINVAL; |
3077 | goto error2; | 3158 | goto error2; |
3078 | } | 3159 | } |
diff --git a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h index 9430ab4969c5..d1a0b0ee9444 100644 --- a/drivers/infiniband/core/mad_priv.h +++ b/drivers/infiniband/core/mad_priv.h | |||
@@ -42,9 +42,6 @@ | |||
42 | #include <rdma/ib_mad.h> | 42 | #include <rdma/ib_mad.h> |
43 | #include <rdma/ib_smi.h> | 43 | #include <rdma/ib_smi.h> |
44 | 44 | ||
45 | |||
46 | #define PFX "ib_mad: " | ||
47 | |||
48 | #define IB_MAD_QPS_CORE 2 /* Always QP0 and QP1 as a minimum */ | 45 | #define IB_MAD_QPS_CORE 2 /* Always QP0 and QP1 as a minimum */ |
49 | 46 | ||
50 | /* QP and CQ parameters */ | 47 | /* QP and CQ parameters */ |
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 233eaf541f55..c38f030f0dc9 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c | |||
@@ -1184,7 +1184,7 @@ static void ib_sa_add_one(struct ib_device *device) | |||
1184 | sa_dev->port[i].agent = | 1184 | sa_dev->port[i].agent = |
1185 | ib_register_mad_agent(device, i + s, IB_QPT_GSI, | 1185 | ib_register_mad_agent(device, i + s, IB_QPT_GSI, |
1186 | NULL, 0, send_handler, | 1186 | NULL, 0, send_handler, |
1187 | recv_handler, sa_dev); | 1187 | recv_handler, sa_dev, 0); |
1188 | if (IS_ERR(sa_dev->port[i].agent)) | 1188 | if (IS_ERR(sa_dev->port[i].agent)) |
1189 | goto err; | 1189 | goto err; |
1190 | 1190 | ||
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 1acb99100556..928cdd20e2d1 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c | |||
@@ -33,6 +33,8 @@ | |||
33 | * SOFTWARE. | 33 | * SOFTWARE. |
34 | */ | 34 | */ |
35 | 35 | ||
36 | #define pr_fmt(fmt) "user_mad: " fmt | ||
37 | |||
36 | #include <linux/module.h> | 38 | #include <linux/module.h> |
37 | #include <linux/init.h> | 39 | #include <linux/init.h> |
38 | #include <linux/device.h> | 40 | #include <linux/device.h> |
@@ -504,13 +506,15 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
504 | 506 | ||
505 | rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data; | 507 | rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data; |
506 | hdr_len = ib_get_mad_data_offset(rmpp_mad->mad_hdr.mgmt_class); | 508 | hdr_len = ib_get_mad_data_offset(rmpp_mad->mad_hdr.mgmt_class); |
507 | if (!ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class)) { | 509 | |
508 | copy_offset = IB_MGMT_MAD_HDR; | 510 | if (ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class) |
509 | rmpp_active = 0; | 511 | && ib_mad_kernel_rmpp_agent(agent)) { |
510 | } else { | ||
511 | copy_offset = IB_MGMT_RMPP_HDR; | 512 | copy_offset = IB_MGMT_RMPP_HDR; |
512 | rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & | 513 | rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & |
513 | IB_MGMT_RMPP_FLAG_ACTIVE; | 514 | IB_MGMT_RMPP_FLAG_ACTIVE; |
515 | } else { | ||
516 | copy_offset = IB_MGMT_MAD_HDR; | ||
517 | rmpp_active = 0; | ||
514 | } | 518 | } |
515 | 519 | ||
516 | data_len = count - hdr_size(file) - hdr_len; | 520 | data_len = count - hdr_size(file) - hdr_len; |
@@ -556,14 +560,22 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf, | |||
556 | rmpp_mad->mad_hdr.tid = *tid; | 560 | rmpp_mad->mad_hdr.tid = *tid; |
557 | } | 561 | } |
558 | 562 | ||
559 | spin_lock_irq(&file->send_lock); | 563 | if (!ib_mad_kernel_rmpp_agent(agent) |
560 | ret = is_duplicate(file, packet); | 564 | && ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class) |
561 | if (!ret) | 565 | && (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE)) { |
566 | spin_lock_irq(&file->send_lock); | ||
562 | list_add_tail(&packet->list, &file->send_list); | 567 | list_add_tail(&packet->list, &file->send_list); |
563 | spin_unlock_irq(&file->send_lock); | 568 | spin_unlock_irq(&file->send_lock); |
564 | if (ret) { | 569 | } else { |
565 | ret = -EINVAL; | 570 | spin_lock_irq(&file->send_lock); |
566 | goto err_msg; | 571 | ret = is_duplicate(file, packet); |
572 | if (!ret) | ||
573 | list_add_tail(&packet->list, &file->send_list); | ||
574 | spin_unlock_irq(&file->send_lock); | ||
575 | if (ret) { | ||
576 | ret = -EINVAL; | ||
577 | goto err_msg; | ||
578 | } | ||
567 | } | 579 | } |
568 | 580 | ||
569 | ret = ib_post_send_mad(packet->msg, NULL); | 581 | ret = ib_post_send_mad(packet->msg, NULL); |
@@ -614,6 +626,8 @@ static int ib_umad_reg_agent(struct ib_umad_file *file, void __user *arg, | |||
614 | mutex_lock(&file->mutex); | 626 | mutex_lock(&file->mutex); |
615 | 627 | ||
616 | if (!file->port->ib_dev) { | 628 | if (!file->port->ib_dev) { |
629 | dev_notice(file->port->dev, | ||
630 | "ib_umad_reg_agent: invalid device\n"); | ||
617 | ret = -EPIPE; | 631 | ret = -EPIPE; |
618 | goto out; | 632 | goto out; |
619 | } | 633 | } |
@@ -624,6 +638,9 @@ static int ib_umad_reg_agent(struct ib_umad_file *file, void __user *arg, | |||
624 | } | 638 | } |
625 | 639 | ||
626 | if (ureq.qpn != 0 && ureq.qpn != 1) { | 640 | if (ureq.qpn != 0 && ureq.qpn != 1) { |
641 | dev_notice(file->port->dev, | ||
642 | "ib_umad_reg_agent: invalid QPN %d specified\n", | ||
643 | ureq.qpn); | ||
627 | ret = -EINVAL; | 644 | ret = -EINVAL; |
628 | goto out; | 645 | goto out; |
629 | } | 646 | } |
@@ -632,11 +649,15 @@ static int ib_umad_reg_agent(struct ib_umad_file *file, void __user *arg, | |||
632 | if (!__get_agent(file, agent_id)) | 649 | if (!__get_agent(file, agent_id)) |
633 | goto found; | 650 | goto found; |
634 | 651 | ||
652 | dev_notice(file->port->dev, | ||
653 | "ib_umad_reg_agent: Max Agents (%u) reached\n", | ||
654 | IB_UMAD_MAX_AGENTS); | ||
635 | ret = -ENOMEM; | 655 | ret = -ENOMEM; |
636 | goto out; | 656 | goto out; |
637 | 657 | ||
638 | found: | 658 | found: |
639 | if (ureq.mgmt_class) { | 659 | if (ureq.mgmt_class) { |
660 | memset(&req, 0, sizeof(req)); | ||
640 | req.mgmt_class = ureq.mgmt_class; | 661 | req.mgmt_class = ureq.mgmt_class; |
641 | req.mgmt_class_version = ureq.mgmt_class_version; | 662 | req.mgmt_class_version = ureq.mgmt_class_version; |
642 | memcpy(req.oui, ureq.oui, sizeof req.oui); | 663 | memcpy(req.oui, ureq.oui, sizeof req.oui); |
@@ -657,7 +678,7 @@ found: | |||
657 | ureq.qpn ? IB_QPT_GSI : IB_QPT_SMI, | 678 | ureq.qpn ? IB_QPT_GSI : IB_QPT_SMI, |
658 | ureq.mgmt_class ? &req : NULL, | 679 | ureq.mgmt_class ? &req : NULL, |
659 | ureq.rmpp_version, | 680 | ureq.rmpp_version, |
660 | send_handler, recv_handler, file); | 681 | send_handler, recv_handler, file, 0); |
661 | if (IS_ERR(agent)) { | 682 | if (IS_ERR(agent)) { |
662 | ret = PTR_ERR(agent); | 683 | ret = PTR_ERR(agent); |
663 | agent = NULL; | 684 | agent = NULL; |
@@ -673,10 +694,11 @@ found: | |||
673 | if (!file->already_used) { | 694 | if (!file->already_used) { |
674 | file->already_used = 1; | 695 | file->already_used = 1; |
675 | if (!file->use_pkey_index) { | 696 | if (!file->use_pkey_index) { |
676 | printk(KERN_WARNING "user_mad: process %s did not enable " | 697 | dev_warn(file->port->dev, |
677 | "P_Key index support.\n", current->comm); | 698 | "process %s did not enable P_Key index support.\n", |
678 | printk(KERN_WARNING "user_mad: Documentation/infiniband/user_mad.txt " | 699 | current->comm); |
679 | "has info on the new ABI.\n"); | 700 | dev_warn(file->port->dev, |
701 | " Documentation/infiniband/user_mad.txt has info on the new ABI.\n"); | ||
680 | } | 702 | } |
681 | } | 703 | } |
682 | 704 | ||
@@ -694,6 +716,119 @@ out: | |||
694 | return ret; | 716 | return ret; |
695 | } | 717 | } |
696 | 718 | ||
719 | static int ib_umad_reg_agent2(struct ib_umad_file *file, void __user *arg) | ||
720 | { | ||
721 | struct ib_user_mad_reg_req2 ureq; | ||
722 | struct ib_mad_reg_req req; | ||
723 | struct ib_mad_agent *agent = NULL; | ||
724 | int agent_id; | ||
725 | int ret; | ||
726 | |||
727 | mutex_lock(&file->port->file_mutex); | ||
728 | mutex_lock(&file->mutex); | ||
729 | |||
730 | if (!file->port->ib_dev) { | ||
731 | dev_notice(file->port->dev, | ||
732 | "ib_umad_reg_agent2: invalid device\n"); | ||
733 | ret = -EPIPE; | ||
734 | goto out; | ||
735 | } | ||
736 | |||
737 | if (copy_from_user(&ureq, arg, sizeof(ureq))) { | ||
738 | ret = -EFAULT; | ||
739 | goto out; | ||
740 | } | ||
741 | |||
742 | if (ureq.qpn != 0 && ureq.qpn != 1) { | ||
743 | dev_notice(file->port->dev, | ||
744 | "ib_umad_reg_agent2: invalid QPN %d specified\n", | ||
745 | ureq.qpn); | ||
746 | ret = -EINVAL; | ||
747 | goto out; | ||
748 | } | ||
749 | |||
750 | if (ureq.flags & ~IB_USER_MAD_REG_FLAGS_CAP) { | ||
751 | dev_notice(file->port->dev, | ||
752 | "ib_umad_reg_agent2 failed: invalid registration flags specified 0x%x; supported 0x%x\n", | ||
753 | ureq.flags, IB_USER_MAD_REG_FLAGS_CAP); | ||
754 | ret = -EINVAL; | ||
755 | |||
756 | if (put_user((u32)IB_USER_MAD_REG_FLAGS_CAP, | ||
757 | (u32 __user *) (arg + offsetof(struct | ||
758 | ib_user_mad_reg_req2, flags)))) | ||
759 | ret = -EFAULT; | ||
760 | |||
761 | goto out; | ||
762 | } | ||
763 | |||
764 | for (agent_id = 0; agent_id < IB_UMAD_MAX_AGENTS; ++agent_id) | ||
765 | if (!__get_agent(file, agent_id)) | ||
766 | goto found; | ||
767 | |||
768 | dev_notice(file->port->dev, | ||
769 | "ib_umad_reg_agent2: Max Agents (%u) reached\n", | ||
770 | IB_UMAD_MAX_AGENTS); | ||
771 | ret = -ENOMEM; | ||
772 | goto out; | ||
773 | |||
774 | found: | ||
775 | if (ureq.mgmt_class) { | ||
776 | memset(&req, 0, sizeof(req)); | ||
777 | req.mgmt_class = ureq.mgmt_class; | ||
778 | req.mgmt_class_version = ureq.mgmt_class_version; | ||
779 | if (ureq.oui & 0xff000000) { | ||
780 | dev_notice(file->port->dev, | ||
781 | "ib_umad_reg_agent2 failed: oui invalid 0x%08x\n", | ||
782 | ureq.oui); | ||
783 | ret = -EINVAL; | ||
784 | goto out; | ||
785 | } | ||
786 | req.oui[2] = ureq.oui & 0x0000ff; | ||
787 | req.oui[1] = (ureq.oui & 0x00ff00) >> 8; | ||
788 | req.oui[0] = (ureq.oui & 0xff0000) >> 16; | ||
789 | memcpy(req.method_mask, ureq.method_mask, | ||
790 | sizeof(req.method_mask)); | ||
791 | } | ||
792 | |||
793 | agent = ib_register_mad_agent(file->port->ib_dev, file->port->port_num, | ||
794 | ureq.qpn ? IB_QPT_GSI : IB_QPT_SMI, | ||
795 | ureq.mgmt_class ? &req : NULL, | ||
796 | ureq.rmpp_version, | ||
797 | send_handler, recv_handler, file, | ||
798 | ureq.flags); | ||
799 | if (IS_ERR(agent)) { | ||
800 | ret = PTR_ERR(agent); | ||
801 | agent = NULL; | ||
802 | goto out; | ||
803 | } | ||
804 | |||
805 | if (put_user(agent_id, | ||
806 | (u32 __user *)(arg + | ||
807 | offsetof(struct ib_user_mad_reg_req2, id)))) { | ||
808 | ret = -EFAULT; | ||
809 | goto out; | ||
810 | } | ||
811 | |||
812 | if (!file->already_used) { | ||
813 | file->already_used = 1; | ||
814 | file->use_pkey_index = 1; | ||
815 | } | ||
816 | |||
817 | file->agent[agent_id] = agent; | ||
818 | ret = 0; | ||
819 | |||
820 | out: | ||
821 | mutex_unlock(&file->mutex); | ||
822 | |||
823 | if (ret && agent) | ||
824 | ib_unregister_mad_agent(agent); | ||
825 | |||
826 | mutex_unlock(&file->port->file_mutex); | ||
827 | |||
828 | return ret; | ||
829 | } | ||
830 | |||
831 | |||
697 | static int ib_umad_unreg_agent(struct ib_umad_file *file, u32 __user *arg) | 832 | static int ib_umad_unreg_agent(struct ib_umad_file *file, u32 __user *arg) |
698 | { | 833 | { |
699 | struct ib_mad_agent *agent = NULL; | 834 | struct ib_mad_agent *agent = NULL; |
@@ -749,6 +884,8 @@ static long ib_umad_ioctl(struct file *filp, unsigned int cmd, | |||
749 | return ib_umad_unreg_agent(filp->private_data, (__u32 __user *) arg); | 884 | return ib_umad_unreg_agent(filp->private_data, (__u32 __user *) arg); |
750 | case IB_USER_MAD_ENABLE_PKEY: | 885 | case IB_USER_MAD_ENABLE_PKEY: |
751 | return ib_umad_enable_pkey(filp->private_data); | 886 | return ib_umad_enable_pkey(filp->private_data); |
887 | case IB_USER_MAD_REGISTER_AGENT2: | ||
888 | return ib_umad_reg_agent2(filp->private_data, (void __user *) arg); | ||
752 | default: | 889 | default: |
753 | return -ENOIOCTLCMD; | 890 | return -ENOIOCTLCMD; |
754 | } | 891 | } |
@@ -765,6 +902,8 @@ static long ib_umad_compat_ioctl(struct file *filp, unsigned int cmd, | |||
765 | return ib_umad_unreg_agent(filp->private_data, compat_ptr(arg)); | 902 | return ib_umad_unreg_agent(filp->private_data, compat_ptr(arg)); |
766 | case IB_USER_MAD_ENABLE_PKEY: | 903 | case IB_USER_MAD_ENABLE_PKEY: |
767 | return ib_umad_enable_pkey(filp->private_data); | 904 | return ib_umad_enable_pkey(filp->private_data); |
905 | case IB_USER_MAD_REGISTER_AGENT2: | ||
906 | return ib_umad_reg_agent2(filp->private_data, compat_ptr(arg)); | ||
768 | default: | 907 | default: |
769 | return -ENOIOCTLCMD; | 908 | return -ENOIOCTLCMD; |
770 | } | 909 | } |
@@ -983,7 +1122,7 @@ static CLASS_ATTR_STRING(abi_version, S_IRUGO, | |||
983 | 1122 | ||
984 | static dev_t overflow_maj; | 1123 | static dev_t overflow_maj; |
985 | static DECLARE_BITMAP(overflow_map, IB_UMAD_MAX_PORTS); | 1124 | static DECLARE_BITMAP(overflow_map, IB_UMAD_MAX_PORTS); |
986 | static int find_overflow_devnum(void) | 1125 | static int find_overflow_devnum(struct ib_device *device) |
987 | { | 1126 | { |
988 | int ret; | 1127 | int ret; |
989 | 1128 | ||
@@ -991,7 +1130,8 @@ static int find_overflow_devnum(void) | |||
991 | ret = alloc_chrdev_region(&overflow_maj, 0, IB_UMAD_MAX_PORTS * 2, | 1130 | ret = alloc_chrdev_region(&overflow_maj, 0, IB_UMAD_MAX_PORTS * 2, |
992 | "infiniband_mad"); | 1131 | "infiniband_mad"); |
993 | if (ret) { | 1132 | if (ret) { |
994 | printk(KERN_ERR "user_mad: couldn't register dynamic device number\n"); | 1133 | dev_err(&device->dev, |
1134 | "couldn't register dynamic device number\n"); | ||
995 | return ret; | 1135 | return ret; |
996 | } | 1136 | } |
997 | } | 1137 | } |
@@ -1014,7 +1154,7 @@ static int ib_umad_init_port(struct ib_device *device, int port_num, | |||
1014 | devnum = find_first_zero_bit(dev_map, IB_UMAD_MAX_PORTS); | 1154 | devnum = find_first_zero_bit(dev_map, IB_UMAD_MAX_PORTS); |
1015 | if (devnum >= IB_UMAD_MAX_PORTS) { | 1155 | if (devnum >= IB_UMAD_MAX_PORTS) { |
1016 | spin_unlock(&port_lock); | 1156 | spin_unlock(&port_lock); |
1017 | devnum = find_overflow_devnum(); | 1157 | devnum = find_overflow_devnum(device); |
1018 | if (devnum < 0) | 1158 | if (devnum < 0) |
1019 | return -1; | 1159 | return -1; |
1020 | 1160 | ||
@@ -1200,14 +1340,14 @@ static int __init ib_umad_init(void) | |||
1200 | ret = register_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2, | 1340 | ret = register_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2, |
1201 | "infiniband_mad"); | 1341 | "infiniband_mad"); |
1202 | if (ret) { | 1342 | if (ret) { |
1203 | printk(KERN_ERR "user_mad: couldn't register device number\n"); | 1343 | pr_err("couldn't register device number\n"); |
1204 | goto out; | 1344 | goto out; |
1205 | } | 1345 | } |
1206 | 1346 | ||
1207 | umad_class = class_create(THIS_MODULE, "infiniband_mad"); | 1347 | umad_class = class_create(THIS_MODULE, "infiniband_mad"); |
1208 | if (IS_ERR(umad_class)) { | 1348 | if (IS_ERR(umad_class)) { |
1209 | ret = PTR_ERR(umad_class); | 1349 | ret = PTR_ERR(umad_class); |
1210 | printk(KERN_ERR "user_mad: couldn't create class infiniband_mad\n"); | 1350 | pr_err("couldn't create class infiniband_mad\n"); |
1211 | goto out_chrdev; | 1351 | goto out_chrdev; |
1212 | } | 1352 | } |
1213 | 1353 | ||
@@ -1215,13 +1355,13 @@ static int __init ib_umad_init(void) | |||
1215 | 1355 | ||
1216 | ret = class_create_file(umad_class, &class_attr_abi_version.attr); | 1356 | ret = class_create_file(umad_class, &class_attr_abi_version.attr); |
1217 | if (ret) { | 1357 | if (ret) { |
1218 | printk(KERN_ERR "user_mad: couldn't create abi_version attribute\n"); | 1358 | pr_err("couldn't create abi_version attribute\n"); |
1219 | goto out_class; | 1359 | goto out_class; |
1220 | } | 1360 | } |
1221 | 1361 | ||
1222 | ret = ib_register_client(&umad_client); | 1362 | ret = ib_register_client(&umad_client); |
1223 | if (ret) { | 1363 | if (ret) { |
1224 | printk(KERN_ERR "user_mad: couldn't register ib_umad client\n"); | 1364 | pr_err("couldn't register ib_umad client\n"); |
1225 | goto out_class; | 1365 | goto out_class; |
1226 | } | 1366 | } |
1227 | 1367 | ||
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h index a283274a5a09..643c08a025a5 100644 --- a/drivers/infiniband/core/uverbs.h +++ b/drivers/infiniband/core/uverbs.h | |||
@@ -221,6 +221,7 @@ IB_UVERBS_DECLARE_CMD(query_port); | |||
221 | IB_UVERBS_DECLARE_CMD(alloc_pd); | 221 | IB_UVERBS_DECLARE_CMD(alloc_pd); |
222 | IB_UVERBS_DECLARE_CMD(dealloc_pd); | 222 | IB_UVERBS_DECLARE_CMD(dealloc_pd); |
223 | IB_UVERBS_DECLARE_CMD(reg_mr); | 223 | IB_UVERBS_DECLARE_CMD(reg_mr); |
224 | IB_UVERBS_DECLARE_CMD(rereg_mr); | ||
224 | IB_UVERBS_DECLARE_CMD(dereg_mr); | 225 | IB_UVERBS_DECLARE_CMD(dereg_mr); |
225 | IB_UVERBS_DECLARE_CMD(alloc_mw); | 226 | IB_UVERBS_DECLARE_CMD(alloc_mw); |
226 | IB_UVERBS_DECLARE_CMD(dealloc_mw); | 227 | IB_UVERBS_DECLARE_CMD(dealloc_mw); |
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index ea6203ee7bcc..0600c50e6215 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -1002,6 +1002,99 @@ err_free: | |||
1002 | return ret; | 1002 | return ret; |
1003 | } | 1003 | } |
1004 | 1004 | ||
1005 | ssize_t ib_uverbs_rereg_mr(struct ib_uverbs_file *file, | ||
1006 | const char __user *buf, int in_len, | ||
1007 | int out_len) | ||
1008 | { | ||
1009 | struct ib_uverbs_rereg_mr cmd; | ||
1010 | struct ib_uverbs_rereg_mr_resp resp; | ||
1011 | struct ib_udata udata; | ||
1012 | struct ib_pd *pd = NULL; | ||
1013 | struct ib_mr *mr; | ||
1014 | struct ib_pd *old_pd; | ||
1015 | int ret; | ||
1016 | struct ib_uobject *uobj; | ||
1017 | |||
1018 | if (out_len < sizeof(resp)) | ||
1019 | return -ENOSPC; | ||
1020 | |||
1021 | if (copy_from_user(&cmd, buf, sizeof(cmd))) | ||
1022 | return -EFAULT; | ||
1023 | |||
1024 | INIT_UDATA(&udata, buf + sizeof(cmd), | ||
1025 | (unsigned long) cmd.response + sizeof(resp), | ||
1026 | in_len - sizeof(cmd), out_len - sizeof(resp)); | ||
1027 | |||
1028 | if (cmd.flags & ~IB_MR_REREG_SUPPORTED || !cmd.flags) | ||
1029 | return -EINVAL; | ||
1030 | |||
1031 | if ((cmd.flags & IB_MR_REREG_TRANS) && | ||
1032 | (!cmd.start || !cmd.hca_va || 0 >= cmd.length || | ||
1033 | (cmd.start & ~PAGE_MASK) != (cmd.hca_va & ~PAGE_MASK))) | ||
1034 | return -EINVAL; | ||
1035 | |||
1036 | uobj = idr_write_uobj(&ib_uverbs_mr_idr, cmd.mr_handle, | ||
1037 | file->ucontext); | ||
1038 | |||
1039 | if (!uobj) | ||
1040 | return -EINVAL; | ||
1041 | |||
1042 | mr = uobj->object; | ||
1043 | |||
1044 | if (cmd.flags & IB_MR_REREG_ACCESS) { | ||
1045 | ret = ib_check_mr_access(cmd.access_flags); | ||
1046 | if (ret) | ||
1047 | goto put_uobjs; | ||
1048 | } | ||
1049 | |||
1050 | if (cmd.flags & IB_MR_REREG_PD) { | ||
1051 | pd = idr_read_pd(cmd.pd_handle, file->ucontext); | ||
1052 | if (!pd) { | ||
1053 | ret = -EINVAL; | ||
1054 | goto put_uobjs; | ||
1055 | } | ||
1056 | } | ||
1057 | |||
1058 | if (atomic_read(&mr->usecnt)) { | ||
1059 | ret = -EBUSY; | ||
1060 | goto put_uobj_pd; | ||
1061 | } | ||
1062 | |||
1063 | old_pd = mr->pd; | ||
1064 | ret = mr->device->rereg_user_mr(mr, cmd.flags, cmd.start, | ||
1065 | cmd.length, cmd.hca_va, | ||
1066 | cmd.access_flags, pd, &udata); | ||
1067 | if (!ret) { | ||
1068 | if (cmd.flags & IB_MR_REREG_PD) { | ||
1069 | atomic_inc(&pd->usecnt); | ||
1070 | mr->pd = pd; | ||
1071 | atomic_dec(&old_pd->usecnt); | ||
1072 | } | ||
1073 | } else { | ||
1074 | goto put_uobj_pd; | ||
1075 | } | ||
1076 | |||
1077 | memset(&resp, 0, sizeof(resp)); | ||
1078 | resp.lkey = mr->lkey; | ||
1079 | resp.rkey = mr->rkey; | ||
1080 | |||
1081 | if (copy_to_user((void __user *)(unsigned long)cmd.response, | ||
1082 | &resp, sizeof(resp))) | ||
1083 | ret = -EFAULT; | ||
1084 | else | ||
1085 | ret = in_len; | ||
1086 | |||
1087 | put_uobj_pd: | ||
1088 | if (cmd.flags & IB_MR_REREG_PD) | ||
1089 | put_pd_read(pd); | ||
1090 | |||
1091 | put_uobjs: | ||
1092 | |||
1093 | put_uobj_write(mr->uobject); | ||
1094 | |||
1095 | return ret; | ||
1096 | } | ||
1097 | |||
1005 | ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file, | 1098 | ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file, |
1006 | const char __user *buf, int in_len, | 1099 | const char __user *buf, int in_len, |
1007 | int out_len) | 1100 | int out_len) |
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 08219fb3338b..c73b22a257fe 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -87,6 +87,7 @@ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file, | |||
87 | [IB_USER_VERBS_CMD_ALLOC_PD] = ib_uverbs_alloc_pd, | 87 | [IB_USER_VERBS_CMD_ALLOC_PD] = ib_uverbs_alloc_pd, |
88 | [IB_USER_VERBS_CMD_DEALLOC_PD] = ib_uverbs_dealloc_pd, | 88 | [IB_USER_VERBS_CMD_DEALLOC_PD] = ib_uverbs_dealloc_pd, |
89 | [IB_USER_VERBS_CMD_REG_MR] = ib_uverbs_reg_mr, | 89 | [IB_USER_VERBS_CMD_REG_MR] = ib_uverbs_reg_mr, |
90 | [IB_USER_VERBS_CMD_REREG_MR] = ib_uverbs_rereg_mr, | ||
90 | [IB_USER_VERBS_CMD_DEREG_MR] = ib_uverbs_dereg_mr, | 91 | [IB_USER_VERBS_CMD_DEREG_MR] = ib_uverbs_dereg_mr, |
91 | [IB_USER_VERBS_CMD_ALLOC_MW] = ib_uverbs_alloc_mw, | 92 | [IB_USER_VERBS_CMD_ALLOC_MW] = ib_uverbs_alloc_mw, |
92 | [IB_USER_VERBS_CMD_DEALLOC_MW] = ib_uverbs_dealloc_mw, | 93 | [IB_USER_VERBS_CMD_DEALLOC_MW] = ib_uverbs_dealloc_mw, |
diff --git a/drivers/infiniband/hw/amso1100/c2_cq.c b/drivers/infiniband/hw/amso1100/c2_cq.c index 49e0e8533f74..1b63185b4ad4 100644 --- a/drivers/infiniband/hw/amso1100/c2_cq.c +++ b/drivers/infiniband/hw/amso1100/c2_cq.c | |||
@@ -260,11 +260,14 @@ static void c2_free_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq) | |||
260 | mq->msg_pool.host, dma_unmap_addr(mq, mapping)); | 260 | mq->msg_pool.host, dma_unmap_addr(mq, mapping)); |
261 | } | 261 | } |
262 | 262 | ||
263 | static int c2_alloc_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq, int q_size, | 263 | static int c2_alloc_cq_buf(struct c2_dev *c2dev, struct c2_mq *mq, |
264 | int msg_size) | 264 | size_t q_size, size_t msg_size) |
265 | { | 265 | { |
266 | u8 *pool_start; | 266 | u8 *pool_start; |
267 | 267 | ||
268 | if (q_size > SIZE_MAX / msg_size) | ||
269 | return -EINVAL; | ||
270 | |||
268 | pool_start = dma_alloc_coherent(&c2dev->pcidev->dev, q_size * msg_size, | 271 | pool_start = dma_alloc_coherent(&c2dev->pcidev->dev, q_size * msg_size, |
269 | &mq->host_dma, GFP_KERNEL); | 272 | &mq->host_dma, GFP_KERNEL); |
270 | if (!pool_start) | 273 | if (!pool_start) |
diff --git a/drivers/infiniband/hw/cxgb4/ev.c b/drivers/infiniband/hw/cxgb4/ev.c index d61d0a18f784..a98426fed9ee 100644 --- a/drivers/infiniband/hw/cxgb4/ev.c +++ b/drivers/infiniband/hw/cxgb4/ev.c | |||
@@ -182,6 +182,7 @@ int c4iw_ev_handler(struct c4iw_dev *dev, u32 qid) | |||
182 | 182 | ||
183 | chp = get_chp(dev, qid); | 183 | chp = get_chp(dev, qid); |
184 | if (chp) { | 184 | if (chp) { |
185 | t4_clear_cq_armed(&chp->cq); | ||
185 | spin_lock_irqsave(&chp->comp_handler_lock, flag); | 186 | spin_lock_irqsave(&chp->comp_handler_lock, flag); |
186 | (*chp->ibcq.comp_handler)(&chp->ibcq, chp->ibcq.cq_context); | 187 | (*chp->ibcq.comp_handler)(&chp->ibcq, chp->ibcq.cq_context); |
187 | spin_unlock_irqrestore(&chp->comp_handler_lock, flag); | 188 | spin_unlock_irqrestore(&chp->comp_handler_lock, flag); |
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 086f62f5dc9e..60cfc11a66e4 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c | |||
@@ -1066,7 +1066,7 @@ static void __flush_qp(struct c4iw_qp *qhp, struct c4iw_cq *rchp, | |||
1066 | struct c4iw_cq *schp) | 1066 | struct c4iw_cq *schp) |
1067 | { | 1067 | { |
1068 | int count; | 1068 | int count; |
1069 | int flushed; | 1069 | int rq_flushed, sq_flushed; |
1070 | unsigned long flag; | 1070 | unsigned long flag; |
1071 | 1071 | ||
1072 | PDBG("%s qhp %p rchp %p schp %p\n", __func__, qhp, rchp, schp); | 1072 | PDBG("%s qhp %p rchp %p schp %p\n", __func__, qhp, rchp, schp); |
@@ -1084,27 +1084,40 @@ static void __flush_qp(struct c4iw_qp *qhp, struct c4iw_cq *rchp, | |||
1084 | 1084 | ||
1085 | c4iw_flush_hw_cq(rchp); | 1085 | c4iw_flush_hw_cq(rchp); |
1086 | c4iw_count_rcqes(&rchp->cq, &qhp->wq, &count); | 1086 | c4iw_count_rcqes(&rchp->cq, &qhp->wq, &count); |
1087 | flushed = c4iw_flush_rq(&qhp->wq, &rchp->cq, count); | 1087 | rq_flushed = c4iw_flush_rq(&qhp->wq, &rchp->cq, count); |
1088 | spin_unlock(&qhp->lock); | 1088 | spin_unlock(&qhp->lock); |
1089 | spin_unlock_irqrestore(&rchp->lock, flag); | 1089 | spin_unlock_irqrestore(&rchp->lock, flag); |
1090 | if (flushed) { | ||
1091 | spin_lock_irqsave(&rchp->comp_handler_lock, flag); | ||
1092 | (*rchp->ibcq.comp_handler)(&rchp->ibcq, rchp->ibcq.cq_context); | ||
1093 | spin_unlock_irqrestore(&rchp->comp_handler_lock, flag); | ||
1094 | } | ||
1095 | 1090 | ||
1096 | /* locking hierarchy: cq lock first, then qp lock. */ | 1091 | /* locking hierarchy: cq lock first, then qp lock. */ |
1097 | spin_lock_irqsave(&schp->lock, flag); | 1092 | spin_lock_irqsave(&schp->lock, flag); |
1098 | spin_lock(&qhp->lock); | 1093 | spin_lock(&qhp->lock); |
1099 | if (schp != rchp) | 1094 | if (schp != rchp) |
1100 | c4iw_flush_hw_cq(schp); | 1095 | c4iw_flush_hw_cq(schp); |
1101 | flushed = c4iw_flush_sq(qhp); | 1096 | sq_flushed = c4iw_flush_sq(qhp); |
1102 | spin_unlock(&qhp->lock); | 1097 | spin_unlock(&qhp->lock); |
1103 | spin_unlock_irqrestore(&schp->lock, flag); | 1098 | spin_unlock_irqrestore(&schp->lock, flag); |
1104 | if (flushed) { | 1099 | |
1105 | spin_lock_irqsave(&schp->comp_handler_lock, flag); | 1100 | if (schp == rchp) { |
1106 | (*schp->ibcq.comp_handler)(&schp->ibcq, schp->ibcq.cq_context); | 1101 | if (t4_clear_cq_armed(&rchp->cq) && |
1107 | spin_unlock_irqrestore(&schp->comp_handler_lock, flag); | 1102 | (rq_flushed || sq_flushed)) { |
1103 | spin_lock_irqsave(&rchp->comp_handler_lock, flag); | ||
1104 | (*rchp->ibcq.comp_handler)(&rchp->ibcq, | ||
1105 | rchp->ibcq.cq_context); | ||
1106 | spin_unlock_irqrestore(&rchp->comp_handler_lock, flag); | ||
1107 | } | ||
1108 | } else { | ||
1109 | if (t4_clear_cq_armed(&rchp->cq) && rq_flushed) { | ||
1110 | spin_lock_irqsave(&rchp->comp_handler_lock, flag); | ||
1111 | (*rchp->ibcq.comp_handler)(&rchp->ibcq, | ||
1112 | rchp->ibcq.cq_context); | ||
1113 | spin_unlock_irqrestore(&rchp->comp_handler_lock, flag); | ||
1114 | } | ||
1115 | if (t4_clear_cq_armed(&schp->cq) && sq_flushed) { | ||
1116 | spin_lock_irqsave(&schp->comp_handler_lock, flag); | ||
1117 | (*schp->ibcq.comp_handler)(&schp->ibcq, | ||
1118 | schp->ibcq.cq_context); | ||
1119 | spin_unlock_irqrestore(&schp->comp_handler_lock, flag); | ||
1120 | } | ||
1108 | } | 1121 | } |
1109 | } | 1122 | } |
1110 | 1123 | ||
diff --git a/drivers/infiniband/hw/cxgb4/t4.h b/drivers/infiniband/hw/cxgb4/t4.h index 68b0a6bf4eb0..d8d7fa3e446d 100644 --- a/drivers/infiniband/hw/cxgb4/t4.h +++ b/drivers/infiniband/hw/cxgb4/t4.h | |||
@@ -531,6 +531,10 @@ static inline int t4_wq_db_enabled(struct t4_wq *wq) | |||
531 | return !wq->rq.queue[wq->rq.size].status.db_off; | 531 | return !wq->rq.queue[wq->rq.size].status.db_off; |
532 | } | 532 | } |
533 | 533 | ||
534 | enum t4_cq_flags { | ||
535 | CQ_ARMED = 1, | ||
536 | }; | ||
537 | |||
534 | struct t4_cq { | 538 | struct t4_cq { |
535 | struct t4_cqe *queue; | 539 | struct t4_cqe *queue; |
536 | dma_addr_t dma_addr; | 540 | dma_addr_t dma_addr; |
@@ -551,12 +555,19 @@ struct t4_cq { | |||
551 | u16 cidx_inc; | 555 | u16 cidx_inc; |
552 | u8 gen; | 556 | u8 gen; |
553 | u8 error; | 557 | u8 error; |
558 | unsigned long flags; | ||
554 | }; | 559 | }; |
555 | 560 | ||
561 | static inline int t4_clear_cq_armed(struct t4_cq *cq) | ||
562 | { | ||
563 | return test_and_clear_bit(CQ_ARMED, &cq->flags); | ||
564 | } | ||
565 | |||
556 | static inline int t4_arm_cq(struct t4_cq *cq, int se) | 566 | static inline int t4_arm_cq(struct t4_cq *cq, int se) |
557 | { | 567 | { |
558 | u32 val; | 568 | u32 val; |
559 | 569 | ||
570 | set_bit(CQ_ARMED, &cq->flags); | ||
560 | while (cq->cidx_inc > CIDXINC_MASK) { | 571 | while (cq->cidx_inc > CIDXINC_MASK) { |
561 | val = SEINTARM(0) | CIDXINC(CIDXINC_MASK) | TIMERREG(7) | | 572 | val = SEINTARM(0) | CIDXINC(CIDXINC_MASK) | TIMERREG(7) | |
562 | INGRESSQID(cq->cqid); | 573 | INGRESSQID(cq->cqid); |
diff --git a/drivers/infiniband/hw/ipath/ipath_mad.c b/drivers/infiniband/hw/ipath/ipath_mad.c index 43f2d0424d4f..e890e5ba0e01 100644 --- a/drivers/infiniband/hw/ipath/ipath_mad.c +++ b/drivers/infiniband/hw/ipath/ipath_mad.c | |||
@@ -726,7 +726,7 @@ bail: | |||
726 | * @dd: the infinipath device | 726 | * @dd: the infinipath device |
727 | * @pkeys: the PKEY table | 727 | * @pkeys: the PKEY table |
728 | */ | 728 | */ |
729 | static int set_pkeys(struct ipath_devdata *dd, u16 *pkeys) | 729 | static int set_pkeys(struct ipath_devdata *dd, u16 *pkeys, u8 port) |
730 | { | 730 | { |
731 | struct ipath_portdata *pd; | 731 | struct ipath_portdata *pd; |
732 | int i; | 732 | int i; |
@@ -759,6 +759,7 @@ static int set_pkeys(struct ipath_devdata *dd, u16 *pkeys) | |||
759 | } | 759 | } |
760 | if (changed) { | 760 | if (changed) { |
761 | u64 pkey; | 761 | u64 pkey; |
762 | struct ib_event event; | ||
762 | 763 | ||
763 | pkey = (u64) dd->ipath_pkeys[0] | | 764 | pkey = (u64) dd->ipath_pkeys[0] | |
764 | ((u64) dd->ipath_pkeys[1] << 16) | | 765 | ((u64) dd->ipath_pkeys[1] << 16) | |
@@ -768,12 +769,17 @@ static int set_pkeys(struct ipath_devdata *dd, u16 *pkeys) | |||
768 | (unsigned long long) pkey); | 769 | (unsigned long long) pkey); |
769 | ipath_write_kreg(dd, dd->ipath_kregs->kr_partitionkey, | 770 | ipath_write_kreg(dd, dd->ipath_kregs->kr_partitionkey, |
770 | pkey); | 771 | pkey); |
772 | |||
773 | event.event = IB_EVENT_PKEY_CHANGE; | ||
774 | event.device = &dd->verbs_dev->ibdev; | ||
775 | event.element.port_num = port; | ||
776 | ib_dispatch_event(&event); | ||
771 | } | 777 | } |
772 | return 0; | 778 | return 0; |
773 | } | 779 | } |
774 | 780 | ||
775 | static int recv_subn_set_pkeytable(struct ib_smp *smp, | 781 | static int recv_subn_set_pkeytable(struct ib_smp *smp, |
776 | struct ib_device *ibdev) | 782 | struct ib_device *ibdev, u8 port) |
777 | { | 783 | { |
778 | u32 startpx = 32 * (be32_to_cpu(smp->attr_mod) & 0xffff); | 784 | u32 startpx = 32 * (be32_to_cpu(smp->attr_mod) & 0xffff); |
779 | __be16 *p = (__be16 *) smp->data; | 785 | __be16 *p = (__be16 *) smp->data; |
@@ -784,7 +790,7 @@ static int recv_subn_set_pkeytable(struct ib_smp *smp, | |||
784 | for (i = 0; i < n; i++) | 790 | for (i = 0; i < n; i++) |
785 | q[i] = be16_to_cpu(p[i]); | 791 | q[i] = be16_to_cpu(p[i]); |
786 | 792 | ||
787 | if (startpx != 0 || set_pkeys(dev->dd, q) != 0) | 793 | if (startpx != 0 || set_pkeys(dev->dd, q, port) != 0) |
788 | smp->status |= IB_SMP_INVALID_FIELD; | 794 | smp->status |= IB_SMP_INVALID_FIELD; |
789 | 795 | ||
790 | return recv_subn_get_pkeytable(smp, ibdev); | 796 | return recv_subn_get_pkeytable(smp, ibdev); |
@@ -1342,7 +1348,7 @@ static int process_subn(struct ib_device *ibdev, int mad_flags, | |||
1342 | ret = recv_subn_set_portinfo(smp, ibdev, port_num); | 1348 | ret = recv_subn_set_portinfo(smp, ibdev, port_num); |
1343 | goto bail; | 1349 | goto bail; |
1344 | case IB_SMP_ATTR_PKEY_TABLE: | 1350 | case IB_SMP_ATTR_PKEY_TABLE: |
1345 | ret = recv_subn_set_pkeytable(smp, ibdev); | 1351 | ret = recv_subn_set_pkeytable(smp, ibdev, port_num); |
1346 | goto bail; | 1352 | goto bail; |
1347 | case IB_SMP_ATTR_SM_INFO: | 1353 | case IB_SMP_ATTR_SM_INFO: |
1348 | if (dev->port_cap_flags & IB_PORT_SM_DISABLED) { | 1354 | if (dev->port_cap_flags & IB_PORT_SM_DISABLED) { |
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index 287ad0564acd..82a7dd87089b 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c | |||
@@ -891,7 +891,7 @@ int mlx4_ib_mad_init(struct mlx4_ib_dev *dev) | |||
891 | agent = ib_register_mad_agent(&dev->ib_dev, p + 1, | 891 | agent = ib_register_mad_agent(&dev->ib_dev, p + 1, |
892 | q ? IB_QPT_GSI : IB_QPT_SMI, | 892 | q ? IB_QPT_GSI : IB_QPT_SMI, |
893 | NULL, 0, send_handler, | 893 | NULL, 0, send_handler, |
894 | NULL, NULL); | 894 | NULL, NULL, 0); |
895 | if (IS_ERR(agent)) { | 895 | if (IS_ERR(agent)) { |
896 | ret = PTR_ERR(agent); | 896 | ret = PTR_ERR(agent); |
897 | goto err; | 897 | goto err; |
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index 0f7027e7db13..e1e558a3d692 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
@@ -910,8 +910,7 @@ static int __mlx4_ib_default_rules_match(struct ib_qp *qp, | |||
910 | const struct default_rules *pdefault_rules = default_table; | 910 | const struct default_rules *pdefault_rules = default_table; |
911 | u8 link_layer = rdma_port_get_link_layer(qp->device, flow_attr->port); | 911 | u8 link_layer = rdma_port_get_link_layer(qp->device, flow_attr->port); |
912 | 912 | ||
913 | for (i = 0; i < sizeof(default_table)/sizeof(default_table[0]); i++, | 913 | for (i = 0; i < ARRAY_SIZE(default_table); i++, pdefault_rules++) { |
914 | pdefault_rules++) { | ||
915 | __u32 field_types[IB_FLOW_SPEC_SUPPORT_LAYERS]; | 914 | __u32 field_types[IB_FLOW_SPEC_SUPPORT_LAYERS]; |
916 | memset(&field_types, 0, sizeof(field_types)); | 915 | memset(&field_types, 0, sizeof(field_types)); |
917 | 916 | ||
@@ -965,8 +964,7 @@ static int __mlx4_ib_create_default_rules( | |||
965 | int size = 0; | 964 | int size = 0; |
966 | int i; | 965 | int i; |
967 | 966 | ||
968 | for (i = 0; i < sizeof(pdefault_rules->rules_create_list)/ | 967 | for (i = 0; i < ARRAY_SIZE(pdefault_rules->rules_create_list); i++) { |
969 | sizeof(pdefault_rules->rules_create_list[0]); i++) { | ||
970 | int ret; | 968 | int ret; |
971 | union ib_flow_spec ib_spec; | 969 | union ib_flow_spec ib_spec; |
972 | switch (pdefault_rules->rules_create_list[i]) { | 970 | switch (pdefault_rules->rules_create_list[i]) { |
@@ -2007,6 +2005,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) | |||
2007 | (1ull << IB_USER_VERBS_CMD_ALLOC_PD) | | 2005 | (1ull << IB_USER_VERBS_CMD_ALLOC_PD) | |
2008 | (1ull << IB_USER_VERBS_CMD_DEALLOC_PD) | | 2006 | (1ull << IB_USER_VERBS_CMD_DEALLOC_PD) | |
2009 | (1ull << IB_USER_VERBS_CMD_REG_MR) | | 2007 | (1ull << IB_USER_VERBS_CMD_REG_MR) | |
2008 | (1ull << IB_USER_VERBS_CMD_REREG_MR) | | ||
2010 | (1ull << IB_USER_VERBS_CMD_DEREG_MR) | | 2009 | (1ull << IB_USER_VERBS_CMD_DEREG_MR) | |
2011 | (1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) | | 2010 | (1ull << IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) | |
2012 | (1ull << IB_USER_VERBS_CMD_CREATE_CQ) | | 2011 | (1ull << IB_USER_VERBS_CMD_CREATE_CQ) | |
@@ -2059,6 +2058,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev) | |||
2059 | ibdev->ib_dev.req_notify_cq = mlx4_ib_arm_cq; | 2058 | ibdev->ib_dev.req_notify_cq = mlx4_ib_arm_cq; |
2060 | ibdev->ib_dev.get_dma_mr = mlx4_ib_get_dma_mr; | 2059 | ibdev->ib_dev.get_dma_mr = mlx4_ib_get_dma_mr; |
2061 | ibdev->ib_dev.reg_user_mr = mlx4_ib_reg_user_mr; | 2060 | ibdev->ib_dev.reg_user_mr = mlx4_ib_reg_user_mr; |
2061 | ibdev->ib_dev.rereg_user_mr = mlx4_ib_rereg_user_mr; | ||
2062 | ibdev->ib_dev.dereg_mr = mlx4_ib_dereg_mr; | 2062 | ibdev->ib_dev.dereg_mr = mlx4_ib_dereg_mr; |
2063 | ibdev->ib_dev.alloc_fast_reg_mr = mlx4_ib_alloc_fast_reg_mr; | 2063 | ibdev->ib_dev.alloc_fast_reg_mr = mlx4_ib_alloc_fast_reg_mr; |
2064 | ibdev->ib_dev.alloc_fast_reg_page_list = mlx4_ib_alloc_fast_reg_page_list; | 2064 | ibdev->ib_dev.alloc_fast_reg_page_list = mlx4_ib_alloc_fast_reg_page_list; |
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h index 369da3ca5d64..e8cad3926bfc 100644 --- a/drivers/infiniband/hw/mlx4/mlx4_ib.h +++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h | |||
@@ -788,5 +788,9 @@ int mlx4_ib_steer_qp_alloc(struct mlx4_ib_dev *dev, int count, int *qpn); | |||
788 | void mlx4_ib_steer_qp_free(struct mlx4_ib_dev *dev, u32 qpn, int count); | 788 | void mlx4_ib_steer_qp_free(struct mlx4_ib_dev *dev, u32 qpn, int count); |
789 | int mlx4_ib_steer_qp_reg(struct mlx4_ib_dev *mdev, struct mlx4_ib_qp *mqp, | 789 | int mlx4_ib_steer_qp_reg(struct mlx4_ib_dev *mdev, struct mlx4_ib_qp *mqp, |
790 | int is_attach); | 790 | int is_attach); |
791 | int mlx4_ib_rereg_user_mr(struct ib_mr *mr, int flags, | ||
792 | u64 start, u64 length, u64 virt_addr, | ||
793 | int mr_access_flags, struct ib_pd *pd, | ||
794 | struct ib_udata *udata); | ||
791 | 795 | ||
792 | #endif /* MLX4_IB_H */ | 796 | #endif /* MLX4_IB_H */ |
diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c index cb2a8727f3fb..9b0e80e59b08 100644 --- a/drivers/infiniband/hw/mlx4/mr.c +++ b/drivers/infiniband/hw/mlx4/mr.c | |||
@@ -144,8 +144,10 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, | |||
144 | if (!mr) | 144 | if (!mr) |
145 | return ERR_PTR(-ENOMEM); | 145 | return ERR_PTR(-ENOMEM); |
146 | 146 | ||
147 | /* Force registering the memory as writable. */ | ||
148 | /* Used for memory re-registeration. HCA protects the access */ | ||
147 | mr->umem = ib_umem_get(pd->uobject->context, start, length, | 149 | mr->umem = ib_umem_get(pd->uobject->context, start, length, |
148 | access_flags, 0); | 150 | access_flags | IB_ACCESS_LOCAL_WRITE, 0); |
149 | if (IS_ERR(mr->umem)) { | 151 | if (IS_ERR(mr->umem)) { |
150 | err = PTR_ERR(mr->umem); | 152 | err = PTR_ERR(mr->umem); |
151 | goto err_free; | 153 | goto err_free; |
@@ -183,6 +185,90 @@ err_free: | |||
183 | return ERR_PTR(err); | 185 | return ERR_PTR(err); |
184 | } | 186 | } |
185 | 187 | ||
188 | int mlx4_ib_rereg_user_mr(struct ib_mr *mr, int flags, | ||
189 | u64 start, u64 length, u64 virt_addr, | ||
190 | int mr_access_flags, struct ib_pd *pd, | ||
191 | struct ib_udata *udata) | ||
192 | { | ||
193 | struct mlx4_ib_dev *dev = to_mdev(mr->device); | ||
194 | struct mlx4_ib_mr *mmr = to_mmr(mr); | ||
195 | struct mlx4_mpt_entry *mpt_entry; | ||
196 | struct mlx4_mpt_entry **pmpt_entry = &mpt_entry; | ||
197 | int err; | ||
198 | |||
199 | /* Since we synchronize this call and mlx4_ib_dereg_mr via uverbs, | ||
200 | * we assume that the calls can't run concurrently. Otherwise, a | ||
201 | * race exists. | ||
202 | */ | ||
203 | err = mlx4_mr_hw_get_mpt(dev->dev, &mmr->mmr, &pmpt_entry); | ||
204 | |||
205 | if (err) | ||
206 | return err; | ||
207 | |||
208 | if (flags & IB_MR_REREG_PD) { | ||
209 | err = mlx4_mr_hw_change_pd(dev->dev, *pmpt_entry, | ||
210 | to_mpd(pd)->pdn); | ||
211 | |||
212 | if (err) | ||
213 | goto release_mpt_entry; | ||
214 | } | ||
215 | |||
216 | if (flags & IB_MR_REREG_ACCESS) { | ||
217 | err = mlx4_mr_hw_change_access(dev->dev, *pmpt_entry, | ||
218 | convert_access(mr_access_flags)); | ||
219 | |||
220 | if (err) | ||
221 | goto release_mpt_entry; | ||
222 | } | ||
223 | |||
224 | if (flags & IB_MR_REREG_TRANS) { | ||
225 | int shift; | ||
226 | int err; | ||
227 | int n; | ||
228 | |||
229 | mlx4_mr_rereg_mem_cleanup(dev->dev, &mmr->mmr); | ||
230 | ib_umem_release(mmr->umem); | ||
231 | mmr->umem = ib_umem_get(mr->uobject->context, start, length, | ||
232 | mr_access_flags | | ||
233 | IB_ACCESS_LOCAL_WRITE, | ||
234 | 0); | ||
235 | if (IS_ERR(mmr->umem)) { | ||
236 | err = PTR_ERR(mmr->umem); | ||
237 | mmr->umem = NULL; | ||
238 | goto release_mpt_entry; | ||
239 | } | ||
240 | n = ib_umem_page_count(mmr->umem); | ||
241 | shift = ilog2(mmr->umem->page_size); | ||
242 | |||
243 | mmr->mmr.iova = virt_addr; | ||
244 | mmr->mmr.size = length; | ||
245 | err = mlx4_mr_rereg_mem_write(dev->dev, &mmr->mmr, | ||
246 | virt_addr, length, n, shift, | ||
247 | *pmpt_entry); | ||
248 | if (err) { | ||
249 | ib_umem_release(mmr->umem); | ||
250 | goto release_mpt_entry; | ||
251 | } | ||
252 | |||
253 | err = mlx4_ib_umem_write_mtt(dev, &mmr->mmr.mtt, mmr->umem); | ||
254 | if (err) { | ||
255 | mlx4_mr_rereg_mem_cleanup(dev->dev, &mmr->mmr); | ||
256 | ib_umem_release(mmr->umem); | ||
257 | goto release_mpt_entry; | ||
258 | } | ||
259 | } | ||
260 | |||
261 | /* If we couldn't transfer the MR to the HCA, just remember to | ||
262 | * return a failure. But dereg_mr will free the resources. | ||
263 | */ | ||
264 | err = mlx4_mr_hw_write_mpt(dev->dev, &mmr->mmr, pmpt_entry); | ||
265 | |||
266 | release_mpt_entry: | ||
267 | mlx4_mr_hw_put_mpt(dev->dev, pmpt_entry); | ||
268 | |||
269 | return err; | ||
270 | } | ||
271 | |||
186 | int mlx4_ib_dereg_mr(struct ib_mr *ibmr) | 272 | int mlx4_ib_dereg_mr(struct ib_mr *ibmr) |
187 | { | 273 | { |
188 | struct mlx4_ib_mr *mr = to_mmr(ibmr); | 274 | struct mlx4_ib_mr *mr = to_mmr(ibmr); |
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index bbbcf389272c..416cb7244224 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c | |||
@@ -2501,7 +2501,7 @@ int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | |||
2501 | spin_lock_irqsave(&qp->sq.lock, flags); | 2501 | spin_lock_irqsave(&qp->sq.lock, flags); |
2502 | 2502 | ||
2503 | for (nreq = 0; wr; nreq++, wr = wr->next) { | 2503 | for (nreq = 0; wr; nreq++, wr = wr->next) { |
2504 | if (unlikely(wr->opcode >= sizeof(mlx5_ib_opcode) / sizeof(mlx5_ib_opcode[0]))) { | 2504 | if (unlikely(wr->opcode >= ARRAY_SIZE(mlx5_ib_opcode))) { |
2505 | mlx5_ib_warn(dev, "\n"); | 2505 | mlx5_ib_warn(dev, "\n"); |
2506 | err = -EINVAL; | 2506 | err = -EINVAL; |
2507 | *bad_wr = wr; | 2507 | *bad_wr = wr; |
diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c index b6f7f457fc55..8881fa376e06 100644 --- a/drivers/infiniband/hw/mthca/mthca_mad.c +++ b/drivers/infiniband/hw/mthca/mthca_mad.c | |||
@@ -294,7 +294,7 @@ int mthca_create_agents(struct mthca_dev *dev) | |||
294 | agent = ib_register_mad_agent(&dev->ib_dev, p + 1, | 294 | agent = ib_register_mad_agent(&dev->ib_dev, p + 1, |
295 | q ? IB_QPT_GSI : IB_QPT_SMI, | 295 | q ? IB_QPT_GSI : IB_QPT_SMI, |
296 | NULL, 0, send_handler, | 296 | NULL, 0, send_handler, |
297 | NULL, NULL); | 297 | NULL, NULL, 0); |
298 | if (IS_ERR(agent)) { | 298 | if (IS_ERR(agent)) { |
299 | ret = PTR_ERR(agent); | 299 | ret = PTR_ERR(agent); |
300 | goto err; | 300 | goto err; |
diff --git a/drivers/infiniband/hw/qib/qib_mad.c b/drivers/infiniband/hw/qib/qib_mad.c index 22c720e5740d..636be117b578 100644 --- a/drivers/infiniband/hw/qib/qib_mad.c +++ b/drivers/infiniband/hw/qib/qib_mad.c | |||
@@ -2476,7 +2476,7 @@ int qib_create_agents(struct qib_ibdev *dev) | |||
2476 | ibp = &dd->pport[p].ibport_data; | 2476 | ibp = &dd->pport[p].ibport_data; |
2477 | agent = ib_register_mad_agent(&dev->ibdev, p + 1, IB_QPT_SMI, | 2477 | agent = ib_register_mad_agent(&dev->ibdev, p + 1, IB_QPT_SMI, |
2478 | NULL, 0, send_handler, | 2478 | NULL, 0, send_handler, |
2479 | NULL, NULL); | 2479 | NULL, NULL, 0); |
2480 | if (IS_ERR(agent)) { | 2480 | if (IS_ERR(agent)) { |
2481 | ret = PTR_ERR(agent); | 2481 | ret = PTR_ERR(agent); |
2482 | goto err; | 2482 | goto err; |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index c639f90cfda4..3edce617c31b 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
@@ -86,7 +86,6 @@ enum { | |||
86 | IPOIB_FLAG_INITIALIZED = 1, | 86 | IPOIB_FLAG_INITIALIZED = 1, |
87 | IPOIB_FLAG_ADMIN_UP = 2, | 87 | IPOIB_FLAG_ADMIN_UP = 2, |
88 | IPOIB_PKEY_ASSIGNED = 3, | 88 | IPOIB_PKEY_ASSIGNED = 3, |
89 | IPOIB_PKEY_STOP = 4, | ||
90 | IPOIB_FLAG_SUBINTERFACE = 5, | 89 | IPOIB_FLAG_SUBINTERFACE = 5, |
91 | IPOIB_MCAST_RUN = 6, | 90 | IPOIB_MCAST_RUN = 6, |
92 | IPOIB_STOP_REAPER = 7, | 91 | IPOIB_STOP_REAPER = 7, |
@@ -312,7 +311,6 @@ struct ipoib_dev_priv { | |||
312 | struct list_head multicast_list; | 311 | struct list_head multicast_list; |
313 | struct rb_root multicast_tree; | 312 | struct rb_root multicast_tree; |
314 | 313 | ||
315 | struct delayed_work pkey_poll_task; | ||
316 | struct delayed_work mcast_task; | 314 | struct delayed_work mcast_task; |
317 | struct work_struct carrier_on_task; | 315 | struct work_struct carrier_on_task; |
318 | struct work_struct flush_light; | 316 | struct work_struct flush_light; |
@@ -473,10 +471,11 @@ void ipoib_ib_dev_flush_heavy(struct work_struct *work); | |||
473 | void ipoib_pkey_event(struct work_struct *work); | 471 | void ipoib_pkey_event(struct work_struct *work); |
474 | void ipoib_ib_dev_cleanup(struct net_device *dev); | 472 | void ipoib_ib_dev_cleanup(struct net_device *dev); |
475 | 473 | ||
476 | int ipoib_ib_dev_open(struct net_device *dev); | 474 | int ipoib_ib_dev_open(struct net_device *dev, int flush); |
477 | int ipoib_ib_dev_up(struct net_device *dev); | 475 | int ipoib_ib_dev_up(struct net_device *dev); |
478 | int ipoib_ib_dev_down(struct net_device *dev, int flush); | 476 | int ipoib_ib_dev_down(struct net_device *dev, int flush); |
479 | int ipoib_ib_dev_stop(struct net_device *dev, int flush); | 477 | int ipoib_ib_dev_stop(struct net_device *dev, int flush); |
478 | void ipoib_pkey_dev_check_presence(struct net_device *dev); | ||
480 | 479 | ||
481 | int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port); | 480 | int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port); |
482 | void ipoib_dev_cleanup(struct net_device *dev); | 481 | void ipoib_dev_cleanup(struct net_device *dev); |
@@ -532,8 +531,7 @@ int ipoib_set_mode(struct net_device *dev, const char *buf); | |||
532 | 531 | ||
533 | void ipoib_setup(struct net_device *dev); | 532 | void ipoib_setup(struct net_device *dev); |
534 | 533 | ||
535 | void ipoib_pkey_poll(struct work_struct *work); | 534 | void ipoib_pkey_open(struct ipoib_dev_priv *priv); |
536 | int ipoib_pkey_dev_delay_open(struct net_device *dev); | ||
537 | void ipoib_drain_cq(struct net_device *dev); | 535 | void ipoib_drain_cq(struct net_device *dev); |
538 | 536 | ||
539 | void ipoib_set_ethtool_ops(struct net_device *dev); | 537 | void ipoib_set_ethtool_ops(struct net_device *dev); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c index 50061854616e..6bd5740e2691 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c | |||
@@ -281,10 +281,8 @@ void ipoib_delete_debug_files(struct net_device *dev) | |||
281 | { | 281 | { |
282 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 282 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
283 | 283 | ||
284 | if (priv->mcg_dentry) | 284 | debugfs_remove(priv->mcg_dentry); |
285 | debugfs_remove(priv->mcg_dentry); | 285 | debugfs_remove(priv->path_dentry); |
286 | if (priv->path_dentry) | ||
287 | debugfs_remove(priv->path_dentry); | ||
288 | } | 286 | } |
289 | 287 | ||
290 | int ipoib_register_debugfs(void) | 288 | int ipoib_register_debugfs(void) |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 6a7003ddb0be..72626c348174 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
@@ -664,17 +664,18 @@ static void ipoib_ib_tx_timer_func(unsigned long ctx) | |||
664 | drain_tx_cq((struct net_device *)ctx); | 664 | drain_tx_cq((struct net_device *)ctx); |
665 | } | 665 | } |
666 | 666 | ||
667 | int ipoib_ib_dev_open(struct net_device *dev) | 667 | int ipoib_ib_dev_open(struct net_device *dev, int flush) |
668 | { | 668 | { |
669 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 669 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
670 | int ret; | 670 | int ret; |
671 | 671 | ||
672 | if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &priv->pkey_index)) { | 672 | ipoib_pkey_dev_check_presence(dev); |
673 | ipoib_warn(priv, "P_Key 0x%04x not found\n", priv->pkey); | 673 | |
674 | clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); | 674 | if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) { |
675 | ipoib_warn(priv, "P_Key 0x%04x is %s\n", priv->pkey, | ||
676 | (!(priv->pkey & 0x7fff) ? "Invalid" : "not found")); | ||
675 | return -1; | 677 | return -1; |
676 | } | 678 | } |
677 | set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); | ||
678 | 679 | ||
679 | ret = ipoib_init_qp(dev); | 680 | ret = ipoib_init_qp(dev); |
680 | if (ret) { | 681 | if (ret) { |
@@ -705,16 +706,17 @@ int ipoib_ib_dev_open(struct net_device *dev) | |||
705 | dev_stop: | 706 | dev_stop: |
706 | if (!test_and_set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) | 707 | if (!test_and_set_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) |
707 | napi_enable(&priv->napi); | 708 | napi_enable(&priv->napi); |
708 | ipoib_ib_dev_stop(dev, 1); | 709 | ipoib_ib_dev_stop(dev, flush); |
709 | return -1; | 710 | return -1; |
710 | } | 711 | } |
711 | 712 | ||
712 | static void ipoib_pkey_dev_check_presence(struct net_device *dev) | 713 | void ipoib_pkey_dev_check_presence(struct net_device *dev) |
713 | { | 714 | { |
714 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 715 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
715 | u16 pkey_index = 0; | ||
716 | 716 | ||
717 | if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &pkey_index)) | 717 | if (!(priv->pkey & 0x7fff) || |
718 | ib_find_pkey(priv->ca, priv->port, priv->pkey, | ||
719 | &priv->pkey_index)) | ||
718 | clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); | 720 | clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); |
719 | else | 721 | else |
720 | set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); | 722 | set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); |
@@ -745,14 +747,6 @@ int ipoib_ib_dev_down(struct net_device *dev, int flush) | |||
745 | clear_bit(IPOIB_FLAG_OPER_UP, &priv->flags); | 747 | clear_bit(IPOIB_FLAG_OPER_UP, &priv->flags); |
746 | netif_carrier_off(dev); | 748 | netif_carrier_off(dev); |
747 | 749 | ||
748 | /* Shutdown the P_Key thread if still active */ | ||
749 | if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) { | ||
750 | mutex_lock(&pkey_mutex); | ||
751 | set_bit(IPOIB_PKEY_STOP, &priv->flags); | ||
752 | cancel_delayed_work_sync(&priv->pkey_poll_task); | ||
753 | mutex_unlock(&pkey_mutex); | ||
754 | } | ||
755 | |||
756 | ipoib_mcast_stop_thread(dev, flush); | 750 | ipoib_mcast_stop_thread(dev, flush); |
757 | ipoib_mcast_dev_flush(dev); | 751 | ipoib_mcast_dev_flush(dev); |
758 | 752 | ||
@@ -924,7 +918,7 @@ int ipoib_ib_dev_init(struct net_device *dev, struct ib_device *ca, int port) | |||
924 | (unsigned long) dev); | 918 | (unsigned long) dev); |
925 | 919 | ||
926 | if (dev->flags & IFF_UP) { | 920 | if (dev->flags & IFF_UP) { |
927 | if (ipoib_ib_dev_open(dev)) { | 921 | if (ipoib_ib_dev_open(dev, 1)) { |
928 | ipoib_transport_dev_cleanup(dev); | 922 | ipoib_transport_dev_cleanup(dev); |
929 | return -ENODEV; | 923 | return -ENODEV; |
930 | } | 924 | } |
@@ -966,13 +960,27 @@ static inline int update_parent_pkey(struct ipoib_dev_priv *priv) | |||
966 | 960 | ||
967 | return 1; | 961 | return 1; |
968 | } | 962 | } |
963 | /* | ||
964 | * returns 0 if pkey value was found in a different slot. | ||
965 | */ | ||
966 | static inline int update_child_pkey(struct ipoib_dev_priv *priv) | ||
967 | { | ||
968 | u16 old_index = priv->pkey_index; | ||
969 | |||
970 | priv->pkey_index = 0; | ||
971 | ipoib_pkey_dev_check_presence(priv->dev); | ||
972 | |||
973 | if (test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags) && | ||
974 | (old_index == priv->pkey_index)) | ||
975 | return 1; | ||
976 | return 0; | ||
977 | } | ||
969 | 978 | ||
970 | static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, | 979 | static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, |
971 | enum ipoib_flush_level level) | 980 | enum ipoib_flush_level level) |
972 | { | 981 | { |
973 | struct ipoib_dev_priv *cpriv; | 982 | struct ipoib_dev_priv *cpriv; |
974 | struct net_device *dev = priv->dev; | 983 | struct net_device *dev = priv->dev; |
975 | u16 new_index; | ||
976 | int result; | 984 | int result; |
977 | 985 | ||
978 | down_read(&priv->vlan_rwsem); | 986 | down_read(&priv->vlan_rwsem); |
@@ -986,16 +994,20 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, | |||
986 | 994 | ||
987 | up_read(&priv->vlan_rwsem); | 995 | up_read(&priv->vlan_rwsem); |
988 | 996 | ||
989 | if (!test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) { | 997 | if (!test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags) && |
990 | /* for non-child devices must check/update the pkey value here */ | 998 | level != IPOIB_FLUSH_HEAVY) { |
991 | if (level == IPOIB_FLUSH_HEAVY && | ||
992 | !test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) | ||
993 | update_parent_pkey(priv); | ||
994 | ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_INITIALIZED not set.\n"); | 999 | ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_INITIALIZED not set.\n"); |
995 | return; | 1000 | return; |
996 | } | 1001 | } |
997 | 1002 | ||
998 | if (!test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) { | 1003 | if (!test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) { |
1004 | /* interface is down. update pkey and leave. */ | ||
1005 | if (level == IPOIB_FLUSH_HEAVY) { | ||
1006 | if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) | ||
1007 | update_parent_pkey(priv); | ||
1008 | else | ||
1009 | update_child_pkey(priv); | ||
1010 | } | ||
999 | ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_ADMIN_UP not set.\n"); | 1011 | ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_ADMIN_UP not set.\n"); |
1000 | return; | 1012 | return; |
1001 | } | 1013 | } |
@@ -1005,20 +1017,13 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, | |||
1005 | * (parent) devices should always takes what present in pkey index 0 | 1017 | * (parent) devices should always takes what present in pkey index 0 |
1006 | */ | 1018 | */ |
1007 | if (test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) { | 1019 | if (test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) { |
1008 | if (ib_find_pkey(priv->ca, priv->port, priv->pkey, &new_index)) { | 1020 | result = update_child_pkey(priv); |
1009 | clear_bit(IPOIB_PKEY_ASSIGNED, &priv->flags); | 1021 | if (result) { |
1010 | ipoib_ib_dev_down(dev, 0); | 1022 | /* restart QP only if P_Key index is changed */ |
1011 | ipoib_ib_dev_stop(dev, 0); | ||
1012 | if (ipoib_pkey_dev_delay_open(dev)) | ||
1013 | return; | ||
1014 | } | ||
1015 | /* restart QP only if P_Key index is changed */ | ||
1016 | if (test_and_set_bit(IPOIB_PKEY_ASSIGNED, &priv->flags) && | ||
1017 | new_index == priv->pkey_index) { | ||
1018 | ipoib_dbg(priv, "Not flushing - P_Key index not changed.\n"); | 1023 | ipoib_dbg(priv, "Not flushing - P_Key index not changed.\n"); |
1019 | return; | 1024 | return; |
1020 | } | 1025 | } |
1021 | priv->pkey_index = new_index; | 1026 | |
1022 | } else { | 1027 | } else { |
1023 | result = update_parent_pkey(priv); | 1028 | result = update_parent_pkey(priv); |
1024 | /* restart QP only if P_Key value changed */ | 1029 | /* restart QP only if P_Key value changed */ |
@@ -1038,8 +1043,12 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv, | |||
1038 | ipoib_ib_dev_down(dev, 0); | 1043 | ipoib_ib_dev_down(dev, 0); |
1039 | 1044 | ||
1040 | if (level == IPOIB_FLUSH_HEAVY) { | 1045 | if (level == IPOIB_FLUSH_HEAVY) { |
1041 | ipoib_ib_dev_stop(dev, 0); | 1046 | if (test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags)) |
1042 | ipoib_ib_dev_open(dev); | 1047 | ipoib_ib_dev_stop(dev, 0); |
1048 | if (ipoib_ib_dev_open(dev, 0) != 0) | ||
1049 | return; | ||
1050 | if (netif_queue_stopped(dev)) | ||
1051 | netif_start_queue(dev); | ||
1043 | } | 1052 | } |
1044 | 1053 | ||
1045 | /* | 1054 | /* |
@@ -1094,54 +1103,4 @@ void ipoib_ib_dev_cleanup(struct net_device *dev) | |||
1094 | ipoib_transport_dev_cleanup(dev); | 1103 | ipoib_transport_dev_cleanup(dev); |
1095 | } | 1104 | } |
1096 | 1105 | ||
1097 | /* | ||
1098 | * Delayed P_Key Assigment Interim Support | ||
1099 | * | ||
1100 | * The following is initial implementation of delayed P_Key assigment | ||
1101 | * mechanism. It is using the same approach implemented for the multicast | ||
1102 | * group join. The single goal of this implementation is to quickly address | ||
1103 | * Bug #2507. This implementation will probably be removed when the P_Key | ||
1104 | * change async notification is available. | ||
1105 | */ | ||
1106 | |||
1107 | void ipoib_pkey_poll(struct work_struct *work) | ||
1108 | { | ||
1109 | struct ipoib_dev_priv *priv = | ||
1110 | container_of(work, struct ipoib_dev_priv, pkey_poll_task.work); | ||
1111 | struct net_device *dev = priv->dev; | ||
1112 | |||
1113 | ipoib_pkey_dev_check_presence(dev); | ||
1114 | |||
1115 | if (test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) | ||
1116 | ipoib_open(dev); | ||
1117 | else { | ||
1118 | mutex_lock(&pkey_mutex); | ||
1119 | if (!test_bit(IPOIB_PKEY_STOP, &priv->flags)) | ||
1120 | queue_delayed_work(ipoib_workqueue, | ||
1121 | &priv->pkey_poll_task, | ||
1122 | HZ); | ||
1123 | mutex_unlock(&pkey_mutex); | ||
1124 | } | ||
1125 | } | ||
1126 | |||
1127 | int ipoib_pkey_dev_delay_open(struct net_device *dev) | ||
1128 | { | ||
1129 | struct ipoib_dev_priv *priv = netdev_priv(dev); | ||
1130 | |||
1131 | /* Look for the interface pkey value in the IB Port P_Key table and */ | ||
1132 | /* set the interface pkey assigment flag */ | ||
1133 | ipoib_pkey_dev_check_presence(dev); | ||
1134 | 1106 | ||
1135 | /* P_Key value not assigned yet - start polling */ | ||
1136 | if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) { | ||
1137 | mutex_lock(&pkey_mutex); | ||
1138 | clear_bit(IPOIB_PKEY_STOP, &priv->flags); | ||
1139 | queue_delayed_work(ipoib_workqueue, | ||
1140 | &priv->pkey_poll_task, | ||
1141 | HZ); | ||
1142 | mutex_unlock(&pkey_mutex); | ||
1143 | return 1; | ||
1144 | } | ||
1145 | |||
1146 | return 0; | ||
1147 | } | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 5786a78ff8bc..217cb77157d8 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -108,11 +108,11 @@ int ipoib_open(struct net_device *dev) | |||
108 | 108 | ||
109 | set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags); | 109 | set_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags); |
110 | 110 | ||
111 | if (ipoib_pkey_dev_delay_open(dev)) | 111 | if (ipoib_ib_dev_open(dev, 1)) { |
112 | return 0; | 112 | if (!test_bit(IPOIB_PKEY_ASSIGNED, &priv->flags)) |
113 | 113 | return 0; | |
114 | if (ipoib_ib_dev_open(dev)) | ||
115 | goto err_disable; | 114 | goto err_disable; |
115 | } | ||
116 | 116 | ||
117 | if (ipoib_ib_dev_up(dev)) | 117 | if (ipoib_ib_dev_up(dev)) |
118 | goto err_stop; | 118 | goto err_stop; |
@@ -1379,7 +1379,6 @@ void ipoib_setup(struct net_device *dev) | |||
1379 | INIT_LIST_HEAD(&priv->dead_ahs); | 1379 | INIT_LIST_HEAD(&priv->dead_ahs); |
1380 | INIT_LIST_HEAD(&priv->multicast_list); | 1380 | INIT_LIST_HEAD(&priv->multicast_list); |
1381 | 1381 | ||
1382 | INIT_DELAYED_WORK(&priv->pkey_poll_task, ipoib_pkey_poll); | ||
1383 | INIT_DELAYED_WORK(&priv->mcast_task, ipoib_mcast_join_task); | 1382 | INIT_DELAYED_WORK(&priv->mcast_task, ipoib_mcast_join_task); |
1384 | INIT_WORK(&priv->carrier_on_task, ipoib_mcast_carrier_on_task); | 1383 | INIT_WORK(&priv->carrier_on_task, ipoib_mcast_carrier_on_task); |
1385 | INIT_WORK(&priv->flush_light, ipoib_ib_dev_flush_light); | 1384 | INIT_WORK(&priv->flush_light, ipoib_ib_dev_flush_light); |
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index eb7973957a6e..61ee91d88380 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c | |||
@@ -596,20 +596,28 @@ iscsi_iser_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, | |||
596 | struct iser_conn *ib_conn; | 596 | struct iser_conn *ib_conn; |
597 | struct iscsi_endpoint *ep; | 597 | struct iscsi_endpoint *ep; |
598 | 598 | ||
599 | ep = iscsi_create_endpoint(sizeof(*ib_conn)); | 599 | ep = iscsi_create_endpoint(0); |
600 | if (!ep) | 600 | if (!ep) |
601 | return ERR_PTR(-ENOMEM); | 601 | return ERR_PTR(-ENOMEM); |
602 | 602 | ||
603 | ib_conn = ep->dd_data; | 603 | ib_conn = kzalloc(sizeof(*ib_conn), GFP_KERNEL); |
604 | if (!ib_conn) { | ||
605 | err = -ENOMEM; | ||
606 | goto failure; | ||
607 | } | ||
608 | |||
609 | ep->dd_data = ib_conn; | ||
604 | ib_conn->ep = ep; | 610 | ib_conn->ep = ep; |
605 | iser_conn_init(ib_conn); | 611 | iser_conn_init(ib_conn); |
606 | 612 | ||
607 | err = iser_connect(ib_conn, NULL, (struct sockaddr_in *)dst_addr, | 613 | err = iser_connect(ib_conn, NULL, dst_addr, non_blocking); |
608 | non_blocking); | ||
609 | if (err) | 614 | if (err) |
610 | return ERR_PTR(err); | 615 | goto failure; |
611 | 616 | ||
612 | return ep; | 617 | return ep; |
618 | failure: | ||
619 | iscsi_destroy_endpoint(ep); | ||
620 | return ERR_PTR(err); | ||
613 | } | 621 | } |
614 | 622 | ||
615 | static int | 623 | static int |
@@ -619,15 +627,16 @@ iscsi_iser_ep_poll(struct iscsi_endpoint *ep, int timeout_ms) | |||
619 | int rc; | 627 | int rc; |
620 | 628 | ||
621 | ib_conn = ep->dd_data; | 629 | ib_conn = ep->dd_data; |
622 | rc = wait_event_interruptible_timeout(ib_conn->wait, | 630 | rc = wait_for_completion_interruptible_timeout(&ib_conn->up_completion, |
623 | ib_conn->state == ISER_CONN_UP, | 631 | msecs_to_jiffies(timeout_ms)); |
624 | msecs_to_jiffies(timeout_ms)); | ||
625 | |||
626 | /* if conn establishment failed, return error code to iscsi */ | 632 | /* if conn establishment failed, return error code to iscsi */ |
627 | if (!rc && | 633 | if (rc == 0) { |
628 | (ib_conn->state == ISER_CONN_TERMINATING || | 634 | mutex_lock(&ib_conn->state_mutex); |
629 | ib_conn->state == ISER_CONN_DOWN)) | 635 | if (ib_conn->state == ISER_CONN_TERMINATING || |
630 | rc = -1; | 636 | ib_conn->state == ISER_CONN_DOWN) |
637 | rc = -1; | ||
638 | mutex_unlock(&ib_conn->state_mutex); | ||
639 | } | ||
631 | 640 | ||
632 | iser_info("ib conn %p rc = %d\n", ib_conn, rc); | 641 | iser_info("ib conn %p rc = %d\n", ib_conn, rc); |
633 | 642 | ||
@@ -646,19 +655,25 @@ iscsi_iser_ep_disconnect(struct iscsi_endpoint *ep) | |||
646 | 655 | ||
647 | ib_conn = ep->dd_data; | 656 | ib_conn = ep->dd_data; |
648 | iser_info("ep %p ib conn %p state %d\n", ep, ib_conn, ib_conn->state); | 657 | iser_info("ep %p ib conn %p state %d\n", ep, ib_conn, ib_conn->state); |
658 | mutex_lock(&ib_conn->state_mutex); | ||
649 | iser_conn_terminate(ib_conn); | 659 | iser_conn_terminate(ib_conn); |
650 | 660 | ||
651 | /* | 661 | /* |
652 | * if iser_conn and iscsi_conn are bound, we must wait iscsi_conn_stop | 662 | * if iser_conn and iscsi_conn are bound, we must wait for |
653 | * call and ISER_CONN_DOWN state before freeing the iser resources. | 663 | * iscsi_conn_stop and flush errors completion before freeing |
654 | * otherwise we are safe to free resources immediately. | 664 | * the iser resources. Otherwise we are safe to free resources |
665 | * immediately. | ||
655 | */ | 666 | */ |
656 | if (ib_conn->iscsi_conn) { | 667 | if (ib_conn->iscsi_conn) { |
657 | INIT_WORK(&ib_conn->release_work, iser_release_work); | 668 | INIT_WORK(&ib_conn->release_work, iser_release_work); |
658 | queue_work(release_wq, &ib_conn->release_work); | 669 | queue_work(release_wq, &ib_conn->release_work); |
670 | mutex_unlock(&ib_conn->state_mutex); | ||
659 | } else { | 671 | } else { |
672 | ib_conn->state = ISER_CONN_DOWN; | ||
673 | mutex_unlock(&ib_conn->state_mutex); | ||
660 | iser_conn_release(ib_conn); | 674 | iser_conn_release(ib_conn); |
661 | } | 675 | } |
676 | iscsi_destroy_endpoint(ep); | ||
662 | } | 677 | } |
663 | 678 | ||
664 | static umode_t iser_attr_is_visible(int param_type, int param) | 679 | static umode_t iser_attr_is_visible(int param_type, int param) |
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h index 97cd385bf7f7..c877dad381cb 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h | |||
@@ -326,7 +326,6 @@ struct iser_conn { | |||
326 | struct iser_device *device; /* device context */ | 326 | struct iser_device *device; /* device context */ |
327 | struct rdma_cm_id *cma_id; /* CMA ID */ | 327 | struct rdma_cm_id *cma_id; /* CMA ID */ |
328 | struct ib_qp *qp; /* QP */ | 328 | struct ib_qp *qp; /* QP */ |
329 | wait_queue_head_t wait; /* waitq for conn/disconn */ | ||
330 | unsigned qp_max_recv_dtos; /* num of rx buffers */ | 329 | unsigned qp_max_recv_dtos; /* num of rx buffers */ |
331 | unsigned qp_max_recv_dtos_mask; /* above minus 1 */ | 330 | unsigned qp_max_recv_dtos_mask; /* above minus 1 */ |
332 | unsigned min_posted_rx; /* qp_max_recv_dtos >> 2 */ | 331 | unsigned min_posted_rx; /* qp_max_recv_dtos >> 2 */ |
@@ -335,6 +334,9 @@ struct iser_conn { | |||
335 | char name[ISER_OBJECT_NAME_SIZE]; | 334 | char name[ISER_OBJECT_NAME_SIZE]; |
336 | struct work_struct release_work; | 335 | struct work_struct release_work; |
337 | struct completion stop_completion; | 336 | struct completion stop_completion; |
337 | struct mutex state_mutex; | ||
338 | struct completion flush_completion; | ||
339 | struct completion up_completion; | ||
338 | struct list_head conn_list; /* entry in ig conn list */ | 340 | struct list_head conn_list; /* entry in ig conn list */ |
339 | 341 | ||
340 | char *login_buf; | 342 | char *login_buf; |
@@ -448,8 +450,8 @@ int iser_reg_rdma_mem_fastreg(struct iscsi_iser_task *task, | |||
448 | enum iser_data_dir cmd_dir); | 450 | enum iser_data_dir cmd_dir); |
449 | 451 | ||
450 | int iser_connect(struct iser_conn *ib_conn, | 452 | int iser_connect(struct iser_conn *ib_conn, |
451 | struct sockaddr_in *src_addr, | 453 | struct sockaddr *src_addr, |
452 | struct sockaddr_in *dst_addr, | 454 | struct sockaddr *dst_addr, |
453 | int non_blocking); | 455 | int non_blocking); |
454 | 456 | ||
455 | int iser_reg_page_vec(struct iser_conn *ib_conn, | 457 | int iser_reg_page_vec(struct iser_conn *ib_conn, |
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index ea01075f9f9b..3ef167f97d6f 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c | |||
@@ -491,10 +491,9 @@ out_err: | |||
491 | } | 491 | } |
492 | 492 | ||
493 | /** | 493 | /** |
494 | * releases the QP objects, returns 0 on success, | 494 | * releases the QP object |
495 | * -1 on failure | ||
496 | */ | 495 | */ |
497 | static int iser_free_ib_conn_res(struct iser_conn *ib_conn) | 496 | static void iser_free_ib_conn_res(struct iser_conn *ib_conn) |
498 | { | 497 | { |
499 | int cq_index; | 498 | int cq_index; |
500 | BUG_ON(ib_conn == NULL); | 499 | BUG_ON(ib_conn == NULL); |
@@ -513,8 +512,6 @@ static int iser_free_ib_conn_res(struct iser_conn *ib_conn) | |||
513 | } | 512 | } |
514 | 513 | ||
515 | ib_conn->qp = NULL; | 514 | ib_conn->qp = NULL; |
516 | |||
517 | return 0; | ||
518 | } | 515 | } |
519 | 516 | ||
520 | /** | 517 | /** |
@@ -568,31 +565,40 @@ static void iser_device_try_release(struct iser_device *device) | |||
568 | mutex_unlock(&ig.device_list_mutex); | 565 | mutex_unlock(&ig.device_list_mutex); |
569 | } | 566 | } |
570 | 567 | ||
568 | /** | ||
569 | * Called with state mutex held | ||
570 | **/ | ||
571 | static int iser_conn_state_comp_exch(struct iser_conn *ib_conn, | 571 | static int iser_conn_state_comp_exch(struct iser_conn *ib_conn, |
572 | enum iser_ib_conn_state comp, | 572 | enum iser_ib_conn_state comp, |
573 | enum iser_ib_conn_state exch) | 573 | enum iser_ib_conn_state exch) |
574 | { | 574 | { |
575 | int ret; | 575 | int ret; |
576 | 576 | ||
577 | spin_lock_bh(&ib_conn->lock); | ||
578 | if ((ret = (ib_conn->state == comp))) | 577 | if ((ret = (ib_conn->state == comp))) |
579 | ib_conn->state = exch; | 578 | ib_conn->state = exch; |
580 | spin_unlock_bh(&ib_conn->lock); | ||
581 | return ret; | 579 | return ret; |
582 | } | 580 | } |
583 | 581 | ||
584 | void iser_release_work(struct work_struct *work) | 582 | void iser_release_work(struct work_struct *work) |
585 | { | 583 | { |
586 | struct iser_conn *ib_conn; | 584 | struct iser_conn *ib_conn; |
585 | int rc; | ||
587 | 586 | ||
588 | ib_conn = container_of(work, struct iser_conn, release_work); | 587 | ib_conn = container_of(work, struct iser_conn, release_work); |
589 | 588 | ||
590 | /* wait for .conn_stop callback */ | 589 | /* wait for .conn_stop callback */ |
591 | wait_for_completion(&ib_conn->stop_completion); | 590 | rc = wait_for_completion_timeout(&ib_conn->stop_completion, 30 * HZ); |
591 | WARN_ON(rc == 0); | ||
592 | 592 | ||
593 | /* wait for the qp`s post send and post receive buffers to empty */ | 593 | /* wait for the qp`s post send and post receive buffers to empty */ |
594 | wait_event_interruptible(ib_conn->wait, | 594 | rc = wait_for_completion_timeout(&ib_conn->flush_completion, 30 * HZ); |
595 | ib_conn->state == ISER_CONN_DOWN); | 595 | WARN_ON(rc == 0); |
596 | |||
597 | ib_conn->state = ISER_CONN_DOWN; | ||
598 | |||
599 | mutex_lock(&ib_conn->state_mutex); | ||
600 | ib_conn->state = ISER_CONN_DOWN; | ||
601 | mutex_unlock(&ib_conn->state_mutex); | ||
596 | 602 | ||
597 | iser_conn_release(ib_conn); | 603 | iser_conn_release(ib_conn); |
598 | } | 604 | } |
@@ -604,23 +610,27 @@ void iser_conn_release(struct iser_conn *ib_conn) | |||
604 | { | 610 | { |
605 | struct iser_device *device = ib_conn->device; | 611 | struct iser_device *device = ib_conn->device; |
606 | 612 | ||
607 | BUG_ON(ib_conn->state == ISER_CONN_UP); | ||
608 | |||
609 | mutex_lock(&ig.connlist_mutex); | 613 | mutex_lock(&ig.connlist_mutex); |
610 | list_del(&ib_conn->conn_list); | 614 | list_del(&ib_conn->conn_list); |
611 | mutex_unlock(&ig.connlist_mutex); | 615 | mutex_unlock(&ig.connlist_mutex); |
616 | |||
617 | mutex_lock(&ib_conn->state_mutex); | ||
618 | BUG_ON(ib_conn->state != ISER_CONN_DOWN); | ||
619 | |||
612 | iser_free_rx_descriptors(ib_conn); | 620 | iser_free_rx_descriptors(ib_conn); |
613 | iser_free_ib_conn_res(ib_conn); | 621 | iser_free_ib_conn_res(ib_conn); |
614 | ib_conn->device = NULL; | 622 | ib_conn->device = NULL; |
615 | /* on EVENT_ADDR_ERROR there's no device yet for this conn */ | 623 | /* on EVENT_ADDR_ERROR there's no device yet for this conn */ |
616 | if (device != NULL) | 624 | if (device != NULL) |
617 | iser_device_try_release(device); | 625 | iser_device_try_release(device); |
626 | mutex_unlock(&ib_conn->state_mutex); | ||
627 | |||
618 | /* if cma handler context, the caller actually destroy the id */ | 628 | /* if cma handler context, the caller actually destroy the id */ |
619 | if (ib_conn->cma_id != NULL) { | 629 | if (ib_conn->cma_id != NULL) { |
620 | rdma_destroy_id(ib_conn->cma_id); | 630 | rdma_destroy_id(ib_conn->cma_id); |
621 | ib_conn->cma_id = NULL; | 631 | ib_conn->cma_id = NULL; |
622 | } | 632 | } |
623 | iscsi_destroy_endpoint(ib_conn->ep); | 633 | kfree(ib_conn); |
624 | } | 634 | } |
625 | 635 | ||
626 | /** | 636 | /** |
@@ -642,22 +652,31 @@ void iser_conn_terminate(struct iser_conn *ib_conn) | |||
642 | ib_conn,err); | 652 | ib_conn,err); |
643 | } | 653 | } |
644 | 654 | ||
655 | /** | ||
656 | * Called with state mutex held | ||
657 | **/ | ||
645 | static void iser_connect_error(struct rdma_cm_id *cma_id) | 658 | static void iser_connect_error(struct rdma_cm_id *cma_id) |
646 | { | 659 | { |
647 | struct iser_conn *ib_conn; | 660 | struct iser_conn *ib_conn; |
648 | 661 | ||
649 | ib_conn = (struct iser_conn *)cma_id->context; | 662 | ib_conn = (struct iser_conn *)cma_id->context; |
650 | |||
651 | ib_conn->state = ISER_CONN_DOWN; | 663 | ib_conn->state = ISER_CONN_DOWN; |
652 | wake_up_interruptible(&ib_conn->wait); | ||
653 | } | 664 | } |
654 | 665 | ||
666 | /** | ||
667 | * Called with state mutex held | ||
668 | **/ | ||
655 | static void iser_addr_handler(struct rdma_cm_id *cma_id) | 669 | static void iser_addr_handler(struct rdma_cm_id *cma_id) |
656 | { | 670 | { |
657 | struct iser_device *device; | 671 | struct iser_device *device; |
658 | struct iser_conn *ib_conn; | 672 | struct iser_conn *ib_conn; |
659 | int ret; | 673 | int ret; |
660 | 674 | ||
675 | ib_conn = (struct iser_conn *)cma_id->context; | ||
676 | if (ib_conn->state != ISER_CONN_PENDING) | ||
677 | /* bailout */ | ||
678 | return; | ||
679 | |||
661 | device = iser_device_find_by_ib_device(cma_id); | 680 | device = iser_device_find_by_ib_device(cma_id); |
662 | if (!device) { | 681 | if (!device) { |
663 | iser_err("device lookup/creation failed\n"); | 682 | iser_err("device lookup/creation failed\n"); |
@@ -665,7 +684,6 @@ static void iser_addr_handler(struct rdma_cm_id *cma_id) | |||
665 | return; | 684 | return; |
666 | } | 685 | } |
667 | 686 | ||
668 | ib_conn = (struct iser_conn *)cma_id->context; | ||
669 | ib_conn->device = device; | 687 | ib_conn->device = device; |
670 | 688 | ||
671 | /* connection T10-PI support */ | 689 | /* connection T10-PI support */ |
@@ -689,18 +707,27 @@ static void iser_addr_handler(struct rdma_cm_id *cma_id) | |||
689 | } | 707 | } |
690 | } | 708 | } |
691 | 709 | ||
710 | /** | ||
711 | * Called with state mutex held | ||
712 | **/ | ||
692 | static void iser_route_handler(struct rdma_cm_id *cma_id) | 713 | static void iser_route_handler(struct rdma_cm_id *cma_id) |
693 | { | 714 | { |
694 | struct rdma_conn_param conn_param; | 715 | struct rdma_conn_param conn_param; |
695 | int ret; | 716 | int ret; |
696 | struct iser_cm_hdr req_hdr; | 717 | struct iser_cm_hdr req_hdr; |
718 | struct iser_conn *ib_conn = (struct iser_conn *)cma_id->context; | ||
719 | struct iser_device *device = ib_conn->device; | ||
720 | |||
721 | if (ib_conn->state != ISER_CONN_PENDING) | ||
722 | /* bailout */ | ||
723 | return; | ||
697 | 724 | ||
698 | ret = iser_create_ib_conn_res((struct iser_conn *)cma_id->context); | 725 | ret = iser_create_ib_conn_res((struct iser_conn *)cma_id->context); |
699 | if (ret) | 726 | if (ret) |
700 | goto failure; | 727 | goto failure; |
701 | 728 | ||
702 | memset(&conn_param, 0, sizeof conn_param); | 729 | memset(&conn_param, 0, sizeof conn_param); |
703 | conn_param.responder_resources = 4; | 730 | conn_param.responder_resources = device->dev_attr.max_qp_rd_atom; |
704 | conn_param.initiator_depth = 1; | 731 | conn_param.initiator_depth = 1; |
705 | conn_param.retry_count = 7; | 732 | conn_param.retry_count = 7; |
706 | conn_param.rnr_retry_count = 6; | 733 | conn_param.rnr_retry_count = 6; |
@@ -728,12 +755,16 @@ static void iser_connected_handler(struct rdma_cm_id *cma_id) | |||
728 | struct ib_qp_attr attr; | 755 | struct ib_qp_attr attr; |
729 | struct ib_qp_init_attr init_attr; | 756 | struct ib_qp_init_attr init_attr; |
730 | 757 | ||
758 | ib_conn = (struct iser_conn *)cma_id->context; | ||
759 | if (ib_conn->state != ISER_CONN_PENDING) | ||
760 | /* bailout */ | ||
761 | return; | ||
762 | |||
731 | (void)ib_query_qp(cma_id->qp, &attr, ~0, &init_attr); | 763 | (void)ib_query_qp(cma_id->qp, &attr, ~0, &init_attr); |
732 | iser_info("remote qpn:%x my qpn:%x\n", attr.dest_qp_num, cma_id->qp->qp_num); | 764 | iser_info("remote qpn:%x my qpn:%x\n", attr.dest_qp_num, cma_id->qp->qp_num); |
733 | 765 | ||
734 | ib_conn = (struct iser_conn *)cma_id->context; | 766 | ib_conn->state = ISER_CONN_UP; |
735 | if (iser_conn_state_comp_exch(ib_conn, ISER_CONN_PENDING, ISER_CONN_UP)) | 767 | complete(&ib_conn->up_completion); |
736 | wake_up_interruptible(&ib_conn->wait); | ||
737 | } | 768 | } |
738 | 769 | ||
739 | static void iser_disconnected_handler(struct rdma_cm_id *cma_id) | 770 | static void iser_disconnected_handler(struct rdma_cm_id *cma_id) |
@@ -752,19 +783,25 @@ static void iser_disconnected_handler(struct rdma_cm_id *cma_id) | |||
752 | iser_err("iscsi_iser connection isn't bound\n"); | 783 | iser_err("iscsi_iser connection isn't bound\n"); |
753 | } | 784 | } |
754 | 785 | ||
755 | /* Complete the termination process if no posts are pending */ | 786 | /* Complete the termination process if no posts are pending. This code |
787 | * block also exists in iser_handle_comp_error(), but it is needed here | ||
788 | * for cases of no flushes at all, e.g. discovery over rdma. | ||
789 | */ | ||
756 | if (ib_conn->post_recv_buf_count == 0 && | 790 | if (ib_conn->post_recv_buf_count == 0 && |
757 | (atomic_read(&ib_conn->post_send_buf_count) == 0)) { | 791 | (atomic_read(&ib_conn->post_send_buf_count) == 0)) { |
758 | ib_conn->state = ISER_CONN_DOWN; | 792 | complete(&ib_conn->flush_completion); |
759 | wake_up_interruptible(&ib_conn->wait); | ||
760 | } | 793 | } |
761 | } | 794 | } |
762 | 795 | ||
763 | static int iser_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) | 796 | static int iser_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) |
764 | { | 797 | { |
798 | struct iser_conn *ib_conn; | ||
799 | |||
800 | ib_conn = (struct iser_conn *)cma_id->context; | ||
765 | iser_info("event %d status %d conn %p id %p\n", | 801 | iser_info("event %d status %d conn %p id %p\n", |
766 | event->event, event->status, cma_id->context, cma_id); | 802 | event->event, event->status, cma_id->context, cma_id); |
767 | 803 | ||
804 | mutex_lock(&ib_conn->state_mutex); | ||
768 | switch (event->event) { | 805 | switch (event->event) { |
769 | case RDMA_CM_EVENT_ADDR_RESOLVED: | 806 | case RDMA_CM_EVENT_ADDR_RESOLVED: |
770 | iser_addr_handler(cma_id); | 807 | iser_addr_handler(cma_id); |
@@ -785,24 +822,28 @@ static int iser_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *eve | |||
785 | case RDMA_CM_EVENT_DISCONNECTED: | 822 | case RDMA_CM_EVENT_DISCONNECTED: |
786 | case RDMA_CM_EVENT_DEVICE_REMOVAL: | 823 | case RDMA_CM_EVENT_DEVICE_REMOVAL: |
787 | case RDMA_CM_EVENT_ADDR_CHANGE: | 824 | case RDMA_CM_EVENT_ADDR_CHANGE: |
825 | case RDMA_CM_EVENT_TIMEWAIT_EXIT: | ||
788 | iser_disconnected_handler(cma_id); | 826 | iser_disconnected_handler(cma_id); |
789 | break; | 827 | break; |
790 | default: | 828 | default: |
791 | iser_err("Unexpected RDMA CM event (%d)\n", event->event); | 829 | iser_err("Unexpected RDMA CM event (%d)\n", event->event); |
792 | break; | 830 | break; |
793 | } | 831 | } |
832 | mutex_unlock(&ib_conn->state_mutex); | ||
794 | return 0; | 833 | return 0; |
795 | } | 834 | } |
796 | 835 | ||
797 | void iser_conn_init(struct iser_conn *ib_conn) | 836 | void iser_conn_init(struct iser_conn *ib_conn) |
798 | { | 837 | { |
799 | ib_conn->state = ISER_CONN_INIT; | 838 | ib_conn->state = ISER_CONN_INIT; |
800 | init_waitqueue_head(&ib_conn->wait); | ||
801 | ib_conn->post_recv_buf_count = 0; | 839 | ib_conn->post_recv_buf_count = 0; |
802 | atomic_set(&ib_conn->post_send_buf_count, 0); | 840 | atomic_set(&ib_conn->post_send_buf_count, 0); |
803 | init_completion(&ib_conn->stop_completion); | 841 | init_completion(&ib_conn->stop_completion); |
842 | init_completion(&ib_conn->flush_completion); | ||
843 | init_completion(&ib_conn->up_completion); | ||
804 | INIT_LIST_HEAD(&ib_conn->conn_list); | 844 | INIT_LIST_HEAD(&ib_conn->conn_list); |
805 | spin_lock_init(&ib_conn->lock); | 845 | spin_lock_init(&ib_conn->lock); |
846 | mutex_init(&ib_conn->state_mutex); | ||
806 | } | 847 | } |
807 | 848 | ||
808 | /** | 849 | /** |
@@ -810,22 +851,21 @@ void iser_conn_init(struct iser_conn *ib_conn) | |||
810 | * sleeps until the connection is established or rejected | 851 | * sleeps until the connection is established or rejected |
811 | */ | 852 | */ |
812 | int iser_connect(struct iser_conn *ib_conn, | 853 | int iser_connect(struct iser_conn *ib_conn, |
813 | struct sockaddr_in *src_addr, | 854 | struct sockaddr *src_addr, |
814 | struct sockaddr_in *dst_addr, | 855 | struct sockaddr *dst_addr, |
815 | int non_blocking) | 856 | int non_blocking) |
816 | { | 857 | { |
817 | struct sockaddr *src, *dst; | ||
818 | int err = 0; | 858 | int err = 0; |
819 | 859 | ||
820 | sprintf(ib_conn->name, "%pI4:%d", | 860 | mutex_lock(&ib_conn->state_mutex); |
821 | &dst_addr->sin_addr.s_addr, dst_addr->sin_port); | 861 | |
862 | sprintf(ib_conn->name, "%pISp", dst_addr); | ||
863 | |||
864 | iser_info("connecting to: %s\n", ib_conn->name); | ||
822 | 865 | ||
823 | /* the device is known only --after-- address resolution */ | 866 | /* the device is known only --after-- address resolution */ |
824 | ib_conn->device = NULL; | 867 | ib_conn->device = NULL; |
825 | 868 | ||
826 | iser_info("connecting to: %pI4, port 0x%x\n", | ||
827 | &dst_addr->sin_addr, dst_addr->sin_port); | ||
828 | |||
829 | ib_conn->state = ISER_CONN_PENDING; | 869 | ib_conn->state = ISER_CONN_PENDING; |
830 | 870 | ||
831 | ib_conn->cma_id = rdma_create_id(iser_cma_handler, | 871 | ib_conn->cma_id = rdma_create_id(iser_cma_handler, |
@@ -837,23 +877,21 @@ int iser_connect(struct iser_conn *ib_conn, | |||
837 | goto id_failure; | 877 | goto id_failure; |
838 | } | 878 | } |
839 | 879 | ||
840 | src = (struct sockaddr *)src_addr; | 880 | err = rdma_resolve_addr(ib_conn->cma_id, src_addr, dst_addr, 1000); |
841 | dst = (struct sockaddr *)dst_addr; | ||
842 | err = rdma_resolve_addr(ib_conn->cma_id, src, dst, 1000); | ||
843 | if (err) { | 881 | if (err) { |
844 | iser_err("rdma_resolve_addr failed: %d\n", err); | 882 | iser_err("rdma_resolve_addr failed: %d\n", err); |
845 | goto addr_failure; | 883 | goto addr_failure; |
846 | } | 884 | } |
847 | 885 | ||
848 | if (!non_blocking) { | 886 | if (!non_blocking) { |
849 | wait_event_interruptible(ib_conn->wait, | 887 | wait_for_completion_interruptible(&ib_conn->up_completion); |
850 | (ib_conn->state != ISER_CONN_PENDING)); | ||
851 | 888 | ||
852 | if (ib_conn->state != ISER_CONN_UP) { | 889 | if (ib_conn->state != ISER_CONN_UP) { |
853 | err = -EIO; | 890 | err = -EIO; |
854 | goto connect_failure; | 891 | goto connect_failure; |
855 | } | 892 | } |
856 | } | 893 | } |
894 | mutex_unlock(&ib_conn->state_mutex); | ||
857 | 895 | ||
858 | mutex_lock(&ig.connlist_mutex); | 896 | mutex_lock(&ig.connlist_mutex); |
859 | list_add(&ib_conn->conn_list, &ig.connlist); | 897 | list_add(&ib_conn->conn_list, &ig.connlist); |
@@ -865,6 +903,7 @@ id_failure: | |||
865 | addr_failure: | 903 | addr_failure: |
866 | ib_conn->state = ISER_CONN_DOWN; | 904 | ib_conn->state = ISER_CONN_DOWN; |
867 | connect_failure: | 905 | connect_failure: |
906 | mutex_unlock(&ib_conn->state_mutex); | ||
868 | iser_conn_release(ib_conn); | 907 | iser_conn_release(ib_conn); |
869 | return err; | 908 | return err; |
870 | } | 909 | } |
@@ -1049,18 +1088,19 @@ static void iser_handle_comp_error(struct iser_tx_desc *desc, | |||
1049 | 1088 | ||
1050 | if (ib_conn->post_recv_buf_count == 0 && | 1089 | if (ib_conn->post_recv_buf_count == 0 && |
1051 | atomic_read(&ib_conn->post_send_buf_count) == 0) { | 1090 | atomic_read(&ib_conn->post_send_buf_count) == 0) { |
1052 | /* getting here when the state is UP means that the conn is * | 1091 | /** |
1053 | * being terminated asynchronously from the iSCSI layer's * | 1092 | * getting here when the state is UP means that the conn is |
1054 | * perspective. */ | 1093 | * being terminated asynchronously from the iSCSI layer's |
1055 | if (iser_conn_state_comp_exch(ib_conn, ISER_CONN_UP, | 1094 | * perspective. It is safe to peek at the connection state |
1056 | ISER_CONN_TERMINATING)) | 1095 | * since iscsi_conn_failure is allowed to be called twice. |
1096 | **/ | ||
1097 | if (ib_conn->state == ISER_CONN_UP) | ||
1057 | iscsi_conn_failure(ib_conn->iscsi_conn, | 1098 | iscsi_conn_failure(ib_conn->iscsi_conn, |
1058 | ISCSI_ERR_CONN_FAILED); | 1099 | ISCSI_ERR_CONN_FAILED); |
1059 | 1100 | ||
1060 | /* no more non completed posts to the QP, complete the | 1101 | /* no more non completed posts to the QP, complete the |
1061 | * termination process w.o worrying on disconnect event */ | 1102 | * termination process w.o worrying on disconnect event */ |
1062 | ib_conn->state = ISER_CONN_DOWN; | 1103 | complete(&ib_conn->flush_completion); |
1063 | wake_up_interruptible(&ib_conn->wait); | ||
1064 | } | 1104 | } |
1065 | } | 1105 | } |
1066 | 1106 | ||
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index e3c2c5b4297f..62d2a18e1b41 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
@@ -130,6 +130,7 @@ static void srp_send_completion(struct ib_cq *cq, void *target_ptr); | |||
130 | static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event); | 130 | static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event); |
131 | 131 | ||
132 | static struct scsi_transport_template *ib_srp_transport_template; | 132 | static struct scsi_transport_template *ib_srp_transport_template; |
133 | static struct workqueue_struct *srp_remove_wq; | ||
133 | 134 | ||
134 | static struct ib_client srp_client = { | 135 | static struct ib_client srp_client = { |
135 | .name = "srp", | 136 | .name = "srp", |
@@ -731,7 +732,7 @@ static bool srp_queue_remove_work(struct srp_target_port *target) | |||
731 | spin_unlock_irq(&target->lock); | 732 | spin_unlock_irq(&target->lock); |
732 | 733 | ||
733 | if (changed) | 734 | if (changed) |
734 | queue_work(system_long_wq, &target->remove_work); | 735 | queue_work(srp_remove_wq, &target->remove_work); |
735 | 736 | ||
736 | return changed; | 737 | return changed; |
737 | } | 738 | } |
@@ -1643,10 +1644,14 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) | |||
1643 | SCSI_SENSE_BUFFERSIZE)); | 1644 | SCSI_SENSE_BUFFERSIZE)); |
1644 | } | 1645 | } |
1645 | 1646 | ||
1646 | if (rsp->flags & (SRP_RSP_FLAG_DOOVER | SRP_RSP_FLAG_DOUNDER)) | 1647 | if (unlikely(rsp->flags & SRP_RSP_FLAG_DIUNDER)) |
1647 | scsi_set_resid(scmnd, be32_to_cpu(rsp->data_out_res_cnt)); | ||
1648 | else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER)) | ||
1649 | scsi_set_resid(scmnd, be32_to_cpu(rsp->data_in_res_cnt)); | 1648 | scsi_set_resid(scmnd, be32_to_cpu(rsp->data_in_res_cnt)); |
1649 | else if (unlikely(rsp->flags & SRP_RSP_FLAG_DIOVER)) | ||
1650 | scsi_set_resid(scmnd, -be32_to_cpu(rsp->data_in_res_cnt)); | ||
1651 | else if (unlikely(rsp->flags & SRP_RSP_FLAG_DOUNDER)) | ||
1652 | scsi_set_resid(scmnd, be32_to_cpu(rsp->data_out_res_cnt)); | ||
1653 | else if (unlikely(rsp->flags & SRP_RSP_FLAG_DOOVER)) | ||
1654 | scsi_set_resid(scmnd, -be32_to_cpu(rsp->data_out_res_cnt)); | ||
1650 | 1655 | ||
1651 | srp_free_req(target, req, scmnd, | 1656 | srp_free_req(target, req, scmnd, |
1652 | be32_to_cpu(rsp->req_lim_delta)); | 1657 | be32_to_cpu(rsp->req_lim_delta)); |
@@ -3261,9 +3266,10 @@ static void srp_remove_one(struct ib_device *device) | |||
3261 | spin_unlock(&host->target_lock); | 3266 | spin_unlock(&host->target_lock); |
3262 | 3267 | ||
3263 | /* | 3268 | /* |
3264 | * Wait for target port removal tasks. | 3269 | * Wait for tl_err and target port removal tasks. |
3265 | */ | 3270 | */ |
3266 | flush_workqueue(system_long_wq); | 3271 | flush_workqueue(system_long_wq); |
3272 | flush_workqueue(srp_remove_wq); | ||
3267 | 3273 | ||
3268 | kfree(host); | 3274 | kfree(host); |
3269 | } | 3275 | } |
@@ -3313,16 +3319,22 @@ static int __init srp_init_module(void) | |||
3313 | indirect_sg_entries = cmd_sg_entries; | 3319 | indirect_sg_entries = cmd_sg_entries; |
3314 | } | 3320 | } |
3315 | 3321 | ||
3322 | srp_remove_wq = create_workqueue("srp_remove"); | ||
3323 | if (!srp_remove_wq) { | ||
3324 | ret = -ENOMEM; | ||
3325 | goto out; | ||
3326 | } | ||
3327 | |||
3328 | ret = -ENOMEM; | ||
3316 | ib_srp_transport_template = | 3329 | ib_srp_transport_template = |
3317 | srp_attach_transport(&ib_srp_transport_functions); | 3330 | srp_attach_transport(&ib_srp_transport_functions); |
3318 | if (!ib_srp_transport_template) | 3331 | if (!ib_srp_transport_template) |
3319 | return -ENOMEM; | 3332 | goto destroy_wq; |
3320 | 3333 | ||
3321 | ret = class_register(&srp_class); | 3334 | ret = class_register(&srp_class); |
3322 | if (ret) { | 3335 | if (ret) { |
3323 | pr_err("couldn't register class infiniband_srp\n"); | 3336 | pr_err("couldn't register class infiniband_srp\n"); |
3324 | srp_release_transport(ib_srp_transport_template); | 3337 | goto release_tr; |
3325 | return ret; | ||
3326 | } | 3338 | } |
3327 | 3339 | ||
3328 | ib_sa_register_client(&srp_sa_client); | 3340 | ib_sa_register_client(&srp_sa_client); |
@@ -3330,13 +3342,22 @@ static int __init srp_init_module(void) | |||
3330 | ret = ib_register_client(&srp_client); | 3342 | ret = ib_register_client(&srp_client); |
3331 | if (ret) { | 3343 | if (ret) { |
3332 | pr_err("couldn't register IB client\n"); | 3344 | pr_err("couldn't register IB client\n"); |
3333 | srp_release_transport(ib_srp_transport_template); | 3345 | goto unreg_sa; |
3334 | ib_sa_unregister_client(&srp_sa_client); | ||
3335 | class_unregister(&srp_class); | ||
3336 | return ret; | ||
3337 | } | 3346 | } |
3338 | 3347 | ||
3339 | return 0; | 3348 | out: |
3349 | return ret; | ||
3350 | |||
3351 | unreg_sa: | ||
3352 | ib_sa_unregister_client(&srp_sa_client); | ||
3353 | class_unregister(&srp_class); | ||
3354 | |||
3355 | release_tr: | ||
3356 | srp_release_transport(ib_srp_transport_template); | ||
3357 | |||
3358 | destroy_wq: | ||
3359 | destroy_workqueue(srp_remove_wq); | ||
3360 | goto out; | ||
3340 | } | 3361 | } |
3341 | 3362 | ||
3342 | static void __exit srp_cleanup_module(void) | 3363 | static void __exit srp_cleanup_module(void) |
@@ -3345,6 +3366,7 @@ static void __exit srp_cleanup_module(void) | |||
3345 | ib_sa_unregister_client(&srp_sa_client); | 3366 | ib_sa_unregister_client(&srp_sa_client); |
3346 | class_unregister(&srp_class); | 3367 | class_unregister(&srp_class); |
3347 | srp_release_transport(ib_srp_transport_template); | 3368 | srp_release_transport(ib_srp_transport_template); |
3369 | destroy_workqueue(srp_remove_wq); | ||
3348 | } | 3370 | } |
3349 | 3371 | ||
3350 | module_init(srp_init_module); | 3372 | module_init(srp_init_module); |
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index fe09f2788b15..d28a8c284da9 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c | |||
@@ -198,6 +198,7 @@ static void srpt_event_handler(struct ib_event_handler *handler, | |||
198 | case IB_EVENT_PKEY_CHANGE: | 198 | case IB_EVENT_PKEY_CHANGE: |
199 | case IB_EVENT_SM_CHANGE: | 199 | case IB_EVENT_SM_CHANGE: |
200 | case IB_EVENT_CLIENT_REREGISTER: | 200 | case IB_EVENT_CLIENT_REREGISTER: |
201 | case IB_EVENT_GID_CHANGE: | ||
201 | /* Refresh port data asynchronously. */ | 202 | /* Refresh port data asynchronously. */ |
202 | if (event->element.port_num <= sdev->device->phys_port_cnt) { | 203 | if (event->element.port_num <= sdev->device->phys_port_cnt) { |
203 | sport = &sdev->port[event->element.port_num - 1]; | 204 | sport = &sdev->port[event->element.port_num - 1]; |
@@ -563,7 +564,7 @@ static int srpt_refresh_port(struct srpt_port *sport) | |||
563 | ®_req, 0, | 564 | ®_req, 0, |
564 | srpt_mad_send_handler, | 565 | srpt_mad_send_handler, |
565 | srpt_mad_recv_handler, | 566 | srpt_mad_recv_handler, |
566 | sport); | 567 | sport, 0); |
567 | if (IS_ERR(sport->mad_agent)) { | 568 | if (IS_ERR(sport->mad_agent)) { |
568 | ret = PTR_ERR(sport->mad_agent); | 569 | ret = PTR_ERR(sport->mad_agent); |
569 | sport->mad_agent = NULL; | 570 | sport->mad_agent = NULL; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 5d940a26055c..65a4a0f88ea0 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c | |||
@@ -1311,6 +1311,15 @@ static struct mlx4_cmd_info cmd_info[] = { | |||
1311 | .wrapper = mlx4_MAD_IFC_wrapper | 1311 | .wrapper = mlx4_MAD_IFC_wrapper |
1312 | }, | 1312 | }, |
1313 | { | 1313 | { |
1314 | .opcode = MLX4_CMD_MAD_DEMUX, | ||
1315 | .has_inbox = false, | ||
1316 | .has_outbox = false, | ||
1317 | .out_is_imm = false, | ||
1318 | .encode_slave_id = false, | ||
1319 | .verify = NULL, | ||
1320 | .wrapper = mlx4_CMD_EPERM_wrapper | ||
1321 | }, | ||
1322 | { | ||
1314 | .opcode = MLX4_CMD_QUERY_IF_STAT, | 1323 | .opcode = MLX4_CMD_QUERY_IF_STAT, |
1315 | .has_inbox = false, | 1324 | .has_inbox = false, |
1316 | .has_outbox = true, | 1325 | .has_outbox = true, |
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 688e1eabab29..494753e44ae3 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c | |||
@@ -136,7 +136,8 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags) | |||
136 | [7] = "FSM (MAC anti-spoofing) support", | 136 | [7] = "FSM (MAC anti-spoofing) support", |
137 | [8] = "Dynamic QP updates support", | 137 | [8] = "Dynamic QP updates support", |
138 | [9] = "Device managed flow steering IPoIB support", | 138 | [9] = "Device managed flow steering IPoIB support", |
139 | [10] = "TCP/IP offloads/flow-steering for VXLAN support" | 139 | [10] = "TCP/IP offloads/flow-steering for VXLAN support", |
140 | [11] = "MAD DEMUX (Secure-Host) support" | ||
140 | }; | 141 | }; |
141 | int i; | 142 | int i; |
142 | 143 | ||
@@ -571,6 +572,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
571 | #define QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET 0xa0 | 572 | #define QUERY_DEV_CAP_MAX_ICM_SZ_OFFSET 0xa0 |
572 | #define QUERY_DEV_CAP_FW_REASSIGN_MAC 0x9d | 573 | #define QUERY_DEV_CAP_FW_REASSIGN_MAC 0x9d |
573 | #define QUERY_DEV_CAP_VXLAN 0x9e | 574 | #define QUERY_DEV_CAP_VXLAN 0x9e |
575 | #define QUERY_DEV_CAP_MAD_DEMUX_OFFSET 0xb0 | ||
574 | 576 | ||
575 | dev_cap->flags2 = 0; | 577 | dev_cap->flags2 = 0; |
576 | mailbox = mlx4_alloc_cmd_mailbox(dev); | 578 | mailbox = mlx4_alloc_cmd_mailbox(dev); |
@@ -748,6 +750,11 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) | |||
748 | MLX4_GET(dev_cap->max_counters, outbox, | 750 | MLX4_GET(dev_cap->max_counters, outbox, |
749 | QUERY_DEV_CAP_MAX_COUNTERS_OFFSET); | 751 | QUERY_DEV_CAP_MAX_COUNTERS_OFFSET); |
750 | 752 | ||
753 | MLX4_GET(field32, outbox, | ||
754 | QUERY_DEV_CAP_MAD_DEMUX_OFFSET); | ||
755 | if (field32 & (1 << 0)) | ||
756 | dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_MAD_DEMUX; | ||
757 | |||
751 | MLX4_GET(field32, outbox, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET); | 758 | MLX4_GET(field32, outbox, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET); |
752 | if (field32 & (1 << 16)) | 759 | if (field32 & (1 << 16)) |
753 | dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_UPDATE_QP; | 760 | dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_UPDATE_QP; |
@@ -2016,3 +2023,85 @@ void mlx4_opreq_action(struct work_struct *work) | |||
2016 | out: | 2023 | out: |
2017 | mlx4_free_cmd_mailbox(dev, mailbox); | 2024 | mlx4_free_cmd_mailbox(dev, mailbox); |
2018 | } | 2025 | } |
2026 | |||
2027 | static int mlx4_check_smp_firewall_active(struct mlx4_dev *dev, | ||
2028 | struct mlx4_cmd_mailbox *mailbox) | ||
2029 | { | ||
2030 | #define MLX4_CMD_MAD_DEMUX_SET_ATTR_OFFSET 0x10 | ||
2031 | #define MLX4_CMD_MAD_DEMUX_GETRESP_ATTR_OFFSET 0x20 | ||
2032 | #define MLX4_CMD_MAD_DEMUX_TRAP_ATTR_OFFSET 0x40 | ||
2033 | #define MLX4_CMD_MAD_DEMUX_TRAP_REPRESS_ATTR_OFFSET 0x70 | ||
2034 | |||
2035 | u32 set_attr_mask, getresp_attr_mask; | ||
2036 | u32 trap_attr_mask, traprepress_attr_mask; | ||
2037 | |||
2038 | MLX4_GET(set_attr_mask, mailbox->buf, | ||
2039 | MLX4_CMD_MAD_DEMUX_SET_ATTR_OFFSET); | ||
2040 | mlx4_dbg(dev, "SMP firewall set_attribute_mask = 0x%x\n", | ||
2041 | set_attr_mask); | ||
2042 | |||
2043 | MLX4_GET(getresp_attr_mask, mailbox->buf, | ||
2044 | MLX4_CMD_MAD_DEMUX_GETRESP_ATTR_OFFSET); | ||
2045 | mlx4_dbg(dev, "SMP firewall getresp_attribute_mask = 0x%x\n", | ||
2046 | getresp_attr_mask); | ||
2047 | |||
2048 | MLX4_GET(trap_attr_mask, mailbox->buf, | ||
2049 | MLX4_CMD_MAD_DEMUX_TRAP_ATTR_OFFSET); | ||
2050 | mlx4_dbg(dev, "SMP firewall trap_attribute_mask = 0x%x\n", | ||
2051 | trap_attr_mask); | ||
2052 | |||
2053 | MLX4_GET(traprepress_attr_mask, mailbox->buf, | ||
2054 | MLX4_CMD_MAD_DEMUX_TRAP_REPRESS_ATTR_OFFSET); | ||
2055 | mlx4_dbg(dev, "SMP firewall traprepress_attribute_mask = 0x%x\n", | ||
2056 | traprepress_attr_mask); | ||
2057 | |||
2058 | if (set_attr_mask && getresp_attr_mask && trap_attr_mask && | ||
2059 | traprepress_attr_mask) | ||
2060 | return 1; | ||
2061 | |||
2062 | return 0; | ||
2063 | } | ||
2064 | |||
2065 | int mlx4_config_mad_demux(struct mlx4_dev *dev) | ||
2066 | { | ||
2067 | struct mlx4_cmd_mailbox *mailbox; | ||
2068 | int secure_host_active; | ||
2069 | int err; | ||
2070 | |||
2071 | /* Check if mad_demux is supported */ | ||
2072 | if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_MAD_DEMUX)) | ||
2073 | return 0; | ||
2074 | |||
2075 | mailbox = mlx4_alloc_cmd_mailbox(dev); | ||
2076 | if (IS_ERR(mailbox)) { | ||
2077 | mlx4_warn(dev, "Failed to allocate mailbox for cmd MAD_DEMUX"); | ||
2078 | return -ENOMEM; | ||
2079 | } | ||
2080 | |||
2081 | /* Query mad_demux to find out which MADs are handled by internal sma */ | ||
2082 | err = mlx4_cmd_box(dev, 0, mailbox->dma, 0x01 /* subn mgmt class */, | ||
2083 | MLX4_CMD_MAD_DEMUX_QUERY_RESTR, MLX4_CMD_MAD_DEMUX, | ||
2084 | MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); | ||
2085 | if (err) { | ||
2086 | mlx4_warn(dev, "MLX4_CMD_MAD_DEMUX: query restrictions failed (%d)\n", | ||
2087 | err); | ||
2088 | goto out; | ||
2089 | } | ||
2090 | |||
2091 | secure_host_active = mlx4_check_smp_firewall_active(dev, mailbox); | ||
2092 | |||
2093 | /* Config mad_demux to handle all MADs returned by the query above */ | ||
2094 | err = mlx4_cmd(dev, mailbox->dma, 0x01 /* subn mgmt class */, | ||
2095 | MLX4_CMD_MAD_DEMUX_CONFIG, MLX4_CMD_MAD_DEMUX, | ||
2096 | MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); | ||
2097 | if (err) { | ||
2098 | mlx4_warn(dev, "MLX4_CMD_MAD_DEMUX: configure failed (%d)\n", err); | ||
2099 | goto out; | ||
2100 | } | ||
2101 | |||
2102 | if (secure_host_active) | ||
2103 | mlx4_warn(dev, "HCA operating in secure-host mode. SMP firewall activated.\n"); | ||
2104 | out: | ||
2105 | mlx4_free_cmd_mailbox(dev, mailbox); | ||
2106 | return err; | ||
2107 | } | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 82ab427290c3..f2c8e8ba23fe 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -1831,6 +1831,11 @@ static int mlx4_setup_hca(struct mlx4_dev *dev) | |||
1831 | mlx4_err(dev, "Failed to initialize multicast group table, aborting\n"); | 1831 | mlx4_err(dev, "Failed to initialize multicast group table, aborting\n"); |
1832 | goto err_mr_table_free; | 1832 | goto err_mr_table_free; |
1833 | } | 1833 | } |
1834 | err = mlx4_config_mad_demux(dev); | ||
1835 | if (err) { | ||
1836 | mlx4_err(dev, "Failed in config_mad_demux, aborting\n"); | ||
1837 | goto err_mcg_table_free; | ||
1838 | } | ||
1834 | } | 1839 | } |
1835 | 1840 | ||
1836 | err = mlx4_init_eq_table(dev); | 1841 | err = mlx4_init_eq_table(dev); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 1d8af7336807..3398ff7e67e9 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
@@ -279,6 +279,8 @@ struct mlx4_icm_table { | |||
279 | #define MLX4_MPT_FLAG_PHYSICAL (1 << 9) | 279 | #define MLX4_MPT_FLAG_PHYSICAL (1 << 9) |
280 | #define MLX4_MPT_FLAG_REGION (1 << 8) | 280 | #define MLX4_MPT_FLAG_REGION (1 << 8) |
281 | 281 | ||
282 | #define MLX4_MPT_PD_MASK (0x1FFFFUL) | ||
283 | #define MLX4_MPT_PD_VF_MASK (0xFE0000UL) | ||
282 | #define MLX4_MPT_PD_FLAG_FAST_REG (1 << 27) | 284 | #define MLX4_MPT_PD_FLAG_FAST_REG (1 << 27) |
283 | #define MLX4_MPT_PD_FLAG_RAE (1 << 28) | 285 | #define MLX4_MPT_PD_FLAG_RAE (1 << 28) |
284 | #define MLX4_MPT_PD_FLAG_EN_INV (3 << 24) | 286 | #define MLX4_MPT_PD_FLAG_EN_INV (3 << 24) |
@@ -1311,5 +1313,6 @@ void mlx4_init_quotas(struct mlx4_dev *dev); | |||
1311 | int mlx4_get_slave_num_gids(struct mlx4_dev *dev, int slave, int port); | 1313 | int mlx4_get_slave_num_gids(struct mlx4_dev *dev, int slave, int port); |
1312 | /* Returns the VF index of slave */ | 1314 | /* Returns the VF index of slave */ |
1313 | int mlx4_get_vf_indx(struct mlx4_dev *dev, int slave); | 1315 | int mlx4_get_vf_indx(struct mlx4_dev *dev, int slave); |
1316 | int mlx4_config_mad_demux(struct mlx4_dev *dev); | ||
1314 | 1317 | ||
1315 | #endif /* MLX4_H */ | 1318 | #endif /* MLX4_H */ |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c index 2839abb878a6..7d717eccb7b0 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/drivers/net/ethernet/mellanox/mlx4/mr.c | |||
@@ -298,6 +298,131 @@ static int mlx4_HW2SW_MPT(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox | |||
298 | MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED); | 298 | MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED); |
299 | } | 299 | } |
300 | 300 | ||
301 | int mlx4_mr_hw_get_mpt(struct mlx4_dev *dev, struct mlx4_mr *mmr, | ||
302 | struct mlx4_mpt_entry ***mpt_entry) | ||
303 | { | ||
304 | int err; | ||
305 | int key = key_to_hw_index(mmr->key) & (dev->caps.num_mpts - 1); | ||
306 | struct mlx4_cmd_mailbox *mailbox = NULL; | ||
307 | |||
308 | /* Make sure that at this point we have single-threaded access only */ | ||
309 | |||
310 | if (mmr->enabled != MLX4_MPT_EN_HW) | ||
311 | return -EINVAL; | ||
312 | |||
313 | err = mlx4_HW2SW_MPT(dev, NULL, key); | ||
314 | |||
315 | if (err) { | ||
316 | mlx4_warn(dev, "HW2SW_MPT failed (%d).", err); | ||
317 | mlx4_warn(dev, "Most likely the MR has MWs bound to it.\n"); | ||
318 | return err; | ||
319 | } | ||
320 | |||
321 | mmr->enabled = MLX4_MPT_EN_SW; | ||
322 | |||
323 | if (!mlx4_is_mfunc(dev)) { | ||
324 | **mpt_entry = mlx4_table_find( | ||
325 | &mlx4_priv(dev)->mr_table.dmpt_table, | ||
326 | key, NULL); | ||
327 | } else { | ||
328 | mailbox = mlx4_alloc_cmd_mailbox(dev); | ||
329 | if (IS_ERR_OR_NULL(mailbox)) | ||
330 | return PTR_ERR(mailbox); | ||
331 | |||
332 | err = mlx4_cmd_box(dev, 0, mailbox->dma, key, | ||
333 | 0, MLX4_CMD_QUERY_MPT, | ||
334 | MLX4_CMD_TIME_CLASS_B, | ||
335 | MLX4_CMD_WRAPPED); | ||
336 | |||
337 | if (err) | ||
338 | goto free_mailbox; | ||
339 | |||
340 | *mpt_entry = (struct mlx4_mpt_entry **)&mailbox->buf; | ||
341 | } | ||
342 | |||
343 | if (!(*mpt_entry) || !(**mpt_entry)) { | ||
344 | err = -ENOMEM; | ||
345 | goto free_mailbox; | ||
346 | } | ||
347 | |||
348 | return 0; | ||
349 | |||
350 | free_mailbox: | ||
351 | mlx4_free_cmd_mailbox(dev, mailbox); | ||
352 | return err; | ||
353 | } | ||
354 | EXPORT_SYMBOL_GPL(mlx4_mr_hw_get_mpt); | ||
355 | |||
356 | int mlx4_mr_hw_write_mpt(struct mlx4_dev *dev, struct mlx4_mr *mmr, | ||
357 | struct mlx4_mpt_entry **mpt_entry) | ||
358 | { | ||
359 | int err; | ||
360 | |||
361 | if (!mlx4_is_mfunc(dev)) { | ||
362 | /* Make sure any changes to this entry are flushed */ | ||
363 | wmb(); | ||
364 | |||
365 | *(u8 *)(*mpt_entry) = MLX4_MPT_STATUS_HW; | ||
366 | |||
367 | /* Make sure the new status is written */ | ||
368 | wmb(); | ||
369 | |||
370 | err = mlx4_SYNC_TPT(dev); | ||
371 | } else { | ||
372 | int key = key_to_hw_index(mmr->key) & (dev->caps.num_mpts - 1); | ||
373 | |||
374 | struct mlx4_cmd_mailbox *mailbox = | ||
375 | container_of((void *)mpt_entry, struct mlx4_cmd_mailbox, | ||
376 | buf); | ||
377 | |||
378 | err = mlx4_SW2HW_MPT(dev, mailbox, key); | ||
379 | } | ||
380 | |||
381 | mmr->pd = be32_to_cpu((*mpt_entry)->pd_flags) & MLX4_MPT_PD_MASK; | ||
382 | if (!err) | ||
383 | mmr->enabled = MLX4_MPT_EN_HW; | ||
384 | return err; | ||
385 | } | ||
386 | EXPORT_SYMBOL_GPL(mlx4_mr_hw_write_mpt); | ||
387 | |||
388 | void mlx4_mr_hw_put_mpt(struct mlx4_dev *dev, | ||
389 | struct mlx4_mpt_entry **mpt_entry) | ||
390 | { | ||
391 | if (mlx4_is_mfunc(dev)) { | ||
392 | struct mlx4_cmd_mailbox *mailbox = | ||
393 | container_of((void *)mpt_entry, struct mlx4_cmd_mailbox, | ||
394 | buf); | ||
395 | mlx4_free_cmd_mailbox(dev, mailbox); | ||
396 | } | ||
397 | } | ||
398 | EXPORT_SYMBOL_GPL(mlx4_mr_hw_put_mpt); | ||
399 | |||
400 | int mlx4_mr_hw_change_pd(struct mlx4_dev *dev, struct mlx4_mpt_entry *mpt_entry, | ||
401 | u32 pdn) | ||
402 | { | ||
403 | u32 pd_flags = be32_to_cpu(mpt_entry->pd_flags); | ||
404 | /* The wrapper function will put the slave's id here */ | ||
405 | if (mlx4_is_mfunc(dev)) | ||
406 | pd_flags &= ~MLX4_MPT_PD_VF_MASK; | ||
407 | mpt_entry->pd_flags = cpu_to_be32((pd_flags & ~MLX4_MPT_PD_MASK) | | ||
408 | (pdn & MLX4_MPT_PD_MASK) | ||
409 | | MLX4_MPT_PD_FLAG_EN_INV); | ||
410 | return 0; | ||
411 | } | ||
412 | EXPORT_SYMBOL_GPL(mlx4_mr_hw_change_pd); | ||
413 | |||
414 | int mlx4_mr_hw_change_access(struct mlx4_dev *dev, | ||
415 | struct mlx4_mpt_entry *mpt_entry, | ||
416 | u32 access) | ||
417 | { | ||
418 | u32 flags = (be32_to_cpu(mpt_entry->flags) & ~MLX4_PERM_MASK) | | ||
419 | (access & MLX4_PERM_MASK); | ||
420 | |||
421 | mpt_entry->flags = cpu_to_be32(flags); | ||
422 | return 0; | ||
423 | } | ||
424 | EXPORT_SYMBOL_GPL(mlx4_mr_hw_change_access); | ||
425 | |||
301 | static int mlx4_mr_alloc_reserved(struct mlx4_dev *dev, u32 mridx, u32 pd, | 426 | static int mlx4_mr_alloc_reserved(struct mlx4_dev *dev, u32 mridx, u32 pd, |
302 | u64 iova, u64 size, u32 access, int npages, | 427 | u64 iova, u64 size, u32 access, int npages, |
303 | int page_shift, struct mlx4_mr *mr) | 428 | int page_shift, struct mlx4_mr *mr) |
@@ -463,6 +588,41 @@ int mlx4_mr_free(struct mlx4_dev *dev, struct mlx4_mr *mr) | |||
463 | } | 588 | } |
464 | EXPORT_SYMBOL_GPL(mlx4_mr_free); | 589 | EXPORT_SYMBOL_GPL(mlx4_mr_free); |
465 | 590 | ||
591 | void mlx4_mr_rereg_mem_cleanup(struct mlx4_dev *dev, struct mlx4_mr *mr) | ||
592 | { | ||
593 | mlx4_mtt_cleanup(dev, &mr->mtt); | ||
594 | } | ||
595 | EXPORT_SYMBOL_GPL(mlx4_mr_rereg_mem_cleanup); | ||
596 | |||
597 | int mlx4_mr_rereg_mem_write(struct mlx4_dev *dev, struct mlx4_mr *mr, | ||
598 | u64 iova, u64 size, int npages, | ||
599 | int page_shift, struct mlx4_mpt_entry *mpt_entry) | ||
600 | { | ||
601 | int err; | ||
602 | |||
603 | mpt_entry->start = cpu_to_be64(mr->iova); | ||
604 | mpt_entry->length = cpu_to_be64(mr->size); | ||
605 | mpt_entry->entity_size = cpu_to_be32(mr->mtt.page_shift); | ||
606 | |||
607 | err = mlx4_mtt_init(dev, npages, page_shift, &mr->mtt); | ||
608 | if (err) | ||
609 | return err; | ||
610 | |||
611 | if (mr->mtt.order < 0) { | ||
612 | mpt_entry->flags |= cpu_to_be32(MLX4_MPT_FLAG_PHYSICAL); | ||
613 | mpt_entry->mtt_addr = 0; | ||
614 | } else { | ||
615 | mpt_entry->mtt_addr = cpu_to_be64(mlx4_mtt_addr(dev, | ||
616 | &mr->mtt)); | ||
617 | if (mr->mtt.page_shift == 0) | ||
618 | mpt_entry->mtt_sz = cpu_to_be32(1 << mr->mtt.order); | ||
619 | } | ||
620 | mr->enabled = MLX4_MPT_EN_SW; | ||
621 | |||
622 | return 0; | ||
623 | } | ||
624 | EXPORT_SYMBOL_GPL(mlx4_mr_rereg_mem_write); | ||
625 | |||
466 | int mlx4_mr_enable(struct mlx4_dev *dev, struct mlx4_mr *mr) | 626 | int mlx4_mr_enable(struct mlx4_dev *dev, struct mlx4_mr *mr) |
467 | { | 627 | { |
468 | struct mlx4_cmd_mailbox *mailbox; | 628 | struct mlx4_cmd_mailbox *mailbox; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 0efc1368e5a8..1089367fed22 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
@@ -2613,12 +2613,34 @@ int mlx4_QUERY_MPT_wrapper(struct mlx4_dev *dev, int slave, | |||
2613 | if (err) | 2613 | if (err) |
2614 | return err; | 2614 | return err; |
2615 | 2615 | ||
2616 | if (mpt->com.from_state != RES_MPT_HW) { | 2616 | if (mpt->com.from_state == RES_MPT_MAPPED) { |
2617 | /* In order to allow rereg in SRIOV, we need to alter the MPT entry. To do | ||
2618 | * that, the VF must read the MPT. But since the MPT entry memory is not | ||
2619 | * in the VF's virtual memory space, it must use QUERY_MPT to obtain the | ||
2620 | * entry contents. To guarantee that the MPT cannot be changed, the driver | ||
2621 | * must perform HW2SW_MPT before this query and return the MPT entry to HW | ||
2622 | * ownership fofollowing the change. The change here allows the VF to | ||
2623 | * perform QUERY_MPT also when the entry is in SW ownership. | ||
2624 | */ | ||
2625 | struct mlx4_mpt_entry *mpt_entry = mlx4_table_find( | ||
2626 | &mlx4_priv(dev)->mr_table.dmpt_table, | ||
2627 | mpt->key, NULL); | ||
2628 | |||
2629 | if (NULL == mpt_entry || NULL == outbox->buf) { | ||
2630 | err = -EINVAL; | ||
2631 | goto out; | ||
2632 | } | ||
2633 | |||
2634 | memcpy(outbox->buf, mpt_entry, sizeof(*mpt_entry)); | ||
2635 | |||
2636 | err = 0; | ||
2637 | } else if (mpt->com.from_state == RES_MPT_HW) { | ||
2638 | err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd); | ||
2639 | } else { | ||
2617 | err = -EBUSY; | 2640 | err = -EBUSY; |
2618 | goto out; | 2641 | goto out; |
2619 | } | 2642 | } |
2620 | 2643 | ||
2621 | err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd); | ||
2622 | 2644 | ||
2623 | out: | 2645 | out: |
2624 | put_res(dev, slave, id, RES_MPT); | 2646 | put_res(dev, slave, id, RES_MPT); |
diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c index 13e898332e45..a0c5bfdc5366 100644 --- a/drivers/scsi/scsi_transport_srp.c +++ b/drivers/scsi/scsi_transport_srp.c | |||
@@ -473,7 +473,8 @@ static void __srp_start_tl_fail_timers(struct srp_rport *rport) | |||
473 | if (delay > 0) | 473 | if (delay > 0) |
474 | queue_delayed_work(system_long_wq, &rport->reconnect_work, | 474 | queue_delayed_work(system_long_wq, &rport->reconnect_work, |
475 | 1UL * delay * HZ); | 475 | 1UL * delay * HZ); |
476 | if (srp_rport_set_state(rport, SRP_RPORT_BLOCKED) == 0) { | 476 | if ((fast_io_fail_tmo >= 0 || dev_loss_tmo >= 0) && |
477 | srp_rport_set_state(rport, SRP_RPORT_BLOCKED) == 0) { | ||
477 | pr_debug("%s new state: %d\n", dev_name(&shost->shost_gendev), | 478 | pr_debug("%s new state: %d\n", dev_name(&shost->shost_gendev), |
478 | rport->state); | 479 | rport->state); |
479 | scsi_target_block(&shost->shost_gendev); | 480 | scsi_target_block(&shost->shost_gendev); |