diff options
author | Bill Fumerola <billf@FreeBSD.org> | 2003-08-07 21:27:17 +0000 |
---|---|---|
committer | Bill Fumerola <billf@FreeBSD.org> | 2003-08-07 21:27:17 +0000 |
commit | 2766bd022fb9875992a8eaffed726b2f83d792a4 (patch) | |
tree | d917f118ba431ce6d25a65bca0a73461c92ade44 /sys/nfsclient/bootp_subr.c | |
parent | 4bab0ee5284a5520232764afef461329243dde21 (diff) | |
download | src-2766bd022fb9875992a8eaffed726b2f83d792a4.tar.gz src-2766bd022fb9875992a8eaffed726b2f83d792a4.zip |
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
Notes
Notes:
svn path=/head/; revision=118639
Diffstat (limited to 'sys/nfsclient/bootp_subr.c')
-rw-r--r-- | sys/nfsclient/bootp_subr.c | 63 |
1 files changed, 38 insertions, 25 deletions
diff --git a/sys/nfsclient/bootp_subr.c b/sys/nfsclient/bootp_subr.c index ee1e824c14b0..61c02c0246e6 100644 --- a/sys/nfsclient/bootp_subr.c +++ b/sys/nfsclient/bootp_subr.c @@ -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,28 +1677,46 @@ 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); #ifdef BOOTP_WIRED_TO @@ -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) { |