Whamcloud - gitweb
LU-4199 libcfs: add CPU table functions for uniprocessor
[fs/lustre-release.git] / libcfs / include / libcfs / libcfs_cpu.h
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 021110-1307, USA
20  *
21  * GPL HEADER END
22  */
23 /*
24  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
25  * Copyright (c) 2012, 2013, Intel Corporation.
26  */
27 /*
28  * This file is part of Lustre, http://www.lustre.org/
29  * Lustre is a trademark of Sun Microsystems, Inc.
30  *
31  * libcfs/include/libcfs/libcfs_cpu.h
32  *
33  * CPU partition
34  *   . CPU partition is virtual processing unit
35  *
36  *   . CPU partition can present 1-N cores, or 1-N NUMA nodes,
37  *     in other words, CPU partition is a processors pool.
38  *
39  * CPU Partition Table (CPT)
40  *   . a set of CPU partitions
41  *
42  *   . There are two modes for CPT: CFS_CPU_MODE_NUMA and CFS_CPU_MODE_SMP
43  *
44  *   . User can specify total number of CPU partitions while creating a
45  *     CPT, ID of CPU partition is always start from 0.
46  *
47  *     Example: if there are 8 cores on the system, while creating a CPT
48  *     with cpu_npartitions=4:
49  *              core[0, 1] = partition[0], core[2, 3] = partition[1]
50  *              core[4, 5] = partition[2], core[6, 7] = partition[3]
51  *
52  *          cpu_npartitions=1:
53  *              core[0, 1, ... 7] = partition[0]
54  *
55  *   . User can also specify CPU partitions by string pattern
56  *
57  *     Examples: cpu_partitions="0[0,1], 1[2,3]"
58  *               cpu_partitions="N 0[0-3], 1[4-8]"
59  *
60  *     The first character "N" means following numbers are numa ID
61  *
62  *   . NUMA allocators, CPU affinity threads are built over CPU partitions,
63  *     instead of HW CPUs or HW nodes.
64  *
65  *   . By default, Lustre modules should refer to the global cfs_cpt_table,
66  *     instead of accessing HW CPUs directly, so concurrency of Lustre can be
67  *     configured by cpu_npartitions of the global cfs_cpt_table
68  *
69  *   . If cpu_npartitions=1(all CPUs in one pool), lustre should work the
70  *     same way as 2.2 or earlier versions
71  *
72  * Author: liang@whamcloud.com
73  */
74
75 #ifndef __LIBCFS_CPU_H__
76 #define __LIBCFS_CPU_H__
77
78 #ifndef HAVE_LIBCFS_CPT
79
80 #ifndef __KERNEL__
81 typedef unsigned long           cpumask_t;
82 typedef unsigned long           nodemask_t;
83 #endif
84
85 struct cfs_cpt_table {
86         /* # of CPU partitions */
87         int                     ctb_nparts;
88         /* cpu mask */
89         cpumask_t               ctb_mask;
90         /* node mask */
91         nodemask_t              ctb_nodemask;
92         /* version */
93         __u64                   ctb_version;
94 };
95
96 #endif /* !HAVE_LIBCFS_CPT */
97
98 /* any CPU partition */
99 #define CFS_CPT_ANY             (-1)
100
101 extern struct cfs_cpt_table     *cfs_cpt_table;
102
103 /**
104  * destroy a CPU partition table
105  */
106 void cfs_cpt_table_free(struct cfs_cpt_table *cptab);
107 /**
108  * create a cfs_cpt_table with \a ncpt number of partitions
109  */
110 struct cfs_cpt_table *cfs_cpt_table_alloc(unsigned int ncpt);
111 /**
112  * print string information of cpt-table
113  */
114 int cfs_cpt_table_print(struct cfs_cpt_table *cptab, char *buf, int len);
115 /**
116  * return total number of CPU partitions in \a cptab
117  */
118 int
119 cfs_cpt_number(struct cfs_cpt_table *cptab);
120 /**
121  * return number of HW cores or hypter-threadings in a CPU partition \a cpt
122  */
123 int cfs_cpt_weight(struct cfs_cpt_table *cptab, int cpt);
124 /**
125  * is there any online CPU in CPU partition \a cpt
126  */
127 int cfs_cpt_online(struct cfs_cpt_table *cptab, int cpt);
128 /**
129  * return cpumask of CPU partition \a cpt
130  */
131 cpumask_t *cfs_cpt_cpumask(struct cfs_cpt_table *cptab, int cpt);
132 /**
133  * return nodemask of CPU partition \a cpt
134  */
135 nodemask_t *cfs_cpt_nodemask(struct cfs_cpt_table *cptab, int cpt);
136 /**
137  * shadow current HW processor ID to CPU-partition ID of \a cptab
138  */
139 int cfs_cpt_current(struct cfs_cpt_table *cptab, int remap);
140 /**
141  * shadow HW processor ID \a CPU to CPU-partition ID by \a cptab
142  */
143 int cfs_cpt_of_cpu(struct cfs_cpt_table *cptab, int cpu);
144 /**
145  * bind current thread on a CPU-partition \a cpt of \a cptab
146  */
147 int cfs_cpt_bind(struct cfs_cpt_table *cptab, int cpt);
148 /**
149  * add \a cpu to CPU partion @cpt of \a cptab, return 1 for success,
150  * otherwise 0 is returned
151  */
152 int cfs_cpt_set_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu);
153 /**
154  * remove \a cpu from CPU partition \a cpt of \a cptab
155  */
156 void cfs_cpt_unset_cpu(struct cfs_cpt_table *cptab, int cpt, int cpu);
157 /**
158  * add all cpus in \a mask to CPU partition \a cpt
159  * return 1 if successfully set all CPUs, otherwise return 0
160  */
161 int cfs_cpt_set_cpumask(struct cfs_cpt_table *cptab,
162                         int cpt, cpumask_t *mask);
163 /**
164  * remove all cpus in \a mask from CPU partition \a cpt
165  */
166 void cfs_cpt_unset_cpumask(struct cfs_cpt_table *cptab,
167                            int cpt, cpumask_t *mask);
168 /**
169  * add all cpus in NUMA node \a node to CPU partition \a cpt
170  * return 1 if successfully set all CPUs, otherwise return 0
171  */
172 int cfs_cpt_set_node(struct cfs_cpt_table *cptab, int cpt, int node);
173 /**
174  * remove all cpus in NUMA node \a node from CPU partition \a cpt
175  */
176 void cfs_cpt_unset_node(struct cfs_cpt_table *cptab, int cpt, int node);
177
178 /**
179  * add all cpus in node mask \a mask to CPU partition \a cpt
180  * return 1 if successfully set all CPUs, otherwise return 0
181  */
182 int cfs_cpt_set_nodemask(struct cfs_cpt_table *cptab,
183                          int cpt, nodemask_t *mask);
184 /**
185  * remove all cpus in node mask \a mask from CPU partition \a cpt
186  */
187 void cfs_cpt_unset_nodemask(struct cfs_cpt_table *cptab,
188                             int cpt, nodemask_t *mask);
189 /**
190  * unset all cpus for CPU partition \a cpt
191  */
192 void cfs_cpt_clear(struct cfs_cpt_table *cptab, int cpt);
193 /**
194  * convert partition id \a cpt to numa node id, if there are more than one
195  * nodes in this partition, it might return a different node id each time.
196  */
197 int cfs_cpt_spread_node(struct cfs_cpt_table *cptab, int cpt);
198
199 /**
200  * return number of HTs in the same core of \a cpu
201  */
202 int cfs_cpu_ht_nsiblings(int cpu);
203
204 /**
205  * iterate over all CPU partitions in \a cptab
206  */
207 #define cfs_cpt_for_each(i, cptab)      \
208         for (i = 0; i < cfs_cpt_number(cptab); i++)
209
210 #ifndef __read_mostly
211 # define __read_mostly
212 #endif
213
214 #ifndef ____cacheline_aligned
215 #define ____cacheline_aligned
216 #endif
217
218 int  cfs_cpu_init(void);
219 void cfs_cpu_fini(void);
220
221 #endif /* __LIBCFS_CPU_H__ */