static void lnet_selftest_exit(void) { int i; switch (lst_init_step) { case LST_INIT_CONSOLE: lstcon_console_fini(); case LST_INIT_FW: sfw_shutdown(); case LST_INIT_RPC: srpc_shutdown(); case LST_INIT_WI_TEST: for (i = 0; i < cfs_cpt_number(lnet_cpt_table()); i++) { if (!lst_sched_test[i]) continue; cfs_wi_sched_destroy(lst_sched_test[i]); } LIBCFS_FREE(lst_sched_test, sizeof(lst_sched_test[0]) * cfs_cpt_number(lnet_cpt_table())); lst_sched_test = NULL; case LST_INIT_WI_SERIAL: cfs_wi_sched_destroy(lst_sched_serial); lst_sched_serial = NULL; case LST_INIT_NONE: break; default: LBUG(); } }
/** * lock a CPU partition * * \a index != CFS_PERCPT_LOCK_EX * hold private lock indexed by \a index * * \a index == CFS_PERCPT_LOCK_EX * exclusively lock @pcl and nobody can take private lock */ void cfs_percpt_lock(struct cfs_percpt_lock *pcl, int index) { int ncpt = cfs_cpt_number(pcl->pcl_cptab); int i; LASSERT(index >= CFS_PERCPT_LOCK_EX && index < ncpt); if (ncpt == 1) { index = 0; } else { /* serialize with exclusive lock */ while (pcl->pcl_locked) cpu_relax(); } if (likely(index != CFS_PERCPT_LOCK_EX)) { spin_lock(pcl->pcl_locks[index]); return; } /* exclusive lock request */ for (i = 0; i < ncpt; i++) { spin_lock(pcl->pcl_locks[i]); if (i == 0) { LASSERT(!pcl->pcl_locked); /* nobody should take private lock after this * so I wouldn't starve for too long time */ pcl->pcl_locked = 1; } } }
static int lnet_selftest_init(void) { int nscheds; int rc; int i; rc = cfs_wi_sched_create("lst_s", lnet_cpt_table(), CFS_CPT_ANY, 1, &lst_sched_serial); if (rc != 0) { CERROR("Failed to create serial WI scheduler for LST\n"); return rc; } lst_init_step = LST_INIT_WI_SERIAL; nscheds = cfs_cpt_number(lnet_cpt_table()); LIBCFS_ALLOC(lst_sched_test, sizeof(lst_sched_test[0]) * nscheds); if (lst_sched_test == NULL) goto error; lst_init_step = LST_INIT_WI_TEST; for (i = 0; i < nscheds; i++) { int nthrs = cfs_cpt_weight(lnet_cpt_table(), i); /* reserve at least one CPU for LND */ nthrs = max(nthrs - 1, 1); rc = cfs_wi_sched_create("lst_t", lnet_cpt_table(), i, nthrs, &lst_sched_test[i]); if (rc != 0) { CERROR("Failed to create CPT affinity WI scheduler %d for LST\n", i); goto error; } } rc = srpc_startup(); if (rc != 0) { CERROR("LST can't startup rpc\n"); goto error; } lst_init_step = LST_INIT_RPC; rc = sfw_startup(); if (rc != 0) { CERROR("LST can't startup framework\n"); goto error; } lst_init_step = LST_INIT_FW; rc = lstcon_console_init(); if (rc != 0) { CERROR("LST can't startup console\n"); goto error; } lst_init_step = LST_INIT_CONSOLE; return 0; error: lnet_selftest_fini(); return rc; }
/** unlock a CPU partition */ void cfs_percpt_unlock(struct cfs_percpt_lock *pcl, int index) { int ncpt = cfs_cpt_number(pcl->pcl_cptab); int i; index = ncpt == 1 ? 0 : index; if (likely(index != CFS_PERCPT_LOCK_EX)) { spin_unlock(pcl->pcl_locks[index]); return; } for (i = ncpt - 1; i >= 0; i--) { if (i == 0) { LASSERT(pcl->pcl_locked); pcl->pcl_locked = 0; } spin_unlock(pcl->pcl_locks[i]); } }