Skip to content

Commit

Permalink
inet: frags: use kmem_cache for inet_frag_queue
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Nikolay Aleksandrov authored and David S. Miller committed Aug 2, 2014
1 parent 2e404f6 commit d4ad4d2
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 9 deletions.
4 changes: 3 additions & 1 deletion include/net/inet_frag.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,11 @@ struct inet_frags {
void (*destructor)(struct inet_frag_queue *);
void (*skb_free)(struct sk_buff *);
void (*frag_expire)(unsigned long data);
struct kmem_cache *frags_cachep;
const char *frags_cache_name;
};

void inet_frags_init(struct inet_frags *);
int inet_frags_init(struct inet_frags *);
void inet_frags_fini(struct inet_frags *);

void inet_frags_init_net(struct netns_frags *nf);
Expand Down
7 changes: 6 additions & 1 deletion net/ieee802154/reassembly.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

#include "reassembly.h"

static const char lowpan_frags_cache_name[] = "lowpan-frags";

struct lowpan_frag_info {
__be16 d_tag;
u16 d_size;
Expand Down Expand Up @@ -571,7 +573,10 @@ int __init lowpan_net_frag_init(void)
lowpan_frags.qsize = sizeof(struct frag_queue);
lowpan_frags.match = lowpan_frag_match;
lowpan_frags.frag_expire = lowpan_frag_expire;
inet_frags_init(&lowpan_frags);
lowpan_frags.frags_cache_name = lowpan_frags_cache_name;
ret = inet_frags_init(&lowpan_frags);
if (ret)
goto err_pernet;

return ret;
err_pernet:
Expand Down
13 changes: 10 additions & 3 deletions net/ipv4/inet_fragment.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ static void inet_frag_schedule_worker(struct inet_frags *f)
schedule_work(&f->frags_work);
}

void inet_frags_init(struct inet_frags *f)
int inet_frags_init(struct inet_frags *f)
{
int i;

Expand All @@ -213,6 +213,12 @@ void inet_frags_init(struct inet_frags *f)

seqlock_init(&f->rnd_seqlock);
f->last_rebuild_jiffies = 0;
f->frags_cachep = kmem_cache_create(f->frags_cache_name, f->qsize, 0, 0,
NULL);
if (!f->frags_cachep)
return -ENOMEM;

return 0;
}
EXPORT_SYMBOL(inet_frags_init);

Expand All @@ -225,6 +231,7 @@ EXPORT_SYMBOL(inet_frags_init_net);
void inet_frags_fini(struct inet_frags *f)
{
cancel_work_sync(&f->frags_work);
kmem_cache_destroy(f->frags_cachep);
}
EXPORT_SYMBOL(inet_frags_fini);

Expand Down Expand Up @@ -327,7 +334,7 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f)

if (f->destructor)
f->destructor(q);
kfree(q);
kmem_cache_free(f->frags_cachep, q);
}
EXPORT_SYMBOL(inet_frag_destroy);

Expand Down Expand Up @@ -377,7 +384,7 @@ static struct inet_frag_queue *inet_frag_alloc(struct netns_frags *nf,
return NULL;
}

q = kzalloc(f->qsize, GFP_ATOMIC);
q = kmem_cache_zalloc(f->frags_cachep, GFP_ATOMIC);
if (q == NULL)
return NULL;

Expand Down
5 changes: 4 additions & 1 deletion net/ipv4/ip_fragment.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
*/

static int sysctl_ipfrag_max_dist __read_mostly = 64;
static const char ip_frag_cache_name[] = "ip4-frags";

struct ipfrag_skb_cb
{
Expand Down Expand Up @@ -860,5 +861,7 @@ void __init ipfrag_init(void)
ip4_frags.qsize = sizeof(struct ipq);
ip4_frags.match = ip4_frag_match;
ip4_frags.frag_expire = ip_expire;
inet_frags_init(&ip4_frags);
ip4_frags.frags_cache_name = ip_frag_cache_name;
if (inet_frags_init(&ip4_frags))
panic("IP: failed to allocate ip4_frags cache\n");
}
8 changes: 6 additions & 2 deletions net/ipv6/netfilter/nf_conntrack_reasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include <linux/module.h>
#include <net/netfilter/ipv6/nf_defrag_ipv6.h>

static const char nf_frags_cache_name[] = "nf-frags";

struct nf_ct_frag6_skb_cb
{
Expand Down Expand Up @@ -677,12 +678,15 @@ int nf_ct_frag6_init(void)
nf_frags.qsize = sizeof(struct frag_queue);
nf_frags.match = ip6_frag_match;
nf_frags.frag_expire = nf_ct_frag6_expire;
inet_frags_init(&nf_frags);

nf_frags.frags_cache_name = nf_frags_cache_name;
ret = inet_frags_init(&nf_frags);
if (ret)
goto out;
ret = register_pernet_subsys(&nf_ct_net_ops);
if (ret)
inet_frags_fini(&nf_frags);

out:
return ret;
}

Expand Down
7 changes: 6 additions & 1 deletion net/ipv6/reassembly.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
#include <net/inet_frag.h>
#include <net/inet_ecn.h>

static const char ip6_frag_cache_name[] = "ip6-frags";

struct ip6frag_skb_cb
{
struct inet6_skb_parm h;
Expand Down Expand Up @@ -748,7 +750,10 @@ int __init ipv6_frag_init(void)
ip6_frags.qsize = sizeof(struct frag_queue);
ip6_frags.match = ip6_frag_match;
ip6_frags.frag_expire = ip6_frag_expire;
inet_frags_init(&ip6_frags);
ip6_frags.frags_cache_name = ip6_frag_cache_name;
ret = inet_frags_init(&ip6_frags);
if (ret)
goto err_pernet;
out:
return ret;

Expand Down

0 comments on commit d4ad4d2

Please sign in to comment.