Print this page
8368 remove warlock leftovers from usr/src/uts


  79                             ibt_async_code_t, ibt_async_event_t *);
  80 
  81 /* Global variables */
  82 char                    cmlog[] = "ibcm";       /* for debug log messages */
  83 ibt_clnt_hdl_t          ibcm_ibt_handle;        /* IBT handle */
  84 kmutex_t                ibcm_svc_info_lock;     /* list lock */
  85 kcondvar_t              ibcm_svc_info_cv;       /* cv for deregister */
  86 kmutex_t                ibcm_recv_mutex;
  87 avl_tree_t              ibcm_svc_avl_tree;
  88 taskq_t                 *ibcm_taskq = NULL;
  89 int                     taskq_dispatch_fail_cnt;
  90 
  91 kmutex_t                ibcm_mcglist_lock;      /* MCG list lock */
  92 kmutex_t                ibcm_trace_mutex;       /* Trace mutex */
  93 kmutex_t                ibcm_trace_print_mutex; /* Trace print mutex */
  94 int                     ibcm_conn_max_trcnt = IBCM_MAX_CONN_TRCNT;
  95 
  96 int                     ibcm_enable_trace = 2;  /* Trace level 4 by default */
  97 int                     ibcm_dtrace = 0; /* conditionally enable more dtrace */
  98 
  99 _NOTE(MUTEX_PROTECTS_DATA(ibcm_svc_info_lock, ibcm_svc_info_s::{svc_bind_list
 100     svc_ref_cnt svc_to_delete}))
 101 
 102 _NOTE(MUTEX_PROTECTS_DATA(ibcm_svc_info_lock, ibcm_svc_bind_s::{sbind_link}))
 103 
 104 _NOTE(MUTEX_PROTECTS_DATA(ibcm_trace_mutex, ibcm_conn_trace_s))
 105 
 106 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibcm_conn_trace_s))
 107 
 108 _NOTE(MUTEX_PROTECTS_DATA(ibcm_trace_print_mutex, ibcm_debug_buf))
 109 
 110 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibcm_debug_buf))
 111 
 112 /*
 113  * Initial state is INIT. All hca dr's return success immediately in this
 114  * state, without adding or deleting any hca's to CM.
 115  */
 116 ibcm_finit_state_t      ibcm_finit_state = IBCM_FINIT_INIT;
 117 
 118 /* mutex and cv to manage hca's reference and resource count(s) */
 119 kmutex_t                ibcm_global_hca_lock;
 120 kcondvar_t              ibcm_global_hca_cv;
 121 
 122 /* mutex and cv to sa session open */
 123 kmutex_t                ibcm_sa_open_lock;
 124 kcondvar_t              ibcm_sa_open_cv;
 125 int                     ibcm_sa_timeout_delay = 1;              /* in ticks */
 126 _NOTE(MUTEX_PROTECTS_DATA(ibcm_sa_open_lock,
 127     ibcm_port_info_s::{port_ibmf_saa_hdl port_saa_open_in_progress}))
 128 
 129 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibcm_port_info_s::{port_ibmf_saa_hdl}))
 130 
 131 /* serialize sm notice callbacks */
 132 kmutex_t                ibcm_sm_notice_serialize_lock;
 133 
 134 _NOTE(LOCK_ORDER(ibcm_sm_notice_serialize_lock ibcm_global_hca_lock))
 135 
 136 _NOTE(MUTEX_PROTECTS_DATA(ibcm_global_hca_lock, ibcm_hca_info_s::{hca_state
 137     hca_svc_cnt hca_acc_cnt hca_res_cnt hca_next}))
 138 
 139 _NOTE(MUTEX_PROTECTS_DATA(ibcm_global_hca_lock,
 140     ibcm_port_info_s::{port_ibmf_hdl}))
 141 
 142 _NOTE(MUTEX_PROTECTS_DATA(ibcm_sm_notice_serialize_lock,
 143     ibcm_port_info_s::{port_event_status}))
 144 
 145 _NOTE(DATA_READABLE_WITHOUT_LOCK(ibcm_hca_info_s::{hca_state}))
 146 _NOTE(DATA_READABLE_WITHOUT_LOCK(
 147     ibcm_hca_info_s::{hca_port_info.port_ibmf_hdl}))
 148 
 149 /* mutex for CM's qp list management */
 150 kmutex_t                ibcm_qp_list_lock;
 151 
 152 _NOTE(MUTEX_PROTECTS_DATA(ibcm_qp_list_lock, ibcm_port_info_s::{port_qplist}))
 153 _NOTE(MUTEX_PROTECTS_DATA(ibcm_qp_list_lock, ibcm_qp_list_s))
 154 _NOTE(MUTEX_PROTECTS_DATA(ibcm_qp_list_lock, ibcm_qp_list_s))
 155 
 156 kcondvar_t              ibcm_timeout_list_cv;
 157 kcondvar_t              ibcm_timeout_thread_done_cv;
 158 kt_did_t                ibcm_timeout_thread_did;
 159 ibcm_state_data_t       *ibcm_timeout_list_hdr, *ibcm_timeout_list_tail;
 160 ibcm_ud_state_data_t    *ibcm_ud_timeout_list_hdr, *ibcm_ud_timeout_list_tail;
 161 kmutex_t                ibcm_timeout_list_lock;
 162 uint8_t                 ibcm_timeout_list_flags = 0;
 163 pri_t                   ibcm_timeout_thread_pri = MINCLSYSPRI;
 164 
 165 _NOTE(MUTEX_PROTECTS_DATA(ibcm_timeout_list_lock,
 166     ibcm_state_data_s::timeout_next))
 167 
 168 _NOTE(MUTEX_PROTECTS_DATA(ibcm_timeout_list_lock,
 169     ibcm_ud_state_data_s::ud_timeout_next))
 170 
 171 /*
 172  * Flow control logic for open_rc_channel uses the following.
 173  */
 174 
 175 struct ibcm_open_s {
 176         kmutex_t                mutex;
 177         kcondvar_t              cv;
 178         uint8_t                 task_running;
 179         uint_t                  queued;
 180         uint_t                  exit_deferred;
 181         uint_t                  in_progress;
 182         uint_t                  in_progress_max;
 183         uint_t                  sends;
 184         uint_t                  sends_max;
 185         uint_t                  sends_lowat;
 186         uint_t                  sends_hiwat;
 187         ibcm_state_data_t       *tail;
 188         ibcm_state_data_t       head;
 189 } ibcm_open;
 190 


 340         "INIT_RTR_FAIL              ",
 341         "RTR_RTS                    ",
 342         "RTR_RTS_FAIL               ",
 343         "RTS_RTS                    ",
 344         "RTS_RTS_FAIL               ",
 345         "TO_ERROR                   ",
 346         "ERROR_FAIL                 ",
 347         "SET_ALT                    ",
 348         "SET_ALT_FAIL               ",
 349         "STALE_DETECT               ",
 350         "OUTGOING_REQ_RETRY         ",
 351         "OUTGOING_REP_RETRY         ",
 352         "OUTGOING_LAP_RETRY         ",
 353         "OUTGOING_MRA_RETRY         ",
 354         "OUTGOING_DREQ_RETRY        ",
 355         "NEVER SEE THIS             "
 356 };
 357 
 358 char    ibcm_debug_buf[IBCM_DEBUG_BUF_SIZE];
 359 
 360 _NOTE(SCHEME_PROTECTS_DATA("used in a localized function consistently",
 361     ibcm_debug_buf))
 362 _NOTE(READ_ONLY_DATA(ibcm_taskq))
 363 
 364 _NOTE(MUTEX_PROTECTS_DATA(ibcm_timeout_list_lock, ibcm_timeout_list_flags))
 365 _NOTE(MUTEX_PROTECTS_DATA(ibcm_timeout_list_lock, ibcm_timeout_list_hdr))
 366 _NOTE(MUTEX_PROTECTS_DATA(ibcm_timeout_list_lock, ibcm_ud_timeout_list_hdr))
 367 
 368 #ifdef DEBUG
 369 int             ibcm_test_mode = 0;     /* set to 1, if running tests */
 370 #endif
 371 
 372 
 373 /* Module Driver Info */
 374 static struct modlmisc ibcm_modlmisc = {
 375         &mod_miscops,
 376         "IB Communication Manager"
 377 };
 378 
 379 /* Module Linkage */
 380 static struct modlinkage ibcm_modlinkage = {
 381         MODREV_1,
 382         &ibcm_modlmisc,
 383         NULL
 384 };
 385 
 386 
 387 int


 507         mutex_destroy(&ibcm_recv_mutex);
 508         mutex_destroy(&ibcm_sm_notice_serialize_lock);
 509         mutex_destroy(&ibcm_qp_list_lock);
 510         mutex_destroy(&ibcm_trace_mutex);
 511         mutex_destroy(&ibcm_trace_print_mutex);
 512         cv_destroy(&ibcm_svc_info_cv);
 513         cv_destroy(&ibcm_timeout_list_cv);
 514         cv_destroy(&ibcm_timeout_thread_done_cv);
 515         cv_destroy(&ibcm_global_hca_cv);
 516         cv_destroy(&ibcm_sa_open_cv);
 517         avl_destroy(&ibcm_svc_avl_tree);
 518 
 519         IBTF_DPRINTF_L5(cmlog, "ibcm_fini_locks: done");
 520 }
 521 
 522 
 523 /* Initialize CM's classport info */
 524 static void
 525 ibcm_init_classportinfo()
 526 {
 527         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_clpinfo));
 528 
 529         ibcm_clpinfo.BaseVersion = IBCM_MAD_BASE_VERSION;
 530         ibcm_clpinfo.ClassVersion = IBCM_MAD_CLASS_VERSION;
 531 
 532         /* For now, CM supports same capabilities at all ports */
 533         ibcm_clpinfo.CapabilityMask =
 534             h2b16(IBCM_CPINFO_CAP_RC | IBCM_CPINFO_CAP_SIDR);
 535 
 536         /* Bits 0-7 are all 0 for Communication Mgmt Class */
 537 
 538         /* For now, CM has the same respvalue at all ports */
 539         ibcm_clpinfo.RespTimeValue_plus =
 540             h2b32(ibt_usec2ib(ibcm_local_processing_time) & 0x1f);
 541 
 542         /* For now, redirect fields are set to 0 */
 543         /* Trap fields are not applicable to CM, hence set to 0 */
 544 
 545         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_clpinfo));
 546         IBTF_DPRINTF_L5(cmlog, "ibcm_init_classportinfo: done");
 547 }
 548 
 549 /*
 550  * ibcm_init():
 551  *      - call ibt_attach()
 552  *      - create AVL trees
 553  *      - Attach HCA handlers that are already present before
 554  *      CM got loaded.
 555  *
 556  * Arguments:   NONE
 557  *
 558  * Return values:
 559  *      IBCM_SUCCESS - success
 560  */
 561 static ibcm_status_t
 562 ibcm_init(void)
 563 {
 564         ibt_status_t    status;
 565         kthread_t       *t;


 567         IBTF_DPRINTF_L3(cmlog, "ibcm_init:");
 568 
 569         ibcm_init_classportinfo();
 570 
 571         if (ibcm_init_ids() != IBCM_SUCCESS) {
 572                 IBTF_DPRINTF_L1(cmlog, "ibcm_init: "
 573                     "fatal error: vmem_create() failed");
 574                 return (IBCM_FAILURE);
 575         }
 576         ibcm_init_locks();
 577 
 578         if (ibcm_ar_init() != IBCM_SUCCESS) {
 579                 IBTF_DPRINTF_L1(cmlog, "ibcm_init: "
 580                     "fatal error: ibcm_ar_init() failed");
 581                 ibcm_fini_ids();
 582                 ibcm_fini_locks();
 583                 return (IBCM_FAILURE);
 584         }
 585         ibcm_rc_flow_control_init();
 586 
 587         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_taskq))
 588         ibcm_taskq = system_taskq;
 589         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_taskq))
 590 
 591         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_timeout_list_flags))
 592         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_timeout_thread_did))
 593 
 594         /* Start the timeout list processing thread */
 595         ibcm_timeout_list_flags = 0;
 596         t = thread_create(NULL, 0, ibcm_process_tlist, 0, 0, &p0, TS_RUN,
 597             ibcm_timeout_thread_pri);
 598         ibcm_timeout_thread_did = t->t_did;
 599 
 600         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_timeout_list_flags))
 601         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_timeout_thread_did))
 602 
 603         /*
 604          * NOTE : if ibt_attach is done after ibcm_init_hcas, then some
 605          * HCA DR events may be lost. CM could call re-init hca list
 606          * again, but it is more complicated. Some HCA's DR's lost may
 607          * be HCA detach, which makes hca list re-syncing and locking more
 608          * complex
 609          */
 610         status = ibt_attach(&ibcm_ibt_modinfo, NULL, NULL, &ibcm_ibt_handle);
 611         if (status != IBT_SUCCESS) {
 612                 IBTF_DPRINTF_L2(cmlog, "ibcm_init(): ibt_attach failed %d",
 613                     status);
 614                 (void) ibcm_ar_fini();
 615                 ibcm_stop_timeout_thread();
 616                 ibcm_fini_ids();
 617                 ibcm_fini_locks();
 618                 ibcm_rc_flow_control_fini();
 619                 return (IBCM_FAILURE);
 620         }
 621 
 622         /* Block all HCA attach/detach asyncs */


 708         /* disables any new hca attach/detaches */
 709         mutex_enter(&ibcm_global_hca_lock);
 710 
 711         ibcm_finit_state = IBCM_FINIT_BUSY;
 712 
 713         if (ibcm_fini_hcas() != IBCM_SUCCESS) {
 714                 IBTF_DPRINTF_L2(cmlog, "ibcm_fini: "
 715                     "some hca's still have client resources");
 716 
 717                 /* First, re-initialize the hcas */
 718                 ibcm_init_hcas();
 719                 /* and then enable the HCA asyncs */
 720                 ibcm_finit_state = IBCM_FINIT_IDLE;
 721                 mutex_exit(&ibcm_global_hca_lock);
 722                 if (ibcm_ar_init() != IBCM_SUCCESS) {
 723                         IBTF_DPRINTF_L1(cmlog, "ibcm_fini:ibcm_ar_init failed");
 724                 }
 725                 return (IBCM_FAILURE);
 726         }
 727 
 728         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_timeout_list_hdr))
 729         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(ibcm_ud_timeout_list_hdr))
 730 
 731         ASSERT(ibcm_timeout_list_hdr == NULL);
 732         ASSERT(ibcm_ud_timeout_list_hdr == NULL);
 733 
 734         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_timeout_list_hdr))
 735         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(ibcm_ud_timeout_list_hdr))
 736 
 737         /* Release any pending asyncs on ibcm_global_hca_lock */
 738         ibcm_finit_state = IBCM_FINIT_SUCCESS;
 739         mutex_exit(&ibcm_global_hca_lock);
 740 
 741         ibcm_stop_timeout_thread();
 742 
 743         ibtl_cm_set_node_info_cb(NULL);
 744         /*
 745          * Detach from IBTL. Waits until all pending asyncs are complete.
 746          * Above cv_broadcast wakes up any waiting hca attach/detach asyncs
 747          */
 748         status = ibt_detach(ibcm_ibt_handle);
 749 
 750         /* if detach fails, CM didn't free up some resources, so assert */
 751         if (status != IBT_SUCCESS)
 752                 IBTF_DPRINTF_L1(cmlog, "ibcm_fini: ibt_detach failed %d",
 753                     status);
 754 
 755         ibcm_rc_flow_control_fini();
 756 


 816  *      hca's
 817  *
 818  * Arguments: (WILL CHANGE BASED ON ASYNC EVENT CODE)
 819  *      hca_guid        - HCA's guid
 820  *
 821  * Return values: NONE
 822  */
 823 static void
 824 ibcm_hca_attach(ib_guid_t hcaguid)
 825 {
 826         int                     i;
 827         ibt_status_t            status;
 828         uint8_t                 nports = 0;
 829         ibcm_hca_info_t         *hcap;
 830         ibt_hca_attr_t          hca_attrs;
 831 
 832         IBTF_DPRINTF_L3(cmlog, "ibcm_hca_attach: guid = 0x%llX", hcaguid);
 833 
 834         ASSERT(MUTEX_HELD(&ibcm_global_hca_lock));
 835 
 836         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*hcap))
 837 
 838         status = ibt_query_hca_byguid(hcaguid, &hca_attrs);
 839         if (status != IBT_SUCCESS) {
 840                 IBTF_DPRINTF_L2(cmlog, "ibcm_hca_attach: "
 841                     "ibt_query_hca_byguid failed = %d", status);
 842                 return;
 843         }
 844         nports = hca_attrs.hca_nports;
 845 
 846         IBTF_DPRINTF_L4(cmlog, "ibcm_hca_attach: num ports = %x", nports);
 847 
 848         if ((hcap = ibcm_add_hca_entry(hcaguid, nports)) == NULL)
 849                 return;
 850 
 851         hcap->hca_guid = hcaguid;    /* Set GUID */
 852         hcap->hca_num_ports = nports;        /* Set number of ports */
 853 
 854         if (ibcm_init_hca_ids(hcap) != IBCM_SUCCESS) {
 855                 ibcm_delete_hca_entry(hcap);
 856                 return;
 857         }


 886             sizeof (ibcm_state_data_t),
 887             offsetof(struct ibcm_state_data_s, avl_active_link));
 888 
 889         /* create the "passive" CM AVL tree */
 890         avl_create(&hcap->hca_passive_tree, ibcm_passive_node_compare,
 891             sizeof (ibcm_state_data_t),
 892             offsetof(struct ibcm_state_data_s, avl_passive_link));
 893 
 894         /* create the "passive comid" CM AVL tree */
 895         avl_create(&hcap->hca_passive_comid_tree,
 896             ibcm_passive_comid_node_compare,
 897             sizeof (ibcm_state_data_t),
 898             offsetof(struct ibcm_state_data_s, avl_passive_comid_link));
 899 
 900         /*
 901          * Mark the state of the HCA to "attach" only at the end
 902          * Now CM starts accepting incoming MADs and client API calls
 903          */
 904         hcap->hca_state = IBCM_HCA_ACTIVE;
 905 
 906         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*hcap))
 907 
 908         IBTF_DPRINTF_L3(cmlog, "ibcm_hca_attach: ATTACH Done");
 909 }
 910 
 911 /*
 912  * ibcm_hca_detach():
 913  *      Called as an asynchronous event to notify CM of a detach of HCA.
 914  *      Here ibcm_hca_info_t is freed up and all fields that
 915  *      were initialized earlier are cleaned up
 916  *
 917  * Arguments: (WILL CHANGE BASED ON ASYNC EVENT CODE)
 918  *      hca_guid    - HCA's guid
 919  *
 920  * Return values:
 921  *      IBCM_SUCCESS    - able to detach HCA
 922  *      IBCM_FAILURE    - failed to detach HCA
 923  */
 924 static ibcm_status_t
 925 ibcm_hca_detach(ibcm_hca_info_t *hcap)
 926 {
 927         int             port_index, i;


2015         ibt_status_t            ibt_status;
2016 
2017         if (port_index >= hcap->hca_num_ports)
2018                 return;
2019 
2020         mutex_enter(&ibcm_sa_open_lock);
2021         if (portp->port_saa_open_in_progress) {
2022                 mutex_exit(&ibcm_sa_open_lock);
2023                 return;
2024         }
2025 
2026         saa_handle = portp->port_ibmf_saa_hdl;
2027         if (saa_handle != NULL) {
2028                 mutex_exit(&ibcm_sa_open_lock);
2029                 return;
2030         }
2031 
2032         portp->port_saa_open_in_progress = 1;
2033         mutex_exit(&ibcm_sa_open_lock);
2034 
2035         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(portp->port_event_status))
2036 
2037         /* The assumption is that we're getting event notifications */
2038         portp->port_event_status = IBMF_SAA_EVENT_STATUS_MASK_PRODUCER_SM;
2039 
2040         _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(portp->port_event_status))
2041 
2042         ibt_status = ibt_get_port_state_byguid(portp->port_hcap->hca_guid,
2043             portp->port_num, &portp->port_sgid0, NULL);
2044         if (ibt_status != IBT_SUCCESS) {
2045                 IBTF_DPRINTF_L2(cmlog, "ibcm_init_saa_handle: "
2046                     "ibt_get_port_state_byguid failed for guid %llX "
2047                     "with status %d", portp->port_hcap->hca_guid, ibt_status);
2048                 mutex_enter(&ibcm_sa_open_lock);
2049                 portp->port_saa_open_in_progress = 0;
2050                 cv_broadcast(&ibcm_sa_open_cv);
2051                 mutex_exit(&ibcm_sa_open_lock);
2052                 return;
2053         }
2054         /* if the port is UP, try sa_session_open */
2055         (void) taskq_dispatch(ibcm_taskq, ibcm_init_saa, portp, TQ_SLEEP);
2056 }
2057 
2058 
2059 ibmf_saa_handle_t
2060 ibcm_get_saa_handle(ibcm_hca_info_t *hcap, uint8_t port)
2061 {


2111  *      - Register port with IBMA
2112  *
2113  * Arguments:
2114  *      hcap            - HCA's guid
2115  *      port_index      - port number minus 1
2116  *
2117  * Return values:
2118  *      IBCM_SUCCESS - success
2119  */
2120 ibt_status_t
2121 ibcm_hca_init_port(ibcm_hca_info_t *hcap, uint8_t port_index)
2122 {
2123         int                     status;
2124         ibmf_register_info_t    *ibmf_reg;
2125 
2126         IBTF_DPRINTF_L4(cmlog, "ibcm_hca_init_port: hcap = 0x%p port_num %d",
2127             hcap, port_index + 1);
2128 
2129         ASSERT(MUTEX_HELD(&ibcm_global_hca_lock));
2130 
2131         _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(hcap->hca_port_info))
2132 
2133         if (hcap->hca_port_info[port_index].port_ibmf_hdl == NULL) {
2134                 /* Register with IBMF */
2135                 ibmf_reg = &hcap->hca_port_info[port_index].port_ibmf_reg;
2136                 ibmf_reg->ir_ci_guid = hcap->hca_guid;
2137                 ibmf_reg->ir_port_num = port_index + 1;
2138                 ibmf_reg->ir_client_class = COMM_MGT_MANAGER_AGENT;
2139 
2140                 /*
2141                  * register with management framework
2142                  */
2143                 status = ibmf_register(ibmf_reg, IBMF_VERSION,
2144                     IBMF_REG_FLAG_NO_OFFLOAD, NULL, NULL,
2145                     &(hcap->hca_port_info[port_index].port_ibmf_hdl),
2146                     &(hcap->hca_port_info[port_index].port_ibmf_caps));
2147 
2148                 if (status != IBMF_SUCCESS) {
2149                         IBTF_DPRINTF_L2(cmlog, "ibcm_hca_init_port: "
2150                             "ibmf_register failed for port_num %x, "
2151                             "status = %x", port_index + 1, status);
2152                         return (ibcm_ibmf_analyze_error(status));


2399                  * Fini is about to return SUCCESS and release the global lock.
2400                  * In all these cases, it is safe to ignore the async.
2401                  */
2402 
2403                 IBTF_DPRINTF_L2(cmlog, "ibcm_async_handler: ignoring event %x, "
2404                     "as either init didn't complete or fini about to succeed",
2405                     code);
2406                 mutex_exit(&ibcm_global_hca_lock);
2407                 return;
2408         }
2409 
2410         switch (code) {
2411         case IBT_PORT_CHANGE_EVENT:
2412                 if ((eventp->ev_port_flags & IBT_PORT_CHANGE_SM_LID) == 0)
2413                         break;
2414         /* FALLTHROUGH */
2415         case IBT_CLNT_REREG_EVENT:
2416         case IBT_EVENT_PORT_UP:
2417                 mutex_exit(&ibcm_global_hca_lock);
2418                 pup = kmem_alloc(sizeof (ibcm_port_up_t), KM_SLEEP);
2419                 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*pup))
2420                 pup->pup_hca_guid = eventp->ev_hca_guid;
2421                 pup->pup_port = eventp->ev_port;
2422                 _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*pup))
2423                 (void) taskq_dispatch(ibcm_taskq,
2424                     ibcm_service_record_rewrite_task, pup, TQ_SLEEP);
2425                 ibcm_path_cache_purge();
2426                 return;
2427 
2428         case IBT_HCA_ATTACH_EVENT:
2429 
2430                 /* eventp->ev_hcaguid is the HCA GUID of interest */
2431                 ibcm_hca_attach(eventp->ev_hca_guid);
2432                 break;
2433 
2434         case IBT_HCA_DETACH_EVENT:
2435 
2436                 /* eventp->ev_hca_guid is the HCA GUID of interest */
2437                 if ((hcap = ibcm_find_hcap_entry(eventp->ev_hca_guid)) ==
2438                     NULL) {
2439                         IBTF_DPRINTF_L2(cmlog, "ibcm_async_handler:"
2440                             " hca %llX doesn't exist", eventp->ev_hca_guid);
2441                         break;
2442                 }


  79                             ibt_async_code_t, ibt_async_event_t *);
  80 
  81 /* Global variables */
  82 char                    cmlog[] = "ibcm";       /* for debug log messages */
  83 ibt_clnt_hdl_t          ibcm_ibt_handle;        /* IBT handle */
  84 kmutex_t                ibcm_svc_info_lock;     /* list lock */
  85 kcondvar_t              ibcm_svc_info_cv;       /* cv for deregister */
  86 kmutex_t                ibcm_recv_mutex;
  87 avl_tree_t              ibcm_svc_avl_tree;
  88 taskq_t                 *ibcm_taskq = NULL;
  89 int                     taskq_dispatch_fail_cnt;
  90 
  91 kmutex_t                ibcm_mcglist_lock;      /* MCG list lock */
  92 kmutex_t                ibcm_trace_mutex;       /* Trace mutex */
  93 kmutex_t                ibcm_trace_print_mutex; /* Trace print mutex */
  94 int                     ibcm_conn_max_trcnt = IBCM_MAX_CONN_TRCNT;
  95 
  96 int                     ibcm_enable_trace = 2;  /* Trace level 4 by default */
  97 int                     ibcm_dtrace = 0; /* conditionally enable more dtrace */
  98 













  99 /*
 100  * Initial state is INIT. All hca dr's return success immediately in this
 101  * state, without adding or deleting any hca's to CM.
 102  */
 103 ibcm_finit_state_t      ibcm_finit_state = IBCM_FINIT_INIT;
 104 
 105 /* mutex and cv to manage hca's reference and resource count(s) */
 106 kmutex_t                ibcm_global_hca_lock;
 107 kcondvar_t              ibcm_global_hca_cv;
 108 
 109 /* mutex and cv to sa session open */
 110 kmutex_t                ibcm_sa_open_lock;
 111 kcondvar_t              ibcm_sa_open_cv;
 112 int                     ibcm_sa_timeout_delay = 1;              /* in ticks */


 113 


 114 /* serialize sm notice callbacks */
 115 kmutex_t                ibcm_sm_notice_serialize_lock;
 116 















 117 /* mutex for CM's qp list management */
 118 kmutex_t                ibcm_qp_list_lock;
 119 




 120 kcondvar_t              ibcm_timeout_list_cv;
 121 kcondvar_t              ibcm_timeout_thread_done_cv;
 122 kt_did_t                ibcm_timeout_thread_did;
 123 ibcm_state_data_t       *ibcm_timeout_list_hdr, *ibcm_timeout_list_tail;
 124 ibcm_ud_state_data_t    *ibcm_ud_timeout_list_hdr, *ibcm_ud_timeout_list_tail;
 125 kmutex_t                ibcm_timeout_list_lock;
 126 uint8_t                 ibcm_timeout_list_flags = 0;
 127 pri_t                   ibcm_timeout_thread_pri = MINCLSYSPRI;
 128 






 129 /*
 130  * Flow control logic for open_rc_channel uses the following.
 131  */
 132 
 133 struct ibcm_open_s {
 134         kmutex_t                mutex;
 135         kcondvar_t              cv;
 136         uint8_t                 task_running;
 137         uint_t                  queued;
 138         uint_t                  exit_deferred;
 139         uint_t                  in_progress;
 140         uint_t                  in_progress_max;
 141         uint_t                  sends;
 142         uint_t                  sends_max;
 143         uint_t                  sends_lowat;
 144         uint_t                  sends_hiwat;
 145         ibcm_state_data_t       *tail;
 146         ibcm_state_data_t       head;
 147 } ibcm_open;
 148 


 298         "INIT_RTR_FAIL              ",
 299         "RTR_RTS                    ",
 300         "RTR_RTS_FAIL               ",
 301         "RTS_RTS                    ",
 302         "RTS_RTS_FAIL               ",
 303         "TO_ERROR                   ",
 304         "ERROR_FAIL                 ",
 305         "SET_ALT                    ",
 306         "SET_ALT_FAIL               ",
 307         "STALE_DETECT               ",
 308         "OUTGOING_REQ_RETRY         ",
 309         "OUTGOING_REP_RETRY         ",
 310         "OUTGOING_LAP_RETRY         ",
 311         "OUTGOING_MRA_RETRY         ",
 312         "OUTGOING_DREQ_RETRY        ",
 313         "NEVER SEE THIS             "
 314 };
 315 
 316 char    ibcm_debug_buf[IBCM_DEBUG_BUF_SIZE];
 317 








 318 #ifdef DEBUG
 319 int             ibcm_test_mode = 0;     /* set to 1, if running tests */
 320 #endif
 321 
 322 
 323 /* Module Driver Info */
 324 static struct modlmisc ibcm_modlmisc = {
 325         &mod_miscops,
 326         "IB Communication Manager"
 327 };
 328 
 329 /* Module Linkage */
 330 static struct modlinkage ibcm_modlinkage = {
 331         MODREV_1,
 332         &ibcm_modlmisc,
 333         NULL
 334 };
 335 
 336 
 337 int


 457         mutex_destroy(&ibcm_recv_mutex);
 458         mutex_destroy(&ibcm_sm_notice_serialize_lock);
 459         mutex_destroy(&ibcm_qp_list_lock);
 460         mutex_destroy(&ibcm_trace_mutex);
 461         mutex_destroy(&ibcm_trace_print_mutex);
 462         cv_destroy(&ibcm_svc_info_cv);
 463         cv_destroy(&ibcm_timeout_list_cv);
 464         cv_destroy(&ibcm_timeout_thread_done_cv);
 465         cv_destroy(&ibcm_global_hca_cv);
 466         cv_destroy(&ibcm_sa_open_cv);
 467         avl_destroy(&ibcm_svc_avl_tree);
 468 
 469         IBTF_DPRINTF_L5(cmlog, "ibcm_fini_locks: done");
 470 }
 471 
 472 
 473 /* Initialize CM's classport info */
 474 static void
 475 ibcm_init_classportinfo()
 476 {


 477         ibcm_clpinfo.BaseVersion = IBCM_MAD_BASE_VERSION;
 478         ibcm_clpinfo.ClassVersion = IBCM_MAD_CLASS_VERSION;
 479 
 480         /* For now, CM supports same capabilities at all ports */
 481         ibcm_clpinfo.CapabilityMask =
 482             h2b16(IBCM_CPINFO_CAP_RC | IBCM_CPINFO_CAP_SIDR);
 483 
 484         /* Bits 0-7 are all 0 for Communication Mgmt Class */
 485 
 486         /* For now, CM has the same respvalue at all ports */
 487         ibcm_clpinfo.RespTimeValue_plus =
 488             h2b32(ibt_usec2ib(ibcm_local_processing_time) & 0x1f);
 489 
 490         /* For now, redirect fields are set to 0 */
 491         /* Trap fields are not applicable to CM, hence set to 0 */
 492 

 493         IBTF_DPRINTF_L5(cmlog, "ibcm_init_classportinfo: done");
 494 }
 495 
 496 /*
 497  * ibcm_init():
 498  *      - call ibt_attach()
 499  *      - create AVL trees
 500  *      - Attach HCA handlers that are already present before
 501  *      CM got loaded.
 502  *
 503  * Arguments:   NONE
 504  *
 505  * Return values:
 506  *      IBCM_SUCCESS - success
 507  */
 508 static ibcm_status_t
 509 ibcm_init(void)
 510 {
 511         ibt_status_t    status;
 512         kthread_t       *t;


 514         IBTF_DPRINTF_L3(cmlog, "ibcm_init:");
 515 
 516         ibcm_init_classportinfo();
 517 
 518         if (ibcm_init_ids() != IBCM_SUCCESS) {
 519                 IBTF_DPRINTF_L1(cmlog, "ibcm_init: "
 520                     "fatal error: vmem_create() failed");
 521                 return (IBCM_FAILURE);
 522         }
 523         ibcm_init_locks();
 524 
 525         if (ibcm_ar_init() != IBCM_SUCCESS) {
 526                 IBTF_DPRINTF_L1(cmlog, "ibcm_init: "
 527                     "fatal error: ibcm_ar_init() failed");
 528                 ibcm_fini_ids();
 529                 ibcm_fini_locks();
 530                 return (IBCM_FAILURE);
 531         }
 532         ibcm_rc_flow_control_init();
 533 

 534         ibcm_taskq = system_taskq;

 535 



 536         /* Start the timeout list processing thread */
 537         ibcm_timeout_list_flags = 0;
 538         t = thread_create(NULL, 0, ibcm_process_tlist, 0, 0, &p0, TS_RUN,
 539             ibcm_timeout_thread_pri);
 540         ibcm_timeout_thread_did = t->t_did;
 541 



 542         /*
 543          * NOTE : if ibt_attach is done after ibcm_init_hcas, then some
 544          * HCA DR events may be lost. CM could call re-init hca list
 545          * again, but it is more complicated. Some HCA's DR's lost may
 546          * be HCA detach, which makes hca list re-syncing and locking more
 547          * complex
 548          */
 549         status = ibt_attach(&ibcm_ibt_modinfo, NULL, NULL, &ibcm_ibt_handle);
 550         if (status != IBT_SUCCESS) {
 551                 IBTF_DPRINTF_L2(cmlog, "ibcm_init(): ibt_attach failed %d",
 552                     status);
 553                 (void) ibcm_ar_fini();
 554                 ibcm_stop_timeout_thread();
 555                 ibcm_fini_ids();
 556                 ibcm_fini_locks();
 557                 ibcm_rc_flow_control_fini();
 558                 return (IBCM_FAILURE);
 559         }
 560 
 561         /* Block all HCA attach/detach asyncs */


 647         /* disables any new hca attach/detaches */
 648         mutex_enter(&ibcm_global_hca_lock);
 649 
 650         ibcm_finit_state = IBCM_FINIT_BUSY;
 651 
 652         if (ibcm_fini_hcas() != IBCM_SUCCESS) {
 653                 IBTF_DPRINTF_L2(cmlog, "ibcm_fini: "
 654                     "some hca's still have client resources");
 655 
 656                 /* First, re-initialize the hcas */
 657                 ibcm_init_hcas();
 658                 /* and then enable the HCA asyncs */
 659                 ibcm_finit_state = IBCM_FINIT_IDLE;
 660                 mutex_exit(&ibcm_global_hca_lock);
 661                 if (ibcm_ar_init() != IBCM_SUCCESS) {
 662                         IBTF_DPRINTF_L1(cmlog, "ibcm_fini:ibcm_ar_init failed");
 663                 }
 664                 return (IBCM_FAILURE);
 665         }
 666 



 667         ASSERT(ibcm_timeout_list_hdr == NULL);
 668         ASSERT(ibcm_ud_timeout_list_hdr == NULL);
 669 



 670         /* Release any pending asyncs on ibcm_global_hca_lock */
 671         ibcm_finit_state = IBCM_FINIT_SUCCESS;
 672         mutex_exit(&ibcm_global_hca_lock);
 673 
 674         ibcm_stop_timeout_thread();
 675 
 676         ibtl_cm_set_node_info_cb(NULL);
 677         /*
 678          * Detach from IBTL. Waits until all pending asyncs are complete.
 679          * Above cv_broadcast wakes up any waiting hca attach/detach asyncs
 680          */
 681         status = ibt_detach(ibcm_ibt_handle);
 682 
 683         /* if detach fails, CM didn't free up some resources, so assert */
 684         if (status != IBT_SUCCESS)
 685                 IBTF_DPRINTF_L1(cmlog, "ibcm_fini: ibt_detach failed %d",
 686                     status);
 687 
 688         ibcm_rc_flow_control_fini();
 689 


 749  *      hca's
 750  *
 751  * Arguments: (WILL CHANGE BASED ON ASYNC EVENT CODE)
 752  *      hca_guid        - HCA's guid
 753  *
 754  * Return values: NONE
 755  */
 756 static void
 757 ibcm_hca_attach(ib_guid_t hcaguid)
 758 {
 759         int                     i;
 760         ibt_status_t            status;
 761         uint8_t                 nports = 0;
 762         ibcm_hca_info_t         *hcap;
 763         ibt_hca_attr_t          hca_attrs;
 764 
 765         IBTF_DPRINTF_L3(cmlog, "ibcm_hca_attach: guid = 0x%llX", hcaguid);
 766 
 767         ASSERT(MUTEX_HELD(&ibcm_global_hca_lock));
 768 


 769         status = ibt_query_hca_byguid(hcaguid, &hca_attrs);
 770         if (status != IBT_SUCCESS) {
 771                 IBTF_DPRINTF_L2(cmlog, "ibcm_hca_attach: "
 772                     "ibt_query_hca_byguid failed = %d", status);
 773                 return;
 774         }
 775         nports = hca_attrs.hca_nports;
 776 
 777         IBTF_DPRINTF_L4(cmlog, "ibcm_hca_attach: num ports = %x", nports);
 778 
 779         if ((hcap = ibcm_add_hca_entry(hcaguid, nports)) == NULL)
 780                 return;
 781 
 782         hcap->hca_guid = hcaguid;    /* Set GUID */
 783         hcap->hca_num_ports = nports;        /* Set number of ports */
 784 
 785         if (ibcm_init_hca_ids(hcap) != IBCM_SUCCESS) {
 786                 ibcm_delete_hca_entry(hcap);
 787                 return;
 788         }


 817             sizeof (ibcm_state_data_t),
 818             offsetof(struct ibcm_state_data_s, avl_active_link));
 819 
 820         /* create the "passive" CM AVL tree */
 821         avl_create(&hcap->hca_passive_tree, ibcm_passive_node_compare,
 822             sizeof (ibcm_state_data_t),
 823             offsetof(struct ibcm_state_data_s, avl_passive_link));
 824 
 825         /* create the "passive comid" CM AVL tree */
 826         avl_create(&hcap->hca_passive_comid_tree,
 827             ibcm_passive_comid_node_compare,
 828             sizeof (ibcm_state_data_t),
 829             offsetof(struct ibcm_state_data_s, avl_passive_comid_link));
 830 
 831         /*
 832          * Mark the state of the HCA to "attach" only at the end
 833          * Now CM starts accepting incoming MADs and client API calls
 834          */
 835         hcap->hca_state = IBCM_HCA_ACTIVE;
 836 


 837         IBTF_DPRINTF_L3(cmlog, "ibcm_hca_attach: ATTACH Done");
 838 }
 839 
 840 /*
 841  * ibcm_hca_detach():
 842  *      Called as an asynchronous event to notify CM of a detach of HCA.
 843  *      Here ibcm_hca_info_t is freed up and all fields that
 844  *      were initialized earlier are cleaned up
 845  *
 846  * Arguments: (WILL CHANGE BASED ON ASYNC EVENT CODE)
 847  *      hca_guid    - HCA's guid
 848  *
 849  * Return values:
 850  *      IBCM_SUCCESS    - able to detach HCA
 851  *      IBCM_FAILURE    - failed to detach HCA
 852  */
 853 static ibcm_status_t
 854 ibcm_hca_detach(ibcm_hca_info_t *hcap)
 855 {
 856         int             port_index, i;


1944         ibt_status_t            ibt_status;
1945 
1946         if (port_index >= hcap->hca_num_ports)
1947                 return;
1948 
1949         mutex_enter(&ibcm_sa_open_lock);
1950         if (portp->port_saa_open_in_progress) {
1951                 mutex_exit(&ibcm_sa_open_lock);
1952                 return;
1953         }
1954 
1955         saa_handle = portp->port_ibmf_saa_hdl;
1956         if (saa_handle != NULL) {
1957                 mutex_exit(&ibcm_sa_open_lock);
1958                 return;
1959         }
1960 
1961         portp->port_saa_open_in_progress = 1;
1962         mutex_exit(&ibcm_sa_open_lock);
1963 


1964         /* The assumption is that we're getting event notifications */
1965         portp->port_event_status = IBMF_SAA_EVENT_STATUS_MASK_PRODUCER_SM;
1966 


1967         ibt_status = ibt_get_port_state_byguid(portp->port_hcap->hca_guid,
1968             portp->port_num, &portp->port_sgid0, NULL);
1969         if (ibt_status != IBT_SUCCESS) {
1970                 IBTF_DPRINTF_L2(cmlog, "ibcm_init_saa_handle: "
1971                     "ibt_get_port_state_byguid failed for guid %llX "
1972                     "with status %d", portp->port_hcap->hca_guid, ibt_status);
1973                 mutex_enter(&ibcm_sa_open_lock);
1974                 portp->port_saa_open_in_progress = 0;
1975                 cv_broadcast(&ibcm_sa_open_cv);
1976                 mutex_exit(&ibcm_sa_open_lock);
1977                 return;
1978         }
1979         /* if the port is UP, try sa_session_open */
1980         (void) taskq_dispatch(ibcm_taskq, ibcm_init_saa, portp, TQ_SLEEP);
1981 }
1982 
1983 
1984 ibmf_saa_handle_t
1985 ibcm_get_saa_handle(ibcm_hca_info_t *hcap, uint8_t port)
1986 {


2036  *      - Register port with IBMA
2037  *
2038  * Arguments:
2039  *      hcap            - HCA's guid
2040  *      port_index      - port number minus 1
2041  *
2042  * Return values:
2043  *      IBCM_SUCCESS - success
2044  */
2045 ibt_status_t
2046 ibcm_hca_init_port(ibcm_hca_info_t *hcap, uint8_t port_index)
2047 {
2048         int                     status;
2049         ibmf_register_info_t    *ibmf_reg;
2050 
2051         IBTF_DPRINTF_L4(cmlog, "ibcm_hca_init_port: hcap = 0x%p port_num %d",
2052             hcap, port_index + 1);
2053 
2054         ASSERT(MUTEX_HELD(&ibcm_global_hca_lock));
2055 


2056         if (hcap->hca_port_info[port_index].port_ibmf_hdl == NULL) {
2057                 /* Register with IBMF */
2058                 ibmf_reg = &hcap->hca_port_info[port_index].port_ibmf_reg;
2059                 ibmf_reg->ir_ci_guid = hcap->hca_guid;
2060                 ibmf_reg->ir_port_num = port_index + 1;
2061                 ibmf_reg->ir_client_class = COMM_MGT_MANAGER_AGENT;
2062 
2063                 /*
2064                  * register with management framework
2065                  */
2066                 status = ibmf_register(ibmf_reg, IBMF_VERSION,
2067                     IBMF_REG_FLAG_NO_OFFLOAD, NULL, NULL,
2068                     &(hcap->hca_port_info[port_index].port_ibmf_hdl),
2069                     &(hcap->hca_port_info[port_index].port_ibmf_caps));
2070 
2071                 if (status != IBMF_SUCCESS) {
2072                         IBTF_DPRINTF_L2(cmlog, "ibcm_hca_init_port: "
2073                             "ibmf_register failed for port_num %x, "
2074                             "status = %x", port_index + 1, status);
2075                         return (ibcm_ibmf_analyze_error(status));


2322                  * Fini is about to return SUCCESS and release the global lock.
2323                  * In all these cases, it is safe to ignore the async.
2324                  */
2325 
2326                 IBTF_DPRINTF_L2(cmlog, "ibcm_async_handler: ignoring event %x, "
2327                     "as either init didn't complete or fini about to succeed",
2328                     code);
2329                 mutex_exit(&ibcm_global_hca_lock);
2330                 return;
2331         }
2332 
2333         switch (code) {
2334         case IBT_PORT_CHANGE_EVENT:
2335                 if ((eventp->ev_port_flags & IBT_PORT_CHANGE_SM_LID) == 0)
2336                         break;
2337         /* FALLTHROUGH */
2338         case IBT_CLNT_REREG_EVENT:
2339         case IBT_EVENT_PORT_UP:
2340                 mutex_exit(&ibcm_global_hca_lock);
2341                 pup = kmem_alloc(sizeof (ibcm_port_up_t), KM_SLEEP);

2342                 pup->pup_hca_guid = eventp->ev_hca_guid;
2343                 pup->pup_port = eventp->ev_port;

2344                 (void) taskq_dispatch(ibcm_taskq,
2345                     ibcm_service_record_rewrite_task, pup, TQ_SLEEP);
2346                 ibcm_path_cache_purge();
2347                 return;
2348 
2349         case IBT_HCA_ATTACH_EVENT:
2350 
2351                 /* eventp->ev_hcaguid is the HCA GUID of interest */
2352                 ibcm_hca_attach(eventp->ev_hca_guid);
2353                 break;
2354 
2355         case IBT_HCA_DETACH_EVENT:
2356 
2357                 /* eventp->ev_hca_guid is the HCA GUID of interest */
2358                 if ((hcap = ibcm_find_hcap_entry(eventp->ev_hca_guid)) ==
2359                     NULL) {
2360                         IBTF_DPRINTF_L2(cmlog, "ibcm_async_handler:"
2361                             " hca %llX doesn't exist", eventp->ev_hca_guid);
2362                         break;
2363                 }