Unlimited per-cpu allocation
Subsystems (6)
PATCH 1/1 Unlimited per-cpu allocation
This goes back to the linked-list of blocks approach I used initially, with the trick that layout-sensitive (ie. NUMA-aware) archs can replace new_percpumem, free_percpumem and initial_percpumem with their own allocators (results must be virtually contiguous).
Limitations:
1) There's a limit on how big each allocation can be, currently 1 page. More than that is probably silly at this stage.
2) Allocator is slow, simple, and sleeps. If you want to start allocating every open(), or in interrupts, it's going to need to be beefed up: for the moment, I expect 4 or 8 byte allocs to be the norm, so fragmentation shouldn't be too bad either.
3) IA64. It could allocate its 64k in initial_percpumem(), and then fail any calls to new_percpumem(). This won't be a problem at the moment, but hard choices have to be made if more than 64k of per-cpu memory is desirable here.
Looking at the users, I made the allocator zero the mem, too, which deserved a rename from "kmalloc_percpu" to "alloc_percpu".
Finally, it's tempting to remove the macros and just use "__percpu":
Linus' address-space markings might be sufficient to catch direct references to per-cpu vars, and archs really don't have much flexibility of implementation anymore (ie. __thread doesn't play well with dynamic allocation).
Feedback welcome,
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
Name: Unlimited per-cpu allocation
Author: Rusty Russell
Status: Tested on 2.5.69-bk8
D: This patch allows an unlimited number of per-cpu allocations. It
D: is more complex than the "simply allocate a big chunk up front"
D: approach of Misc/kmalloc_percpu.patch.gz, but it has a hook for
D: NUMA-aware allocations (default is alloc_bootmem then vmalloc
D: based).
D:
D: Given the interface change, kmalloc_percpu is renamed to
D: alloc_percpu, and zeros memory (most callers want that, and it's
D: not completely trivial), and kfree_percpu renamed to free_percpu.
include/asm-generic/percpu.h +4 -12
@@ -2,7 +2,6 @@#define _ASM_GENERIC_PERCPU_H_#include <linux/compiler.h> -#define __GENERIC_PER_CPU#ifdef CONFIG_SMP extern unsigned long __per_cpu_offset[NR_CPUS ];
@@ -17,18 +16,11 @@ extern unsigned long __per_cpu_offset[NR#define per_cpu (var, cpu) (*RELOC_HIDE(&var##__per_cpu, __per_cpu_offset[cpu]))#define __get_cpu_var (var) per_cpu(var, smp_processor_id()) -#else /* ! SMP */ - -/* Can't define per-cpu variables in modules. Sorry --RR */ -#ifndef MODULE -#define DEFINE_PER_CPU (type, name) \ - __typeof__(type) name##__per_cpu -#endif - -#define per_cpu (var, cpu) ((void)cpu, var##__per_cpu) -#define __get_cpu_var (var) var##__per_cpu +#define per_cpu_ptr (ptr, cpu) ((__typeof__(ptr))(RELOC_HIDE(ptr, __per_cpu_offset[cpu]))) +#define __get_cpu_ptr (var) per_cpu_ptr(ptr, smp_processor_id()) -#endif /* SMP */ +void setup_per_cpu_areas (void ); +#endif /* SMP */ #define DECLARE_PER_CPU (type, name) extern __typeof__(type) name##__per_cpu
include/asm-i386/percpu.h +1 -0
@@ -2,5 +2,6 @@#define __ARCH_I386_PERCPU__#include <asm-generic/percpu.h> +#define __NEED_PERCPU_ALLOC#endif /* __ARCH_I386_PERCPU__ */
include/linux/genhd.h +1 -2
@@ -160,10 +160,9 @@ static inline void disk_stat_set_all(str#ifdef CONFIG_SMP static inline int init_disk_stats (struct gendisk *disk) { - disk->dkstats =kmalloc_percpu (sizeof (struct disk_stats ),GFP_KERNEL ); + disk->dkstats = alloc_percpu(struct disk_stats);if (!disk->dkstats)return 0 ; -disk_stat_set_all (disk,0 );return 1 ; }
include/linux/percpu.h +41 -46
112 lines not on this page · raw message
include/net/ipv6.h +1 -1
@@ -145,7 +145,7 @@ extern atomic_t inet6_sock_nr;int snmp6_register_dev (struct inet6_dev *idev);int snmp6_unregister_dev (struct inet6_dev *idev); -int snmp6_mib_init (void *ptr[2 ],size_t mibsize); +int snmp6_mib_init (void *ptr[2 ],size_t mibsize,size_t mibalign);void snmp6_mib_free (void *ptr[2 ]);struct ip6_ra_chain
init/main.c +0 -24
@@ -306,30 +306,6 @@ static inline void smp_prepare_cpus(unsi#else -#ifdef __GENERIC_PER_CPU -unsigned long __per_cpu_offset[NR_CPUS ]; - -static void __init setup_per_cpu_areas (void ) -{ -unsigned long size, i; -char *ptr; -/* Created by linker magic */ -extern char __per_cpu_start[], __per_cpu_end[]; - -/* Copy section for each CPU (we discard the original) */ - size =ALIGN (__per_cpu_end - __per_cpu_start,SMP_CACHE_BYTES ); -if (!size) -return ; - - ptr =alloc_bootmem (size *NR_CPUS ); - -for (i =0 ; i <NR_CPUS ; i++, ptr += size) { - __per_cpu_offset[i] = ptr - __per_cpu_start; -memcpy (ptr, __per_cpu_start, size); - } -} -#endif /* !__GENERIC_PER_CPU */ -/* Called by boot processor to activate the rest. */ static void __init smp_init (void ) {
kernel/ksyms.c +2 -2
@@ -98,8 +98,8 @@ EXPORT_SYMBOL(remove_shrinker);EXPORT_SYMBOL (kmalloc);EXPORT_SYMBOL (kfree);#ifdef CONFIG_SMP -EXPORT_SYMBOL (kmalloc_percpu); -EXPORT_SYMBOL (kfree_percpu); +EXPORT_SYMBOL (__alloc_percpu); +EXPORT_SYMBOL (free_percpu);EXPORT_SYMBOL (percpu_counter_mod);#endif EXPORT_SYMBOL (vfree);
mm/Makefile +1 -0
@@ -12,3 +12,4 @@ obj-y := bootmem.o filemap.o mempool.o slab.o swap.o truncate.o vcache.o vmscan.o $(mmu-y) obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o +obj-$(CONFIG_SMP) += percpu.o
mm/percpu.c +442 -0
442 lines not on this page · raw message
mm/slab.c +0 -70
82 lines not on this page · raw message
net/ipv4/af_inet.c +10 -40
62 lines not on this page · raw message
net/ipv4/route.c +2 -9
@@ -2692,16 +2692,9 @@ int __init ip_rt_init(void) ipv4_dst_ops.gc_thresh = (rt_hash_mask +1 ); ip_rt_max_size = (rt_hash_mask +1 ) *16 ; - rt_cache_stat =kmalloc_percpu (sizeof (struct rt_cache_stat ), -GFP_KERNEL ); + rt_cache_stat = alloc_percpu(struct rt_cache_stat);if (!rt_cache_stat) goto out_enomem1; -for (i =0 ; i <NR_CPUS ; i++) { -if (cpu_possible (i)) { -memset (per_cpu_ptr (rt_cache_stat, i),0 , -sizeof (struct rt_cache_stat )); - } - }devinet_init ();ip_fib_init ();
@@ -2737,7 +2730,7 @@ int __init ip_rt_init(void) out:return rc; out_enomem: -kfree_percpu (rt_cache_stat); +free_percpu (rt_cache_stat); out_enomem1: rc = -ENOMEM ; goto out;
net/ipv6/af_inet6.c +12 -16
@@ -637,32 +637,25 @@ inet6_unregister_protosw(struct inet_pro }int -snmp6_mib_init (void *ptr[2 ],size_t mibsize) +snmp6_mib_init (void *ptr[2 ],size_t mibsize,size_t mibalign) {int i;if (ptr ==NULL )return -EINVAL ; - ptr[0 ] =kmalloc_percpu (mibsize,GFP_KERNEL ); + ptr[0 ] =__alloc_percpu (mibsize, mibalign);if (!ptr[0 ]) goto err0; - ptr[1 ] =kmalloc_percpu (mibsize,GFP_KERNEL ); + ptr[1 ] =__alloc_percpu (mibsize, mibalign);if (!ptr[1 ]) goto err1; -/* Zero percpu version of the mibs */ -for (i =0 ; i <NR_CPUS ; i++) { -if (cpu_possible (i)) { -memset (per_cpu_ptr (ptr[0 ], i),0 , mibsize); -memset (per_cpu_ptr (ptr[1 ], i),0 , mibsize); - } - }return 0 ; err1: -kfree_percpu (ptr[0 ]); +free_percpu (ptr[0 ]); ptr[0 ] =NULL ; err0:return -ENOMEM ;
@@ -673,18 +666,21 @@ snmp6_mib_free(void *ptr[2]) {if (ptr ==NULL )return ; -kfree_percpu (ptr[0 ]); -kfree_percpu (ptr[1 ]); +free_percpu (ptr[0 ]); +free_percpu (ptr[1 ]); ptr[0 ] = ptr[1 ] =NULL ; }static int __init init_ipv6_mibs (void ) { -if (snmp6_mib_init ((void **)ipv6_statistics,sizeof (struct ipv6_mib )) <0 ) +if (snmp6_mib_init ((void **)ipv6_statistics,sizeof (struct ipv6_mib ), + __alignof__(struct ipv6_mib )) <0 ) goto err_ip_mib; -if (snmp6_mib_init ((void **)icmpv6_statistics,sizeof (struct icmpv6_mib )) <0 ) +if (snmp6_mib_init ((void **)icmpv6_statistics,sizeof (struct icmpv6_mib ), + __alignof__(struct ipv6_mib )) <0 ) goto err_icmp_mib; -if (snmp6_mib_init ((void **)udp_stats_in6,sizeof (struct udp_mib )) <0 ) +if (snmp6_mib_init ((void **)udp_stats_in6,sizeof (struct udp_mib ), + __alignof__(struct ipv6_mib )) <0 ) goto err_udp_mib;return 0 ;
net/ipv6/proc.c +2 -1
@@ -228,7 +228,8 @@ int snmp6_register_dev(struct inet6_devif (!idev || !idev->dev)return -EINVAL ; -if (snmp6_mib_init ((void **)idev->stats.icmpv6,sizeof (struct icmpv6_mib )) <0 ) +if (snmp6_mib_init ((void **)idev->stats.icmpv6,sizeof (struct icmpv6_mib ), + __alignof__(struct ipv6_mib )) <0 ) goto err_icmp;#ifdef CONFIG_PROC_FS
net/sctp/protocol.c +5 -17
@@ -880,34 +880,22 @@ static int __init init_sctp_mibs(void) {int i; - sctp_statistics[0 ] =kmalloc_percpu (sizeof (struct sctp_mib ), -GFP_KERNEL ); + sctp_statistics[0] = alloc_percpu(struct sctp_mib);if (!sctp_statistics[0 ])return -ENOMEM ; - sctp_statistics[1 ] =kmalloc_percpu (sizeof (struct sctp_mib ), -GFP_KERNEL ); + sctp_statistics[1] = alloc_percpu(struct sctp_mib);if (!sctp_statistics[1 ]) { -kfree_percpu (sctp_statistics[0 ]); +free_percpu (sctp_statistics[0 ]);return -ENOMEM ; } - -/* Zero all percpu versions of the mibs */ -for (i =0 ; i <NR_CPUS ; i++) { -if (cpu_possible (i)) { -memset (per_cpu_ptr (sctp_statistics[0 ], i),0 , -sizeof (struct sctp_mib )); -memset (per_cpu_ptr (sctp_statistics[1 ], i),0 , -sizeof (struct sctp_mib )); - } - }return 0 ; }static void cleanup_sctp_mibs (void ) { -kfree_percpu (sctp_statistics[0 ]); -kfree_percpu (sctp_statistics[1 ]); +free_percpu (sctp_statistics[0 ]); +free_percpu (sctp_statistics[1 ]); }/* Initialize the universe into something sensible. */
From: Rusty Russell <[email protected]>
Date: Fri, 16 May 2003 15:30:36 +1000
D: This patch allows an unlimited number of per-cpu allocations.
Except, of course, on IA64. Maybe I missed the end of some thread, but I thought we had all agreed that this kind of limitation was a showstopper.
In message <[email protected]> you write:
Quoted 8 lines
From: Rusty Russell <[email protected]>
Date: Fri, 16 May 2003 15:30:36 +1000D: This patch allows an unlimited number of per-cpu allocations.
Except, of course, on IA64. Maybe I missed the end of some thread, but I thought we had all agreed that this kind of limitation was a showstopper.
Not breaking IA64 is nice, but it's not an inherent "IA64 can't do it" thing.
IA64 could just use the generic mechanism, like everyone else. But they do the tricky 64k mapping thing. As I pointed out, maybe their decision would have to be rethought if that proves inadaquate.
Cheers,
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
From: Rusty Russell <[email protected]>
Date: Sat, 17 May 2003 11:58:55 +1000
IA64 could just use the generic mechanism, like everyone else. But they do the tricky 64k mapping thing. As I pointed out, maybe their decision would have to be rethought if that proves inadaquate.
But we should also give them the option to implement module percpu data using indirect buffers.
In message <[email protected]> you write:
Quoted 9 lines
From: Rusty Russell <[email protected]>
Date: Sat, 17 May 2003 11:58:55 +1000IA64 could just use the generic mechanism, like everyone else. But they do the tricky 64k mapping thing. As I pointed out, maybe their decision would have to be rethought if that proves inadaquate.
But we should also give them the option to implement module percpu data using indirect buffers.
Well, AFAICT that can't be done realistically: the module percpu mechanisms must be the same as the core ones (you can't hide the difference under #ifdef MODULE, either, since they can be handed about).
You can do TLS-style tricks (with toolchain support), but we don't need to, and almost certainly don't want to.
The question is not whether we need this allocator to implement percpu inside modules (we do), but whether it can also be used for kmalloc_percpu.
Hope that clarifies,
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
From: Rusty Russell <[email protected]>
Date: Sat, 17 May 2003 13:07:21 +1000
The question is not whether we need this allocator to implement percpu inside modules (we do), but whether it can also be used for kmalloc_percpu.
I hadn't caught this distinction, and thus I misunderstood what was going on here. Thanks for clarifying.
In message <[email protected]> you write:
Quoted 9 lines
From: Rusty Russell <[email protected]>
Date: Sat, 17 May 2003 13:07:21 +1000The question is not whether we need this allocator to implement percpu inside modules (we do), but whether it can also be used for
kmalloc_percpu.I hadn't caught this distinction, and thus I misunderstood what was going on here. Thanks for clarifying.
Right, that makes sense. If we leave the current implementation as a "fix it later" thing, I think it's worth changing the interface at least as per the patch below, so that if we change in future we haven't promised everyone cacheline alignment.
Andrew? Linus?
Rusty.
--
Anyone who quotes me in their sig is an idiot. -- Rusty Russell.
Name: Change kmalloc_percpu interface
Author: Rusty Russell
Status: Experimental
D: kmalloc_percpu is renamed to alloc_percpu, takes a type
D: (__alloc_percpu takes an alignment as well) and zeros memory (most
D: callers want that, and it's not completely trivial), and
D: kfree_percpu renamed to free_percpu.
include/linux/genhd.h +2 -3
@@ -160,16 +160,15 @@ static inline void disk_stat_set_all(str#ifdef CONFIG_SMP static inline int init_disk_stats (struct gendisk *disk) { - disk->dkstats =kmalloc_percpu (sizeof (struct disk_stats ),GFP_KERNEL ); + disk->dkstats = alloc_percpu(struct disk_stats);if (!disk->dkstats)return 0 ; -disk_stat_set_all (disk,0 );return 1 ; }static inline void free_disk_stats (struct gendisk *disk) { -kfree_percpu (disk->dkstats); +free_percpu (disk->dkstats); }#else /* CONFIG_SMP */ static inline int init_disk_stats (struct gendisk *disk)
include/linux/percpu.h +16 -9
@@ -1,7 +1,7 @@#ifndef __LINUX_PERCPU_H#define __LINUX_PERCPU_H#include <linux/spinlock.h> /* For preempt_disable() */ -#include <linux/slab.h> /* For kmalloc_percpu() */ +#include <linux/slab.h> /* For kmalloc() */ #include <asm/percpu.h> /* Must be an lvalue. */
@@ -17,7 +17,7 @@ struct percpu_data {/* * Use this to get to a cpu's version of the per-cpu object allocated using -* kmalloc_percpu. If you want to get "this cpu's version", maybe you want +* alloc_percpu. If you want to get "this cpu's version", maybe you want * to use get_cpu_ptr... */ #define per_cpu_ptr (ptr, cpu) \
@@ -26,19 +26,22 @@ struct percpu_data { (__typeof__ (ptr ))__p->ptrs[(cpu)]; \ }) -extern void *kmalloc_percpu (size_t size,int flags); -extern void kfree_percpu (const void *); +extern void *__alloc_percpu (size_t size,int flags); +extern void free_percpu (const void *);extern void kmalloc_percpu_init (void );#else /* CONFIG_SMP */ #define per_cpu_ptr (ptr, cpu) (ptr) -static inline void *kmalloc_percpu (size_t size,int flags) +static inline void *__alloc_percpu (size_t size,size_t align) { -return (kmalloc (size, flags)); +void *ret =kmalloc (size,GFP_KERNEL ); +if (ret) +memset (ret,0 , size); +return ret; } -static inline void kfree_percpu (const void *ptr) +static inline void free_percpu (const void *ptr) {kfree (ptr); }
@@ -46,9 +49,13 @@ static inline void kmalloc_percpu_init(v#endif /* CONFIG_SMP */ +/* Simple wrapper for the common case: zeros memory. */ +#define alloc_percpu (type) \ + ((type *)(__alloc_percpu(sizeof(type), __alignof__(type)))) +/* -* Use these with kmalloc_percpu. If -* 1. You want to operate on memory allocated by kmalloc_percpu (dereference +* Use these with alloc_percpu. If +* 1. You want to operate on memory allocated by alloc_percpu (dereference * and read/modify/write) AND * 2. You want "this cpu's version" of the object AND * 3. You want to do this safely since:
include/net/ipv6.h +1 -1
@@ -145,7 +145,7 @@ extern atomic_t inet6_sock_nr;int snmp6_register_dev (struct inet6_dev *idev);int snmp6_unregister_dev (struct inet6_dev *idev); -int snmp6_mib_init (void *ptr[2 ],size_t mibsize); +int snmp6_mib_init (void *ptr[2 ],size_t mibsize,size_t mibalign);void snmp6_mib_free (void *ptr[2 ]);struct ip6_ra_chain
kernel/ksyms.c +2 -2
@@ -98,8 +98,8 @@ EXPORT_SYMBOL(remove_shrinker);EXPORT_SYMBOL (kmalloc);EXPORT_SYMBOL (kfree);#ifdef CONFIG_SMP -EXPORT_SYMBOL (kmalloc_percpu); -EXPORT_SYMBOL (kfree_percpu); +EXPORT_SYMBOL (__alloc_percpu); +EXPORT_SYMBOL (free_percpu);EXPORT_SYMBOL (percpu_counter_mod);#endif EXPORT_SYMBOL (vfree);
mm/Makefile +1 -0
@@ -12,3 +12,4 @@ obj-y := bootmem.o filemap.o mempool.o slab.o swap.o truncate.o vcache.o vmscan.o $(mmu-y) obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o +obj-$(CONFIG_SMP) += percpu.o
mm/slab.c +11 -18
@@ -1939,26 +1939,18 @@ void * kmalloc (size_t size, int flags)#ifdef CONFIG_SMP /** -* kmalloc_percpu - allocate one copy of the object for every present -* cpu in the system. +* __alloc_percpu - allocate one copy of the object for every present +* cpu in the system, zeroing them. * Objects should be dereferenced using per_cpu_ptr/get_cpu_ptr * macros only. * * @size: how many bytes of memory are required. -* @flags: the type of memory to allocate. -* The @flags argument may be one of: -* -* %GFP_USER - Allocate memory on behalf of user. May sleep. -* -* %GFP_KERNEL - Allocate normal kernel ram. May sleep. -* -* %GFP_ATOMIC - Allocation will not sleep. Use inside interrupt handlers. +* @align: the alignment, which can't be greater than SMP_CACHE_BYTES. */ -void * -kmalloc_percpu (size_t size,int flags) +void *__alloc_percpu (size_t size,size_t align) {int i; -struct percpu_data *pdata =kmalloc (sizeof (*pdata), flags); +struct percpu_data *pdata =kmalloc (sizeof (*pdata),GFP_KERNEL );if (!pdata)return NULL ;
@@ -1966,9 +1958,10 @@ kmalloc_percpu(size_t size, int flags)for (i =0 ; i <NR_CPUS ; i++) {if (!cpu_possible (i))continue ; - pdata->ptrs[i] =kmalloc (size, flags); + pdata->ptrs[i] =kmalloc (size,GFP_KERNEL );if (!pdata->ptrs[i]) goto unwind_oom; +memset (pdata->ptrs[i],0 , size); }/* Catch derefs w/o wrappers */
@@ -2025,14 +2018,14 @@ void kfree (const void *objp)#ifdef CONFIG_SMP /** -* kfree_percpu - free previously allocated percpu memory -* @objp: pointer returned by kmalloc_percpu. +* free_percpu - free previously allocated percpu memory +* @objp: pointer returned by alloc_percpu. * -* Don't free memory not originally allocated by kmalloc_percpu() +* Don't free memory not originally allocated by alloc_percpu() * The complemented objp is to check for that. */ void -kfree_percpu (const void *objp) +free_percpu (const void *objp) {int i;struct percpu_data *p = (struct percpu_data *) (~(unsigned long ) objp);
net/ipv4/af_inet.c +10 -40
62 lines not on this page · raw message
net/ipv4/route.c +2 -9
@@ -2692,16 +2692,9 @@ int __init ip_rt_init(void) ipv4_dst_ops.gc_thresh = (rt_hash_mask +1 ); ip_rt_max_size = (rt_hash_mask +1 ) *16 ; - rt_cache_stat =kmalloc_percpu (sizeof (struct rt_cache_stat ), -GFP_KERNEL ); + rt_cache_stat = alloc_percpu(struct rt_cache_stat);if (!rt_cache_stat) goto out_enomem1; -for (i =0 ; i <NR_CPUS ; i++) { -if (cpu_possible (i)) { -memset (per_cpu_ptr (rt_cache_stat, i),0 , -sizeof (struct rt_cache_stat )); - } - }devinet_init ();ip_fib_init ();
@@ -2737,7 +2730,7 @@ int __init ip_rt_init(void) out:return rc; out_enomem: -kfree_percpu (rt_cache_stat); +free_percpu (rt_cache_stat); out_enomem1: rc = -ENOMEM ; goto out;
net/ipv6/af_inet6.c +12 -16
@@ -637,32 +637,25 @@ inet6_unregister_protosw(struct inet_pro }int -snmp6_mib_init (void *ptr[2 ],size_t mibsize) +snmp6_mib_init (void *ptr[2 ],size_t mibsize,size_t mibalign) {int i;if (ptr ==NULL )return -EINVAL ; - ptr[0 ] =kmalloc_percpu (mibsize,GFP_KERNEL ); + ptr[0 ] =__alloc_percpu (mibsize, mibalign);if (!ptr[0 ]) goto err0; - ptr[1 ] =kmalloc_percpu (mibsize,GFP_KERNEL ); + ptr[1 ] =__alloc_percpu (mibsize, mibalign);if (!ptr[1 ]) goto err1; -/* Zero percpu version of the mibs */ -for (i =0 ; i <NR_CPUS ; i++) { -if (cpu_possible (i)) { -memset (per_cpu_ptr (ptr[0 ], i),0 , mibsize); -memset (per_cpu_ptr (ptr[1 ], i),0 , mibsize); - } - }return 0 ; err1: -kfree_percpu (ptr[0 ]); +free_percpu (ptr[0 ]); ptr[0 ] =NULL ; err0:return -ENOMEM ;
@@ -673,18 +666,21 @@ snmp6_mib_free(void *ptr[2]) {if (ptr ==NULL )return ; -kfree_percpu (ptr[0 ]); -kfree_percpu (ptr[1 ]); +free_percpu (ptr[0 ]); +free_percpu (ptr[1 ]); ptr[0 ] = ptr[1 ] =NULL ; }static int __init init_ipv6_mibs (void ) { -if (snmp6_mib_init ((void **)ipv6_statistics,sizeof (struct ipv6_mib )) <0 ) +if (snmp6_mib_init ((void **)ipv6_statistics,sizeof (struct ipv6_mib ), + __alignof__(struct ipv6_mib )) <0 ) goto err_ip_mib; -if (snmp6_mib_init ((void **)icmpv6_statistics,sizeof (struct icmpv6_mib )) <0 ) +if (snmp6_mib_init ((void **)icmpv6_statistics,sizeof (struct icmpv6_mib ), + __alignof__(struct ipv6_mib )) <0 ) goto err_icmp_mib; -if (snmp6_mib_init ((void **)udp_stats_in6,sizeof (struct udp_mib )) <0 ) +if (snmp6_mib_init ((void **)udp_stats_in6,sizeof (struct udp_mib ), + __alignof__(struct ipv6_mib )) <0 ) goto err_udp_mib;return 0 ;
net/ipv6/proc.c +2 -1
@@ -228,7 +228,8 @@ int snmp6_register_dev(struct inet6_devif (!idev || !idev->dev)return -EINVAL ; -if (snmp6_mib_init ((void **)idev->stats.icmpv6,sizeof (struct icmpv6_mib )) <0 ) +if (snmp6_mib_init ((void **)idev->stats.icmpv6,sizeof (struct icmpv6_mib ), + __alignof__(struct ipv6_mib )) <0 ) goto err_icmp;#ifdef CONFIG_PROC_FS
net/sctp/protocol.c +5 -17
@@ -880,34 +880,22 @@ static int __init init_sctp_mibs(void) {int i; - sctp_statistics[0 ] =kmalloc_percpu (sizeof (struct sctp_mib ), -GFP_KERNEL ); + sctp_statistics[0] = alloc_percpu(struct sctp_mib);if (!sctp_statistics[0 ])return -ENOMEM ; - sctp_statistics[1 ] =kmalloc_percpu (sizeof (struct sctp_mib ), -GFP_KERNEL ); + sctp_statistics[1] = alloc_percpu(struct sctp_mib);if (!sctp_statistics[1 ]) { -kfree_percpu (sctp_statistics[0 ]); +free_percpu (sctp_statistics[0 ]);return -ENOMEM ; } - -/* Zero all percpu versions of the mibs */ -for (i =0 ; i <NR_CPUS ; i++) { -if (cpu_possible (i)) { -memset (per_cpu_ptr (sctp_statistics[0 ], i),0 , -sizeof (struct sctp_mib )); -memset (per_cpu_ptr (sctp_statistics[1 ], i),0 , -sizeof (struct sctp_mib )); - } - }return 0 ; }static void cleanup_sctp_mibs (void ) { -kfree_percpu (sctp_statistics[0 ]); -kfree_percpu (sctp_statistics[1 ]); +free_percpu (sctp_statistics[0 ]); +free_percpu (sctp_statistics[1 ]); }/* Initialize the universe into something sensible. */