From 767b9c0b3efe618078d08c4cf137ab912f502ca2 Mon Sep 17 00:00:00 2001 From: rwatson Date: Thu, 30 Dec 2004 17:49:40 +0000 Subject: Convert netipx to use queue(9) doubly-linked lists instead of home-brew linked lists for ipxpcb's. --- sys/netipx/ipx_input.c | 19 +++++++++++-------- sys/netipx/ipx_pcb.c | 9 +++++---- sys/netipx/ipx_pcb.h | 14 ++++++++++---- sys/netipx/ipx_usrreq.c | 5 +++-- sys/netipx/ipx_var.h | 1 - sys/netipx/spx_usrreq.c | 35 ++++++++++++++++------------------- 6 files changed, 45 insertions(+), 38 deletions(-) (limited to 'sys') diff --git a/sys/netipx/ipx_input.c b/sys/netipx/ipx_input.c index 9e12ac6..e7036e2 100644 --- a/sys/netipx/ipx_input.c +++ b/sys/netipx/ipx_input.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2004, Robert N. M. Watson * Copyright (c) 1995, Mike Mitchell * Copyright (c) 1984, 1985, 1986, 1987, 1993 * The Regents of the University of California. All rights reserved. @@ -84,8 +85,11 @@ const union ipx_host ipx_broadhost = { .s_host[0] = 0xffff, struct ipxstat ipxstat; struct sockaddr_ipx ipx_netmask, ipx_hostmask; -struct ipxpcb ipxpcb; -struct ipxpcb ipxrawpcb; +/* + * IPX protocol control block (pcb) lists. + */ +struct ipxpcbhead ipxpcb_list; +struct ipxpcbhead ipxrawpcb_list; static int ipxqmaxlen = IFQ_MAXLEN; static struct ifqueue ipxintrq; @@ -106,8 +110,9 @@ ipx_init() { read_random(&ipx_pexseq, sizeof ipx_pexseq); - ipxpcb.ipxp_next = ipxpcb.ipxp_prev = &ipxpcb; - ipxrawpcb.ipxp_next = ipxrawpcb.ipxp_prev = &ipxrawpcb; + + LIST_INIT(&ipxpcb_list); + LIST_INIT(&ipxrawpcb_list); ipx_netmask.sipx_len = 6; ipx_netmask.sipx_addr.x_net = ipx_broadnet; @@ -152,8 +157,7 @@ ipxintr(struct mbuf *m) /* * Give any raw listeners a crack at the packet */ - for (ipxp = ipxrawpcb.ipxp_next; ipxp != &ipxrawpcb; - ipxp = ipxp->ipxp_next) { + LIST_FOREACH(ipxp, &ipxrawpcb_list, ipxp_list) { struct mbuf *m1 = m_copy(m, 0, (int)M_COPYALL); if (m1 != NULL) ipx_input(m1, ipxp); @@ -466,8 +470,7 @@ struct ifnet *ifp; /* * Give any raw listeners a crack at the packet */ - for (ipxp = ipxrawpcb.ipxp_next; ipxp != &ipxrawpcb; - ipxp = ipxp->ipxp_next) { + LIST_FOREACH(ipxp, &ipxrawpcb_list, ipxp_list) { struct mbuf *m0 = m_copy(m, 0, (int)M_COPYALL); if (m0 != NULL) { register struct ipx *ipx; diff --git a/sys/netipx/ipx_pcb.c b/sys/netipx/ipx_pcb.c index ebd4df1..6cb8e50 100644 --- a/sys/netipx/ipx_pcb.c +++ b/sys/netipx/ipx_pcb.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2004, Robert N. M. Watson * Copyright (c) 1995, Mike Mitchell * Copyright (c) 1984, 1985, 1986, 1987, 1993 * The Regents of the University of California. All rights reserved. @@ -56,7 +57,7 @@ static struct ipx_addr zeroipx_addr; int ipx_pcballoc(so, head, td) struct socket *so; - struct ipxpcb *head; + struct ipxpcbhead *head; struct thread *td; { register struct ipxpcb *ipxp; @@ -67,7 +68,7 @@ ipx_pcballoc(so, head, td) ipxp->ipxp_socket = so; if (ipxcksum) ipxp->ipxp_flags |= IPXP_CHECKSUM; - insque(ipxp, head); + LIST_INSERT_HEAD(head, ipxp, ipxp_list); so->so_pcb = (caddr_t)ipxp; return (0); } @@ -274,7 +275,7 @@ ipx_pcbdetach(ipxp) sotryfree(so); if (ipxp->ipxp_route.ro_rt != NULL) rtfree(ipxp->ipxp_route.ro_rt); - remque(ipxp); + LIST_REMOVE(ipxp, ipxp_list); FREE(ipxp, M_PCB); } @@ -319,7 +320,7 @@ ipx_pcblookup(faddr, lport, wildp) u_short fport; fport = faddr->x_port; - for (ipxp = (&ipxpcb)->ipxp_next; ipxp != (&ipxpcb); ipxp = ipxp->ipxp_next) { + LIST_FOREACH(ipxp, &ipxpcb_list, ipxp_list) { if (ipxp->ipxp_lport != lport) continue; wildcard = 0; diff --git a/sys/netipx/ipx_pcb.h b/sys/netipx/ipx_pcb.h index d91865a..144d12b 100644 --- a/sys/netipx/ipx_pcb.h +++ b/sys/netipx/ipx_pcb.h @@ -1,4 +1,5 @@ /* + * Copyright (c) 2004, Robert N. M. Watson * Copyright (c) 1995, Mike Mitchell * Copyright (c) 1984, 1985, 1986, 1987, 1993 * The Regents of the University of California. All rights reserved. @@ -43,9 +44,7 @@ * IPX protocol interface control block. */ struct ipxpcb { - struct ipxpcb *ipxp_next; /* doubly linked list */ - struct ipxpcb *ipxp_prev; - struct ipxpcb *ipxp_head; + LIST_ENTRY(ipxpcb) ipxp_list; struct socket *ipxp_socket; /* back pointer to socket */ struct ipx_addr ipxp_faddr; /* destination address */ struct ipx_addr ipxp_laddr; /* socket's address */ @@ -57,6 +56,13 @@ struct ipxpcb { u_char ipxp_rpt; /* last received packet type by ipx_input() */ }; +/* + * Additional IPX pcb-related types and variables. + */ +LIST_HEAD(ipxpcbhead, ipxpcb); +extern struct ipxpcbhead ipxpcb_list; +extern struct ipxpcbhead ipxrawpcb_list; + /* possible flags */ #define IPXP_IN_ABORT 0x1 /* calling abort through socket */ @@ -81,7 +87,7 @@ struct ipxpcb { #ifdef _KERNEL extern struct ipxpcb ipxpcb; /* head of list */ -int ipx_pcballoc(struct socket *so, struct ipxpcb *head, +int ipx_pcballoc(struct socket *so, struct ipxpcbhead *head, struct thread *p); int ipx_pcbbind(struct ipxpcb *ipxp, struct sockaddr *nam, struct thread *p); diff --git a/sys/netipx/ipx_usrreq.c b/sys/netipx/ipx_usrreq.c index 1c342a7..c7f78f4 100644 --- a/sys/netipx/ipx_usrreq.c +++ b/sys/netipx/ipx_usrreq.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2004, Robert N. M. Watson * Copyright (c) 1995, Mike Mitchell * Copyright (c) 1984, 1985, 1986, 1987, 1993 * The Regents of the University of California. All rights reserved. @@ -455,7 +456,7 @@ ipx_attach(so, proto, td) if (ipxp != NULL) return (EINVAL); s = splnet(); - error = ipx_pcballoc(so, &ipxpcb, td); + error = ipx_pcballoc(so, &ipxpcb_list, td); splx(s); if (error == 0) error = soreserve(so, ipxsendspace, ipxrecvspace); @@ -616,7 +617,7 @@ ripx_attach(so, proto, td) if (td != NULL && (error = suser(td)) != 0) return (error); s = splnet(); - error = ipx_pcballoc(so, &ipxrawpcb, td); + error = ipx_pcballoc(so, &ipxrawpcb_list, td); splx(s); if (error) return (error); diff --git a/sys/netipx/ipx_var.h b/sys/netipx/ipx_var.h index 04cbec5..2cef866 100644 --- a/sys/netipx/ipx_var.h +++ b/sys/netipx/ipx_var.h @@ -66,7 +66,6 @@ SYSCTL_DECL(_net_ipx_ipx); extern int ipxcksum; extern long ipx_pexseq; extern struct ipxstat ipxstat; -extern struct ipxpcb ipxrawpcb; extern struct pr_usrreqs ipx_usrreqs; extern struct pr_usrreqs ripx_usrreqs; extern struct sockaddr_ipx ipx_netmask; diff --git a/sys/netipx/spx_usrreq.c b/sys/netipx/spx_usrreq.c index 409bf46..01cd86b 100644 --- a/sys/netipx/spx_usrreq.c +++ b/sys/netipx/spx_usrreq.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2004, Robert N. M. Watson * Copyright (c) 1995, Mike Mitchell * Copyright (c) 1984, 1985, 1986, 1987, 1993 * The Regents of the University of California. All rights reserved. @@ -1310,7 +1311,7 @@ spx_attach(so, proto, td) if (ipxp != NULL) return (EISCONN); s = splnet(); - error = ipx_pcballoc(so, &ipxpcb, td); + error = ipx_pcballoc(so, &ipxpcb_list, td); if (error) goto spx_attach_end; if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { @@ -1731,9 +1732,7 @@ spx_fasttimo() register struct spxpcb *cb; int s = splnet(); - ipxp = ipxpcb.ipxp_next; - if (ipxp != NULL) - for (; ipxp != &ipxpcb; ipxp = ipxp->ipxp_next) + LIST_FOREACH(ipxp, &ipxpcb_list, ipxp_list) { if ((cb = (struct spxpcb *)ipxp->ipxp_pcb) != NULL && (cb->s_flags & SF_DELACK)) { cb->s_flags &= ~SF_DELACK; @@ -1741,6 +1740,8 @@ spx_fasttimo() spxstat.spxs_delack++; spx_output(cb, (struct mbuf *)NULL); } + } + splx(s); } @@ -1752,36 +1753,32 @@ spx_fasttimo() void spx_slowtimo() { - register struct ipxpcb *ip, *ipnxt; + register struct ipxpcb *ip, *ip_temp; register struct spxpcb *cb; int s = splnet(); register int i; /* - * Search through tcb's and update active timers. + * Search through tcb's and update active timers. Note that timers + * may free the ipxpcb, so be sure to handle that case. */ - ip = ipxpcb.ipxp_next; - if (ip == NULL) { - splx(s); - return; - } - while (ip != &ipxpcb) { + LIST_FOREACH_SAFE(ip, &ipxpcb_list, ipxp_list, ip_temp) { cb = ipxtospxpcb(ip); - ipnxt = ip->ipxp_next; if (cb == NULL) - goto tpgone; + continue; for (i = 0; i < SPXT_NTIMERS; i++) { if (cb->s_timer[i] && --cb->s_timer[i] == 0) { - spx_timers(cb, i); - if (ipnxt->ipxp_prev != ip) - goto tpgone; + /* + * spx_timers() returns (NULL) if it free'd + * the pcb. + */ + if (spx_timers(cb, i) == NULL) + continue; } } cb->s_idle++; if (cb->s_rtt) cb->s_rtt++; -tpgone: - ip = ipnxt; } spx_iss += SPX_ISSINCR/PR_SLOWHZ; /* increment iss */ splx(s); -- cgit v1.1