Commit 3b7119f4 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo Committed by David S. Miller

[IPX] use a private slab cache for socks

Renaming ipx_opt to ipx_sock, tested with mars-nwe/ncpmount.
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@conectiva.com.br>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent aced97aa
...@@ -90,7 +90,11 @@ struct ipx_cb { ...@@ -90,7 +90,11 @@ struct ipx_cb {
} last_hop; } last_hop;
}; };
struct ipx_opt { #include <net/sock.h>
struct ipx_sock {
/* struct sock has to be the first member of ipx_sock */
struct sock sk;
struct ipx_address dest_addr; struct ipx_address dest_addr;
struct ipx_interface *intrfc; struct ipx_interface *intrfc;
unsigned short port; unsigned short port;
...@@ -105,9 +109,14 @@ struct ipx_opt { ...@@ -105,9 +109,14 @@ struct ipx_opt {
unsigned short ipx_ncp_conn; unsigned short ipx_ncp_conn;
}; };
#define ipx_sk(__sk) ((struct ipx_opt *)(__sk)->sk_protinfo) static inline struct ipx_sock *ipx_sk(struct sock *sk)
{
return (struct ipx_sock *)sk;
}
#define IPX_SKB_CB(__skb) ((struct ipx_cb *)&((__skb)->cb[0])) #define IPX_SKB_CB(__skb) ((struct ipx_cb *)&((__skb)->cb[0]))
#endif #endif
#define IPX_MIN_EPHEMERAL_SOCKET 0x4000 #define IPX_MIN_EPHEMERAL_SOCKET 0x4000
#define IPX_MAX_EPHEMERAL_SOCKET 0x7fff #define IPX_MAX_EPHEMERAL_SOCKET 0x7fff
......
...@@ -80,6 +80,8 @@ static struct proto_ops ipx_dgram_ops; ...@@ -80,6 +80,8 @@ static struct proto_ops ipx_dgram_ops;
LIST_HEAD(ipx_interfaces); LIST_HEAD(ipx_interfaces);
DEFINE_SPINLOCK(ipx_interfaces_lock); DEFINE_SPINLOCK(ipx_interfaces_lock);
static kmem_cache_t *ipx_sk_slab;
struct ipx_interface *ipx_primary_net; struct ipx_interface *ipx_primary_net;
struct ipx_interface *ipx_internal_net; struct ipx_interface *ipx_internal_net;
...@@ -277,7 +279,7 @@ static struct sock *ipxitf_find_internal_socket(struct ipx_interface *intrfc, ...@@ -277,7 +279,7 @@ static struct sock *ipxitf_find_internal_socket(struct ipx_interface *intrfc,
spin_lock_bh(&intrfc->if_sklist_lock); spin_lock_bh(&intrfc->if_sklist_lock);
sk_for_each(s, node, &intrfc->if_sklist) { sk_for_each(s, node, &intrfc->if_sklist) {
struct ipx_opt *ipxs = ipx_sk(s); struct ipx_sock *ipxs = ipx_sk(s);
if (ipxs->port == port && if (ipxs->port == port &&
!memcmp(ipx_node, ipxs->node, IPX_NODE_LEN)) !memcmp(ipx_node, ipxs->node, IPX_NODE_LEN))
...@@ -302,7 +304,7 @@ static void __ipxitf_down(struct ipx_interface *intrfc) ...@@ -302,7 +304,7 @@ static void __ipxitf_down(struct ipx_interface *intrfc)
spin_lock_bh(&intrfc->if_sklist_lock); spin_lock_bh(&intrfc->if_sklist_lock);
/* error sockets */ /* error sockets */
sk_for_each_safe(s, node, t, &intrfc->if_sklist) { sk_for_each_safe(s, node, t, &intrfc->if_sklist) {
struct ipx_opt *ipxs = ipx_sk(s); struct ipx_sock *ipxs = ipx_sk(s);
s->sk_err = ENOLINK; s->sk_err = ENOLINK;
s->sk_error_report(s); s->sk_error_report(s);
...@@ -400,7 +402,7 @@ static int ipxitf_demux_socket(struct ipx_interface *intrfc, ...@@ -400,7 +402,7 @@ static int ipxitf_demux_socket(struct ipx_interface *intrfc,
spin_lock_bh(&intrfc->if_sklist_lock); spin_lock_bh(&intrfc->if_sklist_lock);
sk_for_each(s, node, &intrfc->if_sklist) { sk_for_each(s, node, &intrfc->if_sklist) {
struct ipx_opt *ipxs = ipx_sk(s); struct ipx_sock *ipxs = ipx_sk(s);
if (ipxs->port == ipx->ipx_dest.sock && if (ipxs->port == ipx->ipx_dest.sock &&
(is_broadcast || !memcmp(ipx->ipx_dest.node, (is_broadcast || !memcmp(ipx->ipx_dest.node,
...@@ -1348,32 +1350,21 @@ static int ipx_getsockopt(struct socket *sock, int level, int optname, ...@@ -1348,32 +1350,21 @@ static int ipx_getsockopt(struct socket *sock, int level, int optname,
static int ipx_create(struct socket *sock, int protocol) static int ipx_create(struct socket *sock, int protocol)
{ {
int rc = -ESOCKTNOSUPPORT; int rc = -ESOCKTNOSUPPORT;
struct ipx_opt *ipx = NULL;
struct sock *sk; struct sock *sk;
switch (sock->type) { /*
case SOCK_DGRAM: * SPX support is not anymore in the kernel sources. If you want to
sk = sk_alloc(PF_IPX, GFP_KERNEL, 1, NULL); * ressurrect it, completing it and making it understand shared skbs,
rc = -ENOMEM; * be fully multithreaded, etc, grab the sources in an early 2.5 kernel
if (!sk) * tree.
goto out; */
ipx = sk->sk_protinfo = kmalloc(sizeof(*ipx), GFP_KERNEL); if (sock->type != SOCK_DGRAM)
if (!ipx) goto out;
goto outsk;
memset(ipx, 0, sizeof(*ipx)); sk = sk_alloc(PF_IPX, GFP_KERNEL, sizeof(struct ipx_sock), ipx_sk_slab);
sock->ops = &ipx_dgram_ops; rc = -ENOMEM;
break; if (!sk)
case SOCK_SEQPACKET:
/*
* SPX support is not anymore in the kernel sources. If
* you want to ressurrect it, completing it and making
* it understand shared skbs, be fully multithreaded,
* etc, grab the sources in an early 2.5 kernel tree.
*/
case SOCK_STREAM: /* Allow higher levels to piggyback */
default:
goto out; goto out;
}
#ifdef IPX_REFCNT_DEBUG #ifdef IPX_REFCNT_DEBUG
atomic_inc(&ipx_sock_nr); atomic_inc(&ipx_sock_nr);
printk(KERN_DEBUG "IPX socket %p created, now we have %d alive\n", sk, printk(KERN_DEBUG "IPX socket %p created, now we have %d alive\n", sk,
...@@ -1382,12 +1373,10 @@ static int ipx_create(struct socket *sock, int protocol) ...@@ -1382,12 +1373,10 @@ static int ipx_create(struct socket *sock, int protocol)
sock_init_data(sock, sk); sock_init_data(sock, sk);
sk_set_owner(sk, THIS_MODULE); sk_set_owner(sk, THIS_MODULE);
sk->sk_no_check = 1; /* Checksum off by default */ sk->sk_no_check = 1; /* Checksum off by default */
sock->ops = &ipx_dgram_ops;
rc = 0; rc = 0;
out: out:
return rc; return rc;
outsk:
sk_free(sk);
goto out;
} }
static int ipx_release(struct socket *sock) static int ipx_release(struct socket *sock)
...@@ -1433,7 +1422,7 @@ static unsigned short ipx_first_free_socketnum(struct ipx_interface *intrfc) ...@@ -1433,7 +1422,7 @@ static unsigned short ipx_first_free_socketnum(struct ipx_interface *intrfc)
static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct ipx_opt *ipxs = ipx_sk(sk); struct ipx_sock *ipxs = ipx_sk(sk);
struct ipx_interface *intrfc; struct ipx_interface *intrfc;
struct sockaddr_ipx *addr = (struct sockaddr_ipx *)uaddr; struct sockaddr_ipx *addr = (struct sockaddr_ipx *)uaddr;
int rc = -EINVAL; int rc = -EINVAL;
...@@ -1529,7 +1518,7 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, ...@@ -1529,7 +1518,7 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr,
int addr_len, int flags) int addr_len, int flags)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct ipx_opt *ipxs = ipx_sk(sk); struct ipx_sock *ipxs = ipx_sk(sk);
struct sockaddr_ipx *addr; struct sockaddr_ipx *addr;
int rc = -EINVAL; int rc = -EINVAL;
struct ipx_route *rt; struct ipx_route *rt;
...@@ -1593,7 +1582,7 @@ static int ipx_getname(struct socket *sock, struct sockaddr *uaddr, ...@@ -1593,7 +1582,7 @@ static int ipx_getname(struct socket *sock, struct sockaddr *uaddr,
struct ipx_address *addr; struct ipx_address *addr;
struct sockaddr_ipx sipx; struct sockaddr_ipx sipx;
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct ipx_opt *ipxs = ipx_sk(sk); struct ipx_sock *ipxs = ipx_sk(sk);
int rc; int rc;
*uaddr_len = sizeof(struct sockaddr_ipx); *uaddr_len = sizeof(struct sockaddr_ipx);
...@@ -1693,7 +1682,7 @@ static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock, ...@@ -1693,7 +1682,7 @@ static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t len) struct msghdr *msg, size_t len)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct ipx_opt *ipxs = ipx_sk(sk); struct ipx_sock *ipxs = ipx_sk(sk);
struct sockaddr_ipx *usipx = (struct sockaddr_ipx *)msg->msg_name; struct sockaddr_ipx *usipx = (struct sockaddr_ipx *)msg->msg_name;
struct sockaddr_ipx local_sipx; struct sockaddr_ipx local_sipx;
int rc = -EINVAL; int rc = -EINVAL;
...@@ -1758,7 +1747,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock, ...@@ -1758,7 +1747,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t size, int flags) struct msghdr *msg, size_t size, int flags)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct ipx_opt *ipxs = ipx_sk(sk); struct ipx_sock *ipxs = ipx_sk(sk);
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)msg->msg_name; struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)msg->msg_name;
struct ipxhdr *ipx = NULL; struct ipxhdr *ipx = NULL;
struct sk_buff *skb; struct sk_buff *skb;
...@@ -1965,6 +1954,13 @@ static char ipx_snap_err_msg[] __initdata = ...@@ -1965,6 +1954,13 @@ static char ipx_snap_err_msg[] __initdata =
static int __init ipx_init(void) static int __init ipx_init(void)
{ {
ipx_sk_slab = kmem_cache_create("ipx_sock",
sizeof(struct ipx_sock), 0,
SLAB_HWCACHE_ALIGN, NULL, NULL);
if (ipx_sk_slab == NULL)
return -ENOMEM;
sock_register(&ipx_family_ops); sock_register(&ipx_family_ops);
pEII_datalink = make_EII_client(); pEII_datalink = make_EII_client();
...@@ -2016,6 +2012,11 @@ static void __exit ipx_proto_finito(void) ...@@ -2016,6 +2012,11 @@ static void __exit ipx_proto_finito(void)
destroy_EII_client(pEII_datalink); destroy_EII_client(pEII_datalink);
pEII_datalink = NULL; pEII_datalink = NULL;
if (ipx_sk_slab != NULL) {
kmem_cache_destroy(ipx_sk_slab);
ipx_sk_slab = NULL;
}
sock_unregister(ipx_family_ops.family); sock_unregister(ipx_family_ops.family);
} }
......
...@@ -202,7 +202,7 @@ static void *ipx_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos) ...@@ -202,7 +202,7 @@ static void *ipx_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
{ {
struct sock* sk, *next; struct sock* sk, *next;
struct ipx_interface *i; struct ipx_interface *i;
struct ipx_opt *ipxs; struct ipx_sock *ipxs;
++*pos; ++*pos;
if (v == SEQ_START_TOKEN) { if (v == SEQ_START_TOKEN) {
...@@ -243,7 +243,7 @@ static void *ipx_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos) ...@@ -243,7 +243,7 @@ static void *ipx_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
static int ipx_seq_socket_show(struct seq_file *seq, void *v) static int ipx_seq_socket_show(struct seq_file *seq, void *v)
{ {
struct sock *s; struct sock *s;
struct ipx_opt *ipxs; struct ipx_sock *ipxs;
if (v == SEQ_START_TOKEN) { if (v == SEQ_START_TOKEN) {
#ifdef CONFIG_IPX_INTERN #ifdef CONFIG_IPX_INTERN
......
...@@ -172,7 +172,7 @@ int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, ...@@ -172,7 +172,7 @@ int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx,
struct iovec *iov, size_t len, int noblock) struct iovec *iov, size_t len, int noblock)
{ {
struct sk_buff *skb; struct sk_buff *skb;
struct ipx_opt *ipxs = ipx_sk(sk); struct ipx_sock *ipxs = ipx_sk(sk);
struct ipx_interface *intrfc; struct ipx_interface *intrfc;
struct ipxhdr *ipx; struct ipxhdr *ipx;
size_t size; size_t size;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment