Skip to content

Commit

Permalink
syncache_socket(): fix abort path by calling pru_abort directly
Browse files Browse the repository at this point in the history
On syncache_socket() abort path, the inp's {fport,lport,faddr,laddr}
is either incomplete or half destroyed, which causes tcp_soport()
mapping the socket to a wrong CPU.  However, in syncache code, inp
is only accessed or created by its owner CPU, i.e. we are already on
the inp's owner CPU during the socket aborting.

Add soabort_oncpu(), which calls pru_abort directly.  Use it on
syncache_socket() abort path.
  • Loading branch information
Sepherosa Ziehau committed Jan 31, 2009
1 parent 9bf0666 commit fd86a41
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 1 deletion.
12 changes: 12 additions & 0 deletions sys/kern/uipc_msg.c
Expand Up @@ -92,6 +92,18 @@ so_pru_aborta(struct socket *so)
lwkt_sendmsg(port, &msg->nm_netmsg.nm_lmsg);
}

/*
* Abort a socket and free it. Called from soabort_oncpu() only.
* Caller must make sure that the current CPU is inpcb's owner CPU.
*
* The SS_ABORTING flag must already be set.
*/
void
so_pru_abort_oncpu(struct socket *so)
{
so->so_proto->pr_usrreqs->pru_abort(so);
}

int
so_pru_accept(struct socket *so, struct sockaddr **nam)
{
Expand Down
9 changes: 9 additions & 0 deletions sys/kern/uipc_socket.c
Expand Up @@ -407,6 +407,15 @@ soaborta(struct socket *so)
}
}

void
soabort_oncpu(struct socket *so)
{
if ((so->so_state & SS_ABORTING) == 0) {
so->so_state |= SS_ABORTING;
so_pru_abort_oncpu(so);
}
}

int
soaccept(struct socket *so, struct sockaddr **nam)
{
Expand Down
2 changes: 1 addition & 1 deletion sys/netinet/tcp_syncache.c
Expand Up @@ -800,7 +800,7 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)

abort:
if (so != NULL)
soaborta(so);
soabort_oncpu(so);
return (NULL);
}

Expand Down
1 change: 1 addition & 0 deletions sys/sys/socketops.h
Expand Up @@ -75,6 +75,7 @@ so_pru_soreceive(struct socket *so, struct sockaddr **paddr, struct uio *uio,

void so_pru_abort (struct socket *so);
void so_pru_aborta (struct socket *so);
void so_pru_abort_oncpu (struct socket *so);
int so_pru_accept (struct socket *so, struct sockaddr **nam);
int so_pru_attach (struct socket *so, int proto, struct pru_attach_info *ai);
int so_pru_bind (struct socket *so, struct sockaddr *nam, struct thread *td);
Expand Down
1 change: 1 addition & 0 deletions sys/sys/socketvar.h
Expand Up @@ -357,6 +357,7 @@ int _ssb_lock (struct signalsockbuf *sb);

void soabort (struct socket *so);
void soaborta (struct socket *so);
void soabort_oncpu (struct socket *so);
int soaccept (struct socket *so, struct sockaddr **nam);
struct socket *soalloc (int waitok);
int sobind (struct socket *so, struct sockaddr *nam, struct thread *td);
Expand Down

0 comments on commit fd86a41

Please sign in to comment.