EXTRA_DIST = \
libcfs.h \
- libcfs_cpu.h \
libcfs_crypto.h \
libcfs_debug.h \
libcfs_fail.h \
#include <uapi/linux/lnet/libcfs_ioctl.h>
#include <libcfs/libcfs_debug.h>
#include <libcfs/libcfs_private.h>
-#include <libcfs/libcfs_cpu.h>
#include <libcfs/libcfs_string.h>
#include <libcfs/libcfs_hash.h>
#include <libcfs/libcfs_fail.h>
libcfs-linux-objs := $(addprefix linux/,$(libcfs-linux-objs))
libcfs-crypto-objs := $(addprefix crypto/,$(libcfs-crypto-objs))
-libcfs-objs-$(CONFIG_SMP) = libcfs_cpu.o
libcfs-all-objs := debug.o fail.o module.o tracefile.o \
libcfs_string.o hash.o \
- linux-crypto.o linux-crypto-adler.o \
- $(libcfs-objs-y)
+ linux-crypto.o linux-crypto-adler.o
libcfs-objs := $(libcfs-linux-objs) $(libcfs-all-objs)
@LLCRYPT_TRUE@libcfs-objs += $(libcfs-crypto-objs)
MOSTLYCLEANFILES := @MOSTLYCLEANFILES@ linux/*.o libcfs crypto/*.o
EXTRA_DIST := $(libcfs-all-objs:%.o=%.c) tracefile.h \
- fail.c libcfs_cpu.c linux-crypto.h
+ fail.c linux-crypto.h
#include <lustre_crypto.h>
#include "tracefile.h"
+int cpu_npartitions;
+EXPORT_SYMBOL(cpu_npartitions);
+module_param(cpu_npartitions, int, 0444);
+MODULE_PARM_DESC(cpu_npartitions, "# of CPU partitions");
+
+char *cpu_pattern = "N";
+EXPORT_SYMBOL(cpu_pattern);
+module_param(cpu_pattern, charp, 0444);
+MODULE_PARM_DESC(cpu_pattern, "CPU partitions pattern");
+
struct lnet_debugfs_symlink_def {
const char *name;
const char *target;
return len;
}
-static int proc_cpt_table(struct ctl_table *table, int write,
- void __user *buffer, size_t *lenp, loff_t *ppos)
-{
- size_t nob = *lenp;
- loff_t pos = *ppos;
- char *buf = NULL;
- int len = 4096;
- int rc = 0;
-
- if (write)
- return -EPERM;
-
- while (1) {
- LIBCFS_ALLOC(buf, len);
- if (buf == NULL)
- return -ENOMEM;
-
- rc = cfs_cpt_table_print(cfs_cpt_tab, buf, len);
- if (rc >= 0)
- break;
-
- if (rc == -EFBIG) {
- LIBCFS_FREE(buf, len);
- len <<= 1;
- continue;
- }
- goto out;
- }
-
- if (pos >= rc) {
- rc = 0;
- goto out;
- }
-
- rc = cfs_trace_copyout_string(buffer, nob, buf + pos, NULL);
-out:
- if (buf != NULL)
- LIBCFS_FREE(buf, len);
- return rc;
-}
-
-static int proc_cpt_distance(struct ctl_table *table, int write,
- void __user *buffer, size_t *lenp, loff_t *ppos)
-{
- size_t nob = *lenp;
- loff_t pos = *ppos;
- char *buf = NULL;
- int len = 4096;
- int rc = 0;
-
- if (write)
- return -EPERM;
-
- while (1) {
- LIBCFS_ALLOC(buf, len);
- if (buf == NULL)
- return -ENOMEM;
-
- rc = cfs_cpt_distance_print(cfs_cpt_tab, buf, len);
- if (rc >= 0)
- break;
-
- if (rc == -EFBIG) {
- LIBCFS_FREE(buf, len);
- len <<= 1;
- continue;
- }
- goto out;
- }
-
- if (pos >= rc) {
- rc = 0;
- goto out;
- }
-
- rc = cfs_trace_copyout_string(buffer, nob, buf + pos, NULL);
- out:
- if (buf != NULL)
- LIBCFS_FREE(buf, len);
- return rc;
-}
-
static struct ctl_table lnet_table[] = {
{
.procname = "debug",
.proc_handler = &proc_dobitmasks,
},
{
- .procname = "cpu_partition_table",
- .maxlen = 128,
- .mode = 0444,
- .proc_handler = &proc_cpt_table,
- },
- {
- .procname = "cpu_partition_distance",
- .maxlen = 128,
- .mode = 0444,
- .proc_handler = &proc_cpt_distance,
- },
- {
.procname = "debug_log_upcall",
.data = lnet_debug_log_upcall,
.maxlen = sizeof(lnet_debug_log_upcall),
goto cleanup_lock;
}
- rc = cfs_cpu_init();
- if (rc != 0)
- goto cleanup_debug;
-
cfs_rehash_wq = alloc_workqueue("cfs_rh", WQ_SYSFS, 4);
if (!cfs_rehash_wq) {
rc = -ENOMEM;
CERROR("libcfs: failed to start rehash workqueue: rc = %d\n",
rc);
- goto cleanup_cpu;
+ goto cleanup_debug;
}
rc = cfs_crypto_register();
cleanup_wq:
destroy_workqueue(cfs_rehash_wq);
cfs_rehash_wq = NULL;
-cleanup_cpu:
- cfs_cpu_fini();
cleanup_debug:
libcfs_debug_cleanup();
cleanup_lock:
cfs_crypto_unregister();
- cfs_cpu_fini();
-
/* the below message is checked in test-framework.sh check_mem_leak() */
if (libcfs_kmem_read() != 0)
CERROR("Portals memory leaked: %lld bytes\n",
EXTRA_DIST = \
api.h \
+ lib-cpt.h \
lib-lnet.h \
lib-types.h \
udsp.h \
*
* GPL HEADER END
*/
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
*
* Copyright (c) 2012, 2017, Intel Corporation.
*/
-/*
- * This file is part of Lustre, http://www.lustre.org/
- *
- * libcfs/include/libcfs/libcfs_cpu.h
+/* This file is part of Lustre, http://www.lustre.org/
*
* CPU partition
* . CPU partition is virtual processing unit
#endif /* CONFIG_SMP */
+/* Module parameters */
+extern int cpu_npartitions;
+extern char *cpu_pattern;
+
static inline
struct workqueue_struct *cfs_cpt_bind_workqueue(const char *wq_name,
struct cfs_cpt_table *tbl,
return wq;
}
-/*
- * allocate per-cpu-partition data, returned value is an array of pointers,
+/* allocate per-cpu-partition data, returned value is an array of pointers,
* variable can be indexed by CPU ID.
* cptab != NULL: size of array is number of CPU partitions
* cptab == NULL: size of array is number of HW cores
*/
void *cfs_percpt_alloc(struct cfs_cpt_table *cptab, unsigned int size);
-/*
- * destroy per-cpu-partition variable
- */
+/* destroy per-cpu-partition variable */
void cfs_percpt_free(void *vars);
int cfs_percpt_number(void *vars);
#include <libcfs/libcfs.h>
#include <lnet/api.h>
+#include <lnet/lib-cpt.h>
#include <lnet/lib-types.h>
#include <uapi/linux/lnet/lnet-dlc.h>
#include <uapi/linux/lnet/lnet-types.h>
MODULES := lnet
+lnet-objs-$(CONFIG_SMP) = lib-cpt.o
lnet-objs := api-ni.o config.o nidstrings.o lnet_rdma.o lock.o
-lnet-objs += lib-me.o lib-msg.o lib-md.o lib-ptl.o lib-mem.o
+lnet-objs += lib-me.o lib-msg.o lib-md.o lib-ptl.o
lnet-objs += lib-socket.o lib-move.o module.o lo.o
-lnet-objs += router.o router_proc.o acceptor.o peer.o net_fault.o udsp.o
+lnet-objs += router.o lnet_debugfs.o acceptor.o peer.o net_fault.o udsp.o
+lnet-objs += $(lnet-objs-y)
CFLAGS_lnet_rdma.o += -I @GDS_PATH@ -I@CUDA_PATH@
endif # MODULES
-EXTRA_DIST := $(lnet-objs:%.o=%.c)
+EXTRA_DIST := $(lnet-objs:%.o=%.c) lib-cpt.c
MOSTLYCLEANFILES = @MOSTLYCLEANFILES@ lnet
*
* GPL HEADER END
*/
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017, Intel Corporation.
*/
-/*
- * This file is part of Lustre, http://www.lustre.org/
+/* This file is part of Lustre, http://www.lustre.org/
*
- * Please see comments in libcfs/include/libcfs/libcfs_cpu.h for introduction
+ * Please see comments in include/lnet/lib-cpt.h for introduction
*
* Author: liang@whamcloud.com
*/
#include <linux/cpu.h>
#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include <libcfs/libcfs_string.h>
#include <libcfs/libcfs.h>
-#include <libcfs/libcfs_cpu.h>
+#include <lnet/lib-cpt.h>
/** virtual processing unit */
struct cfs_cpu_partition {
* 1 : disable multiple partitions
* >1 : specify number of partitions
*/
-static int cpu_npartitions;
module_param(cpu_npartitions, int, 0444);
MODULE_PARM_DESC(cpu_npartitions, "# of CPU partitions");
* modparam for setting CPU partitions patterns:
*
* i.e: "0[0,1,2,3] 1[4,5,6,7]", number before bracket is CPU partition ID,
- * number in bracket is processor ID (core or HT)
+ * number in bracket is processor ID (core or HT)
*
* i.e: "N 0[0,1] 1[2,3]" the first character 'N' means numbers in bracket
- * are NUMA node ID, number before bracket is CPU partition ID.
+ * are NUMA node ID, number before bracket is CPU partition ID.
*
* i.e: "N", shortcut expression to create CPT from NUMA & CPU topology
*
* NB: If user specified cpu_pattern, cpu_npartitions will be ignored
*/
-static char *cpu_pattern = "N";
module_param(cpu_pattern, charp, 0444);
MODULE_PARM_DESC(cpu_pattern, "CPU partitions pattern");
}
EXPORT_SYMBOL(cfs_cpt_distance);
-/*
- * Calculate the maximum NUMA distance between all nodes in the
+/* Calculate the maximum NUMA distance between all nodes in the
* from_mask and all nodes in the to_mask.
*/
static unsigned int cfs_cpt_distance_calculate(nodemask_t *from_mask,
return 0;
}
- /*
- * Allocate scratch buffers
+ /* Allocate scratch buffers
* As we cannot initialize a cpumask_var_t, we need
* to alloc both before we can risk trying to free either
*/
return ERR_PTR(rc);
}
+struct cfs_var_array {
+ unsigned int va_count; /* # of buffers */
+ unsigned int va_size; /* size of each var */
+ struct cfs_cpt_table *va_cptab; /* cpu partition table */
+ void *va_ptrs[0]; /* buffer addresses */
+};
+
+/* free per-cpu data, see more detail in cfs_percpt_free */
+void
+cfs_percpt_free(void *vars)
+{
+ struct cfs_var_array *arr;
+ int i;
+
+ arr = container_of(vars, struct cfs_var_array, va_ptrs[0]);
+
+ for (i = 0; i < arr->va_count; i++) {
+ if (arr->va_ptrs[i])
+ LIBCFS_FREE(arr->va_ptrs[i], arr->va_size);
+ }
+
+ LIBCFS_FREE(arr, offsetof(struct cfs_var_array,
+ va_ptrs[arr->va_count]));
+}
+EXPORT_SYMBOL(cfs_percpt_free);
+
+/* allocate per cpu-partition variables, returned value is an array of pointers,
+ * variable can be indexed by CPU partition ID, i.e:
+ *
+ * arr = cfs_percpt_alloc(cfs_cpu_pt, size);
+ * then caller can access memory block for CPU 0 by arr[0],
+ * memory block for CPU 1 by arr[1]...
+ * memory block for CPU N by arr[N]...
+ *
+ * cacheline aligned.
+ */
+void *
+cfs_percpt_alloc(struct cfs_cpt_table *cptab, unsigned int size)
+{
+ struct cfs_var_array *arr;
+ int count;
+ int i;
+
+ count = cfs_cpt_number(cptab);
+
+ LIBCFS_ALLOC(arr, offsetof(struct cfs_var_array, va_ptrs[count]));
+ if (!arr)
+ return NULL;
+
+ size = L1_CACHE_ALIGN(size);
+ arr->va_size = size;
+ arr->va_count = count;
+ arr->va_cptab = cptab;
+
+ for (i = 0; i < count; i++) {
+ LIBCFS_CPT_ALLOC(arr->va_ptrs[i], cptab, i, size);
+ if (!arr->va_ptrs[i]) {
+ cfs_percpt_free((void *)&arr->va_ptrs[0]);
+ return NULL;
+ }
+ }
+
+ return (void *)&arr->va_ptrs[0];
+}
+EXPORT_SYMBOL(cfs_percpt_alloc);
+
+/* return number of CPUs (or number of elements in per-cpu data)
+ * according to cptab of @vars
+ */
+int
+cfs_percpt_number(void *vars)
+{
+ struct cfs_var_array *arr;
+
+ arr = container_of(vars, struct cfs_var_array, va_ptrs[0]);
+
+ return arr->va_count;
+}
+EXPORT_SYMBOL(cfs_percpt_number);
+
#ifdef CONFIG_HOTPLUG_CPU
#ifdef HAVE_HOTPLUG_STATE_MACHINE
static enum cpuhp_state lustre_cpu_online;
+++ /dev/null
-/*
- * 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).
- *
- * GPL HEADER END
- */
-/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, Intel Corporation.
- */
-/* This file is part of Lustre, http://www.lustre.org/
- *
- * Author: liang@whamcloud.com
- */
-
-#define DEBUG_SUBSYSTEM S_LNET
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <libcfs/libcfs.h>
-#include <libcfs/libcfs_cpu.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-
-struct cfs_var_array {
- unsigned int va_count; /* # of buffers */
- unsigned int va_size; /* size of each var */
- struct cfs_cpt_table *va_cptab; /* cpu partition table */
- void *va_ptrs[0]; /* buffer addresses */
-};
-
-/* free per-cpu data, see more detail in cfs_percpt_free
- */
-void
-cfs_percpt_free(void *vars)
-{
- struct cfs_var_array *arr;
- int i;
-
- arr = container_of(vars, struct cfs_var_array, va_ptrs[0]);
-
- for (i = 0; i < arr->va_count; i++) {
- if (arr->va_ptrs[i] != NULL)
- LIBCFS_FREE(arr->va_ptrs[i], arr->va_size);
- }
-
- LIBCFS_FREE(arr, offsetof(struct cfs_var_array,
- va_ptrs[arr->va_count]));
-}
-EXPORT_SYMBOL(cfs_percpt_free);
-
-/* allocate per cpu-partition variables, returned value is an array of pointers,
- * variable can be indexed by CPU partition ID, i.e:
- *
- * arr = cfs_percpt_alloc(cfs_cpu_pt, size);
- * then caller can access memory block for CPU 0 by arr[0],
- * memory block for CPU 1 by arr[1]...
- * memory block for CPU N by arr[N]...
- *
- * cacheline aligned.
- */
-void *
-cfs_percpt_alloc(struct cfs_cpt_table *cptab, unsigned int size)
-{
- struct cfs_var_array *arr;
- int count;
- int i;
-
- count = cfs_cpt_number(cptab);
-
- LIBCFS_ALLOC(arr, offsetof(struct cfs_var_array, va_ptrs[count]));
- if (!arr)
- return NULL;
-
- size = L1_CACHE_ALIGN(size);
- arr->va_size = size;
- arr->va_count = count;
- arr->va_cptab = cptab;
-
- for (i = 0; i < count; i++) {
- LIBCFS_CPT_ALLOC(arr->va_ptrs[i], cptab, i, size);
- if (!arr->va_ptrs[i]) {
- cfs_percpt_free((void *)&arr->va_ptrs[0]);
- return NULL;
- }
- }
-
- return (void *)&arr->va_ptrs[0];
-}
-EXPORT_SYMBOL(cfs_percpt_alloc);
-
-/* return number of CPUs (or number of elements in per-cpu data)
- * according to cptab of @vars
- */
-int
-cfs_percpt_number(void *vars)
-{
- struct cfs_var_array *arr;
-
- arr = container_of(vars, struct cfs_var_array, va_ptrs[0]);
-
- return arr->va_count;
-}
-EXPORT_SYMBOL(cfs_percpt_number);
#include <libcfs/libcfs.h>
#include <lnet/lib-lnet.h>
-/* This is really lnet_proc.c. You might need to update sanity test 215
- * if any file format is changed. */
-
#define LNET_LOFFT_BITS (sizeof(loff_t) * 8)
-/*
- * NB: max allowed LNET_CPT_BITS is 8 on 64-bit system and 2 on 32-bit system
+/* NB: max allowed LNET_CPT_BITS is 8 on 64-bit system and 2 on 32-bit system
*/
#define LNET_PROC_CPT_BITS (LNET_CPT_BITS + 1)
/* change version, 16 bits or 8 bits */
clamp_t(int, LNET_LOFFT_BITS / 4, 8, 16)
#define LNET_PROC_HASH_BITS LNET_PEER_HASH_BITS
-/*
- * bits for peer hash offset
+/* bits for peer hash offset
* NB: we don't use the highest bit of *ppos because it's signed
*/
#define LNET_PROC_HOFF_BITS (LNET_LOFFT_BITS - \
#define LNET_PROC_VERSION(v) ((unsigned int)((v) & LNET_PROC_VER_MASK))
+static int proc_cpt_table(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ size_t nob = *lenp;
+ loff_t pos = *ppos;
+ char *buf = NULL;
+ int len = 4096;
+ int rc = 0;
+
+ if (write)
+ return -EPERM;
+
+ while (1) {
+ LIBCFS_ALLOC(buf, len);
+ if (!buf)
+ return -ENOMEM;
+
+ rc = cfs_cpt_table_print(cfs_cpt_tab, buf, len);
+ if (rc >= 0)
+ break;
+
+ if (rc == -EFBIG) {
+ LIBCFS_FREE(buf, len);
+ len <<= 1;
+ continue;
+ }
+ goto out;
+ }
+
+ if (pos >= rc) {
+ rc = 0;
+ goto out;
+ }
+
+ rc = cfs_trace_copyout_string(buffer, nob, buf + pos, NULL);
+out:
+ if (buf)
+ LIBCFS_FREE(buf, len);
+ return rc;
+}
+
+static int proc_cpt_distance(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+ size_t nob = *lenp;
+ loff_t pos = *ppos;
+ char *buf = NULL;
+ int len = 4096;
+ int rc = 0;
+
+ if (write)
+ return -EPERM;
+
+ while (1) {
+ LIBCFS_ALLOC(buf, len);
+ if (!buf)
+ return -ENOMEM;
+
+ rc = cfs_cpt_distance_print(cfs_cpt_tab, buf, len);
+ if (rc >= 0)
+ break;
+
+ if (rc == -EFBIG) {
+ LIBCFS_FREE(buf, len);
+ len <<= 1;
+ continue;
+ }
+ goto out;
+ }
+
+ if (pos >= rc) {
+ rc = 0;
+ goto out;
+ }
+
+ rc = cfs_trace_copyout_string(buffer, nob, buf + pos, NULL);
+out:
+ if (buf)
+ LIBCFS_FREE(buf, len);
+ return rc;
+}
+
static int proc_lnet_stats(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
* to go via /proc for portability.
*/
{
+ .procname = "cpu_partition_table",
+ .maxlen = 128,
+ .mode = 0444,
+ .proc_handler = &proc_cpt_table,
+ },
+ {
+ .procname = "cpu_partition_distance",
+ .maxlen = 128,
+ .mode = 0444,
+ .proc_handler = &proc_cpt_distance,
+ },
+ {
.procname = "stats",
.mode = 0644,
.proc_handler = &proc_lnet_stats,
if (rc)
return rc;
+ rc = cfs_cpu_init();
+ if (rc < 0) {
+ CERROR("cfs_cpu_init: rc = %d\n", rc);
+ RETURN(rc);
+ }
+
rc = lnet_lib_init();
if (rc != 0) {
CERROR("lnet_lib_init: rc = %d\n", rc);
+ cfs_cpu_fini();
RETURN(rc);
}
rc = misc_register(&lnet_dev);
if (rc) {
CERROR("misc_register: rc = %d\n", rc);
+ cfs_cpu_fini();
RETURN(rc);
}
lnet_router_exit();
lnet_lib_exit();
+ cfs_cpu_fini();
}
MODULE_AUTHOR("OpenSFS, Inc. <http://www.lustre.org/>");
#include <linux/types.h>
#include <libcfs/libcfs.h>
+#include <lnet/lib-cpt.h>
#include <lprocfs_status.h>
#include <lustre_handles.h>