-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * GPL HEADER END
- */
+// SPDX-License-Identifier: GPL-2.0
+
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
* Copyright (c) 2012, 2015, Intel Corporation.
*/
+
/*
* This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
*/
#define DEBUG_SUBSYSTEM S_LNET
static int lst_init_step = LST_INIT_NONE;
-struct cfs_wi_sched *lst_sched_serial;
-struct cfs_wi_sched **lst_sched_test;
+struct workqueue_struct *lst_serial_wq;
+struct workqueue_struct **lst_test_wq;
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] == NULL)
- 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();
- }
- return;
+ int i;
+
+ switch (lst_init_step) {
+ case LST_INIT_CONSOLE:
+ lstcon_console_fini();
+ fallthrough;
+ case LST_INIT_FW:
+ sfw_shutdown();
+ fallthrough;
+ case LST_INIT_RPC:
+ srpc_shutdown();
+ fallthrough;
+ case LST_INIT_WI_TEST:
+ for (i = 0;
+ i < cfs_cpt_number(lnet_cpt_table()); i++) {
+ if (!lst_test_wq[i])
+ continue;
+ destroy_workqueue(lst_test_wq[i]);
+ }
+ CFS_FREE_PTR_ARRAY(lst_test_wq,
+ cfs_cpt_number(lnet_cpt_table()));
+ lst_test_wq = NULL;
+ fallthrough;
+ case LST_INIT_WI_SERIAL:
+ destroy_workqueue(lst_serial_wq);
+ lst_serial_wq = NULL;
+ fallthrough;
+ case LST_INIT_NONE:
+ break;
+ default:
+ LBUG();
+ }
}
-void
+static void
lnet_selftest_structure_assertion(void)
{
- CLASSERT(sizeof(struct srpc_msg) == 160);
- CLASSERT(sizeof(struct srpc_test_reqst) == 70);
- CLASSERT(offsetof(struct srpc_msg, msg_body.tes_reqst.tsr_concur) == 72);
- CLASSERT(offsetof(struct srpc_msg, msg_body.tes_reqst.tsr_ndest) == 78);
- CLASSERT(sizeof(struct srpc_stat_reply) == 136);
- CLASSERT(sizeof(struct srpc_stat_reqst) == 28);
-
+ BUILD_BUG_ON(sizeof(struct srpc_msg) != 160);
+ BUILD_BUG_ON(sizeof(struct srpc_test_reqst) != 70);
+ BUILD_BUG_ON(offsetof(struct srpc_msg, msg_body.tes_reqst.tsr_concur) !=
+ 72);
+ BUILD_BUG_ON(offsetof(struct srpc_msg, msg_body.tes_reqst.tsr_ndest) !=
+ 78);
+ BUILD_BUG_ON(sizeof(struct srpc_stat_reply) != 136);
+ BUILD_BUG_ON(sizeof(struct srpc_stat_reqst) != 28);
}
static int __init
lnet_selftest_init(void)
{
- int nscheds;
- int rc;
- int i;
+ int nscheds;
+ int rc = -ENOMEM;
+ int i;
+
+ /* This assertion checks that struct sizes do not drift
+ * inadvertently and induce crashes when different nodes
+ * running LNet Selftest have mismatched structures.
+ */
+ lnet_selftest_structure_assertion();
+
+ rc = libcfs_setup();
+ if (rc)
+ return rc;
- rc = cfs_wi_sched_create("lst_s", lnet_cpt_table(), CFS_CPT_ANY,
- 1, &lst_sched_serial);
- if (rc != 0) {
+ lst_serial_wq = alloc_ordered_workqueue("lst_s", 0);
+ if (!lst_serial_wq) {
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)
+ CFS_ALLOC_PTR_ARRAY(lst_test_wq, nscheds);
+ if (!lst_test_wq) {
+ rc = -ENOMEM;
goto error;
+ }
lst_init_step = LST_INIT_WI_TEST;
for (i = 0; i < nscheds; 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 CPU partition affinity WI "
- "scheduler %d for LST\n", i);
+ lst_test_wq[i] = cfs_cpt_bind_workqueue("lst_t",
+ lnet_cpt_table(), 0,
+ i, nthrs);
+ if (IS_ERR(lst_test_wq[i])) {
+ rc = PTR_ERR(lst_test_wq[i]);
+ CERROR("Failed to create CPU partition affinity WI scheduler %d for LST: rc = %d\n",
+ i, rc);
+ lst_test_wq[i] = NULL;
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;
- }
+ 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: