diff options
Diffstat (limited to 'drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c')
-rw-r--r-- | drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c | 187 |
1 files changed, 106 insertions, 81 deletions
diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c index e8b1a61..6b9cf06 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-cpu.c @@ -55,6 +55,8 @@ MODULE_PARM_DESC(cpu_npartitions, "# of CPU partitions"); * 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. * + * 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 = ""; @@ -88,7 +90,7 @@ cfs_node_to_cpumask(int node, cpumask_t *mask) void cfs_cpt_table_free(struct cfs_cpt_table *cptab) { - int i; + int i; if (cptab->ctb_cpu2cpt) { LIBCFS_FREE(cptab->ctb_cpu2cpt, @@ -126,7 +128,7 @@ struct cfs_cpt_table * cfs_cpt_table_alloc(unsigned int ncpt) { struct cfs_cpt_table *cptab; - int i; + int i; LIBCFS_ALLOC(cptab, sizeof(*cptab)); if (!cptab) @@ -177,10 +179,10 @@ EXPORT_SYMBOL(cfs_cpt_table_alloc); int cfs_cpt_table_print(struct cfs_cpt_table *cptab, char *buf, int len) { - char *tmp = buf; - int rc = 0; - int i; - int j; + char *tmp = buf; + int rc = 0; + int i; + int j; for (i = 0; i < cptab->ctb_nparts; i++) { if (len > 0) { @@ -271,7 +273,7 @@ EXPORT_SYMBOL(cfs_cpt_nodemask); int cfs_cpt_set_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu) { - int node; + int node; LASSERT(cpt >= 0 && cpt < cptab->ctb_nparts); @@ -311,8 +313,8 @@ EXPORT_SYMBOL(cfs_cpt_set_cpu); void cfs_cpt_unset_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu) { - int node; - int i; + int node; + int i; LASSERT(cpt == CFS_CPT_ANY || (cpt >= 0 && cpt < cptab->ctb_nparts)); @@ -371,9 +373,9 @@ EXPORT_SYMBOL(cfs_cpt_unset_cpu); int cfs_cpt_set_cpumask(struct cfs_cpt_table *cptab, int cpt, cpumask_t *mask) { - int i; + int i; - if (cpumask_weight(mask) == 0 || + if (!cpumask_weight(mask) || cpumask_any_and(mask, cpu_online_mask) >= nr_cpu_ids) { CDEBUG(D_INFO, "No online CPU is found in the CPU mask for CPU partition %d\n", cpt); @@ -392,7 +394,7 @@ EXPORT_SYMBOL(cfs_cpt_set_cpumask); void cfs_cpt_unset_cpumask(struct cfs_cpt_table *cptab, int cpt, cpumask_t *mask) { - int i; + int i; for_each_cpu(i, mask) cfs_cpt_unset_cpu(cptab, cpt, i); @@ -402,8 +404,8 @@ EXPORT_SYMBOL(cfs_cpt_unset_cpumask); int cfs_cpt_set_node(struct cfs_cpt_table *cptab, int cpt, int node) { - cpumask_t *mask; - int rc; + cpumask_t *mask; + int rc; if (node < 0 || node >= MAX_NUMNODES) { CDEBUG(D_INFO, @@ -449,7 +451,7 @@ EXPORT_SYMBOL(cfs_cpt_unset_node); int cfs_cpt_set_nodemask(struct cfs_cpt_table *cptab, int cpt, nodemask_t *mask) { - int i; + int i; for_each_node_mask(i, *mask) { if (!cfs_cpt_set_node(cptab, cpt, i)) @@ -463,7 +465,7 @@ EXPORT_SYMBOL(cfs_cpt_set_nodemask); void cfs_cpt_unset_nodemask(struct cfs_cpt_table *cptab, int cpt, nodemask_t *mask) { - int i; + int i; for_each_node_mask(i, *mask) cfs_cpt_unset_node(cptab, cpt, i); @@ -473,8 +475,8 @@ EXPORT_SYMBOL(cfs_cpt_unset_nodemask); void cfs_cpt_clear(struct cfs_cpt_table *cptab, int cpt) { - int last; - int i; + int last; + int i; if (cpt == CFS_CPT_ANY) { last = cptab->ctb_nparts - 1; @@ -493,10 +495,10 @@ EXPORT_SYMBOL(cfs_cpt_clear); int cfs_cpt_spread_node(struct cfs_cpt_table *cptab, int cpt) { - nodemask_t *mask; - int weight; - int rotor; - int node; + nodemask_t *mask; + int weight; + int rotor; + int node; /* convert CPU partition ID to HW node id */ @@ -514,7 +516,7 @@ cfs_cpt_spread_node(struct cfs_cpt_table *cptab, int cpt) rotor %= weight; for_each_node_mask(node, *mask) { - if (rotor-- == 0) + if (!rotor--) return node; } @@ -526,8 +528,8 @@ EXPORT_SYMBOL(cfs_cpt_spread_node); int cfs_cpt_current(struct cfs_cpt_table *cptab, int remap) { - int cpu = smp_processor_id(); - int cpt = cptab->ctb_cpu2cpt[cpu]; + int cpu = smp_processor_id(); + int cpt = cptab->ctb_cpu2cpt[cpu]; if (cpt < 0) { if (!remap) @@ -555,10 +557,10 @@ EXPORT_SYMBOL(cfs_cpt_of_cpu); int cfs_cpt_bind(struct cfs_cpt_table *cptab, int cpt) { - cpumask_t *cpumask; - nodemask_t *nodemask; - int rc; - int i; + cpumask_t *cpumask; + nodemask_t *nodemask; + int rc; + int i; LASSERT(cpt == CFS_CPT_ANY || (cpt >= 0 && cpt < cptab->ctb_nparts)); @@ -582,7 +584,7 @@ cfs_cpt_bind(struct cfs_cpt_table *cptab, int cpt) rc = set_cpus_allowed_ptr(current, cpumask); set_mems_allowed(*nodemask); - if (rc == 0) + if (!rc) schedule(); /* switch to allowed CPU */ return rc; @@ -601,10 +603,10 @@ static int cfs_cpt_choose_ncpus(struct cfs_cpt_table *cptab, int cpt, cpumask_t *node, int number) { - cpumask_t *socket = NULL; - cpumask_t *core = NULL; - int rc = 0; - int cpu; + cpumask_t *socket = NULL; + cpumask_t *core = NULL; + int rc = 0; + int cpu; LASSERT(number > 0); @@ -638,7 +640,7 @@ cfs_cpt_choose_ncpus(struct cfs_cpt_table *cptab, int cpt, LASSERT(!cpumask_empty(socket)); while (!cpumask_empty(socket)) { - int i; + int i; /* get cpumask for hts in the same core */ cpumask_copy(core, topology_sibling_cpumask(cpu)); @@ -656,14 +658,14 @@ cfs_cpt_choose_ncpus(struct cfs_cpt_table *cptab, int cpt, goto out; } - if (--number == 0) + if (!--number) goto out; } cpu = cpumask_first(socket); } } - out: +out: if (socket) LIBCFS_FREE(socket, cpumask_size()); if (core) @@ -676,9 +678,9 @@ cfs_cpt_choose_ncpus(struct cfs_cpt_table *cptab, int cpt, static unsigned int cfs_cpt_num_estimate(void) { - unsigned nnode = num_online_nodes(); - unsigned ncpu = num_online_cpus(); - unsigned ncpt; + unsigned int nnode = num_online_nodes(); + unsigned int ncpu = num_online_cpus(); + unsigned int ncpt; if (ncpu <= CPT_WEIGHT_MIN) { ncpt = 1; @@ -703,14 +705,14 @@ cfs_cpt_num_estimate(void) ncpt = nnode; - out: +out: #if (BITS_PER_LONG == 32) /* config many CPU partitions on 32-bit system could consume * too much memory */ ncpt = min(2U, ncpt); #endif - while (ncpu % ncpt != 0) + while (ncpu % ncpt) ncpt--; /* worst case is 1 */ return ncpt; @@ -720,11 +722,11 @@ static struct cfs_cpt_table * cfs_cpt_table_create(int ncpt) { struct cfs_cpt_table *cptab = NULL; - cpumask_t *mask = NULL; - int cpt = 0; - int num; - int rc; - int i; + cpumask_t *mask = NULL; + int cpt = 0; + int num; + int rc; + int i; rc = cfs_cpt_num_estimate(); if (ncpt <= 0) @@ -735,7 +737,7 @@ cfs_cpt_table_create(int ncpt) ncpt, rc); } - if (num_online_cpus() % ncpt != 0) { + if (num_online_cpus() % ncpt) { CERROR("CPU number %d is not multiple of cpu_npartition %d, please try different cpu_npartitions value or set pattern string by cpu_pattern=STRING\n", (int)num_online_cpus(), ncpt); goto failed; @@ -748,7 +750,7 @@ cfs_cpt_table_create(int ncpt) } num = num_online_cpus() / ncpt; - if (num == 0) { + if (!num) { CERROR("CPU changed while setting CPU partition\n"); goto failed; } @@ -764,7 +766,7 @@ cfs_cpt_table_create(int ncpt) while (!cpumask_empty(mask)) { struct cfs_cpu_partition *part; - int n; + int n; /* * Each emulated NUMA node has all allowed CPUs in @@ -817,27 +819,36 @@ cfs_cpt_table_create(int ncpt) static struct cfs_cpt_table * cfs_cpt_table_create_pattern(char *pattern) { - struct cfs_cpt_table *cptab; - char *str = pattern; - int node = 0; - int high; - int ncpt; - int c; - - for (ncpt = 0;; ncpt++) { /* quick scan bracket */ - str = strchr(str, '['); - if (!str) - break; - str++; - } + struct cfs_cpt_table *cptab; + char *str; + int node = 0; + int high; + int ncpt = 0; + int cpt; + int rc; + int c; + int i; str = cfs_trimwhite(pattern); if (*str == 'n' || *str == 'N') { pattern = str + 1; - node = 1; + if (*pattern != '\0') { + node = 1; + } else { /* shortcut to create CPT from NUMA & CPU topology */ + node = -1; + ncpt = num_online_nodes(); + } + } + + if (!ncpt) { /* scanning bracket which is mark of partition */ + for (str = pattern;; str++, ncpt++) { + str = strchr(str, '['); + if (!str) + break; + } } - if (ncpt == 0 || + if (!ncpt || (node && ncpt > num_online_nodes()) || (!node && ncpt > num_online_cpus())) { CERROR("Invalid pattern %s, or too many partitions %d\n", @@ -845,25 +856,39 @@ cfs_cpt_table_create_pattern(char *pattern) return NULL; } - high = node ? MAX_NUMNODES - 1 : nr_cpu_ids - 1; - cptab = cfs_cpt_table_alloc(ncpt); if (!cptab) { CERROR("Failed to allocate cpu partition table\n"); return NULL; } + if (node < 0) { /* shortcut to create CPT from NUMA & CPU topology */ + cpt = 0; + + for_each_online_node(i) { + if (cpt >= ncpt) { + CERROR("CPU changed while setting CPU partition table, %d/%d\n", + cpt, ncpt); + goto failed; + } + + rc = cfs_cpt_set_node(cptab, cpt++, i); + if (!rc) + goto failed; + } + return cptab; + } + + high = node ? MAX_NUMNODES - 1 : nr_cpu_ids - 1; + for (str = cfs_trimwhite(pattern), c = 0;; c++) { - struct cfs_range_expr *range; - struct cfs_expr_list *el; - char *bracket = strchr(str, '['); - int cpt; - int rc; - int i; - int n; + struct cfs_range_expr *range; + struct cfs_expr_list *el; + char *bracket = strchr(str, '['); + int n; if (!bracket) { - if (*str != 0) { + if (*str) { CERROR("Invalid pattern %s\n", str); goto failed; } @@ -886,7 +911,7 @@ cfs_cpt_table_create_pattern(char *pattern) goto failed; } - if (cfs_cpt_weight(cptab, cpt) != 0) { + if (cfs_cpt_weight(cptab, cpt)) { CERROR("Partition %d has already been set.\n", cpt); goto failed; } @@ -905,14 +930,14 @@ cfs_cpt_table_create_pattern(char *pattern) } if (cfs_expr_list_parse(str, (bracket - str) + 1, - 0, high, &el) != 0) { + 0, high, &el)) { CERROR("Can't parse number range: %s\n", str); goto failed; } list_for_each_entry(range, &el->el_exprs, re_link) { for (i = range->re_lo; i <= range->re_hi; i++) { - if ((i - range->re_lo) % range->re_stride != 0) + if ((i - range->re_lo) % range->re_stride) continue; rc = node ? cfs_cpt_set_node(cptab, cpt, i) : @@ -945,8 +970,8 @@ cfs_cpt_table_create_pattern(char *pattern) static int cfs_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { - unsigned int cpu = (unsigned long)hcpu; - bool warn; + unsigned int cpu = (unsigned long)hcpu; + bool warn; switch (action) { case CPU_DEAD: @@ -1019,7 +1044,7 @@ cfs_cpu_init(void) register_hotcpu_notifier(&cfs_cpu_notifier); #endif - if (*cpu_pattern != 0) { + if (*cpu_pattern) { cfs_cpt_table = cfs_cpt_table_create_pattern(cpu_pattern); if (!cfs_cpt_table) { CERROR("Failed to create cptab from pattern %s\n", |