diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 11 | ||||
-rw-r--r-- | arch/x86/kernel/setup_percpu.c | 24 | ||||
-rw-r--r-- | include/linux/percpu.h | 12 | ||||
-rw-r--r-- | mm/percpu.c | 32 |
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 */ | ||
271 | static char pcpu_chosen_alloc[16] __initdata; | ||
272 | |||
273 | static int __init percpu_alloc_setup(char *str) | ||
274 | { | ||
275 | strncpy(pcpu_chosen_alloc, str, sizeof(pcpu_chosen_alloc) - 1); | ||
276 | return 0; | ||
277 | } | ||
278 | early_param("percpu_alloc", percpu_alloc_setup); | ||
279 | |||
280 | static inline void setup_percpu_segment(int cpu) | 270 | static 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 @@ | |||
59 | extern void *pcpu_base_addr; | 59 | extern void *pcpu_base_addr; |
60 | extern const int *pcpu_unit_map; | 60 | extern const int *pcpu_unit_map; |
61 | 61 | ||
62 | enum pcpu_fc { | ||
63 | PCPU_FC_AUTO, | ||
64 | PCPU_FC_EMBED, | ||
65 | PCPU_FC_PAGE, | ||
66 | PCPU_FC_LPAGE, | ||
67 | |||
68 | PCPU_FC_NR, | ||
69 | }; | ||
70 | extern const char *pcpu_fc_names[PCPU_FC_NR]; | ||
71 | |||
72 | extern enum pcpu_fc pcpu_chosen_fc; | ||
73 | |||
62 | typedef void * (*pcpu_fc_alloc_fn_t)(unsigned int cpu, size_t size); | 74 | typedef void * (*pcpu_fc_alloc_fn_t)(unsigned int cpu, size_t size); |
63 | typedef void (*pcpu_fc_free_fn_t)(void *ptr, size_t size); | 75 | typedef void (*pcpu_fc_free_fn_t)(void *ptr, size_t size); |
64 | typedef void (*pcpu_fc_populate_pte_fn_t)(unsigned long addr); | 76 | typedef 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 | ||
1417 | const 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 | |||
1424 | enum pcpu_fc pcpu_chosen_fc __initdata = PCPU_FC_AUTO; | ||
1425 | |||
1426 | static 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 | } | ||
1447 | early_param("percpu_alloc", percpu_alloc_setup); | ||
1448 | |||
1417 | static inline size_t pcpu_calc_fc_sizes(size_t static_size, | 1449 | static 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) |