📄 o2iblnd.c
字号:
case IBLND_CONN_DISCONNECTED: /* connvars should have been freed already */ LASSERT (conn->ibc_connvars == NULL); break; case IBLND_CONN_INIT: break; } if (conn->ibc_cmid->qp != NULL) rdma_destroy_qp(conn->ibc_cmid); if (conn->ibc_cq != NULL) { rc = ib_destroy_cq(conn->ibc_cq); if (rc != 0) CWARN("Error destroying CQ: %d\n", rc); } if (conn->ibc_rx_pages != NULL) { LASSERT (conn->ibc_rxs != NULL); for (i = 0; i < IBLND_RX_MSGS; i++) { kib_rx_t *rx = &conn->ibc_rxs[i]; LASSERT (rx->rx_nob >= 0); /* not posted */ kiblnd_dma_unmap_single(conn->ibc_cmid->device, KIBLND_UNMAP_ADDR(rx, rx_msgunmap, rx->rx_msgaddr), IBLND_MSG_SIZE, DMA_FROM_DEVICE); } kiblnd_free_pages(conn->ibc_rx_pages); } if (conn->ibc_rxs != NULL) { LIBCFS_FREE(conn->ibc_rxs, IBLND_RX_MSGS * sizeof(kib_rx_t)); } if (conn->ibc_connvars != NULL) LIBCFS_FREE(conn->ibc_connvars, sizeof(*conn->ibc_connvars)); /* See CAVEAT EMPTOR above in kiblnd_create_conn */ if (conn->ibc_state != IBLND_CONN_INIT) { kib_net_t *net = peer->ibp_ni->ni_data; kiblnd_peer_decref(peer); rdma_destroy_id(cmid); atomic_dec(&net->ibn_nconns); } LIBCFS_FREE(conn, sizeof(*conn));}intkiblnd_close_peer_conns_locked (kib_peer_t *peer, int why){ kib_conn_t *conn; struct list_head *ctmp; struct list_head *cnxt; int count = 0; list_for_each_safe (ctmp, cnxt, &peer->ibp_conns) { conn = list_entry(ctmp, kib_conn_t, ibc_list); count++; kiblnd_close_conn_locked(conn, why); } return count;}intkiblnd_close_stale_conns_locked (kib_peer_t *peer, __u64 incarnation){ kib_conn_t *conn; struct list_head *ctmp; struct list_head *cnxt; int count = 0; list_for_each_safe (ctmp, cnxt, &peer->ibp_conns) { conn = list_entry(ctmp, kib_conn_t, ibc_list); if (conn->ibc_incarnation == incarnation) continue; CDEBUG(D_NET, "Closing stale conn -> %s incarnation:"LPX64"("LPX64")\n", libcfs_nid2str(peer->ibp_nid), conn->ibc_incarnation, incarnation); count++; kiblnd_close_conn_locked(conn, -ESTALE); } return count;}intkiblnd_close_matching_conns (lnet_ni_t *ni, lnet_nid_t nid){ kib_peer_t *peer; struct list_head *ptmp; struct list_head *pnxt; int lo; int hi; int i; unsigned long flags; int count = 0; write_lock_irqsave(&kiblnd_data.kib_global_lock, flags); if (nid != LNET_NID_ANY) lo = hi = kiblnd_nid2peerlist(nid) - kiblnd_data.kib_peers; else { lo = 0; hi = kiblnd_data.kib_peer_hash_size - 1; } for (i = lo; i <= hi; i++) { list_for_each_safe (ptmp, pnxt, &kiblnd_data.kib_peers[i]) { peer = list_entry(ptmp, kib_peer_t, ibp_list); LASSERT (peer->ibp_connecting > 0 || peer->ibp_accepting > 0 || !list_empty(&peer->ibp_conns)); if (peer->ibp_ni != ni) continue; if (!(nid == LNET_NID_ANY || nid == peer->ibp_nid)) continue; count += kiblnd_close_peer_conns_locked(peer, 0); } } write_unlock_irqrestore(&kiblnd_data.kib_global_lock, flags); /* wildcards always succeed */ if (nid == LNET_NID_ANY) return 0; return (count == 0) ? -ENOENT : 0;}intkiblnd_ctl(lnet_ni_t *ni, unsigned int cmd, void *arg){ struct libcfs_ioctl_data *data = arg; int rc = -EINVAL; switch(cmd) { case IOC_LIBCFS_GET_PEER: { lnet_nid_t nid = 0; int count = 0; rc = kiblnd_get_peer_info(ni, data->ioc_count, &nid, &count); data->ioc_nid = nid; data->ioc_count = count; break; } case IOC_LIBCFS_DEL_PEER: { rc = kiblnd_del_peer(ni, data->ioc_nid); break; } case IOC_LIBCFS_GET_CONN: { kib_conn_t *conn = kiblnd_get_conn_by_idx(ni, data->ioc_count); if (conn == NULL) { rc = -ENOENT; } else { // kiblnd_debug_conn(conn); rc = 0; data->ioc_nid = conn->ibc_peer->ibp_nid; kiblnd_conn_decref(conn); } break; } case IOC_LIBCFS_CLOSE_CONNECTION: { rc = kiblnd_close_matching_conns(ni, data->ioc_nid); break; } default: break; } return rc;}voidkiblnd_free_pages (kib_pages_t *p){ int npages = p->ibp_npages; int i; for (i = 0; i < npages; i++) if (p->ibp_pages[i] != NULL) __free_page(p->ibp_pages[i]); LIBCFS_FREE (p, offsetof(kib_pages_t, ibp_pages[npages]));}intkiblnd_alloc_pages (kib_pages_t **pp, int npages){ kib_pages_t *p; int i; LIBCFS_ALLOC(p, offsetof(kib_pages_t, ibp_pages[npages])); if (p == NULL) { CERROR("Can't allocate descriptor for %d pages\n", npages); return -ENOMEM; } memset(p, 0, offsetof(kib_pages_t, ibp_pages[npages])); p->ibp_npages = npages; for (i = 0; i < npages; i++) { p->ibp_pages[i] = alloc_page(GFP_KERNEL); if (p->ibp_pages[i] == NULL) { CERROR("Can't allocate page %d of %d\n", i, npages); kiblnd_free_pages(p); return -ENOMEM; } } *pp = p; return 0;}voidkiblnd_free_tx_descs (lnet_ni_t *ni){ int i; kib_net_t *net = ni->ni_data; LASSERT (net != NULL); if (net->ibn_tx_descs != NULL) { for (i = 0; i < IBLND_TX_MSGS(); i++) { kib_tx_t *tx = &net->ibn_tx_descs[i];#if IBLND_MAP_ON_DEMAND if (tx->tx_pages != NULL) LIBCFS_FREE(tx->tx_pages, LNET_MAX_IOV * sizeof(*tx->tx_pages));#else if (tx->tx_wrq != NULL) LIBCFS_FREE(tx->tx_wrq, (1 + IBLND_MAX_RDMA_FRAGS) * sizeof(*tx->tx_wrq)); if (tx->tx_sge != NULL) LIBCFS_FREE(tx->tx_sge, (1 + IBLND_MAX_RDMA_FRAGS) * sizeof(*tx->tx_sge)); if (tx->tx_rd != NULL) LIBCFS_FREE(tx->tx_rd, offsetof(kib_rdma_desc_t, rd_frags[IBLND_MAX_RDMA_FRAGS])); if (tx->tx_frags != NULL) LIBCFS_FREE(tx->tx_frags, IBLND_MAX_RDMA_FRAGS * sizeof(*tx->tx_frags));#endif } LIBCFS_FREE(net->ibn_tx_descs, IBLND_TX_MSGS() * sizeof(kib_tx_t)); } if (net->ibn_tx_pages != NULL) kiblnd_free_pages(net->ibn_tx_pages);}intkiblnd_alloc_tx_descs (lnet_ni_t *ni){ int i; int rc; kib_net_t *net = ni->ni_data; LASSERT (net != NULL); rc = kiblnd_alloc_pages(&net->ibn_tx_pages, IBLND_TX_MSG_PAGES()); if (rc != 0) { CERROR("Can't allocate tx pages\n"); return rc; } LIBCFS_ALLOC (net->ibn_tx_descs, IBLND_TX_MSGS() * sizeof(kib_tx_t)); if (net->ibn_tx_descs == NULL) { CERROR("Can't allocate %d tx descriptors\n", IBLND_TX_MSGS()); return -ENOMEM; } memset(net->ibn_tx_descs, 0, IBLND_TX_MSGS() * sizeof(kib_tx_t)); for (i = 0; i < IBLND_TX_MSGS(); i++) { kib_tx_t *tx = &net->ibn_tx_descs[i];#if IBLND_MAP_ON_DEMAND LIBCFS_ALLOC(tx->tx_pages, LNET_MAX_IOV * sizeof(*tx->tx_pages)); if (tx->tx_pages == NULL) { CERROR("Can't allocate phys page vector[%d]\n", LNET_MAX_IOV); return -ENOMEM; }#else LIBCFS_ALLOC(tx->tx_wrq, (1 + IBLND_MAX_RDMA_FRAGS) * sizeof(*tx->tx_wrq)); if (tx->tx_wrq == NULL) return -ENOMEM; LIBCFS_ALLOC(tx->tx_sge, (1 + IBLND_MAX_RDMA_FRAGS) * sizeof(*tx->tx_sge)); if (tx->tx_sge == NULL) return -ENOMEM; LIBCFS_ALLOC(tx->tx_rd, offsetof(kib_rdma_desc_t, rd_frags[IBLND_MAX_RDMA_FRAGS])); if (tx->tx_rd == NULL) return -ENOMEM; LIBCFS_ALLOC(tx->tx_frags, IBLND_MAX_RDMA_FRAGS * sizeof(*tx->tx_frags)); if (tx->tx_frags == NULL) return -ENOMEM;#endif } return 0;}voidkiblnd_unmap_tx_descs (lnet_ni_t *ni){ int i; kib_tx_t *tx; kib_net_t *net = ni->ni_data; LASSERT (net != NULL); for (i = 0; i < IBLND_TX_MSGS(); i++) { tx = &net->ibn_tx_descs[i]; kiblnd_dma_unmap_single(net->ibn_dev->ibd_cmid->device, KIBLND_UNMAP_ADDR(tx, tx_msgunmap, tx->tx_msgaddr), IBLND_MSG_SIZE, DMA_TO_DEVICE); }}voidkiblnd_map_tx_descs (lnet_ni_t *ni){ int ipage = 0; int page_offset = 0; int i; struct page *page; kib_tx_t *tx; kib_net_t *net = ni->ni_data; LASSERT (net != NULL); /* pre-mapped messages are not bigger than 1 page */ CLASSERT (IBLND_MSG_SIZE <= PAGE_SIZE); /* No fancy arithmetic when we do the buffer calculations */ CLASSERT (PAGE_SIZE % IBLND_MSG_SIZE == 0); for (i = 0; i < IBLND_TX_MSGS(); i++) { page = net->ibn_tx_pages->ibp_pages[ipage]; tx = &net->ibn_tx_descs[i]; tx->tx_msg = (kib_msg_t *)(((char *)page_address(page)) + page_offset); tx->tx_msgaddr = kiblnd_dma_map_single( net->ibn_dev->ibd_cmid->device, tx->tx_msg, IBLND_MSG_SIZE, DMA_TO_DEVICE); KIBLND_UNMAP_ADDR_SET(tx, tx_msgunmap, tx->tx_msgaddr); list_add(&tx->tx_list, &net->ibn_idle_txs); page_offset += IBLND_MSG_SIZE; LASSERT (page_offset <= PAGE_SIZE); if (page_offset == PAGE_SIZE) { page_offset = 0; ipage++; LASSERT (ipage <= IBLND_TX_MSG_PAGES()); } }}voidkiblnd_base_shutdown (void){ int i; LASSERT (list_empty(&kiblnd_data.kib_devs)); CDEBUG(D_MALLOC, "before LND base cleanup: kmem %d\n", atomic_read(&libcfs_kmemory)); switch (kiblnd_data.kib_init) { default: LBUG(); case IBLND_INIT_ALL: case IBLND_INIT_DATA: LASSERT (kiblnd_data.kib_peers != NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -