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 <vladislav.yasevich@hp.com>
This commit is contained in:
parent
027f6e1ad3
commit
123ed979ea
1 changed files with 25 additions and 15 deletions
|
@ -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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
*transport = NULL;
|
||||
return NULL;
|
||||
rport = ntohs(paddr->v4.sin_port);
|
||||
|
||||
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;
|
||||
}
|
||||
read_unlock(&head->lock);
|
||||
return asoc;
|
||||
}
|
||||
|
||||
/* Lookup association on an endpoint based on a peer address. BH-safe. */
|
||||
|
|
Loading…
Reference in a new issue