diff options
Diffstat (limited to 'net/core/dst.c')
-rw-r--r-- | net/core/dst.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/net/core/dst.c b/net/core/dst.c index 76a617f6d60a..f8694d1b8702 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -362,15 +362,10 @@ static int dst_md_discard(struct sk_buff *skb) return 0; } -struct metadata_dst *metadata_dst_alloc(u8 optslen, gfp_t flags) +static void __metadata_dst_init(struct metadata_dst *md_dst, u8 optslen) { - struct metadata_dst *md_dst; struct dst_entry *dst; - md_dst = kmalloc(sizeof(*md_dst) + optslen, flags); - if (!md_dst) - return ERR_PTR(-ENOMEM); - dst = &md_dst->dst; dst_init(dst, &md_dst_ops, NULL, 1, DST_OBSOLETE_NONE, DST_METADATA | DST_NOCACHE | DST_NOCOUNT); @@ -380,11 +375,39 @@ struct metadata_dst *metadata_dst_alloc(u8 optslen, gfp_t flags) memset(dst + 1, 0, sizeof(*md_dst) + optslen - sizeof(*dst)); md_dst->opts_len = optslen; +} + +struct metadata_dst *metadata_dst_alloc(u8 optslen, gfp_t flags) +{ + struct metadata_dst *md_dst; + + md_dst = kmalloc(sizeof(*md_dst) + optslen, flags); + if (!md_dst) + return NULL; + + __metadata_dst_init(md_dst, optslen); return md_dst; } EXPORT_SYMBOL_GPL(metadata_dst_alloc); +struct metadata_dst __percpu *metadata_dst_alloc_percpu(u8 optslen, gfp_t flags) +{ + int cpu; + struct metadata_dst __percpu *md_dst; + + md_dst = __alloc_percpu_gfp(sizeof(struct metadata_dst) + optslen, + __alignof__(struct metadata_dst), flags); + if (!md_dst) + return NULL; + + for_each_possible_cpu(cpu) + __metadata_dst_init(per_cpu_ptr(md_dst, cpu), optslen); + + return md_dst; +} +EXPORT_SYMBOL_GPL(metadata_dst_alloc_percpu); + /* Dirty hack. We did it in 2.2 (in __dst_free), * we have _very_ good reasons not to repeat * this mistake in 2.3, but we have no choice |