532 return (DDI_FAILURE); |
527 return (DDI_FAILURE); |
533 } |
528 } |
534 |
529 |
535 mutex_enter(&rib_stat->open_hca_lock); |
530 mutex_enter(&rib_stat->open_hca_lock); |
536 if (open_hcas(rib_stat) != RDMA_SUCCESS) { |
531 if (open_hcas(rib_stat) != RDMA_SUCCESS) { |
537 ibt_free_hca_list(rib_stat->hca_guids, rib_stat->hca_count); |
|
538 (void) ibt_detach(rib_stat->ibt_clnt_hdl); |
|
539 mutex_exit(&rib_stat->open_hca_lock); |
532 mutex_exit(&rib_stat->open_hca_lock); |
540 mutex_destroy(&rib_stat->open_hca_lock); |
533 goto open_fail; |
541 kmem_free(rib_stat, sizeof (*rib_stat)); |
|
542 rib_stat = NULL; |
|
543 return (DDI_FAILURE); |
|
544 } |
534 } |
545 mutex_exit(&rib_stat->open_hca_lock); |
535 mutex_exit(&rib_stat->open_hca_lock); |
546 |
536 |
|
537 if (ddi_prop_update_int(DDI_DEV_T_NONE, dip, DDI_NO_AUTODETACH, 1) != |
|
538 DDI_PROP_SUCCESS) { |
|
539 cmn_err(CE_WARN, "rpcib_attach: ddi-no-autodetach prop update " |
|
540 "failed."); |
|
541 goto register_fail; |
|
542 } |
|
543 |
547 /* |
544 /* |
548 * Register with rdmatf |
545 * Register with rdmatf |
549 */ |
546 */ |
550 rib_mod.rdma_count = rib_stat->hca_count; |
547 rib_mod.rdma_count = rib_stat->nhca_inited; |
551 r_status = rdma_register_mod(&rib_mod); |
548 r_status = rdma_register_mod(&rib_mod); |
552 if (r_status != RDMA_SUCCESS && r_status != RDMA_REG_EXIST) { |
549 if (r_status != RDMA_SUCCESS && r_status != RDMA_REG_EXIST) { |
553 rib_detach_hca(rib_stat->hca); |
550 cmn_err(CE_WARN, "rpcib_attach:rdma_register_mod failed, " |
554 ibt_free_hca_list(rib_stat->hca_guids, rib_stat->hca_count); |
551 "status = %d", r_status); |
555 (void) ibt_detach(rib_stat->ibt_clnt_hdl); |
552 goto register_fail; |
556 mutex_destroy(&rib_stat->open_hca_lock); |
553 } |
557 kmem_free(rib_stat, sizeof (*rib_stat)); |
|
558 rib_stat = NULL; |
|
559 return (DDI_FAILURE); |
|
560 } |
|
561 |
|
562 |
554 |
563 return (DDI_SUCCESS); |
555 return (DDI_SUCCESS); |
|
556 |
|
557 register_fail: |
|
558 rib_detach_hca(rib_stat->hca); |
|
559 open_fail: |
|
560 ibt_free_hca_list(rib_stat->hca_guids, rib_stat->hca_count); |
|
561 (void) ibt_detach(rib_stat->ibt_clnt_hdl); |
|
562 mutex_destroy(&rib_stat->open_hca_lock); |
|
563 kmem_free(rib_stat, sizeof (*rib_stat)); |
|
564 rib_stat = NULL; |
|
565 return (DDI_FAILURE); |
564 } |
566 } |
565 |
567 |
566 /*ARGSUSED*/ |
568 /*ARGSUSED*/ |
567 static int |
569 static int |
568 rpcib_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) |
570 rpcib_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) |
584 plugin_state = NO_ACCEPT; |
586 plugin_state = NO_ACCEPT; |
585 mutex_exit(&plugin_state_lock); |
587 mutex_exit(&plugin_state_lock); |
586 rib_detach_hca(rib_stat->hca); |
588 rib_detach_hca(rib_stat->hca); |
587 ibt_free_hca_list(rib_stat->hca_guids, rib_stat->hca_count); |
589 ibt_free_hca_list(rib_stat->hca_guids, rib_stat->hca_count); |
588 (void) ibt_detach(rib_stat->ibt_clnt_hdl); |
590 (void) ibt_detach(rib_stat->ibt_clnt_hdl); |
|
591 mutex_destroy(&rib_stat->open_hca_lock); |
|
592 if (rib_stat->hcas) { |
|
593 kmem_free(rib_stat->hcas, rib_stat->hca_count * |
|
594 sizeof (rib_hca_t)); |
|
595 rib_stat->hcas = NULL; |
|
596 } |
|
597 kmem_free(rib_stat, sizeof (*rib_stat)); |
|
598 rib_stat = NULL; |
589 |
599 |
590 mutex_enter(&rpcib.rpcib_mutex); |
600 mutex_enter(&rpcib.rpcib_mutex); |
591 rpcib.rpcib_dip = NULL; |
601 rpcib.rpcib_dip = NULL; |
592 mutex_exit(&rpcib.rpcib_mutex); |
602 mutex_exit(&rpcib.rpcib_mutex); |
593 |
|
594 mutex_destroy(&rpcib.rpcib_mutex); |
603 mutex_destroy(&rpcib.rpcib_mutex); |
595 return (DDI_SUCCESS); |
604 return (DDI_SUCCESS); |
596 } |
605 } |
597 |
606 |
598 |
607 |
3903 * C_DISCONN_PEND state: When a connection is in C_ERROR_CONN state and when |
3912 * C_DISCONN_PEND state: When a connection is in C_ERROR_CONN state and when |
3904 * c_ref drops to 0 (this indicates that RPC has no more references to this |
3913 * c_ref drops to 0 (this indicates that RPC has no more references to this |
3905 * connection), the connection should be destroyed. A connection transitions |
3914 * connection), the connection should be destroyed. A connection transitions |
3906 * into this state when it is being destroyed. |
3915 * into this state when it is being destroyed. |
3907 */ |
3916 */ |
|
3917 /* ARGSUSED */ |
3908 static rdma_stat |
3918 static rdma_stat |
3909 rib_conn_get(struct netbuf *svcaddr, int addr_type, void *handle, CONN **conn) |
3919 rib_conn_get(struct netbuf *svcaddr, int addr_type, void *handle, CONN **conn) |
3910 { |
3920 { |
3911 CONN *cn; |
3921 CONN *cn; |
3912 int status = RDMA_SUCCESS; |
3922 int status = RDMA_SUCCESS; |
3913 rib_hca_t *hca = (rib_hca_t *)handle; |
3923 rib_hca_t *hca = rib_stat->hca; |
3914 rib_qp_t *qp; |
3924 rib_qp_t *qp; |
3915 clock_t cv_stat, timout; |
3925 clock_t cv_stat, timout; |
3916 ibt_path_info_t path; |
3926 ibt_path_info_t path; |
3917 ibt_ip_addr_t s_ip, d_ip; |
3927 ibt_ip_addr_t s_ip, d_ip; |
|
3928 |
|
3929 if (hca == NULL) |
|
3930 return (RDMA_FAILED); |
|
3931 |
|
3932 rw_enter(&rib_stat->hca->state_lock, RW_READER); |
|
3933 if (hca->state == HCA_DETACHED) { |
|
3934 rw_exit(&rib_stat->hca->state_lock); |
|
3935 return (RDMA_FAILED); |
|
3936 } |
|
3937 rw_exit(&rib_stat->hca->state_lock); |
3918 |
3938 |
3919 again: |
3939 again: |
3920 rw_enter(&hca->cl_conn_list.conn_lock, RW_READER); |
3940 rw_enter(&hca->cl_conn_list.conn_lock, RW_READER); |
3921 cn = hca->cl_conn_list.conn_hd; |
3941 cn = hca->cl_conn_list.conn_hd; |
3922 while (cn != NULL) { |
3942 while (cn != NULL) { |
4267 rib_stat->nhca_inited--; |
4287 rib_stat->nhca_inited--; |
4268 |
4288 |
4269 rib_stop_services(hca); |
4289 rib_stop_services(hca); |
4270 rib_close_channels(&hca->cl_conn_list); |
4290 rib_close_channels(&hca->cl_conn_list); |
4271 rib_close_channels(&hca->srv_conn_list); |
4291 rib_close_channels(&hca->srv_conn_list); |
|
4292 |
|
4293 rib_mod.rdma_count--; |
|
4294 |
4272 rw_exit(&hca->state_lock); |
4295 rw_exit(&hca->state_lock); |
4273 |
4296 |
4274 rib_purge_connlist(&hca->cl_conn_list); |
4297 /* |
4275 rib_purge_connlist(&hca->srv_conn_list); |
4298 * purge will free all datastructures used by CQ handlers. We don't |
4276 |
4299 * want to receive completions after purge, so we'll free the CQs now. |
|
4300 */ |
4277 (void) ibt_free_cq(hca->clnt_rcq->rib_cq_hdl); |
4301 (void) ibt_free_cq(hca->clnt_rcq->rib_cq_hdl); |
4278 (void) ibt_free_cq(hca->clnt_scq->rib_cq_hdl); |
4302 (void) ibt_free_cq(hca->clnt_scq->rib_cq_hdl); |
4279 (void) ibt_free_cq(hca->svc_rcq->rib_cq_hdl); |
4303 (void) ibt_free_cq(hca->svc_rcq->rib_cq_hdl); |
4280 (void) ibt_free_cq(hca->svc_scq->rib_cq_hdl); |
4304 (void) ibt_free_cq(hca->svc_scq->rib_cq_hdl); |
|
4305 |
|
4306 rib_purge_connlist(&hca->cl_conn_list); |
|
4307 rib_purge_connlist(&hca->srv_conn_list); |
|
4308 |
4281 kmem_free(hca->clnt_rcq, sizeof (rib_cq_t)); |
4309 kmem_free(hca->clnt_rcq, sizeof (rib_cq_t)); |
4282 kmem_free(hca->clnt_scq, sizeof (rib_cq_t)); |
4310 kmem_free(hca->clnt_scq, sizeof (rib_cq_t)); |
4283 kmem_free(hca->svc_rcq, sizeof (rib_cq_t)); |
4311 kmem_free(hca->svc_rcq, sizeof (rib_cq_t)); |
4284 kmem_free(hca->svc_scq, sizeof (rib_cq_t)); |
4312 kmem_free(hca->svc_scq, sizeof (rib_cq_t)); |
|
4313 if (stats_enabled) { |
|
4314 kstat_delete_byname_zone("unix", 0, "rpcib_cache", |
|
4315 GLOBAL_ZONEID); |
|
4316 } |
4285 |
4317 |
4286 rw_enter(&hca->srv_conn_list.conn_lock, RW_READER); |
4318 rw_enter(&hca->srv_conn_list.conn_lock, RW_READER); |
4287 rw_enter(&hca->cl_conn_list.conn_lock, RW_READER); |
4319 rw_enter(&hca->cl_conn_list.conn_lock, RW_READER); |
4288 if (hca->srv_conn_list.conn_hd == NULL && |
4320 if (hca->srv_conn_list.conn_hd == NULL && |
4289 hca->cl_conn_list.conn_hd == NULL) { |
4321 hca->cl_conn_list.conn_hd == NULL) { |
4292 * buffers, close hca and be done. |
4324 * buffers, close hca and be done. |
4293 */ |
4325 */ |
4294 rib_rbufpool_destroy(hca, RECV_BUFFER); |
4326 rib_rbufpool_destroy(hca, RECV_BUFFER); |
4295 rib_rbufpool_destroy(hca, SEND_BUFFER); |
4327 rib_rbufpool_destroy(hca, SEND_BUFFER); |
4296 rib_destroy_cache(hca); |
4328 rib_destroy_cache(hca); |
|
4329 rdma_unregister_mod(&rib_mod); |
4297 (void) ibt_free_pd(hca->hca_hdl, hca->pd_hdl); |
4330 (void) ibt_free_pd(hca->hca_hdl, hca->pd_hdl); |
4298 (void) ibt_close_hca(hca->hca_hdl); |
4331 (void) ibt_close_hca(hca->hca_hdl); |
4299 hca->hca_hdl = NULL; |
4332 hca->hca_hdl = NULL; |
4300 } |
4333 } |
4301 rw_exit(&hca->cl_conn_list.conn_lock); |
4334 rw_exit(&hca->cl_conn_list.conn_lock); |
4304 if (hca->hca_hdl != NULL) { |
4337 if (hca->hca_hdl != NULL) { |
4305 mutex_enter(&hca->inuse_lock); |
4338 mutex_enter(&hca->inuse_lock); |
4306 while (hca->inuse) |
4339 while (hca->inuse) |
4307 cv_wait(&hca->cb_cv, &hca->inuse_lock); |
4340 cv_wait(&hca->cb_cv, &hca->inuse_lock); |
4308 mutex_exit(&hca->inuse_lock); |
4341 mutex_exit(&hca->inuse_lock); |
|
4342 |
|
4343 rdma_unregister_mod(&rib_mod); |
|
4344 |
4309 /* |
4345 /* |
4310 * conn_lists are now NULL, so destroy |
4346 * conn_lists are now NULL, so destroy |
4311 * buffers, close hca and be done. |
4347 * buffers, close hca and be done. |
4312 */ |
4348 */ |
4313 rib_rbufpool_destroy(hca, RECV_BUFFER); |
4349 rib_rbufpool_destroy(hca, RECV_BUFFER); |
4314 rib_rbufpool_destroy(hca, SEND_BUFFER); |
4350 rib_rbufpool_destroy(hca, SEND_BUFFER); |
|
4351 rib_destroy_cache(hca); |
4315 (void) ibt_free_pd(hca->hca_hdl, hca->pd_hdl); |
4352 (void) ibt_free_pd(hca->hca_hdl, hca->pd_hdl); |
4316 (void) ibt_close_hca(hca->hca_hdl); |
4353 (void) ibt_close_hca(hca->hca_hdl); |
4317 hca->hca_hdl = NULL; |
4354 hca->hca_hdl = NULL; |
4318 } |
4355 } |
4319 } |
4356 } |
4383 cache_allocation -= rb->lrc_len; |
4420 cache_allocation -= rb->lrc_len; |
4384 kmem_free(rb->lrc_buf, rb->lrc_len); |
4421 kmem_free(rb->lrc_buf, rb->lrc_len); |
4385 kmem_free(rb, sizeof (rib_lrc_entry_t)); |
4422 kmem_free(rb, sizeof (rib_lrc_entry_t)); |
4386 } |
4423 } |
4387 mutex_destroy(&rcas->node_lock); |
4424 mutex_destroy(&rcas->node_lock); |
4388 kmem_cache_free(hca->server_side_cache, rcas); |
4425 if (hca->server_side_cache) { |
|
4426 kmem_cache_free(hca->server_side_cache, rcas); |
|
4427 } |
4389 if ((cache_allocation) < cache_limit) { |
4428 if ((cache_allocation) < cache_limit) { |
4390 rw_exit(&hca->avl_rw_lock); |
4429 rw_exit(&hca->avl_rw_lock); |
4391 return; |
4430 return; |
4392 } |
4431 } |
4393 |
4432 |
4415 { |
4454 { |
4416 if (hca->reg_cache_clean_up != NULL) { |
4455 if (hca->reg_cache_clean_up != NULL) { |
4417 ddi_taskq_destroy(hca->reg_cache_clean_up); |
4456 ddi_taskq_destroy(hca->reg_cache_clean_up); |
4418 hca->reg_cache_clean_up = NULL; |
4457 hca->reg_cache_clean_up = NULL; |
4419 } |
4458 } |
4420 if (!hca->avl_init) { |
4459 if (hca->avl_init) { |
4421 kmem_cache_destroy(hca->server_side_cache); |
4460 rib_server_side_cache_reclaim((void *)hca); |
|
4461 if (hca->server_side_cache) { |
|
4462 kmem_cache_destroy(hca->server_side_cache); |
|
4463 hca->server_side_cache = NULL; |
|
4464 } |
4422 avl_destroy(&hca->avl_tree); |
4465 avl_destroy(&hca->avl_tree); |
4423 mutex_destroy(&hca->cache_allocation); |
4466 mutex_destroy(&hca->cache_allocation); |
4424 rw_destroy(&hca->avl_rw_lock); |
4467 rw_destroy(&hca->avl_rw_lock); |
4425 } |
4468 } |
4426 hca->avl_init = FALSE; |
4469 hca->avl_init = FALSE; |