Index: if.c =================================================================== RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.615 diff -u -p -r1.615 if.c --- if.c 22 Jul 2020 02:16:01 -0000 1.615 +++ if.c 23 Jul 2020 09:22:47 -0000 @@ -195,17 +195,20 @@ void if_map_dtor(void *, void *); struct ifnet *if_ref(struct ifnet *); /* - * struct if_map + * union if_map * * bounded array of ifnet srp pointers used to fetch references of live * interfaces with if_get(). */ -struct if_map { - unsigned long limit; - /* followed by limit ifnet srp pointers */ +union if_map { + unsigned int limit; + /* followed by limit-1 ifnet srp pointers */ + struct srp srp; }; +#define IF_MAP_SRP(_if_map, _i) (&(_if_map)[(_i)].srp) + /* * struct if_idxmap * @@ -281,19 +284,15 @@ struct ifnet_head ifnet = TAILQ_HEAD_INI void if_idxmap_init(unsigned int limit) { - struct if_map *if_map; - struct srp *map; + union if_map *if_map; unsigned int i; - if_idxmap.serial = 1; /* skip ifidx 0 so it can return NULL */ - - if_map = malloc(sizeof(*if_map) + limit * sizeof(*map), - M_IFADDR, M_WAITOK); + if_idxmap.serial = 1; /* skip ifidx 0 */ + if_map = mallocarray(limit, sizeof(*if_map), M_IFADDR, M_WAITOK); if_map->limit = limit; - map = (struct srp *)(if_map + 1); - for (i = 0; i < limit; i++) - srp_init(&map[i]); + for (i = 1; i < limit; i++) + srp_init(IF_MAP_SRP(if_map, i)); /* this is called early so there's nothing to race with */ srp_update_locked(&if_map_gc, &if_idxmap.map, if_map); @@ -302,8 +301,7 @@ if_idxmap_init(unsigned int limit) void if_idxmap_insert(struct ifnet *ifp) { - struct if_map *if_map; - struct srp *map; + union if_map *if_map; unsigned int index, i; refcnt_init(&ifp->if_refcnt); @@ -315,44 +313,41 @@ if_idxmap_insert(struct ifnet *ifp) panic("too many interfaces"); if_map = srp_get_locked(&if_idxmap.map); - map = (struct srp *)(if_map + 1); index = if_idxmap.serial++ & USHRT_MAX; if (index >= if_map->limit) { - struct if_map *nif_map; - struct srp *nmap; + union if_map *nif_map; unsigned int nlimit; struct ifnet *nifp; nlimit = if_map->limit * 2; - nif_map = malloc(sizeof(*nif_map) + nlimit * sizeof(*nmap), + nif_map = mallocarray(nlimit, sizeof(*nif_map), M_IFADDR, M_WAITOK); - nmap = (struct srp *)(nif_map + 1); nif_map->limit = nlimit; - for (i = 0; i < if_map->limit; i++) { - srp_init(&nmap[i]); - nifp = srp_get_locked(&map[i]); + for (i = 1; i < if_map->limit; i++) { + srp_init(IF_MAP_SRP(nif_map, i)); + nifp = srp_get_locked(IF_MAP_SRP(if_map, i)); if (nifp != NULL) { - srp_update_locked(&if_ifp_gc, &nmap[i], - if_ref(nifp)); + srp_update_locked(&if_ifp_gc, + IF_MAP_SRP(nif_map, i), if_ref(nifp)); } } while (i < nlimit) { - srp_init(&nmap[i]); + srp_init(IF_MAP_SRP(nif_map, i)); i++; } srp_update_locked(&if_map_gc, &if_idxmap.map, nif_map); if_map = nif_map; - map = nmap; } /* pick the next free index */ - for (i = 0; i < USHRT_MAX; i++) { - if (index != 0 && srp_get_locked(&map[index]) == NULL) + for (i = 1; i < USHRT_MAX; i++) { + if (index != 0 && + srp_get_locked(IF_MAP_SRP(if_map, index)) == NULL) break; index = if_idxmap.serial++ & USHRT_MAX; @@ -360,14 +355,13 @@ if_idxmap_insert(struct ifnet *ifp) /* commit */ ifp->if_index = index; - srp_update_locked(&if_ifp_gc, &map[index], if_ref(ifp)); + srp_update_locked(&if_ifp_gc, IF_MAP_SRP(if_map, index), if_ref(ifp)); } void if_idxmap_remove(struct ifnet *ifp) { - struct if_map *if_map; - struct srp *map; + union if_map *if_map; unsigned int index; index = ifp->if_index; @@ -378,10 +372,9 @@ if_idxmap_remove(struct ifnet *ifp) if_map = srp_get_locked(&if_idxmap.map); KASSERT(index < if_map->limit); - map = (struct srp *)(if_map + 1); - KASSERT(ifp == (struct ifnet *)srp_get_locked(&map[index])); + KASSERT(ifp == srp_get_locked(IF_MAP_SRP(if_map, index))); - srp_update_locked(&if_ifp_gc, &map[index], NULL); + srp_update_locked(&if_ifp_gc, IF_MAP_SRP(if_map, index), NULL); if_idxmap.count--; /* end of if_idxmap modifications */ @@ -398,18 +391,17 @@ if_ifp_dtor(void *null, void *ifp) void if_map_dtor(void *null, void *m) { - struct if_map *if_map = m; - struct srp *map = (struct srp *)(if_map + 1); + union if_map *if_map = m; unsigned int i; /* * dont need to serialize the use of update_locked since this is * the last reference to this map. there's nothing to race against. */ - for (i = 0; i < if_map->limit; i++) - srp_update_locked(&if_ifp_gc, &map[i], NULL); + for (i = 1; i < if_map->limit; i++) + srp_update_locked(&if_ifp_gc, IF_MAP_SRP(if_map, i), NULL); - free(if_map, M_IFADDR, sizeof(*if_map) + if_map->limit * sizeof(*map)); + free(if_map, M_IFADDR, sizeof(*if_map) * if_map->limit); } /* @@ -1660,15 +1652,15 @@ struct ifnet * if_get(unsigned int index) { struct srp_ref sr; - struct if_map *if_map; - struct srp *map; + union if_map *if_map; struct ifnet *ifp = NULL; + if (index == 0) + return (NULL); + if_map = srp_enter(&sr, &if_idxmap.map); if (index < if_map->limit) { - map = (struct srp *)(if_map + 1); - - ifp = srp_follow(&sr, &map[index]); + ifp = srp_follow(&sr, IF_MAP_SRP(if_map, index)); if (ifp != NULL) { KASSERT(ifp->if_index == index); if_ref(ifp);