aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2009-08-14 02:00:50 -0400
committerTejun Heo <tj@kernel.org>2009-08-14 02:00:50 -0400
commitf58dc01ba2ca9fe3ab2ba4ca43d9c8a735cf62d8 (patch)
tree9eb76a0d6aa34e56f8650fe98a5ce26891a522ab
parent08fc45806103e59a37418e84719b878f9bb32540 (diff)
percpu: generalize first chunk allocator selection
Now that all first chunk allocators are in mm/percpu.c, it makes sense to make generalize percpu_alloc kernel parameter. Define PCPU_FC_* and set pcpu_chosen_fc using early_param() in mm/percpu.c. Arch code can use the set value to determine which first chunk allocator to use. Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r--Documentation/kernel-parameters.txt11
-rw-r--r--arch/x86/kernel/setup_percpu.c24
-rw-r--r--include/linux/percpu.h12
-rw-r--r--mm/percpu.c32
4 files changed, 56 insertions, 23 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 12e9eb77ee0d..dee9ce2e6cfa 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1919,11 +1919,12 @@ and is between 256 and 4096 characters. It is defined in the file
1919 Format: { 0 | 1 } 1919 Format: { 0 | 1 }
1920 See arch/parisc/kernel/pdc_chassis.c 1920 See arch/parisc/kernel/pdc_chassis.c
1921 1921
1922 percpu_alloc= [X86] Select which percpu first chunk allocator to use. 1922 percpu_alloc= Select which percpu first chunk allocator to use.
1923 Allowed values are one of "lpage", "embed" and "page". 1923 Currently supported values are "embed", "page" and
1924 See comments in arch/x86/kernel/setup_percpu.c for 1924 "lpage". Archs may support subset or none of the
1925 details on each allocator. This parameter is primarily 1925 selections. See comments in mm/percpu.c for details
1926 for debugging and performance comparison. 1926 on each allocator. This parameter is primarily for
1927 debugging and performance comparison.
1927 1928
1928 pf. [PARIDE] 1929 pf. [PARIDE]
1929 See Documentation/blockdev/paride.txt. 1930 See Documentation/blockdev/paride.txt.
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index 1e17711c29d6..b961d99e6416 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -267,16 +267,6 @@ static ssize_t __init setup_pcpu_page(size_t static_size)
267 pcpup_populate_pte); 267 pcpup_populate_pte);
268} 268}
269 269
270/* for explicit first chunk allocator selection */
271static char pcpu_chosen_alloc[16] __initdata;
272
273static int __init percpu_alloc_setup(char *str)
274{
275 strncpy(pcpu_chosen_alloc, str, sizeof(pcpu_chosen_alloc) - 1);
276 return 0;
277}
278early_param("percpu_alloc", percpu_alloc_setup);
279
280static inline void setup_percpu_segment(int cpu) 270static inline void setup_percpu_segment(int cpu)
281{ 271{
282#ifdef CONFIG_X86_32 272#ifdef CONFIG_X86_32
@@ -307,19 +297,17 @@ void __init setup_per_cpu_areas(void)
307 * each allocator for details. 297 * each allocator for details.
308 */ 298 */
309 ret = -EINVAL; 299 ret = -EINVAL;
310 if (strlen(pcpu_chosen_alloc)) { 300 if (pcpu_chosen_fc != PCPU_FC_AUTO) {
311 if (strcmp(pcpu_chosen_alloc, "page")) { 301 if (pcpu_chosen_fc != PCPU_FC_PAGE) {
312 if (!strcmp(pcpu_chosen_alloc, "lpage")) 302 if (pcpu_chosen_fc == PCPU_FC_LPAGE)
313 ret = setup_pcpu_lpage(static_size, true); 303 ret = setup_pcpu_lpage(static_size, true);
314 else if (!strcmp(pcpu_chosen_alloc, "embed"))
315 ret = setup_pcpu_embed(static_size, true);
316 else 304 else
317 pr_warning("PERCPU: unknown allocator %s " 305 ret = setup_pcpu_embed(static_size, true);
318 "specified\n", pcpu_chosen_alloc); 306
319 if (ret < 0) 307 if (ret < 0)
320 pr_warning("PERCPU: %s allocator failed (%zd), " 308 pr_warning("PERCPU: %s allocator failed (%zd), "
321 "falling back to page size\n", 309 "falling back to page size\n",
322 pcpu_chosen_alloc, ret); 310 pcpu_fc_names[pcpu_chosen_fc], ret);
323 } 311 }
324 } else { 312 } else {
325 ret = setup_pcpu_lpage(static_size, false); 313 ret = setup_pcpu_lpage(static_size, false);
diff --git a/include/linux/percpu.h b/include/linux/percpu.h
index e26788e0da4a..9be05cbe5ee0 100644
--- a/include/linux/percpu.h
+++ b/include/linux/percpu.h
@@ -59,6 +59,18 @@
59extern void *pcpu_base_addr; 59extern void *pcpu_base_addr;
60extern const int *pcpu_unit_map; 60extern const int *pcpu_unit_map;
61 61
62enum pcpu_fc {
63 PCPU_FC_AUTO,
64 PCPU_FC_EMBED,
65 PCPU_FC_PAGE,
66 PCPU_FC_LPAGE,
67
68 PCPU_FC_NR,
69};
70extern const char *pcpu_fc_names[PCPU_FC_NR];
71
72extern enum pcpu_fc pcpu_chosen_fc;
73
62typedef void * (*pcpu_fc_alloc_fn_t)(unsigned int cpu, size_t size); 74typedef void * (*pcpu_fc_alloc_fn_t)(unsigned int cpu, size_t size);
63typedef void (*pcpu_fc_free_fn_t)(void *ptr, size_t size); 75typedef void (*pcpu_fc_free_fn_t)(void *ptr, size_t size);
64typedef void (*pcpu_fc_populate_pte_fn_t)(unsigned long addr); 76typedef void (*pcpu_fc_populate_pte_fn_t)(unsigned long addr);
diff --git a/mm/percpu.c b/mm/percpu.c
index 7971997de310..7fb40bb1555a 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -1414,6 +1414,38 @@ size_t __init pcpu_setup_first_chunk(size_t static_size, size_t reserved_size,
1414 return pcpu_unit_size; 1414 return pcpu_unit_size;
1415} 1415}
1416 1416
1417const char *pcpu_fc_names[PCPU_FC_NR] __initdata = {
1418 [PCPU_FC_AUTO] = "auto",
1419 [PCPU_FC_EMBED] = "embed",
1420 [PCPU_FC_PAGE] = "page",
1421 [PCPU_FC_LPAGE] = "lpage",
1422};
1423
1424enum pcpu_fc pcpu_chosen_fc __initdata = PCPU_FC_AUTO;
1425
1426static int __init percpu_alloc_setup(char *str)
1427{
1428 if (0)
1429 /* nada */;
1430#ifdef CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK
1431 else if (!strcmp(str, "embed"))
1432 pcpu_chosen_fc = PCPU_FC_EMBED;
1433#endif
1434#ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK
1435 else if (!strcmp(str, "page"))
1436 pcpu_chosen_fc = PCPU_FC_PAGE;
1437#endif
1438#ifdef CONFIG_NEED_PER_CPU_LPAGE_FIRST_CHUNK
1439 else if (!strcmp(str, "lpage"))
1440 pcpu_chosen_fc = PCPU_FC_LPAGE;
1441#endif
1442 else
1443 pr_warning("PERCPU: unknown allocator %s specified\n", str);
1444
1445 return 0;
1446}
1447early_param("percpu_alloc", percpu_alloc_setup);
1448
1417static inline size_t pcpu_calc_fc_sizes(size_t static_size, 1449static inline size_t pcpu_calc_fc_sizes(size_t static_size,
1418 size_t reserved_size, 1450 size_t reserved_size,
1419 ssize_t *dyn_sizep) 1451 ssize_t *dyn_sizep)