Vlad Yasevich wrote: > 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 endopoint we already have.
This one is missing an unlock. Will send an update shortly. -vlad > > Signed-off-by: Vlad Yasevich <[EMAIL PROTECTED]> > --- > net/sctp/endpointola.c | 33 +++++++++++++++++++++------------ > 1 files changed, 21 insertions(+), 12 deletions(-) > > diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c > index 2d2d81e..f38fa0f 100644 > --- a/net/sctp/endpointola.c > +++ b/net/sctp/endpointola.c > @@ -328,24 +328,33 @@ 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; > + return asoc; > } > > /* Lookup association on an endpoint based on a peer address. BH-safe. */ - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html