aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/sctp/sctp.h3
-rw-r--r--include/net/sctp/structs.h10
-rw-r--r--net/sctp/endpointola.c3
-rw-r--r--net/sctp/input.c43
-rw-r--r--net/sctp/proc.c6
-rw-r--r--net/sctp/protocol.c6
-rw-r--r--net/sctp/socket.c14
7 files changed, 32 insertions, 53 deletions
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 70827305f501..67c997cecf58 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -665,6 +665,9 @@ static inline int sctp_vtag_hashfn(__u16 lport, __u16 rport, __u32 vtag)
665 return (h & (sctp_assoc_hashsize-1)); 665 return (h & (sctp_assoc_hashsize-1));
666} 666}
667 667
668#define sctp_for_each_hentry(epb, node, head) \
669 hlist_for_each_entry(epb, node, head, node)
670
668/* Is a socket of this style? */ 671/* Is a socket of this style? */
669#define sctp_style(sk, style) __sctp_style((sk), (SCTP_SOCKET_##style)) 672#define sctp_style(sk, style) __sctp_style((sk), (SCTP_SOCKET_##style))
670static inline int __sctp_style(const struct sock *sk, sctp_socket_type_t style) 673static inline int __sctp_style(const struct sock *sk, sctp_socket_type_t style)
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 44f2672859e2..eb3113c38a94 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -100,20 +100,19 @@ struct crypto_hash;
100struct sctp_bind_bucket { 100struct sctp_bind_bucket {
101 unsigned short port; 101 unsigned short port;
102 unsigned short fastreuse; 102 unsigned short fastreuse;
103 struct sctp_bind_bucket *next; 103 struct hlist_node node;
104 struct sctp_bind_bucket **pprev;
105 struct hlist_head owner; 104 struct hlist_head owner;
106}; 105};
107 106
108struct sctp_bind_hashbucket { 107struct sctp_bind_hashbucket {
109 spinlock_t lock; 108 spinlock_t lock;
110 struct sctp_bind_bucket *chain; 109 struct hlist_head chain;
111}; 110};
112 111
113/* Used for hashing all associations. */ 112/* Used for hashing all associations. */
114struct sctp_hashbucket { 113struct sctp_hashbucket {
115 rwlock_t lock; 114 rwlock_t lock;
116 struct sctp_ep_common *chain; 115 struct hlist_head chain;
117} __attribute__((__aligned__(8))); 116} __attribute__((__aligned__(8)));
118 117
119 118
@@ -1230,8 +1229,7 @@ typedef enum {
1230 1229
1231struct sctp_ep_common { 1230struct sctp_ep_common {
1232 /* Fields to help us manage our entries in the hash tables. */ 1231 /* Fields to help us manage our entries in the hash tables. */
1233 struct sctp_ep_common *next; 1232 struct hlist_node node;
1234 struct sctp_ep_common **pprev;
1235 int hashent; 1233 int hashent;
1236 1234
1237 /* Runtime type information. What kind of endpoint is this? */ 1235 /* Runtime type information. What kind of endpoint is this? */
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 68f0556efcc6..de6f505d6ff8 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -332,6 +332,7 @@ static struct sctp_association *__sctp_endpoint_lookup_assoc(
332 struct sctp_transport *t = NULL; 332 struct sctp_transport *t = NULL;
333 struct sctp_hashbucket *head; 333 struct sctp_hashbucket *head;
334 struct sctp_ep_common *epb; 334 struct sctp_ep_common *epb;
335 struct hlist_node *node;
335 int hash; 336 int hash;
336 int rport; 337 int rport;
337 338
@@ -341,7 +342,7 @@ static struct sctp_association *__sctp_endpoint_lookup_assoc(
341 hash = sctp_assoc_hashfn(ep->base.bind_addr.port, rport); 342 hash = sctp_assoc_hashfn(ep->base.bind_addr.port, rport);
342 head = &sctp_assoc_hashtable[hash]; 343 head = &sctp_assoc_hashtable[hash];
343 read_lock(&head->lock); 344 read_lock(&head->lock);
344 for (epb = head->chain; epb; epb = epb->next) { 345 sctp_for_each_hentry(epb, node, &head->chain) {
345 asoc = sctp_assoc(epb); 346 asoc = sctp_assoc(epb);
346 if (asoc->ep != ep || rport != asoc->peer.port) 347 if (asoc->ep != ep || rport != asoc->peer.port)
347 goto next; 348 goto next;
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 86503e7fa21e..91ae463b079b 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -656,7 +656,6 @@ discard:
656/* Insert endpoint into the hash table. */ 656/* Insert endpoint into the hash table. */
657static void __sctp_hash_endpoint(struct sctp_endpoint *ep) 657static void __sctp_hash_endpoint(struct sctp_endpoint *ep)
658{ 658{
659 struct sctp_ep_common **epp;
660 struct sctp_ep_common *epb; 659 struct sctp_ep_common *epb;
661 struct sctp_hashbucket *head; 660 struct sctp_hashbucket *head;
662 661
@@ -666,12 +665,7 @@ static void __sctp_hash_endpoint(struct sctp_endpoint *ep)
666 head = &sctp_ep_hashtable[epb->hashent]; 665 head = &sctp_ep_hashtable[epb->hashent];
667 666
668 sctp_write_lock(&head->lock); 667 sctp_write_lock(&head->lock);
669 epp = &head->chain; 668 hlist_add_head(&epb->node, &head->chain);
670 epb->next = *epp;
671 if (epb->next)
672 (*epp)->pprev = &epb->next;
673 *epp = epb;
674 epb->pprev = epp;
675 sctp_write_unlock(&head->lock); 669 sctp_write_unlock(&head->lock);
676} 670}
677 671
@@ -691,19 +685,15 @@ static void __sctp_unhash_endpoint(struct sctp_endpoint *ep)
691 685
692 epb = &ep->base; 686 epb = &ep->base;
693 687
688 if (hlist_unhashed(&epb->node))
689 return;
690
694 epb->hashent = sctp_ep_hashfn(epb->bind_addr.port); 691 epb->hashent = sctp_ep_hashfn(epb->bind_addr.port);
695 692
696 head = &sctp_ep_hashtable[epb->hashent]; 693 head = &sctp_ep_hashtable[epb->hashent];
697 694
698 sctp_write_lock(&head->lock); 695 sctp_write_lock(&head->lock);
699 696 __hlist_del(&epb->node);
700 if (epb->pprev) {
701 if (epb->next)
702 epb->next->pprev = epb->pprev;
703 *epb->pprev = epb->next;
704 epb->pprev = NULL;
705 }
706
707 sctp_write_unlock(&head->lock); 697 sctp_write_unlock(&head->lock);
708} 698}
709 699
@@ -721,12 +711,13 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *l
721 struct sctp_hashbucket *head; 711 struct sctp_hashbucket *head;
722 struct sctp_ep_common *epb; 712 struct sctp_ep_common *epb;
723 struct sctp_endpoint *ep; 713 struct sctp_endpoint *ep;
714 struct hlist_node *node;
724 int hash; 715 int hash;
725 716
726 hash = sctp_ep_hashfn(ntohs(laddr->v4.sin_port)); 717 hash = sctp_ep_hashfn(ntohs(laddr->v4.sin_port));
727 head = &sctp_ep_hashtable[hash]; 718 head = &sctp_ep_hashtable[hash];
728 read_lock(&head->lock); 719 read_lock(&head->lock);
729 for (epb = head->chain; epb; epb = epb->next) { 720 sctp_for_each_hentry(epb, node, &head->chain) {
730 ep = sctp_ep(epb); 721 ep = sctp_ep(epb);
731 if (sctp_endpoint_is_match(ep, laddr)) 722 if (sctp_endpoint_is_match(ep, laddr))
732 goto hit; 723 goto hit;
@@ -744,7 +735,6 @@ hit:
744/* Insert association into the hash table. */ 735/* Insert association into the hash table. */
745static void __sctp_hash_established(struct sctp_association *asoc) 736static void __sctp_hash_established(struct sctp_association *asoc)
746{ 737{
747 struct sctp_ep_common **epp;
748 struct sctp_ep_common *epb; 738 struct sctp_ep_common *epb;
749 struct sctp_hashbucket *head; 739 struct sctp_hashbucket *head;
750 740
@@ -756,12 +746,7 @@ static void __sctp_hash_established(struct sctp_association *asoc)
756 head = &sctp_assoc_hashtable[epb->hashent]; 746 head = &sctp_assoc_hashtable[epb->hashent];
757 747
758 sctp_write_lock(&head->lock); 748 sctp_write_lock(&head->lock);
759 epp = &head->chain; 749 hlist_add_head(&epb->node, &head->chain);
760 epb->next = *epp;
761 if (epb->next)
762 (*epp)->pprev = &epb->next;
763 *epp = epb;
764 epb->pprev = epp;
765 sctp_write_unlock(&head->lock); 750 sctp_write_unlock(&head->lock);
766} 751}
767 752
@@ -790,14 +775,7 @@ static void __sctp_unhash_established(struct sctp_association *asoc)
790 head = &sctp_assoc_hashtable[epb->hashent]; 775 head = &sctp_assoc_hashtable[epb->hashent];
791 776
792 sctp_write_lock(&head->lock); 777 sctp_write_lock(&head->lock);
793 778 __hlist_del(&epb->node);
794 if (epb->pprev) {
795 if (epb->next)
796 epb->next->pprev = epb->pprev;
797 *epb->pprev = epb->next;
798 epb->pprev = NULL;
799 }
800
801 sctp_write_unlock(&head->lock); 779 sctp_write_unlock(&head->lock);
802} 780}
803 781
@@ -822,6 +800,7 @@ static struct sctp_association *__sctp_lookup_association(
822 struct sctp_ep_common *epb; 800 struct sctp_ep_common *epb;
823 struct sctp_association *asoc; 801 struct sctp_association *asoc;
824 struct sctp_transport *transport; 802 struct sctp_transport *transport;
803 struct hlist_node *node;
825 int hash; 804 int hash;
826 805
827 /* Optimize here for direct hit, only listening connections can 806 /* Optimize here for direct hit, only listening connections can
@@ -830,7 +809,7 @@ static struct sctp_association *__sctp_lookup_association(
830 hash = sctp_assoc_hashfn(ntohs(local->v4.sin_port), ntohs(peer->v4.sin_port)); 809 hash = sctp_assoc_hashfn(ntohs(local->v4.sin_port), ntohs(peer->v4.sin_port));
831 head = &sctp_assoc_hashtable[hash]; 810 head = &sctp_assoc_hashtable[hash];
832 read_lock(&head->lock); 811 read_lock(&head->lock);
833 for (epb = head->chain; epb; epb = epb->next) { 812 sctp_for_each_hentry(epb, node, &head->chain) {
834 asoc = sctp_assoc(epb); 813 asoc = sctp_assoc(epb);
835 transport = sctp_assoc_is_match(asoc, local, peer); 814 transport = sctp_assoc_is_match(asoc, local, peer);
836 if (transport) 815 if (transport)
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index e4cd841a22e4..249973204070 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -225,6 +225,7 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v)
225 struct sctp_ep_common *epb; 225 struct sctp_ep_common *epb;
226 struct sctp_endpoint *ep; 226 struct sctp_endpoint *ep;
227 struct sock *sk; 227 struct sock *sk;
228 struct hlist_node *node;
228 int hash = *(loff_t *)v; 229 int hash = *(loff_t *)v;
229 230
230 if (hash >= sctp_ep_hashsize) 231 if (hash >= sctp_ep_hashsize)
@@ -233,7 +234,7 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v)
233 head = &sctp_ep_hashtable[hash]; 234 head = &sctp_ep_hashtable[hash];
234 sctp_local_bh_disable(); 235 sctp_local_bh_disable();
235 read_lock(&head->lock); 236 read_lock(&head->lock);
236 for (epb = head->chain; epb; epb = epb->next) { 237 sctp_for_each_hentry(epb, node, &head->chain) {
237 ep = sctp_ep(epb); 238 ep = sctp_ep(epb);
238 sk = epb->sk; 239 sk = epb->sk;
239 seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk, 240 seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk,
@@ -328,6 +329,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
328 struct sctp_ep_common *epb; 329 struct sctp_ep_common *epb;
329 struct sctp_association *assoc; 330 struct sctp_association *assoc;
330 struct sock *sk; 331 struct sock *sk;
332 struct hlist_node *node;
331 int hash = *(loff_t *)v; 333 int hash = *(loff_t *)v;
332 334
333 if (hash >= sctp_assoc_hashsize) 335 if (hash >= sctp_assoc_hashsize)
@@ -336,7 +338,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
336 head = &sctp_assoc_hashtable[hash]; 338 head = &sctp_assoc_hashtable[hash];
337 sctp_local_bh_disable(); 339 sctp_local_bh_disable();
338 read_lock(&head->lock); 340 read_lock(&head->lock);
339 for (epb = head->chain; epb; epb = epb->next) { 341 sctp_for_each_hentry(epb, node, &head->chain) {
340 assoc = sctp_assoc(epb); 342 assoc = sctp_assoc(epb);
341 sk = epb->sk; 343 sk = epb->sk;
342 seq_printf(seq, 344 seq_printf(seq,
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index ecfab0344e73..d50f610d1b02 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -1137,7 +1137,7 @@ SCTP_STATIC __init int sctp_init(void)
1137 } 1137 }
1138 for (i = 0; i < sctp_assoc_hashsize; i++) { 1138 for (i = 0; i < sctp_assoc_hashsize; i++) {
1139 rwlock_init(&sctp_assoc_hashtable[i].lock); 1139 rwlock_init(&sctp_assoc_hashtable[i].lock);
1140 sctp_assoc_hashtable[i].chain = NULL; 1140 INIT_HLIST_HEAD(&sctp_assoc_hashtable[i].chain);
1141 } 1141 }
1142 1142
1143 /* Allocate and initialize the endpoint hash table. */ 1143 /* Allocate and initialize the endpoint hash table. */
@@ -1151,7 +1151,7 @@ SCTP_STATIC __init int sctp_init(void)
1151 } 1151 }
1152 for (i = 0; i < sctp_ep_hashsize; i++) { 1152 for (i = 0; i < sctp_ep_hashsize; i++) {
1153 rwlock_init(&sctp_ep_hashtable[i].lock); 1153 rwlock_init(&sctp_ep_hashtable[i].lock);
1154 sctp_ep_hashtable[i].chain = NULL; 1154 INIT_HLIST_HEAD(&sctp_ep_hashtable[i].chain);
1155 } 1155 }
1156 1156
1157 /* Allocate and initialize the SCTP port hash table. */ 1157 /* Allocate and initialize the SCTP port hash table. */
@@ -1170,7 +1170,7 @@ SCTP_STATIC __init int sctp_init(void)
1170 } 1170 }
1171 for (i = 0; i < sctp_port_hashsize; i++) { 1171 for (i = 0; i < sctp_port_hashsize; i++) {
1172 spin_lock_init(&sctp_port_hashtable[i].lock); 1172 spin_lock_init(&sctp_port_hashtable[i].lock);
1173 sctp_port_hashtable[i].chain = NULL; 1173 INIT_HLIST_HEAD(&sctp_port_hashtable[i].chain);
1174 } 1174 }
1175 1175
1176 printk(KERN_INFO "SCTP: Hash tables configured " 1176 printk(KERN_INFO "SCTP: Hash tables configured "
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 6ce9b490fad5..ff8bc95670ed 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -5307,6 +5307,7 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
5307{ 5307{
5308 struct sctp_bind_hashbucket *head; /* hash list */ 5308 struct sctp_bind_hashbucket *head; /* hash list */
5309 struct sctp_bind_bucket *pp; /* hash list port iterator */ 5309 struct sctp_bind_bucket *pp; /* hash list port iterator */
5310 struct hlist_node *node;
5310 unsigned short snum; 5311 unsigned short snum;
5311 int ret; 5312 int ret;
5312 5313
@@ -5331,7 +5332,7 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
5331 index = sctp_phashfn(rover); 5332 index = sctp_phashfn(rover);
5332 head = &sctp_port_hashtable[index]; 5333 head = &sctp_port_hashtable[index];
5333 sctp_spin_lock(&head->lock); 5334 sctp_spin_lock(&head->lock);
5334 for (pp = head->chain; pp; pp = pp->next) 5335 sctp_for_each_hentry(pp, node, &head->chain)
5335 if (pp->port == rover) 5336 if (pp->port == rover)
5336 goto next; 5337 goto next;
5337 break; 5338 break;
@@ -5358,7 +5359,7 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
5358 */ 5359 */
5359 head = &sctp_port_hashtable[sctp_phashfn(snum)]; 5360 head = &sctp_port_hashtable[sctp_phashfn(snum)];
5360 sctp_spin_lock(&head->lock); 5361 sctp_spin_lock(&head->lock);
5361 for (pp = head->chain; pp; pp = pp->next) { 5362 sctp_for_each_hentry(pp, node, &head->chain) {
5362 if (pp->port == snum) 5363 if (pp->port == snum)
5363 goto pp_found; 5364 goto pp_found;
5364 } 5365 }
@@ -5702,10 +5703,7 @@ static struct sctp_bind_bucket *sctp_bucket_create(
5702 pp->port = snum; 5703 pp->port = snum;
5703 pp->fastreuse = 0; 5704 pp->fastreuse = 0;
5704 INIT_HLIST_HEAD(&pp->owner); 5705 INIT_HLIST_HEAD(&pp->owner);
5705 if ((pp->next = head->chain) != NULL) 5706 hlist_add_head(&pp->node, &head->chain);
5706 pp->next->pprev = &pp->next;
5707 head->chain = pp;
5708 pp->pprev = &head->chain;
5709 } 5707 }
5710 return pp; 5708 return pp;
5711} 5709}
@@ -5714,9 +5712,7 @@ static struct sctp_bind_bucket *sctp_bucket_create(
5714static void sctp_bucket_destroy(struct sctp_bind_bucket *pp) 5712static void sctp_bucket_destroy(struct sctp_bind_bucket *pp)
5715{ 5713{
5716 if (pp && hlist_empty(&pp->owner)) { 5714 if (pp && hlist_empty(&pp->owner)) {
5717 if (pp->next) 5715 __hlist_del(&pp->node);
5718 pp->next->pprev = pp->pprev;
5719 *(pp->pprev) = pp->next;
5720 kmem_cache_free(sctp_bucket_cachep, pp); 5716 kmem_cache_free(sctp_bucket_cachep, pp);
5721 SCTP_DBG_OBJCNT_DEC(bind_bucket); 5717 SCTP_DBG_OBJCNT_DEC(bind_bucket);
5722 } 5718 }