aboutsummaryrefslogtreecommitdiffstats
path: root/mm/percpu.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-01-23 01:45:46 -0500
committerDavid S. Miller <davem@davemloft.net>2010-01-23 01:45:46 -0500
commit6be325719b3e54624397e413efd4b33a997e55a3 (patch)
tree57f321a56794cab2222e179b16731e0d76a4a68a /mm/percpu.c
parent26d92f9276a56d55511a427fb70bd70886af647a (diff)
parent92dcffb916d309aa01778bf8963a6932e4014d07 (diff)
Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Diffstat (limited to 'mm/percpu.c')
-rw-r--r--mm/percpu.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/mm/percpu.c b/mm/percpu.c
index 5adfc268b408..083e7c91e5f6 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -46,8 +46,6 @@
46 * 46 *
47 * To use this allocator, arch code should do the followings. 47 * To use this allocator, arch code should do the followings.
48 * 48 *
49 * - drop CONFIG_HAVE_LEGACY_PER_CPU_AREA
50 *
51 * - define __addr_to_pcpu_ptr() and __pcpu_ptr_to_addr() to translate 49 * - define __addr_to_pcpu_ptr() and __pcpu_ptr_to_addr() to translate
52 * regular address to percpu pointer and back if they need to be 50 * regular address to percpu pointer and back if they need to be
53 * different from the default 51 * different from the default
@@ -74,6 +72,7 @@
74#include <asm/cacheflush.h> 72#include <asm/cacheflush.h>
75#include <asm/sections.h> 73#include <asm/sections.h>
76#include <asm/tlbflush.h> 74#include <asm/tlbflush.h>
75#include <asm/io.h>
77 76
78#define PCPU_SLOT_BASE_SHIFT 5 /* 1-31 shares the same slot */ 77#define PCPU_SLOT_BASE_SHIFT 5 /* 1-31 shares the same slot */
79#define PCPU_DFL_MAP_ALLOC 16 /* start a map with 16 ents */ 78#define PCPU_DFL_MAP_ALLOC 16 /* start a map with 16 ents */
@@ -1272,7 +1271,7 @@ static void pcpu_reclaim(struct work_struct *work)
1272 */ 1271 */
1273void free_percpu(void *ptr) 1272void free_percpu(void *ptr)
1274{ 1273{
1275 void *addr = __pcpu_ptr_to_addr(ptr); 1274 void *addr;
1276 struct pcpu_chunk *chunk; 1275 struct pcpu_chunk *chunk;
1277 unsigned long flags; 1276 unsigned long flags;
1278 int off; 1277 int off;
@@ -1280,6 +1279,8 @@ void free_percpu(void *ptr)
1280 if (!ptr) 1279 if (!ptr)
1281 return; 1280 return;
1282 1281
1282 addr = __pcpu_ptr_to_addr(ptr);
1283
1283 spin_lock_irqsave(&pcpu_lock, flags); 1284 spin_lock_irqsave(&pcpu_lock, flags);
1284 1285
1285 chunk = pcpu_chunk_addr_search(addr); 1286 chunk = pcpu_chunk_addr_search(addr);
@@ -1302,6 +1303,27 @@ void free_percpu(void *ptr)
1302} 1303}
1303EXPORT_SYMBOL_GPL(free_percpu); 1304EXPORT_SYMBOL_GPL(free_percpu);
1304 1305
1306/**
1307 * per_cpu_ptr_to_phys - convert translated percpu address to physical address
1308 * @addr: the address to be converted to physical address
1309 *
1310 * Given @addr which is dereferenceable address obtained via one of
1311 * percpu access macros, this function translates it into its physical
1312 * address. The caller is responsible for ensuring @addr stays valid
1313 * until this function finishes.
1314 *
1315 * RETURNS:
1316 * The physical address for @addr.
1317 */
1318phys_addr_t per_cpu_ptr_to_phys(void *addr)
1319{
1320 if ((unsigned long)addr < VMALLOC_START ||
1321 (unsigned long)addr >= VMALLOC_END)
1322 return __pa(addr);
1323 else
1324 return page_to_phys(vmalloc_to_page(addr));
1325}
1326
1305static inline size_t pcpu_calc_fc_sizes(size_t static_size, 1327static inline size_t pcpu_calc_fc_sizes(size_t static_size,
1306 size_t reserved_size, 1328 size_t reserved_size,
1307 ssize_t *dyn_sizep) 1329 ssize_t *dyn_sizep)