.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (c) 2004-2007 Intel Corporation. All rights reserved. |
---|
3 | 4 | * Copyright (c) 2004 Topspin Corporation. All rights reserved. |
---|
4 | 5 | * Copyright (c) 2004, 2005 Voltaire Corporation. All rights reserved. |
---|
5 | 6 | * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. |
---|
6 | | - * |
---|
7 | | - * This software is available to you under a choice of one of two |
---|
8 | | - * licenses. You may choose to be licensed under the terms of the GNU |
---|
9 | | - * General Public License (GPL) Version 2, available from the file |
---|
10 | | - * COPYING in the main directory of this source tree, or the |
---|
11 | | - * OpenIB.org BSD license below: |
---|
12 | | - * |
---|
13 | | - * Redistribution and use in source and binary forms, with or |
---|
14 | | - * without modification, are permitted provided that the following |
---|
15 | | - * conditions are met: |
---|
16 | | - * |
---|
17 | | - * - Redistributions of source code must retain the above |
---|
18 | | - * copyright notice, this list of conditions and the following |
---|
19 | | - * disclaimer. |
---|
20 | | - * |
---|
21 | | - * - Redistributions in binary form must reproduce the above |
---|
22 | | - * copyright notice, this list of conditions and the following |
---|
23 | | - * disclaimer in the documentation and/or other materials |
---|
24 | | - * provided with the distribution. |
---|
25 | | - * |
---|
26 | | - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
---|
27 | | - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
---|
28 | | - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
---|
29 | | - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
---|
30 | | - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
---|
31 | | - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
---|
32 | | - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
---|
33 | | - * SOFTWARE. |
---|
| 7 | + * Copyright (c) 2019, Mellanox Technologies inc. All rights reserved. |
---|
34 | 8 | */ |
---|
35 | 9 | |
---|
36 | 10 | #include <linux/completion.h> |
---|
.. | .. |
---|
52 | 26 | #include <rdma/ib_cache.h> |
---|
53 | 27 | #include <rdma/ib_cm.h> |
---|
54 | 28 | #include "cm_msgs.h" |
---|
| 29 | +#include "core_priv.h" |
---|
| 30 | +#include "cm_trace.h" |
---|
55 | 31 | |
---|
56 | 32 | MODULE_AUTHOR("Sean Hefty"); |
---|
57 | 33 | MODULE_DESCRIPTION("InfiniBand CM"); |
---|
.. | .. |
---|
91 | 67 | [IB_CM_REJ_INVALID_CLASS_VERSION] = "invalid class version", |
---|
92 | 68 | [IB_CM_REJ_INVALID_FLOW_LABEL] = "invalid flow label", |
---|
93 | 69 | [IB_CM_REJ_INVALID_ALT_FLOW_LABEL] = "invalid alt flow label", |
---|
| 70 | + [IB_CM_REJ_VENDOR_OPTION_NOT_SUPPORTED] = |
---|
| 71 | + "vendor option is not supported", |
---|
94 | 72 | }; |
---|
95 | 73 | |
---|
96 | 74 | const char *__attribute_const__ ibcm_reject_msg(int reason) |
---|
.. | .. |
---|
105 | 83 | } |
---|
106 | 84 | EXPORT_SYMBOL(ibcm_reject_msg); |
---|
107 | 85 | |
---|
108 | | -static void cm_add_one(struct ib_device *device); |
---|
| 86 | +struct cm_id_private; |
---|
| 87 | +struct cm_work; |
---|
| 88 | +static int cm_add_one(struct ib_device *device); |
---|
109 | 89 | static void cm_remove_one(struct ib_device *device, void *client_data); |
---|
| 90 | +static void cm_process_work(struct cm_id_private *cm_id_priv, |
---|
| 91 | + struct cm_work *work); |
---|
| 92 | +static int cm_send_sidr_rep_locked(struct cm_id_private *cm_id_priv, |
---|
| 93 | + struct ib_cm_sidr_rep_param *param); |
---|
| 94 | +static int cm_send_dreq_locked(struct cm_id_private *cm_id_priv, |
---|
| 95 | + const void *private_data, u8 private_data_len); |
---|
| 96 | +static int cm_send_drep_locked(struct cm_id_private *cm_id_priv, |
---|
| 97 | + void *private_data, u8 private_data_len); |
---|
| 98 | +static int cm_send_rej_locked(struct cm_id_private *cm_id_priv, |
---|
| 99 | + enum ib_cm_rej_reason reason, void *ari, |
---|
| 100 | + u8 ari_length, const void *private_data, |
---|
| 101 | + u8 private_data_len); |
---|
110 | 102 | |
---|
111 | 103 | static struct ib_client cm_client = { |
---|
112 | 104 | .name = "cm", |
---|
.. | .. |
---|
124 | 116 | struct rb_root remote_qp_table; |
---|
125 | 117 | struct rb_root remote_id_table; |
---|
126 | 118 | struct rb_root remote_sidr_table; |
---|
127 | | - struct idr local_id_table; |
---|
| 119 | + struct xarray local_id_table; |
---|
| 120 | + u32 local_id_next; |
---|
128 | 121 | __be32 random_id_operand; |
---|
129 | 122 | struct list_head timewait_list; |
---|
130 | 123 | struct workqueue_struct *wq; |
---|
.. | .. |
---|
209 | 202 | struct cm_port { |
---|
210 | 203 | struct cm_device *cm_dev; |
---|
211 | 204 | struct ib_mad_agent *mad_agent; |
---|
212 | | - struct kobject port_obj; |
---|
213 | 205 | u8 port_num; |
---|
214 | 206 | struct list_head cm_priv_prim_list; |
---|
215 | 207 | struct list_head cm_priv_altr_list; |
---|
.. | .. |
---|
219 | 211 | struct cm_device { |
---|
220 | 212 | struct list_head list; |
---|
221 | 213 | struct ib_device *ib_device; |
---|
222 | | - struct device *device; |
---|
223 | 214 | u8 ack_delay; |
---|
224 | 215 | int going_down; |
---|
225 | | - struct cm_port *port[0]; |
---|
| 216 | + struct cm_port *port[]; |
---|
226 | 217 | }; |
---|
227 | 218 | |
---|
228 | 219 | struct cm_av { |
---|
.. | .. |
---|
241 | 232 | __be32 local_id; /* Established / timewait */ |
---|
242 | 233 | __be32 remote_id; |
---|
243 | 234 | struct ib_cm_event cm_event; |
---|
244 | | - struct sa_path_rec path[0]; |
---|
| 235 | + struct sa_path_rec path[]; |
---|
245 | 236 | }; |
---|
246 | 237 | |
---|
247 | 238 | struct cm_timewait_info { |
---|
248 | | - struct cm_work work; /* Must be first. */ |
---|
| 239 | + struct cm_work work; |
---|
249 | 240 | struct list_head list; |
---|
250 | 241 | struct rb_node remote_qp_node; |
---|
251 | 242 | struct rb_node remote_id_node; |
---|
.. | .. |
---|
262 | 253 | struct rb_node sidr_id_node; |
---|
263 | 254 | spinlock_t lock; /* Do not acquire inside cm.lock */ |
---|
264 | 255 | struct completion comp; |
---|
265 | | - atomic_t refcount; |
---|
| 256 | + refcount_t refcount; |
---|
266 | 257 | /* Number of clients sharing this ib_cm_id. Only valid for listeners. |
---|
267 | 258 | * Protected by the cm.lock spinlock. */ |
---|
268 | 259 | int listen_sharecount; |
---|
| 260 | + struct rcu_head rcu; |
---|
269 | 261 | |
---|
270 | 262 | struct ib_mad_send_buf *msg; |
---|
271 | 263 | struct cm_timewait_info *timewait_info; |
---|
.. | .. |
---|
285 | 277 | __be16 pkey; |
---|
286 | 278 | u8 private_data_len; |
---|
287 | 279 | u8 max_cm_retries; |
---|
288 | | - u8 peer_to_peer; |
---|
289 | 280 | u8 responder_resources; |
---|
290 | 281 | u8 initiator_depth; |
---|
291 | 282 | u8 retry_count; |
---|
.. | .. |
---|
301 | 292 | |
---|
302 | 293 | struct list_head work_list; |
---|
303 | 294 | atomic_t work_count; |
---|
| 295 | + |
---|
| 296 | + struct rdma_ucm_ece ece; |
---|
304 | 297 | }; |
---|
305 | 298 | |
---|
306 | 299 | static void cm_work_handler(struct work_struct *work); |
---|
307 | 300 | |
---|
308 | 301 | static inline void cm_deref_id(struct cm_id_private *cm_id_priv) |
---|
309 | 302 | { |
---|
310 | | - if (atomic_dec_and_test(&cm_id_priv->refcount)) |
---|
| 303 | + if (refcount_dec_and_test(&cm_id_priv->refcount)) |
---|
311 | 304 | complete(&cm_id_priv->comp); |
---|
312 | 305 | } |
---|
313 | 306 | |
---|
.. | .. |
---|
343 | 336 | ret = -ENODEV; |
---|
344 | 337 | goto out; |
---|
345 | 338 | } |
---|
346 | | - ah = rdma_create_ah(mad_agent->qp->pd, &av->ah_attr); |
---|
| 339 | + ah = rdma_create_ah(mad_agent->qp->pd, &av->ah_attr, 0); |
---|
347 | 340 | if (IS_ERR(ah)) { |
---|
348 | 341 | ret = PTR_ERR(ah); |
---|
349 | 342 | goto out; |
---|
.. | .. |
---|
355 | 348 | GFP_ATOMIC, |
---|
356 | 349 | IB_MGMT_BASE_VERSION); |
---|
357 | 350 | if (IS_ERR(m)) { |
---|
358 | | - rdma_destroy_ah(ah); |
---|
| 351 | + rdma_destroy_ah(ah, 0); |
---|
359 | 352 | ret = PTR_ERR(m); |
---|
360 | 353 | goto out; |
---|
361 | 354 | } |
---|
.. | .. |
---|
364 | 357 | m->ah = ah; |
---|
365 | 358 | m->retries = cm_id_priv->max_cm_retries; |
---|
366 | 359 | |
---|
367 | | - atomic_inc(&cm_id_priv->refcount); |
---|
| 360 | + refcount_inc(&cm_id_priv->refcount); |
---|
368 | 361 | m->context[0] = cm_id_priv; |
---|
369 | 362 | *msg = m; |
---|
370 | 363 | |
---|
.. | .. |
---|
400 | 393 | static void cm_free_msg(struct ib_mad_send_buf *msg) |
---|
401 | 394 | { |
---|
402 | 395 | if (msg->ah) |
---|
403 | | - rdma_destroy_ah(msg->ah); |
---|
| 396 | + rdma_destroy_ah(msg->ah, 0); |
---|
404 | 397 | if (msg->context[0]) |
---|
405 | 398 | cm_deref_id(msg->context[0]); |
---|
406 | 399 | ib_free_send_mad(msg); |
---|
.. | .. |
---|
488 | 481 | grh, &av->ah_attr); |
---|
489 | 482 | } |
---|
490 | 483 | |
---|
491 | | -static int add_cm_id_to_port_list(struct cm_id_private *cm_id_priv, |
---|
492 | | - struct cm_av *av, |
---|
493 | | - struct cm_port *port) |
---|
| 484 | +static void add_cm_id_to_port_list(struct cm_id_private *cm_id_priv, |
---|
| 485 | + struct cm_av *av, struct cm_port *port) |
---|
494 | 486 | { |
---|
495 | 487 | unsigned long flags; |
---|
496 | | - int ret = 0; |
---|
497 | 488 | |
---|
498 | 489 | spin_lock_irqsave(&cm.lock, flags); |
---|
499 | | - |
---|
500 | 490 | if (&cm_id_priv->av == av) |
---|
501 | 491 | list_add_tail(&cm_id_priv->prim_list, &port->cm_priv_prim_list); |
---|
502 | 492 | else if (&cm_id_priv->alt_av == av) |
---|
503 | 493 | list_add_tail(&cm_id_priv->altr_list, &port->cm_priv_altr_list); |
---|
504 | 494 | else |
---|
505 | | - ret = -EINVAL; |
---|
506 | | - |
---|
| 495 | + WARN_ON(true); |
---|
507 | 496 | spin_unlock_irqrestore(&cm.lock, flags); |
---|
508 | | - return ret; |
---|
509 | 497 | } |
---|
510 | 498 | |
---|
511 | 499 | static struct cm_port * |
---|
.. | .. |
---|
586 | 574 | return ret; |
---|
587 | 575 | |
---|
588 | 576 | av->timeout = path->packet_life_time + 1; |
---|
589 | | - |
---|
590 | | - ret = add_cm_id_to_port_list(cm_id_priv, av, port); |
---|
591 | | - if (ret) { |
---|
592 | | - rdma_destroy_ah_attr(&new_ah_attr); |
---|
593 | | - return ret; |
---|
594 | | - } |
---|
| 577 | + add_cm_id_to_port_list(cm_id_priv, av, port); |
---|
595 | 578 | rdma_move_ah_attr(&av->ah_attr, &new_ah_attr); |
---|
596 | 579 | return 0; |
---|
597 | 580 | } |
---|
598 | 581 | |
---|
599 | | -static int cm_alloc_id(struct cm_id_private *cm_id_priv) |
---|
| 582 | +static u32 cm_local_id(__be32 local_id) |
---|
600 | 583 | { |
---|
601 | | - unsigned long flags; |
---|
602 | | - int id; |
---|
603 | | - |
---|
604 | | - idr_preload(GFP_KERNEL); |
---|
605 | | - spin_lock_irqsave(&cm.lock, flags); |
---|
606 | | - |
---|
607 | | - id = idr_alloc_cyclic(&cm.local_id_table, cm_id_priv, 0, 0, GFP_NOWAIT); |
---|
608 | | - |
---|
609 | | - spin_unlock_irqrestore(&cm.lock, flags); |
---|
610 | | - idr_preload_end(); |
---|
611 | | - |
---|
612 | | - cm_id_priv->id.local_id = (__force __be32)id ^ cm.random_id_operand; |
---|
613 | | - return id < 0 ? id : 0; |
---|
| 584 | + return (__force u32) (local_id ^ cm.random_id_operand); |
---|
614 | 585 | } |
---|
615 | 586 | |
---|
616 | | -static void cm_free_id(__be32 local_id) |
---|
617 | | -{ |
---|
618 | | - spin_lock_irq(&cm.lock); |
---|
619 | | - idr_remove(&cm.local_id_table, |
---|
620 | | - (__force int) (local_id ^ cm.random_id_operand)); |
---|
621 | | - spin_unlock_irq(&cm.lock); |
---|
622 | | -} |
---|
623 | | - |
---|
624 | | -static struct cm_id_private * cm_get_id(__be32 local_id, __be32 remote_id) |
---|
| 587 | +static struct cm_id_private *cm_acquire_id(__be32 local_id, __be32 remote_id) |
---|
625 | 588 | { |
---|
626 | 589 | struct cm_id_private *cm_id_priv; |
---|
627 | 590 | |
---|
628 | | - cm_id_priv = idr_find(&cm.local_id_table, |
---|
629 | | - (__force int) (local_id ^ cm.random_id_operand)); |
---|
630 | | - if (cm_id_priv) { |
---|
631 | | - if (cm_id_priv->id.remote_id == remote_id) |
---|
632 | | - atomic_inc(&cm_id_priv->refcount); |
---|
633 | | - else |
---|
634 | | - cm_id_priv = NULL; |
---|
635 | | - } |
---|
636 | | - |
---|
637 | | - return cm_id_priv; |
---|
638 | | -} |
---|
639 | | - |
---|
640 | | -static struct cm_id_private * cm_acquire_id(__be32 local_id, __be32 remote_id) |
---|
641 | | -{ |
---|
642 | | - struct cm_id_private *cm_id_priv; |
---|
643 | | - |
---|
644 | | - spin_lock_irq(&cm.lock); |
---|
645 | | - cm_id_priv = cm_get_id(local_id, remote_id); |
---|
646 | | - spin_unlock_irq(&cm.lock); |
---|
| 591 | + rcu_read_lock(); |
---|
| 592 | + cm_id_priv = xa_load(&cm.local_id_table, cm_local_id(local_id)); |
---|
| 593 | + if (!cm_id_priv || cm_id_priv->id.remote_id != remote_id || |
---|
| 594 | + !refcount_inc_not_zero(&cm_id_priv->refcount)) |
---|
| 595 | + cm_id_priv = NULL; |
---|
| 596 | + rcu_read_unlock(); |
---|
647 | 597 | |
---|
648 | 598 | return cm_id_priv; |
---|
649 | 599 | } |
---|
.. | .. |
---|
673 | 623 | return (__force u64) a > (__force u64) b; |
---|
674 | 624 | } |
---|
675 | 625 | |
---|
676 | | -static struct cm_id_private * cm_insert_listen(struct cm_id_private *cm_id_priv) |
---|
| 626 | +/* |
---|
| 627 | + * Inserts a new cm_id_priv into the listen_service_table. Returns cm_id_priv |
---|
| 628 | + * if the new ID was inserted, NULL if it could not be inserted due to a |
---|
| 629 | + * collision, or the existing cm_id_priv ready for shared usage. |
---|
| 630 | + */ |
---|
| 631 | +static struct cm_id_private *cm_insert_listen(struct cm_id_private *cm_id_priv, |
---|
| 632 | + ib_cm_handler shared_handler) |
---|
677 | 633 | { |
---|
678 | 634 | struct rb_node **link = &cm.listen_service_table.rb_node; |
---|
679 | 635 | struct rb_node *parent = NULL; |
---|
680 | 636 | struct cm_id_private *cur_cm_id_priv; |
---|
681 | 637 | __be64 service_id = cm_id_priv->id.service_id; |
---|
682 | 638 | __be64 service_mask = cm_id_priv->id.service_mask; |
---|
| 639 | + unsigned long flags; |
---|
683 | 640 | |
---|
| 641 | + spin_lock_irqsave(&cm.lock, flags); |
---|
684 | 642 | while (*link) { |
---|
685 | 643 | parent = *link; |
---|
686 | 644 | cur_cm_id_priv = rb_entry(parent, struct cm_id_private, |
---|
687 | 645 | service_node); |
---|
688 | 646 | if ((cur_cm_id_priv->id.service_mask & service_id) == |
---|
689 | 647 | (service_mask & cur_cm_id_priv->id.service_id) && |
---|
690 | | - (cm_id_priv->id.device == cur_cm_id_priv->id.device)) |
---|
| 648 | + (cm_id_priv->id.device == cur_cm_id_priv->id.device)) { |
---|
| 649 | + /* |
---|
| 650 | + * Sharing an ib_cm_id with different handlers is not |
---|
| 651 | + * supported |
---|
| 652 | + */ |
---|
| 653 | + if (cur_cm_id_priv->id.cm_handler != shared_handler || |
---|
| 654 | + cur_cm_id_priv->id.context || |
---|
| 655 | + WARN_ON(!cur_cm_id_priv->id.cm_handler)) { |
---|
| 656 | + spin_unlock_irqrestore(&cm.lock, flags); |
---|
| 657 | + return NULL; |
---|
| 658 | + } |
---|
| 659 | + refcount_inc(&cur_cm_id_priv->refcount); |
---|
| 660 | + cur_cm_id_priv->listen_sharecount++; |
---|
| 661 | + spin_unlock_irqrestore(&cm.lock, flags); |
---|
691 | 662 | return cur_cm_id_priv; |
---|
| 663 | + } |
---|
692 | 664 | |
---|
693 | 665 | if (cm_id_priv->id.device < cur_cm_id_priv->id.device) |
---|
694 | 666 | link = &(*link)->rb_left; |
---|
.. | .. |
---|
701 | 673 | else |
---|
702 | 674 | link = &(*link)->rb_right; |
---|
703 | 675 | } |
---|
| 676 | + cm_id_priv->listen_sharecount++; |
---|
704 | 677 | rb_link_node(&cm_id_priv->service_node, parent, link); |
---|
705 | 678 | rb_insert_color(&cm_id_priv->service_node, &cm.listen_service_table); |
---|
706 | | - return NULL; |
---|
| 679 | + spin_unlock_irqrestore(&cm.lock, flags); |
---|
| 680 | + return cm_id_priv; |
---|
707 | 681 | } |
---|
708 | 682 | |
---|
709 | 683 | static struct cm_id_private * cm_find_listen(struct ib_device *device, |
---|
.. | .. |
---|
716 | 690 | cm_id_priv = rb_entry(node, struct cm_id_private, service_node); |
---|
717 | 691 | if ((cm_id_priv->id.service_mask & service_id) == |
---|
718 | 692 | cm_id_priv->id.service_id && |
---|
719 | | - (cm_id_priv->id.device == device)) |
---|
| 693 | + (cm_id_priv->id.device == device)) { |
---|
| 694 | + refcount_inc(&cm_id_priv->refcount); |
---|
720 | 695 | return cm_id_priv; |
---|
721 | | - |
---|
| 696 | + } |
---|
722 | 697 | if (device < cm_id_priv->id.device) |
---|
723 | 698 | node = node->rb_left; |
---|
724 | 699 | else if (device > cm_id_priv->id.device) |
---|
.. | .. |
---|
763 | 738 | return NULL; |
---|
764 | 739 | } |
---|
765 | 740 | |
---|
766 | | -static struct cm_timewait_info * cm_find_remote_id(__be64 remote_ca_guid, |
---|
767 | | - __be32 remote_id) |
---|
| 741 | +static struct cm_id_private *cm_find_remote_id(__be64 remote_ca_guid, |
---|
| 742 | + __be32 remote_id) |
---|
768 | 743 | { |
---|
769 | 744 | struct rb_node *node = cm.remote_id_table.rb_node; |
---|
770 | 745 | struct cm_timewait_info *timewait_info; |
---|
| 746 | + struct cm_id_private *res = NULL; |
---|
771 | 747 | |
---|
| 748 | + spin_lock_irq(&cm.lock); |
---|
772 | 749 | while (node) { |
---|
773 | 750 | timewait_info = rb_entry(node, struct cm_timewait_info, |
---|
774 | 751 | remote_id_node); |
---|
.. | .. |
---|
780 | 757 | node = node->rb_left; |
---|
781 | 758 | else if (be64_gt(remote_ca_guid, timewait_info->remote_ca_guid)) |
---|
782 | 759 | node = node->rb_right; |
---|
783 | | - else |
---|
784 | | - return timewait_info; |
---|
| 760 | + else { |
---|
| 761 | + res = cm_acquire_id(timewait_info->work.local_id, |
---|
| 762 | + timewait_info->work.remote_id); |
---|
| 763 | + break; |
---|
| 764 | + } |
---|
785 | 765 | } |
---|
786 | | - return NULL; |
---|
| 766 | + spin_unlock_irq(&cm.lock); |
---|
| 767 | + return res; |
---|
787 | 768 | } |
---|
788 | 769 | |
---|
789 | 770 | static struct cm_timewait_info * cm_insert_remote_qpn(struct cm_timewait_info |
---|
.. | .. |
---|
850 | 831 | return NULL; |
---|
851 | 832 | } |
---|
852 | 833 | |
---|
853 | | -static void cm_reject_sidr_req(struct cm_id_private *cm_id_priv, |
---|
854 | | - enum ib_cm_sidr_status status) |
---|
855 | | -{ |
---|
856 | | - struct ib_cm_sidr_rep_param param; |
---|
857 | | - |
---|
858 | | - memset(¶m, 0, sizeof param); |
---|
859 | | - param.status = status; |
---|
860 | | - ib_send_cm_sidr_rep(&cm_id_priv->id, ¶m); |
---|
861 | | -} |
---|
862 | | - |
---|
863 | | -struct ib_cm_id *ib_create_cm_id(struct ib_device *device, |
---|
864 | | - ib_cm_handler cm_handler, |
---|
865 | | - void *context) |
---|
| 834 | +static struct cm_id_private *cm_alloc_id_priv(struct ib_device *device, |
---|
| 835 | + ib_cm_handler cm_handler, |
---|
| 836 | + void *context) |
---|
866 | 837 | { |
---|
867 | 838 | struct cm_id_private *cm_id_priv; |
---|
| 839 | + u32 id; |
---|
868 | 840 | int ret; |
---|
869 | 841 | |
---|
870 | 842 | cm_id_priv = kzalloc(sizeof *cm_id_priv, GFP_KERNEL); |
---|
.. | .. |
---|
876 | 848 | cm_id_priv->id.cm_handler = cm_handler; |
---|
877 | 849 | cm_id_priv->id.context = context; |
---|
878 | 850 | cm_id_priv->id.remote_cm_qpn = 1; |
---|
879 | | - ret = cm_alloc_id(cm_id_priv); |
---|
880 | | - if (ret) |
---|
881 | | - goto error; |
---|
882 | 851 | |
---|
| 852 | + RB_CLEAR_NODE(&cm_id_priv->service_node); |
---|
| 853 | + RB_CLEAR_NODE(&cm_id_priv->sidr_id_node); |
---|
883 | 854 | spin_lock_init(&cm_id_priv->lock); |
---|
884 | 855 | init_completion(&cm_id_priv->comp); |
---|
885 | 856 | INIT_LIST_HEAD(&cm_id_priv->work_list); |
---|
886 | 857 | INIT_LIST_HEAD(&cm_id_priv->prim_list); |
---|
887 | 858 | INIT_LIST_HEAD(&cm_id_priv->altr_list); |
---|
888 | 859 | atomic_set(&cm_id_priv->work_count, -1); |
---|
889 | | - atomic_set(&cm_id_priv->refcount, 1); |
---|
890 | | - return &cm_id_priv->id; |
---|
| 860 | + refcount_set(&cm_id_priv->refcount, 1); |
---|
| 861 | + |
---|
| 862 | + ret = xa_alloc_cyclic(&cm.local_id_table, &id, NULL, xa_limit_32b, |
---|
| 863 | + &cm.local_id_next, GFP_KERNEL); |
---|
| 864 | + if (ret < 0) |
---|
| 865 | + goto error; |
---|
| 866 | + cm_id_priv->id.local_id = (__force __be32)id ^ cm.random_id_operand; |
---|
| 867 | + |
---|
| 868 | + return cm_id_priv; |
---|
891 | 869 | |
---|
892 | 870 | error: |
---|
893 | 871 | kfree(cm_id_priv); |
---|
894 | | - return ERR_PTR(-ENOMEM); |
---|
| 872 | + return ERR_PTR(ret); |
---|
| 873 | +} |
---|
| 874 | + |
---|
| 875 | +/* |
---|
| 876 | + * Make the ID visible to the MAD handlers and other threads that use the |
---|
| 877 | + * xarray. |
---|
| 878 | + */ |
---|
| 879 | +static void cm_finalize_id(struct cm_id_private *cm_id_priv) |
---|
| 880 | +{ |
---|
| 881 | + xa_store(&cm.local_id_table, cm_local_id(cm_id_priv->id.local_id), |
---|
| 882 | + cm_id_priv, GFP_ATOMIC); |
---|
| 883 | +} |
---|
| 884 | + |
---|
| 885 | +struct ib_cm_id *ib_create_cm_id(struct ib_device *device, |
---|
| 886 | + ib_cm_handler cm_handler, |
---|
| 887 | + void *context) |
---|
| 888 | +{ |
---|
| 889 | + struct cm_id_private *cm_id_priv; |
---|
| 890 | + |
---|
| 891 | + cm_id_priv = cm_alloc_id_priv(device, cm_handler, context); |
---|
| 892 | + if (IS_ERR(cm_id_priv)) |
---|
| 893 | + return ERR_CAST(cm_id_priv); |
---|
| 894 | + |
---|
| 895 | + cm_finalize_id(cm_id_priv); |
---|
| 896 | + return &cm_id_priv->id; |
---|
895 | 897 | } |
---|
896 | 898 | EXPORT_SYMBOL(ib_create_cm_id); |
---|
897 | 899 | |
---|
.. | .. |
---|
912 | 914 | if (work->mad_recv_wc) |
---|
913 | 915 | ib_free_recv_mad(work->mad_recv_wc); |
---|
914 | 916 | kfree(work); |
---|
| 917 | +} |
---|
| 918 | + |
---|
| 919 | +static void cm_queue_work_unlock(struct cm_id_private *cm_id_priv, |
---|
| 920 | + struct cm_work *work) |
---|
| 921 | + __releases(&cm_id_priv->lock) |
---|
| 922 | +{ |
---|
| 923 | + bool immediate; |
---|
| 924 | + |
---|
| 925 | + /* |
---|
| 926 | + * To deliver the event to the user callback we have the drop the |
---|
| 927 | + * spinlock, however, we need to ensure that the user callback is single |
---|
| 928 | + * threaded and receives events in the temporal order. If there are |
---|
| 929 | + * already events being processed then thread new events onto a list, |
---|
| 930 | + * the thread currently processing will pick them up. |
---|
| 931 | + */ |
---|
| 932 | + immediate = atomic_inc_and_test(&cm_id_priv->work_count); |
---|
| 933 | + if (!immediate) { |
---|
| 934 | + list_add_tail(&work->list, &cm_id_priv->work_list); |
---|
| 935 | + /* |
---|
| 936 | + * This routine always consumes incoming reference. Once queued |
---|
| 937 | + * to the work_list then a reference is held by the thread |
---|
| 938 | + * currently running cm_process_work() and this reference is not |
---|
| 939 | + * needed. |
---|
| 940 | + */ |
---|
| 941 | + cm_deref_id(cm_id_priv); |
---|
| 942 | + } |
---|
| 943 | + spin_unlock_irq(&cm_id_priv->lock); |
---|
| 944 | + |
---|
| 945 | + if (immediate) |
---|
| 946 | + cm_process_work(cm_id_priv, work); |
---|
915 | 947 | } |
---|
916 | 948 | |
---|
917 | 949 | static inline int cm_convert_to_ms(int iba_time) |
---|
.. | .. |
---|
939 | 971 | return min(31, ack_timeout); |
---|
940 | 972 | } |
---|
941 | 973 | |
---|
942 | | -static void cm_cleanup_timewait(struct cm_timewait_info *timewait_info) |
---|
| 974 | +static void cm_remove_remote(struct cm_id_private *cm_id_priv) |
---|
943 | 975 | { |
---|
| 976 | + struct cm_timewait_info *timewait_info = cm_id_priv->timewait_info; |
---|
| 977 | + |
---|
944 | 978 | if (timewait_info->inserted_remote_id) { |
---|
945 | 979 | rb_erase(&timewait_info->remote_id_node, &cm.remote_id_table); |
---|
946 | 980 | timewait_info->inserted_remote_id = 0; |
---|
.. | .. |
---|
972 | 1006 | unsigned long flags; |
---|
973 | 1007 | struct cm_device *cm_dev; |
---|
974 | 1008 | |
---|
| 1009 | + lockdep_assert_held(&cm_id_priv->lock); |
---|
| 1010 | + |
---|
975 | 1011 | cm_dev = ib_get_client_data(cm_id_priv->id.device, &cm_client); |
---|
976 | 1012 | if (!cm_dev) |
---|
977 | 1013 | return; |
---|
978 | 1014 | |
---|
979 | 1015 | spin_lock_irqsave(&cm.lock, flags); |
---|
980 | | - cm_cleanup_timewait(cm_id_priv->timewait_info); |
---|
| 1016 | + cm_remove_remote(cm_id_priv); |
---|
981 | 1017 | list_add_tail(&cm_id_priv->timewait_info->list, &cm.timewait_list); |
---|
982 | 1018 | spin_unlock_irqrestore(&cm.lock, flags); |
---|
983 | 1019 | |
---|
.. | .. |
---|
996 | 1032 | msecs_to_jiffies(wait_time)); |
---|
997 | 1033 | spin_unlock_irqrestore(&cm.lock, flags); |
---|
998 | 1034 | |
---|
| 1035 | + /* |
---|
| 1036 | + * The timewait_info is converted into a work and gets freed during |
---|
| 1037 | + * cm_free_work() in cm_timewait_handler(). |
---|
| 1038 | + */ |
---|
| 1039 | + BUILD_BUG_ON(offsetof(struct cm_timewait_info, work) != 0); |
---|
999 | 1040 | cm_id_priv->timewait_info = NULL; |
---|
1000 | 1041 | } |
---|
1001 | 1042 | |
---|
.. | .. |
---|
1003 | 1044 | { |
---|
1004 | 1045 | unsigned long flags; |
---|
1005 | 1046 | |
---|
| 1047 | + lockdep_assert_held(&cm_id_priv->lock); |
---|
| 1048 | + |
---|
1006 | 1049 | cm_id_priv->id.state = IB_CM_IDLE; |
---|
1007 | 1050 | if (cm_id_priv->timewait_info) { |
---|
1008 | 1051 | spin_lock_irqsave(&cm.lock, flags); |
---|
1009 | | - cm_cleanup_timewait(cm_id_priv->timewait_info); |
---|
| 1052 | + cm_remove_remote(cm_id_priv); |
---|
1010 | 1053 | spin_unlock_irqrestore(&cm.lock, flags); |
---|
1011 | 1054 | kfree(cm_id_priv->timewait_info); |
---|
1012 | 1055 | cm_id_priv->timewait_info = NULL; |
---|
.. | .. |
---|
1019 | 1062 | struct cm_work *work; |
---|
1020 | 1063 | |
---|
1021 | 1064 | cm_id_priv = container_of(cm_id, struct cm_id_private, id); |
---|
1022 | | -retest: |
---|
1023 | 1065 | spin_lock_irq(&cm_id_priv->lock); |
---|
| 1066 | +retest: |
---|
1024 | 1067 | switch (cm_id->state) { |
---|
1025 | 1068 | case IB_CM_LISTEN: |
---|
1026 | | - spin_unlock_irq(&cm_id_priv->lock); |
---|
1027 | | - |
---|
1028 | | - spin_lock_irq(&cm.lock); |
---|
| 1069 | + spin_lock(&cm.lock); |
---|
1029 | 1070 | if (--cm_id_priv->listen_sharecount > 0) { |
---|
1030 | 1071 | /* The id is still shared. */ |
---|
| 1072 | + WARN_ON(refcount_read(&cm_id_priv->refcount) == 1); |
---|
| 1073 | + spin_unlock(&cm.lock); |
---|
| 1074 | + spin_unlock_irq(&cm_id_priv->lock); |
---|
1031 | 1075 | cm_deref_id(cm_id_priv); |
---|
1032 | | - spin_unlock_irq(&cm.lock); |
---|
1033 | 1076 | return; |
---|
1034 | 1077 | } |
---|
| 1078 | + cm_id->state = IB_CM_IDLE; |
---|
1035 | 1079 | rb_erase(&cm_id_priv->service_node, &cm.listen_service_table); |
---|
1036 | | - spin_unlock_irq(&cm.lock); |
---|
| 1080 | + RB_CLEAR_NODE(&cm_id_priv->service_node); |
---|
| 1081 | + spin_unlock(&cm.lock); |
---|
1037 | 1082 | break; |
---|
1038 | 1083 | case IB_CM_SIDR_REQ_SENT: |
---|
1039 | 1084 | cm_id->state = IB_CM_IDLE; |
---|
1040 | 1085 | ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); |
---|
1041 | | - spin_unlock_irq(&cm_id_priv->lock); |
---|
1042 | 1086 | break; |
---|
1043 | 1087 | case IB_CM_SIDR_REQ_RCVD: |
---|
1044 | | - spin_unlock_irq(&cm_id_priv->lock); |
---|
1045 | | - cm_reject_sidr_req(cm_id_priv, IB_SIDR_REJECT); |
---|
1046 | | - spin_lock_irq(&cm.lock); |
---|
1047 | | - if (!RB_EMPTY_NODE(&cm_id_priv->sidr_id_node)) |
---|
1048 | | - rb_erase(&cm_id_priv->sidr_id_node, |
---|
1049 | | - &cm.remote_sidr_table); |
---|
1050 | | - spin_unlock_irq(&cm.lock); |
---|
| 1088 | + cm_send_sidr_rep_locked(cm_id_priv, |
---|
| 1089 | + &(struct ib_cm_sidr_rep_param){ |
---|
| 1090 | + .status = IB_SIDR_REJECT }); |
---|
| 1091 | + /* cm_send_sidr_rep_locked will not move to IDLE if it fails */ |
---|
| 1092 | + cm_id->state = IB_CM_IDLE; |
---|
1051 | 1093 | break; |
---|
1052 | 1094 | case IB_CM_REQ_SENT: |
---|
1053 | 1095 | case IB_CM_MRA_REQ_RCVD: |
---|
1054 | 1096 | ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); |
---|
1055 | | - spin_unlock_irq(&cm_id_priv->lock); |
---|
1056 | | - ib_send_cm_rej(cm_id, IB_CM_REJ_TIMEOUT, |
---|
1057 | | - &cm_id_priv->id.device->node_guid, |
---|
1058 | | - sizeof cm_id_priv->id.device->node_guid, |
---|
1059 | | - NULL, 0); |
---|
| 1097 | + cm_send_rej_locked(cm_id_priv, IB_CM_REJ_TIMEOUT, |
---|
| 1098 | + &cm_id_priv->id.device->node_guid, |
---|
| 1099 | + sizeof(cm_id_priv->id.device->node_guid), |
---|
| 1100 | + NULL, 0); |
---|
1060 | 1101 | break; |
---|
1061 | 1102 | case IB_CM_REQ_RCVD: |
---|
1062 | 1103 | if (err == -ENOMEM) { |
---|
1063 | 1104 | /* Do not reject to allow future retries. */ |
---|
1064 | 1105 | cm_reset_to_idle(cm_id_priv); |
---|
1065 | | - spin_unlock_irq(&cm_id_priv->lock); |
---|
1066 | 1106 | } else { |
---|
1067 | | - spin_unlock_irq(&cm_id_priv->lock); |
---|
1068 | | - ib_send_cm_rej(cm_id, IB_CM_REJ_CONSUMER_DEFINED, |
---|
1069 | | - NULL, 0, NULL, 0); |
---|
| 1107 | + cm_send_rej_locked(cm_id_priv, |
---|
| 1108 | + IB_CM_REJ_CONSUMER_DEFINED, NULL, 0, |
---|
| 1109 | + NULL, 0); |
---|
1070 | 1110 | } |
---|
1071 | 1111 | break; |
---|
1072 | 1112 | case IB_CM_REP_SENT: |
---|
1073 | 1113 | case IB_CM_MRA_REP_RCVD: |
---|
1074 | 1114 | ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); |
---|
1075 | | - /* Fall through */ |
---|
| 1115 | + cm_send_rej_locked(cm_id_priv, IB_CM_REJ_CONSUMER_DEFINED, NULL, |
---|
| 1116 | + 0, NULL, 0); |
---|
| 1117 | + goto retest; |
---|
1076 | 1118 | case IB_CM_MRA_REQ_SENT: |
---|
1077 | 1119 | case IB_CM_REP_RCVD: |
---|
1078 | 1120 | case IB_CM_MRA_REP_SENT: |
---|
1079 | | - spin_unlock_irq(&cm_id_priv->lock); |
---|
1080 | | - ib_send_cm_rej(cm_id, IB_CM_REJ_CONSUMER_DEFINED, |
---|
1081 | | - NULL, 0, NULL, 0); |
---|
| 1121 | + cm_send_rej_locked(cm_id_priv, IB_CM_REJ_CONSUMER_DEFINED, NULL, |
---|
| 1122 | + 0, NULL, 0); |
---|
1082 | 1123 | break; |
---|
1083 | 1124 | case IB_CM_ESTABLISHED: |
---|
1084 | | - spin_unlock_irq(&cm_id_priv->lock); |
---|
1085 | | - if (cm_id_priv->qp_type == IB_QPT_XRC_TGT) |
---|
| 1125 | + if (cm_id_priv->qp_type == IB_QPT_XRC_TGT) { |
---|
| 1126 | + cm_id->state = IB_CM_IDLE; |
---|
1086 | 1127 | break; |
---|
1087 | | - ib_send_cm_dreq(cm_id, NULL, 0); |
---|
| 1128 | + } |
---|
| 1129 | + cm_send_dreq_locked(cm_id_priv, NULL, 0); |
---|
1088 | 1130 | goto retest; |
---|
1089 | 1131 | case IB_CM_DREQ_SENT: |
---|
1090 | 1132 | ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); |
---|
1091 | 1133 | cm_enter_timewait(cm_id_priv); |
---|
1092 | | - spin_unlock_irq(&cm_id_priv->lock); |
---|
1093 | | - break; |
---|
| 1134 | + goto retest; |
---|
1094 | 1135 | case IB_CM_DREQ_RCVD: |
---|
1095 | | - spin_unlock_irq(&cm_id_priv->lock); |
---|
1096 | | - ib_send_cm_drep(cm_id, NULL, 0); |
---|
| 1136 | + cm_send_drep_locked(cm_id_priv, NULL, 0); |
---|
| 1137 | + WARN_ON(cm_id->state != IB_CM_TIMEWAIT); |
---|
| 1138 | + goto retest; |
---|
| 1139 | + case IB_CM_TIMEWAIT: |
---|
| 1140 | + /* |
---|
| 1141 | + * The cm_acquire_id in cm_timewait_handler will stop working |
---|
| 1142 | + * once we do xa_erase below, so just move to idle here for |
---|
| 1143 | + * consistency. |
---|
| 1144 | + */ |
---|
| 1145 | + cm_id->state = IB_CM_IDLE; |
---|
1097 | 1146 | break; |
---|
1098 | | - default: |
---|
1099 | | - spin_unlock_irq(&cm_id_priv->lock); |
---|
| 1147 | + case IB_CM_IDLE: |
---|
1100 | 1148 | break; |
---|
1101 | 1149 | } |
---|
| 1150 | + WARN_ON(cm_id->state != IB_CM_IDLE); |
---|
1102 | 1151 | |
---|
1103 | | - spin_lock_irq(&cm_id_priv->lock); |
---|
1104 | 1152 | spin_lock(&cm.lock); |
---|
1105 | 1153 | /* Required for cleanup paths related cm_req_handler() */ |
---|
1106 | 1154 | if (cm_id_priv->timewait_info) { |
---|
1107 | | - cm_cleanup_timewait(cm_id_priv->timewait_info); |
---|
| 1155 | + cm_remove_remote(cm_id_priv); |
---|
1108 | 1156 | kfree(cm_id_priv->timewait_info); |
---|
1109 | 1157 | cm_id_priv->timewait_info = NULL; |
---|
1110 | 1158 | } |
---|
.. | .. |
---|
1114 | 1162 | if (!list_empty(&cm_id_priv->prim_list) && |
---|
1115 | 1163 | (!cm_id_priv->prim_send_port_not_ready)) |
---|
1116 | 1164 | list_del(&cm_id_priv->prim_list); |
---|
| 1165 | + WARN_ON(cm_id_priv->listen_sharecount); |
---|
| 1166 | + WARN_ON(!RB_EMPTY_NODE(&cm_id_priv->service_node)); |
---|
| 1167 | + if (!RB_EMPTY_NODE(&cm_id_priv->sidr_id_node)) |
---|
| 1168 | + rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table); |
---|
1117 | 1169 | spin_unlock(&cm.lock); |
---|
1118 | 1170 | spin_unlock_irq(&cm_id_priv->lock); |
---|
1119 | 1171 | |
---|
1120 | | - cm_free_id(cm_id->local_id); |
---|
| 1172 | + xa_erase(&cm.local_id_table, cm_local_id(cm_id->local_id)); |
---|
1121 | 1173 | cm_deref_id(cm_id_priv); |
---|
1122 | 1174 | wait_for_completion(&cm_id_priv->comp); |
---|
1123 | 1175 | while ((work = cm_dequeue_work(cm_id_priv)) != NULL) |
---|
.. | .. |
---|
1126 | 1178 | rdma_destroy_ah_attr(&cm_id_priv->av.ah_attr); |
---|
1127 | 1179 | rdma_destroy_ah_attr(&cm_id_priv->alt_av.ah_attr); |
---|
1128 | 1180 | kfree(cm_id_priv->private_data); |
---|
1129 | | - kfree(cm_id_priv); |
---|
| 1181 | + kfree_rcu(cm_id_priv, rcu); |
---|
1130 | 1182 | } |
---|
1131 | 1183 | |
---|
1132 | 1184 | void ib_destroy_cm_id(struct ib_cm_id *cm_id) |
---|
.. | .. |
---|
1135 | 1187 | } |
---|
1136 | 1188 | EXPORT_SYMBOL(ib_destroy_cm_id); |
---|
1137 | 1189 | |
---|
| 1190 | +static int cm_init_listen(struct cm_id_private *cm_id_priv, __be64 service_id, |
---|
| 1191 | + __be64 service_mask) |
---|
| 1192 | +{ |
---|
| 1193 | + service_mask = service_mask ? service_mask : ~cpu_to_be64(0); |
---|
| 1194 | + service_id &= service_mask; |
---|
| 1195 | + if ((service_id & IB_SERVICE_ID_AGN_MASK) == IB_CM_ASSIGN_SERVICE_ID && |
---|
| 1196 | + (service_id != IB_CM_ASSIGN_SERVICE_ID)) |
---|
| 1197 | + return -EINVAL; |
---|
| 1198 | + |
---|
| 1199 | + if (service_id == IB_CM_ASSIGN_SERVICE_ID) { |
---|
| 1200 | + cm_id_priv->id.service_id = cpu_to_be64(cm.listen_service_id++); |
---|
| 1201 | + cm_id_priv->id.service_mask = ~cpu_to_be64(0); |
---|
| 1202 | + } else { |
---|
| 1203 | + cm_id_priv->id.service_id = service_id; |
---|
| 1204 | + cm_id_priv->id.service_mask = service_mask; |
---|
| 1205 | + } |
---|
| 1206 | + return 0; |
---|
| 1207 | +} |
---|
| 1208 | + |
---|
1138 | 1209 | /** |
---|
1139 | | - * __ib_cm_listen - Initiates listening on the specified service ID for |
---|
| 1210 | + * ib_cm_listen - Initiates listening on the specified service ID for |
---|
1140 | 1211 | * connection and service ID resolution requests. |
---|
1141 | 1212 | * @cm_id: Connection identifier associated with the listen request. |
---|
1142 | 1213 | * @service_id: Service identifier matched against incoming connection |
---|
.. | .. |
---|
1148 | 1219 | * exactly. This parameter is ignored if %service_id is set to |
---|
1149 | 1220 | * IB_CM_ASSIGN_SERVICE_ID. |
---|
1150 | 1221 | */ |
---|
1151 | | -static int __ib_cm_listen(struct ib_cm_id *cm_id, __be64 service_id, |
---|
1152 | | - __be64 service_mask) |
---|
1153 | | -{ |
---|
1154 | | - struct cm_id_private *cm_id_priv, *cur_cm_id_priv; |
---|
1155 | | - int ret = 0; |
---|
1156 | | - |
---|
1157 | | - service_mask = service_mask ? service_mask : ~cpu_to_be64(0); |
---|
1158 | | - service_id &= service_mask; |
---|
1159 | | - if ((service_id & IB_SERVICE_ID_AGN_MASK) == IB_CM_ASSIGN_SERVICE_ID && |
---|
1160 | | - (service_id != IB_CM_ASSIGN_SERVICE_ID)) |
---|
1161 | | - return -EINVAL; |
---|
1162 | | - |
---|
1163 | | - cm_id_priv = container_of(cm_id, struct cm_id_private, id); |
---|
1164 | | - if (cm_id->state != IB_CM_IDLE) |
---|
1165 | | - return -EINVAL; |
---|
1166 | | - |
---|
1167 | | - cm_id->state = IB_CM_LISTEN; |
---|
1168 | | - ++cm_id_priv->listen_sharecount; |
---|
1169 | | - |
---|
1170 | | - if (service_id == IB_CM_ASSIGN_SERVICE_ID) { |
---|
1171 | | - cm_id->service_id = cpu_to_be64(cm.listen_service_id++); |
---|
1172 | | - cm_id->service_mask = ~cpu_to_be64(0); |
---|
1173 | | - } else { |
---|
1174 | | - cm_id->service_id = service_id; |
---|
1175 | | - cm_id->service_mask = service_mask; |
---|
1176 | | - } |
---|
1177 | | - cur_cm_id_priv = cm_insert_listen(cm_id_priv); |
---|
1178 | | - |
---|
1179 | | - if (cur_cm_id_priv) { |
---|
1180 | | - cm_id->state = IB_CM_IDLE; |
---|
1181 | | - --cm_id_priv->listen_sharecount; |
---|
1182 | | - ret = -EBUSY; |
---|
1183 | | - } |
---|
1184 | | - return ret; |
---|
1185 | | -} |
---|
1186 | | - |
---|
1187 | 1222 | int ib_cm_listen(struct ib_cm_id *cm_id, __be64 service_id, __be64 service_mask) |
---|
1188 | 1223 | { |
---|
| 1224 | + struct cm_id_private *cm_id_priv = |
---|
| 1225 | + container_of(cm_id, struct cm_id_private, id); |
---|
1189 | 1226 | unsigned long flags; |
---|
1190 | 1227 | int ret; |
---|
1191 | 1228 | |
---|
1192 | | - spin_lock_irqsave(&cm.lock, flags); |
---|
1193 | | - ret = __ib_cm_listen(cm_id, service_id, service_mask); |
---|
1194 | | - spin_unlock_irqrestore(&cm.lock, flags); |
---|
| 1229 | + spin_lock_irqsave(&cm_id_priv->lock, flags); |
---|
| 1230 | + if (cm_id_priv->id.state != IB_CM_IDLE) { |
---|
| 1231 | + ret = -EINVAL; |
---|
| 1232 | + goto out; |
---|
| 1233 | + } |
---|
1195 | 1234 | |
---|
| 1235 | + ret = cm_init_listen(cm_id_priv, service_id, service_mask); |
---|
| 1236 | + if (ret) |
---|
| 1237 | + goto out; |
---|
| 1238 | + |
---|
| 1239 | + if (!cm_insert_listen(cm_id_priv, NULL)) { |
---|
| 1240 | + ret = -EBUSY; |
---|
| 1241 | + goto out; |
---|
| 1242 | + } |
---|
| 1243 | + |
---|
| 1244 | + cm_id_priv->id.state = IB_CM_LISTEN; |
---|
| 1245 | + ret = 0; |
---|
| 1246 | + |
---|
| 1247 | +out: |
---|
| 1248 | + spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
---|
1196 | 1249 | return ret; |
---|
1197 | 1250 | } |
---|
1198 | 1251 | EXPORT_SYMBOL(ib_cm_listen); |
---|
.. | .. |
---|
1217 | 1270 | ib_cm_handler cm_handler, |
---|
1218 | 1271 | __be64 service_id) |
---|
1219 | 1272 | { |
---|
| 1273 | + struct cm_id_private *listen_id_priv; |
---|
1220 | 1274 | struct cm_id_private *cm_id_priv; |
---|
1221 | | - struct ib_cm_id *cm_id; |
---|
1222 | | - unsigned long flags; |
---|
1223 | 1275 | int err = 0; |
---|
1224 | 1276 | |
---|
1225 | 1277 | /* Create an ID in advance, since the creation may sleep */ |
---|
1226 | | - cm_id = ib_create_cm_id(device, cm_handler, NULL); |
---|
1227 | | - if (IS_ERR(cm_id)) |
---|
1228 | | - return cm_id; |
---|
| 1278 | + cm_id_priv = cm_alloc_id_priv(device, cm_handler, NULL); |
---|
| 1279 | + if (IS_ERR(cm_id_priv)) |
---|
| 1280 | + return ERR_CAST(cm_id_priv); |
---|
1229 | 1281 | |
---|
1230 | | - spin_lock_irqsave(&cm.lock, flags); |
---|
1231 | | - |
---|
1232 | | - if (service_id == IB_CM_ASSIGN_SERVICE_ID) |
---|
1233 | | - goto new_id; |
---|
1234 | | - |
---|
1235 | | - /* Find an existing ID */ |
---|
1236 | | - cm_id_priv = cm_find_listen(device, service_id); |
---|
1237 | | - if (cm_id_priv) { |
---|
1238 | | - if (cm_id->cm_handler != cm_handler || cm_id->context) { |
---|
1239 | | - /* Sharing an ib_cm_id with different handlers is not |
---|
1240 | | - * supported */ |
---|
1241 | | - spin_unlock_irqrestore(&cm.lock, flags); |
---|
1242 | | - ib_destroy_cm_id(cm_id); |
---|
1243 | | - return ERR_PTR(-EINVAL); |
---|
1244 | | - } |
---|
1245 | | - atomic_inc(&cm_id_priv->refcount); |
---|
1246 | | - ++cm_id_priv->listen_sharecount; |
---|
1247 | | - spin_unlock_irqrestore(&cm.lock, flags); |
---|
1248 | | - |
---|
1249 | | - ib_destroy_cm_id(cm_id); |
---|
1250 | | - cm_id = &cm_id_priv->id; |
---|
1251 | | - return cm_id; |
---|
1252 | | - } |
---|
1253 | | - |
---|
1254 | | -new_id: |
---|
1255 | | - /* Use newly created ID */ |
---|
1256 | | - err = __ib_cm_listen(cm_id, service_id, 0); |
---|
1257 | | - |
---|
1258 | | - spin_unlock_irqrestore(&cm.lock, flags); |
---|
1259 | | - |
---|
| 1282 | + err = cm_init_listen(cm_id_priv, service_id, 0); |
---|
1260 | 1283 | if (err) { |
---|
1261 | | - ib_destroy_cm_id(cm_id); |
---|
| 1284 | + ib_destroy_cm_id(&cm_id_priv->id); |
---|
1262 | 1285 | return ERR_PTR(err); |
---|
1263 | 1286 | } |
---|
1264 | | - return cm_id; |
---|
| 1287 | + |
---|
| 1288 | + spin_lock_irq(&cm_id_priv->lock); |
---|
| 1289 | + listen_id_priv = cm_insert_listen(cm_id_priv, cm_handler); |
---|
| 1290 | + if (listen_id_priv != cm_id_priv) { |
---|
| 1291 | + spin_unlock_irq(&cm_id_priv->lock); |
---|
| 1292 | + ib_destroy_cm_id(&cm_id_priv->id); |
---|
| 1293 | + if (!listen_id_priv) |
---|
| 1294 | + return ERR_PTR(-EINVAL); |
---|
| 1295 | + return &listen_id_priv->id; |
---|
| 1296 | + } |
---|
| 1297 | + cm_id_priv->id.state = IB_CM_LISTEN; |
---|
| 1298 | + spin_unlock_irq(&cm_id_priv->lock); |
---|
| 1299 | + |
---|
| 1300 | + /* |
---|
| 1301 | + * A listen ID does not need to be in the xarray since it does not |
---|
| 1302 | + * receive mads, is not placed in the remote_id or remote_qpn rbtree, |
---|
| 1303 | + * and does not enter timewait. |
---|
| 1304 | + */ |
---|
| 1305 | + |
---|
| 1306 | + return &cm_id_priv->id; |
---|
1265 | 1307 | } |
---|
1266 | 1308 | EXPORT_SYMBOL(ib_cm_insert_listen); |
---|
1267 | 1309 | |
---|
.. | .. |
---|
1285 | 1327 | hdr->tid = tid; |
---|
1286 | 1328 | } |
---|
1287 | 1329 | |
---|
| 1330 | +static void cm_format_mad_ece_hdr(struct ib_mad_hdr *hdr, __be16 attr_id, |
---|
| 1331 | + __be64 tid, u32 attr_mod) |
---|
| 1332 | +{ |
---|
| 1333 | + cm_format_mad_hdr(hdr, attr_id, tid); |
---|
| 1334 | + hdr->attr_mod = cpu_to_be32(attr_mod); |
---|
| 1335 | +} |
---|
| 1336 | + |
---|
1288 | 1337 | static void cm_format_req(struct cm_req_msg *req_msg, |
---|
1289 | 1338 | struct cm_id_private *cm_id_priv, |
---|
1290 | 1339 | struct ib_cm_req_param *param) |
---|
.. | .. |
---|
1297 | 1346 | pri_ext = opa_is_extended_lid(pri_path->opa.dlid, |
---|
1298 | 1347 | pri_path->opa.slid); |
---|
1299 | 1348 | |
---|
1300 | | - cm_format_mad_hdr(&req_msg->hdr, CM_REQ_ATTR_ID, |
---|
1301 | | - cm_form_tid(cm_id_priv)); |
---|
| 1349 | + cm_format_mad_ece_hdr(&req_msg->hdr, CM_REQ_ATTR_ID, |
---|
| 1350 | + cm_form_tid(cm_id_priv), param->ece.attr_mod); |
---|
1302 | 1351 | |
---|
1303 | | - req_msg->local_comm_id = cm_id_priv->id.local_id; |
---|
1304 | | - req_msg->service_id = param->service_id; |
---|
1305 | | - req_msg->local_ca_guid = cm_id_priv->id.device->node_guid; |
---|
1306 | | - cm_req_set_local_qpn(req_msg, cpu_to_be32(param->qp_num)); |
---|
1307 | | - cm_req_set_init_depth(req_msg, param->initiator_depth); |
---|
1308 | | - cm_req_set_remote_resp_timeout(req_msg, |
---|
1309 | | - param->remote_cm_response_timeout); |
---|
| 1352 | + IBA_SET(CM_REQ_LOCAL_COMM_ID, req_msg, |
---|
| 1353 | + be32_to_cpu(cm_id_priv->id.local_id)); |
---|
| 1354 | + IBA_SET(CM_REQ_SERVICE_ID, req_msg, be64_to_cpu(param->service_id)); |
---|
| 1355 | + IBA_SET(CM_REQ_LOCAL_CA_GUID, req_msg, |
---|
| 1356 | + be64_to_cpu(cm_id_priv->id.device->node_guid)); |
---|
| 1357 | + IBA_SET(CM_REQ_LOCAL_QPN, req_msg, param->qp_num); |
---|
| 1358 | + IBA_SET(CM_REQ_INITIATOR_DEPTH, req_msg, param->initiator_depth); |
---|
| 1359 | + IBA_SET(CM_REQ_REMOTE_CM_RESPONSE_TIMEOUT, req_msg, |
---|
| 1360 | + param->remote_cm_response_timeout); |
---|
1310 | 1361 | cm_req_set_qp_type(req_msg, param->qp_type); |
---|
1311 | | - cm_req_set_flow_ctrl(req_msg, param->flow_control); |
---|
1312 | | - cm_req_set_starting_psn(req_msg, cpu_to_be32(param->starting_psn)); |
---|
1313 | | - cm_req_set_local_resp_timeout(req_msg, |
---|
1314 | | - param->local_cm_response_timeout); |
---|
1315 | | - req_msg->pkey = param->primary_path->pkey; |
---|
1316 | | - cm_req_set_path_mtu(req_msg, param->primary_path->mtu); |
---|
1317 | | - cm_req_set_max_cm_retries(req_msg, param->max_cm_retries); |
---|
| 1362 | + IBA_SET(CM_REQ_END_TO_END_FLOW_CONTROL, req_msg, param->flow_control); |
---|
| 1363 | + IBA_SET(CM_REQ_STARTING_PSN, req_msg, param->starting_psn); |
---|
| 1364 | + IBA_SET(CM_REQ_LOCAL_CM_RESPONSE_TIMEOUT, req_msg, |
---|
| 1365 | + param->local_cm_response_timeout); |
---|
| 1366 | + IBA_SET(CM_REQ_PARTITION_KEY, req_msg, |
---|
| 1367 | + be16_to_cpu(param->primary_path->pkey)); |
---|
| 1368 | + IBA_SET(CM_REQ_PATH_PACKET_PAYLOAD_MTU, req_msg, |
---|
| 1369 | + param->primary_path->mtu); |
---|
| 1370 | + IBA_SET(CM_REQ_MAX_CM_RETRIES, req_msg, param->max_cm_retries); |
---|
1318 | 1371 | |
---|
1319 | 1372 | if (param->qp_type != IB_QPT_XRC_INI) { |
---|
1320 | | - cm_req_set_resp_res(req_msg, param->responder_resources); |
---|
1321 | | - cm_req_set_retry_count(req_msg, param->retry_count); |
---|
1322 | | - cm_req_set_rnr_retry_count(req_msg, param->rnr_retry_count); |
---|
1323 | | - cm_req_set_srq(req_msg, param->srq); |
---|
| 1373 | + IBA_SET(CM_REQ_RESPONDER_RESOURCES, req_msg, |
---|
| 1374 | + param->responder_resources); |
---|
| 1375 | + IBA_SET(CM_REQ_RETRY_COUNT, req_msg, param->retry_count); |
---|
| 1376 | + IBA_SET(CM_REQ_RNR_RETRY_COUNT, req_msg, |
---|
| 1377 | + param->rnr_retry_count); |
---|
| 1378 | + IBA_SET(CM_REQ_SRQ, req_msg, param->srq); |
---|
1324 | 1379 | } |
---|
1325 | 1380 | |
---|
1326 | | - req_msg->primary_local_gid = pri_path->sgid; |
---|
1327 | | - req_msg->primary_remote_gid = pri_path->dgid; |
---|
| 1381 | + *IBA_GET_MEM_PTR(CM_REQ_PRIMARY_LOCAL_PORT_GID, req_msg) = |
---|
| 1382 | + pri_path->sgid; |
---|
| 1383 | + *IBA_GET_MEM_PTR(CM_REQ_PRIMARY_REMOTE_PORT_GID, req_msg) = |
---|
| 1384 | + pri_path->dgid; |
---|
1328 | 1385 | if (pri_ext) { |
---|
1329 | | - req_msg->primary_local_gid.global.interface_id |
---|
1330 | | - = OPA_MAKE_ID(be32_to_cpu(pri_path->opa.slid)); |
---|
1331 | | - req_msg->primary_remote_gid.global.interface_id |
---|
1332 | | - = OPA_MAKE_ID(be32_to_cpu(pri_path->opa.dlid)); |
---|
| 1386 | + IBA_GET_MEM_PTR(CM_REQ_PRIMARY_LOCAL_PORT_GID, req_msg) |
---|
| 1387 | + ->global.interface_id = |
---|
| 1388 | + OPA_MAKE_ID(be32_to_cpu(pri_path->opa.slid)); |
---|
| 1389 | + IBA_GET_MEM_PTR(CM_REQ_PRIMARY_REMOTE_PORT_GID, req_msg) |
---|
| 1390 | + ->global.interface_id = |
---|
| 1391 | + OPA_MAKE_ID(be32_to_cpu(pri_path->opa.dlid)); |
---|
1333 | 1392 | } |
---|
1334 | 1393 | if (pri_path->hop_limit <= 1) { |
---|
1335 | | - req_msg->primary_local_lid = pri_ext ? 0 : |
---|
1336 | | - htons(ntohl(sa_path_get_slid(pri_path))); |
---|
1337 | | - req_msg->primary_remote_lid = pri_ext ? 0 : |
---|
1338 | | - htons(ntohl(sa_path_get_dlid(pri_path))); |
---|
| 1394 | + IBA_SET(CM_REQ_PRIMARY_LOCAL_PORT_LID, req_msg, |
---|
| 1395 | + be16_to_cpu(pri_ext ? 0 : |
---|
| 1396 | + htons(ntohl(sa_path_get_slid( |
---|
| 1397 | + pri_path))))); |
---|
| 1398 | + IBA_SET(CM_REQ_PRIMARY_REMOTE_PORT_LID, req_msg, |
---|
| 1399 | + be16_to_cpu(pri_ext ? 0 : |
---|
| 1400 | + htons(ntohl(sa_path_get_dlid( |
---|
| 1401 | + pri_path))))); |
---|
1339 | 1402 | } else { |
---|
1340 | 1403 | /* Work-around until there's a way to obtain remote LID info */ |
---|
1341 | | - req_msg->primary_local_lid = IB_LID_PERMISSIVE; |
---|
1342 | | - req_msg->primary_remote_lid = IB_LID_PERMISSIVE; |
---|
| 1404 | + IBA_SET(CM_REQ_PRIMARY_LOCAL_PORT_LID, req_msg, |
---|
| 1405 | + be16_to_cpu(IB_LID_PERMISSIVE)); |
---|
| 1406 | + IBA_SET(CM_REQ_PRIMARY_REMOTE_PORT_LID, req_msg, |
---|
| 1407 | + be16_to_cpu(IB_LID_PERMISSIVE)); |
---|
1343 | 1408 | } |
---|
1344 | | - cm_req_set_primary_flow_label(req_msg, pri_path->flow_label); |
---|
1345 | | - cm_req_set_primary_packet_rate(req_msg, pri_path->rate); |
---|
1346 | | - req_msg->primary_traffic_class = pri_path->traffic_class; |
---|
1347 | | - req_msg->primary_hop_limit = pri_path->hop_limit; |
---|
1348 | | - cm_req_set_primary_sl(req_msg, pri_path->sl); |
---|
1349 | | - cm_req_set_primary_subnet_local(req_msg, (pri_path->hop_limit <= 1)); |
---|
1350 | | - cm_req_set_primary_local_ack_timeout(req_msg, |
---|
| 1409 | + IBA_SET(CM_REQ_PRIMARY_FLOW_LABEL, req_msg, |
---|
| 1410 | + be32_to_cpu(pri_path->flow_label)); |
---|
| 1411 | + IBA_SET(CM_REQ_PRIMARY_PACKET_RATE, req_msg, pri_path->rate); |
---|
| 1412 | + IBA_SET(CM_REQ_PRIMARY_TRAFFIC_CLASS, req_msg, pri_path->traffic_class); |
---|
| 1413 | + IBA_SET(CM_REQ_PRIMARY_HOP_LIMIT, req_msg, pri_path->hop_limit); |
---|
| 1414 | + IBA_SET(CM_REQ_PRIMARY_SL, req_msg, pri_path->sl); |
---|
| 1415 | + IBA_SET(CM_REQ_PRIMARY_SUBNET_LOCAL, req_msg, |
---|
| 1416 | + (pri_path->hop_limit <= 1)); |
---|
| 1417 | + IBA_SET(CM_REQ_PRIMARY_LOCAL_ACK_TIMEOUT, req_msg, |
---|
1351 | 1418 | cm_ack_timeout(cm_id_priv->av.port->cm_dev->ack_delay, |
---|
1352 | 1419 | pri_path->packet_life_time)); |
---|
1353 | 1420 | |
---|
.. | .. |
---|
1358 | 1425 | alt_ext = opa_is_extended_lid(alt_path->opa.dlid, |
---|
1359 | 1426 | alt_path->opa.slid); |
---|
1360 | 1427 | |
---|
1361 | | - req_msg->alt_local_gid = alt_path->sgid; |
---|
1362 | | - req_msg->alt_remote_gid = alt_path->dgid; |
---|
| 1428 | + *IBA_GET_MEM_PTR(CM_REQ_ALTERNATE_LOCAL_PORT_GID, req_msg) = |
---|
| 1429 | + alt_path->sgid; |
---|
| 1430 | + *IBA_GET_MEM_PTR(CM_REQ_ALTERNATE_REMOTE_PORT_GID, req_msg) = |
---|
| 1431 | + alt_path->dgid; |
---|
1363 | 1432 | if (alt_ext) { |
---|
1364 | | - req_msg->alt_local_gid.global.interface_id |
---|
1365 | | - = OPA_MAKE_ID(be32_to_cpu(alt_path->opa.slid)); |
---|
1366 | | - req_msg->alt_remote_gid.global.interface_id |
---|
1367 | | - = OPA_MAKE_ID(be32_to_cpu(alt_path->opa.dlid)); |
---|
| 1433 | + IBA_GET_MEM_PTR(CM_REQ_ALTERNATE_LOCAL_PORT_GID, |
---|
| 1434 | + req_msg) |
---|
| 1435 | + ->global.interface_id = |
---|
| 1436 | + OPA_MAKE_ID(be32_to_cpu(alt_path->opa.slid)); |
---|
| 1437 | + IBA_GET_MEM_PTR(CM_REQ_ALTERNATE_REMOTE_PORT_GID, |
---|
| 1438 | + req_msg) |
---|
| 1439 | + ->global.interface_id = |
---|
| 1440 | + OPA_MAKE_ID(be32_to_cpu(alt_path->opa.dlid)); |
---|
1368 | 1441 | } |
---|
1369 | 1442 | if (alt_path->hop_limit <= 1) { |
---|
1370 | | - req_msg->alt_local_lid = alt_ext ? 0 : |
---|
1371 | | - htons(ntohl(sa_path_get_slid(alt_path))); |
---|
1372 | | - req_msg->alt_remote_lid = alt_ext ? 0 : |
---|
1373 | | - htons(ntohl(sa_path_get_dlid(alt_path))); |
---|
| 1443 | + IBA_SET(CM_REQ_ALTERNATE_LOCAL_PORT_LID, req_msg, |
---|
| 1444 | + be16_to_cpu( |
---|
| 1445 | + alt_ext ? 0 : |
---|
| 1446 | + htons(ntohl(sa_path_get_slid( |
---|
| 1447 | + alt_path))))); |
---|
| 1448 | + IBA_SET(CM_REQ_ALTERNATE_REMOTE_PORT_LID, req_msg, |
---|
| 1449 | + be16_to_cpu( |
---|
| 1450 | + alt_ext ? 0 : |
---|
| 1451 | + htons(ntohl(sa_path_get_dlid( |
---|
| 1452 | + alt_path))))); |
---|
1374 | 1453 | } else { |
---|
1375 | | - req_msg->alt_local_lid = IB_LID_PERMISSIVE; |
---|
1376 | | - req_msg->alt_remote_lid = IB_LID_PERMISSIVE; |
---|
| 1454 | + IBA_SET(CM_REQ_ALTERNATE_LOCAL_PORT_LID, req_msg, |
---|
| 1455 | + be16_to_cpu(IB_LID_PERMISSIVE)); |
---|
| 1456 | + IBA_SET(CM_REQ_ALTERNATE_REMOTE_PORT_LID, req_msg, |
---|
| 1457 | + be16_to_cpu(IB_LID_PERMISSIVE)); |
---|
1377 | 1458 | } |
---|
1378 | | - cm_req_set_alt_flow_label(req_msg, |
---|
1379 | | - alt_path->flow_label); |
---|
1380 | | - cm_req_set_alt_packet_rate(req_msg, alt_path->rate); |
---|
1381 | | - req_msg->alt_traffic_class = alt_path->traffic_class; |
---|
1382 | | - req_msg->alt_hop_limit = alt_path->hop_limit; |
---|
1383 | | - cm_req_set_alt_sl(req_msg, alt_path->sl); |
---|
1384 | | - cm_req_set_alt_subnet_local(req_msg, (alt_path->hop_limit <= 1)); |
---|
1385 | | - cm_req_set_alt_local_ack_timeout(req_msg, |
---|
| 1459 | + IBA_SET(CM_REQ_ALTERNATE_FLOW_LABEL, req_msg, |
---|
| 1460 | + be32_to_cpu(alt_path->flow_label)); |
---|
| 1461 | + IBA_SET(CM_REQ_ALTERNATE_PACKET_RATE, req_msg, alt_path->rate); |
---|
| 1462 | + IBA_SET(CM_REQ_ALTERNATE_TRAFFIC_CLASS, req_msg, |
---|
| 1463 | + alt_path->traffic_class); |
---|
| 1464 | + IBA_SET(CM_REQ_ALTERNATE_HOP_LIMIT, req_msg, |
---|
| 1465 | + alt_path->hop_limit); |
---|
| 1466 | + IBA_SET(CM_REQ_ALTERNATE_SL, req_msg, alt_path->sl); |
---|
| 1467 | + IBA_SET(CM_REQ_ALTERNATE_SUBNET_LOCAL, req_msg, |
---|
| 1468 | + (alt_path->hop_limit <= 1)); |
---|
| 1469 | + IBA_SET(CM_REQ_ALTERNATE_LOCAL_ACK_TIMEOUT, req_msg, |
---|
1386 | 1470 | cm_ack_timeout(cm_id_priv->av.port->cm_dev->ack_delay, |
---|
1387 | 1471 | alt_path->packet_life_time)); |
---|
1388 | 1472 | } |
---|
| 1473 | + IBA_SET(CM_REQ_VENDOR_ID, req_msg, param->ece.vendor_id); |
---|
1389 | 1474 | |
---|
1390 | 1475 | if (param->private_data && param->private_data_len) |
---|
1391 | | - memcpy(req_msg->private_data, param->private_data, |
---|
1392 | | - param->private_data_len); |
---|
| 1476 | + IBA_SET_MEM(CM_REQ_PRIVATE_DATA, req_msg, param->private_data, |
---|
| 1477 | + param->private_data_len); |
---|
1393 | 1478 | } |
---|
1394 | 1479 | |
---|
1395 | 1480 | static int cm_validate_req_param(struct ib_cm_req_param *param) |
---|
1396 | 1481 | { |
---|
1397 | | - /* peer-to-peer not supported */ |
---|
1398 | | - if (param->peer_to_peer) |
---|
1399 | | - return -EINVAL; |
---|
1400 | | - |
---|
1401 | 1482 | if (!param->primary_path) |
---|
1402 | 1483 | return -EINVAL; |
---|
1403 | 1484 | |
---|
.. | .. |
---|
1482 | 1563 | cm_id_priv->msg->timeout_ms = cm_id_priv->timeout_ms; |
---|
1483 | 1564 | cm_id_priv->msg->context[1] = (void *) (unsigned long) IB_CM_REQ_SENT; |
---|
1484 | 1565 | |
---|
1485 | | - cm_id_priv->local_qpn = cm_req_get_local_qpn(req_msg); |
---|
1486 | | - cm_id_priv->rq_psn = cm_req_get_starting_psn(req_msg); |
---|
| 1566 | + cm_id_priv->local_qpn = cpu_to_be32(IBA_GET(CM_REQ_LOCAL_QPN, req_msg)); |
---|
| 1567 | + cm_id_priv->rq_psn = cpu_to_be32(IBA_GET(CM_REQ_STARTING_PSN, req_msg)); |
---|
1487 | 1568 | |
---|
| 1569 | + trace_icm_send_req(&cm_id_priv->id); |
---|
1488 | 1570 | spin_lock_irqsave(&cm_id_priv->lock, flags); |
---|
1489 | 1571 | ret = ib_post_send_mad(cm_id_priv->msg, NULL); |
---|
1490 | 1572 | if (ret) { |
---|
.. | .. |
---|
1520 | 1602 | rej_msg = (struct cm_rej_msg *) msg->mad; |
---|
1521 | 1603 | |
---|
1522 | 1604 | cm_format_mad_hdr(&rej_msg->hdr, CM_REJ_ATTR_ID, rcv_msg->hdr.tid); |
---|
1523 | | - rej_msg->remote_comm_id = rcv_msg->local_comm_id; |
---|
1524 | | - rej_msg->local_comm_id = rcv_msg->remote_comm_id; |
---|
1525 | | - cm_rej_set_msg_rejected(rej_msg, msg_rejected); |
---|
1526 | | - rej_msg->reason = cpu_to_be16(reason); |
---|
| 1605 | + IBA_SET(CM_REJ_REMOTE_COMM_ID, rej_msg, |
---|
| 1606 | + IBA_GET(CM_REJ_LOCAL_COMM_ID, rcv_msg)); |
---|
| 1607 | + IBA_SET(CM_REJ_LOCAL_COMM_ID, rej_msg, |
---|
| 1608 | + IBA_GET(CM_REJ_REMOTE_COMM_ID, rcv_msg)); |
---|
| 1609 | + IBA_SET(CM_REJ_MESSAGE_REJECTED, rej_msg, msg_rejected); |
---|
| 1610 | + IBA_SET(CM_REJ_REASON, rej_msg, reason); |
---|
1527 | 1611 | |
---|
1528 | 1612 | if (ari && ari_length) { |
---|
1529 | | - cm_rej_set_reject_info_len(rej_msg, ari_length); |
---|
1530 | | - memcpy(rej_msg->ari, ari, ari_length); |
---|
| 1613 | + IBA_SET(CM_REJ_REJECTED_INFO_LENGTH, rej_msg, ari_length); |
---|
| 1614 | + IBA_SET_MEM(CM_REJ_ARI, rej_msg, ari, ari_length); |
---|
1531 | 1615 | } |
---|
1532 | 1616 | |
---|
| 1617 | + trace_icm_issue_rej( |
---|
| 1618 | + IBA_GET(CM_REJ_LOCAL_COMM_ID, rcv_msg), |
---|
| 1619 | + IBA_GET(CM_REJ_REMOTE_COMM_ID, rcv_msg)); |
---|
1533 | 1620 | ret = ib_post_send_mad(msg, NULL); |
---|
1534 | 1621 | if (ret) |
---|
1535 | 1622 | cm_free_msg(msg); |
---|
.. | .. |
---|
1537 | 1624 | return ret; |
---|
1538 | 1625 | } |
---|
1539 | 1626 | |
---|
1540 | | -static inline int cm_is_active_peer(__be64 local_ca_guid, __be64 remote_ca_guid, |
---|
1541 | | - __be32 local_qpn, __be32 remote_qpn) |
---|
1542 | | -{ |
---|
1543 | | - return (be64_to_cpu(local_ca_guid) > be64_to_cpu(remote_ca_guid) || |
---|
1544 | | - ((local_ca_guid == remote_ca_guid) && |
---|
1545 | | - (be32_to_cpu(local_qpn) > be32_to_cpu(remote_qpn)))); |
---|
1546 | | -} |
---|
1547 | | - |
---|
1548 | 1627 | static bool cm_req_has_alt_path(struct cm_req_msg *req_msg) |
---|
1549 | 1628 | { |
---|
1550 | | - return ((req_msg->alt_local_lid) || |
---|
1551 | | - (ib_is_opa_gid(&req_msg->alt_local_gid))); |
---|
| 1629 | + return ((cpu_to_be16( |
---|
| 1630 | + IBA_GET(CM_REQ_ALTERNATE_LOCAL_PORT_LID, req_msg))) || |
---|
| 1631 | + (ib_is_opa_gid(IBA_GET_MEM_PTR(CM_REQ_ALTERNATE_LOCAL_PORT_GID, |
---|
| 1632 | + req_msg)))); |
---|
1552 | 1633 | } |
---|
1553 | 1634 | |
---|
1554 | 1635 | static void cm_path_set_rec_type(struct ib_device *ib_device, u8 port_num, |
---|
.. | .. |
---|
1562 | 1643 | |
---|
1563 | 1644 | static void cm_format_path_lid_from_req(struct cm_req_msg *req_msg, |
---|
1564 | 1645 | struct sa_path_rec *primary_path, |
---|
1565 | | - struct sa_path_rec *alt_path) |
---|
| 1646 | + struct sa_path_rec *alt_path, |
---|
| 1647 | + struct ib_wc *wc) |
---|
1566 | 1648 | { |
---|
1567 | 1649 | u32 lid; |
---|
1568 | 1650 | |
---|
1569 | 1651 | if (primary_path->rec_type != SA_PATH_REC_TYPE_OPA) { |
---|
1570 | | - sa_path_set_dlid(primary_path, |
---|
1571 | | - ntohs(req_msg->primary_local_lid)); |
---|
| 1652 | + sa_path_set_dlid(primary_path, wc->slid); |
---|
1572 | 1653 | sa_path_set_slid(primary_path, |
---|
1573 | | - ntohs(req_msg->primary_remote_lid)); |
---|
| 1654 | + IBA_GET(CM_REQ_PRIMARY_REMOTE_PORT_LID, |
---|
| 1655 | + req_msg)); |
---|
1574 | 1656 | } else { |
---|
1575 | | - lid = opa_get_lid_from_gid(&req_msg->primary_local_gid); |
---|
| 1657 | + lid = opa_get_lid_from_gid(IBA_GET_MEM_PTR( |
---|
| 1658 | + CM_REQ_PRIMARY_LOCAL_PORT_GID, req_msg)); |
---|
1576 | 1659 | sa_path_set_dlid(primary_path, lid); |
---|
1577 | 1660 | |
---|
1578 | | - lid = opa_get_lid_from_gid(&req_msg->primary_remote_gid); |
---|
| 1661 | + lid = opa_get_lid_from_gid(IBA_GET_MEM_PTR( |
---|
| 1662 | + CM_REQ_PRIMARY_REMOTE_PORT_GID, req_msg)); |
---|
1579 | 1663 | sa_path_set_slid(primary_path, lid); |
---|
1580 | 1664 | } |
---|
1581 | 1665 | |
---|
.. | .. |
---|
1583 | 1667 | return; |
---|
1584 | 1668 | |
---|
1585 | 1669 | if (alt_path->rec_type != SA_PATH_REC_TYPE_OPA) { |
---|
1586 | | - sa_path_set_dlid(alt_path, ntohs(req_msg->alt_local_lid)); |
---|
1587 | | - sa_path_set_slid(alt_path, ntohs(req_msg->alt_remote_lid)); |
---|
| 1670 | + sa_path_set_dlid(alt_path, |
---|
| 1671 | + IBA_GET(CM_REQ_ALTERNATE_LOCAL_PORT_LID, |
---|
| 1672 | + req_msg)); |
---|
| 1673 | + sa_path_set_slid(alt_path, |
---|
| 1674 | + IBA_GET(CM_REQ_ALTERNATE_REMOTE_PORT_LID, |
---|
| 1675 | + req_msg)); |
---|
1588 | 1676 | } else { |
---|
1589 | | - lid = opa_get_lid_from_gid(&req_msg->alt_local_gid); |
---|
| 1677 | + lid = opa_get_lid_from_gid(IBA_GET_MEM_PTR( |
---|
| 1678 | + CM_REQ_ALTERNATE_LOCAL_PORT_GID, req_msg)); |
---|
1590 | 1679 | sa_path_set_dlid(alt_path, lid); |
---|
1591 | 1680 | |
---|
1592 | | - lid = opa_get_lid_from_gid(&req_msg->alt_remote_gid); |
---|
| 1681 | + lid = opa_get_lid_from_gid(IBA_GET_MEM_PTR( |
---|
| 1682 | + CM_REQ_ALTERNATE_REMOTE_PORT_GID, req_msg)); |
---|
1593 | 1683 | sa_path_set_slid(alt_path, lid); |
---|
1594 | 1684 | } |
---|
1595 | 1685 | } |
---|
1596 | 1686 | |
---|
1597 | 1687 | static void cm_format_paths_from_req(struct cm_req_msg *req_msg, |
---|
1598 | 1688 | struct sa_path_rec *primary_path, |
---|
1599 | | - struct sa_path_rec *alt_path) |
---|
| 1689 | + struct sa_path_rec *alt_path, |
---|
| 1690 | + struct ib_wc *wc) |
---|
1600 | 1691 | { |
---|
1601 | | - primary_path->dgid = req_msg->primary_local_gid; |
---|
1602 | | - primary_path->sgid = req_msg->primary_remote_gid; |
---|
1603 | | - primary_path->flow_label = cm_req_get_primary_flow_label(req_msg); |
---|
1604 | | - primary_path->hop_limit = req_msg->primary_hop_limit; |
---|
1605 | | - primary_path->traffic_class = req_msg->primary_traffic_class; |
---|
| 1692 | + primary_path->dgid = |
---|
| 1693 | + *IBA_GET_MEM_PTR(CM_REQ_PRIMARY_LOCAL_PORT_GID, req_msg); |
---|
| 1694 | + primary_path->sgid = |
---|
| 1695 | + *IBA_GET_MEM_PTR(CM_REQ_PRIMARY_REMOTE_PORT_GID, req_msg); |
---|
| 1696 | + primary_path->flow_label = |
---|
| 1697 | + cpu_to_be32(IBA_GET(CM_REQ_PRIMARY_FLOW_LABEL, req_msg)); |
---|
| 1698 | + primary_path->hop_limit = IBA_GET(CM_REQ_PRIMARY_HOP_LIMIT, req_msg); |
---|
| 1699 | + primary_path->traffic_class = |
---|
| 1700 | + IBA_GET(CM_REQ_PRIMARY_TRAFFIC_CLASS, req_msg); |
---|
1606 | 1701 | primary_path->reversible = 1; |
---|
1607 | | - primary_path->pkey = req_msg->pkey; |
---|
1608 | | - primary_path->sl = cm_req_get_primary_sl(req_msg); |
---|
| 1702 | + primary_path->pkey = |
---|
| 1703 | + cpu_to_be16(IBA_GET(CM_REQ_PARTITION_KEY, req_msg)); |
---|
| 1704 | + primary_path->sl = IBA_GET(CM_REQ_PRIMARY_SL, req_msg); |
---|
1609 | 1705 | primary_path->mtu_selector = IB_SA_EQ; |
---|
1610 | | - primary_path->mtu = cm_req_get_path_mtu(req_msg); |
---|
| 1706 | + primary_path->mtu = IBA_GET(CM_REQ_PATH_PACKET_PAYLOAD_MTU, req_msg); |
---|
1611 | 1707 | primary_path->rate_selector = IB_SA_EQ; |
---|
1612 | | - primary_path->rate = cm_req_get_primary_packet_rate(req_msg); |
---|
| 1708 | + primary_path->rate = IBA_GET(CM_REQ_PRIMARY_PACKET_RATE, req_msg); |
---|
1613 | 1709 | primary_path->packet_life_time_selector = IB_SA_EQ; |
---|
1614 | 1710 | primary_path->packet_life_time = |
---|
1615 | | - cm_req_get_primary_local_ack_timeout(req_msg); |
---|
| 1711 | + IBA_GET(CM_REQ_PRIMARY_LOCAL_ACK_TIMEOUT, req_msg); |
---|
1616 | 1712 | primary_path->packet_life_time -= (primary_path->packet_life_time > 0); |
---|
1617 | | - primary_path->service_id = req_msg->service_id; |
---|
| 1713 | + primary_path->service_id = |
---|
| 1714 | + cpu_to_be64(IBA_GET(CM_REQ_SERVICE_ID, req_msg)); |
---|
1618 | 1715 | if (sa_path_is_roce(primary_path)) |
---|
1619 | 1716 | primary_path->roce.route_resolved = false; |
---|
1620 | 1717 | |
---|
1621 | 1718 | if (cm_req_has_alt_path(req_msg)) { |
---|
1622 | | - alt_path->dgid = req_msg->alt_local_gid; |
---|
1623 | | - alt_path->sgid = req_msg->alt_remote_gid; |
---|
1624 | | - alt_path->flow_label = cm_req_get_alt_flow_label(req_msg); |
---|
1625 | | - alt_path->hop_limit = req_msg->alt_hop_limit; |
---|
1626 | | - alt_path->traffic_class = req_msg->alt_traffic_class; |
---|
| 1719 | + alt_path->dgid = *IBA_GET_MEM_PTR( |
---|
| 1720 | + CM_REQ_ALTERNATE_LOCAL_PORT_GID, req_msg); |
---|
| 1721 | + alt_path->sgid = *IBA_GET_MEM_PTR( |
---|
| 1722 | + CM_REQ_ALTERNATE_REMOTE_PORT_GID, req_msg); |
---|
| 1723 | + alt_path->flow_label = cpu_to_be32( |
---|
| 1724 | + IBA_GET(CM_REQ_ALTERNATE_FLOW_LABEL, req_msg)); |
---|
| 1725 | + alt_path->hop_limit = |
---|
| 1726 | + IBA_GET(CM_REQ_ALTERNATE_HOP_LIMIT, req_msg); |
---|
| 1727 | + alt_path->traffic_class = |
---|
| 1728 | + IBA_GET(CM_REQ_ALTERNATE_TRAFFIC_CLASS, req_msg); |
---|
1627 | 1729 | alt_path->reversible = 1; |
---|
1628 | | - alt_path->pkey = req_msg->pkey; |
---|
1629 | | - alt_path->sl = cm_req_get_alt_sl(req_msg); |
---|
| 1730 | + alt_path->pkey = |
---|
| 1731 | + cpu_to_be16(IBA_GET(CM_REQ_PARTITION_KEY, req_msg)); |
---|
| 1732 | + alt_path->sl = IBA_GET(CM_REQ_ALTERNATE_SL, req_msg); |
---|
1630 | 1733 | alt_path->mtu_selector = IB_SA_EQ; |
---|
1631 | | - alt_path->mtu = cm_req_get_path_mtu(req_msg); |
---|
| 1734 | + alt_path->mtu = |
---|
| 1735 | + IBA_GET(CM_REQ_PATH_PACKET_PAYLOAD_MTU, req_msg); |
---|
1632 | 1736 | alt_path->rate_selector = IB_SA_EQ; |
---|
1633 | | - alt_path->rate = cm_req_get_alt_packet_rate(req_msg); |
---|
| 1737 | + alt_path->rate = IBA_GET(CM_REQ_ALTERNATE_PACKET_RATE, req_msg); |
---|
1634 | 1738 | alt_path->packet_life_time_selector = IB_SA_EQ; |
---|
1635 | 1739 | alt_path->packet_life_time = |
---|
1636 | | - cm_req_get_alt_local_ack_timeout(req_msg); |
---|
| 1740 | + IBA_GET(CM_REQ_ALTERNATE_LOCAL_ACK_TIMEOUT, req_msg); |
---|
1637 | 1741 | alt_path->packet_life_time -= (alt_path->packet_life_time > 0); |
---|
1638 | | - alt_path->service_id = req_msg->service_id; |
---|
| 1742 | + alt_path->service_id = |
---|
| 1743 | + cpu_to_be64(IBA_GET(CM_REQ_SERVICE_ID, req_msg)); |
---|
1639 | 1744 | |
---|
1640 | 1745 | if (sa_path_is_roce(alt_path)) |
---|
1641 | 1746 | alt_path->roce.route_resolved = false; |
---|
1642 | 1747 | } |
---|
1643 | | - cm_format_path_lid_from_req(req_msg, primary_path, alt_path); |
---|
| 1748 | + cm_format_path_lid_from_req(req_msg, primary_path, alt_path, wc); |
---|
1644 | 1749 | } |
---|
1645 | 1750 | |
---|
1646 | 1751 | static u16 cm_get_bth_pkey(struct cm_work *work) |
---|
.. | .. |
---|
1710 | 1815 | } else { |
---|
1711 | 1816 | param->alternate_path = NULL; |
---|
1712 | 1817 | } |
---|
1713 | | - param->remote_ca_guid = req_msg->local_ca_guid; |
---|
1714 | | - param->remote_qkey = be32_to_cpu(req_msg->local_qkey); |
---|
1715 | | - param->remote_qpn = be32_to_cpu(cm_req_get_local_qpn(req_msg)); |
---|
| 1818 | + param->remote_ca_guid = |
---|
| 1819 | + cpu_to_be64(IBA_GET(CM_REQ_LOCAL_CA_GUID, req_msg)); |
---|
| 1820 | + param->remote_qkey = IBA_GET(CM_REQ_LOCAL_Q_KEY, req_msg); |
---|
| 1821 | + param->remote_qpn = IBA_GET(CM_REQ_LOCAL_QPN, req_msg); |
---|
1716 | 1822 | param->qp_type = cm_req_get_qp_type(req_msg); |
---|
1717 | | - param->starting_psn = be32_to_cpu(cm_req_get_starting_psn(req_msg)); |
---|
1718 | | - param->responder_resources = cm_req_get_init_depth(req_msg); |
---|
1719 | | - param->initiator_depth = cm_req_get_resp_res(req_msg); |
---|
| 1823 | + param->starting_psn = IBA_GET(CM_REQ_STARTING_PSN, req_msg); |
---|
| 1824 | + param->responder_resources = IBA_GET(CM_REQ_INITIATOR_DEPTH, req_msg); |
---|
| 1825 | + param->initiator_depth = IBA_GET(CM_REQ_RESPONDER_RESOURCES, req_msg); |
---|
1720 | 1826 | param->local_cm_response_timeout = |
---|
1721 | | - cm_req_get_remote_resp_timeout(req_msg); |
---|
1722 | | - param->flow_control = cm_req_get_flow_ctrl(req_msg); |
---|
| 1827 | + IBA_GET(CM_REQ_REMOTE_CM_RESPONSE_TIMEOUT, req_msg); |
---|
| 1828 | + param->flow_control = IBA_GET(CM_REQ_END_TO_END_FLOW_CONTROL, req_msg); |
---|
1723 | 1829 | param->remote_cm_response_timeout = |
---|
1724 | | - cm_req_get_local_resp_timeout(req_msg); |
---|
1725 | | - param->retry_count = cm_req_get_retry_count(req_msg); |
---|
1726 | | - param->rnr_retry_count = cm_req_get_rnr_retry_count(req_msg); |
---|
1727 | | - param->srq = cm_req_get_srq(req_msg); |
---|
| 1830 | + IBA_GET(CM_REQ_LOCAL_CM_RESPONSE_TIMEOUT, req_msg); |
---|
| 1831 | + param->retry_count = IBA_GET(CM_REQ_RETRY_COUNT, req_msg); |
---|
| 1832 | + param->rnr_retry_count = IBA_GET(CM_REQ_RNR_RETRY_COUNT, req_msg); |
---|
| 1833 | + param->srq = IBA_GET(CM_REQ_SRQ, req_msg); |
---|
1728 | 1834 | param->ppath_sgid_attr = cm_id_priv->av.ah_attr.grh.sgid_attr; |
---|
1729 | | - work->cm_event.private_data = &req_msg->private_data; |
---|
| 1835 | + param->ece.vendor_id = IBA_GET(CM_REQ_VENDOR_ID, req_msg); |
---|
| 1836 | + param->ece.attr_mod = be32_to_cpu(req_msg->hdr.attr_mod); |
---|
| 1837 | + |
---|
| 1838 | + work->cm_event.private_data = |
---|
| 1839 | + IBA_GET_MEM_PTR(CM_REQ_PRIVATE_DATA, req_msg); |
---|
1730 | 1840 | } |
---|
1731 | 1841 | |
---|
1732 | 1842 | static void cm_process_work(struct cm_id_private *cm_id_priv, |
---|
.. | .. |
---|
1760 | 1870 | const void *private_data, u8 private_data_len) |
---|
1761 | 1871 | { |
---|
1762 | 1872 | cm_format_mad_hdr(&mra_msg->hdr, CM_MRA_ATTR_ID, cm_id_priv->tid); |
---|
1763 | | - cm_mra_set_msg_mraed(mra_msg, msg_mraed); |
---|
1764 | | - mra_msg->local_comm_id = cm_id_priv->id.local_id; |
---|
1765 | | - mra_msg->remote_comm_id = cm_id_priv->id.remote_id; |
---|
1766 | | - cm_mra_set_service_timeout(mra_msg, service_timeout); |
---|
| 1873 | + IBA_SET(CM_MRA_MESSAGE_MRAED, mra_msg, msg_mraed); |
---|
| 1874 | + IBA_SET(CM_MRA_LOCAL_COMM_ID, mra_msg, |
---|
| 1875 | + be32_to_cpu(cm_id_priv->id.local_id)); |
---|
| 1876 | + IBA_SET(CM_MRA_REMOTE_COMM_ID, mra_msg, |
---|
| 1877 | + be32_to_cpu(cm_id_priv->id.remote_id)); |
---|
| 1878 | + IBA_SET(CM_MRA_SERVICE_TIMEOUT, mra_msg, service_timeout); |
---|
1767 | 1879 | |
---|
1768 | 1880 | if (private_data && private_data_len) |
---|
1769 | | - memcpy(mra_msg->private_data, private_data, private_data_len); |
---|
| 1881 | + IBA_SET_MEM(CM_MRA_PRIVATE_DATA, mra_msg, private_data, |
---|
| 1882 | + private_data_len); |
---|
1770 | 1883 | } |
---|
1771 | 1884 | |
---|
1772 | 1885 | static void cm_format_rej(struct cm_rej_msg *rej_msg, |
---|
1773 | 1886 | struct cm_id_private *cm_id_priv, |
---|
1774 | | - enum ib_cm_rej_reason reason, |
---|
1775 | | - void *ari, |
---|
1776 | | - u8 ari_length, |
---|
1777 | | - const void *private_data, |
---|
1778 | | - u8 private_data_len) |
---|
| 1887 | + enum ib_cm_rej_reason reason, void *ari, |
---|
| 1888 | + u8 ari_length, const void *private_data, |
---|
| 1889 | + u8 private_data_len, enum ib_cm_state state) |
---|
1779 | 1890 | { |
---|
1780 | | - cm_format_mad_hdr(&rej_msg->hdr, CM_REJ_ATTR_ID, cm_id_priv->tid); |
---|
1781 | | - rej_msg->remote_comm_id = cm_id_priv->id.remote_id; |
---|
| 1891 | + lockdep_assert_held(&cm_id_priv->lock); |
---|
1782 | 1892 | |
---|
1783 | | - switch(cm_id_priv->id.state) { |
---|
| 1893 | + cm_format_mad_hdr(&rej_msg->hdr, CM_REJ_ATTR_ID, cm_id_priv->tid); |
---|
| 1894 | + IBA_SET(CM_REJ_REMOTE_COMM_ID, rej_msg, |
---|
| 1895 | + be32_to_cpu(cm_id_priv->id.remote_id)); |
---|
| 1896 | + |
---|
| 1897 | + switch (state) { |
---|
1784 | 1898 | case IB_CM_REQ_RCVD: |
---|
1785 | | - rej_msg->local_comm_id = 0; |
---|
1786 | | - cm_rej_set_msg_rejected(rej_msg, CM_MSG_RESPONSE_REQ); |
---|
| 1899 | + IBA_SET(CM_REJ_LOCAL_COMM_ID, rej_msg, be32_to_cpu(0)); |
---|
| 1900 | + IBA_SET(CM_REJ_MESSAGE_REJECTED, rej_msg, CM_MSG_RESPONSE_REQ); |
---|
1787 | 1901 | break; |
---|
1788 | 1902 | case IB_CM_MRA_REQ_SENT: |
---|
1789 | | - rej_msg->local_comm_id = cm_id_priv->id.local_id; |
---|
1790 | | - cm_rej_set_msg_rejected(rej_msg, CM_MSG_RESPONSE_REQ); |
---|
| 1903 | + IBA_SET(CM_REJ_LOCAL_COMM_ID, rej_msg, |
---|
| 1904 | + be32_to_cpu(cm_id_priv->id.local_id)); |
---|
| 1905 | + IBA_SET(CM_REJ_MESSAGE_REJECTED, rej_msg, CM_MSG_RESPONSE_REQ); |
---|
1791 | 1906 | break; |
---|
1792 | 1907 | case IB_CM_REP_RCVD: |
---|
1793 | 1908 | case IB_CM_MRA_REP_SENT: |
---|
1794 | | - rej_msg->local_comm_id = cm_id_priv->id.local_id; |
---|
1795 | | - cm_rej_set_msg_rejected(rej_msg, CM_MSG_RESPONSE_REP); |
---|
| 1909 | + IBA_SET(CM_REJ_LOCAL_COMM_ID, rej_msg, |
---|
| 1910 | + be32_to_cpu(cm_id_priv->id.local_id)); |
---|
| 1911 | + IBA_SET(CM_REJ_MESSAGE_REJECTED, rej_msg, CM_MSG_RESPONSE_REP); |
---|
1796 | 1912 | break; |
---|
1797 | 1913 | default: |
---|
1798 | | - rej_msg->local_comm_id = cm_id_priv->id.local_id; |
---|
1799 | | - cm_rej_set_msg_rejected(rej_msg, CM_MSG_RESPONSE_OTHER); |
---|
| 1914 | + IBA_SET(CM_REJ_LOCAL_COMM_ID, rej_msg, |
---|
| 1915 | + be32_to_cpu(cm_id_priv->id.local_id)); |
---|
| 1916 | + IBA_SET(CM_REJ_MESSAGE_REJECTED, rej_msg, |
---|
| 1917 | + CM_MSG_RESPONSE_OTHER); |
---|
1800 | 1918 | break; |
---|
1801 | 1919 | } |
---|
1802 | 1920 | |
---|
1803 | | - rej_msg->reason = cpu_to_be16(reason); |
---|
| 1921 | + IBA_SET(CM_REJ_REASON, rej_msg, reason); |
---|
1804 | 1922 | if (ari && ari_length) { |
---|
1805 | | - cm_rej_set_reject_info_len(rej_msg, ari_length); |
---|
1806 | | - memcpy(rej_msg->ari, ari, ari_length); |
---|
| 1923 | + IBA_SET(CM_REJ_REJECTED_INFO_LENGTH, rej_msg, ari_length); |
---|
| 1924 | + IBA_SET_MEM(CM_REJ_ARI, rej_msg, ari, ari_length); |
---|
1807 | 1925 | } |
---|
1808 | 1926 | |
---|
1809 | 1927 | if (private_data && private_data_len) |
---|
1810 | | - memcpy(rej_msg->private_data, private_data, private_data_len); |
---|
| 1928 | + IBA_SET_MEM(CM_REJ_PRIVATE_DATA, rej_msg, private_data, |
---|
| 1929 | + private_data_len); |
---|
1811 | 1930 | } |
---|
1812 | 1931 | |
---|
1813 | 1932 | static void cm_dup_req_handler(struct cm_work *work, |
---|
.. | .. |
---|
1820 | 1939 | counter[CM_REQ_COUNTER]); |
---|
1821 | 1940 | |
---|
1822 | 1941 | /* Quick state check to discard duplicate REQs. */ |
---|
1823 | | - if (cm_id_priv->id.state == IB_CM_REQ_RCVD) |
---|
| 1942 | + spin_lock_irq(&cm_id_priv->lock); |
---|
| 1943 | + if (cm_id_priv->id.state == IB_CM_REQ_RCVD) { |
---|
| 1944 | + spin_unlock_irq(&cm_id_priv->lock); |
---|
1824 | 1945 | return; |
---|
| 1946 | + } |
---|
| 1947 | + spin_unlock_irq(&cm_id_priv->lock); |
---|
1825 | 1948 | |
---|
1826 | 1949 | ret = cm_alloc_response_msg(work->port, work->mad_recv_wc, &msg); |
---|
1827 | 1950 | if (ret) |
---|
.. | .. |
---|
1836 | 1959 | cm_id_priv->private_data_len); |
---|
1837 | 1960 | break; |
---|
1838 | 1961 | case IB_CM_TIMEWAIT: |
---|
1839 | | - cm_format_rej((struct cm_rej_msg *) msg->mad, cm_id_priv, |
---|
1840 | | - IB_CM_REJ_STALE_CONN, NULL, 0, NULL, 0); |
---|
| 1962 | + cm_format_rej((struct cm_rej_msg *)msg->mad, cm_id_priv, |
---|
| 1963 | + IB_CM_REJ_STALE_CONN, NULL, 0, NULL, 0, |
---|
| 1964 | + IB_CM_TIMEWAIT); |
---|
1841 | 1965 | break; |
---|
1842 | 1966 | default: |
---|
1843 | 1967 | goto unlock; |
---|
1844 | 1968 | } |
---|
1845 | 1969 | spin_unlock_irq(&cm_id_priv->lock); |
---|
1846 | 1970 | |
---|
| 1971 | + trace_icm_send_dup_req(&cm_id_priv->id); |
---|
1847 | 1972 | ret = ib_post_send_mad(msg, NULL); |
---|
1848 | 1973 | if (ret) |
---|
1849 | 1974 | goto free; |
---|
.. | .. |
---|
1859 | 1984 | struct cm_id_private *listen_cm_id_priv, *cur_cm_id_priv; |
---|
1860 | 1985 | struct cm_timewait_info *timewait_info; |
---|
1861 | 1986 | struct cm_req_msg *req_msg; |
---|
1862 | | - struct ib_cm_id *cm_id; |
---|
1863 | 1987 | |
---|
1864 | 1988 | req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad; |
---|
1865 | 1989 | |
---|
.. | .. |
---|
1867 | 1991 | spin_lock_irq(&cm.lock); |
---|
1868 | 1992 | timewait_info = cm_insert_remote_id(cm_id_priv->timewait_info); |
---|
1869 | 1993 | if (timewait_info) { |
---|
1870 | | - cur_cm_id_priv = cm_get_id(timewait_info->work.local_id, |
---|
| 1994 | + cur_cm_id_priv = cm_acquire_id(timewait_info->work.local_id, |
---|
1871 | 1995 | timewait_info->work.remote_id); |
---|
1872 | 1996 | spin_unlock_irq(&cm.lock); |
---|
1873 | 1997 | if (cur_cm_id_priv) { |
---|
.. | .. |
---|
1880 | 2004 | /* Check for stale connections. */ |
---|
1881 | 2005 | timewait_info = cm_insert_remote_qpn(cm_id_priv->timewait_info); |
---|
1882 | 2006 | if (timewait_info) { |
---|
1883 | | - cm_cleanup_timewait(cm_id_priv->timewait_info); |
---|
1884 | | - cur_cm_id_priv = cm_get_id(timewait_info->work.local_id, |
---|
| 2007 | + cm_remove_remote(cm_id_priv); |
---|
| 2008 | + cur_cm_id_priv = cm_acquire_id(timewait_info->work.local_id, |
---|
1885 | 2009 | timewait_info->work.remote_id); |
---|
1886 | 2010 | |
---|
1887 | 2011 | spin_unlock_irq(&cm.lock); |
---|
.. | .. |
---|
1889 | 2013 | IB_CM_REJ_STALE_CONN, CM_MSG_RESPONSE_REQ, |
---|
1890 | 2014 | NULL, 0); |
---|
1891 | 2015 | if (cur_cm_id_priv) { |
---|
1892 | | - cm_id = &cur_cm_id_priv->id; |
---|
1893 | | - ib_send_cm_dreq(cm_id, NULL, 0); |
---|
| 2016 | + ib_send_cm_dreq(&cur_cm_id_priv->id, NULL, 0); |
---|
1894 | 2017 | cm_deref_id(cur_cm_id_priv); |
---|
1895 | 2018 | } |
---|
1896 | 2019 | return NULL; |
---|
1897 | 2020 | } |
---|
1898 | 2021 | |
---|
1899 | 2022 | /* Find matching listen request. */ |
---|
1900 | | - listen_cm_id_priv = cm_find_listen(cm_id_priv->id.device, |
---|
1901 | | - req_msg->service_id); |
---|
| 2023 | + listen_cm_id_priv = cm_find_listen( |
---|
| 2024 | + cm_id_priv->id.device, |
---|
| 2025 | + cpu_to_be64(IBA_GET(CM_REQ_SERVICE_ID, req_msg))); |
---|
1902 | 2026 | if (!listen_cm_id_priv) { |
---|
1903 | | - cm_cleanup_timewait(cm_id_priv->timewait_info); |
---|
| 2027 | + cm_remove_remote(cm_id_priv); |
---|
1904 | 2028 | spin_unlock_irq(&cm.lock); |
---|
1905 | 2029 | cm_issue_rej(work->port, work->mad_recv_wc, |
---|
1906 | 2030 | IB_CM_REJ_INVALID_SERVICE_ID, CM_MSG_RESPONSE_REQ, |
---|
1907 | 2031 | NULL, 0); |
---|
1908 | | - goto out; |
---|
| 2032 | + return NULL; |
---|
1909 | 2033 | } |
---|
1910 | | - atomic_inc(&listen_cm_id_priv->refcount); |
---|
1911 | | - atomic_inc(&cm_id_priv->refcount); |
---|
1912 | | - cm_id_priv->id.state = IB_CM_REQ_RCVD; |
---|
1913 | | - atomic_inc(&cm_id_priv->work_count); |
---|
1914 | 2034 | spin_unlock_irq(&cm.lock); |
---|
1915 | | -out: |
---|
1916 | 2035 | return listen_cm_id_priv; |
---|
1917 | 2036 | } |
---|
1918 | 2037 | |
---|
.. | .. |
---|
1923 | 2042 | */ |
---|
1924 | 2043 | static void cm_process_routed_req(struct cm_req_msg *req_msg, struct ib_wc *wc) |
---|
1925 | 2044 | { |
---|
1926 | | - if (!cm_req_get_primary_subnet_local(req_msg)) { |
---|
1927 | | - if (req_msg->primary_local_lid == IB_LID_PERMISSIVE) { |
---|
1928 | | - req_msg->primary_local_lid = ib_lid_be16(wc->slid); |
---|
1929 | | - cm_req_set_primary_sl(req_msg, wc->sl); |
---|
| 2045 | + if (!IBA_GET(CM_REQ_PRIMARY_SUBNET_LOCAL, req_msg)) { |
---|
| 2046 | + if (cpu_to_be16(IBA_GET(CM_REQ_PRIMARY_LOCAL_PORT_LID, |
---|
| 2047 | + req_msg)) == IB_LID_PERMISSIVE) { |
---|
| 2048 | + IBA_SET(CM_REQ_PRIMARY_LOCAL_PORT_LID, req_msg, |
---|
| 2049 | + be16_to_cpu(ib_lid_be16(wc->slid))); |
---|
| 2050 | + IBA_SET(CM_REQ_PRIMARY_SL, req_msg, wc->sl); |
---|
1930 | 2051 | } |
---|
1931 | 2052 | |
---|
1932 | | - if (req_msg->primary_remote_lid == IB_LID_PERMISSIVE) |
---|
1933 | | - req_msg->primary_remote_lid = cpu_to_be16(wc->dlid_path_bits); |
---|
| 2053 | + if (cpu_to_be16(IBA_GET(CM_REQ_PRIMARY_REMOTE_PORT_LID, |
---|
| 2054 | + req_msg)) == IB_LID_PERMISSIVE) |
---|
| 2055 | + IBA_SET(CM_REQ_PRIMARY_REMOTE_PORT_LID, req_msg, |
---|
| 2056 | + wc->dlid_path_bits); |
---|
1934 | 2057 | } |
---|
1935 | 2058 | |
---|
1936 | | - if (!cm_req_get_alt_subnet_local(req_msg)) { |
---|
1937 | | - if (req_msg->alt_local_lid == IB_LID_PERMISSIVE) { |
---|
1938 | | - req_msg->alt_local_lid = ib_lid_be16(wc->slid); |
---|
1939 | | - cm_req_set_alt_sl(req_msg, wc->sl); |
---|
| 2059 | + if (!IBA_GET(CM_REQ_ALTERNATE_SUBNET_LOCAL, req_msg)) { |
---|
| 2060 | + if (cpu_to_be16(IBA_GET(CM_REQ_ALTERNATE_LOCAL_PORT_LID, |
---|
| 2061 | + req_msg)) == IB_LID_PERMISSIVE) { |
---|
| 2062 | + IBA_SET(CM_REQ_ALTERNATE_LOCAL_PORT_LID, req_msg, |
---|
| 2063 | + be16_to_cpu(ib_lid_be16(wc->slid))); |
---|
| 2064 | + IBA_SET(CM_REQ_ALTERNATE_SL, req_msg, wc->sl); |
---|
1940 | 2065 | } |
---|
1941 | 2066 | |
---|
1942 | | - if (req_msg->alt_remote_lid == IB_LID_PERMISSIVE) |
---|
1943 | | - req_msg->alt_remote_lid = cpu_to_be16(wc->dlid_path_bits); |
---|
| 2067 | + if (cpu_to_be16(IBA_GET(CM_REQ_ALTERNATE_REMOTE_PORT_LID, |
---|
| 2068 | + req_msg)) == IB_LID_PERMISSIVE) |
---|
| 2069 | + IBA_SET(CM_REQ_ALTERNATE_REMOTE_PORT_LID, req_msg, |
---|
| 2070 | + wc->dlid_path_bits); |
---|
1944 | 2071 | } |
---|
1945 | 2072 | } |
---|
1946 | 2073 | |
---|
1947 | 2074 | static int cm_req_handler(struct cm_work *work) |
---|
1948 | 2075 | { |
---|
1949 | | - struct ib_cm_id *cm_id; |
---|
1950 | 2076 | struct cm_id_private *cm_id_priv, *listen_cm_id_priv; |
---|
1951 | 2077 | struct cm_req_msg *req_msg; |
---|
1952 | 2078 | const struct ib_global_route *grh; |
---|
.. | .. |
---|
1955 | 2081 | |
---|
1956 | 2082 | req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad; |
---|
1957 | 2083 | |
---|
1958 | | - cm_id = ib_create_cm_id(work->port->cm_dev->ib_device, NULL, NULL); |
---|
1959 | | - if (IS_ERR(cm_id)) |
---|
1960 | | - return PTR_ERR(cm_id); |
---|
| 2084 | + cm_id_priv = |
---|
| 2085 | + cm_alloc_id_priv(work->port->cm_dev->ib_device, NULL, NULL); |
---|
| 2086 | + if (IS_ERR(cm_id_priv)) |
---|
| 2087 | + return PTR_ERR(cm_id_priv); |
---|
1961 | 2088 | |
---|
1962 | | - cm_id_priv = container_of(cm_id, struct cm_id_private, id); |
---|
1963 | | - cm_id_priv->id.remote_id = req_msg->local_comm_id; |
---|
| 2089 | + cm_id_priv->id.remote_id = |
---|
| 2090 | + cpu_to_be32(IBA_GET(CM_REQ_LOCAL_COMM_ID, req_msg)); |
---|
| 2091 | + cm_id_priv->id.service_id = |
---|
| 2092 | + cpu_to_be64(IBA_GET(CM_REQ_SERVICE_ID, req_msg)); |
---|
| 2093 | + cm_id_priv->id.service_mask = ~cpu_to_be64(0); |
---|
| 2094 | + cm_id_priv->tid = req_msg->hdr.tid; |
---|
| 2095 | + cm_id_priv->timeout_ms = cm_convert_to_ms( |
---|
| 2096 | + IBA_GET(CM_REQ_LOCAL_CM_RESPONSE_TIMEOUT, req_msg)); |
---|
| 2097 | + cm_id_priv->max_cm_retries = IBA_GET(CM_REQ_MAX_CM_RETRIES, req_msg); |
---|
| 2098 | + cm_id_priv->remote_qpn = |
---|
| 2099 | + cpu_to_be32(IBA_GET(CM_REQ_LOCAL_QPN, req_msg)); |
---|
| 2100 | + cm_id_priv->initiator_depth = |
---|
| 2101 | + IBA_GET(CM_REQ_RESPONDER_RESOURCES, req_msg); |
---|
| 2102 | + cm_id_priv->responder_resources = |
---|
| 2103 | + IBA_GET(CM_REQ_INITIATOR_DEPTH, req_msg); |
---|
| 2104 | + cm_id_priv->path_mtu = IBA_GET(CM_REQ_PATH_PACKET_PAYLOAD_MTU, req_msg); |
---|
| 2105 | + cm_id_priv->pkey = cpu_to_be16(IBA_GET(CM_REQ_PARTITION_KEY, req_msg)); |
---|
| 2106 | + cm_id_priv->sq_psn = cpu_to_be32(IBA_GET(CM_REQ_STARTING_PSN, req_msg)); |
---|
| 2107 | + cm_id_priv->retry_count = IBA_GET(CM_REQ_RETRY_COUNT, req_msg); |
---|
| 2108 | + cm_id_priv->rnr_retry_count = IBA_GET(CM_REQ_RNR_RETRY_COUNT, req_msg); |
---|
| 2109 | + cm_id_priv->qp_type = cm_req_get_qp_type(req_msg); |
---|
| 2110 | + |
---|
1964 | 2111 | ret = cm_init_av_for_response(work->port, work->mad_recv_wc->wc, |
---|
1965 | 2112 | work->mad_recv_wc->recv_buf.grh, |
---|
1966 | 2113 | &cm_id_priv->av); |
---|
.. | .. |
---|
1973 | 2120 | cm_id_priv->timewait_info = NULL; |
---|
1974 | 2121 | goto destroy; |
---|
1975 | 2122 | } |
---|
1976 | | - cm_id_priv->timewait_info->work.remote_id = req_msg->local_comm_id; |
---|
1977 | | - cm_id_priv->timewait_info->remote_ca_guid = req_msg->local_ca_guid; |
---|
1978 | | - cm_id_priv->timewait_info->remote_qpn = cm_req_get_local_qpn(req_msg); |
---|
| 2123 | + cm_id_priv->timewait_info->work.remote_id = cm_id_priv->id.remote_id; |
---|
| 2124 | + cm_id_priv->timewait_info->remote_ca_guid = |
---|
| 2125 | + cpu_to_be64(IBA_GET(CM_REQ_LOCAL_CA_GUID, req_msg)); |
---|
| 2126 | + cm_id_priv->timewait_info->remote_qpn = cm_id_priv->remote_qpn; |
---|
| 2127 | + |
---|
| 2128 | + /* |
---|
| 2129 | + * Note that the ID pointer is not in the xarray at this point, |
---|
| 2130 | + * so this set is only visible to the local thread. |
---|
| 2131 | + */ |
---|
| 2132 | + cm_id_priv->id.state = IB_CM_REQ_RCVD; |
---|
1979 | 2133 | |
---|
1980 | 2134 | listen_cm_id_priv = cm_match_req(work, cm_id_priv); |
---|
1981 | 2135 | if (!listen_cm_id_priv) { |
---|
1982 | | - pr_debug("%s: local_id %d, no listen_cm_id_priv\n", __func__, |
---|
1983 | | - be32_to_cpu(cm_id->local_id)); |
---|
| 2136 | + trace_icm_no_listener_err(&cm_id_priv->id); |
---|
| 2137 | + cm_id_priv->id.state = IB_CM_IDLE; |
---|
1984 | 2138 | ret = -EINVAL; |
---|
1985 | 2139 | goto destroy; |
---|
1986 | 2140 | } |
---|
1987 | 2141 | |
---|
1988 | | - cm_id_priv->id.cm_handler = listen_cm_id_priv->id.cm_handler; |
---|
1989 | | - cm_id_priv->id.context = listen_cm_id_priv->id.context; |
---|
1990 | | - cm_id_priv->id.service_id = req_msg->service_id; |
---|
1991 | | - cm_id_priv->id.service_mask = ~cpu_to_be64(0); |
---|
1992 | | - |
---|
1993 | | - cm_process_routed_req(req_msg, work->mad_recv_wc->wc); |
---|
| 2142 | + if (cm_id_priv->av.ah_attr.type != RDMA_AH_ATTR_TYPE_ROCE) |
---|
| 2143 | + cm_process_routed_req(req_msg, work->mad_recv_wc->wc); |
---|
1994 | 2144 | |
---|
1995 | 2145 | memset(&work->path[0], 0, sizeof(work->path[0])); |
---|
1996 | 2146 | if (cm_req_has_alt_path(req_msg)) |
---|
.. | .. |
---|
1998 | 2148 | grh = rdma_ah_read_grh(&cm_id_priv->av.ah_attr); |
---|
1999 | 2149 | gid_attr = grh->sgid_attr; |
---|
2000 | 2150 | |
---|
2001 | | - if (gid_attr && gid_attr->ndev) { |
---|
| 2151 | + if (gid_attr && |
---|
| 2152 | + rdma_protocol_roce(work->port->cm_dev->ib_device, |
---|
| 2153 | + work->port->port_num)) { |
---|
2002 | 2154 | work->path[0].rec_type = |
---|
2003 | 2155 | sa_conv_gid_to_pathrec_type(gid_attr->gid_type); |
---|
2004 | 2156 | } else { |
---|
2005 | | - /* If no GID attribute or ndev is null, it is not RoCE. */ |
---|
2006 | | - cm_path_set_rec_type(work->port->cm_dev->ib_device, |
---|
2007 | | - work->port->port_num, |
---|
2008 | | - &work->path[0], |
---|
2009 | | - &req_msg->primary_local_gid); |
---|
| 2157 | + cm_path_set_rec_type( |
---|
| 2158 | + work->port->cm_dev->ib_device, work->port->port_num, |
---|
| 2159 | + &work->path[0], |
---|
| 2160 | + IBA_GET_MEM_PTR(CM_REQ_PRIMARY_LOCAL_PORT_GID, |
---|
| 2161 | + req_msg)); |
---|
2010 | 2162 | } |
---|
2011 | 2163 | if (cm_req_has_alt_path(req_msg)) |
---|
2012 | 2164 | work->path[1].rec_type = work->path[0].rec_type; |
---|
2013 | 2165 | cm_format_paths_from_req(req_msg, &work->path[0], |
---|
2014 | | - &work->path[1]); |
---|
| 2166 | + &work->path[1], work->mad_recv_wc->wc); |
---|
2015 | 2167 | if (cm_id_priv->av.ah_attr.type == RDMA_AH_ATTR_TYPE_ROCE) |
---|
2016 | 2168 | sa_path_set_dmac(&work->path[0], |
---|
2017 | 2169 | cm_id_priv->av.ah_attr.roce.dmac); |
---|
.. | .. |
---|
2025 | 2177 | work->port->port_num, 0, |
---|
2026 | 2178 | &work->path[0].sgid); |
---|
2027 | 2179 | if (err) |
---|
2028 | | - ib_send_cm_rej(cm_id, IB_CM_REJ_INVALID_GID, |
---|
| 2180 | + ib_send_cm_rej(&cm_id_priv->id, IB_CM_REJ_INVALID_GID, |
---|
2029 | 2181 | NULL, 0, NULL, 0); |
---|
2030 | 2182 | else |
---|
2031 | | - ib_send_cm_rej(cm_id, IB_CM_REJ_INVALID_GID, |
---|
| 2183 | + ib_send_cm_rej(&cm_id_priv->id, IB_CM_REJ_INVALID_GID, |
---|
2032 | 2184 | &work->path[0].sgid, |
---|
2033 | 2185 | sizeof(work->path[0].sgid), |
---|
2034 | 2186 | NULL, 0); |
---|
.. | .. |
---|
2038 | 2190 | ret = cm_init_av_by_path(&work->path[1], NULL, |
---|
2039 | 2191 | &cm_id_priv->alt_av, cm_id_priv); |
---|
2040 | 2192 | if (ret) { |
---|
2041 | | - ib_send_cm_rej(cm_id, IB_CM_REJ_INVALID_ALT_GID, |
---|
| 2193 | + ib_send_cm_rej(&cm_id_priv->id, |
---|
| 2194 | + IB_CM_REJ_INVALID_ALT_GID, |
---|
2042 | 2195 | &work->path[0].sgid, |
---|
2043 | 2196 | sizeof(work->path[0].sgid), NULL, 0); |
---|
2044 | 2197 | goto rejected; |
---|
2045 | 2198 | } |
---|
2046 | 2199 | } |
---|
2047 | | - cm_id_priv->tid = req_msg->hdr.tid; |
---|
2048 | | - cm_id_priv->timeout_ms = cm_convert_to_ms( |
---|
2049 | | - cm_req_get_local_resp_timeout(req_msg)); |
---|
2050 | | - cm_id_priv->max_cm_retries = cm_req_get_max_cm_retries(req_msg); |
---|
2051 | | - cm_id_priv->remote_qpn = cm_req_get_local_qpn(req_msg); |
---|
2052 | | - cm_id_priv->initiator_depth = cm_req_get_resp_res(req_msg); |
---|
2053 | | - cm_id_priv->responder_resources = cm_req_get_init_depth(req_msg); |
---|
2054 | | - cm_id_priv->path_mtu = cm_req_get_path_mtu(req_msg); |
---|
2055 | | - cm_id_priv->pkey = req_msg->pkey; |
---|
2056 | | - cm_id_priv->sq_psn = cm_req_get_starting_psn(req_msg); |
---|
2057 | | - cm_id_priv->retry_count = cm_req_get_retry_count(req_msg); |
---|
2058 | | - cm_id_priv->rnr_retry_count = cm_req_get_rnr_retry_count(req_msg); |
---|
2059 | | - cm_id_priv->qp_type = cm_req_get_qp_type(req_msg); |
---|
2060 | 2200 | |
---|
| 2201 | + cm_id_priv->id.cm_handler = listen_cm_id_priv->id.cm_handler; |
---|
| 2202 | + cm_id_priv->id.context = listen_cm_id_priv->id.context; |
---|
2061 | 2203 | cm_format_req_event(work, cm_id_priv, &listen_cm_id_priv->id); |
---|
2062 | | - cm_process_work(cm_id_priv, work); |
---|
| 2204 | + |
---|
| 2205 | + /* Now MAD handlers can see the new ID */ |
---|
| 2206 | + spin_lock_irq(&cm_id_priv->lock); |
---|
| 2207 | + cm_finalize_id(cm_id_priv); |
---|
| 2208 | + |
---|
| 2209 | + /* Refcount belongs to the event, pairs with cm_process_work() */ |
---|
| 2210 | + refcount_inc(&cm_id_priv->refcount); |
---|
| 2211 | + cm_queue_work_unlock(cm_id_priv, work); |
---|
| 2212 | + /* |
---|
| 2213 | + * Since this ID was just created and was not made visible to other MAD |
---|
| 2214 | + * handlers until the cm_finalize_id() above we know that the |
---|
| 2215 | + * cm_process_work() will deliver the event and the listen_cm_id |
---|
| 2216 | + * embedded in the event can be derefed here. |
---|
| 2217 | + */ |
---|
2063 | 2218 | cm_deref_id(listen_cm_id_priv); |
---|
2064 | 2219 | return 0; |
---|
2065 | 2220 | |
---|
2066 | 2221 | rejected: |
---|
2067 | | - atomic_dec(&cm_id_priv->refcount); |
---|
2068 | 2222 | cm_deref_id(listen_cm_id_priv); |
---|
2069 | 2223 | destroy: |
---|
2070 | | - ib_destroy_cm_id(cm_id); |
---|
| 2224 | + ib_destroy_cm_id(&cm_id_priv->id); |
---|
2071 | 2225 | return ret; |
---|
2072 | 2226 | } |
---|
2073 | 2227 | |
---|
.. | .. |
---|
2075 | 2229 | struct cm_id_private *cm_id_priv, |
---|
2076 | 2230 | struct ib_cm_rep_param *param) |
---|
2077 | 2231 | { |
---|
2078 | | - cm_format_mad_hdr(&rep_msg->hdr, CM_REP_ATTR_ID, cm_id_priv->tid); |
---|
2079 | | - rep_msg->local_comm_id = cm_id_priv->id.local_id; |
---|
2080 | | - rep_msg->remote_comm_id = cm_id_priv->id.remote_id; |
---|
2081 | | - cm_rep_set_starting_psn(rep_msg, cpu_to_be32(param->starting_psn)); |
---|
2082 | | - rep_msg->resp_resources = param->responder_resources; |
---|
2083 | | - cm_rep_set_target_ack_delay(rep_msg, |
---|
2084 | | - cm_id_priv->av.port->cm_dev->ack_delay); |
---|
2085 | | - cm_rep_set_failover(rep_msg, param->failover_accepted); |
---|
2086 | | - cm_rep_set_rnr_retry_count(rep_msg, param->rnr_retry_count); |
---|
2087 | | - rep_msg->local_ca_guid = cm_id_priv->id.device->node_guid; |
---|
| 2232 | + cm_format_mad_ece_hdr(&rep_msg->hdr, CM_REP_ATTR_ID, cm_id_priv->tid, |
---|
| 2233 | + param->ece.attr_mod); |
---|
| 2234 | + IBA_SET(CM_REP_LOCAL_COMM_ID, rep_msg, |
---|
| 2235 | + be32_to_cpu(cm_id_priv->id.local_id)); |
---|
| 2236 | + IBA_SET(CM_REP_REMOTE_COMM_ID, rep_msg, |
---|
| 2237 | + be32_to_cpu(cm_id_priv->id.remote_id)); |
---|
| 2238 | + IBA_SET(CM_REP_STARTING_PSN, rep_msg, param->starting_psn); |
---|
| 2239 | + IBA_SET(CM_REP_RESPONDER_RESOURCES, rep_msg, |
---|
| 2240 | + param->responder_resources); |
---|
| 2241 | + IBA_SET(CM_REP_TARGET_ACK_DELAY, rep_msg, |
---|
| 2242 | + cm_id_priv->av.port->cm_dev->ack_delay); |
---|
| 2243 | + IBA_SET(CM_REP_FAILOVER_ACCEPTED, rep_msg, param->failover_accepted); |
---|
| 2244 | + IBA_SET(CM_REP_RNR_RETRY_COUNT, rep_msg, param->rnr_retry_count); |
---|
| 2245 | + IBA_SET(CM_REP_LOCAL_CA_GUID, rep_msg, |
---|
| 2246 | + be64_to_cpu(cm_id_priv->id.device->node_guid)); |
---|
2088 | 2247 | |
---|
2089 | 2248 | if (cm_id_priv->qp_type != IB_QPT_XRC_TGT) { |
---|
2090 | | - rep_msg->initiator_depth = param->initiator_depth; |
---|
2091 | | - cm_rep_set_flow_ctrl(rep_msg, param->flow_control); |
---|
2092 | | - cm_rep_set_srq(rep_msg, param->srq); |
---|
2093 | | - cm_rep_set_local_qpn(rep_msg, cpu_to_be32(param->qp_num)); |
---|
| 2249 | + IBA_SET(CM_REP_INITIATOR_DEPTH, rep_msg, |
---|
| 2250 | + param->initiator_depth); |
---|
| 2251 | + IBA_SET(CM_REP_END_TO_END_FLOW_CONTROL, rep_msg, |
---|
| 2252 | + param->flow_control); |
---|
| 2253 | + IBA_SET(CM_REP_SRQ, rep_msg, param->srq); |
---|
| 2254 | + IBA_SET(CM_REP_LOCAL_QPN, rep_msg, param->qp_num); |
---|
2094 | 2255 | } else { |
---|
2095 | | - cm_rep_set_srq(rep_msg, 1); |
---|
2096 | | - cm_rep_set_local_eecn(rep_msg, cpu_to_be32(param->qp_num)); |
---|
| 2256 | + IBA_SET(CM_REP_SRQ, rep_msg, 1); |
---|
| 2257 | + IBA_SET(CM_REP_LOCAL_EE_CONTEXT_NUMBER, rep_msg, param->qp_num); |
---|
2097 | 2258 | } |
---|
2098 | 2259 | |
---|
| 2260 | + IBA_SET(CM_REP_VENDOR_ID_L, rep_msg, param->ece.vendor_id); |
---|
| 2261 | + IBA_SET(CM_REP_VENDOR_ID_M, rep_msg, param->ece.vendor_id >> 8); |
---|
| 2262 | + IBA_SET(CM_REP_VENDOR_ID_H, rep_msg, param->ece.vendor_id >> 16); |
---|
| 2263 | + |
---|
2099 | 2264 | if (param->private_data && param->private_data_len) |
---|
2100 | | - memcpy(rep_msg->private_data, param->private_data, |
---|
2101 | | - param->private_data_len); |
---|
| 2265 | + IBA_SET_MEM(CM_REP_PRIVATE_DATA, rep_msg, param->private_data, |
---|
| 2266 | + param->private_data_len); |
---|
2102 | 2267 | } |
---|
2103 | 2268 | |
---|
2104 | 2269 | int ib_send_cm_rep(struct ib_cm_id *cm_id, |
---|
.. | .. |
---|
2118 | 2283 | spin_lock_irqsave(&cm_id_priv->lock, flags); |
---|
2119 | 2284 | if (cm_id->state != IB_CM_REQ_RCVD && |
---|
2120 | 2285 | cm_id->state != IB_CM_MRA_REQ_SENT) { |
---|
2121 | | - pr_debug("%s: local_comm_id %d, cm_id->state: %d\n", __func__, |
---|
2122 | | - be32_to_cpu(cm_id_priv->id.local_id), cm_id->state); |
---|
| 2286 | + trace_icm_send_rep_err(cm_id_priv->id.local_id, cm_id->state); |
---|
2123 | 2287 | ret = -EINVAL; |
---|
2124 | 2288 | goto out; |
---|
2125 | 2289 | } |
---|
.. | .. |
---|
2133 | 2297 | msg->timeout_ms = cm_id_priv->timeout_ms; |
---|
2134 | 2298 | msg->context[1] = (void *) (unsigned long) IB_CM_REP_SENT; |
---|
2135 | 2299 | |
---|
| 2300 | + trace_icm_send_rep(cm_id); |
---|
2136 | 2301 | ret = ib_post_send_mad(msg, NULL); |
---|
2137 | 2302 | if (ret) { |
---|
2138 | 2303 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
---|
.. | .. |
---|
2144 | 2309 | cm_id_priv->msg = msg; |
---|
2145 | 2310 | cm_id_priv->initiator_depth = param->initiator_depth; |
---|
2146 | 2311 | cm_id_priv->responder_resources = param->responder_resources; |
---|
2147 | | - cm_id_priv->rq_psn = cm_rep_get_starting_psn(rep_msg); |
---|
| 2312 | + cm_id_priv->rq_psn = cpu_to_be32(IBA_GET(CM_REP_STARTING_PSN, rep_msg)); |
---|
| 2313 | + WARN_ONCE(param->qp_num & 0xFF000000, |
---|
| 2314 | + "IBTA declares QPN to be 24 bits, but it is 0x%X\n", |
---|
| 2315 | + param->qp_num); |
---|
2148 | 2316 | cm_id_priv->local_qpn = cpu_to_be32(param->qp_num & 0xFFFFFF); |
---|
2149 | 2317 | |
---|
2150 | 2318 | out: spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
---|
.. | .. |
---|
2158 | 2326 | u8 private_data_len) |
---|
2159 | 2327 | { |
---|
2160 | 2328 | cm_format_mad_hdr(&rtu_msg->hdr, CM_RTU_ATTR_ID, cm_id_priv->tid); |
---|
2161 | | - rtu_msg->local_comm_id = cm_id_priv->id.local_id; |
---|
2162 | | - rtu_msg->remote_comm_id = cm_id_priv->id.remote_id; |
---|
| 2329 | + IBA_SET(CM_RTU_LOCAL_COMM_ID, rtu_msg, |
---|
| 2330 | + be32_to_cpu(cm_id_priv->id.local_id)); |
---|
| 2331 | + IBA_SET(CM_RTU_REMOTE_COMM_ID, rtu_msg, |
---|
| 2332 | + be32_to_cpu(cm_id_priv->id.remote_id)); |
---|
2163 | 2333 | |
---|
2164 | 2334 | if (private_data && private_data_len) |
---|
2165 | | - memcpy(rtu_msg->private_data, private_data, private_data_len); |
---|
| 2335 | + IBA_SET_MEM(CM_RTU_PRIVATE_DATA, rtu_msg, private_data, |
---|
| 2336 | + private_data_len); |
---|
2166 | 2337 | } |
---|
2167 | 2338 | |
---|
2168 | 2339 | int ib_send_cm_rtu(struct ib_cm_id *cm_id, |
---|
.. | .. |
---|
2186 | 2357 | spin_lock_irqsave(&cm_id_priv->lock, flags); |
---|
2187 | 2358 | if (cm_id->state != IB_CM_REP_RCVD && |
---|
2188 | 2359 | cm_id->state != IB_CM_MRA_REP_SENT) { |
---|
2189 | | - pr_debug("%s: local_id %d, cm_id->state %d\n", __func__, |
---|
2190 | | - be32_to_cpu(cm_id->local_id), cm_id->state); |
---|
| 2360 | + trace_icm_send_cm_rtu_err(cm_id); |
---|
2191 | 2361 | ret = -EINVAL; |
---|
2192 | 2362 | goto error; |
---|
2193 | 2363 | } |
---|
.. | .. |
---|
2199 | 2369 | cm_format_rtu((struct cm_rtu_msg *) msg->mad, cm_id_priv, |
---|
2200 | 2370 | private_data, private_data_len); |
---|
2201 | 2371 | |
---|
| 2372 | + trace_icm_send_rtu(cm_id); |
---|
2202 | 2373 | ret = ib_post_send_mad(msg, NULL); |
---|
2203 | 2374 | if (ret) { |
---|
2204 | 2375 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
---|
.. | .. |
---|
2225 | 2396 | |
---|
2226 | 2397 | rep_msg = (struct cm_rep_msg *)work->mad_recv_wc->recv_buf.mad; |
---|
2227 | 2398 | param = &work->cm_event.param.rep_rcvd; |
---|
2228 | | - param->remote_ca_guid = rep_msg->local_ca_guid; |
---|
2229 | | - param->remote_qkey = be32_to_cpu(rep_msg->local_qkey); |
---|
| 2399 | + param->remote_ca_guid = |
---|
| 2400 | + cpu_to_be64(IBA_GET(CM_REP_LOCAL_CA_GUID, rep_msg)); |
---|
| 2401 | + param->remote_qkey = IBA_GET(CM_REP_LOCAL_Q_KEY, rep_msg); |
---|
2230 | 2402 | param->remote_qpn = be32_to_cpu(cm_rep_get_qpn(rep_msg, qp_type)); |
---|
2231 | | - param->starting_psn = be32_to_cpu(cm_rep_get_starting_psn(rep_msg)); |
---|
2232 | | - param->responder_resources = rep_msg->initiator_depth; |
---|
2233 | | - param->initiator_depth = rep_msg->resp_resources; |
---|
2234 | | - param->target_ack_delay = cm_rep_get_target_ack_delay(rep_msg); |
---|
2235 | | - param->failover_accepted = cm_rep_get_failover(rep_msg); |
---|
2236 | | - param->flow_control = cm_rep_get_flow_ctrl(rep_msg); |
---|
2237 | | - param->rnr_retry_count = cm_rep_get_rnr_retry_count(rep_msg); |
---|
2238 | | - param->srq = cm_rep_get_srq(rep_msg); |
---|
2239 | | - work->cm_event.private_data = &rep_msg->private_data; |
---|
| 2403 | + param->starting_psn = IBA_GET(CM_REP_STARTING_PSN, rep_msg); |
---|
| 2404 | + param->responder_resources = IBA_GET(CM_REP_INITIATOR_DEPTH, rep_msg); |
---|
| 2405 | + param->initiator_depth = IBA_GET(CM_REP_RESPONDER_RESOURCES, rep_msg); |
---|
| 2406 | + param->target_ack_delay = IBA_GET(CM_REP_TARGET_ACK_DELAY, rep_msg); |
---|
| 2407 | + param->failover_accepted = IBA_GET(CM_REP_FAILOVER_ACCEPTED, rep_msg); |
---|
| 2408 | + param->flow_control = IBA_GET(CM_REP_END_TO_END_FLOW_CONTROL, rep_msg); |
---|
| 2409 | + param->rnr_retry_count = IBA_GET(CM_REP_RNR_RETRY_COUNT, rep_msg); |
---|
| 2410 | + param->srq = IBA_GET(CM_REP_SRQ, rep_msg); |
---|
| 2411 | + param->ece.vendor_id = IBA_GET(CM_REP_VENDOR_ID_H, rep_msg) << 16; |
---|
| 2412 | + param->ece.vendor_id |= IBA_GET(CM_REP_VENDOR_ID_M, rep_msg) << 8; |
---|
| 2413 | + param->ece.vendor_id |= IBA_GET(CM_REP_VENDOR_ID_L, rep_msg); |
---|
| 2414 | + param->ece.attr_mod = be32_to_cpu(rep_msg->hdr.attr_mod); |
---|
| 2415 | + |
---|
| 2416 | + work->cm_event.private_data = |
---|
| 2417 | + IBA_GET_MEM_PTR(CM_REP_PRIVATE_DATA, rep_msg); |
---|
2240 | 2418 | } |
---|
2241 | 2419 | |
---|
2242 | 2420 | static void cm_dup_rep_handler(struct cm_work *work) |
---|
.. | .. |
---|
2247 | 2425 | int ret; |
---|
2248 | 2426 | |
---|
2249 | 2427 | rep_msg = (struct cm_rep_msg *) work->mad_recv_wc->recv_buf.mad; |
---|
2250 | | - cm_id_priv = cm_acquire_id(rep_msg->remote_comm_id, |
---|
2251 | | - rep_msg->local_comm_id); |
---|
| 2428 | + cm_id_priv = cm_acquire_id( |
---|
| 2429 | + cpu_to_be32(IBA_GET(CM_REP_REMOTE_COMM_ID, rep_msg)), |
---|
| 2430 | + cpu_to_be32(IBA_GET(CM_REP_LOCAL_COMM_ID, rep_msg))); |
---|
2252 | 2431 | if (!cm_id_priv) |
---|
2253 | 2432 | return; |
---|
2254 | 2433 | |
---|
.. | .. |
---|
2272 | 2451 | goto unlock; |
---|
2273 | 2452 | spin_unlock_irq(&cm_id_priv->lock); |
---|
2274 | 2453 | |
---|
| 2454 | + trace_icm_send_dup_rep(&cm_id_priv->id); |
---|
2275 | 2455 | ret = ib_post_send_mad(msg, NULL); |
---|
2276 | 2456 | if (ret) |
---|
2277 | 2457 | goto free; |
---|
.. | .. |
---|
2288 | 2468 | struct cm_rep_msg *rep_msg; |
---|
2289 | 2469 | int ret; |
---|
2290 | 2470 | struct cm_id_private *cur_cm_id_priv; |
---|
2291 | | - struct ib_cm_id *cm_id; |
---|
2292 | 2471 | struct cm_timewait_info *timewait_info; |
---|
2293 | 2472 | |
---|
2294 | 2473 | rep_msg = (struct cm_rep_msg *)work->mad_recv_wc->recv_buf.mad; |
---|
2295 | | - cm_id_priv = cm_acquire_id(rep_msg->remote_comm_id, 0); |
---|
| 2474 | + cm_id_priv = cm_acquire_id( |
---|
| 2475 | + cpu_to_be32(IBA_GET(CM_REP_REMOTE_COMM_ID, rep_msg)), 0); |
---|
2296 | 2476 | if (!cm_id_priv) { |
---|
2297 | 2477 | cm_dup_rep_handler(work); |
---|
2298 | | - pr_debug("%s: remote_comm_id %d, no cm_id_priv\n", __func__, |
---|
2299 | | - be32_to_cpu(rep_msg->remote_comm_id)); |
---|
| 2478 | + trace_icm_remote_no_priv_err( |
---|
| 2479 | + IBA_GET(CM_REP_REMOTE_COMM_ID, rep_msg)); |
---|
2300 | 2480 | return -EINVAL; |
---|
2301 | 2481 | } |
---|
2302 | 2482 | |
---|
.. | .. |
---|
2308 | 2488 | case IB_CM_MRA_REQ_RCVD: |
---|
2309 | 2489 | break; |
---|
2310 | 2490 | default: |
---|
2311 | | - spin_unlock_irq(&cm_id_priv->lock); |
---|
2312 | 2491 | ret = -EINVAL; |
---|
2313 | | - pr_debug("%s: cm_id_priv->id.state: %d, local_comm_id %d, remote_comm_id %d\n", |
---|
2314 | | - __func__, cm_id_priv->id.state, |
---|
2315 | | - be32_to_cpu(rep_msg->local_comm_id), |
---|
2316 | | - be32_to_cpu(rep_msg->remote_comm_id)); |
---|
| 2492 | + trace_icm_rep_unknown_err( |
---|
| 2493 | + IBA_GET(CM_REP_LOCAL_COMM_ID, rep_msg), |
---|
| 2494 | + IBA_GET(CM_REP_REMOTE_COMM_ID, rep_msg), |
---|
| 2495 | + cm_id_priv->id.state); |
---|
| 2496 | + spin_unlock_irq(&cm_id_priv->lock); |
---|
2317 | 2497 | goto error; |
---|
2318 | 2498 | } |
---|
2319 | 2499 | |
---|
2320 | | - cm_id_priv->timewait_info->work.remote_id = rep_msg->local_comm_id; |
---|
2321 | | - cm_id_priv->timewait_info->remote_ca_guid = rep_msg->local_ca_guid; |
---|
| 2500 | + cm_id_priv->timewait_info->work.remote_id = |
---|
| 2501 | + cpu_to_be32(IBA_GET(CM_REP_LOCAL_COMM_ID, rep_msg)); |
---|
| 2502 | + cm_id_priv->timewait_info->remote_ca_guid = |
---|
| 2503 | + cpu_to_be64(IBA_GET(CM_REP_LOCAL_CA_GUID, rep_msg)); |
---|
2322 | 2504 | cm_id_priv->timewait_info->remote_qpn = cm_rep_get_qpn(rep_msg, cm_id_priv->qp_type); |
---|
2323 | 2505 | |
---|
2324 | 2506 | spin_lock(&cm.lock); |
---|
.. | .. |
---|
2327 | 2509 | spin_unlock(&cm.lock); |
---|
2328 | 2510 | spin_unlock_irq(&cm_id_priv->lock); |
---|
2329 | 2511 | ret = -EINVAL; |
---|
2330 | | - pr_debug("%s: Failed to insert remote id %d\n", __func__, |
---|
2331 | | - be32_to_cpu(rep_msg->remote_comm_id)); |
---|
| 2512 | + trace_icm_insert_failed_err( |
---|
| 2513 | + IBA_GET(CM_REP_REMOTE_COMM_ID, rep_msg)); |
---|
2332 | 2514 | goto error; |
---|
2333 | 2515 | } |
---|
2334 | 2516 | /* Check for a stale connection. */ |
---|
2335 | 2517 | timewait_info = cm_insert_remote_qpn(cm_id_priv->timewait_info); |
---|
2336 | 2518 | if (timewait_info) { |
---|
2337 | | - rb_erase(&cm_id_priv->timewait_info->remote_id_node, |
---|
2338 | | - &cm.remote_id_table); |
---|
2339 | | - cm_id_priv->timewait_info->inserted_remote_id = 0; |
---|
2340 | | - cur_cm_id_priv = cm_get_id(timewait_info->work.local_id, |
---|
| 2519 | + cm_remove_remote(cm_id_priv); |
---|
| 2520 | + cur_cm_id_priv = cm_acquire_id(timewait_info->work.local_id, |
---|
2341 | 2521 | timewait_info->work.remote_id); |
---|
2342 | 2522 | |
---|
2343 | 2523 | spin_unlock(&cm.lock); |
---|
.. | .. |
---|
2346 | 2526 | IB_CM_REJ_STALE_CONN, CM_MSG_RESPONSE_REP, |
---|
2347 | 2527 | NULL, 0); |
---|
2348 | 2528 | ret = -EINVAL; |
---|
2349 | | - pr_debug("%s: Stale connection. local_comm_id %d, remote_comm_id %d\n", |
---|
2350 | | - __func__, be32_to_cpu(rep_msg->local_comm_id), |
---|
2351 | | - be32_to_cpu(rep_msg->remote_comm_id)); |
---|
| 2529 | + trace_icm_staleconn_err( |
---|
| 2530 | + IBA_GET(CM_REP_LOCAL_COMM_ID, rep_msg), |
---|
| 2531 | + IBA_GET(CM_REP_REMOTE_COMM_ID, rep_msg)); |
---|
2352 | 2532 | |
---|
2353 | 2533 | if (cur_cm_id_priv) { |
---|
2354 | | - cm_id = &cur_cm_id_priv->id; |
---|
2355 | | - ib_send_cm_dreq(cm_id, NULL, 0); |
---|
| 2534 | + ib_send_cm_dreq(&cur_cm_id_priv->id, NULL, 0); |
---|
2356 | 2535 | cm_deref_id(cur_cm_id_priv); |
---|
2357 | 2536 | } |
---|
2358 | 2537 | |
---|
.. | .. |
---|
2361 | 2540 | spin_unlock(&cm.lock); |
---|
2362 | 2541 | |
---|
2363 | 2542 | cm_id_priv->id.state = IB_CM_REP_RCVD; |
---|
2364 | | - cm_id_priv->id.remote_id = rep_msg->local_comm_id; |
---|
| 2543 | + cm_id_priv->id.remote_id = |
---|
| 2544 | + cpu_to_be32(IBA_GET(CM_REP_LOCAL_COMM_ID, rep_msg)); |
---|
2365 | 2545 | cm_id_priv->remote_qpn = cm_rep_get_qpn(rep_msg, cm_id_priv->qp_type); |
---|
2366 | | - cm_id_priv->initiator_depth = rep_msg->resp_resources; |
---|
2367 | | - cm_id_priv->responder_resources = rep_msg->initiator_depth; |
---|
2368 | | - cm_id_priv->sq_psn = cm_rep_get_starting_psn(rep_msg); |
---|
2369 | | - cm_id_priv->rnr_retry_count = cm_rep_get_rnr_retry_count(rep_msg); |
---|
2370 | | - cm_id_priv->target_ack_delay = cm_rep_get_target_ack_delay(rep_msg); |
---|
| 2546 | + cm_id_priv->initiator_depth = |
---|
| 2547 | + IBA_GET(CM_REP_RESPONDER_RESOURCES, rep_msg); |
---|
| 2548 | + cm_id_priv->responder_resources = |
---|
| 2549 | + IBA_GET(CM_REP_INITIATOR_DEPTH, rep_msg); |
---|
| 2550 | + cm_id_priv->sq_psn = cpu_to_be32(IBA_GET(CM_REP_STARTING_PSN, rep_msg)); |
---|
| 2551 | + cm_id_priv->rnr_retry_count = IBA_GET(CM_REP_RNR_RETRY_COUNT, rep_msg); |
---|
| 2552 | + cm_id_priv->target_ack_delay = |
---|
| 2553 | + IBA_GET(CM_REP_TARGET_ACK_DELAY, rep_msg); |
---|
2371 | 2554 | cm_id_priv->av.timeout = |
---|
2372 | 2555 | cm_ack_timeout(cm_id_priv->target_ack_delay, |
---|
2373 | 2556 | cm_id_priv->av.timeout - 1); |
---|
.. | .. |
---|
2375 | 2558 | cm_ack_timeout(cm_id_priv->target_ack_delay, |
---|
2376 | 2559 | cm_id_priv->alt_av.timeout - 1); |
---|
2377 | 2560 | |
---|
2378 | | - /* todo: handle peer_to_peer */ |
---|
2379 | | - |
---|
2380 | 2561 | ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); |
---|
2381 | | - ret = atomic_inc_and_test(&cm_id_priv->work_count); |
---|
2382 | | - if (!ret) |
---|
2383 | | - list_add_tail(&work->list, &cm_id_priv->work_list); |
---|
2384 | | - spin_unlock_irq(&cm_id_priv->lock); |
---|
2385 | | - |
---|
2386 | | - if (ret) |
---|
2387 | | - cm_process_work(cm_id_priv, work); |
---|
2388 | | - else |
---|
2389 | | - cm_deref_id(cm_id_priv); |
---|
| 2562 | + cm_queue_work_unlock(cm_id_priv, work); |
---|
2390 | 2563 | return 0; |
---|
2391 | 2564 | |
---|
2392 | 2565 | error: |
---|
.. | .. |
---|
2397 | 2570 | static int cm_establish_handler(struct cm_work *work) |
---|
2398 | 2571 | { |
---|
2399 | 2572 | struct cm_id_private *cm_id_priv; |
---|
2400 | | - int ret; |
---|
2401 | 2573 | |
---|
2402 | 2574 | /* See comment in cm_establish about lookup. */ |
---|
2403 | 2575 | cm_id_priv = cm_acquire_id(work->local_id, work->remote_id); |
---|
.. | .. |
---|
2411 | 2583 | } |
---|
2412 | 2584 | |
---|
2413 | 2585 | ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); |
---|
2414 | | - ret = atomic_inc_and_test(&cm_id_priv->work_count); |
---|
2415 | | - if (!ret) |
---|
2416 | | - list_add_tail(&work->list, &cm_id_priv->work_list); |
---|
2417 | | - spin_unlock_irq(&cm_id_priv->lock); |
---|
2418 | | - |
---|
2419 | | - if (ret) |
---|
2420 | | - cm_process_work(cm_id_priv, work); |
---|
2421 | | - else |
---|
2422 | | - cm_deref_id(cm_id_priv); |
---|
| 2586 | + cm_queue_work_unlock(cm_id_priv, work); |
---|
2423 | 2587 | return 0; |
---|
2424 | 2588 | out: |
---|
2425 | 2589 | cm_deref_id(cm_id_priv); |
---|
.. | .. |
---|
2430 | 2594 | { |
---|
2431 | 2595 | struct cm_id_private *cm_id_priv; |
---|
2432 | 2596 | struct cm_rtu_msg *rtu_msg; |
---|
2433 | | - int ret; |
---|
2434 | 2597 | |
---|
2435 | 2598 | rtu_msg = (struct cm_rtu_msg *)work->mad_recv_wc->recv_buf.mad; |
---|
2436 | | - cm_id_priv = cm_acquire_id(rtu_msg->remote_comm_id, |
---|
2437 | | - rtu_msg->local_comm_id); |
---|
| 2599 | + cm_id_priv = cm_acquire_id( |
---|
| 2600 | + cpu_to_be32(IBA_GET(CM_RTU_REMOTE_COMM_ID, rtu_msg)), |
---|
| 2601 | + cpu_to_be32(IBA_GET(CM_RTU_LOCAL_COMM_ID, rtu_msg))); |
---|
2438 | 2602 | if (!cm_id_priv) |
---|
2439 | 2603 | return -EINVAL; |
---|
2440 | 2604 | |
---|
2441 | | - work->cm_event.private_data = &rtu_msg->private_data; |
---|
| 2605 | + work->cm_event.private_data = |
---|
| 2606 | + IBA_GET_MEM_PTR(CM_RTU_PRIVATE_DATA, rtu_msg); |
---|
2442 | 2607 | |
---|
2443 | 2608 | spin_lock_irq(&cm_id_priv->lock); |
---|
2444 | 2609 | if (cm_id_priv->id.state != IB_CM_REP_SENT && |
---|
.. | .. |
---|
2451 | 2616 | cm_id_priv->id.state = IB_CM_ESTABLISHED; |
---|
2452 | 2617 | |
---|
2453 | 2618 | ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); |
---|
2454 | | - ret = atomic_inc_and_test(&cm_id_priv->work_count); |
---|
2455 | | - if (!ret) |
---|
2456 | | - list_add_tail(&work->list, &cm_id_priv->work_list); |
---|
2457 | | - spin_unlock_irq(&cm_id_priv->lock); |
---|
2458 | | - |
---|
2459 | | - if (ret) |
---|
2460 | | - cm_process_work(cm_id_priv, work); |
---|
2461 | | - else |
---|
2462 | | - cm_deref_id(cm_id_priv); |
---|
| 2619 | + cm_queue_work_unlock(cm_id_priv, work); |
---|
2463 | 2620 | return 0; |
---|
2464 | 2621 | out: |
---|
2465 | 2622 | cm_deref_id(cm_id_priv); |
---|
.. | .. |
---|
2473 | 2630 | { |
---|
2474 | 2631 | cm_format_mad_hdr(&dreq_msg->hdr, CM_DREQ_ATTR_ID, |
---|
2475 | 2632 | cm_form_tid(cm_id_priv)); |
---|
2476 | | - dreq_msg->local_comm_id = cm_id_priv->id.local_id; |
---|
2477 | | - dreq_msg->remote_comm_id = cm_id_priv->id.remote_id; |
---|
2478 | | - cm_dreq_set_remote_qpn(dreq_msg, cm_id_priv->remote_qpn); |
---|
| 2633 | + IBA_SET(CM_DREQ_LOCAL_COMM_ID, dreq_msg, |
---|
| 2634 | + be32_to_cpu(cm_id_priv->id.local_id)); |
---|
| 2635 | + IBA_SET(CM_DREQ_REMOTE_COMM_ID, dreq_msg, |
---|
| 2636 | + be32_to_cpu(cm_id_priv->id.remote_id)); |
---|
| 2637 | + IBA_SET(CM_DREQ_REMOTE_QPN_EECN, dreq_msg, |
---|
| 2638 | + be32_to_cpu(cm_id_priv->remote_qpn)); |
---|
2479 | 2639 | |
---|
2480 | 2640 | if (private_data && private_data_len) |
---|
2481 | | - memcpy(dreq_msg->private_data, private_data, private_data_len); |
---|
| 2641 | + IBA_SET_MEM(CM_DREQ_PRIVATE_DATA, dreq_msg, private_data, |
---|
| 2642 | + private_data_len); |
---|
2482 | 2643 | } |
---|
2483 | 2644 | |
---|
2484 | | -int ib_send_cm_dreq(struct ib_cm_id *cm_id, |
---|
2485 | | - const void *private_data, |
---|
2486 | | - u8 private_data_len) |
---|
| 2645 | +static int cm_send_dreq_locked(struct cm_id_private *cm_id_priv, |
---|
| 2646 | + const void *private_data, u8 private_data_len) |
---|
2487 | 2647 | { |
---|
2488 | | - struct cm_id_private *cm_id_priv; |
---|
2489 | 2648 | struct ib_mad_send_buf *msg; |
---|
2490 | | - unsigned long flags; |
---|
2491 | 2649 | int ret; |
---|
| 2650 | + |
---|
| 2651 | + lockdep_assert_held(&cm_id_priv->lock); |
---|
2492 | 2652 | |
---|
2493 | 2653 | if (private_data && private_data_len > IB_CM_DREQ_PRIVATE_DATA_SIZE) |
---|
2494 | 2654 | return -EINVAL; |
---|
2495 | 2655 | |
---|
2496 | | - cm_id_priv = container_of(cm_id, struct cm_id_private, id); |
---|
2497 | | - spin_lock_irqsave(&cm_id_priv->lock, flags); |
---|
2498 | | - if (cm_id->state != IB_CM_ESTABLISHED) { |
---|
2499 | | - pr_debug("%s: local_id %d, cm_id->state: %d\n", __func__, |
---|
2500 | | - be32_to_cpu(cm_id->local_id), cm_id->state); |
---|
2501 | | - ret = -EINVAL; |
---|
2502 | | - goto out; |
---|
| 2656 | + if (cm_id_priv->id.state != IB_CM_ESTABLISHED) { |
---|
| 2657 | + trace_icm_dreq_skipped(&cm_id_priv->id); |
---|
| 2658 | + return -EINVAL; |
---|
2503 | 2659 | } |
---|
2504 | 2660 | |
---|
2505 | | - if (cm_id->lap_state == IB_CM_LAP_SENT || |
---|
2506 | | - cm_id->lap_state == IB_CM_MRA_LAP_RCVD) |
---|
| 2661 | + if (cm_id_priv->id.lap_state == IB_CM_LAP_SENT || |
---|
| 2662 | + cm_id_priv->id.lap_state == IB_CM_MRA_LAP_RCVD) |
---|
2507 | 2663 | ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); |
---|
2508 | 2664 | |
---|
2509 | 2665 | ret = cm_alloc_msg(cm_id_priv, &msg); |
---|
2510 | 2666 | if (ret) { |
---|
2511 | 2667 | cm_enter_timewait(cm_id_priv); |
---|
2512 | | - goto out; |
---|
| 2668 | + return ret; |
---|
2513 | 2669 | } |
---|
2514 | 2670 | |
---|
2515 | 2671 | cm_format_dreq((struct cm_dreq_msg *) msg->mad, cm_id_priv, |
---|
.. | .. |
---|
2517 | 2673 | msg->timeout_ms = cm_id_priv->timeout_ms; |
---|
2518 | 2674 | msg->context[1] = (void *) (unsigned long) IB_CM_DREQ_SENT; |
---|
2519 | 2675 | |
---|
| 2676 | + trace_icm_send_dreq(&cm_id_priv->id); |
---|
2520 | 2677 | ret = ib_post_send_mad(msg, NULL); |
---|
2521 | 2678 | if (ret) { |
---|
2522 | 2679 | cm_enter_timewait(cm_id_priv); |
---|
2523 | | - spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
---|
2524 | 2680 | cm_free_msg(msg); |
---|
2525 | 2681 | return ret; |
---|
2526 | 2682 | } |
---|
2527 | 2683 | |
---|
2528 | | - cm_id->state = IB_CM_DREQ_SENT; |
---|
| 2684 | + cm_id_priv->id.state = IB_CM_DREQ_SENT; |
---|
2529 | 2685 | cm_id_priv->msg = msg; |
---|
2530 | | -out: spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
---|
| 2686 | + return 0; |
---|
| 2687 | +} |
---|
| 2688 | + |
---|
| 2689 | +int ib_send_cm_dreq(struct ib_cm_id *cm_id, const void *private_data, |
---|
| 2690 | + u8 private_data_len) |
---|
| 2691 | +{ |
---|
| 2692 | + struct cm_id_private *cm_id_priv = |
---|
| 2693 | + container_of(cm_id, struct cm_id_private, id); |
---|
| 2694 | + unsigned long flags; |
---|
| 2695 | + int ret; |
---|
| 2696 | + |
---|
| 2697 | + spin_lock_irqsave(&cm_id_priv->lock, flags); |
---|
| 2698 | + ret = cm_send_dreq_locked(cm_id_priv, private_data, private_data_len); |
---|
| 2699 | + spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
---|
2531 | 2700 | return ret; |
---|
2532 | 2701 | } |
---|
2533 | 2702 | EXPORT_SYMBOL(ib_send_cm_dreq); |
---|
.. | .. |
---|
2538 | 2707 | u8 private_data_len) |
---|
2539 | 2708 | { |
---|
2540 | 2709 | cm_format_mad_hdr(&drep_msg->hdr, CM_DREP_ATTR_ID, cm_id_priv->tid); |
---|
2541 | | - drep_msg->local_comm_id = cm_id_priv->id.local_id; |
---|
2542 | | - drep_msg->remote_comm_id = cm_id_priv->id.remote_id; |
---|
| 2710 | + IBA_SET(CM_DREP_LOCAL_COMM_ID, drep_msg, |
---|
| 2711 | + be32_to_cpu(cm_id_priv->id.local_id)); |
---|
| 2712 | + IBA_SET(CM_DREP_REMOTE_COMM_ID, drep_msg, |
---|
| 2713 | + be32_to_cpu(cm_id_priv->id.remote_id)); |
---|
2543 | 2714 | |
---|
2544 | 2715 | if (private_data && private_data_len) |
---|
2545 | | - memcpy(drep_msg->private_data, private_data, private_data_len); |
---|
| 2716 | + IBA_SET_MEM(CM_DREP_PRIVATE_DATA, drep_msg, private_data, |
---|
| 2717 | + private_data_len); |
---|
2546 | 2718 | } |
---|
2547 | 2719 | |
---|
2548 | | -int ib_send_cm_drep(struct ib_cm_id *cm_id, |
---|
2549 | | - const void *private_data, |
---|
2550 | | - u8 private_data_len) |
---|
| 2720 | +static int cm_send_drep_locked(struct cm_id_private *cm_id_priv, |
---|
| 2721 | + void *private_data, u8 private_data_len) |
---|
2551 | 2722 | { |
---|
2552 | | - struct cm_id_private *cm_id_priv; |
---|
2553 | 2723 | struct ib_mad_send_buf *msg; |
---|
2554 | | - unsigned long flags; |
---|
2555 | | - void *data; |
---|
2556 | 2724 | int ret; |
---|
| 2725 | + |
---|
| 2726 | + lockdep_assert_held(&cm_id_priv->lock); |
---|
2557 | 2727 | |
---|
2558 | 2728 | if (private_data && private_data_len > IB_CM_DREP_PRIVATE_DATA_SIZE) |
---|
2559 | 2729 | return -EINVAL; |
---|
| 2730 | + |
---|
| 2731 | + if (cm_id_priv->id.state != IB_CM_DREQ_RCVD) { |
---|
| 2732 | + trace_icm_send_drep_err(&cm_id_priv->id); |
---|
| 2733 | + kfree(private_data); |
---|
| 2734 | + return -EINVAL; |
---|
| 2735 | + } |
---|
| 2736 | + |
---|
| 2737 | + cm_set_private_data(cm_id_priv, private_data, private_data_len); |
---|
| 2738 | + cm_enter_timewait(cm_id_priv); |
---|
| 2739 | + |
---|
| 2740 | + ret = cm_alloc_msg(cm_id_priv, &msg); |
---|
| 2741 | + if (ret) |
---|
| 2742 | + return ret; |
---|
| 2743 | + |
---|
| 2744 | + cm_format_drep((struct cm_drep_msg *) msg->mad, cm_id_priv, |
---|
| 2745 | + private_data, private_data_len); |
---|
| 2746 | + |
---|
| 2747 | + trace_icm_send_drep(&cm_id_priv->id); |
---|
| 2748 | + ret = ib_post_send_mad(msg, NULL); |
---|
| 2749 | + if (ret) { |
---|
| 2750 | + cm_free_msg(msg); |
---|
| 2751 | + return ret; |
---|
| 2752 | + } |
---|
| 2753 | + return 0; |
---|
| 2754 | +} |
---|
| 2755 | + |
---|
| 2756 | +int ib_send_cm_drep(struct ib_cm_id *cm_id, const void *private_data, |
---|
| 2757 | + u8 private_data_len) |
---|
| 2758 | +{ |
---|
| 2759 | + struct cm_id_private *cm_id_priv = |
---|
| 2760 | + container_of(cm_id, struct cm_id_private, id); |
---|
| 2761 | + unsigned long flags; |
---|
| 2762 | + void *data; |
---|
| 2763 | + int ret; |
---|
2560 | 2764 | |
---|
2561 | 2765 | data = cm_copy_private_data(private_data, private_data_len); |
---|
2562 | 2766 | if (IS_ERR(data)) |
---|
2563 | 2767 | return PTR_ERR(data); |
---|
2564 | 2768 | |
---|
2565 | | - cm_id_priv = container_of(cm_id, struct cm_id_private, id); |
---|
2566 | 2769 | spin_lock_irqsave(&cm_id_priv->lock, flags); |
---|
2567 | | - if (cm_id->state != IB_CM_DREQ_RCVD) { |
---|
2568 | | - spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
---|
2569 | | - kfree(data); |
---|
2570 | | - pr_debug("%s: local_id %d, cm_idcm_id->state(%d) != IB_CM_DREQ_RCVD\n", |
---|
2571 | | - __func__, be32_to_cpu(cm_id->local_id), cm_id->state); |
---|
2572 | | - return -EINVAL; |
---|
2573 | | - } |
---|
2574 | | - |
---|
2575 | | - cm_set_private_data(cm_id_priv, data, private_data_len); |
---|
2576 | | - cm_enter_timewait(cm_id_priv); |
---|
2577 | | - |
---|
2578 | | - ret = cm_alloc_msg(cm_id_priv, &msg); |
---|
2579 | | - if (ret) |
---|
2580 | | - goto out; |
---|
2581 | | - |
---|
2582 | | - cm_format_drep((struct cm_drep_msg *) msg->mad, cm_id_priv, |
---|
2583 | | - private_data, private_data_len); |
---|
2584 | | - |
---|
2585 | | - ret = ib_post_send_mad(msg, NULL); |
---|
2586 | | - if (ret) { |
---|
2587 | | - spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
---|
2588 | | - cm_free_msg(msg); |
---|
2589 | | - return ret; |
---|
2590 | | - } |
---|
2591 | | - |
---|
2592 | | -out: spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
---|
| 2770 | + ret = cm_send_drep_locked(cm_id_priv, data, private_data_len); |
---|
| 2771 | + spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
---|
2593 | 2772 | return ret; |
---|
2594 | 2773 | } |
---|
2595 | 2774 | EXPORT_SYMBOL(ib_send_cm_drep); |
---|
.. | .. |
---|
2610 | 2789 | drep_msg = (struct cm_drep_msg *) msg->mad; |
---|
2611 | 2790 | |
---|
2612 | 2791 | cm_format_mad_hdr(&drep_msg->hdr, CM_DREP_ATTR_ID, dreq_msg->hdr.tid); |
---|
2613 | | - drep_msg->remote_comm_id = dreq_msg->local_comm_id; |
---|
2614 | | - drep_msg->local_comm_id = dreq_msg->remote_comm_id; |
---|
| 2792 | + IBA_SET(CM_DREP_REMOTE_COMM_ID, drep_msg, |
---|
| 2793 | + IBA_GET(CM_DREQ_LOCAL_COMM_ID, dreq_msg)); |
---|
| 2794 | + IBA_SET(CM_DREP_LOCAL_COMM_ID, drep_msg, |
---|
| 2795 | + IBA_GET(CM_DREQ_REMOTE_COMM_ID, dreq_msg)); |
---|
2615 | 2796 | |
---|
| 2797 | + trace_icm_issue_drep( |
---|
| 2798 | + IBA_GET(CM_DREQ_LOCAL_COMM_ID, dreq_msg), |
---|
| 2799 | + IBA_GET(CM_DREQ_REMOTE_COMM_ID, dreq_msg)); |
---|
2616 | 2800 | ret = ib_post_send_mad(msg, NULL); |
---|
2617 | 2801 | if (ret) |
---|
2618 | 2802 | cm_free_msg(msg); |
---|
.. | .. |
---|
2625 | 2809 | struct cm_id_private *cm_id_priv; |
---|
2626 | 2810 | struct cm_dreq_msg *dreq_msg; |
---|
2627 | 2811 | struct ib_mad_send_buf *msg = NULL; |
---|
2628 | | - int ret; |
---|
2629 | 2812 | |
---|
2630 | 2813 | dreq_msg = (struct cm_dreq_msg *)work->mad_recv_wc->recv_buf.mad; |
---|
2631 | | - cm_id_priv = cm_acquire_id(dreq_msg->remote_comm_id, |
---|
2632 | | - dreq_msg->local_comm_id); |
---|
| 2814 | + cm_id_priv = cm_acquire_id( |
---|
| 2815 | + cpu_to_be32(IBA_GET(CM_DREQ_REMOTE_COMM_ID, dreq_msg)), |
---|
| 2816 | + cpu_to_be32(IBA_GET(CM_DREQ_LOCAL_COMM_ID, dreq_msg))); |
---|
2633 | 2817 | if (!cm_id_priv) { |
---|
2634 | 2818 | atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES]. |
---|
2635 | 2819 | counter[CM_DREQ_COUNTER]); |
---|
2636 | 2820 | cm_issue_drep(work->port, work->mad_recv_wc); |
---|
2637 | | - pr_debug("%s: no cm_id_priv, local_comm_id %d, remote_comm_id %d\n", |
---|
2638 | | - __func__, be32_to_cpu(dreq_msg->local_comm_id), |
---|
2639 | | - be32_to_cpu(dreq_msg->remote_comm_id)); |
---|
| 2821 | + trace_icm_no_priv_err( |
---|
| 2822 | + IBA_GET(CM_DREQ_LOCAL_COMM_ID, dreq_msg), |
---|
| 2823 | + IBA_GET(CM_DREQ_REMOTE_COMM_ID, dreq_msg)); |
---|
2640 | 2824 | return -EINVAL; |
---|
2641 | 2825 | } |
---|
2642 | 2826 | |
---|
2643 | | - work->cm_event.private_data = &dreq_msg->private_data; |
---|
| 2827 | + work->cm_event.private_data = |
---|
| 2828 | + IBA_GET_MEM_PTR(CM_DREQ_PRIVATE_DATA, dreq_msg); |
---|
2644 | 2829 | |
---|
2645 | 2830 | spin_lock_irq(&cm_id_priv->lock); |
---|
2646 | | - if (cm_id_priv->local_qpn != cm_dreq_get_remote_qpn(dreq_msg)) |
---|
| 2831 | + if (cm_id_priv->local_qpn != |
---|
| 2832 | + cpu_to_be32(IBA_GET(CM_DREQ_REMOTE_QPN_EECN, dreq_msg))) |
---|
2647 | 2833 | goto unlock; |
---|
2648 | 2834 | |
---|
2649 | 2835 | switch (cm_id_priv->id.state) { |
---|
.. | .. |
---|
2679 | 2865 | counter[CM_DREQ_COUNTER]); |
---|
2680 | 2866 | goto unlock; |
---|
2681 | 2867 | default: |
---|
2682 | | - pr_debug("%s: local_id %d, cm_id_priv->id.state: %d\n", |
---|
2683 | | - __func__, be32_to_cpu(cm_id_priv->id.local_id), |
---|
2684 | | - cm_id_priv->id.state); |
---|
| 2868 | + trace_icm_dreq_unknown_err(&cm_id_priv->id); |
---|
2685 | 2869 | goto unlock; |
---|
2686 | 2870 | } |
---|
2687 | 2871 | cm_id_priv->id.state = IB_CM_DREQ_RCVD; |
---|
2688 | 2872 | cm_id_priv->tid = dreq_msg->hdr.tid; |
---|
2689 | | - ret = atomic_inc_and_test(&cm_id_priv->work_count); |
---|
2690 | | - if (!ret) |
---|
2691 | | - list_add_tail(&work->list, &cm_id_priv->work_list); |
---|
2692 | | - spin_unlock_irq(&cm_id_priv->lock); |
---|
2693 | | - |
---|
2694 | | - if (ret) |
---|
2695 | | - cm_process_work(cm_id_priv, work); |
---|
2696 | | - else |
---|
2697 | | - cm_deref_id(cm_id_priv); |
---|
| 2873 | + cm_queue_work_unlock(cm_id_priv, work); |
---|
2698 | 2874 | return 0; |
---|
2699 | 2875 | |
---|
2700 | 2876 | unlock: spin_unlock_irq(&cm_id_priv->lock); |
---|
.. | .. |
---|
2706 | 2882 | { |
---|
2707 | 2883 | struct cm_id_private *cm_id_priv; |
---|
2708 | 2884 | struct cm_drep_msg *drep_msg; |
---|
2709 | | - int ret; |
---|
2710 | 2885 | |
---|
2711 | 2886 | drep_msg = (struct cm_drep_msg *)work->mad_recv_wc->recv_buf.mad; |
---|
2712 | | - cm_id_priv = cm_acquire_id(drep_msg->remote_comm_id, |
---|
2713 | | - drep_msg->local_comm_id); |
---|
| 2887 | + cm_id_priv = cm_acquire_id( |
---|
| 2888 | + cpu_to_be32(IBA_GET(CM_DREP_REMOTE_COMM_ID, drep_msg)), |
---|
| 2889 | + cpu_to_be32(IBA_GET(CM_DREP_LOCAL_COMM_ID, drep_msg))); |
---|
2714 | 2890 | if (!cm_id_priv) |
---|
2715 | 2891 | return -EINVAL; |
---|
2716 | 2892 | |
---|
2717 | | - work->cm_event.private_data = &drep_msg->private_data; |
---|
| 2893 | + work->cm_event.private_data = |
---|
| 2894 | + IBA_GET_MEM_PTR(CM_DREP_PRIVATE_DATA, drep_msg); |
---|
2718 | 2895 | |
---|
2719 | 2896 | spin_lock_irq(&cm_id_priv->lock); |
---|
2720 | 2897 | if (cm_id_priv->id.state != IB_CM_DREQ_SENT && |
---|
.. | .. |
---|
2725 | 2902 | cm_enter_timewait(cm_id_priv); |
---|
2726 | 2903 | |
---|
2727 | 2904 | ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); |
---|
2728 | | - ret = atomic_inc_and_test(&cm_id_priv->work_count); |
---|
2729 | | - if (!ret) |
---|
2730 | | - list_add_tail(&work->list, &cm_id_priv->work_list); |
---|
2731 | | - spin_unlock_irq(&cm_id_priv->lock); |
---|
2732 | | - |
---|
2733 | | - if (ret) |
---|
2734 | | - cm_process_work(cm_id_priv, work); |
---|
2735 | | - else |
---|
2736 | | - cm_deref_id(cm_id_priv); |
---|
| 2905 | + cm_queue_work_unlock(cm_id_priv, work); |
---|
2737 | 2906 | return 0; |
---|
2738 | 2907 | out: |
---|
2739 | 2908 | cm_deref_id(cm_id_priv); |
---|
2740 | 2909 | return -EINVAL; |
---|
2741 | 2910 | } |
---|
2742 | 2911 | |
---|
2743 | | -int ib_send_cm_rej(struct ib_cm_id *cm_id, |
---|
2744 | | - enum ib_cm_rej_reason reason, |
---|
2745 | | - void *ari, |
---|
2746 | | - u8 ari_length, |
---|
2747 | | - const void *private_data, |
---|
2748 | | - u8 private_data_len) |
---|
| 2912 | +static int cm_send_rej_locked(struct cm_id_private *cm_id_priv, |
---|
| 2913 | + enum ib_cm_rej_reason reason, void *ari, |
---|
| 2914 | + u8 ari_length, const void *private_data, |
---|
| 2915 | + u8 private_data_len) |
---|
2749 | 2916 | { |
---|
2750 | | - struct cm_id_private *cm_id_priv; |
---|
| 2917 | + enum ib_cm_state state = cm_id_priv->id.state; |
---|
2751 | 2918 | struct ib_mad_send_buf *msg; |
---|
2752 | | - unsigned long flags; |
---|
2753 | 2919 | int ret; |
---|
| 2920 | + |
---|
| 2921 | + lockdep_assert_held(&cm_id_priv->lock); |
---|
2754 | 2922 | |
---|
2755 | 2923 | if ((private_data && private_data_len > IB_CM_REJ_PRIVATE_DATA_SIZE) || |
---|
2756 | 2924 | (ari && ari_length > IB_CM_REJ_ARI_LENGTH)) |
---|
2757 | 2925 | return -EINVAL; |
---|
2758 | 2926 | |
---|
2759 | | - cm_id_priv = container_of(cm_id, struct cm_id_private, id); |
---|
| 2927 | + trace_icm_send_rej(&cm_id_priv->id, reason); |
---|
2760 | 2928 | |
---|
2761 | | - spin_lock_irqsave(&cm_id_priv->lock, flags); |
---|
2762 | | - switch (cm_id->state) { |
---|
| 2929 | + switch (state) { |
---|
2763 | 2930 | case IB_CM_REQ_SENT: |
---|
2764 | 2931 | case IB_CM_MRA_REQ_RCVD: |
---|
2765 | 2932 | case IB_CM_REQ_RCVD: |
---|
2766 | 2933 | case IB_CM_MRA_REQ_SENT: |
---|
2767 | 2934 | case IB_CM_REP_RCVD: |
---|
2768 | 2935 | case IB_CM_MRA_REP_SENT: |
---|
2769 | | - ret = cm_alloc_msg(cm_id_priv, &msg); |
---|
2770 | | - if (!ret) |
---|
2771 | | - cm_format_rej((struct cm_rej_msg *) msg->mad, |
---|
2772 | | - cm_id_priv, reason, ari, ari_length, |
---|
2773 | | - private_data, private_data_len); |
---|
2774 | | - |
---|
2775 | 2936 | cm_reset_to_idle(cm_id_priv); |
---|
| 2937 | + ret = cm_alloc_msg(cm_id_priv, &msg); |
---|
| 2938 | + if (ret) |
---|
| 2939 | + return ret; |
---|
| 2940 | + cm_format_rej((struct cm_rej_msg *)msg->mad, cm_id_priv, reason, |
---|
| 2941 | + ari, ari_length, private_data, private_data_len, |
---|
| 2942 | + state); |
---|
2776 | 2943 | break; |
---|
2777 | 2944 | case IB_CM_REP_SENT: |
---|
2778 | 2945 | case IB_CM_MRA_REP_RCVD: |
---|
2779 | | - ret = cm_alloc_msg(cm_id_priv, &msg); |
---|
2780 | | - if (!ret) |
---|
2781 | | - cm_format_rej((struct cm_rej_msg *) msg->mad, |
---|
2782 | | - cm_id_priv, reason, ari, ari_length, |
---|
2783 | | - private_data, private_data_len); |
---|
2784 | | - |
---|
2785 | 2946 | cm_enter_timewait(cm_id_priv); |
---|
| 2947 | + ret = cm_alloc_msg(cm_id_priv, &msg); |
---|
| 2948 | + if (ret) |
---|
| 2949 | + return ret; |
---|
| 2950 | + cm_format_rej((struct cm_rej_msg *)msg->mad, cm_id_priv, reason, |
---|
| 2951 | + ari, ari_length, private_data, private_data_len, |
---|
| 2952 | + state); |
---|
2786 | 2953 | break; |
---|
2787 | 2954 | default: |
---|
2788 | | - pr_debug("%s: local_id %d, cm_id->state: %d\n", __func__, |
---|
2789 | | - be32_to_cpu(cm_id_priv->id.local_id), cm_id->state); |
---|
2790 | | - ret = -EINVAL; |
---|
2791 | | - goto out; |
---|
| 2955 | + trace_icm_send_unknown_rej_err(&cm_id_priv->id); |
---|
| 2956 | + return -EINVAL; |
---|
2792 | 2957 | } |
---|
2793 | 2958 | |
---|
2794 | | - if (ret) |
---|
2795 | | - goto out; |
---|
2796 | | - |
---|
2797 | 2959 | ret = ib_post_send_mad(msg, NULL); |
---|
2798 | | - if (ret) |
---|
| 2960 | + if (ret) { |
---|
2799 | 2961 | cm_free_msg(msg); |
---|
| 2962 | + return ret; |
---|
| 2963 | + } |
---|
2800 | 2964 | |
---|
2801 | | -out: spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
---|
| 2965 | + return 0; |
---|
| 2966 | +} |
---|
| 2967 | + |
---|
| 2968 | +int ib_send_cm_rej(struct ib_cm_id *cm_id, enum ib_cm_rej_reason reason, |
---|
| 2969 | + void *ari, u8 ari_length, const void *private_data, |
---|
| 2970 | + u8 private_data_len) |
---|
| 2971 | +{ |
---|
| 2972 | + struct cm_id_private *cm_id_priv = |
---|
| 2973 | + container_of(cm_id, struct cm_id_private, id); |
---|
| 2974 | + unsigned long flags; |
---|
| 2975 | + int ret; |
---|
| 2976 | + |
---|
| 2977 | + spin_lock_irqsave(&cm_id_priv->lock, flags); |
---|
| 2978 | + ret = cm_send_rej_locked(cm_id_priv, reason, ari, ari_length, |
---|
| 2979 | + private_data, private_data_len); |
---|
| 2980 | + spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
---|
2802 | 2981 | return ret; |
---|
2803 | 2982 | } |
---|
2804 | 2983 | EXPORT_SYMBOL(ib_send_cm_rej); |
---|
.. | .. |
---|
2810 | 2989 | |
---|
2811 | 2990 | rej_msg = (struct cm_rej_msg *)work->mad_recv_wc->recv_buf.mad; |
---|
2812 | 2991 | param = &work->cm_event.param.rej_rcvd; |
---|
2813 | | - param->ari = rej_msg->ari; |
---|
2814 | | - param->ari_length = cm_rej_get_reject_info_len(rej_msg); |
---|
2815 | | - param->reason = __be16_to_cpu(rej_msg->reason); |
---|
2816 | | - work->cm_event.private_data = &rej_msg->private_data; |
---|
| 2992 | + param->ari = IBA_GET_MEM_PTR(CM_REJ_ARI, rej_msg); |
---|
| 2993 | + param->ari_length = IBA_GET(CM_REJ_REJECTED_INFO_LENGTH, rej_msg); |
---|
| 2994 | + param->reason = IBA_GET(CM_REJ_REASON, rej_msg); |
---|
| 2995 | + work->cm_event.private_data = |
---|
| 2996 | + IBA_GET_MEM_PTR(CM_REJ_PRIVATE_DATA, rej_msg); |
---|
2817 | 2997 | } |
---|
2818 | 2998 | |
---|
2819 | 2999 | static struct cm_id_private * cm_acquire_rejected_id(struct cm_rej_msg *rej_msg) |
---|
2820 | 3000 | { |
---|
2821 | | - struct cm_timewait_info *timewait_info; |
---|
2822 | 3001 | struct cm_id_private *cm_id_priv; |
---|
2823 | 3002 | __be32 remote_id; |
---|
2824 | 3003 | |
---|
2825 | | - remote_id = rej_msg->local_comm_id; |
---|
| 3004 | + remote_id = cpu_to_be32(IBA_GET(CM_REJ_LOCAL_COMM_ID, rej_msg)); |
---|
2826 | 3005 | |
---|
2827 | | - if (__be16_to_cpu(rej_msg->reason) == IB_CM_REJ_TIMEOUT) { |
---|
2828 | | - spin_lock_irq(&cm.lock); |
---|
2829 | | - timewait_info = cm_find_remote_id( *((__be64 *) rej_msg->ari), |
---|
2830 | | - remote_id); |
---|
2831 | | - if (!timewait_info) { |
---|
2832 | | - spin_unlock_irq(&cm.lock); |
---|
2833 | | - return NULL; |
---|
2834 | | - } |
---|
2835 | | - cm_id_priv = idr_find(&cm.local_id_table, (__force int) |
---|
2836 | | - (timewait_info->work.local_id ^ |
---|
2837 | | - cm.random_id_operand)); |
---|
2838 | | - if (cm_id_priv) { |
---|
2839 | | - if (cm_id_priv->id.remote_id == remote_id) |
---|
2840 | | - atomic_inc(&cm_id_priv->refcount); |
---|
2841 | | - else |
---|
2842 | | - cm_id_priv = NULL; |
---|
2843 | | - } |
---|
2844 | | - spin_unlock_irq(&cm.lock); |
---|
2845 | | - } else if (cm_rej_get_msg_rejected(rej_msg) == CM_MSG_RESPONSE_REQ) |
---|
2846 | | - cm_id_priv = cm_acquire_id(rej_msg->remote_comm_id, 0); |
---|
| 3006 | + if (IBA_GET(CM_REJ_REASON, rej_msg) == IB_CM_REJ_TIMEOUT) { |
---|
| 3007 | + cm_id_priv = cm_find_remote_id( |
---|
| 3008 | + *((__be64 *)IBA_GET_MEM_PTR(CM_REJ_ARI, rej_msg)), |
---|
| 3009 | + remote_id); |
---|
| 3010 | + } else if (IBA_GET(CM_REJ_MESSAGE_REJECTED, rej_msg) == |
---|
| 3011 | + CM_MSG_RESPONSE_REQ) |
---|
| 3012 | + cm_id_priv = cm_acquire_id( |
---|
| 3013 | + cpu_to_be32(IBA_GET(CM_REJ_REMOTE_COMM_ID, rej_msg)), |
---|
| 3014 | + 0); |
---|
2847 | 3015 | else |
---|
2848 | | - cm_id_priv = cm_acquire_id(rej_msg->remote_comm_id, remote_id); |
---|
| 3016 | + cm_id_priv = cm_acquire_id( |
---|
| 3017 | + cpu_to_be32(IBA_GET(CM_REJ_REMOTE_COMM_ID, rej_msg)), |
---|
| 3018 | + remote_id); |
---|
2849 | 3019 | |
---|
2850 | 3020 | return cm_id_priv; |
---|
2851 | 3021 | } |
---|
.. | .. |
---|
2854 | 3024 | { |
---|
2855 | 3025 | struct cm_id_private *cm_id_priv; |
---|
2856 | 3026 | struct cm_rej_msg *rej_msg; |
---|
2857 | | - int ret; |
---|
2858 | 3027 | |
---|
2859 | 3028 | rej_msg = (struct cm_rej_msg *)work->mad_recv_wc->recv_buf.mad; |
---|
2860 | 3029 | cm_id_priv = cm_acquire_rejected_id(rej_msg); |
---|
.. | .. |
---|
2870 | 3039 | case IB_CM_REP_SENT: |
---|
2871 | 3040 | case IB_CM_MRA_REP_RCVD: |
---|
2872 | 3041 | ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); |
---|
2873 | | - /* fall through */ |
---|
| 3042 | + fallthrough; |
---|
2874 | 3043 | case IB_CM_REQ_RCVD: |
---|
2875 | 3044 | case IB_CM_MRA_REQ_SENT: |
---|
2876 | | - if (__be16_to_cpu(rej_msg->reason) == IB_CM_REJ_STALE_CONN) |
---|
| 3045 | + if (IBA_GET(CM_REJ_REASON, rej_msg) == IB_CM_REJ_STALE_CONN) |
---|
2877 | 3046 | cm_enter_timewait(cm_id_priv); |
---|
2878 | 3047 | else |
---|
2879 | 3048 | cm_reset_to_idle(cm_id_priv); |
---|
2880 | 3049 | break; |
---|
2881 | 3050 | case IB_CM_DREQ_SENT: |
---|
2882 | 3051 | ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); |
---|
2883 | | - /* fall through */ |
---|
| 3052 | + fallthrough; |
---|
2884 | 3053 | case IB_CM_REP_RCVD: |
---|
2885 | 3054 | case IB_CM_MRA_REP_SENT: |
---|
2886 | 3055 | cm_enter_timewait(cm_id_priv); |
---|
.. | .. |
---|
2894 | 3063 | cm_enter_timewait(cm_id_priv); |
---|
2895 | 3064 | break; |
---|
2896 | 3065 | } |
---|
2897 | | - /* fall through */ |
---|
| 3066 | + fallthrough; |
---|
2898 | 3067 | default: |
---|
| 3068 | + trace_icm_rej_unknown_err(&cm_id_priv->id); |
---|
2899 | 3069 | spin_unlock_irq(&cm_id_priv->lock); |
---|
2900 | | - pr_debug("%s: local_id %d, cm_id_priv->id.state: %d\n", |
---|
2901 | | - __func__, be32_to_cpu(cm_id_priv->id.local_id), |
---|
2902 | | - cm_id_priv->id.state); |
---|
2903 | | - ret = -EINVAL; |
---|
2904 | 3070 | goto out; |
---|
2905 | 3071 | } |
---|
2906 | 3072 | |
---|
2907 | | - ret = atomic_inc_and_test(&cm_id_priv->work_count); |
---|
2908 | | - if (!ret) |
---|
2909 | | - list_add_tail(&work->list, &cm_id_priv->work_list); |
---|
2910 | | - spin_unlock_irq(&cm_id_priv->lock); |
---|
2911 | | - |
---|
2912 | | - if (ret) |
---|
2913 | | - cm_process_work(cm_id_priv, work); |
---|
2914 | | - else |
---|
2915 | | - cm_deref_id(cm_id_priv); |
---|
| 3073 | + cm_queue_work_unlock(cm_id_priv, work); |
---|
2916 | 3074 | return 0; |
---|
2917 | 3075 | out: |
---|
2918 | 3076 | cm_deref_id(cm_id_priv); |
---|
.. | .. |
---|
2961 | 3119 | msg_response = CM_MSG_RESPONSE_OTHER; |
---|
2962 | 3120 | break; |
---|
2963 | 3121 | } |
---|
2964 | | - /* fall through */ |
---|
| 3122 | + fallthrough; |
---|
2965 | 3123 | default: |
---|
2966 | | - pr_debug("%s: local_id %d, cm_id_priv->id.state: %d\n", |
---|
2967 | | - __func__, be32_to_cpu(cm_id_priv->id.local_id), |
---|
2968 | | - cm_id_priv->id.state); |
---|
| 3124 | + trace_icm_send_mra_unknown_err(&cm_id_priv->id); |
---|
2969 | 3125 | ret = -EINVAL; |
---|
2970 | 3126 | goto error1; |
---|
2971 | 3127 | } |
---|
.. | .. |
---|
2978 | 3134 | cm_format_mra((struct cm_mra_msg *) msg->mad, cm_id_priv, |
---|
2979 | 3135 | msg_response, service_timeout, |
---|
2980 | 3136 | private_data, private_data_len); |
---|
| 3137 | + trace_icm_send_mra(cm_id); |
---|
2981 | 3138 | ret = ib_post_send_mad(msg, NULL); |
---|
2982 | 3139 | if (ret) |
---|
2983 | 3140 | goto error2; |
---|
.. | .. |
---|
3003 | 3160 | |
---|
3004 | 3161 | static struct cm_id_private * cm_acquire_mraed_id(struct cm_mra_msg *mra_msg) |
---|
3005 | 3162 | { |
---|
3006 | | - switch (cm_mra_get_msg_mraed(mra_msg)) { |
---|
| 3163 | + switch (IBA_GET(CM_MRA_MESSAGE_MRAED, mra_msg)) { |
---|
3007 | 3164 | case CM_MSG_RESPONSE_REQ: |
---|
3008 | | - return cm_acquire_id(mra_msg->remote_comm_id, 0); |
---|
| 3165 | + return cm_acquire_id( |
---|
| 3166 | + cpu_to_be32(IBA_GET(CM_MRA_REMOTE_COMM_ID, mra_msg)), |
---|
| 3167 | + 0); |
---|
3009 | 3168 | case CM_MSG_RESPONSE_REP: |
---|
3010 | 3169 | case CM_MSG_RESPONSE_OTHER: |
---|
3011 | | - return cm_acquire_id(mra_msg->remote_comm_id, |
---|
3012 | | - mra_msg->local_comm_id); |
---|
| 3170 | + return cm_acquire_id( |
---|
| 3171 | + cpu_to_be32(IBA_GET(CM_MRA_REMOTE_COMM_ID, mra_msg)), |
---|
| 3172 | + cpu_to_be32(IBA_GET(CM_MRA_LOCAL_COMM_ID, mra_msg))); |
---|
3013 | 3173 | default: |
---|
3014 | 3174 | return NULL; |
---|
3015 | 3175 | } |
---|
.. | .. |
---|
3019 | 3179 | { |
---|
3020 | 3180 | struct cm_id_private *cm_id_priv; |
---|
3021 | 3181 | struct cm_mra_msg *mra_msg; |
---|
3022 | | - int timeout, ret; |
---|
| 3182 | + int timeout; |
---|
3023 | 3183 | |
---|
3024 | 3184 | mra_msg = (struct cm_mra_msg *)work->mad_recv_wc->recv_buf.mad; |
---|
3025 | 3185 | cm_id_priv = cm_acquire_mraed_id(mra_msg); |
---|
3026 | 3186 | if (!cm_id_priv) |
---|
3027 | 3187 | return -EINVAL; |
---|
3028 | 3188 | |
---|
3029 | | - work->cm_event.private_data = &mra_msg->private_data; |
---|
| 3189 | + work->cm_event.private_data = |
---|
| 3190 | + IBA_GET_MEM_PTR(CM_MRA_PRIVATE_DATA, mra_msg); |
---|
3030 | 3191 | work->cm_event.param.mra_rcvd.service_timeout = |
---|
3031 | | - cm_mra_get_service_timeout(mra_msg); |
---|
3032 | | - timeout = cm_convert_to_ms(cm_mra_get_service_timeout(mra_msg)) + |
---|
| 3192 | + IBA_GET(CM_MRA_SERVICE_TIMEOUT, mra_msg); |
---|
| 3193 | + timeout = cm_convert_to_ms(IBA_GET(CM_MRA_SERVICE_TIMEOUT, mra_msg)) + |
---|
3033 | 3194 | cm_convert_to_ms(cm_id_priv->av.timeout); |
---|
3034 | 3195 | |
---|
3035 | 3196 | spin_lock_irq(&cm_id_priv->lock); |
---|
3036 | 3197 | switch (cm_id_priv->id.state) { |
---|
3037 | 3198 | case IB_CM_REQ_SENT: |
---|
3038 | | - if (cm_mra_get_msg_mraed(mra_msg) != CM_MSG_RESPONSE_REQ || |
---|
| 3199 | + if (IBA_GET(CM_MRA_MESSAGE_MRAED, mra_msg) != |
---|
| 3200 | + CM_MSG_RESPONSE_REQ || |
---|
3039 | 3201 | ib_modify_mad(cm_id_priv->av.port->mad_agent, |
---|
3040 | 3202 | cm_id_priv->msg, timeout)) |
---|
3041 | 3203 | goto out; |
---|
3042 | 3204 | cm_id_priv->id.state = IB_CM_MRA_REQ_RCVD; |
---|
3043 | 3205 | break; |
---|
3044 | 3206 | case IB_CM_REP_SENT: |
---|
3045 | | - if (cm_mra_get_msg_mraed(mra_msg) != CM_MSG_RESPONSE_REP || |
---|
| 3207 | + if (IBA_GET(CM_MRA_MESSAGE_MRAED, mra_msg) != |
---|
| 3208 | + CM_MSG_RESPONSE_REP || |
---|
3046 | 3209 | ib_modify_mad(cm_id_priv->av.port->mad_agent, |
---|
3047 | 3210 | cm_id_priv->msg, timeout)) |
---|
3048 | 3211 | goto out; |
---|
3049 | 3212 | cm_id_priv->id.state = IB_CM_MRA_REP_RCVD; |
---|
3050 | 3213 | break; |
---|
3051 | 3214 | case IB_CM_ESTABLISHED: |
---|
3052 | | - if (cm_mra_get_msg_mraed(mra_msg) != CM_MSG_RESPONSE_OTHER || |
---|
| 3215 | + if (IBA_GET(CM_MRA_MESSAGE_MRAED, mra_msg) != |
---|
| 3216 | + CM_MSG_RESPONSE_OTHER || |
---|
3053 | 3217 | cm_id_priv->id.lap_state != IB_CM_LAP_SENT || |
---|
3054 | 3218 | ib_modify_mad(cm_id_priv->av.port->mad_agent, |
---|
3055 | 3219 | cm_id_priv->msg, timeout)) { |
---|
.. | .. |
---|
3065 | 3229 | case IB_CM_MRA_REP_RCVD: |
---|
3066 | 3230 | atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES]. |
---|
3067 | 3231 | counter[CM_MRA_COUNTER]); |
---|
3068 | | - /* fall through */ |
---|
| 3232 | + fallthrough; |
---|
3069 | 3233 | default: |
---|
3070 | | - pr_debug("%s local_id %d, cm_id_priv->id.state: %d\n", |
---|
3071 | | - __func__, be32_to_cpu(cm_id_priv->id.local_id), |
---|
3072 | | - cm_id_priv->id.state); |
---|
| 3234 | + trace_icm_mra_unknown_err(&cm_id_priv->id); |
---|
3073 | 3235 | goto out; |
---|
3074 | 3236 | } |
---|
3075 | 3237 | |
---|
3076 | 3238 | cm_id_priv->msg->context[1] = (void *) (unsigned long) |
---|
3077 | 3239 | cm_id_priv->id.state; |
---|
3078 | | - ret = atomic_inc_and_test(&cm_id_priv->work_count); |
---|
3079 | | - if (!ret) |
---|
3080 | | - list_add_tail(&work->list, &cm_id_priv->work_list); |
---|
3081 | | - spin_unlock_irq(&cm_id_priv->lock); |
---|
3082 | | - |
---|
3083 | | - if (ret) |
---|
3084 | | - cm_process_work(cm_id_priv, work); |
---|
3085 | | - else |
---|
3086 | | - cm_deref_id(cm_id_priv); |
---|
| 3240 | + cm_queue_work_unlock(cm_id_priv, work); |
---|
3087 | 3241 | return 0; |
---|
3088 | 3242 | out: |
---|
3089 | 3243 | spin_unlock_irq(&cm_id_priv->lock); |
---|
.. | .. |
---|
3091 | 3245 | return -EINVAL; |
---|
3092 | 3246 | } |
---|
3093 | 3247 | |
---|
3094 | | -static void cm_format_lap(struct cm_lap_msg *lap_msg, |
---|
3095 | | - struct cm_id_private *cm_id_priv, |
---|
3096 | | - struct sa_path_rec *alternate_path, |
---|
3097 | | - const void *private_data, |
---|
3098 | | - u8 private_data_len) |
---|
3099 | | -{ |
---|
3100 | | - bool alt_ext = false; |
---|
3101 | | - |
---|
3102 | | - if (alternate_path->rec_type == SA_PATH_REC_TYPE_OPA) |
---|
3103 | | - alt_ext = opa_is_extended_lid(alternate_path->opa.dlid, |
---|
3104 | | - alternate_path->opa.slid); |
---|
3105 | | - cm_format_mad_hdr(&lap_msg->hdr, CM_LAP_ATTR_ID, |
---|
3106 | | - cm_form_tid(cm_id_priv)); |
---|
3107 | | - lap_msg->local_comm_id = cm_id_priv->id.local_id; |
---|
3108 | | - lap_msg->remote_comm_id = cm_id_priv->id.remote_id; |
---|
3109 | | - cm_lap_set_remote_qpn(lap_msg, cm_id_priv->remote_qpn); |
---|
3110 | | - /* todo: need remote CM response timeout */ |
---|
3111 | | - cm_lap_set_remote_resp_timeout(lap_msg, 0x1F); |
---|
3112 | | - lap_msg->alt_local_lid = |
---|
3113 | | - htons(ntohl(sa_path_get_slid(alternate_path))); |
---|
3114 | | - lap_msg->alt_remote_lid = |
---|
3115 | | - htons(ntohl(sa_path_get_dlid(alternate_path))); |
---|
3116 | | - lap_msg->alt_local_gid = alternate_path->sgid; |
---|
3117 | | - lap_msg->alt_remote_gid = alternate_path->dgid; |
---|
3118 | | - if (alt_ext) { |
---|
3119 | | - lap_msg->alt_local_gid.global.interface_id |
---|
3120 | | - = OPA_MAKE_ID(be32_to_cpu(alternate_path->opa.slid)); |
---|
3121 | | - lap_msg->alt_remote_gid.global.interface_id |
---|
3122 | | - = OPA_MAKE_ID(be32_to_cpu(alternate_path->opa.dlid)); |
---|
3123 | | - } |
---|
3124 | | - cm_lap_set_flow_label(lap_msg, alternate_path->flow_label); |
---|
3125 | | - cm_lap_set_traffic_class(lap_msg, alternate_path->traffic_class); |
---|
3126 | | - lap_msg->alt_hop_limit = alternate_path->hop_limit; |
---|
3127 | | - cm_lap_set_packet_rate(lap_msg, alternate_path->rate); |
---|
3128 | | - cm_lap_set_sl(lap_msg, alternate_path->sl); |
---|
3129 | | - cm_lap_set_subnet_local(lap_msg, 1); /* local only... */ |
---|
3130 | | - cm_lap_set_local_ack_timeout(lap_msg, |
---|
3131 | | - cm_ack_timeout(cm_id_priv->av.port->cm_dev->ack_delay, |
---|
3132 | | - alternate_path->packet_life_time)); |
---|
3133 | | - |
---|
3134 | | - if (private_data && private_data_len) |
---|
3135 | | - memcpy(lap_msg->private_data, private_data, private_data_len); |
---|
3136 | | -} |
---|
3137 | | - |
---|
3138 | | -int ib_send_cm_lap(struct ib_cm_id *cm_id, |
---|
3139 | | - struct sa_path_rec *alternate_path, |
---|
3140 | | - const void *private_data, |
---|
3141 | | - u8 private_data_len) |
---|
3142 | | -{ |
---|
3143 | | - struct cm_id_private *cm_id_priv; |
---|
3144 | | - struct ib_mad_send_buf *msg; |
---|
3145 | | - unsigned long flags; |
---|
3146 | | - int ret; |
---|
3147 | | - |
---|
3148 | | - if (private_data && private_data_len > IB_CM_LAP_PRIVATE_DATA_SIZE) |
---|
3149 | | - return -EINVAL; |
---|
3150 | | - |
---|
3151 | | - cm_id_priv = container_of(cm_id, struct cm_id_private, id); |
---|
3152 | | - spin_lock_irqsave(&cm_id_priv->lock, flags); |
---|
3153 | | - if (cm_id->state != IB_CM_ESTABLISHED || |
---|
3154 | | - (cm_id->lap_state != IB_CM_LAP_UNINIT && |
---|
3155 | | - cm_id->lap_state != IB_CM_LAP_IDLE)) { |
---|
3156 | | - ret = -EINVAL; |
---|
3157 | | - goto out; |
---|
3158 | | - } |
---|
3159 | | - |
---|
3160 | | - ret = cm_init_av_by_path(alternate_path, NULL, &cm_id_priv->alt_av, |
---|
3161 | | - cm_id_priv); |
---|
3162 | | - if (ret) |
---|
3163 | | - goto out; |
---|
3164 | | - cm_id_priv->alt_av.timeout = |
---|
3165 | | - cm_ack_timeout(cm_id_priv->target_ack_delay, |
---|
3166 | | - cm_id_priv->alt_av.timeout - 1); |
---|
3167 | | - |
---|
3168 | | - ret = cm_alloc_msg(cm_id_priv, &msg); |
---|
3169 | | - if (ret) |
---|
3170 | | - goto out; |
---|
3171 | | - |
---|
3172 | | - cm_format_lap((struct cm_lap_msg *) msg->mad, cm_id_priv, |
---|
3173 | | - alternate_path, private_data, private_data_len); |
---|
3174 | | - msg->timeout_ms = cm_id_priv->timeout_ms; |
---|
3175 | | - msg->context[1] = (void *) (unsigned long) IB_CM_ESTABLISHED; |
---|
3176 | | - |
---|
3177 | | - ret = ib_post_send_mad(msg, NULL); |
---|
3178 | | - if (ret) { |
---|
3179 | | - spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
---|
3180 | | - cm_free_msg(msg); |
---|
3181 | | - return ret; |
---|
3182 | | - } |
---|
3183 | | - |
---|
3184 | | - cm_id->lap_state = IB_CM_LAP_SENT; |
---|
3185 | | - cm_id_priv->msg = msg; |
---|
3186 | | - |
---|
3187 | | -out: spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
---|
3188 | | - return ret; |
---|
3189 | | -} |
---|
3190 | | -EXPORT_SYMBOL(ib_send_cm_lap); |
---|
3191 | | - |
---|
3192 | 3248 | static void cm_format_path_lid_from_lap(struct cm_lap_msg *lap_msg, |
---|
3193 | 3249 | struct sa_path_rec *path) |
---|
3194 | 3250 | { |
---|
3195 | 3251 | u32 lid; |
---|
3196 | 3252 | |
---|
3197 | 3253 | if (path->rec_type != SA_PATH_REC_TYPE_OPA) { |
---|
3198 | | - sa_path_set_dlid(path, ntohs(lap_msg->alt_local_lid)); |
---|
3199 | | - sa_path_set_slid(path, ntohs(lap_msg->alt_remote_lid)); |
---|
| 3254 | + sa_path_set_dlid(path, IBA_GET(CM_LAP_ALTERNATE_LOCAL_PORT_LID, |
---|
| 3255 | + lap_msg)); |
---|
| 3256 | + sa_path_set_slid(path, IBA_GET(CM_LAP_ALTERNATE_REMOTE_PORT_LID, |
---|
| 3257 | + lap_msg)); |
---|
3200 | 3258 | } else { |
---|
3201 | | - lid = opa_get_lid_from_gid(&lap_msg->alt_local_gid); |
---|
| 3259 | + lid = opa_get_lid_from_gid(IBA_GET_MEM_PTR( |
---|
| 3260 | + CM_LAP_ALTERNATE_LOCAL_PORT_GID, lap_msg)); |
---|
3202 | 3261 | sa_path_set_dlid(path, lid); |
---|
3203 | 3262 | |
---|
3204 | | - lid = opa_get_lid_from_gid(&lap_msg->alt_remote_gid); |
---|
| 3263 | + lid = opa_get_lid_from_gid(IBA_GET_MEM_PTR( |
---|
| 3264 | + CM_LAP_ALTERNATE_REMOTE_PORT_GID, lap_msg)); |
---|
3205 | 3265 | sa_path_set_slid(path, lid); |
---|
3206 | 3266 | } |
---|
3207 | 3267 | } |
---|
.. | .. |
---|
3210 | 3270 | struct sa_path_rec *path, |
---|
3211 | 3271 | struct cm_lap_msg *lap_msg) |
---|
3212 | 3272 | { |
---|
3213 | | - path->dgid = lap_msg->alt_local_gid; |
---|
3214 | | - path->sgid = lap_msg->alt_remote_gid; |
---|
3215 | | - path->flow_label = cm_lap_get_flow_label(lap_msg); |
---|
3216 | | - path->hop_limit = lap_msg->alt_hop_limit; |
---|
3217 | | - path->traffic_class = cm_lap_get_traffic_class(lap_msg); |
---|
| 3273 | + path->dgid = *IBA_GET_MEM_PTR(CM_LAP_ALTERNATE_LOCAL_PORT_GID, lap_msg); |
---|
| 3274 | + path->sgid = |
---|
| 3275 | + *IBA_GET_MEM_PTR(CM_LAP_ALTERNATE_REMOTE_PORT_GID, lap_msg); |
---|
| 3276 | + path->flow_label = |
---|
| 3277 | + cpu_to_be32(IBA_GET(CM_LAP_ALTERNATE_FLOW_LABEL, lap_msg)); |
---|
| 3278 | + path->hop_limit = IBA_GET(CM_LAP_ALTERNATE_HOP_LIMIT, lap_msg); |
---|
| 3279 | + path->traffic_class = IBA_GET(CM_LAP_ALTERNATE_TRAFFIC_CLASS, lap_msg); |
---|
3218 | 3280 | path->reversible = 1; |
---|
3219 | 3281 | path->pkey = cm_id_priv->pkey; |
---|
3220 | | - path->sl = cm_lap_get_sl(lap_msg); |
---|
| 3282 | + path->sl = IBA_GET(CM_LAP_ALTERNATE_SL, lap_msg); |
---|
3221 | 3283 | path->mtu_selector = IB_SA_EQ; |
---|
3222 | 3284 | path->mtu = cm_id_priv->path_mtu; |
---|
3223 | 3285 | path->rate_selector = IB_SA_EQ; |
---|
3224 | | - path->rate = cm_lap_get_packet_rate(lap_msg); |
---|
| 3286 | + path->rate = IBA_GET(CM_LAP_ALTERNATE_PACKET_RATE, lap_msg); |
---|
3225 | 3287 | path->packet_life_time_selector = IB_SA_EQ; |
---|
3226 | | - path->packet_life_time = cm_lap_get_local_ack_timeout(lap_msg); |
---|
| 3288 | + path->packet_life_time = |
---|
| 3289 | + IBA_GET(CM_LAP_ALTERNATE_LOCAL_ACK_TIMEOUT, lap_msg); |
---|
3227 | 3290 | path->packet_life_time -= (path->packet_life_time > 0); |
---|
3228 | 3291 | cm_format_path_lid_from_lap(lap_msg, path); |
---|
3229 | 3292 | } |
---|
.. | .. |
---|
3245 | 3308 | |
---|
3246 | 3309 | /* todo: verify LAP request and send reject APR if invalid. */ |
---|
3247 | 3310 | lap_msg = (struct cm_lap_msg *)work->mad_recv_wc->recv_buf.mad; |
---|
3248 | | - cm_id_priv = cm_acquire_id(lap_msg->remote_comm_id, |
---|
3249 | | - lap_msg->local_comm_id); |
---|
| 3311 | + cm_id_priv = cm_acquire_id( |
---|
| 3312 | + cpu_to_be32(IBA_GET(CM_LAP_REMOTE_COMM_ID, lap_msg)), |
---|
| 3313 | + cpu_to_be32(IBA_GET(CM_LAP_LOCAL_COMM_ID, lap_msg))); |
---|
3250 | 3314 | if (!cm_id_priv) |
---|
3251 | 3315 | return -EINVAL; |
---|
3252 | 3316 | |
---|
3253 | 3317 | param = &work->cm_event.param.lap_rcvd; |
---|
3254 | 3318 | memset(&work->path[0], 0, sizeof(work->path[1])); |
---|
3255 | 3319 | cm_path_set_rec_type(work->port->cm_dev->ib_device, |
---|
3256 | | - work->port->port_num, |
---|
3257 | | - &work->path[0], |
---|
3258 | | - &lap_msg->alt_local_gid); |
---|
| 3320 | + work->port->port_num, &work->path[0], |
---|
| 3321 | + IBA_GET_MEM_PTR(CM_LAP_ALTERNATE_LOCAL_PORT_GID, |
---|
| 3322 | + lap_msg)); |
---|
3259 | 3323 | param->alternate_path = &work->path[0]; |
---|
3260 | 3324 | cm_format_path_from_lap(cm_id_priv, param->alternate_path, lap_msg); |
---|
3261 | | - work->cm_event.private_data = &lap_msg->private_data; |
---|
| 3325 | + work->cm_event.private_data = |
---|
| 3326 | + IBA_GET_MEM_PTR(CM_LAP_PRIVATE_DATA, lap_msg); |
---|
3262 | 3327 | |
---|
3263 | 3328 | spin_lock_irq(&cm_id_priv->lock); |
---|
3264 | 3329 | if (cm_id_priv->id.state != IB_CM_ESTABLISHED) |
---|
.. | .. |
---|
3307 | 3372 | |
---|
3308 | 3373 | cm_id_priv->id.lap_state = IB_CM_LAP_RCVD; |
---|
3309 | 3374 | cm_id_priv->tid = lap_msg->hdr.tid; |
---|
3310 | | - ret = atomic_inc_and_test(&cm_id_priv->work_count); |
---|
3311 | | - if (!ret) |
---|
3312 | | - list_add_tail(&work->list, &cm_id_priv->work_list); |
---|
3313 | | - spin_unlock_irq(&cm_id_priv->lock); |
---|
3314 | | - |
---|
3315 | | - if (ret) |
---|
3316 | | - cm_process_work(cm_id_priv, work); |
---|
3317 | | - else |
---|
3318 | | - cm_deref_id(cm_id_priv); |
---|
| 3375 | + cm_queue_work_unlock(cm_id_priv, work); |
---|
3319 | 3376 | return 0; |
---|
3320 | 3377 | |
---|
3321 | 3378 | unlock: spin_unlock_irq(&cm_id_priv->lock); |
---|
.. | .. |
---|
3323 | 3380 | return -EINVAL; |
---|
3324 | 3381 | } |
---|
3325 | 3382 | |
---|
3326 | | -static void cm_format_apr(struct cm_apr_msg *apr_msg, |
---|
3327 | | - struct cm_id_private *cm_id_priv, |
---|
3328 | | - enum ib_cm_apr_status status, |
---|
3329 | | - void *info, |
---|
3330 | | - u8 info_length, |
---|
3331 | | - const void *private_data, |
---|
3332 | | - u8 private_data_len) |
---|
3333 | | -{ |
---|
3334 | | - cm_format_mad_hdr(&apr_msg->hdr, CM_APR_ATTR_ID, cm_id_priv->tid); |
---|
3335 | | - apr_msg->local_comm_id = cm_id_priv->id.local_id; |
---|
3336 | | - apr_msg->remote_comm_id = cm_id_priv->id.remote_id; |
---|
3337 | | - apr_msg->ap_status = (u8) status; |
---|
3338 | | - |
---|
3339 | | - if (info && info_length) { |
---|
3340 | | - apr_msg->info_length = info_length; |
---|
3341 | | - memcpy(apr_msg->info, info, info_length); |
---|
3342 | | - } |
---|
3343 | | - |
---|
3344 | | - if (private_data && private_data_len) |
---|
3345 | | - memcpy(apr_msg->private_data, private_data, private_data_len); |
---|
3346 | | -} |
---|
3347 | | - |
---|
3348 | | -int ib_send_cm_apr(struct ib_cm_id *cm_id, |
---|
3349 | | - enum ib_cm_apr_status status, |
---|
3350 | | - void *info, |
---|
3351 | | - u8 info_length, |
---|
3352 | | - const void *private_data, |
---|
3353 | | - u8 private_data_len) |
---|
3354 | | -{ |
---|
3355 | | - struct cm_id_private *cm_id_priv; |
---|
3356 | | - struct ib_mad_send_buf *msg; |
---|
3357 | | - unsigned long flags; |
---|
3358 | | - int ret; |
---|
3359 | | - |
---|
3360 | | - if ((private_data && private_data_len > IB_CM_APR_PRIVATE_DATA_SIZE) || |
---|
3361 | | - (info && info_length > IB_CM_APR_INFO_LENGTH)) |
---|
3362 | | - return -EINVAL; |
---|
3363 | | - |
---|
3364 | | - cm_id_priv = container_of(cm_id, struct cm_id_private, id); |
---|
3365 | | - spin_lock_irqsave(&cm_id_priv->lock, flags); |
---|
3366 | | - if (cm_id->state != IB_CM_ESTABLISHED || |
---|
3367 | | - (cm_id->lap_state != IB_CM_LAP_RCVD && |
---|
3368 | | - cm_id->lap_state != IB_CM_MRA_LAP_SENT)) { |
---|
3369 | | - ret = -EINVAL; |
---|
3370 | | - goto out; |
---|
3371 | | - } |
---|
3372 | | - |
---|
3373 | | - ret = cm_alloc_msg(cm_id_priv, &msg); |
---|
3374 | | - if (ret) |
---|
3375 | | - goto out; |
---|
3376 | | - |
---|
3377 | | - cm_format_apr((struct cm_apr_msg *) msg->mad, cm_id_priv, status, |
---|
3378 | | - info, info_length, private_data, private_data_len); |
---|
3379 | | - ret = ib_post_send_mad(msg, NULL); |
---|
3380 | | - if (ret) { |
---|
3381 | | - spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
---|
3382 | | - cm_free_msg(msg); |
---|
3383 | | - return ret; |
---|
3384 | | - } |
---|
3385 | | - |
---|
3386 | | - cm_id->lap_state = IB_CM_LAP_IDLE; |
---|
3387 | | -out: spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
---|
3388 | | - return ret; |
---|
3389 | | -} |
---|
3390 | | -EXPORT_SYMBOL(ib_send_cm_apr); |
---|
3391 | | - |
---|
3392 | 3383 | static int cm_apr_handler(struct cm_work *work) |
---|
3393 | 3384 | { |
---|
3394 | 3385 | struct cm_id_private *cm_id_priv; |
---|
3395 | 3386 | struct cm_apr_msg *apr_msg; |
---|
3396 | | - int ret; |
---|
3397 | 3387 | |
---|
3398 | 3388 | /* Currently Alternate path messages are not supported for |
---|
3399 | 3389 | * RoCE link layer. |
---|
.. | .. |
---|
3403 | 3393 | return -EINVAL; |
---|
3404 | 3394 | |
---|
3405 | 3395 | apr_msg = (struct cm_apr_msg *)work->mad_recv_wc->recv_buf.mad; |
---|
3406 | | - cm_id_priv = cm_acquire_id(apr_msg->remote_comm_id, |
---|
3407 | | - apr_msg->local_comm_id); |
---|
| 3396 | + cm_id_priv = cm_acquire_id( |
---|
| 3397 | + cpu_to_be32(IBA_GET(CM_APR_REMOTE_COMM_ID, apr_msg)), |
---|
| 3398 | + cpu_to_be32(IBA_GET(CM_APR_LOCAL_COMM_ID, apr_msg))); |
---|
3408 | 3399 | if (!cm_id_priv) |
---|
3409 | 3400 | return -EINVAL; /* Unmatched reply. */ |
---|
3410 | 3401 | |
---|
3411 | | - work->cm_event.param.apr_rcvd.ap_status = apr_msg->ap_status; |
---|
3412 | | - work->cm_event.param.apr_rcvd.apr_info = &apr_msg->info; |
---|
3413 | | - work->cm_event.param.apr_rcvd.info_len = apr_msg->info_length; |
---|
3414 | | - work->cm_event.private_data = &apr_msg->private_data; |
---|
| 3402 | + work->cm_event.param.apr_rcvd.ap_status = |
---|
| 3403 | + IBA_GET(CM_APR_AR_STATUS, apr_msg); |
---|
| 3404 | + work->cm_event.param.apr_rcvd.apr_info = |
---|
| 3405 | + IBA_GET_MEM_PTR(CM_APR_ADDITIONAL_INFORMATION, apr_msg); |
---|
| 3406 | + work->cm_event.param.apr_rcvd.info_len = |
---|
| 3407 | + IBA_GET(CM_APR_ADDITIONAL_INFORMATION_LENGTH, apr_msg); |
---|
| 3408 | + work->cm_event.private_data = |
---|
| 3409 | + IBA_GET_MEM_PTR(CM_APR_PRIVATE_DATA, apr_msg); |
---|
3415 | 3410 | |
---|
3416 | 3411 | spin_lock_irq(&cm_id_priv->lock); |
---|
3417 | 3412 | if (cm_id_priv->id.state != IB_CM_ESTABLISHED || |
---|
.. | .. |
---|
3423 | 3418 | cm_id_priv->id.lap_state = IB_CM_LAP_IDLE; |
---|
3424 | 3419 | ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); |
---|
3425 | 3420 | cm_id_priv->msg = NULL; |
---|
3426 | | - |
---|
3427 | | - ret = atomic_inc_and_test(&cm_id_priv->work_count); |
---|
3428 | | - if (!ret) |
---|
3429 | | - list_add_tail(&work->list, &cm_id_priv->work_list); |
---|
3430 | | - spin_unlock_irq(&cm_id_priv->lock); |
---|
3431 | | - |
---|
3432 | | - if (ret) |
---|
3433 | | - cm_process_work(cm_id_priv, work); |
---|
3434 | | - else |
---|
3435 | | - cm_deref_id(cm_id_priv); |
---|
| 3421 | + cm_queue_work_unlock(cm_id_priv, work); |
---|
3436 | 3422 | return 0; |
---|
3437 | 3423 | out: |
---|
3438 | 3424 | cm_deref_id(cm_id_priv); |
---|
.. | .. |
---|
3443 | 3429 | { |
---|
3444 | 3430 | struct cm_timewait_info *timewait_info; |
---|
3445 | 3431 | struct cm_id_private *cm_id_priv; |
---|
3446 | | - int ret; |
---|
3447 | 3432 | |
---|
3448 | | - timewait_info = (struct cm_timewait_info *)work; |
---|
| 3433 | + timewait_info = container_of(work, struct cm_timewait_info, work); |
---|
3449 | 3434 | spin_lock_irq(&cm.lock); |
---|
3450 | 3435 | list_del(&timewait_info->list); |
---|
3451 | 3436 | spin_unlock_irq(&cm.lock); |
---|
.. | .. |
---|
3462 | 3447 | goto out; |
---|
3463 | 3448 | } |
---|
3464 | 3449 | cm_id_priv->id.state = IB_CM_IDLE; |
---|
3465 | | - ret = atomic_inc_and_test(&cm_id_priv->work_count); |
---|
3466 | | - if (!ret) |
---|
3467 | | - list_add_tail(&work->list, &cm_id_priv->work_list); |
---|
3468 | | - spin_unlock_irq(&cm_id_priv->lock); |
---|
3469 | | - |
---|
3470 | | - if (ret) |
---|
3471 | | - cm_process_work(cm_id_priv, work); |
---|
3472 | | - else |
---|
3473 | | - cm_deref_id(cm_id_priv); |
---|
| 3450 | + cm_queue_work_unlock(cm_id_priv, work); |
---|
3474 | 3451 | return 0; |
---|
3475 | 3452 | out: |
---|
3476 | 3453 | cm_deref_id(cm_id_priv); |
---|
.. | .. |
---|
3483 | 3460 | { |
---|
3484 | 3461 | cm_format_mad_hdr(&sidr_req_msg->hdr, CM_SIDR_REQ_ATTR_ID, |
---|
3485 | 3462 | cm_form_tid(cm_id_priv)); |
---|
3486 | | - sidr_req_msg->request_id = cm_id_priv->id.local_id; |
---|
3487 | | - sidr_req_msg->pkey = param->path->pkey; |
---|
3488 | | - sidr_req_msg->service_id = param->service_id; |
---|
| 3463 | + IBA_SET(CM_SIDR_REQ_REQUESTID, sidr_req_msg, |
---|
| 3464 | + be32_to_cpu(cm_id_priv->id.local_id)); |
---|
| 3465 | + IBA_SET(CM_SIDR_REQ_PARTITION_KEY, sidr_req_msg, |
---|
| 3466 | + be16_to_cpu(param->path->pkey)); |
---|
| 3467 | + IBA_SET(CM_SIDR_REQ_SERVICEID, sidr_req_msg, |
---|
| 3468 | + be64_to_cpu(param->service_id)); |
---|
3489 | 3469 | |
---|
3490 | 3470 | if (param->private_data && param->private_data_len) |
---|
3491 | | - memcpy(sidr_req_msg->private_data, param->private_data, |
---|
3492 | | - param->private_data_len); |
---|
| 3471 | + IBA_SET_MEM(CM_SIDR_REQ_PRIVATE_DATA, sidr_req_msg, |
---|
| 3472 | + param->private_data, param->private_data_len); |
---|
3493 | 3473 | } |
---|
3494 | 3474 | |
---|
3495 | 3475 | int ib_send_cm_sidr_req(struct ib_cm_id *cm_id, |
---|
.. | .. |
---|
3525 | 3505 | msg->context[1] = (void *) (unsigned long) IB_CM_SIDR_REQ_SENT; |
---|
3526 | 3506 | |
---|
3527 | 3507 | spin_lock_irqsave(&cm_id_priv->lock, flags); |
---|
3528 | | - if (cm_id->state == IB_CM_IDLE) |
---|
| 3508 | + if (cm_id->state == IB_CM_IDLE) { |
---|
| 3509 | + trace_icm_send_sidr_req(&cm_id_priv->id); |
---|
3529 | 3510 | ret = ib_post_send_mad(msg, NULL); |
---|
3530 | | - else |
---|
| 3511 | + } else { |
---|
3531 | 3512 | ret = -EINVAL; |
---|
| 3513 | + } |
---|
3532 | 3514 | |
---|
3533 | 3515 | if (ret) { |
---|
3534 | 3516 | spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
---|
.. | .. |
---|
3553 | 3535 | sidr_req_msg = (struct cm_sidr_req_msg *) |
---|
3554 | 3536 | work->mad_recv_wc->recv_buf.mad; |
---|
3555 | 3537 | param = &work->cm_event.param.sidr_req_rcvd; |
---|
3556 | | - param->pkey = __be16_to_cpu(sidr_req_msg->pkey); |
---|
| 3538 | + param->pkey = IBA_GET(CM_SIDR_REQ_PARTITION_KEY, sidr_req_msg); |
---|
3557 | 3539 | param->listen_id = listen_id; |
---|
3558 | | - param->service_id = sidr_req_msg->service_id; |
---|
| 3540 | + param->service_id = |
---|
| 3541 | + cpu_to_be64(IBA_GET(CM_SIDR_REQ_SERVICEID, sidr_req_msg)); |
---|
3559 | 3542 | param->bth_pkey = cm_get_bth_pkey(work); |
---|
3560 | 3543 | param->port = work->port->port_num; |
---|
3561 | 3544 | param->sgid_attr = rx_cm_id->av.ah_attr.grh.sgid_attr; |
---|
3562 | | - work->cm_event.private_data = &sidr_req_msg->private_data; |
---|
| 3545 | + work->cm_event.private_data = |
---|
| 3546 | + IBA_GET_MEM_PTR(CM_SIDR_REQ_PRIVATE_DATA, sidr_req_msg); |
---|
3563 | 3547 | } |
---|
3564 | 3548 | |
---|
3565 | 3549 | static int cm_sidr_req_handler(struct cm_work *work) |
---|
3566 | 3550 | { |
---|
3567 | | - struct ib_cm_id *cm_id; |
---|
3568 | | - struct cm_id_private *cm_id_priv, *cur_cm_id_priv; |
---|
| 3551 | + struct cm_id_private *cm_id_priv, *listen_cm_id_priv; |
---|
3569 | 3552 | struct cm_sidr_req_msg *sidr_req_msg; |
---|
3570 | 3553 | struct ib_wc *wc; |
---|
3571 | 3554 | int ret; |
---|
3572 | 3555 | |
---|
3573 | | - cm_id = ib_create_cm_id(work->port->cm_dev->ib_device, NULL, NULL); |
---|
3574 | | - if (IS_ERR(cm_id)) |
---|
3575 | | - return PTR_ERR(cm_id); |
---|
3576 | | - cm_id_priv = container_of(cm_id, struct cm_id_private, id); |
---|
| 3556 | + cm_id_priv = |
---|
| 3557 | + cm_alloc_id_priv(work->port->cm_dev->ib_device, NULL, NULL); |
---|
| 3558 | + if (IS_ERR(cm_id_priv)) |
---|
| 3559 | + return PTR_ERR(cm_id_priv); |
---|
3577 | 3560 | |
---|
3578 | 3561 | /* Record SGID/SLID and request ID for lookup. */ |
---|
3579 | 3562 | sidr_req_msg = (struct cm_sidr_req_msg *) |
---|
3580 | 3563 | work->mad_recv_wc->recv_buf.mad; |
---|
| 3564 | + |
---|
| 3565 | + cm_id_priv->id.remote_id = |
---|
| 3566 | + cpu_to_be32(IBA_GET(CM_SIDR_REQ_REQUESTID, sidr_req_msg)); |
---|
| 3567 | + cm_id_priv->id.service_id = |
---|
| 3568 | + cpu_to_be64(IBA_GET(CM_SIDR_REQ_SERVICEID, sidr_req_msg)); |
---|
| 3569 | + cm_id_priv->id.service_mask = ~cpu_to_be64(0); |
---|
| 3570 | + cm_id_priv->tid = sidr_req_msg->hdr.tid; |
---|
| 3571 | + |
---|
3581 | 3572 | wc = work->mad_recv_wc->wc; |
---|
3582 | 3573 | cm_id_priv->av.dgid.global.subnet_prefix = cpu_to_be64(wc->slid); |
---|
3583 | 3574 | cm_id_priv->av.dgid.global.interface_id = 0; |
---|
.. | .. |
---|
3587 | 3578 | if (ret) |
---|
3588 | 3579 | goto out; |
---|
3589 | 3580 | |
---|
3590 | | - cm_id_priv->id.remote_id = sidr_req_msg->request_id; |
---|
3591 | | - cm_id_priv->tid = sidr_req_msg->hdr.tid; |
---|
3592 | | - atomic_inc(&cm_id_priv->work_count); |
---|
3593 | | - |
---|
3594 | 3581 | spin_lock_irq(&cm.lock); |
---|
3595 | | - cur_cm_id_priv = cm_insert_remote_sidr(cm_id_priv); |
---|
3596 | | - if (cur_cm_id_priv) { |
---|
| 3582 | + listen_cm_id_priv = cm_insert_remote_sidr(cm_id_priv); |
---|
| 3583 | + if (listen_cm_id_priv) { |
---|
3597 | 3584 | spin_unlock_irq(&cm.lock); |
---|
3598 | 3585 | atomic_long_inc(&work->port->counter_group[CM_RECV_DUPLICATES]. |
---|
3599 | 3586 | counter[CM_SIDR_REQ_COUNTER]); |
---|
3600 | 3587 | goto out; /* Duplicate message. */ |
---|
3601 | 3588 | } |
---|
3602 | 3589 | cm_id_priv->id.state = IB_CM_SIDR_REQ_RCVD; |
---|
3603 | | - cur_cm_id_priv = cm_find_listen(cm_id->device, |
---|
3604 | | - sidr_req_msg->service_id); |
---|
3605 | | - if (!cur_cm_id_priv) { |
---|
| 3590 | + listen_cm_id_priv = cm_find_listen(cm_id_priv->id.device, |
---|
| 3591 | + cm_id_priv->id.service_id); |
---|
| 3592 | + if (!listen_cm_id_priv) { |
---|
3606 | 3593 | spin_unlock_irq(&cm.lock); |
---|
3607 | | - cm_reject_sidr_req(cm_id_priv, IB_SIDR_UNSUPPORTED); |
---|
| 3594 | + ib_send_cm_sidr_rep(&cm_id_priv->id, |
---|
| 3595 | + &(struct ib_cm_sidr_rep_param){ |
---|
| 3596 | + .status = IB_SIDR_UNSUPPORTED }); |
---|
3608 | 3597 | goto out; /* No match. */ |
---|
3609 | 3598 | } |
---|
3610 | | - atomic_inc(&cur_cm_id_priv->refcount); |
---|
3611 | | - atomic_inc(&cm_id_priv->refcount); |
---|
3612 | 3599 | spin_unlock_irq(&cm.lock); |
---|
3613 | 3600 | |
---|
3614 | | - cm_id_priv->id.cm_handler = cur_cm_id_priv->id.cm_handler; |
---|
3615 | | - cm_id_priv->id.context = cur_cm_id_priv->id.context; |
---|
3616 | | - cm_id_priv->id.service_id = sidr_req_msg->service_id; |
---|
3617 | | - cm_id_priv->id.service_mask = ~cpu_to_be64(0); |
---|
| 3601 | + cm_id_priv->id.cm_handler = listen_cm_id_priv->id.cm_handler; |
---|
| 3602 | + cm_id_priv->id.context = listen_cm_id_priv->id.context; |
---|
3618 | 3603 | |
---|
3619 | | - cm_format_sidr_req_event(work, cm_id_priv, &cur_cm_id_priv->id); |
---|
3620 | | - cm_process_work(cm_id_priv, work); |
---|
3621 | | - cm_deref_id(cur_cm_id_priv); |
---|
| 3604 | + /* |
---|
| 3605 | + * A SIDR ID does not need to be in the xarray since it does not receive |
---|
| 3606 | + * mads, is not placed in the remote_id or remote_qpn rbtree, and does |
---|
| 3607 | + * not enter timewait. |
---|
| 3608 | + */ |
---|
| 3609 | + |
---|
| 3610 | + cm_format_sidr_req_event(work, cm_id_priv, &listen_cm_id_priv->id); |
---|
| 3611 | + ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, &work->cm_event); |
---|
| 3612 | + cm_free_work(work); |
---|
| 3613 | + /* |
---|
| 3614 | + * A pointer to the listen_cm_id is held in the event, so this deref |
---|
| 3615 | + * must be after the event is delivered above. |
---|
| 3616 | + */ |
---|
| 3617 | + cm_deref_id(listen_cm_id_priv); |
---|
| 3618 | + if (ret) |
---|
| 3619 | + cm_destroy_id(&cm_id_priv->id, ret); |
---|
3622 | 3620 | return 0; |
---|
3623 | 3621 | out: |
---|
3624 | 3622 | ib_destroy_cm_id(&cm_id_priv->id); |
---|
.. | .. |
---|
3629 | 3627 | struct cm_id_private *cm_id_priv, |
---|
3630 | 3628 | struct ib_cm_sidr_rep_param *param) |
---|
3631 | 3629 | { |
---|
3632 | | - cm_format_mad_hdr(&sidr_rep_msg->hdr, CM_SIDR_REP_ATTR_ID, |
---|
3633 | | - cm_id_priv->tid); |
---|
3634 | | - sidr_rep_msg->request_id = cm_id_priv->id.remote_id; |
---|
3635 | | - sidr_rep_msg->status = param->status; |
---|
3636 | | - cm_sidr_rep_set_qpn(sidr_rep_msg, cpu_to_be32(param->qp_num)); |
---|
3637 | | - sidr_rep_msg->service_id = cm_id_priv->id.service_id; |
---|
3638 | | - sidr_rep_msg->qkey = cpu_to_be32(param->qkey); |
---|
| 3630 | + cm_format_mad_ece_hdr(&sidr_rep_msg->hdr, CM_SIDR_REP_ATTR_ID, |
---|
| 3631 | + cm_id_priv->tid, param->ece.attr_mod); |
---|
| 3632 | + IBA_SET(CM_SIDR_REP_REQUESTID, sidr_rep_msg, |
---|
| 3633 | + be32_to_cpu(cm_id_priv->id.remote_id)); |
---|
| 3634 | + IBA_SET(CM_SIDR_REP_STATUS, sidr_rep_msg, param->status); |
---|
| 3635 | + IBA_SET(CM_SIDR_REP_QPN, sidr_rep_msg, param->qp_num); |
---|
| 3636 | + IBA_SET(CM_SIDR_REP_SERVICEID, sidr_rep_msg, |
---|
| 3637 | + be64_to_cpu(cm_id_priv->id.service_id)); |
---|
| 3638 | + IBA_SET(CM_SIDR_REP_Q_KEY, sidr_rep_msg, param->qkey); |
---|
| 3639 | + IBA_SET(CM_SIDR_REP_VENDOR_ID_L, sidr_rep_msg, |
---|
| 3640 | + param->ece.vendor_id & 0xFF); |
---|
| 3641 | + IBA_SET(CM_SIDR_REP_VENDOR_ID_H, sidr_rep_msg, |
---|
| 3642 | + (param->ece.vendor_id >> 8) & 0xFF); |
---|
3639 | 3643 | |
---|
3640 | 3644 | if (param->info && param->info_length) |
---|
3641 | | - memcpy(sidr_rep_msg->info, param->info, param->info_length); |
---|
| 3645 | + IBA_SET_MEM(CM_SIDR_REP_ADDITIONAL_INFORMATION, sidr_rep_msg, |
---|
| 3646 | + param->info, param->info_length); |
---|
3642 | 3647 | |
---|
3643 | 3648 | if (param->private_data && param->private_data_len) |
---|
3644 | | - memcpy(sidr_rep_msg->private_data, param->private_data, |
---|
3645 | | - param->private_data_len); |
---|
| 3649 | + IBA_SET_MEM(CM_SIDR_REP_PRIVATE_DATA, sidr_rep_msg, |
---|
| 3650 | + param->private_data, param->private_data_len); |
---|
3646 | 3651 | } |
---|
3647 | 3652 | |
---|
3648 | | -int ib_send_cm_sidr_rep(struct ib_cm_id *cm_id, |
---|
3649 | | - struct ib_cm_sidr_rep_param *param) |
---|
| 3653 | +static int cm_send_sidr_rep_locked(struct cm_id_private *cm_id_priv, |
---|
| 3654 | + struct ib_cm_sidr_rep_param *param) |
---|
3650 | 3655 | { |
---|
3651 | | - struct cm_id_private *cm_id_priv; |
---|
3652 | 3656 | struct ib_mad_send_buf *msg; |
---|
3653 | 3657 | unsigned long flags; |
---|
3654 | 3658 | int ret; |
---|
| 3659 | + |
---|
| 3660 | + lockdep_assert_held(&cm_id_priv->lock); |
---|
3655 | 3661 | |
---|
3656 | 3662 | if ((param->info && param->info_length > IB_CM_SIDR_REP_INFO_LENGTH) || |
---|
3657 | 3663 | (param->private_data && |
---|
3658 | 3664 | param->private_data_len > IB_CM_SIDR_REP_PRIVATE_DATA_SIZE)) |
---|
3659 | 3665 | return -EINVAL; |
---|
3660 | 3666 | |
---|
3661 | | - cm_id_priv = container_of(cm_id, struct cm_id_private, id); |
---|
3662 | | - spin_lock_irqsave(&cm_id_priv->lock, flags); |
---|
3663 | | - if (cm_id->state != IB_CM_SIDR_REQ_RCVD) { |
---|
3664 | | - ret = -EINVAL; |
---|
3665 | | - goto error; |
---|
3666 | | - } |
---|
| 3667 | + if (cm_id_priv->id.state != IB_CM_SIDR_REQ_RCVD) |
---|
| 3668 | + return -EINVAL; |
---|
3667 | 3669 | |
---|
3668 | 3670 | ret = cm_alloc_msg(cm_id_priv, &msg); |
---|
3669 | 3671 | if (ret) |
---|
3670 | | - goto error; |
---|
| 3672 | + return ret; |
---|
3671 | 3673 | |
---|
3672 | 3674 | cm_format_sidr_rep((struct cm_sidr_rep_msg *) msg->mad, cm_id_priv, |
---|
3673 | 3675 | param); |
---|
| 3676 | + trace_icm_send_sidr_rep(&cm_id_priv->id); |
---|
3674 | 3677 | ret = ib_post_send_mad(msg, NULL); |
---|
3675 | 3678 | if (ret) { |
---|
3676 | | - spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
---|
3677 | 3679 | cm_free_msg(msg); |
---|
3678 | 3680 | return ret; |
---|
3679 | 3681 | } |
---|
3680 | | - cm_id->state = IB_CM_IDLE; |
---|
3681 | | - spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
---|
3682 | | - |
---|
| 3682 | + cm_id_priv->id.state = IB_CM_IDLE; |
---|
3683 | 3683 | spin_lock_irqsave(&cm.lock, flags); |
---|
3684 | 3684 | if (!RB_EMPTY_NODE(&cm_id_priv->sidr_id_node)) { |
---|
3685 | 3685 | rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table); |
---|
.. | .. |
---|
3687 | 3687 | } |
---|
3688 | 3688 | spin_unlock_irqrestore(&cm.lock, flags); |
---|
3689 | 3689 | return 0; |
---|
| 3690 | +} |
---|
3690 | 3691 | |
---|
3691 | | -error: spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
---|
| 3692 | +int ib_send_cm_sidr_rep(struct ib_cm_id *cm_id, |
---|
| 3693 | + struct ib_cm_sidr_rep_param *param) |
---|
| 3694 | +{ |
---|
| 3695 | + struct cm_id_private *cm_id_priv = |
---|
| 3696 | + container_of(cm_id, struct cm_id_private, id); |
---|
| 3697 | + unsigned long flags; |
---|
| 3698 | + int ret; |
---|
| 3699 | + |
---|
| 3700 | + spin_lock_irqsave(&cm_id_priv->lock, flags); |
---|
| 3701 | + ret = cm_send_sidr_rep_locked(cm_id_priv, param); |
---|
| 3702 | + spin_unlock_irqrestore(&cm_id_priv->lock, flags); |
---|
3692 | 3703 | return ret; |
---|
3693 | 3704 | } |
---|
3694 | 3705 | EXPORT_SYMBOL(ib_send_cm_sidr_rep); |
---|
.. | .. |
---|
3702 | 3713 | sidr_rep_msg = (struct cm_sidr_rep_msg *) |
---|
3703 | 3714 | work->mad_recv_wc->recv_buf.mad; |
---|
3704 | 3715 | param = &work->cm_event.param.sidr_rep_rcvd; |
---|
3705 | | - param->status = sidr_rep_msg->status; |
---|
3706 | | - param->qkey = be32_to_cpu(sidr_rep_msg->qkey); |
---|
3707 | | - param->qpn = be32_to_cpu(cm_sidr_rep_get_qpn(sidr_rep_msg)); |
---|
3708 | | - param->info = &sidr_rep_msg->info; |
---|
3709 | | - param->info_len = sidr_rep_msg->info_length; |
---|
| 3716 | + param->status = IBA_GET(CM_SIDR_REP_STATUS, sidr_rep_msg); |
---|
| 3717 | + param->qkey = IBA_GET(CM_SIDR_REP_Q_KEY, sidr_rep_msg); |
---|
| 3718 | + param->qpn = IBA_GET(CM_SIDR_REP_QPN, sidr_rep_msg); |
---|
| 3719 | + param->info = IBA_GET_MEM_PTR(CM_SIDR_REP_ADDITIONAL_INFORMATION, |
---|
| 3720 | + sidr_rep_msg); |
---|
| 3721 | + param->info_len = IBA_GET(CM_SIDR_REP_ADDITIONAL_INFORMATION_LENGTH, |
---|
| 3722 | + sidr_rep_msg); |
---|
3710 | 3723 | param->sgid_attr = cm_id_priv->av.ah_attr.grh.sgid_attr; |
---|
3711 | | - work->cm_event.private_data = &sidr_rep_msg->private_data; |
---|
| 3724 | + work->cm_event.private_data = |
---|
| 3725 | + IBA_GET_MEM_PTR(CM_SIDR_REP_PRIVATE_DATA, sidr_rep_msg); |
---|
3712 | 3726 | } |
---|
3713 | 3727 | |
---|
3714 | 3728 | static int cm_sidr_rep_handler(struct cm_work *work) |
---|
.. | .. |
---|
3718 | 3732 | |
---|
3719 | 3733 | sidr_rep_msg = (struct cm_sidr_rep_msg *) |
---|
3720 | 3734 | work->mad_recv_wc->recv_buf.mad; |
---|
3721 | | - cm_id_priv = cm_acquire_id(sidr_rep_msg->request_id, 0); |
---|
| 3735 | + cm_id_priv = cm_acquire_id( |
---|
| 3736 | + cpu_to_be32(IBA_GET(CM_SIDR_REP_REQUESTID, sidr_rep_msg)), 0); |
---|
3722 | 3737 | if (!cm_id_priv) |
---|
3723 | 3738 | return -EINVAL; /* Unmatched reply. */ |
---|
3724 | 3739 | |
---|
.. | .. |
---|
3756 | 3771 | if (msg != cm_id_priv->msg || state != cm_id_priv->id.state) |
---|
3757 | 3772 | goto discard; |
---|
3758 | 3773 | |
---|
3759 | | - pr_debug_ratelimited("CM: failed sending MAD in state %d. (%s)\n", |
---|
3760 | | - state, ib_wc_status_msg(wc_status)); |
---|
| 3774 | + trace_icm_mad_send_err(state, wc_status); |
---|
3761 | 3775 | switch (state) { |
---|
3762 | 3776 | case IB_CM_REQ_SENT: |
---|
3763 | 3777 | case IB_CM_MRA_REQ_RCVD: |
---|
.. | .. |
---|
3880 | 3894 | ret = cm_timewait_handler(work); |
---|
3881 | 3895 | break; |
---|
3882 | 3896 | default: |
---|
3883 | | - pr_debug("cm_event.event: 0x%x\n", work->cm_event.event); |
---|
| 3897 | + trace_icm_handler_err(work->cm_event.event); |
---|
3884 | 3898 | ret = -EINVAL; |
---|
3885 | 3899 | break; |
---|
3886 | 3900 | } |
---|
.. | .. |
---|
3916 | 3930 | ret = -EISCONN; |
---|
3917 | 3931 | break; |
---|
3918 | 3932 | default: |
---|
3919 | | - pr_debug("%s: local_id %d, cm_id->state: %d\n", __func__, |
---|
3920 | | - be32_to_cpu(cm_id->local_id), cm_id->state); |
---|
| 3933 | + trace_icm_establish_err(cm_id); |
---|
3921 | 3934 | ret = -EINVAL; |
---|
3922 | 3935 | break; |
---|
3923 | 3936 | } |
---|
.. | .. |
---|
4060 | 4073 | atomic_long_inc(&port->counter_group[CM_RECV]. |
---|
4061 | 4074 | counter[attr_id - CM_ATTR_ID_OFFSET]); |
---|
4062 | 4075 | |
---|
4063 | | - work = kmalloc(sizeof(*work) + sizeof(struct sa_path_rec) * paths, |
---|
4064 | | - GFP_KERNEL); |
---|
| 4076 | + work = kmalloc(struct_size(work, path, paths), GFP_KERNEL); |
---|
4065 | 4077 | if (!work) { |
---|
4066 | 4078 | ib_free_recv_mad(mad_recv_wc); |
---|
4067 | 4079 | return; |
---|
.. | .. |
---|
4115 | 4127 | ret = 0; |
---|
4116 | 4128 | break; |
---|
4117 | 4129 | default: |
---|
4118 | | - pr_debug("%s: local_id %d, cm_id_priv->id.state: %d\n", |
---|
4119 | | - __func__, be32_to_cpu(cm_id_priv->id.local_id), |
---|
4120 | | - cm_id_priv->id.state); |
---|
| 4130 | + trace_icm_qp_init_err(&cm_id_priv->id); |
---|
4121 | 4131 | ret = -EINVAL; |
---|
4122 | 4132 | break; |
---|
4123 | 4133 | } |
---|
.. | .. |
---|
4165 | 4175 | ret = 0; |
---|
4166 | 4176 | break; |
---|
4167 | 4177 | default: |
---|
4168 | | - pr_debug("%s: local_id %d, cm_id_priv->id.state: %d\n", |
---|
4169 | | - __func__, be32_to_cpu(cm_id_priv->id.local_id), |
---|
4170 | | - cm_id_priv->id.state); |
---|
| 4178 | + trace_icm_qp_rtr_err(&cm_id_priv->id); |
---|
4171 | 4179 | ret = -EINVAL; |
---|
4172 | 4180 | break; |
---|
4173 | 4181 | } |
---|
.. | .. |
---|
4204 | 4212 | qp_attr->retry_cnt = cm_id_priv->retry_count; |
---|
4205 | 4213 | qp_attr->rnr_retry = cm_id_priv->rnr_retry_count; |
---|
4206 | 4214 | qp_attr->max_rd_atomic = cm_id_priv->initiator_depth; |
---|
4207 | | - /* fall through */ |
---|
| 4215 | + fallthrough; |
---|
4208 | 4216 | case IB_QPT_XRC_TGT: |
---|
4209 | 4217 | *qp_attr_mask |= IB_QP_TIMEOUT; |
---|
4210 | 4218 | qp_attr->timeout = cm_id_priv->av.timeout; |
---|
.. | .. |
---|
4227 | 4235 | ret = 0; |
---|
4228 | 4236 | break; |
---|
4229 | 4237 | default: |
---|
4230 | | - pr_debug("%s: local_id %d, cm_id_priv->id.state: %d\n", |
---|
4231 | | - __func__, be32_to_cpu(cm_id_priv->id.local_id), |
---|
4232 | | - cm_id_priv->id.state); |
---|
| 4238 | + trace_icm_qp_rts_err(&cm_id_priv->id); |
---|
4233 | 4239 | ret = -EINVAL; |
---|
4234 | 4240 | break; |
---|
4235 | 4241 | } |
---|
.. | .. |
---|
4285 | 4291 | .default_attrs = cm_counter_default_attrs |
---|
4286 | 4292 | }; |
---|
4287 | 4293 | |
---|
4288 | | -static void cm_release_port_obj(struct kobject *obj) |
---|
4289 | | -{ |
---|
4290 | | - struct cm_port *cm_port; |
---|
4291 | | - |
---|
4292 | | - cm_port = container_of(obj, struct cm_port, port_obj); |
---|
4293 | | - kfree(cm_port); |
---|
4294 | | -} |
---|
4295 | | - |
---|
4296 | | -static struct kobj_type cm_port_obj_type = { |
---|
4297 | | - .release = cm_release_port_obj |
---|
4298 | | -}; |
---|
4299 | | - |
---|
4300 | | -static char *cm_devnode(struct device *dev, umode_t *mode) |
---|
4301 | | -{ |
---|
4302 | | - if (mode) |
---|
4303 | | - *mode = 0666; |
---|
4304 | | - return kasprintf(GFP_KERNEL, "infiniband/%s", dev_name(dev)); |
---|
4305 | | -} |
---|
4306 | | - |
---|
4307 | | -struct class cm_class = { |
---|
4308 | | - .owner = THIS_MODULE, |
---|
4309 | | - .name = "infiniband_cm", |
---|
4310 | | - .devnode = cm_devnode, |
---|
4311 | | -}; |
---|
4312 | | -EXPORT_SYMBOL(cm_class); |
---|
4313 | | - |
---|
4314 | 4294 | static int cm_create_port_fs(struct cm_port *port) |
---|
4315 | 4295 | { |
---|
4316 | 4296 | int i, ret; |
---|
4317 | 4297 | |
---|
4318 | | - ret = kobject_init_and_add(&port->port_obj, &cm_port_obj_type, |
---|
4319 | | - &port->cm_dev->device->kobj, |
---|
4320 | | - "%d", port->port_num); |
---|
4321 | | - if (ret) { |
---|
4322 | | - kfree(port); |
---|
4323 | | - return ret; |
---|
4324 | | - } |
---|
4325 | | - |
---|
4326 | 4298 | for (i = 0; i < CM_COUNTER_GROUPS; i++) { |
---|
4327 | | - ret = kobject_init_and_add(&port->counter_group[i].obj, |
---|
4328 | | - &cm_counter_obj_type, |
---|
4329 | | - &port->port_obj, |
---|
4330 | | - "%s", counter_group_names[i]); |
---|
| 4299 | + ret = ib_port_register_module_stat(port->cm_dev->ib_device, |
---|
| 4300 | + port->port_num, |
---|
| 4301 | + &port->counter_group[i].obj, |
---|
| 4302 | + &cm_counter_obj_type, |
---|
| 4303 | + counter_group_names[i]); |
---|
4331 | 4304 | if (ret) |
---|
4332 | 4305 | goto error; |
---|
4333 | 4306 | } |
---|
.. | .. |
---|
4336 | 4309 | |
---|
4337 | 4310 | error: |
---|
4338 | 4311 | while (i--) |
---|
4339 | | - kobject_put(&port->counter_group[i].obj); |
---|
4340 | | - kobject_put(&port->port_obj); |
---|
| 4312 | + ib_port_unregister_module_stat(&port->counter_group[i].obj); |
---|
4341 | 4313 | return ret; |
---|
4342 | 4314 | |
---|
4343 | 4315 | } |
---|
.. | .. |
---|
4347 | 4319 | int i; |
---|
4348 | 4320 | |
---|
4349 | 4321 | for (i = 0; i < CM_COUNTER_GROUPS; i++) |
---|
4350 | | - kobject_put(&port->counter_group[i].obj); |
---|
| 4322 | + ib_port_unregister_module_stat(&port->counter_group[i].obj); |
---|
4351 | 4323 | |
---|
4352 | | - kobject_put(&port->port_obj); |
---|
4353 | 4324 | } |
---|
4354 | 4325 | |
---|
4355 | | -static void cm_add_one(struct ib_device *ib_device) |
---|
| 4326 | +static int cm_add_one(struct ib_device *ib_device) |
---|
4356 | 4327 | { |
---|
4357 | 4328 | struct cm_device *cm_dev; |
---|
4358 | 4329 | struct cm_port *port; |
---|
.. | .. |
---|
4366 | 4337 | unsigned long flags; |
---|
4367 | 4338 | int ret; |
---|
4368 | 4339 | int count = 0; |
---|
4369 | | - u8 i; |
---|
| 4340 | + unsigned int i; |
---|
4370 | 4341 | |
---|
4371 | 4342 | cm_dev = kzalloc(struct_size(cm_dev, port, ib_device->phys_port_cnt), |
---|
4372 | 4343 | GFP_KERNEL); |
---|
4373 | 4344 | if (!cm_dev) |
---|
4374 | | - return; |
---|
| 4345 | + return -ENOMEM; |
---|
4375 | 4346 | |
---|
4376 | 4347 | cm_dev->ib_device = ib_device; |
---|
4377 | 4348 | cm_dev->ack_delay = ib_device->attrs.local_ca_ack_delay; |
---|
4378 | 4349 | cm_dev->going_down = 0; |
---|
4379 | | - cm_dev->device = device_create(&cm_class, &ib_device->dev, |
---|
4380 | | - MKDEV(0, 0), NULL, |
---|
4381 | | - "%s", ib_device->name); |
---|
4382 | | - if (IS_ERR(cm_dev->device)) { |
---|
4383 | | - kfree(cm_dev); |
---|
4384 | | - return; |
---|
4385 | | - } |
---|
4386 | 4350 | |
---|
4387 | 4351 | set_bit(IB_MGMT_METHOD_SEND, reg_req.method_mask); |
---|
4388 | | - for (i = 1; i <= ib_device->phys_port_cnt; i++) { |
---|
| 4352 | + rdma_for_each_port (ib_device, i) { |
---|
4389 | 4353 | if (!rdma_cap_ib_cm(ib_device, i)) |
---|
4390 | 4354 | continue; |
---|
4391 | 4355 | |
---|
4392 | 4356 | port = kzalloc(sizeof *port, GFP_KERNEL); |
---|
4393 | | - if (!port) |
---|
| 4357 | + if (!port) { |
---|
| 4358 | + ret = -ENOMEM; |
---|
4394 | 4359 | goto error1; |
---|
| 4360 | + } |
---|
4395 | 4361 | |
---|
4396 | 4362 | cm_dev->port[i-1] = port; |
---|
4397 | 4363 | port->cm_dev = cm_dev; |
---|
.. | .. |
---|
4412 | 4378 | cm_recv_handler, |
---|
4413 | 4379 | port, |
---|
4414 | 4380 | 0); |
---|
4415 | | - if (IS_ERR(port->mad_agent)) |
---|
| 4381 | + if (IS_ERR(port->mad_agent)) { |
---|
| 4382 | + ret = PTR_ERR(port->mad_agent); |
---|
4416 | 4383 | goto error2; |
---|
| 4384 | + } |
---|
4417 | 4385 | |
---|
4418 | 4386 | ret = ib_modify_port(ib_device, i, 0, &port_modify); |
---|
4419 | 4387 | if (ret) |
---|
.. | .. |
---|
4422 | 4390 | count++; |
---|
4423 | 4391 | } |
---|
4424 | 4392 | |
---|
4425 | | - if (!count) |
---|
| 4393 | + if (!count) { |
---|
| 4394 | + ret = -EOPNOTSUPP; |
---|
4426 | 4395 | goto free; |
---|
| 4396 | + } |
---|
4427 | 4397 | |
---|
4428 | 4398 | ib_set_client_data(ib_device, &cm_client, cm_dev); |
---|
4429 | 4399 | |
---|
4430 | 4400 | write_lock_irqsave(&cm.device_lock, flags); |
---|
4431 | 4401 | list_add_tail(&cm_dev->list, &cm.device_list); |
---|
4432 | 4402 | write_unlock_irqrestore(&cm.device_lock, flags); |
---|
4433 | | - return; |
---|
| 4403 | + return 0; |
---|
4434 | 4404 | |
---|
4435 | 4405 | error3: |
---|
4436 | 4406 | ib_unregister_mad_agent(port->mad_agent); |
---|
.. | .. |
---|
4439 | 4409 | error1: |
---|
4440 | 4410 | port_modify.set_port_cap_mask = 0; |
---|
4441 | 4411 | port_modify.clr_port_cap_mask = IB_PORT_CM_SUP; |
---|
| 4412 | + kfree(port); |
---|
4442 | 4413 | while (--i) { |
---|
4443 | 4414 | if (!rdma_cap_ib_cm(ib_device, i)) |
---|
4444 | 4415 | continue; |
---|
.. | .. |
---|
4447 | 4418 | ib_modify_port(ib_device, port->port_num, 0, &port_modify); |
---|
4448 | 4419 | ib_unregister_mad_agent(port->mad_agent); |
---|
4449 | 4420 | cm_remove_port_fs(port); |
---|
| 4421 | + kfree(port); |
---|
4450 | 4422 | } |
---|
4451 | 4423 | free: |
---|
4452 | | - device_unregister(cm_dev->device); |
---|
4453 | 4424 | kfree(cm_dev); |
---|
| 4425 | + return ret; |
---|
4454 | 4426 | } |
---|
4455 | 4427 | |
---|
4456 | 4428 | static void cm_remove_one(struct ib_device *ib_device, void *client_data) |
---|
.. | .. |
---|
4463 | 4435 | .clr_port_cap_mask = IB_PORT_CM_SUP |
---|
4464 | 4436 | }; |
---|
4465 | 4437 | unsigned long flags; |
---|
4466 | | - int i; |
---|
4467 | | - |
---|
4468 | | - if (!cm_dev) |
---|
4469 | | - return; |
---|
| 4438 | + unsigned int i; |
---|
4470 | 4439 | |
---|
4471 | 4440 | write_lock_irqsave(&cm.device_lock, flags); |
---|
4472 | 4441 | list_del(&cm_dev->list); |
---|
.. | .. |
---|
4476 | 4445 | cm_dev->going_down = 1; |
---|
4477 | 4446 | spin_unlock_irq(&cm.lock); |
---|
4478 | 4447 | |
---|
4479 | | - for (i = 1; i <= ib_device->phys_port_cnt; i++) { |
---|
| 4448 | + rdma_for_each_port (ib_device, i) { |
---|
4480 | 4449 | if (!rdma_cap_ib_cm(ib_device, i)) |
---|
4481 | 4450 | continue; |
---|
4482 | 4451 | |
---|
.. | .. |
---|
4501 | 4470 | spin_unlock_irq(&cm.state_lock); |
---|
4502 | 4471 | ib_unregister_mad_agent(cur_mad_agent); |
---|
4503 | 4472 | cm_remove_port_fs(port); |
---|
| 4473 | + kfree(port); |
---|
4504 | 4474 | } |
---|
4505 | 4475 | |
---|
4506 | | - device_unregister(cm_dev->device); |
---|
4507 | 4476 | kfree(cm_dev); |
---|
4508 | 4477 | } |
---|
4509 | 4478 | |
---|
.. | .. |
---|
4511 | 4480 | { |
---|
4512 | 4481 | int ret; |
---|
4513 | 4482 | |
---|
4514 | | - memset(&cm, 0, sizeof cm); |
---|
4515 | 4483 | INIT_LIST_HEAD(&cm.device_list); |
---|
4516 | 4484 | rwlock_init(&cm.device_lock); |
---|
4517 | 4485 | spin_lock_init(&cm.lock); |
---|
.. | .. |
---|
4521 | 4489 | cm.remote_id_table = RB_ROOT; |
---|
4522 | 4490 | cm.remote_qp_table = RB_ROOT; |
---|
4523 | 4491 | cm.remote_sidr_table = RB_ROOT; |
---|
4524 | | - idr_init(&cm.local_id_table); |
---|
| 4492 | + xa_init_flags(&cm.local_id_table, XA_FLAGS_ALLOC); |
---|
4525 | 4493 | get_random_bytes(&cm.random_id_operand, sizeof cm.random_id_operand); |
---|
4526 | 4494 | INIT_LIST_HEAD(&cm.timewait_list); |
---|
4527 | | - |
---|
4528 | | - ret = class_register(&cm_class); |
---|
4529 | | - if (ret) { |
---|
4530 | | - ret = -ENOMEM; |
---|
4531 | | - goto error1; |
---|
4532 | | - } |
---|
4533 | 4495 | |
---|
4534 | 4496 | cm.wq = alloc_workqueue("ib_cm", 0, 1); |
---|
4535 | 4497 | if (!cm.wq) { |
---|
.. | .. |
---|
4545 | 4507 | error3: |
---|
4546 | 4508 | destroy_workqueue(cm.wq); |
---|
4547 | 4509 | error2: |
---|
4548 | | - class_unregister(&cm_class); |
---|
4549 | | -error1: |
---|
4550 | | - idr_destroy(&cm.local_id_table); |
---|
4551 | 4510 | return ret; |
---|
4552 | 4511 | } |
---|
4553 | 4512 | |
---|
.. | .. |
---|
4568 | 4527 | kfree(timewait_info); |
---|
4569 | 4528 | } |
---|
4570 | 4529 | |
---|
4571 | | - class_unregister(&cm_class); |
---|
4572 | | - idr_destroy(&cm.local_id_table); |
---|
| 4530 | + WARN_ON(!xa_empty(&cm.local_id_table)); |
---|
4573 | 4531 | } |
---|
4574 | 4532 | |
---|
4575 | 4533 | module_init(ib_cm_init); |
---|
4576 | 4534 | module_exit(ib_cm_cleanup); |
---|
4577 | | - |
---|