From 2e6599cb899ba4b133f42cbf9d2b1883d2dc583a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 18 Jun 2005 22:46:52 -0700 Subject: [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 Signed-off-by: David S. Miller --- net/core/sock.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'net/core') diff --git a/net/core/sock.c b/net/core/sock.c index 96e00b08698f..a6ec3ada7f9e 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -118,6 +118,7 @@ #include #include #include +#include #include #include #include @@ -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); } -- cgit v1.2.3