From 15d26df09084ff3a891a696efd0d56b52d852e24 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 26 Mar 2005 14:04:49 -0300 Subject: [NET] make all protos partially use sk_prot sk_alloc_slab becomes proto_register, that receives a struct proto not necessarily completely filled, but at least with the proto name, owner and obj_size (aka proto specific sock size), with this we can remove the struct sock sk_owner and sk_slab, using sk->sk_prot->{owner,slab} instead. This patch also makes sk_set_owner not necessary anymore, as at sk_alloc time we have now access to the struct proto onwer and slab members, so we can bump the module refcount exactly at sock allocation time. Another nice "side effect" is that this patch removes the generic sk_cachep slab cache, making the only last two protocols that used it use just kmalloc, informing a struct proto obj_size equal to sizeof(struct sock). Ah, almost forgot that with this patch it is very easy to use a slab cache, as it is now created at proto_register time, and all protocols need to use proto_register, so its just a matter of switching the second parameter of proto_register to '1', heck, this can be done even at module load time with some small additional patch. Another optimization that will be possible in the future is to move the sk_protocol and sk_type struct sock members to struct proto, but this has to wait for all protocols to move completely to sk_prot. This changeset also introduces /proc/net/protocols, that lists the registered protocols details, some may seem excessive, but I'd like to keep them while working on further struct sock hierarchy work and also to realize which protocols are old ones, i.e. that still use struct proto_ops, etc, yeah, this is a bit of an exaggeration, as all protos still use struct proto_ops, but in time the idea is to move all to use sk->sk_prot and make the proto_ops infrastructure be shared among all protos, reducing one level of indirection. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- net/unix/af_unix.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'net/unix/af_unix.c') diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 0768f8814759..c8e44fe1ee25 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -121,8 +121,6 @@ int sysctl_unix_max_dgram_qlen = 10; -static kmem_cache_t *unix_sk_cachep; - struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; DEFINE_RWLOCK(unix_table_lock); static atomic_t unix_nr_socks = ATOMIC_INIT(0); @@ -532,6 +530,12 @@ static struct proto_ops unix_seqpacket_ops = { .sendpage = sock_no_sendpage, }; +static struct proto unix_proto = { + .name = "UNIX", + .owner = THIS_MODULE, + .obj_size = sizeof(struct unix_sock), +}; + static struct sock * unix_create1(struct socket *sock) { struct sock *sk = NULL; @@ -540,15 +544,13 @@ static struct sock * unix_create1(struct socket *sock) if (atomic_read(&unix_nr_socks) >= 2*files_stat.max_files) goto out; - sk = sk_alloc(PF_UNIX, GFP_KERNEL, sizeof(struct unix_sock), - unix_sk_cachep); + sk = sk_alloc(PF_UNIX, GFP_KERNEL, &unix_proto, 1); if (!sk) goto out; atomic_inc(&unix_nr_socks); sock_init_data(sock,sk); - sk_set_owner(sk, THIS_MODULE); sk->sk_write_space = unix_write_space; sk->sk_max_ack_backlog = sysctl_unix_max_dgram_qlen; @@ -2050,26 +2052,28 @@ static inline void unix_sysctl_unregister(void) {} static int __init af_unix_init(void) { + int rc = -1; struct sk_buff *dummy_skb; if (sizeof(struct unix_skb_parms) > sizeof(dummy_skb->cb)) { printk(KERN_CRIT "%s: panic\n", __FUNCTION__); - return -1; + goto out; + } + + rc = proto_register(&unix_proto, 1); + if (rc != 0) { + printk(KERN_CRIT "%s: Cannot create unix_sock SLAB cache!\n", + __FUNCTION__); + goto out; } - /* allocate our sock slab cache */ - unix_sk_cachep = kmem_cache_create("unix_sock", - sizeof(struct unix_sock), 0, - SLAB_HWCACHE_ALIGN, NULL, NULL); - if (!unix_sk_cachep) - printk(KERN_CRIT - "af_unix_init: Cannot create unix_sock SLAB cache!\n"); sock_register(&unix_family_ops); #ifdef CONFIG_PROC_FS proc_net_fops_create("unix", 0, &unix_seq_fops); #endif unix_sysctl_register(); - return 0; +out: + return rc; } static void __exit af_unix_exit(void) @@ -2077,7 +2081,7 @@ static void __exit af_unix_exit(void) sock_unregister(PF_UNIX); unix_sysctl_unregister(); proc_net_remove("unix"); - kmem_cache_destroy(unix_sk_cachep); + proto_unregister(&unix_proto); } module_init(af_unix_init); -- cgit v1.2.3