0) preallocate per-interface context structures without the ifnet lock held

1) avoid immediately calling bzero() after malloc() by passing M_ZERO
2) do not initialize individual members of the global context to zero
3) remove an unused assignment of ifctx in bootpc_init()

Reviewed by:	tegge
This commit is contained in:
Bill Fumerola 2003-08-07 21:27:17 +00:00
parent 4bab0ee528
commit 2766bd022f

View File

@ -232,7 +232,7 @@ static int xdr_int_decode(struct mbuf **ptr, int *iptr);
static void print_in_addr(struct in_addr addr);
static void print_sin_addr(struct sockaddr_in *addr);
static void clear_sinaddr(struct sockaddr_in *sin);
static struct bootpc_ifcontext *allocifctx(struct bootpc_globalcontext *gctx);
static void allocifctx(struct bootpc_globalcontext *gctx);
static void bootpc_compose_query(struct bootpc_ifcontext *ifctx,
struct bootpc_globalcontext *gctx, struct thread *td);
static unsigned char *bootpc_tag(struct bootpc_tagcontext *tctx,
@ -428,16 +428,15 @@ clear_sinaddr(struct sockaddr_in *sin)
sin->sin_port = 0;
}
static struct bootpc_ifcontext *
static void
allocifctx(struct bootpc_globalcontext *gctx)
{
struct bootpc_ifcontext *ifctx;
ifctx = (struct bootpc_ifcontext *) malloc(sizeof(*ifctx),
M_TEMP, M_WAITOK);
M_TEMP, M_WAITOK | M_ZERO);
if (ifctx == NULL)
panic("Failed to allocate bootp interface context structure");
bzero(ifctx, sizeof(*ifctx));
ifctx->xid = gctx->xid;
#ifdef BOOTP_NO_DHCP
ifctx->state = IF_BOOTP_UNRESOLVED;
@ -445,7 +444,11 @@ allocifctx(struct bootpc_globalcontext *gctx)
ifctx->state = IF_DHCP_UNRESOLVED;
#endif
gctx->xid += 0x100;
return ifctx;
if (gctx->interfaces != NULL)
gctx->lastinterface->next = ifctx;
else
gctx->interfaces = ifctx;
gctx->lastinterface = ifctx;
}
static __inline int
@ -1659,6 +1662,9 @@ bootpc_init(void)
struct bootpc_globalcontext *gctx; /* Global BOOTP context */
struct ifnet *ifp;
int error;
#ifndef BOOTP_WIRED_TO
int ifcnt;
#endif
struct nfsv3_diskless *nd;
struct thread *td;
@ -1671,27 +1677,45 @@ bootpc_init(void)
if (nfs_diskless_valid != 0)
return;
gctx = malloc(sizeof(*gctx), M_TEMP, M_WAITOK);
gctx = malloc(sizeof(*gctx), M_TEMP, M_WAITOK | M_ZERO);
if (gctx == NULL)
panic("Failed to allocate bootp global context structure");
bzero(gctx, sizeof(*gctx));
gctx->xid = ~0xFFFF;
gctx->starttime = time_second;
ifctx = allocifctx(gctx);
/*
* Find a network interface.
*/
#ifdef BOOTP_WIRED_TO
printf("bootpc_init: wired to interface '%s'\n",
__XSTRING(BOOTP_WIRED_TO));
#endif
bzero(&ifctx->ireq, sizeof(ifctx->ireq));
allocifctx(gctx);
#else
/*
* Preallocate interface context storage, if another interface
* attaches and wins the race, it won't be eligible for bootp.
*/
IFNET_RLOCK();
for (ifp = TAILQ_FIRST(&ifnet);
for (ifp = TAILQ_FIRST(&ifnet), ifcnt = 0;
ifp != NULL;
ifp = TAILQ_NEXT(ifp, if_link)) {
if ((ifp->if_flags &
(IFF_LOOPBACK | IFF_POINTOPOINT | IFF_BROADCAST)) !=
IFF_BROADCAST)
continue;
ifcnt++;
}
IFNET_RUNLOCK();
if (ifcnt == 0)
panic("bootpc_init: no eligible interfaces");
for (; ifcnt > 0; ifcnt--)
allocifctx(gctx);
#endif
IFNET_RLOCK();
for (ifp = TAILQ_FIRST(&ifnet), ifctx = gctx->interfaces;
ifp != NULL && ifctx != NULL;
ifp = TAILQ_NEXT(ifp, if_link)) {
snprintf(ifctx->ireq.ifr_name, sizeof(ifctx->ireq.ifr_name),
"%s%d", ifp->if_name, ifp->if_unit);
@ -1705,18 +1729,12 @@ bootpc_init(void)
IFF_BROADCAST)
continue;
#endif
if (gctx->interfaces != NULL)
gctx->lastinterface->next = ifctx;
else
gctx->interfaces = ifctx;
ifctx->ifp = ifp;
gctx->lastinterface = ifctx;
ifctx = allocifctx(gctx);
ifctx = ifctx->next;
}
IFNET_RUNLOCK();
free(ifctx, M_TEMP);
if (gctx->interfaces == NULL) {
if (gctx->interfaces == NULL || gctx->interfaces->ifp == NULL) {
#ifdef BOOTP_WIRED_TO
panic("bootpc_init: Could not find interface specified "
"by BOOTP_WIRED_TO: "
@ -1726,17 +1744,12 @@ bootpc_init(void)
#endif
}
gctx->gotrootpath = 0;
gctx->gotswappath = 0;
gctx->gotgw = 0;
for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next)
bootpc_fakeup_interface(ifctx, gctx, td);
for (ifctx = gctx->interfaces; ifctx != NULL; ifctx = ifctx->next)
bootpc_compose_query(ifctx, gctx, td);
ifctx = gctx->interfaces;
error = bootpc_call(gctx, td);
if (error != 0) {