* [PATCH][NET] generalise per socket slab cache use
@ 2004-09-11 3:23 Arnaldo Carvalho de Melo
2004-09-13 21:17 ` Sridhar Samudrala
0 siblings, 1 reply; 4+ messages in thread
From: Arnaldo Carvalho de Melo @ 2004-09-11 3:23 UTC (permalink / raw)
To: David S.Miller; +Cc: Sridhar Samudrala, YOSHIFUJI Hideaki, netdev
[-- Attachment #1: Type: text/plain, Size: 620 bytes --]
Hi,
Please see if it is acceptable, if it is, please pull from:
bk://kernel.bkbits.net/acme/net-2.6
I want to improve it a bit by not passing the slab cache name to
sk_alloc_slab, but create the name from the sk->sk_prot->name member,
but unfortunately the kmem_cache_t struct stores a pointer to the slab
cache name, which also creates problems for other improvements, like
my __initstr patch, that moves the strings in __init and __exit functions to
.text.init and .text.exit, perhaps I should send a patch to the slab code
to have a char array to store the slab cache name.
Comments?
Best Regards,
- Arnaldo
[-- Attachment #2: slab.patch --]
[-- Type: text/x-diff, Size: 24291 bytes --]
You can import this changeset into BK by piping this whole message to:
'| bk receive [path to repository]' or apply the patch as usual.
===================================================================
ChangeSet@1.2165, 2004-09-11 00:02:02-03:00, acme@conectiva.com.br
[NET] generalise per socket slab cache use
With this patch we get two new slabcaches, for sctp socks, that previously
were being allocated on the default, that was tcp[6]_sock, i.e. wasting 288
bytes per sock in the IPv4 case and 256 bytes for the IPv6 version, this is in
preparation for DCCP (or any other new protocol :) ).
With this in place another nice side effect that is easier to achieve is to
get rid of struct sock sk->sk_slab, and instead use sk->sk_prot->slab, saving
sizeof(void *) on every struct sock instance, but this unfortunatly has to
wait for the conversion of all protocols that use per socket slabcaches to
use sk->sk_prot, AF_UNIX is the only one AFAIK, so I'll try to convert it to
use sk->sk_prot and then get rid of sk->sk_slab.
As for the protocols that don't use per socket slabcaches its just a matter
of defaulting to sk_cachep at sk_free time if sk->sk_prot is NULL.
[root@qemu ~]# modprobe sctp
[root@qemu ~]# grep _sock /proc/slabinfo
sctpv6_sock 9 9 864 9 2 : tunables 54 27 0 :
sctp_sock 0 0 736 5 1 : tunables 54 27 0 :
rawv6_sock 3 6 640 6 1 : tunables 54 27 0 :
udpv6_sock 0 0 608 6 1 : tunables 54 27 0 :
tcpv6_sock 1 7 1120 7 2 : tunables 24 12 0 :
unix_sock 6 10 384 10 1 : tunables 54 27 0 :
raw_sock 2 8 480 8 1 : tunables 54 27 0 :
udp_sock 0 0 512 7 1 : tunables 54 27 0 :
tcp_sock 0 0 1024 4 1 : tunables 54 27 0 :
include/linux/ipv6.h | 4 +
include/net/raw.h | 1
include/net/sctp/sctp.h | 1
include/net/sock.h | 7 ++
include/net/tcp.h | 3
net/core/sock.c | 21 ++++++
net/ipv4/af_inet.c | 103 ++++++++++++++------------------
net/ipv4/raw.c | 1
net/ipv4/tcp_ipv4.c | 1
net/ipv4/tcp_minisocks.c | 2
net/ipv4/udp.c | 1
net/ipv6/af_inet6.c | 151 +++++++++++++++++++----------------------------
net/ipv6/raw.c | 6 +
net/ipv6/tcp_ipv6.c | 6 +
net/ipv6/udp.c | 6 +
net/sctp/ipv6.c | 24 +++++--
net/sctp/protocol.c | 26 +++++---
net/sctp/socket.c | 30 +++++++++
18 files changed, 231 insertions(+), 163 deletions(-)
diff -Nru a/include/linux/ipv6.h b/include/linux/ipv6.h
--- a/include/linux/ipv6.h 2004-09-11 00:15:42 -03:00
+++ b/include/linux/ipv6.h 2004-09-11 00:15:42 -03:00
@@ -282,6 +282,10 @@
return &((struct raw6_sock *)__sk)->raw6;
}
+struct ipv6_sk_offset {
+ int offset;
+};
+
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
#define __ipv6_only_sock(sk) (inet6_sk(sk)->ipv6only)
#define ipv6_only_sock(sk) ((sk)->sk_family == PF_INET6 && __ipv6_only_sock(sk))
diff -Nru a/include/net/raw.h b/include/net/raw.h
--- a/include/net/raw.h 2004-09-11 00:15:42 -03:00
+++ b/include/net/raw.h 2004-09-11 00:15:42 -03:00
@@ -17,7 +17,6 @@
#ifndef _RAW_H
#define _RAW_H
-
extern struct proto raw_prot;
diff -Nru a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
--- a/include/net/sctp/sctp.h 2004-09-11 00:15:42 -03:00
+++ b/include/net/sctp/sctp.h 2004-09-11 00:15:42 -03:00
@@ -505,6 +505,7 @@
/* External references. */
extern struct proto sctp_prot;
+extern struct proto sctpv6_prot;
extern struct proc_dir_entry *proc_net_sctp;
void sctp_put_port(struct sock *sk);
diff -Nru a/include/net/sock.h b/include/net/sock.h
--- a/include/net/sock.h 2004-09-11 00:15:42 -03:00
+++ b/include/net/sock.h 2004-09-11 00:15:42 -03:00
@@ -410,6 +410,9 @@
return test_bit(flag, &sk->sk_flags);
}
+extern int sk_alloc_slab(struct proto *prot, char *name);
+extern void sk_free_slab(struct proto *prot);
+
static inline void sk_acceptq_removed(struct sock *sk)
{
sk->sk_ack_backlog--;
@@ -554,6 +557,10 @@
int *sysctl_wmem;
int *sysctl_rmem;
int max_header;
+
+ kmem_cache_t *slab;
+ int slab_obj_size;
+ void *af_specific;
char name[32];
diff -Nru a/include/net/tcp.h b/include/net/tcp.h
--- a/include/net/tcp.h 2004-09-11 00:15:42 -03:00
+++ b/include/net/tcp.h 2004-09-11 00:15:42 -03:00
@@ -153,9 +153,6 @@
#define tcp_lhash_wait (tcp_hashinfo.__tcp_lhash_wait)
#define tcp_portalloc_lock (tcp_hashinfo.__tcp_portalloc_lock)
-/* SLAB cache for TCP socks */
-extern kmem_cache_t *tcp_sk_cachep;
-
extern kmem_cache_t *tcp_bucket_cachep;
extern struct tcp_bind_bucket *tcp_bucket_create(struct tcp_bind_hashbucket *head,
unsigned short snum);
diff -Nru a/net/core/sock.c b/net/core/sock.c
--- a/net/core/sock.c 2004-09-11 00:15:42 -03:00
+++ b/net/core/sock.c 2004-09-11 00:15:42 -03:00
@@ -1343,6 +1343,27 @@
EXPORT_SYMBOL(sk_common_release);
+int sk_alloc_slab(struct proto *prot, char *name)
+{
+ prot->slab = kmem_cache_create(name,
+ prot->slab_obj_size, 0,
+ SLAB_HWCACHE_ALIGN, NULL, NULL);
+
+ return prot->slab != NULL ? 0 : -ENOBUFS;
+}
+
+EXPORT_SYMBOL(sk_alloc_slab);
+
+void sk_free_slab(struct proto *prot)
+{
+ if (prot->slab != NULL) {
+ kmem_cache_destroy(prot->slab);
+ prot->slab = NULL;
+ }
+}
+
+EXPORT_SYMBOL(sk_free_slab);
+
EXPORT_SYMBOL(__lock_sock);
EXPORT_SYMBOL(__release_sock);
EXPORT_SYMBOL(sk_alloc);
diff -Nru a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
--- a/net/ipv4/af_inet.c 2004-09-11 00:15:42 -03:00
+++ b/net/ipv4/af_inet.c 2004-09-11 00:15:42 -03:00
@@ -121,11 +121,6 @@
extern void ip_mc_drop_socket(struct sock *sk);
-/* Per protocol sock slabcache */
-kmem_cache_t *tcp_sk_cachep;
-static kmem_cache_t *udp_sk_cachep;
-static kmem_cache_t *raw4_sk_cachep;
-
/* The inetsw table contains everything that inet_create needs to
* build a new socket.
*/
@@ -228,28 +223,6 @@
return err;
}
-static __inline__ kmem_cache_t *inet_sk_slab(int protocol)
-{
- kmem_cache_t* rc = tcp_sk_cachep;
-
- if (protocol == IPPROTO_UDP)
- rc = udp_sk_cachep;
- else if (protocol == IPPROTO_RAW)
- rc = raw4_sk_cachep;
- return rc;
-}
-
-static __inline__ int inet_sk_size(int protocol)
-{
- int rc = sizeof(struct tcp_sock);
-
- if (protocol == IPPROTO_UDP)
- rc = sizeof(struct udp_sock);
- else if (protocol == IPPROTO_RAW)
- rc = sizeof(struct raw_sock);
- return rc;
-}
-
/*
* Create an inet socket.
*/
@@ -260,13 +233,12 @@
struct list_head *p;
struct inet_protosw *answer;
struct inet_opt *inet;
- int err = -ENOBUFS;
+ struct proto *answer_prot;
+ unsigned char answer_flags;
+ char answer_no_check;
+ int err;
sock->state = SS_UNCONNECTED;
- sk = sk_alloc(PF_INET, GFP_KERNEL, inet_sk_size(protocol),
- inet_sk_slab(protocol));
- if (!sk)
- goto out;
/* Look for the requested type/protocol pair. */
answer = NULL;
@@ -292,21 +264,35 @@
err = -ESOCKTNOSUPPORT;
if (!answer)
- goto out_sk_free;
+ goto out_rcu_unlock;
err = -EPERM;
if (answer->capability > 0 && !capable(answer->capability))
- goto out_sk_free;
+ goto out_rcu_unlock;
err = -EPROTONOSUPPORT;
if (!protocol)
- goto out_sk_free;
- err = 0;
+ goto out_rcu_unlock;
+
sock->ops = answer->ops;
- sk->sk_prot = answer->prot;
- sk->sk_no_check = answer->no_check;
- if (INET_PROTOSW_REUSE & answer->flags)
- sk->sk_reuse = 1;
+ answer_prot = answer->prot;
+ answer_no_check = answer->no_check;
+ answer_flags = answer->flags;
rcu_read_unlock();
+ BUG_TRAP(answer_prot->slab != NULL);
+
+ err = -ENOBUFS;
+ sk = sk_alloc(PF_INET, GFP_KERNEL,
+ answer_prot->slab_obj_size,
+ answer_prot->slab);
+ if (sk == NULL)
+ goto out;
+
+ err = 0;
+ sk->sk_prot = answer_prot;
+ sk->sk_no_check = answer_no_check;
+ if (INET_PROTOSW_REUSE & answer_flags)
+ sk->sk_reuse = 1;
+
inet = inet_sk(sk);
if (SOCK_RAW == sock->type) {
@@ -359,9 +345,8 @@
}
out:
return err;
-out_sk_free:
+out_rcu_unlock:
rcu_read_unlock();
- sk_free(sk);
goto out;
}
@@ -1010,24 +995,23 @@
struct sk_buff *dummy_skb;
struct inet_protosw *q;
struct list_head *r;
+ int rc = -EINVAL;
if (sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb)) {
printk(KERN_CRIT "%s: panic\n", __FUNCTION__);
- return -EINVAL;
+ goto out;
}
- tcp_sk_cachep = kmem_cache_create("tcp_sock",
- sizeof(struct tcp_sock), 0,
- SLAB_HWCACHE_ALIGN, NULL, NULL);
- udp_sk_cachep = kmem_cache_create("udp_sock",
- sizeof(struct udp_sock), 0,
- SLAB_HWCACHE_ALIGN, NULL, NULL);
- raw4_sk_cachep = kmem_cache_create("raw4_sock",
- sizeof(struct raw_sock), 0,
- SLAB_HWCACHE_ALIGN, NULL, NULL);
- if (!tcp_sk_cachep || !udp_sk_cachep || !raw4_sk_cachep)
- printk(KERN_CRIT
- "inet_init: Can't create protocol sock SLAB caches!\n");
+ rc = sk_alloc_slab(&tcp_prot, "tcp_sock");
+ if (rc)
+ goto out;
+ rc = sk_alloc_slab(&udp_prot, "udp_sock");
+ if (rc)
+ goto out_tcp_free_slab;
+ rc = sk_alloc_slab(&raw_prot, "raw_sock");
+ if (rc)
+ goto out_udp_free_slab;
+
/*
* Tell SOCKET that we are alive...
*/
@@ -1097,7 +1081,14 @@
ipfrag_init();
- return 0;
+ rc = 0;
+out:
+ return rc;
+out_tcp_free_slab:
+ sk_free_slab(&tcp_prot);
+out_udp_free_slab:
+ sk_free_slab(&udp_prot);
+ goto out;
}
module_init(inet_init);
diff -Nru a/net/ipv4/raw.c b/net/ipv4/raw.c
--- a/net/ipv4/raw.c 2004-09-11 00:15:42 -03:00
+++ b/net/ipv4/raw.c 2004-09-11 00:15:42 -03:00
@@ -719,6 +719,7 @@
.backlog_rcv = raw_rcv_skb,
.hash = raw_v4_hash,
.unhash = raw_v4_unhash,
+ .slab_obj_size = sizeof(struct raw_sock),
};
#ifdef CONFIG_PROC_FS
diff -Nru a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
--- a/net/ipv4/tcp_ipv4.c 2004-09-11 00:15:42 -03:00
+++ b/net/ipv4/tcp_ipv4.c 2004-09-11 00:15:42 -03:00
@@ -2617,6 +2617,7 @@
.sysctl_wmem = sysctl_tcp_wmem,
.sysctl_rmem = sysctl_tcp_rmem,
.max_header = MAX_TCP_HEADER,
+ .slab_obj_size = sizeof(struct tcp_sock),
};
diff -Nru a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
--- a/net/ipv4/tcp_minisocks.c 2004-09-11 00:15:42 -03:00
+++ b/net/ipv4/tcp_minisocks.c 2004-09-11 00:15:42 -03:00
@@ -687,7 +687,7 @@
/* allocate the newsk from the same slab of the master sock,
* if not, at sk_free time we'll try to free it from the wrong
* slabcache (i.e. is it TCPv4 or v6?) -acme */
- struct sock *newsk = sk_alloc(PF_INET, GFP_ATOMIC, 0, sk->sk_slab);
+ struct sock *newsk = sk_alloc(PF_INET, GFP_ATOMIC, 0, sk->sk_prot->slab);
if(newsk != NULL) {
struct tcp_opt *newtp;
diff -Nru a/net/ipv4/udp.c b/net/ipv4/udp.c
--- a/net/ipv4/udp.c 2004-09-11 00:15:42 -03:00
+++ b/net/ipv4/udp.c 2004-09-11 00:15:42 -03:00
@@ -1320,6 +1320,7 @@
.hash = udp_v4_hash,
.unhash = udp_v4_unhash,
.get_port = udp_v4_get_port,
+ .slab_obj_size = sizeof(struct udp_sock),
};
/* ------------------------------------------------------------------------ */
diff -Nru a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
--- a/net/ipv6/af_inet6.c 2004-09-11 00:15:42 -03:00
+++ b/net/ipv6/af_inet6.c 2004-09-11 00:15:42 -03:00
@@ -90,11 +90,6 @@
atomic_t inet6_sock_nr;
#endif
-/* Per protocol sock slabcache */
-kmem_cache_t *tcp6_sk_cachep;
-kmem_cache_t *udp6_sk_cachep;
-kmem_cache_t *raw6_sk_cachep;
-
/* The inetsw table contains everything that inet_create needs to
* build a new socket.
*/
@@ -110,37 +105,11 @@
#endif
}
-static __inline__ kmem_cache_t *inet6_sk_slab(int protocol)
-{
- kmem_cache_t* rc = tcp6_sk_cachep;
-
- if (protocol == IPPROTO_UDP)
- rc = udp6_sk_cachep;
- else if (protocol == IPPROTO_RAW)
- rc = raw6_sk_cachep;
- return rc;
-}
-
-static __inline__ int inet6_sk_size(int protocol)
+static inline struct ipv6_pinfo *inet6_sk_generic(struct sock *sk)
{
- int rc = sizeof(struct tcp6_sock);
+ const struct ipv6_sk_offset *offset = sk->sk_prot->af_specific;
- if (protocol == IPPROTO_UDP)
- rc = sizeof(struct udp6_sock);
- else if (protocol == IPPROTO_RAW)
- rc = sizeof(struct raw6_sock);
- return rc;
-}
-
-static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk)
-{
- struct ipv6_pinfo *rc = (&((struct tcp6_sock *)sk)->inet6);
-
- if (sk->sk_protocol == IPPROTO_UDP)
- rc = (&((struct udp6_sock *)sk)->inet6);
- else if (sk->sk_protocol == IPPROTO_RAW)
- rc = (&((struct raw6_sock *)sk)->inet6);
- return rc;
+ return (struct ipv6_pinfo *)(((u8 *)sk) + offset->offset);
}
static int inet6_create(struct socket *sock, int protocol)
@@ -151,11 +120,10 @@
struct tcp6_sock* tcp6sk;
struct list_head *p;
struct inet_protosw *answer;
-
- sk = sk_alloc(PF_INET6, GFP_KERNEL, inet6_sk_size(protocol),
- inet6_sk_slab(protocol));
- if (sk == NULL)
- goto do_oom;
+ struct proto *answer_prot;
+ unsigned char answer_flags;
+ char answer_no_check;
+ int rc;
/* Look for the requested type/protocol pair. */
answer = NULL;
@@ -179,22 +147,40 @@
answer = NULL;
}
+ rc = -ESOCKTNOSUPPORT;
if (!answer)
- goto free_and_badtype;
+ goto out_rcu_unlock;
+ rc = -EPERM;
if (answer->capability > 0 && !capable(answer->capability))
- goto free_and_badperm;
+ goto out_rcu_unlock;
+ rc = -EPROTONOSUPPORT;
if (!protocol)
- goto free_and_noproto;
+ goto out_rcu_unlock;
sock->ops = answer->ops;
+
+ answer_prot = answer->prot;
+ answer_no_check = answer->no_check;
+ answer_flags = answer->flags;
+ rcu_read_unlock();
+
+ BUG_TRAP(answer_prot->slab != NULL);
+
+ rc = -ENOBUFS;
+ sk = sk_alloc(PF_INET6, GFP_KERNEL,
+ answer_prot->slab_obj_size,
+ answer_prot->slab);
+ if (sk == NULL)
+ goto out;
+
sock_init_data(sock, sk);
sk_set_owner(sk, THIS_MODULE);
- sk->sk_prot = answer->prot;
- sk->sk_no_check = answer->no_check;
- if (INET_PROTOSW_REUSE & answer->flags)
+ rc = 0;
+ sk->sk_prot = answer_prot;
+ sk->sk_no_check = answer_no_check;
+ if (INET_PROTOSW_REUSE & answer_flags)
sk->sk_reuse = 1;
- rcu_read_unlock();
inet = inet_sk(sk);
@@ -248,28 +234,17 @@
sk->sk_prot->hash(sk);
}
if (sk->sk_prot->init) {
- int err = sk->sk_prot->init(sk);
- if (err != 0) {
+ rc = sk->sk_prot->init(sk);
+ if (rc) {
sk_common_release(sk);
- return err;
+ goto out;
}
}
- return 0;
-
-free_and_badtype:
- rcu_read_unlock();
- sk_free(sk);
- return -ESOCKTNOSUPPORT;
-free_and_badperm:
- rcu_read_unlock();
- sk_free(sk);
- return -EPERM;
-free_and_noproto:
+out:
+ return rc;
+out_rcu_unlock:
rcu_read_unlock();
- sk_free(sk);
- return -EPROTONOSUPPORT;
-do_oom:
- return -ENOBUFS;
+ goto out;
}
@@ -709,24 +684,20 @@
#endif
#endif
- if (sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb))
- {
+ if (sizeof(struct inet6_skb_parm) > sizeof(dummy_skb->cb)) {
printk(KERN_CRIT "inet6_proto_init: size fault\n");
return -EINVAL;
}
- /* allocate our sock slab caches */
- tcp6_sk_cachep = kmem_cache_create("tcp6_sock",
- sizeof(struct tcp6_sock), 0,
- SLAB_HWCACHE_ALIGN, NULL, NULL);
- udp6_sk_cachep = kmem_cache_create("udp6_sock",
- sizeof(struct udp6_sock), 0,
- SLAB_HWCACHE_ALIGN, NULL, NULL);
- raw6_sk_cachep = kmem_cache_create("raw6_sock",
- sizeof(struct raw6_sock), 0,
- SLAB_HWCACHE_ALIGN, NULL, NULL);
- if (!tcp6_sk_cachep || !udp6_sk_cachep || !raw6_sk_cachep)
- printk(KERN_CRIT "%s: Can't create protocol sock SLAB "
- "caches!\n", __FUNCTION__);
+
+ err = sk_alloc_slab(&tcpv6_prot, "tcpv6_sock");
+ if (err)
+ goto out;
+ err = sk_alloc_slab(&udpv6_prot, "udpv6_sock");
+ if (err)
+ goto out_tcp_free_slab;
+ err = sk_alloc_slab(&rawv6_prot, "rawv6_sock");
+ if (err)
+ goto out_udp_free_slab;
/* Register the socket-side information for inet6_create. */
for(r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r)
@@ -745,7 +716,7 @@
/* Initialise ipv6 mibs */
err = init_ipv6_mibs();
if (err)
- goto init_mib_fail;
+ goto out_raw_free_slab;
/*
* ipngwg API draft makes clear that the correct semantics
@@ -798,8 +769,9 @@
/* Init v6 transport protocols. */
udpv6_init();
tcpv6_init();
-
- return 0;
+ err = 0;
+out:
+ return err;
#ifdef CONFIG_PROC_FS
proc_if6_fail:
@@ -824,8 +796,13 @@
ipv6_sysctl_unregister();
#endif
cleanup_ipv6_mibs();
-init_mib_fail:
- return err;
+out_raw_free_slab:
+ sk_free_slab(&rawv6_prot);
+out_udp_free_slab:
+ sk_free_slab(&udpv6_prot);
+out_tcp_free_slab:
+ sk_free_slab(&tcpv6_prot);
+ goto out;
}
module_init(inet6_init);
@@ -854,9 +831,9 @@
ipv6_sysctl_unregister();
#endif
cleanup_ipv6_mibs();
- kmem_cache_destroy(tcp6_sk_cachep);
- kmem_cache_destroy(udp6_sk_cachep);
- kmem_cache_destroy(raw6_sk_cachep);
+ sk_free_slab(&rawv6_prot);
+ sk_free_slab(&udpv6_prot);
+ sk_free_slab(&tcpv6_prot);
}
module_exit(inet6_exit);
diff -Nru a/net/ipv6/raw.c b/net/ipv6/raw.c
--- a/net/ipv6/raw.c 2004-09-11 00:15:42 -03:00
+++ b/net/ipv6/raw.c 2004-09-11 00:15:42 -03:00
@@ -973,6 +973,10 @@
return(0);
}
+struct ipv6_sk_offset raw_sock_offset = {
+ .offset = offsetof(struct udp6_sock, inet6),
+};
+
struct proto rawv6_prot = {
.name = "RAW",
.close = rawv6_close,
@@ -989,6 +993,8 @@
.backlog_rcv = rawv6_rcv_skb,
.hash = raw_v6_hash,
.unhash = raw_v6_unhash,
+ .slab_obj_size = sizeof(struct raw6_sock),
+ .af_specific = &raw_sock_offset,
};
#ifdef CONFIG_PROC_FS
diff -Nru a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
--- a/net/ipv6/tcp_ipv6.c 2004-09-11 00:15:42 -03:00
+++ b/net/ipv6/tcp_ipv6.c 2004-09-11 00:15:42 -03:00
@@ -2119,6 +2119,10 @@
}
#endif
+struct ipv6_sk_offset tcp_sock_offset = {
+ .offset = offsetof(struct tcp6_sock, inet6),
+};
+
struct proto tcpv6_prot = {
.name = "TCPv6",
.close = tcp_close,
@@ -2145,6 +2149,8 @@
.sysctl_wmem = sysctl_tcp_wmem,
.sysctl_rmem = sysctl_tcp_rmem,
.max_header = MAX_TCP_HEADER,
+ .slab_obj_size = sizeof(struct tcp6_sock),
+ .af_specific = &tcp_sock_offset,
};
static struct inet6_protocol tcpv6_protocol = {
diff -Nru a/net/ipv6/udp.c b/net/ipv6/udp.c
--- a/net/ipv6/udp.c 2004-09-11 00:15:42 -03:00
+++ b/net/ipv6/udp.c 2004-09-11 00:15:42 -03:00
@@ -1031,6 +1031,10 @@
/* ------------------------------------------------------------------------ */
+struct ipv6_sk_offset udp_sock_offset = {
+ .offset = offsetof(struct udp6_sock, inet6),
+};
+
struct proto udpv6_prot = {
.name = "UDP",
.close = udpv6_close,
@@ -1046,6 +1050,8 @@
.hash = udp_v6_hash,
.unhash = udp_v6_unhash,
.get_port = udp_v6_get_port,
+ .slab_obj_size = sizeof(struct udp6_sock),
+ .af_specific = &udp_sock_offset,
};
extern struct proto_ops inet6_dgram_ops;
diff -Nru a/net/sctp/ipv6.c b/net/sctp/ipv6.c
--- a/net/sctp/ipv6.c 2004-09-11 00:15:42 -03:00
+++ b/net/sctp/ipv6.c 2004-09-11 00:15:42 -03:00
@@ -583,8 +583,8 @@
struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
struct sctp6_sock *newsctp6sk;
- newsk = sk_alloc(PF_INET6, GFP_KERNEL, sizeof(struct sctp6_sock),
- sk->sk_slab);
+ newsk = sk_alloc(PF_INET6, GFP_KERNEL, sk->sk_prot->slab_obj_size,
+ sk->sk_prot->slab);
if (!newsk)
goto out;
@@ -892,7 +892,7 @@
static struct inet_protosw sctpv6_seqpacket_protosw = {
.type = SOCK_SEQPACKET,
.protocol = IPPROTO_SCTP,
- .prot = &sctp_prot,
+ .prot = &sctpv6_prot,
.ops = &inet6_seqpacket_ops,
.capability = -1,
.no_check = 0,
@@ -901,7 +901,7 @@
static struct inet_protosw sctpv6_stream_protosw = {
.type = SOCK_STREAM,
.protocol = IPPROTO_SCTP,
- .prot = &sctp_prot,
+ .prot = &sctpv6_prot,
.ops = &inet6_seqpacket_ops,
.capability = -1,
.no_check = 0,
@@ -963,9 +963,14 @@
/* Initialize IPv6 support and register with inet6 stack. */
int sctp_v6_init(void)
{
+ int rc = sk_alloc_slab(&sctpv6_prot, "sctpv6_sock");
+
+ if (rc)
+ goto out;
/* Register inet6 protocol. */
+ rc = -EAGAIN;
if (inet6_add_protocol(&sctpv6_protocol, IPPROTO_SCTP) < 0)
- return -EAGAIN;
+ goto out_sctp_free_slab;
/* Add SCTPv6(UDP and TCP style) to inetsw6 linked list. */
inet6_register_protosw(&sctpv6_seqpacket_protosw);
@@ -979,8 +984,12 @@
/* Register notifier for inet6 address additions/deletions. */
register_inet6addr_notifier(&sctp_inetaddr_notifier);
-
- return 0;
+ rc = 0;
+out:
+ return rc;
+out_sctp_free_slab:
+ sk_free_slab(&sctpv6_prot);
+ goto out;
}
/* IPv6 specific exit support. */
@@ -991,4 +1000,5 @@
inet6_unregister_protosw(&sctpv6_seqpacket_protosw);
inet6_unregister_protosw(&sctpv6_stream_protosw);
unregister_inet6addr_notifier(&sctp_inetaddr_notifier);
+ sk_free_slab(&sctpv6_prot);
}
diff -Nru a/net/sctp/protocol.c b/net/sctp/protocol.c
--- a/net/sctp/protocol.c 2004-09-11 00:15:42 -03:00
+++ b/net/sctp/protocol.c 2004-09-11 00:15:42 -03:00
@@ -554,8 +554,8 @@
struct inet_opt *inet = inet_sk(sk);
struct inet_opt *newinet;
- newsk = sk_alloc(PF_INET, GFP_KERNEL, sizeof(struct sctp_sock),
- sk->sk_slab);
+ newsk = sk_alloc(PF_INET, GFP_KERNEL, sk->sk_prot->slab_obj_size,
+ sk->sk_prot->slab);
if (!newsk)
goto out;
@@ -962,23 +962,29 @@
__init int sctp_init(void)
{
int i;
- int status = 0;
+ int status = -EINVAL;
unsigned long goal;
int order;
/* SCTP_DEBUG sanity check. */
if (!sctp_sanity_check())
- return -EINVAL;
+ goto out;
+
+ status = sk_alloc_slab(&sctp_prot, "sctp_sock");
+ if (status)
+ goto out;
/* Add SCTP to inet_protos hash table. */
+ status = -EAGAIN;
if (inet_add_protocol(&sctp_protocol, IPPROTO_SCTP) < 0)
- return -EAGAIN;
+ goto err_add_protocol;
/* Add SCTP(TCP and UDP style) to inetsw linked list. */
inet_register_protosw(&sctp_seqpacket_protosw);
inet_register_protosw(&sctp_stream_protosw);
/* Allocate a cache pools. */
+ status = -ENOBUFS;
sctp_bucket_cachep = kmem_cache_create("sctp_bind_bucket",
sizeof(struct sctp_bind_bucket),
0, SLAB_HWCACHE_ALIGN,
@@ -1154,8 +1160,11 @@
sctp_get_local_addr_list();
__unsafe(THIS_MODULE);
- return 0;
-
+ status = 0;
+out:
+ return status;
+err_add_protocol:
+ sk_free_slab(&sctp_prot);
err_ctl_sock_init:
sctp_v6_exit();
err_v6_init:
@@ -1183,7 +1192,7 @@
inet_del_protocol(&sctp_protocol, IPPROTO_SCTP);
inet_unregister_protosw(&sctp_seqpacket_protosw);
inet_unregister_protosw(&sctp_stream_protosw);
- return status;
+ goto out;
}
/* Exit handler for the SCTP protocol. */
@@ -1224,6 +1233,7 @@
inet_del_protocol(&sctp_protocol, IPPROTO_SCTP);
inet_unregister_protosw(&sctp_seqpacket_protosw);
inet_unregister_protosw(&sctp_stream_protosw);
+ sk_free_slab(&sctp_prot);
}
module_init(sctp_init);
diff -Nru a/net/sctp/socket.c b/net/sctp/socket.c
--- a/net/sctp/socket.c 2004-09-11 00:15:42 -03:00
+++ b/net/sctp/socket.c 2004-09-11 00:15:42 -03:00
@@ -4622,4 +4622,34 @@
.hash = sctp_hash,
.unhash = sctp_unhash,
.get_port = sctp_get_port,
+ .slab_obj_size = sizeof(struct sctp_sock),
};
+
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+struct ipv6_sk_offset sctp_sock_offset = {
+ .offset = offsetof(struct sctp6_sock, inet6),
+};
+
+struct proto sctpv6_prot = {
+ .name = "SCTPv6",
+ .close = sctp_close,
+ .connect = sctp_connect,
+ .disconnect = sctp_disconnect,
+ .accept = sctp_accept,
+ .ioctl = sctp_ioctl,
+ .init = sctp_init_sock,
+ .destroy = sctp_destroy_sock,
+ .shutdown = sctp_shutdown,
+ .setsockopt = sctp_setsockopt,
+ .getsockopt = sctp_getsockopt,
+ .sendmsg = sctp_sendmsg,
+ .recvmsg = sctp_recvmsg,
+ .bind = sctp_bind,
+ .backlog_rcv = sctp_backlog_rcv,
+ .hash = sctp_hash,
+ .unhash = sctp_unhash,
+ .get_port = sctp_get_port,
+ .slab_obj_size = sizeof(struct sctp6_sock),
+ .af_specific = &sctp_sock_offset,
+};
+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH][NET] generalise per socket slab cache use
2004-09-11 3:23 [PATCH][NET] generalise per socket slab cache use Arnaldo Carvalho de Melo
@ 2004-09-13 21:17 ` Sridhar Samudrala
2004-09-13 21:51 ` Arnaldo Carvalho de Melo
0 siblings, 1 reply; 4+ messages in thread
From: Sridhar Samudrala @ 2004-09-13 21:17 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo; +Cc: David S.Miller, YOSHIFUJI Hideaki, netdev
Arnaldo,
looks good, but i have a few comments. It is great that SCTP now has its own
slabcaches.
> +struct ipv6_sk_offset raw_sock_offset = {
> + .offset = offsetof(struct udp6_sock, inet6),
> +};
I think there is a typo here. udp6_sock should be raw6_sock
> - printk(KERN_CRIT "%s: Can't create protocol sock SLAB "
> - "caches!\n", __FUNCTION__);
You have removed the above critical messages. Is this by intent or a mistake.
I am not clear on why we need this new structure ipv6_sk_offset.
> +struct ipv6_sk_offset {
> + int offset;
> +};
> +
Instead of adding the new field void *af_specific to struct proto, is it not
sufficient to add
int pinet6_offset;
and assign it as follows for each v6 sock type
.pinet6_offset = offsetof(struct struct tcp6_sock, inet6)
In inet6_sk_generic(), you can directly use sk->sk_prot->pinet6_offset.
Thanks
Sridhar
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH][NET] generalise per socket slab cache use
2004-09-13 21:17 ` Sridhar Samudrala
@ 2004-09-13 21:51 ` Arnaldo Carvalho de Melo
2004-09-13 22:55 ` David S. Miller
0 siblings, 1 reply; 4+ messages in thread
From: Arnaldo Carvalho de Melo @ 2004-09-13 21:51 UTC (permalink / raw)
To: Sridhar Samudrala; +Cc: David S.Miller, YOSHIFUJI Hideaki, netdev
Em Seg 13 Set 2004 18:17, Sridhar Samudrala escreveu:
> Arnaldo,
>
> looks good, but i have a few comments. It is great that SCTP now has its
> own slabcaches.
>
> > +struct ipv6_sk_offset raw_sock_offset = {
> > + .offset = offsetof(struct udp6_sock, inet6),
> > +};
>
> I think there is a typo here. udp6_sock should be raw6_sock
Good spotting! I'll fix this one
> > - printk(KERN_CRIT "%s: Can't create protocol sock SLAB "
> > - "caches!\n", __FUNCTION__);
>
> You have removed the above critical messages. Is this by intent or a
> mistake.
Humm, I'll put it on the sk_alloc_slab callers
>
> I am not clear on why we need this new structure ipv6_sk_offset.
>
> > +struct ipv6_sk_offset {
> > + int offset;
> > +};
> > +
>
> Instead of adding the new field void *af_specific to struct proto, is it
> not sufficient to add
> int pinet6_offset;
>
> and assign it as follows for each v6 sock type
> .pinet6_offset = offsetof(struct struct tcp6_sock, inet6)
>
> In inet6_sk_generic(), you can directly use sk->sk_prot->pinet6_offset.
I thought about it, but idea was to not introduce any family specific stuff in
struct proto, I don't plan to have LLC over IPv6, for instance :)
> Thanks
> Sridhar
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH][NET] generalise per socket slab cache use
2004-09-13 21:51 ` Arnaldo Carvalho de Melo
@ 2004-09-13 22:55 ` David S. Miller
0 siblings, 0 replies; 4+ messages in thread
From: David S. Miller @ 2004-09-13 22:55 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo; +Cc: sri, davem, yoshfuji, netdev
On Mon, 13 Sep 2004 18:51:08 -0300
Arnaldo Carvalho de Melo <acme@conectiva.com.br> wrote:
> > I think there is a typo here. udp6_sock should be raw6_sock
>
> Good spotting! I'll fix this one
Let me know when the fixed version is available, thanks.
:)
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2004-09-13 22:55 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-09-11 3:23 [PATCH][NET] generalise per socket slab cache use Arnaldo Carvalho de Melo
2004-09-13 21:17 ` Sridhar Samudrala
2004-09-13 21:51 ` Arnaldo Carvalho de Melo
2004-09-13 22:55 ` David S. Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).