at v2.6.24 3.7 kB view raw
1/* 2 * linux/mm/allocpercpu.c 3 * 4 * Separated from slab.c August 11, 2006 Christoph Lameter <clameter@sgi.com> 5 */ 6#include <linux/mm.h> 7#include <linux/module.h> 8 9/** 10 * percpu_depopulate - depopulate per-cpu data for given cpu 11 * @__pdata: per-cpu data to depopulate 12 * @cpu: depopulate per-cpu data for this cpu 13 * 14 * Depopulating per-cpu data for a cpu going offline would be a typical 15 * use case. You need to register a cpu hotplug handler for that purpose. 16 */ 17void percpu_depopulate(void *__pdata, int cpu) 18{ 19 struct percpu_data *pdata = __percpu_disguise(__pdata); 20 21 kfree(pdata->ptrs[cpu]); 22 pdata->ptrs[cpu] = NULL; 23} 24EXPORT_SYMBOL_GPL(percpu_depopulate); 25 26/** 27 * percpu_depopulate_mask - depopulate per-cpu data for some cpu's 28 * @__pdata: per-cpu data to depopulate 29 * @mask: depopulate per-cpu data for cpu's selected through mask bits 30 */ 31void __percpu_depopulate_mask(void *__pdata, cpumask_t *mask) 32{ 33 int cpu; 34 for_each_cpu_mask(cpu, *mask) 35 percpu_depopulate(__pdata, cpu); 36} 37EXPORT_SYMBOL_GPL(__percpu_depopulate_mask); 38 39/** 40 * percpu_populate - populate per-cpu data for given cpu 41 * @__pdata: per-cpu data to populate further 42 * @size: size of per-cpu object 43 * @gfp: may sleep or not etc. 44 * @cpu: populate per-data for this cpu 45 * 46 * Populating per-cpu data for a cpu coming online would be a typical 47 * use case. You need to register a cpu hotplug handler for that purpose. 48 * Per-cpu object is populated with zeroed buffer. 49 */ 50void *percpu_populate(void *__pdata, size_t size, gfp_t gfp, int cpu) 51{ 52 struct percpu_data *pdata = __percpu_disguise(__pdata); 53 int node = cpu_to_node(cpu); 54 55 BUG_ON(pdata->ptrs[cpu]); 56 if (node_online(node)) 57 pdata->ptrs[cpu] = kmalloc_node(size, gfp|__GFP_ZERO, node); 58 else 59 pdata->ptrs[cpu] = kzalloc(size, gfp); 60 return pdata->ptrs[cpu]; 61} 62EXPORT_SYMBOL_GPL(percpu_populate); 63 64/** 65 * percpu_populate_mask - populate per-cpu data for more cpu's 66 * @__pdata: per-cpu data to populate further 67 * @size: size of per-cpu object 68 * @gfp: may sleep or not etc. 69 * @mask: populate per-cpu data for cpu's selected through mask bits 70 * 71 * Per-cpu objects are populated with zeroed buffers. 72 */ 73int __percpu_populate_mask(void *__pdata, size_t size, gfp_t gfp, 74 cpumask_t *mask) 75{ 76 cpumask_t populated = CPU_MASK_NONE; 77 int cpu; 78 79 for_each_cpu_mask(cpu, *mask) 80 if (unlikely(!percpu_populate(__pdata, size, gfp, cpu))) { 81 __percpu_depopulate_mask(__pdata, &populated); 82 return -ENOMEM; 83 } else 84 cpu_set(cpu, populated); 85 return 0; 86} 87EXPORT_SYMBOL_GPL(__percpu_populate_mask); 88 89/** 90 * percpu_alloc_mask - initial setup of per-cpu data 91 * @size: size of per-cpu object 92 * @gfp: may sleep or not etc. 93 * @mask: populate per-data for cpu's selected through mask bits 94 * 95 * Populating per-cpu data for all online cpu's would be a typical use case, 96 * which is simplified by the percpu_alloc() wrapper. 97 * Per-cpu objects are populated with zeroed buffers. 98 */ 99void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask) 100{ 101 void *pdata = kzalloc(sizeof(struct percpu_data), gfp); 102 void *__pdata = __percpu_disguise(pdata); 103 104 if (unlikely(!pdata)) 105 return NULL; 106 if (likely(!__percpu_populate_mask(__pdata, size, gfp, mask))) 107 return __pdata; 108 kfree(pdata); 109 return NULL; 110} 111EXPORT_SYMBOL_GPL(__percpu_alloc_mask); 112 113/** 114 * percpu_free - final cleanup of per-cpu data 115 * @__pdata: object to clean up 116 * 117 * We simply clean up any per-cpu object left. No need for the client to 118 * track and specify through a bis mask which per-cpu objects are to free. 119 */ 120void percpu_free(void *__pdata) 121{ 122 if (unlikely(!__pdata)) 123 return; 124 __percpu_depopulate_mask(__pdata, &cpu_possible_map); 125 kfree(__percpu_disguise(__pdata)); 126} 127EXPORT_SYMBOL_GPL(percpu_free);