Module Name: src Committed By: thorpej Date: Fri Jan 31 00:49:18 UTC 2020
Modified Files: src/sys/net: if_media.c Log Message: - Use kmem(9) instead of malloc(9). - When handling SIOCGIFMEDIA, don't traverse the media list directly; refactor that out into a ifmedia_getwords() function. To generate a diff of this commit: cvs rdiff -u -r1.49 -r1.50 src/sys/net/if_media.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/if_media.c diff -u src/sys/net/if_media.c:1.49 src/sys/net/if_media.c:1.50 --- src/sys/net/if_media.c:1.49 Mon Jan 20 19:35:39 2020 +++ src/sys/net/if_media.c Fri Jan 31 00:49:18 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: if_media.c,v 1.49 2020/01/20 19:35:39 thorpej Exp $ */ +/* $NetBSD: if_media.c,v 1.50 2020/01/31 00:49:18 thorpej Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -76,14 +76,14 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_media.c,v 1.49 2020/01/20 19:35:39 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_media.c,v 1.50 2020/01/31 00:49:18 thorpej Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/errno.h> #include <sys/ioctl.h> #include <sys/socket.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <net/if.h> #include <net/if_media.h> @@ -106,8 +106,6 @@ int ifmedia_debug = 0; static void ifmedia_printword(int); #endif -MALLOC_DEFINE(M_IFMEDIA, "ifmedia", "interface media state"); - /* * Initialize if_media struct for a specific interface instance. */ @@ -162,7 +160,7 @@ ifmedia_add(struct ifmedia *ifm, int mwo } #endif - entry = malloc(sizeof(*entry), M_IFMEDIA, M_WAITOK); + entry = kmem_zalloc(sizeof(*entry), KM_SLEEP); entry->ifm_media = mword; entry->ifm_data = data; entry->ifm_aux = aux; @@ -235,6 +233,22 @@ ifmedia_set(struct ifmedia *ifm, int tar #endif } +static int +ifmedia_getwords(struct ifmedia * const ifm, int *words, int maxwords) +{ + struct ifmedia_entry *ep; + int nwords = 0; + + TAILQ_FOREACH(ep, &ifm->ifm_list, ifm_list) { + if (words != NULL && nwords < maxwords) { + words[nwords] = ep->ifm_media; + } + nwords++; + } + + return nwords; +} + /* * Device-independent media ioctl support function. */ @@ -304,8 +318,7 @@ ifmedia_ioctl_locked(struct ifnet *ifp, /* Get list of available media and current media on interface. */ case SIOCGIFMEDIA: { - struct ifmedia_entry *ep; - size_t nwords; + int nwords1, nwords2; if (ifmr->ifm_count < 0) return EINVAL; @@ -320,31 +333,22 @@ ifmedia_ioctl_locked(struct ifnet *ifp, * Count them so we know a-priori how much is the max we'll * need. */ - ep = TAILQ_FIRST(&ifm->ifm_list); - for (nwords = 0; ep != NULL; ep = TAILQ_NEXT(ep, ifm_list)) - nwords++; + nwords1 = nwords2 = ifmedia_getwords(ifm, NULL, 0); if (ifmr->ifm_count != 0) { - size_t count; - size_t minwords = nwords > (size_t)ifmr->ifm_count - ? (size_t)ifmr->ifm_count : nwords; - int *kptr = malloc(minwords * sizeof(int), M_TEMP, - M_WAITOK); - - /* Get the media words from the interface's list. */ - ep = TAILQ_FIRST(&ifm->ifm_list); - for (count = 0; ep != NULL && count < minwords; - ep = TAILQ_NEXT(ep, ifm_list), count++) - kptr[count] = ep->ifm_media; + int maxwords = MIN(nwords1, ifmr->ifm_count); + int *kptr = kmem_zalloc(maxwords * sizeof(int), + KM_SLEEP); + nwords2 = ifmedia_getwords(ifm, kptr, maxwords); error = copyout(kptr, ifmr->ifm_ulist, - minwords * sizeof(int)); - if (error == 0 && ep != NULL) + maxwords * sizeof(int)); + if (error == 0 && nwords2 > nwords1) error = E2BIG; /* oops! */ - free(kptr, M_TEMP); + kmem_free(kptr, maxwords * sizeof(int)); } /* Update with the real number */ - ifmr->ifm_count = nwords; + ifmr->ifm_count = nwords2; break; } @@ -420,7 +424,7 @@ ifmedia_delete_instance(struct ifmedia * if (inst == IFM_INST_ANY || inst == IFM_INST(ife->ifm_media)) { TAILQ_REMOVE(&ifm->ifm_list, ife, ifm_list); - free(ife, M_IFMEDIA); + kmem_free(ife, sizeof(*ife)); } } if (inst == IFM_INST_ANY) {