📄 iiblnd.c
字号:
if (kibnal_data.kib_tx_descs == NULL) return; for (i = 0; i < IBNAL_TX_MSGS(); i++) { kib_tx_t *tx = &kibnal_data.kib_tx_descs[i];#if IBNAL_USE_FMR 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 + IBNAL_MAX_RDMA_FRAGS) * sizeof(*tx->tx_wrq)); if (tx->tx_gl != NULL) LIBCFS_FREE(tx->tx_gl, (1 + IBNAL_MAX_RDMA_FRAGS) * sizeof(*tx->tx_gl)); if (tx->tx_rd != NULL) LIBCFS_FREE(tx->tx_rd, offsetof(kib_rdma_desc_t, rd_frags[IBNAL_MAX_RDMA_FRAGS]));#endif } LIBCFS_FREE(kibnal_data.kib_tx_descs, IBNAL_TX_MSGS() * sizeof(kib_tx_t));}intkibnal_setup_tx_descs (void){ int ipage = 0; int page_offset = 0; struct page *page; kib_tx_t *tx; int i; int rc; /* pre-mapped messages are not bigger than 1 page */ CLASSERT (IBNAL_MSG_SIZE <= PAGE_SIZE); /* No fancy arithmetic when we do the buffer calculations */ CLASSERT (PAGE_SIZE % IBNAL_MSG_SIZE == 0); rc = kibnal_alloc_pages(&kibnal_data.kib_tx_pages, IBNAL_TX_MSG_PAGES()); if (rc != 0) return (rc); for (i = 0; i < IBNAL_TX_MSGS(); i++) { page = kibnal_data.kib_tx_pages->ibp_pages[ipage]; tx = &kibnal_data.kib_tx_descs[i];#if IBNAL_USE_FMR /* Allocate an FMR for this TX so it can map src/sink buffers * for large transfers */#endif tx->tx_msg = (kib_msg_t *)(((char *)page_address(page)) + page_offset); tx->tx_hca_msg = kibnal_data.kib_whole_mem.md_addr + lnet_page2phys(page) + page_offset; CDEBUG(D_NET, "Tx[%d] %p->%p - "LPX64"\n", i, tx, tx->tx_msg, tx->tx_hca_msg); list_add (&tx->tx_list, &kibnal_data.kib_idle_txs); page_offset += IBNAL_MSG_SIZE; LASSERT (page_offset <= PAGE_SIZE); if (page_offset == PAGE_SIZE) { page_offset = 0; ipage++; LASSERT (ipage <= IBNAL_TX_MSG_PAGES()); } } return (0);}intkibnal_register_all_memory(void){ /* CAVEAT EMPTOR: this assumes all physical memory is in 1 contiguous * chunk starting at 0 */ struct sysinfo si; __u64 total; __u64 total2; __u64 roundup = (128<<20); /* round up in big chunks */ IB_MR_PHYS_BUFFER phys; IB_ACCESS_CONTROL access; FSTATUS frc; memset(&access, 0, sizeof(access)); access.s.MWBindable = 1; access.s.LocalWrite = 1; access.s.RdmaRead = 1; access.s.RdmaWrite = 1; /* XXX we don't bother with first-gen cards */ if (kibnal_data.kib_hca_attrs.VendorId == 0xd0b7 && kibnal_data.kib_hca_attrs.DeviceId == 0x3101) { CERROR("Can't register all memory on first generation HCAs\n"); return -EINVAL; } si_meminfo(&si); CDEBUG(D_NET, "si_meminfo: %lu/%u, num_physpages %lu/%lu\n", si.totalram, si.mem_unit, num_physpages, PAGE_SIZE); total = ((__u64)si.totalram) * si.mem_unit; total2 = num_physpages * PAGE_SIZE; if (total < total2) total = total2; if (total == 0) { CERROR("Can't determine memory size\n"); return -ENOMEM; } roundup = (128<<20); total = (total + (roundup - 1)) & ~(roundup - 1); phys.PhysAddr = 0; phys.Length = total; frc = iba_register_contig_pmr(kibnal_data.kib_hca, 0, &phys, 1, 0, kibnal_data.kib_pd, access, &kibnal_data.kib_whole_mem.md_handle, &kibnal_data.kib_whole_mem.md_addr, &kibnal_data.kib_whole_mem.md_lkey, &kibnal_data.kib_whole_mem.md_rkey); if (frc != FSUCCESS) { CERROR("registering physical memory failed: %d\n", frc); return -EIO; } CDEBUG(D_WARNING, "registered phys mem from 0("LPX64") for "LPU64"("LPU64") -> "LPX64"\n", phys.PhysAddr, total, phys.Length, kibnal_data.kib_whole_mem.md_addr); return 0;}voidkibnal_shutdown (lnet_ni_t *ni){ int i; int rc; LASSERT (ni == kibnal_data.kib_ni); LASSERT (ni->ni_data == &kibnal_data); CDEBUG(D_MALLOC, "before NAL cleanup: kmem %d\n", atomic_read (&libcfs_kmemory)); switch (kibnal_data.kib_init) { default: CERROR ("Unexpected state %d\n", kibnal_data.kib_init); LBUG(); case IBNAL_INIT_ALL: /* stop accepting connections, prevent new peers and start to * tear down all existing ones... */ kibnal_stop_listener(1); /* Wait for all peer state to clean up */ i = 2; while (atomic_read (&kibnal_data.kib_npeers) != 0) { i++; CDEBUG(((i & (-i)) == i) ? D_WARNING : D_NET, /* power of 2? */ "waiting for %d peers to disconnect\n", atomic_read (&kibnal_data.kib_npeers)); set_current_state (TASK_UNINTERRUPTIBLE); schedule_timeout (HZ); } /* fall through */ case IBNAL_INIT_CQ: rc = iba_destroy_cq(kibnal_data.kib_cq); if (rc != 0) CERROR ("Destroy CQ error: %d\n", rc); /* fall through */ case IBNAL_INIT_TXD: kibnal_free_pages (kibnal_data.kib_tx_pages); /* fall through */ case IBNAL_INIT_MD: rc = iba_deregister_mr(kibnal_data.kib_whole_mem.md_handle); if (rc != FSUCCESS) CERROR ("Deregister memory: %d\n", rc); /* fall through */ case IBNAL_INIT_PD: rc = iba_free_pd(kibnal_data.kib_pd); if (rc != 0) CERROR ("Destroy PD error: %d\n", rc); /* fall through */ case IBNAL_INIT_SD: rc = iba_sd_deregister(kibnal_data.kib_sd); if (rc != 0) CERROR ("Deregister SD error: %d\n", rc); /* fall through */ case IBNAL_INIT_PORTATTRS: LIBCFS_FREE(kibnal_data.kib_hca_attrs.PortAttributesList, kibnal_data.kib_hca_attrs.PortAttributesListSize); /* fall through */ case IBNAL_INIT_HCA: rc = iba_close_ca(kibnal_data.kib_hca); if (rc != 0) CERROR ("Close HCA error: %d\n", rc); /* fall through */ case IBNAL_INIT_DATA: LASSERT (atomic_read (&kibnal_data.kib_npeers) == 0); LASSERT (kibnal_data.kib_peers != NULL); for (i = 0; i < kibnal_data.kib_peer_hash_size; i++) { LASSERT (list_empty (&kibnal_data.kib_peers[i])); } LASSERT (atomic_read (&kibnal_data.kib_nconns) == 0); LASSERT (list_empty (&kibnal_data.kib_connd_zombies)); LASSERT (list_empty (&kibnal_data.kib_connd_conns)); LASSERT (list_empty (&kibnal_data.kib_connd_peers)); /* flag threads to terminate; wake and wait for them to die */ kibnal_data.kib_shutdown = 1; wake_up_all (&kibnal_data.kib_sched_waitq); wake_up_all (&kibnal_data.kib_connd_waitq); i = 2; while (atomic_read (&kibnal_data.kib_nthreads) != 0) { i++; CDEBUG(((i & (-i)) == i) ? D_WARNING : D_NET, /* power of 2? */ "Waiting for %d threads to terminate\n", atomic_read (&kibnal_data.kib_nthreads)); set_current_state (TASK_INTERRUPTIBLE); schedule_timeout (HZ); } /* fall through */ case IBNAL_INIT_NOTHING: break; } kibnal_free_tx_descs(); if (kibnal_data.kib_peers != NULL) LIBCFS_FREE (kibnal_data.kib_peers, sizeof (struct list_head) * kibnal_data.kib_peer_hash_size); CDEBUG(D_MALLOC, "after NAL cleanup: kmem %d\n", atomic_read (&libcfs_kmemory)); kibnal_data.kib_init = IBNAL_INIT_NOTHING; PORTAL_MODULE_UNUSE;}int kibnal_get_ipif_name(char *ifname, int ifname_size, int idx){ char *basename = *kibnal_tunables.kib_ipif_basename; int n = strlen(basename); int baseidx; int m; if (n == 0) { /* empty string */ CERROR("Empty IP interface basename specified\n"); return -EINVAL; } for (m = n; m > 0; m--) /* find max numeric postfix */ if (sscanf(basename + m - 1, "%d", &baseidx) != 1) break; if (m == 0) /* just a number */ m = n; if (m == n) /* no postfix */ baseidx = 1; /* default to 1 */ if (m >= ifname_size) m = ifname_size - 1; memcpy(ifname, basename, m); /* copy prefix name */ snprintf(ifname + m, ifname_size - m, "%d", baseidx + idx); if (strlen(ifname) == ifname_size - 1) { CERROR("IP interface basename %s too long\n", basename); return -EINVAL; } return 0;}intkibnal_startup (lnet_ni_t *ni){ char ipif_name[32]; __u32 ip; __u32 netmask; int up; int nob; struct timeval tv; IB_PORT_ATTRIBUTES *pattr; FSTATUS frc; int rc; __u32 n; int i; LASSERT (ni->ni_lnd == &the_kiblnd); /* Only 1 instance supported */ if (kibnal_data.kib_init != IBNAL_INIT_NOTHING) { CERROR ("Only 1 instance supported\n"); return -EPERM; } if (*kibnal_tunables.kib_credits > *kibnal_tunables.kib_ntx) { CERROR ("Can't set credits(%d) > ntx(%d)\n", *kibnal_tunables.kib_credits, *kibnal_tunables.kib_ntx); return -EINVAL; } ni->ni_maxtxcredits = *kibnal_tunables.kib_credits; ni->ni_peertxcredits = *kibnal_tunables.kib_peercredits; CLASSERT (LNET_MAX_INTERFACES > 1); if (ni->ni_interfaces[0] == NULL) { kibnal_data.kib_hca_idx = 0; } else { /* Use the HCA specified in 'networks=' */ if (ni->ni_interfaces[1] != NULL) { CERROR("Multiple interfaces not supported\n"); return -EPERM; } /* Parse <number> into kib_hca_idx */ nob = strlen(ni->ni_interfaces[0]); if (sscanf(ni->ni_interfaces[0], "%d%n", &kibnal_data.kib_hca_idx, &nob) < 1 || nob != strlen(ni->ni_interfaces[0])) { CERROR("Can't parse interface '%s'\n", ni->ni_interfaces[0]); return -EINVAL; } } rc = kibnal_get_ipif_name(ipif_name, sizeof(ipif_name), kibnal_data.kib_hca_idx); if (rc != 0) return rc; rc = libcfs_ipif_query(ipif_name, &up, &ip, &netmask); if (rc != 0) { CERROR("Can't query IPoIB interface %s: %d\n", ipif_name, rc); return -ENETDOWN; } if (!up) { CERR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -