From 4fbd6c6f38a41a887a15bd849782bf546883d57a Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Fri, 18 May 2007 11:24:47 -0400 Subject: [PATCH 4/4] [SCTP] Convert the endpoint listen hash to use inet hashes We still need our own lookup function since we do different address matching. May be somthing to improve in generic inet layer. Signed-off-by: Vlad Yasevich --- include/net/sctp/sctp.h | 2 +- include/net/sctp/structs.h | 8 +---- net/sctp/endpointola.c | 4 +- net/sctp/input.c | 61 ++++++------------------------------------- net/sctp/proc.c | 14 +++++----- net/sctp/protocol.c | 16 +---------- net/sctp/socket.c | 4 +- 7 files changed, 25 insertions(+), 84 deletions(-) diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index af5e288..79ca202 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -620,7 +620,7 @@ static inline int sctp_phashfn(__u16 lport) /* This is the hash function for the endpoint hash table. */ static inline int sctp_ep_hashfn(__u16 lport) { - return (lport & (sctp_ep_hashsize - 1)); + return inet_lhashfn(lport); } /* This is the hash function for the association hash table. */ diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 906e0a2..25ece1f 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -171,10 +171,6 @@ extern struct sctp_globals { */ struct list_head address_families; - /* This is the hash of all endpoints. */ - int ep_hashsize; - struct sctp_hashbucket *ep_hashtable; - /* This is the hash of all associations. */ int assoc_hashsize; struct sctp_hashbucket *assoc_hashtable; @@ -214,8 +210,6 @@ extern struct inet_hashinfo sctp_hashinfo; #define sctp_max_instreams (sctp_globals.max_instreams) #define sctp_max_outstreams (sctp_globals.max_outstreams) #define sctp_address_families (sctp_globals.address_families) -#define sctp_ep_hashsize (sctp_globals.ep_hashsize) -#define sctp_ep_hashtable (sctp_globals.ep_hashtable) #define sctp_assoc_hashsize (sctp_globals.assoc_hashsize) #define sctp_assoc_hashtable (sctp_globals.assoc_hashtable) #define sctp_local_addr_list (sctp_globals.local_addr_list) @@ -227,6 +221,8 @@ extern struct inet_hashinfo sctp_hashinfo; #define sctp_bucket_cachep (sctp_hashinfo.bind_bucket_cachep) #define sctp_port_hashsize (sctp_hashinfo.bhash_size) #define sctp_port_hashtable (sctp_hashinfo.bhash) +#define sctp_ep_hashsize INET_LHTABLE_SIZE +#define sctp_ep_hashtable (sctp_hashinfo.listening_hash) /* SCTP Socket type: UDP or TCP style. */ typedef enum { diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index cb932c2..5b3ab0f 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c @@ -168,11 +168,11 @@ void sctp_endpoint_free(struct sctp_endpoint *ep) { ep->base.dead = 1; - ep->base.sk->sk_state = SCTP_SS_CLOSED; - /* Unlink this endpoint, so we can't find it again! */ sctp_unhash_endpoint(ep); + ep->base.sk->sk_state = SCTP_SS_CLOSED; + sctp_endpoint_put(ep); } diff --git a/net/sctp/input.c b/net/sctp/input.c index e83fe9e..5741b84 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -651,82 +651,39 @@ discard: return 1; } -/* Insert endpoint into the hash table. */ -static void __sctp_hash_endpoint(struct sctp_endpoint *ep) -{ - struct sctp_ep_common *epb; - struct sctp_hashbucket *head; - - epb = &ep->base; - - epb->hashent = sctp_ep_hashfn(epb->bind_addr.port); - head = &sctp_ep_hashtable[epb->hashent]; - - sctp_write_lock(&head->lock); - hlist_add_head(&epb->node, &head->chain); - sctp_write_unlock(&head->lock); -} - /* Add an endpoint to the hash. Local BH-safe. */ void sctp_hash_endpoint(struct sctp_endpoint *ep) { - sctp_local_bh_disable(); - __sctp_hash_endpoint(ep); - sctp_local_bh_enable(); -} - -/* Remove endpoint from the hash table. */ -static void __sctp_unhash_endpoint(struct sctp_endpoint *ep) -{ - struct sctp_hashbucket *head; - struct sctp_ep_common *epb; - - epb = &ep->base; - - if (hlist_unhashed(&epb->node)) - return; - - epb->hashent = sctp_ep_hashfn(epb->bind_addr.port); - - head = &sctp_ep_hashtable[epb->hashent]; - - sctp_write_lock(&head->lock); - __hlist_del(&epb->node); - sctp_write_unlock(&head->lock); + inet_hash(&sctp_hashinfo, ep->base.sk); } /* Remove endpoint from the hash. Local BH-safe. */ void sctp_unhash_endpoint(struct sctp_endpoint *ep) { - sctp_local_bh_disable(); - __sctp_unhash_endpoint(ep); - sctp_local_bh_enable(); + inet_unhash(&sctp_hashinfo, ep->base.sk); } /* Look up an endpoint. */ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *laddr) { - struct sctp_hashbucket *head; - struct sctp_ep_common *epb; + struct hlist_head *head; + struct sock *sk = NULL; struct sctp_endpoint *ep; struct hlist_node *node; - int hash; - hash = sctp_ep_hashfn(ntohs(laddr->v4.sin_port)); - head = &sctp_ep_hashtable[hash]; - read_lock(&head->lock); - hlist_for_each_entry(epb, node, &head->chain, node) { - ep = sctp_ep(epb); + read_lock(&sctp_hashinfo.lhash_lock); + head = &sctp_ep_hashtable[sctp_ep_hashfn(ntohs(laddr->v4.sin_port))]; + sk_for_each(sk, node, head) { + ep = sctp_sk(sk)->ep;; if (sctp_endpoint_is_match(ep, laddr)) goto hit; } ep = sctp_sk((sctp_get_ctl_sock()))->ep; - epb = &ep->base; hit: sctp_endpoint_hold(ep); - read_unlock(&head->lock); + read_unlock(&sctp_hashinfo.lhash_lock); return ep; } diff --git a/net/sctp/proc.c b/net/sctp/proc.c index 18f89e3..53c137c 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c @@ -221,7 +221,7 @@ static void * sctp_eps_seq_next(struct seq_file *seq, void *v, loff_t *pos) /* Display sctp endpoints (/proc/net/sctp/eps). */ static int sctp_eps_seq_show(struct seq_file *seq, void *v) { - struct sctp_hashbucket *head; + struct hlist_head *head; struct sctp_ep_common *epb; struct sctp_endpoint *ep; struct sock *sk; @@ -231,12 +231,12 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v) if (hash >= sctp_ep_hashsize) return -ENOMEM; - head = &sctp_ep_hashtable[hash]; sctp_local_bh_disable(); - read_lock(&head->lock); - hlist_for_each_entry(epb, node, &head->chain, node) { - ep = sctp_ep(epb); - sk = epb->sk; + read_lock(&sctp_hashinfo.lhash_lock); + head = &sctp_ep_hashtable[hash]; + sk_for_each(sk, node, head) { + ep = sctp_sk(sk)->ep; + epb = &ep->base; seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk, sctp_sk(sk)->type, sk->sk_state, hash, epb->bind_addr.port, @@ -245,7 +245,7 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v) sctp_seq_dump_local_addrs(seq, epb); seq_printf(seq, "\n"); } - read_unlock(&head->lock); + read_unlock(&sctp_hashinfo.lhash_lock); sctp_local_bh_enable(); return 0; diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 84334ef..ba7ba85 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -1095,18 +1095,9 @@ SCTP_STATIC __init int sctp_init(void) INIT_HLIST_HEAD(&sctp_assoc_hashtable[i].chain); } - /* Allocate and initialize the endpoint hash table. */ - sctp_ep_hashsize = 64; - sctp_ep_hashtable = (struct sctp_hashbucket *) - kmalloc(64 * sizeof(struct sctp_hashbucket), GFP_KERNEL); - if (!sctp_ep_hashtable) { - printk(KERN_ERR "SCTP: Failed endpoint_hash alloc.\n"); - status = -ENOMEM; - goto err_ehash_alloc; - } + /* Initialize the endpoint listen hash */ for (i = 0; i < sctp_ep_hashsize; i++) { - rwlock_init(&sctp_ep_hashtable[i].lock); - INIT_HLIST_HEAD(&sctp_ep_hashtable[i].chain); + INIT_HLIST_HEAD(&sctp_ep_hashtable[i]); } /* Allocate and initialize the SCTP port hash table. */ @@ -1203,8 +1194,6 @@ err_proto_register: get_order(sctp_port_hashsize * sizeof(struct inet_bind_hashbucket))); err_bhash_alloc: - kfree(sctp_ep_hashtable); -err_ehash_alloc: free_pages((unsigned long)sctp_assoc_hashtable, get_order(sctp_assoc_hashsize * sizeof(struct sctp_hashbucket))); @@ -1253,7 +1242,6 @@ SCTP_STATIC __exit void sctp_exit(void) free_pages((unsigned long)sctp_assoc_hashtable, get_order(sctp_assoc_hashsize * sizeof(struct sctp_hashbucket))); - kfree(sctp_ep_hashtable); free_pages((unsigned long)sctp_port_hashtable, get_order(sctp_port_hashsize * sizeof(struct inet_bind_hashbucket))); diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 7aec624..6499b37 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -4940,12 +4940,12 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, static void sctp_hash(struct sock *sk) { - /* STUB */ + sctp_hash_endpoint(sctp_sk(sk)->ep); } static void sctp_unhash(struct sock *sk) { - /* STUB */ + sctp_unhash_endpoint(sctp_sk(sk)->ep); } /* Check if port is acceptable. Possibly find first available port. -- 1.5.2.4