Commit d970dbf8455eb1b8cebd3cde6e18f73dd1b3ce38
1 parent
123ed979ea
Exists in
master
and in
7 other branches
SCTP: Convert custom hash lists to use hlist.
Convert the custom hash list traversals to use hlist functions. Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Showing 7 changed files with 32 additions and 53 deletions Side-by-side Diff
include/net/sctp/sctp.h
... | ... | @@ -665,6 +665,9 @@ |
665 | 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 | 671 | /* Is a socket of this style? */ |
669 | 672 | #define sctp_style(sk, style) __sctp_style((sk), (SCTP_SOCKET_##style)) |
670 | 673 | static inline int __sctp_style(const struct sock *sk, sctp_socket_type_t style) |
include/net/sctp/structs.h
... | ... | @@ -100,20 +100,19 @@ |
100 | 100 | struct sctp_bind_bucket { |
101 | 101 | unsigned short port; |
102 | 102 | unsigned short fastreuse; |
103 | - struct sctp_bind_bucket *next; | |
104 | - struct sctp_bind_bucket **pprev; | |
103 | + struct hlist_node node; | |
105 | 104 | struct hlist_head owner; |
106 | 105 | }; |
107 | 106 | |
108 | 107 | struct sctp_bind_hashbucket { |
109 | 108 | spinlock_t lock; |
110 | - struct sctp_bind_bucket *chain; | |
109 | + struct hlist_head chain; | |
111 | 110 | }; |
112 | 111 | |
113 | 112 | /* Used for hashing all associations. */ |
114 | 113 | struct sctp_hashbucket { |
115 | 114 | rwlock_t lock; |
116 | - struct sctp_ep_common *chain; | |
115 | + struct hlist_head chain; | |
117 | 116 | } __attribute__((__aligned__(8))); |
118 | 117 | |
119 | 118 | |
... | ... | @@ -1230,8 +1229,7 @@ |
1230 | 1229 | |
1231 | 1230 | struct sctp_ep_common { |
1232 | 1231 | /* Fields to help us manage our entries in the hash tables. */ |
1233 | - struct sctp_ep_common *next; | |
1234 | - struct sctp_ep_common **pprev; | |
1232 | + struct hlist_node node; | |
1235 | 1233 | int hashent; |
1236 | 1234 | |
1237 | 1235 | /* Runtime type information. What kind of endpoint is this? */ |
net/sctp/endpointola.c
... | ... | @@ -332,6 +332,7 @@ |
332 | 332 | struct sctp_transport *t = NULL; |
333 | 333 | struct sctp_hashbucket *head; |
334 | 334 | struct sctp_ep_common *epb; |
335 | + struct hlist_node *node; | |
335 | 336 | int hash; |
336 | 337 | int rport; |
337 | 338 | |
... | ... | @@ -341,7 +342,7 @@ |
341 | 342 | hash = sctp_assoc_hashfn(ep->base.bind_addr.port, rport); |
342 | 343 | head = &sctp_assoc_hashtable[hash]; |
343 | 344 | read_lock(&head->lock); |
344 | - for (epb = head->chain; epb; epb = epb->next) { | |
345 | + sctp_for_each_hentry(epb, node, &head->chain) { | |
345 | 346 | asoc = sctp_assoc(epb); |
346 | 347 | if (asoc->ep != ep || rport != asoc->peer.port) |
347 | 348 | goto next; |
net/sctp/input.c
... | ... | @@ -656,7 +656,6 @@ |
656 | 656 | /* Insert endpoint into the hash table. */ |
657 | 657 | static void __sctp_hash_endpoint(struct sctp_endpoint *ep) |
658 | 658 | { |
659 | - struct sctp_ep_common **epp; | |
660 | 659 | struct sctp_ep_common *epb; |
661 | 660 | struct sctp_hashbucket *head; |
662 | 661 | |
... | ... | @@ -666,12 +665,7 @@ |
666 | 665 | head = &sctp_ep_hashtable[epb->hashent]; |
667 | 666 | |
668 | 667 | sctp_write_lock(&head->lock); |
669 | - epp = &head->chain; | |
670 | - epb->next = *epp; | |
671 | - if (epb->next) | |
672 | - (*epp)->pprev = &epb->next; | |
673 | - *epp = epb; | |
674 | - epb->pprev = epp; | |
668 | + hlist_add_head(&epb->node, &head->chain); | |
675 | 669 | sctp_write_unlock(&head->lock); |
676 | 670 | } |
677 | 671 | |
678 | 672 | |
... | ... | @@ -691,19 +685,15 @@ |
691 | 685 | |
692 | 686 | epb = &ep->base; |
693 | 687 | |
688 | + if (hlist_unhashed(&epb->node)) | |
689 | + return; | |
690 | + | |
694 | 691 | epb->hashent = sctp_ep_hashfn(epb->bind_addr.port); |
695 | 692 | |
696 | 693 | head = &sctp_ep_hashtable[epb->hashent]; |
697 | 694 | |
698 | 695 | sctp_write_lock(&head->lock); |
699 | - | |
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 | - | |
696 | + __hlist_del(&epb->node); | |
707 | 697 | sctp_write_unlock(&head->lock); |
708 | 698 | } |
709 | 699 | |
710 | 700 | |
... | ... | @@ -721,12 +711,13 @@ |
721 | 711 | struct sctp_hashbucket *head; |
722 | 712 | struct sctp_ep_common *epb; |
723 | 713 | struct sctp_endpoint *ep; |
714 | + struct hlist_node *node; | |
724 | 715 | int hash; |
725 | 716 | |
726 | 717 | hash = sctp_ep_hashfn(ntohs(laddr->v4.sin_port)); |
727 | 718 | head = &sctp_ep_hashtable[hash]; |
728 | 719 | read_lock(&head->lock); |
729 | - for (epb = head->chain; epb; epb = epb->next) { | |
720 | + sctp_for_each_hentry(epb, node, &head->chain) { | |
730 | 721 | ep = sctp_ep(epb); |
731 | 722 | if (sctp_endpoint_is_match(ep, laddr)) |
732 | 723 | goto hit; |
... | ... | @@ -744,7 +735,6 @@ |
744 | 735 | /* Insert association into the hash table. */ |
745 | 736 | static void __sctp_hash_established(struct sctp_association *asoc) |
746 | 737 | { |
747 | - struct sctp_ep_common **epp; | |
748 | 738 | struct sctp_ep_common *epb; |
749 | 739 | struct sctp_hashbucket *head; |
750 | 740 | |
... | ... | @@ -756,12 +746,7 @@ |
756 | 746 | head = &sctp_assoc_hashtable[epb->hashent]; |
757 | 747 | |
758 | 748 | sctp_write_lock(&head->lock); |
759 | - epp = &head->chain; | |
760 | - epb->next = *epp; | |
761 | - if (epb->next) | |
762 | - (*epp)->pprev = &epb->next; | |
763 | - *epp = epb; | |
764 | - epb->pprev = epp; | |
749 | + hlist_add_head(&epb->node, &head->chain); | |
765 | 750 | sctp_write_unlock(&head->lock); |
766 | 751 | } |
767 | 752 | |
... | ... | @@ -790,14 +775,7 @@ |
790 | 775 | head = &sctp_assoc_hashtable[epb->hashent]; |
791 | 776 | |
792 | 777 | sctp_write_lock(&head->lock); |
793 | - | |
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 | - | |
778 | + __hlist_del(&epb->node); | |
801 | 779 | sctp_write_unlock(&head->lock); |
802 | 780 | } |
803 | 781 | |
... | ... | @@ -822,6 +800,7 @@ |
822 | 800 | struct sctp_ep_common *epb; |
823 | 801 | struct sctp_association *asoc; |
824 | 802 | struct sctp_transport *transport; |
803 | + struct hlist_node *node; | |
825 | 804 | int hash; |
826 | 805 | |
827 | 806 | /* Optimize here for direct hit, only listening connections can |
... | ... | @@ -830,7 +809,7 @@ |
830 | 809 | hash = sctp_assoc_hashfn(ntohs(local->v4.sin_port), ntohs(peer->v4.sin_port)); |
831 | 810 | head = &sctp_assoc_hashtable[hash]; |
832 | 811 | read_lock(&head->lock); |
833 | - for (epb = head->chain; epb; epb = epb->next) { | |
812 | + sctp_for_each_hentry(epb, node, &head->chain) { | |
834 | 813 | asoc = sctp_assoc(epb); |
835 | 814 | transport = sctp_assoc_is_match(asoc, local, peer); |
836 | 815 | if (transport) |
net/sctp/proc.c
... | ... | @@ -225,6 +225,7 @@ |
225 | 225 | struct sctp_ep_common *epb; |
226 | 226 | struct sctp_endpoint *ep; |
227 | 227 | struct sock *sk; |
228 | + struct hlist_node *node; | |
228 | 229 | int hash = *(loff_t *)v; |
229 | 230 | |
230 | 231 | if (hash >= sctp_ep_hashsize) |
... | ... | @@ -233,7 +234,7 @@ |
233 | 234 | head = &sctp_ep_hashtable[hash]; |
234 | 235 | sctp_local_bh_disable(); |
235 | 236 | read_lock(&head->lock); |
236 | - for (epb = head->chain; epb; epb = epb->next) { | |
237 | + sctp_for_each_hentry(epb, node, &head->chain) { | |
237 | 238 | ep = sctp_ep(epb); |
238 | 239 | sk = epb->sk; |
239 | 240 | seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk, |
... | ... | @@ -328,6 +329,7 @@ |
328 | 329 | struct sctp_ep_common *epb; |
329 | 330 | struct sctp_association *assoc; |
330 | 331 | struct sock *sk; |
332 | + struct hlist_node *node; | |
331 | 333 | int hash = *(loff_t *)v; |
332 | 334 | |
333 | 335 | if (hash >= sctp_assoc_hashsize) |
... | ... | @@ -336,7 +338,7 @@ |
336 | 338 | head = &sctp_assoc_hashtable[hash]; |
337 | 339 | sctp_local_bh_disable(); |
338 | 340 | read_lock(&head->lock); |
339 | - for (epb = head->chain; epb; epb = epb->next) { | |
341 | + sctp_for_each_hentry(epb, node, &head->chain) { | |
340 | 342 | assoc = sctp_assoc(epb); |
341 | 343 | sk = epb->sk; |
342 | 344 | seq_printf(seq, |
net/sctp/protocol.c
... | ... | @@ -1137,7 +1137,7 @@ |
1137 | 1137 | } |
1138 | 1138 | for (i = 0; i < sctp_assoc_hashsize; i++) { |
1139 | 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 | 1143 | /* Allocate and initialize the endpoint hash table. */ |
... | ... | @@ -1151,7 +1151,7 @@ |
1151 | 1151 | } |
1152 | 1152 | for (i = 0; i < sctp_ep_hashsize; i++) { |
1153 | 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 | 1157 | /* Allocate and initialize the SCTP port hash table. */ |
... | ... | @@ -1170,7 +1170,7 @@ |
1170 | 1170 | } |
1171 | 1171 | for (i = 0; i < sctp_port_hashsize; i++) { |
1172 | 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 | 1176 | printk(KERN_INFO "SCTP: Hash tables configured " |
net/sctp/socket.c
... | ... | @@ -5307,6 +5307,7 @@ |
5307 | 5307 | { |
5308 | 5308 | struct sctp_bind_hashbucket *head; /* hash list */ |
5309 | 5309 | struct sctp_bind_bucket *pp; /* hash list port iterator */ |
5310 | + struct hlist_node *node; | |
5310 | 5311 | unsigned short snum; |
5311 | 5312 | int ret; |
5312 | 5313 | |
... | ... | @@ -5331,7 +5332,7 @@ |
5331 | 5332 | index = sctp_phashfn(rover); |
5332 | 5333 | head = &sctp_port_hashtable[index]; |
5333 | 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 | 5336 | if (pp->port == rover) |
5336 | 5337 | goto next; |
5337 | 5338 | break; |
... | ... | @@ -5358,7 +5359,7 @@ |
5358 | 5359 | */ |
5359 | 5360 | head = &sctp_port_hashtable[sctp_phashfn(snum)]; |
5360 | 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 | 5363 | if (pp->port == snum) |
5363 | 5364 | goto pp_found; |
5364 | 5365 | } |
... | ... | @@ -5702,10 +5703,7 @@ |
5702 | 5703 | pp->port = snum; |
5703 | 5704 | pp->fastreuse = 0; |
5704 | 5705 | INIT_HLIST_HEAD(&pp->owner); |
5705 | - if ((pp->next = head->chain) != NULL) | |
5706 | - pp->next->pprev = &pp->next; | |
5707 | - head->chain = pp; | |
5708 | - pp->pprev = &head->chain; | |
5706 | + hlist_add_head(&pp->node, &head->chain); | |
5709 | 5707 | } |
5710 | 5708 | return pp; |
5711 | 5709 | } |
... | ... | @@ -5714,9 +5712,7 @@ |
5714 | 5712 | static void sctp_bucket_destroy(struct sctp_bind_bucket *pp) |
5715 | 5713 | { |
5716 | 5714 | if (pp && hlist_empty(&pp->owner)) { |
5717 | - if (pp->next) | |
5718 | - pp->next->pprev = pp->pprev; | |
5719 | - *(pp->pprev) = pp->next; | |
5715 | + __hlist_del(&pp->node); | |
5720 | 5716 | kmem_cache_free(sctp_bucket_cachep, pp); |
5721 | 5717 | SCTP_DBG_OBJCNT_DEC(bind_bucket); |
5722 | 5718 | } |