aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/Kconfig8
-rw-r--r--mm/Makefile7
-rw-r--r--mm/percpu-km.c2
-rw-r--r--mm/percpu.c60
-rw-r--r--mm/percpu_up.c30
5 files changed, 66 insertions, 41 deletions
diff --git a/mm/Kconfig b/mm/Kconfig
index f4e516e9c37c..01a57447a410 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -301,3 +301,11 @@ config NOMMU_INITIAL_TRIM_EXCESS
301 of 1 says that all excess pages should be trimmed. 301 of 1 says that all excess pages should be trimmed.
302 302
303 See Documentation/nommu-mmap.txt for more information. 303 See Documentation/nommu-mmap.txt for more information.
304
305#
306# UP and nommu archs use km based percpu allocator
307#
308config NEED_PER_CPU_KM
309 depends on !SMP
310 bool
311 default y
diff --git a/mm/Makefile b/mm/Makefile
index 34b2546a9e37..f73f75a29f82 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -11,7 +11,7 @@ obj-y := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \
11 maccess.o page_alloc.o page-writeback.o \ 11 maccess.o page_alloc.o page-writeback.o \
12 readahead.o swap.o truncate.o vmscan.o shmem.o \ 12 readahead.o swap.o truncate.o vmscan.o shmem.o \
13 prio_tree.o util.o mmzone.o vmstat.o backing-dev.o \ 13 prio_tree.o util.o mmzone.o vmstat.o backing-dev.o \
14 page_isolation.o mm_init.o mmu_context.o \ 14 page_isolation.o mm_init.o mmu_context.o percpu.o \
15 $(mmu-y) 15 $(mmu-y)
16obj-y += init-mm.o 16obj-y += init-mm.o
17 17
@@ -36,11 +36,6 @@ obj-$(CONFIG_FAILSLAB) += failslab.o
36obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o 36obj-$(CONFIG_MEMORY_HOTPLUG) += memory_hotplug.o
37obj-$(CONFIG_FS_XIP) += filemap_xip.o 37obj-$(CONFIG_FS_XIP) += filemap_xip.o
38obj-$(CONFIG_MIGRATION) += migrate.o 38obj-$(CONFIG_MIGRATION) += migrate.o
39ifdef CONFIG_SMP
40obj-y += percpu.o
41else
42obj-y += percpu_up.o
43endif
44obj-$(CONFIG_QUICKLIST) += quicklist.o 39obj-$(CONFIG_QUICKLIST) += quicklist.o
45obj-$(CONFIG_CGROUP_MEM_RES_CTLR) += memcontrol.o page_cgroup.o 40obj-$(CONFIG_CGROUP_MEM_RES_CTLR) += memcontrol.o page_cgroup.o
46obj-$(CONFIG_MEMORY_FAILURE) += memory-failure.o 41obj-$(CONFIG_MEMORY_FAILURE) += memory-failure.o
diff --git a/mm/percpu-km.c b/mm/percpu-km.c
index df680855540a..7037bc73bfa4 100644
--- a/mm/percpu-km.c
+++ b/mm/percpu-km.c
@@ -27,7 +27,7 @@
27 * chunk size is not aligned. percpu-km code will whine about it. 27 * chunk size is not aligned. percpu-km code will whine about it.
28 */ 28 */
29 29
30#ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK 30#if defined(CONFIG_SMP) && defined(CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK)
31#error "contiguous percpu allocation is incompatible with paged first chunk" 31#error "contiguous percpu allocation is incompatible with paged first chunk"
32#endif 32#endif
33 33
diff --git a/mm/percpu.c b/mm/percpu.c
index 58c572b18b07..fa70122dfdd0 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -76,6 +76,7 @@
76#define PCPU_SLOT_BASE_SHIFT 5 /* 1-31 shares the same slot */ 76#define PCPU_SLOT_BASE_SHIFT 5 /* 1-31 shares the same slot */
77#define PCPU_DFL_MAP_ALLOC 16 /* start a map with 16 ents */ 77#define PCPU_DFL_MAP_ALLOC 16 /* start a map with 16 ents */
78 78
79#ifdef CONFIG_SMP
79/* default addr <-> pcpu_ptr mapping, override in asm/percpu.h if necessary */ 80/* default addr <-> pcpu_ptr mapping, override in asm/percpu.h if necessary */
80#ifndef __addr_to_pcpu_ptr 81#ifndef __addr_to_pcpu_ptr
81#define __addr_to_pcpu_ptr(addr) \ 82#define __addr_to_pcpu_ptr(addr) \
@@ -89,6 +90,11 @@
89 (unsigned long)pcpu_base_addr - \ 90 (unsigned long)pcpu_base_addr - \
90 (unsigned long)__per_cpu_start) 91 (unsigned long)__per_cpu_start)
91#endif 92#endif
93#else /* CONFIG_SMP */
94/* on UP, it's always identity mapped */
95#define __addr_to_pcpu_ptr(addr) (void __percpu *)(addr)
96#define __pcpu_ptr_to_addr(ptr) (void __force *)(ptr)
97#endif /* CONFIG_SMP */
92 98
93struct pcpu_chunk { 99struct pcpu_chunk {
94 struct list_head list; /* linked to pcpu_slot lists */ 100 struct list_head list; /* linked to pcpu_slot lists */
@@ -949,6 +955,7 @@ EXPORT_SYMBOL_GPL(free_percpu);
949 */ 955 */
950bool is_kernel_percpu_address(unsigned long addr) 956bool is_kernel_percpu_address(unsigned long addr)
951{ 957{
958#ifdef CONFIG_SMP
952 const size_t static_size = __per_cpu_end - __per_cpu_start; 959 const size_t static_size = __per_cpu_end - __per_cpu_start;
953 void __percpu *base = __addr_to_pcpu_ptr(pcpu_base_addr); 960 void __percpu *base = __addr_to_pcpu_ptr(pcpu_base_addr);
954 unsigned int cpu; 961 unsigned int cpu;
@@ -959,6 +966,8 @@ bool is_kernel_percpu_address(unsigned long addr)
959 if ((void *)addr >= start && (void *)addr < start + static_size) 966 if ((void *)addr >= start && (void *)addr < start + static_size)
960 return true; 967 return true;
961 } 968 }
969#endif
970 /* on UP, can't distinguish from other static vars, always false */
962 return false; 971 return false;
963} 972}
964 973
@@ -1066,6 +1075,8 @@ void __init pcpu_free_alloc_info(struct pcpu_alloc_info *ai)
1066 free_bootmem(__pa(ai), ai->__ai_size); 1075 free_bootmem(__pa(ai), ai->__ai_size);
1067} 1076}
1068 1077
1078#if defined(CONFIG_SMP) && (defined(CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK) || \
1079 defined(CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK))
1069/** 1080/**
1070 * pcpu_build_alloc_info - build alloc_info considering distances between CPUs 1081 * pcpu_build_alloc_info - build alloc_info considering distances between CPUs
1071 * @reserved_size: the size of reserved percpu area in bytes 1082 * @reserved_size: the size of reserved percpu area in bytes
@@ -1220,6 +1231,8 @@ static struct pcpu_alloc_info * __init pcpu_build_alloc_info(
1220 1231
1221 return ai; 1232 return ai;
1222} 1233}
1234#endif /* CONFIG_SMP && (CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK ||
1235 CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK) */
1223 1236
1224/** 1237/**
1225 * pcpu_dump_alloc_info - print out information about pcpu_alloc_info 1238 * pcpu_dump_alloc_info - print out information about pcpu_alloc_info
@@ -1363,7 +1376,9 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
1363 1376
1364 /* sanity checks */ 1377 /* sanity checks */
1365 PCPU_SETUP_BUG_ON(ai->nr_groups <= 0); 1378 PCPU_SETUP_BUG_ON(ai->nr_groups <= 0);
1379#ifdef CONFIG_SMP
1366 PCPU_SETUP_BUG_ON(!ai->static_size); 1380 PCPU_SETUP_BUG_ON(!ai->static_size);
1381#endif
1367 PCPU_SETUP_BUG_ON(!base_addr); 1382 PCPU_SETUP_BUG_ON(!base_addr);
1368 PCPU_SETUP_BUG_ON(ai->unit_size < size_sum); 1383 PCPU_SETUP_BUG_ON(ai->unit_size < size_sum);
1369 PCPU_SETUP_BUG_ON(ai->unit_size & ~PAGE_MASK); 1384 PCPU_SETUP_BUG_ON(ai->unit_size & ~PAGE_MASK);
@@ -1488,6 +1503,8 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
1488 return 0; 1503 return 0;
1489} 1504}
1490 1505
1506#ifdef CONFIG_SMP
1507
1491const char *pcpu_fc_names[PCPU_FC_NR] __initdata = { 1508const char *pcpu_fc_names[PCPU_FC_NR] __initdata = {
1492 [PCPU_FC_AUTO] = "auto", 1509 [PCPU_FC_AUTO] = "auto",
1493 [PCPU_FC_EMBED] = "embed", 1510 [PCPU_FC_EMBED] = "embed",
@@ -1758,8 +1775,9 @@ out_free_ar:
1758} 1775}
1759#endif /* CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK */ 1776#endif /* CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK */
1760 1777
1778#ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
1761/* 1779/*
1762 * Generic percpu area setup. 1780 * Generic SMP percpu area setup.
1763 * 1781 *
1764 * The embedding helper is used because its behavior closely resembles 1782 * The embedding helper is used because its behavior closely resembles
1765 * the original non-dynamic generic percpu area setup. This is 1783 * the original non-dynamic generic percpu area setup. This is
@@ -1770,7 +1788,6 @@ out_free_ar:
1770 * on the physical linear memory mapping which uses large page 1788 * on the physical linear memory mapping which uses large page
1771 * mappings on applicable archs. 1789 * mappings on applicable archs.
1772 */ 1790 */
1773#ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
1774unsigned long __per_cpu_offset[NR_CPUS] __read_mostly; 1791unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
1775EXPORT_SYMBOL(__per_cpu_offset); 1792EXPORT_SYMBOL(__per_cpu_offset);
1776 1793
@@ -1799,13 +1816,48 @@ void __init setup_per_cpu_areas(void)
1799 PERCPU_DYNAMIC_RESERVE, PAGE_SIZE, NULL, 1816 PERCPU_DYNAMIC_RESERVE, PAGE_SIZE, NULL,
1800 pcpu_dfl_fc_alloc, pcpu_dfl_fc_free); 1817 pcpu_dfl_fc_alloc, pcpu_dfl_fc_free);
1801 if (rc < 0) 1818 if (rc < 0)
1802 panic("Failed to initialized percpu areas."); 1819 panic("Failed to initialize percpu areas.");
1803 1820
1804 delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start; 1821 delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
1805 for_each_possible_cpu(cpu) 1822 for_each_possible_cpu(cpu)
1806 __per_cpu_offset[cpu] = delta + pcpu_unit_offsets[cpu]; 1823 __per_cpu_offset[cpu] = delta + pcpu_unit_offsets[cpu];
1807} 1824}
1808#endif /* CONFIG_HAVE_SETUP_PER_CPU_AREA */ 1825#endif /* CONFIG_HAVE_SETUP_PER_CPU_AREA */
1826
1827#else /* CONFIG_SMP */
1828
1829/*
1830 * UP percpu area setup.
1831 *
1832 * UP always uses km-based percpu allocator with identity mapping.
1833 * Static percpu variables are indistinguishable from the usual static
1834 * variables and don't require any special preparation.
1835 */
1836void __init setup_per_cpu_areas(void)
1837{
1838 const size_t unit_size =
1839 roundup_pow_of_two(max_t(size_t, PCPU_MIN_UNIT_SIZE,
1840 PERCPU_DYNAMIC_RESERVE));
1841 struct pcpu_alloc_info *ai;
1842 void *fc;
1843
1844 ai = pcpu_alloc_alloc_info(1, 1);
1845 fc = __alloc_bootmem(unit_size, PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
1846 if (!ai || !fc)
1847 panic("Failed to allocate memory for percpu areas.");
1848
1849 ai->dyn_size = unit_size;
1850 ai->unit_size = unit_size;
1851 ai->atom_size = unit_size;
1852 ai->alloc_size = unit_size;
1853 ai->groups[0].nr_units = 1;
1854 ai->groups[0].cpu_map[0] = 0;
1855
1856 if (pcpu_setup_first_chunk(ai, fc) < 0)
1857 panic("Failed to initialize percpu areas.");
1858}
1859
1860#endif /* CONFIG_SMP */
1809 1861
1810/* 1862/*
1811 * First and reserved chunks are initialized with temporary allocation 1863 * First and reserved chunks are initialized with temporary allocation
diff --git a/mm/percpu_up.c b/mm/percpu_up.c
deleted file mode 100644
index db884fae5721..000000000000
--- a/mm/percpu_up.c
+++ /dev/null
@@ -1,30 +0,0 @@
1/*
2 * mm/percpu_up.c - dummy percpu memory allocator implementation for UP
3 */
4
5#include <linux/module.h>
6#include <linux/percpu.h>
7#include <linux/slab.h>
8
9void __percpu *__alloc_percpu(size_t size, size_t align)
10{
11 /*
12 * Can't easily make larger alignment work with kmalloc. WARN
13 * on it. Larger alignment should only be used for module
14 * percpu sections on SMP for which this path isn't used.
15 */
16 WARN_ON_ONCE(align > SMP_CACHE_BYTES);
17 return (void __percpu __force *)kzalloc(size, GFP_KERNEL);
18}
19EXPORT_SYMBOL_GPL(__alloc_percpu);
20
21void free_percpu(void __percpu *p)
22{
23 kfree(this_cpu_ptr(p));
24}
25EXPORT_SYMBOL_GPL(free_percpu);
26
27phys_addr_t per_cpu_ptr_to_phys(void *addr)
28{
29 return __pa(addr);
30}