From 123ed979eaa8de0dd2422862d247469eda0bd645 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Fri, 9 Nov 2007 11:41:36 -0500 Subject: SCTP: Use hashed lookup when looking for an association. A SCTP endpoint may have a lot of associations on them and walking the list is fairly inefficient. Instead, use a hashed lookup, and filter out the hash list based on the endopoing we already have. Signed-off-by: Vlad Yasevich --- net/sctp/endpointola.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 2d2d81ef4a69..68f0556efcc6 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c @@ -328,24 +328,34 @@ static struct sctp_association *__sctp_endpoint_lookup_assoc( const union sctp_addr *paddr, struct sctp_transport **transport) { + struct sctp_association *asoc = NULL; + struct sctp_transport *t = NULL; + struct sctp_hashbucket *head; + struct sctp_ep_common *epb; + int hash; int rport; - struct sctp_association *asoc; - struct list_head *pos; + *transport = NULL; rport = ntohs(paddr->v4.sin_port); - list_for_each(pos, &ep->asocs) { - asoc = list_entry(pos, struct sctp_association, asocs); - if (rport == asoc->peer.port) { - *transport = sctp_assoc_lookup_paddr(asoc, paddr); - - if (*transport) - return asoc; + hash = sctp_assoc_hashfn(ep->base.bind_addr.port, rport); + head = &sctp_assoc_hashtable[hash]; + read_lock(&head->lock); + for (epb = head->chain; epb; epb = epb->next) { + asoc = sctp_assoc(epb); + if (asoc->ep != ep || rport != asoc->peer.port) + goto next; + + t = sctp_assoc_lookup_paddr(asoc, paddr); + if (t) { + *transport = t; + break; } +next: + asoc = NULL; } - - *transport = NULL; - return NULL; + read_unlock(&head->lock); + return asoc; } /* Lookup association on an endpoint based on a peer address. BH-safe. */ -- cgit v1.2.2