提交 d970dbf8 编写于 作者: V Vlad Yasevich

SCTP: Convert custom hash lists to use hlist.

Convert the custom hash list traversals to use hlist functions.
Signed-off-by: NVlad Yasevich <vladislav.yasevich@hp.com>
上级 123ed979
...@@ -665,6 +665,9 @@ static inline int sctp_vtag_hashfn(__u16 lport, __u16 rport, __u32 vtag) ...@@ -665,6 +665,9 @@ static inline int sctp_vtag_hashfn(__u16 lport, __u16 rport, __u32 vtag)
return (h & (sctp_assoc_hashsize-1)); return (h & (sctp_assoc_hashsize-1));
} }
#define sctp_for_each_hentry(epb, node, head) \
hlist_for_each_entry(epb, node, head, node)
/* Is a socket of this style? */ /* Is a socket of this style? */
#define sctp_style(sk, style) __sctp_style((sk), (SCTP_SOCKET_##style)) #define sctp_style(sk, style) __sctp_style((sk), (SCTP_SOCKET_##style))
static inline int __sctp_style(const struct sock *sk, sctp_socket_type_t style) static inline int __sctp_style(const struct sock *sk, sctp_socket_type_t style)
......
...@@ -100,20 +100,19 @@ struct crypto_hash; ...@@ -100,20 +100,19 @@ struct crypto_hash;
struct sctp_bind_bucket { struct sctp_bind_bucket {
unsigned short port; unsigned short port;
unsigned short fastreuse; unsigned short fastreuse;
struct sctp_bind_bucket *next; struct hlist_node node;
struct sctp_bind_bucket **pprev;
struct hlist_head owner; struct hlist_head owner;
}; };
struct sctp_bind_hashbucket { struct sctp_bind_hashbucket {
spinlock_t lock; spinlock_t lock;
struct sctp_bind_bucket *chain; struct hlist_head chain;
}; };
/* Used for hashing all associations. */ /* Used for hashing all associations. */
struct sctp_hashbucket { struct sctp_hashbucket {
rwlock_t lock; rwlock_t lock;
struct sctp_ep_common *chain; struct hlist_head chain;
} __attribute__((__aligned__(8))); } __attribute__((__aligned__(8)));
...@@ -1230,8 +1229,7 @@ typedef enum { ...@@ -1230,8 +1229,7 @@ typedef enum {
struct sctp_ep_common { struct sctp_ep_common {
/* Fields to help us manage our entries in the hash tables. */ /* Fields to help us manage our entries in the hash tables. */
struct sctp_ep_common *next; struct hlist_node node;
struct sctp_ep_common **pprev;
int hashent; int hashent;
/* Runtime type information. What kind of endpoint is this? */ /* Runtime type information. What kind of endpoint is this? */
......
...@@ -332,6 +332,7 @@ static struct sctp_association *__sctp_endpoint_lookup_assoc( ...@@ -332,6 +332,7 @@ static struct sctp_association *__sctp_endpoint_lookup_assoc(
struct sctp_transport *t = NULL; struct sctp_transport *t = NULL;
struct sctp_hashbucket *head; struct sctp_hashbucket *head;
struct sctp_ep_common *epb; struct sctp_ep_common *epb;
struct hlist_node *node;
int hash; int hash;
int rport; int rport;
...@@ -341,7 +342,7 @@ static struct sctp_association *__sctp_endpoint_lookup_assoc( ...@@ -341,7 +342,7 @@ static struct sctp_association *__sctp_endpoint_lookup_assoc(
hash = sctp_assoc_hashfn(ep->base.bind_addr.port, rport); hash = sctp_assoc_hashfn(ep->base.bind_addr.port, rport);
head = &sctp_assoc_hashtable[hash]; head = &sctp_assoc_hashtable[hash];
read_lock(&head->lock); read_lock(&head->lock);
for (epb = head->chain; epb; epb = epb->next) { sctp_for_each_hentry(epb, node, &head->chain) {
asoc = sctp_assoc(epb); asoc = sctp_assoc(epb);
if (asoc->ep != ep || rport != asoc->peer.port) if (asoc->ep != ep || rport != asoc->peer.port)
goto next; goto next;
......
...@@ -656,7 +656,6 @@ static int sctp_rcv_ootb(struct sk_buff *skb) ...@@ -656,7 +656,6 @@ static int sctp_rcv_ootb(struct sk_buff *skb)
/* Insert endpoint into the hash table. */ /* Insert endpoint into the hash table. */
static void __sctp_hash_endpoint(struct sctp_endpoint *ep) static void __sctp_hash_endpoint(struct sctp_endpoint *ep)
{ {
struct sctp_ep_common **epp;
struct sctp_ep_common *epb; struct sctp_ep_common *epb;
struct sctp_hashbucket *head; struct sctp_hashbucket *head;
...@@ -666,12 +665,7 @@ static void __sctp_hash_endpoint(struct sctp_endpoint *ep) ...@@ -666,12 +665,7 @@ static void __sctp_hash_endpoint(struct sctp_endpoint *ep)
head = &sctp_ep_hashtable[epb->hashent]; head = &sctp_ep_hashtable[epb->hashent];
sctp_write_lock(&head->lock); sctp_write_lock(&head->lock);
epp = &head->chain; hlist_add_head(&epb->node, &head->chain);
epb->next = *epp;
if (epb->next)
(*epp)->pprev = &epb->next;
*epp = epb;
epb->pprev = epp;
sctp_write_unlock(&head->lock); sctp_write_unlock(&head->lock);
} }
...@@ -691,19 +685,15 @@ static void __sctp_unhash_endpoint(struct sctp_endpoint *ep) ...@@ -691,19 +685,15 @@ static void __sctp_unhash_endpoint(struct sctp_endpoint *ep)
epb = &ep->base; epb = &ep->base;
if (hlist_unhashed(&epb->node))
return;
epb->hashent = sctp_ep_hashfn(epb->bind_addr.port); epb->hashent = sctp_ep_hashfn(epb->bind_addr.port);
head = &sctp_ep_hashtable[epb->hashent]; head = &sctp_ep_hashtable[epb->hashent];
sctp_write_lock(&head->lock); sctp_write_lock(&head->lock);
__hlist_del(&epb->node);
if (epb->pprev) {
if (epb->next)
epb->next->pprev = epb->pprev;
*epb->pprev = epb->next;
epb->pprev = NULL;
}
sctp_write_unlock(&head->lock); sctp_write_unlock(&head->lock);
} }
...@@ -721,12 +711,13 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *l ...@@ -721,12 +711,13 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *l
struct sctp_hashbucket *head; struct sctp_hashbucket *head;
struct sctp_ep_common *epb; struct sctp_ep_common *epb;
struct sctp_endpoint *ep; struct sctp_endpoint *ep;
struct hlist_node *node;
int hash; int hash;
hash = sctp_ep_hashfn(ntohs(laddr->v4.sin_port)); hash = sctp_ep_hashfn(ntohs(laddr->v4.sin_port));
head = &sctp_ep_hashtable[hash]; head = &sctp_ep_hashtable[hash];
read_lock(&head->lock); read_lock(&head->lock);
for (epb = head->chain; epb; epb = epb->next) { sctp_for_each_hentry(epb, node, &head->chain) {
ep = sctp_ep(epb); ep = sctp_ep(epb);
if (sctp_endpoint_is_match(ep, laddr)) if (sctp_endpoint_is_match(ep, laddr))
goto hit; goto hit;
...@@ -744,7 +735,6 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *l ...@@ -744,7 +735,6 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *l
/* Insert association into the hash table. */ /* Insert association into the hash table. */
static void __sctp_hash_established(struct sctp_association *asoc) static void __sctp_hash_established(struct sctp_association *asoc)
{ {
struct sctp_ep_common **epp;
struct sctp_ep_common *epb; struct sctp_ep_common *epb;
struct sctp_hashbucket *head; struct sctp_hashbucket *head;
...@@ -756,12 +746,7 @@ static void __sctp_hash_established(struct sctp_association *asoc) ...@@ -756,12 +746,7 @@ static void __sctp_hash_established(struct sctp_association *asoc)
head = &sctp_assoc_hashtable[epb->hashent]; head = &sctp_assoc_hashtable[epb->hashent];
sctp_write_lock(&head->lock); sctp_write_lock(&head->lock);
epp = &head->chain; hlist_add_head(&epb->node, &head->chain);
epb->next = *epp;
if (epb->next)
(*epp)->pprev = &epb->next;
*epp = epb;
epb->pprev = epp;
sctp_write_unlock(&head->lock); sctp_write_unlock(&head->lock);
} }
...@@ -790,14 +775,7 @@ static void __sctp_unhash_established(struct sctp_association *asoc) ...@@ -790,14 +775,7 @@ static void __sctp_unhash_established(struct sctp_association *asoc)
head = &sctp_assoc_hashtable[epb->hashent]; head = &sctp_assoc_hashtable[epb->hashent];
sctp_write_lock(&head->lock); sctp_write_lock(&head->lock);
__hlist_del(&epb->node);
if (epb->pprev) {
if (epb->next)
epb->next->pprev = epb->pprev;
*epb->pprev = epb->next;
epb->pprev = NULL;
}
sctp_write_unlock(&head->lock); sctp_write_unlock(&head->lock);
} }
...@@ -822,6 +800,7 @@ static struct sctp_association *__sctp_lookup_association( ...@@ -822,6 +800,7 @@ static struct sctp_association *__sctp_lookup_association(
struct sctp_ep_common *epb; struct sctp_ep_common *epb;
struct sctp_association *asoc; struct sctp_association *asoc;
struct sctp_transport *transport; struct sctp_transport *transport;
struct hlist_node *node;
int hash; int hash;
/* Optimize here for direct hit, only listening connections can /* Optimize here for direct hit, only listening connections can
...@@ -830,7 +809,7 @@ static struct sctp_association *__sctp_lookup_association( ...@@ -830,7 +809,7 @@ static struct sctp_association *__sctp_lookup_association(
hash = sctp_assoc_hashfn(ntohs(local->v4.sin_port), ntohs(peer->v4.sin_port)); hash = sctp_assoc_hashfn(ntohs(local->v4.sin_port), ntohs(peer->v4.sin_port));
head = &sctp_assoc_hashtable[hash]; head = &sctp_assoc_hashtable[hash];
read_lock(&head->lock); read_lock(&head->lock);
for (epb = head->chain; epb; epb = epb->next) { sctp_for_each_hentry(epb, node, &head->chain) {
asoc = sctp_assoc(epb); asoc = sctp_assoc(epb);
transport = sctp_assoc_is_match(asoc, local, peer); transport = sctp_assoc_is_match(asoc, local, peer);
if (transport) if (transport)
......
...@@ -225,6 +225,7 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v) ...@@ -225,6 +225,7 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v)
struct sctp_ep_common *epb; struct sctp_ep_common *epb;
struct sctp_endpoint *ep; struct sctp_endpoint *ep;
struct sock *sk; struct sock *sk;
struct hlist_node *node;
int hash = *(loff_t *)v; int hash = *(loff_t *)v;
if (hash >= sctp_ep_hashsize) if (hash >= sctp_ep_hashsize)
...@@ -233,7 +234,7 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v) ...@@ -233,7 +234,7 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v)
head = &sctp_ep_hashtable[hash]; head = &sctp_ep_hashtable[hash];
sctp_local_bh_disable(); sctp_local_bh_disable();
read_lock(&head->lock); read_lock(&head->lock);
for (epb = head->chain; epb; epb = epb->next) { sctp_for_each_hentry(epb, node, &head->chain) {
ep = sctp_ep(epb); ep = sctp_ep(epb);
sk = epb->sk; sk = epb->sk;
seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk, 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,6 +329,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
struct sctp_ep_common *epb; struct sctp_ep_common *epb;
struct sctp_association *assoc; struct sctp_association *assoc;
struct sock *sk; struct sock *sk;
struct hlist_node *node;
int hash = *(loff_t *)v; int hash = *(loff_t *)v;
if (hash >= sctp_assoc_hashsize) if (hash >= sctp_assoc_hashsize)
...@@ -336,7 +338,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v) ...@@ -336,7 +338,7 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
head = &sctp_assoc_hashtable[hash]; head = &sctp_assoc_hashtable[hash];
sctp_local_bh_disable(); sctp_local_bh_disable();
read_lock(&head->lock); read_lock(&head->lock);
for (epb = head->chain; epb; epb = epb->next) { sctp_for_each_hentry(epb, node, &head->chain) {
assoc = sctp_assoc(epb); assoc = sctp_assoc(epb);
sk = epb->sk; sk = epb->sk;
seq_printf(seq, seq_printf(seq,
......
...@@ -1137,7 +1137,7 @@ SCTP_STATIC __init int sctp_init(void) ...@@ -1137,7 +1137,7 @@ SCTP_STATIC __init int sctp_init(void)
} }
for (i = 0; i < sctp_assoc_hashsize; i++) { for (i = 0; i < sctp_assoc_hashsize; i++) {
rwlock_init(&sctp_assoc_hashtable[i].lock); rwlock_init(&sctp_assoc_hashtable[i].lock);
sctp_assoc_hashtable[i].chain = NULL; INIT_HLIST_HEAD(&sctp_assoc_hashtable[i].chain);
} }
/* Allocate and initialize the endpoint hash table. */ /* Allocate and initialize the endpoint hash table. */
...@@ -1151,7 +1151,7 @@ SCTP_STATIC __init int sctp_init(void) ...@@ -1151,7 +1151,7 @@ SCTP_STATIC __init int sctp_init(void)
} }
for (i = 0; i < sctp_ep_hashsize; i++) { for (i = 0; i < sctp_ep_hashsize; i++) {
rwlock_init(&sctp_ep_hashtable[i].lock); rwlock_init(&sctp_ep_hashtable[i].lock);
sctp_ep_hashtable[i].chain = NULL; INIT_HLIST_HEAD(&sctp_ep_hashtable[i].chain);
} }
/* Allocate and initialize the SCTP port hash table. */ /* Allocate and initialize the SCTP port hash table. */
...@@ -1170,7 +1170,7 @@ SCTP_STATIC __init int sctp_init(void) ...@@ -1170,7 +1170,7 @@ SCTP_STATIC __init int sctp_init(void)
} }
for (i = 0; i < sctp_port_hashsize; i++) { for (i = 0; i < sctp_port_hashsize; i++) {
spin_lock_init(&sctp_port_hashtable[i].lock); spin_lock_init(&sctp_port_hashtable[i].lock);
sctp_port_hashtable[i].chain = NULL; INIT_HLIST_HEAD(&sctp_port_hashtable[i].chain);
} }
printk(KERN_INFO "SCTP: Hash tables configured " printk(KERN_INFO "SCTP: Hash tables configured "
......
...@@ -5307,6 +5307,7 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr) ...@@ -5307,6 +5307,7 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
{ {
struct sctp_bind_hashbucket *head; /* hash list */ struct sctp_bind_hashbucket *head; /* hash list */
struct sctp_bind_bucket *pp; /* hash list port iterator */ struct sctp_bind_bucket *pp; /* hash list port iterator */
struct hlist_node *node;
unsigned short snum; unsigned short snum;
int ret; int ret;
...@@ -5331,7 +5332,7 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr) ...@@ -5331,7 +5332,7 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
index = sctp_phashfn(rover); index = sctp_phashfn(rover);
head = &sctp_port_hashtable[index]; head = &sctp_port_hashtable[index];
sctp_spin_lock(&head->lock); sctp_spin_lock(&head->lock);
for (pp = head->chain; pp; pp = pp->next) sctp_for_each_hentry(pp, node, &head->chain)
if (pp->port == rover) if (pp->port == rover)
goto next; goto next;
break; break;
...@@ -5358,7 +5359,7 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr) ...@@ -5358,7 +5359,7 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
*/ */
head = &sctp_port_hashtable[sctp_phashfn(snum)]; head = &sctp_port_hashtable[sctp_phashfn(snum)];
sctp_spin_lock(&head->lock); sctp_spin_lock(&head->lock);
for (pp = head->chain; pp; pp = pp->next) { sctp_for_each_hentry(pp, node, &head->chain) {
if (pp->port == snum) if (pp->port == snum)
goto pp_found; goto pp_found;
} }
...@@ -5702,10 +5703,7 @@ static struct sctp_bind_bucket *sctp_bucket_create( ...@@ -5702,10 +5703,7 @@ static struct sctp_bind_bucket *sctp_bucket_create(
pp->port = snum; pp->port = snum;
pp->fastreuse = 0; pp->fastreuse = 0;
INIT_HLIST_HEAD(&pp->owner); INIT_HLIST_HEAD(&pp->owner);
if ((pp->next = head->chain) != NULL) hlist_add_head(&pp->node, &head->chain);
pp->next->pprev = &pp->next;
head->chain = pp;
pp->pprev = &head->chain;
} }
return pp; return pp;
} }
...@@ -5714,9 +5712,7 @@ static struct sctp_bind_bucket *sctp_bucket_create( ...@@ -5714,9 +5712,7 @@ static struct sctp_bind_bucket *sctp_bucket_create(
static void sctp_bucket_destroy(struct sctp_bind_bucket *pp) static void sctp_bucket_destroy(struct sctp_bind_bucket *pp)
{ {
if (pp && hlist_empty(&pp->owner)) { if (pp && hlist_empty(&pp->owner)) {
if (pp->next) __hlist_del(&pp->node);
pp->next->pprev = pp->pprev;
*(pp->pprev) = pp->next;
kmem_cache_free(sctp_bucket_cachep, pp); kmem_cache_free(sctp_bucket_cachep, pp);
SCTP_DBG_OBJCNT_DEC(bind_bucket); SCTP_DBG_OBJCNT_DEC(bind_bucket);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册