diff options
| author | Nikolay Aleksandrov <nikolay@redhat.com> | 2014-08-01 06:29:48 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-08-02 18:31:31 -0400 |
| commit | d4ad4d22e7ac6b8711b35d7e86eb29f03f8ac153 (patch) | |
| tree | 929ebb9bc76b52037572bfb58475112989b51ba0 | |
| parent | 2e404f632f44979ddf0ce0808a438249a72d7015 (diff) | |
inet: frags: use kmem_cache for inet_frag_queue
Use kmem_cache to allocate/free inet_frag_queue objects since they're
all the same size per inet_frags user and are alloced/freed in high volumes
thus making it a perfect case for kmem_cache.
Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
Acked-by: Florian Westphal <fw@strlen.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | include/net/inet_frag.h | 4 | ||||
| -rw-r--r-- | net/ieee802154/reassembly.c | 7 | ||||
| -rw-r--r-- | net/ipv4/inet_fragment.c | 13 | ||||
| -rw-r--r-- | net/ipv4/ip_fragment.c | 5 | ||||
| -rw-r--r-- | net/ipv6/netfilter/nf_conntrack_reasm.c | 8 | ||||
| -rw-r--r-- | net/ipv6/reassembly.c | 7 |
6 files changed, 35 insertions, 9 deletions
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h index 90015c47b447..65a8855e99fe 100644 --- a/include/net/inet_frag.h +++ b/include/net/inet_frag.h | |||
| @@ -101,9 +101,11 @@ struct inet_frags { | |||
| 101 | void (*destructor)(struct inet_frag_queue *); | 101 | void (*destructor)(struct inet_frag_queue *); |
| 102 | void (*skb_free)(struct sk_buff *); | 102 | void (*skb_free)(struct sk_buff *); |
| 103 | void (*frag_expire)(unsigned long data); | 103 | void (*frag_expire)(unsigned long data); |
| 104 | struct kmem_cache *frags_cachep; | ||
| 105 | const char *frags_cache_name; | ||
| 104 | }; | 106 | }; |
| 105 | 107 | ||
| 106 | void inet_frags_init(struct inet_frags *); | 108 | int inet_frags_init(struct inet_frags *); |
| 107 | void inet_frags_fini(struct inet_frags *); | 109 | void inet_frags_fini(struct inet_frags *); |
| 108 | 110 | ||
| 109 | void inet_frags_init_net(struct netns_frags *nf); | 111 | void inet_frags_init_net(struct netns_frags *nf); |
diff --git a/net/ieee802154/reassembly.c b/net/ieee802154/reassembly.c index 5607accd2fee..ffec6ce51005 100644 --- a/net/ieee802154/reassembly.c +++ b/net/ieee802154/reassembly.c | |||
| @@ -30,6 +30,8 @@ | |||
| 30 | 30 | ||
| 31 | #include "reassembly.h" | 31 | #include "reassembly.h" |
| 32 | 32 | ||
| 33 | static const char lowpan_frags_cache_name[] = "lowpan-frags"; | ||
| 34 | |||
| 33 | struct lowpan_frag_info { | 35 | struct lowpan_frag_info { |
| 34 | __be16 d_tag; | 36 | __be16 d_tag; |
| 35 | u16 d_size; | 37 | u16 d_size; |
| @@ -571,7 +573,10 @@ int __init lowpan_net_frag_init(void) | |||
| 571 | lowpan_frags.qsize = sizeof(struct frag_queue); | 573 | lowpan_frags.qsize = sizeof(struct frag_queue); |
| 572 | lowpan_frags.match = lowpan_frag_match; | 574 | lowpan_frags.match = lowpan_frag_match; |
| 573 | lowpan_frags.frag_expire = lowpan_frag_expire; | 575 | lowpan_frags.frag_expire = lowpan_frag_expire; |
| 574 | inet_frags_init(&lowpan_frags); | 576 | lowpan_frags.frags_cache_name = lowpan_frags_cache_name; |
| 577 | ret = inet_frags_init(&lowpan_frags); | ||
| 578 | if (ret) | ||
| 579 | goto err_pernet; | ||
| 575 | 580 | ||
| 576 | return ret; | 581 | return ret; |
| 577 | err_pernet: | 582 | err_pernet: |
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c index 4baa76c60398..9eb89f3f0ee4 100644 --- a/net/ipv4/inet_fragment.c +++ b/net/ipv4/inet_fragment.c | |||
| @@ -198,7 +198,7 @@ static void inet_frag_schedule_worker(struct inet_frags *f) | |||
| 198 | schedule_work(&f->frags_work); | 198 | schedule_work(&f->frags_work); |
| 199 | } | 199 | } |
| 200 | 200 | ||
| 201 | void inet_frags_init(struct inet_frags *f) | 201 | int inet_frags_init(struct inet_frags *f) |
| 202 | { | 202 | { |
| 203 | int i; | 203 | int i; |
| 204 | 204 | ||
| @@ -213,6 +213,12 @@ void inet_frags_init(struct inet_frags *f) | |||
| 213 | 213 | ||
| 214 | seqlock_init(&f->rnd_seqlock); | 214 | seqlock_init(&f->rnd_seqlock); |
| 215 | f->last_rebuild_jiffies = 0; | 215 | f->last_rebuild_jiffies = 0; |
| 216 | f->frags_cachep = kmem_cache_create(f->frags_cache_name, f->qsize, 0, 0, | ||
| 217 | NULL); | ||
| 218 | if (!f->frags_cachep) | ||
| 219 | return -ENOMEM; | ||
| 220 | |||
| 221 | return 0; | ||
| 216 | } | 222 | } |
| 217 | EXPORT_SYMBOL(inet_frags_init); | 223 | EXPORT_SYMBOL(inet_frags_init); |
| 218 | 224 | ||
| @@ -225,6 +231,7 @@ EXPORT_SYMBOL(inet_frags_init_net); | |||
| 225 | void inet_frags_fini(struct inet_frags *f) | 231 | void inet_frags_fini(struct inet_frags *f) |
| 226 | { | 232 | { |
| 227 | cancel_work_sync(&f->frags_work); | 233 | cancel_work_sync(&f->frags_work); |
| 234 | kmem_cache_destroy(f->frags_cachep); | ||
| 228 | } | 235 | } |
| 229 | EXPORT_SYMBOL(inet_frags_fini); | 236 | EXPORT_SYMBOL(inet_frags_fini); |
| 230 | 237 | ||
| @@ -327,7 +334,7 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f) | |||
| 327 | 334 | ||
| 328 | if (f->destructor) | 335 | if (f->destructor) |
| 329 | f->destructor(q); | 336 | f->destructor(q); |
| 330 | kfree(q); | 337 | kmem_cache_free(f->frags_cachep, q); |
| 331 | } | 338 | } |
| 332 | EXPORT_SYMBOL(inet_frag_destroy); | 339 | EXPORT_SYMBOL(inet_frag_destroy); |
| 333 | 340 | ||
| @@ -377,7 +384,7 @@ static struct inet_frag_queue *inet_frag_alloc(struct netns_frags *nf, | |||
| 377 | return NULL; | 384 | return NULL; |
| 378 | } | 385 | } |
| 379 | 386 | ||
| 380 | q = kzalloc(f->qsize, GFP_ATOMIC); | 387 | q = kmem_cache_zalloc(f->frags_cachep, GFP_ATOMIC); |
| 381 | if (q == NULL) | 388 | if (q == NULL) |
| 382 | return NULL; | 389 | return NULL; |
| 383 | 390 | ||
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index cb56bcc1eee2..15f0e2bad7ad 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
| @@ -55,6 +55,7 @@ | |||
| 55 | */ | 55 | */ |
| 56 | 56 | ||
| 57 | static int sysctl_ipfrag_max_dist __read_mostly = 64; | 57 | static int sysctl_ipfrag_max_dist __read_mostly = 64; |
| 58 | static const char ip_frag_cache_name[] = "ip4-frags"; | ||
| 58 | 59 | ||
| 59 | struct ipfrag_skb_cb | 60 | struct ipfrag_skb_cb |
| 60 | { | 61 | { |
| @@ -860,5 +861,7 @@ void __init ipfrag_init(void) | |||
| 860 | ip4_frags.qsize = sizeof(struct ipq); | 861 | ip4_frags.qsize = sizeof(struct ipq); |
| 861 | ip4_frags.match = ip4_frag_match; | 862 | ip4_frags.match = ip4_frag_match; |
| 862 | ip4_frags.frag_expire = ip_expire; | 863 | ip4_frags.frag_expire = ip_expire; |
| 863 | inet_frags_init(&ip4_frags); | 864 | ip4_frags.frags_cache_name = ip_frag_cache_name; |
| 865 | if (inet_frags_init(&ip4_frags)) | ||
| 866 | panic("IP: failed to allocate ip4_frags cache\n"); | ||
| 864 | } | 867 | } |
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index cca686e42b97..6f187c8d8a1b 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
| @@ -50,6 +50,7 @@ | |||
| 50 | #include <linux/module.h> | 50 | #include <linux/module.h> |
| 51 | #include <net/netfilter/ipv6/nf_defrag_ipv6.h> | 51 | #include <net/netfilter/ipv6/nf_defrag_ipv6.h> |
| 52 | 52 | ||
| 53 | static const char nf_frags_cache_name[] = "nf-frags"; | ||
| 53 | 54 | ||
| 54 | struct nf_ct_frag6_skb_cb | 55 | struct nf_ct_frag6_skb_cb |
| 55 | { | 56 | { |
| @@ -677,12 +678,15 @@ int nf_ct_frag6_init(void) | |||
| 677 | nf_frags.qsize = sizeof(struct frag_queue); | 678 | nf_frags.qsize = sizeof(struct frag_queue); |
| 678 | nf_frags.match = ip6_frag_match; | 679 | nf_frags.match = ip6_frag_match; |
| 679 | nf_frags.frag_expire = nf_ct_frag6_expire; | 680 | nf_frags.frag_expire = nf_ct_frag6_expire; |
| 680 | inet_frags_init(&nf_frags); | 681 | nf_frags.frags_cache_name = nf_frags_cache_name; |
| 681 | 682 | ret = inet_frags_init(&nf_frags); | |
| 683 | if (ret) | ||
| 684 | goto out; | ||
| 682 | ret = register_pernet_subsys(&nf_ct_net_ops); | 685 | ret = register_pernet_subsys(&nf_ct_net_ops); |
| 683 | if (ret) | 686 | if (ret) |
| 684 | inet_frags_fini(&nf_frags); | 687 | inet_frags_fini(&nf_frags); |
| 685 | 688 | ||
| 689 | out: | ||
| 686 | return ret; | 690 | return ret; |
| 687 | } | 691 | } |
| 688 | 692 | ||
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index beb6872a8fa5..c6557d9f7808 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
| @@ -60,6 +60,8 @@ | |||
| 60 | #include <net/inet_frag.h> | 60 | #include <net/inet_frag.h> |
| 61 | #include <net/inet_ecn.h> | 61 | #include <net/inet_ecn.h> |
| 62 | 62 | ||
| 63 | static const char ip6_frag_cache_name[] = "ip6-frags"; | ||
| 64 | |||
| 63 | struct ip6frag_skb_cb | 65 | struct ip6frag_skb_cb |
| 64 | { | 66 | { |
| 65 | struct inet6_skb_parm h; | 67 | struct inet6_skb_parm h; |
| @@ -748,7 +750,10 @@ int __init ipv6_frag_init(void) | |||
| 748 | ip6_frags.qsize = sizeof(struct frag_queue); | 750 | ip6_frags.qsize = sizeof(struct frag_queue); |
| 749 | ip6_frags.match = ip6_frag_match; | 751 | ip6_frags.match = ip6_frag_match; |
| 750 | ip6_frags.frag_expire = ip6_frag_expire; | 752 | ip6_frags.frag_expire = ip6_frag_expire; |
| 751 | inet_frags_init(&ip6_frags); | 753 | ip6_frags.frags_cache_name = ip6_frag_cache_name; |
| 754 | ret = inet_frags_init(&ip6_frags); | ||
| 755 | if (ret) | ||
| 756 | goto err_pernet; | ||
| 752 | out: | 757 | out: |
| 753 | return ret; | ||
