[NET] Generalise TCP's struct open_request minisock infrastructure
Kept this first changeset minimal, without changing existing names to ease peer review. Basicaly tcp_openreq_alloc now receives the or_calltable, that in turn has two new members: ->slab, that replaces tcp_openreq_cachep ->obj_size, to inform the size of the openreq descendant for a specific protocol The protocol specific fields in struct open_request were moved to a class hierarchy, with the things that are common to all connection oriented PF_INET protocols in struct inet_request_sock, the TCP ones in tcp_request_sock, that is an inet_request_sock, that is an open_request. I.e. this uses the same approach used for the struct sock class hierarchy, with sk_prot indicating if the protocol wants to use the open_request infrastructure by filling in sk_prot->rsk_prot with an or_calltable. Results? Performance is improved and TCP v4 now uses only 64 bytes per open request minisock, down from 96 without this patch :-) Next changeset will rename some of the structs, fields and functions mentioned above, struct or_calltable is way unclear, better name it struct request_sock_ops, s/struct open_request/struct request_sock/g, etc. Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
1944972d3b
commit
2e6599cb89
@ -118,6 +118,7 @@
|
||||
#include <linux/netdevice.h>
|
||||
#include <net/protocol.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <net/request_sock.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/xfrm.h>
|
||||
#include <linux/ipsec.h>
|
||||
@ -1363,6 +1364,7 @@ static LIST_HEAD(proto_list);
|
||||
|
||||
int proto_register(struct proto *prot, int alloc_slab)
|
||||
{
|
||||
char *request_sock_slab_name;
|
||||
int rc = -ENOBUFS;
|
||||
|
||||
if (alloc_slab) {
|
||||
@ -1374,6 +1376,25 @@ int proto_register(struct proto *prot, int alloc_slab)
|
||||
prot->name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (prot->rsk_prot != NULL) {
|
||||
static const char mask[] = "request_sock_%s";
|
||||
|
||||
request_sock_slab_name = kmalloc(strlen(prot->name) + sizeof(mask) - 1, GFP_KERNEL);
|
||||
if (request_sock_slab_name == NULL)
|
||||
goto out_free_sock_slab;
|
||||
|
||||
sprintf(request_sock_slab_name, mask, prot->name);
|
||||
prot->rsk_prot->slab = kmem_cache_create(request_sock_slab_name,
|
||||
prot->rsk_prot->obj_size, 0,
|
||||
SLAB_HWCACHE_ALIGN, NULL, NULL);
|
||||
|
||||
if (prot->rsk_prot->slab == NULL) {
|
||||
printk(KERN_CRIT "%s: Can't create request sock SLAB cache!\n",
|
||||
prot->name);
|
||||
goto out_free_request_sock_slab_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
write_lock(&proto_list_lock);
|
||||
@ -1382,6 +1403,12 @@ int proto_register(struct proto *prot, int alloc_slab)
|
||||
rc = 0;
|
||||
out:
|
||||
return rc;
|
||||
out_free_request_sock_slab_name:
|
||||
kfree(request_sock_slab_name);
|
||||
out_free_sock_slab:
|
||||
kmem_cache_destroy(prot->slab);
|
||||
prot->slab = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(proto_register);
|
||||
@ -1395,6 +1422,14 @@ void proto_unregister(struct proto *prot)
|
||||
prot->slab = NULL;
|
||||
}
|
||||
|
||||
if (prot->rsk_prot != NULL && prot->rsk_prot->slab != NULL) {
|
||||
const char *name = kmem_cache_name(prot->rsk_prot->slab);
|
||||
|
||||
kmem_cache_destroy(prot->rsk_prot->slab);
|
||||
kfree(name);
|
||||
prot->rsk_prot->slab = NULL;
|
||||
}
|
||||
|
||||
list_del(&prot->node);
|
||||
write_unlock(&proto_list_lock);
|
||||
}
|
||||
|
Reference in New Issue
Block a user