From nobody Thu Sep 22 09:33:31 2022 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4MY97v586Tz4ctdk; Thu, 22 Sep 2022 09:33:31 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4MY97v4bxyz3lG8; Thu, 22 Sep 2022 09:33:31 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1663839211; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=BctT5Y9PNF60yYXszFG6dphALaffgo9Q7kx12+1arXU=; b=k+k/sa2El24WKSHA/AH1GDvve7Qy+AuxbkUNM+Yod1hGJ1TY+8ASbA3dzbSEZaU2Qagc9Y 9bb+a3SoZtz3RpEEDSINBgs1ghNdvPyZMatOFdeK8a6XdzN9TLLIAqU2OeIrrBWUuIB1sV Zgp8v7jCTNiIz46y4G3yNr5K5rRdlQwjfpk14OCwW3ItjfUPnr/sAT3Nur3u+mwjqY/N3v 3u6icgm3XGZZO2WEsr9mEWqUEosnVKLQpWJUSzUsPFEbJnpDaFVV0+eysMUFBdsH/1Od73 /L/i8vDjCgjlBzWWdnjkwty2JsSuVznk+8Px6BSTfHfiVVj5cFnaI0PfoTbrcg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4MY97v3dY5zMf5; Thu, 22 Sep 2022 09:33:31 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 28M9XVcq052284; Thu, 22 Sep 2022 09:33:31 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 28M9XVRF052283; Thu, 22 Sep 2022 09:33:31 GMT (envelope-from git) Date: Thu, 22 Sep 2022 09:33:31 GMT Message-Id: <202209220933.28M9XVRF052283@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: "Alexander V. Chernikov" Subject: git: 12aeeb91903b - main - epair: deduplicate interface allocation code #1 List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: melifaro X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 12aeeb91903bbb4a117aa00cd32a7c0504ebded0 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1663839211; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=BctT5Y9PNF60yYXszFG6dphALaffgo9Q7kx12+1arXU=; b=HAxuL8LiMjlTiaZ43L18vAwIk7fjPgDCVsQfoqnboHh0GV2nEkiBZNyq/OHXbt+FQ9IrSV 4/0lQmGhoFsr8MHe5Gt8e9QuGQ0IQ15frq9yUbvfZsre1xv3tPsTvSwf40TBfXJUWaOq2Z 7wARGlVEaWzLrNpUoxO3ItHjwOlpfPZMJqfzXOB/EH3+cAkqnMAQLdiF0OQdztqaal9Qta k29gNed3kWfdxBqSKc8YAA3uwB1sWI4bcnUrMZEmqgCBkv+0y2hKp0TRL2SC67OoJNI+Ky qe5/M70kt99zO9hKvakqcORaBkXEJcpyVZ5byghTvS7Qzya2zjC6NMnrreE7cA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1663839211; a=rsa-sha256; cv=none; b=ms3k324VBlZpmEq1A/YxhJZPmtunFdNLkWtEKaSodoNbyQuMQtAibB6LLEN0OxfG0Jq3g1 wLw7itJh7QX7yMcL4wm1RDPm4FzbGxMwkarLYRcpp9O8/5ihgMZXn1LpPW3nv9pRHDys/D V2ViaeEW+o4vtbRoxd6u7aB69ff2elL2tv4WWcFiY+Lb4/LnbCUTvdB2zyZGPxpaiD72Le NNZGs/4GS4B1/T65R1a610RF//SeanVHkKC8WH30AIszrKRgHyVpS/k0/E+6YNssDvVuw9 1KhnYlCNLOtJ+HX73m4ns8KxYQTovHE6PtC4f/EqMGzcgYKTEdtiOY+EtP0Bdg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by melifaro: URL: https://cgit.FreeBSD.org/src/commit/?id=12aeeb91903bbb4a117aa00cd32a7c0504ebded0 commit 12aeeb91903bbb4a117aa00cd32a7c0504ebded0 Author: Alexander V. Chernikov AuthorDate: 2022-09-22 09:01:03 +0000 Commit: Alexander V. Chernikov CommitDate: 2022-09-22 09:06:06 +0000 epair: deduplicate interface allocation code #1 Simplify epair_clone_create() and epair_clone_destroy() by factoring out epair softc allocation / desctruction and interface setup/teardown into separate functions. Reviewed By: kp, zlei.huang_gmail.com Differential Revision: https://reviews.freebsd.org/D36614 MFC after: 2 weeks --- sys/net/if_epair.c | 274 ++++++++++++++++++++++++++--------------------------- 1 file changed, 137 insertions(+), 137 deletions(-) diff --git a/sys/net/if_epair.c b/sys/net/if_epair.c index 21e50b5171aa..1dc5cb695d86 100644 --- a/sys/net/if_epair.c +++ b/sys/net/if_epair.c @@ -385,6 +385,11 @@ epair_transmit(struct ifnet *ifp, struct mbuf *m) return (error); } +static void +epair_qflush(struct ifnet *ifp __unused) +{ +} + static int epair_media_change(struct ifnet *ifp __unused) { @@ -486,6 +491,126 @@ epair_clone_add(struct if_clone *ifc, struct epair_softc *scb) if_clone_addif(ifc, ifp); } +static struct epair_softc * +epair_alloc_sc(struct if_clone *ifc) +{ + struct epair_softc *sc; + + struct ifnet *ifp = if_alloc(IFT_ETHER); + if (ifp == NULL) + return (NULL); + + sc = malloc(sizeof(struct epair_softc), M_EPAIR, M_WAITOK | M_ZERO); + sc->ifp = ifp; + sc->num_queues = epair_tasks.tasks; + sc->queues = mallocarray(sc->num_queues, sizeof(struct epair_queue), + M_EPAIR, M_WAITOK); + for (int i = 0; i < sc->num_queues; i++) { + struct epair_queue *q = &sc->queues[i]; + q->id = i; + q->rxring[0] = buf_ring_alloc(RXRSIZE, M_EPAIR, M_WAITOK, NULL); + q->rxring[1] = buf_ring_alloc(RXRSIZE, M_EPAIR, M_WAITOK, NULL); + q->ridx = 0; + q->state = 0; + q->sc = sc; + NET_TASK_INIT(&q->tx_task, 0, epair_tx_start_deferred, q); + } + + /* Initialise pseudo media types. */ + ifmedia_init(&sc->media, 0, epair_media_change, epair_media_status); + ifmedia_add(&sc->media, IFM_ETHER | IFM_10G_T, 0, NULL); + ifmedia_set(&sc->media, IFM_ETHER | IFM_10G_T); + + return (sc); +} + +static void +epair_setup_ifp(struct epair_softc *sc, char *name, int unit) +{ + struct ifnet *ifp = sc->ifp; + + ifp->if_softc = sc; + strlcpy(ifp->if_xname, name, IFNAMSIZ); + ifp->if_dname = epairname; + ifp->if_dunit = unit; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_flags |= IFF_KNOWSEPOCH; + ifp->if_capabilities = IFCAP_VLAN_MTU; + ifp->if_capenable = IFCAP_VLAN_MTU; + ifp->if_transmit = epair_transmit; + ifp->if_qflush = epair_qflush; + ifp->if_start = epair_start; + ifp->if_ioctl = epair_ioctl; + ifp->if_init = epair_init; + if_setsendqlen(ifp, ifqmaxlen); + if_setsendqready(ifp); + + ifp->if_baudrate = IF_Gbps(10); /* arbitrary maximum */ +} + +static void +epair_generate_mac(struct epair_softc *sc, uint8_t *eaddr) +{ + uint32_t key[3]; + uint32_t hash; + uint64_t hostid; + + EPAIR_LOCK(); +#ifdef SMP + /* Get an approximate distribution. */ + hash = next_index % mp_ncpus; +#else + hash = 0; +#endif + EPAIR_UNLOCK(); + + /* + * Calculate the etheraddr hashing the hostid and the + * interface index. The result would be hopefully unique. + * Note that the "a" component of an epair instance may get moved + * to a different VNET after creation. In that case its index + * will be freed and the index can get reused by new epair instance. + * Make sure we do not create same etheraddr again. + */ + getcredhostid(curthread->td_ucred, (unsigned long *)&hostid); + if (hostid == 0) + arc4rand(&hostid, sizeof(hostid), 0); + + struct ifnet *ifp = sc->ifp; + EPAIR_LOCK(); + if (ifp->if_index > next_index) + next_index = ifp->if_index; + else + next_index++; + + key[0] = (uint32_t)next_index; + EPAIR_UNLOCK(); + key[1] = (uint32_t)(hostid & 0xffffffff); + key[2] = (uint32_t)((hostid >> 32) & 0xfffffffff); + hash = jenkins_hash32(key, 3, 0); + + eaddr[0] = 0x02; + memcpy(&eaddr[1], &hash, 4); + eaddr[5] = 0x0a; +} + +static void +epair_free_sc(struct epair_softc *sc) +{ + if (sc == NULL) + return; + + if_free(sc->ifp); + ifmedia_removeall(&sc->media); + for (int i = 0; i < sc->num_queues; i++) { + struct epair_queue *q = &sc->queues[i]; + buf_ring_free(q->rxring[0], M_EPAIR); + buf_ring_free(q->rxring[1], M_EPAIR); + } + free(sc->queues, M_EPAIR); + free(sc, M_EPAIR); +} + static int epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) { @@ -493,9 +618,6 @@ epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) struct ifnet *ifp; char *dp; int error, unit, wildcard; - uint64_t hostid; - uint32_t key[3]; - uint32_t hash; uint8_t eaddr[ETHER_ADDR_LEN]; /* 00:00:00:00:00:00 */ /* Try to see if a special unit was requested. */ @@ -539,49 +661,14 @@ epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) return (EEXIST); /* Allocate memory for both [ab] interfaces */ - sca = malloc(sizeof(struct epair_softc), M_EPAIR, M_WAITOK | M_ZERO); - sca->ifp = if_alloc(IFT_ETHER); - sca->num_queues = epair_tasks.tasks; - if (sca->ifp == NULL) { - free(sca, M_EPAIR); + sca = epair_alloc_sc(ifc); + scb = epair_alloc_sc(ifc); + if (sca == NULL || scb == NULL) { + epair_free_sc(sca); + epair_free_sc(scb); ifc_free_unit(ifc, unit); return (ENOSPC); } - sca->queues = mallocarray(sca->num_queues, sizeof(struct epair_queue), - M_EPAIR, M_WAITOK); - for (int i = 0; i < sca->num_queues; i++) { - struct epair_queue *q = &sca->queues[i]; - q->id = i; - q->rxring[0] = buf_ring_alloc(RXRSIZE, M_EPAIR, M_WAITOK, NULL); - q->rxring[1] = buf_ring_alloc(RXRSIZE, M_EPAIR, M_WAITOK, NULL); - q->ridx = 0; - q->state = 0; - q->sc = sca; - NET_TASK_INIT(&q->tx_task, 0, epair_tx_start_deferred, q); - } - - scb = malloc(sizeof(struct epair_softc), M_EPAIR, M_WAITOK | M_ZERO); - scb->ifp = if_alloc(IFT_ETHER); - scb->num_queues = epair_tasks.tasks; - if (scb->ifp == NULL) { - free(scb, M_EPAIR); - if_free(sca->ifp); - free(sca, M_EPAIR); - ifc_free_unit(ifc, unit); - return (ENOSPC); - } - scb->queues = mallocarray(scb->num_queues, sizeof(struct epair_queue), - M_EPAIR, M_WAITOK); - for (int i = 0; i < scb->num_queues; i++) { - struct epair_queue *q = &scb->queues[i]; - q->id = i; - q->rxring[0] = buf_ring_alloc(RXRSIZE, M_EPAIR, M_WAITOK, NULL); - q->rxring[1] = buf_ring_alloc(RXRSIZE, M_EPAIR, M_WAITOK, NULL); - q->ridx = 0; - q->state = 0; - q->sc = scb; - NET_TASK_INIT(&q->tx_task, 0, epair_tx_start_deferred, q); - } /* * Cross-reference the interfaces so we will be able to free both. @@ -589,96 +676,25 @@ epair_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) sca->oifp = scb->ifp; scb->oifp = sca->ifp; - EPAIR_LOCK(); -#ifdef SMP - /* Get an approximate distribution. */ - hash = next_index % mp_ncpus; -#else - hash = 0; -#endif - EPAIR_UNLOCK(); - - /* Initialise pseudo media types. */ - ifmedia_init(&sca->media, 0, epair_media_change, epair_media_status); - ifmedia_add(&sca->media, IFM_ETHER | IFM_10G_T, 0, NULL); - ifmedia_set(&sca->media, IFM_ETHER | IFM_10G_T); - ifmedia_init(&scb->media, 0, epair_media_change, epair_media_status); - ifmedia_add(&scb->media, IFM_ETHER | IFM_10G_T, 0, NULL); - ifmedia_set(&scb->media, IFM_ETHER | IFM_10G_T); - /* Finish initialization of interface a. */ ifp = sca->ifp; - ifp->if_softc = sca; - strlcpy(ifp->if_xname, name, IFNAMSIZ); - ifp->if_dname = epairname; - ifp->if_dunit = unit; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_flags |= IFF_KNOWSEPOCH; - ifp->if_capabilities = IFCAP_VLAN_MTU; - ifp->if_capenable = IFCAP_VLAN_MTU; - ifp->if_start = epair_start; - ifp->if_ioctl = epair_ioctl; - ifp->if_init = epair_init; - if_setsendqlen(ifp, ifqmaxlen); - if_setsendqready(ifp); + epair_setup_ifp(sca, name, unit); + epair_generate_mac(sca, eaddr); - /* - * Calculate the etheraddr hashing the hostid and the - * interface index. The result would be hopefully unique. - * Note that the "a" component of an epair instance may get moved - * to a different VNET after creation. In that case its index - * will be freed and the index can get reused by new epair instance. - * Make sure we do not create same etheraddr again. - */ - getcredhostid(curthread->td_ucred, (unsigned long *)&hostid); - if (hostid == 0) - arc4rand(&hostid, sizeof(hostid), 0); - - EPAIR_LOCK(); - if (ifp->if_index > next_index) - next_index = ifp->if_index; - else - next_index++; - - key[0] = (uint32_t)next_index; - EPAIR_UNLOCK(); - key[1] = (uint32_t)(hostid & 0xffffffff); - key[2] = (uint32_t)((hostid >> 32) & 0xfffffffff); - hash = jenkins_hash32(key, 3, 0); - - eaddr[0] = 0x02; - memcpy(&eaddr[1], &hash, 4); - eaddr[5] = 0x0a; ether_ifattach(ifp, eaddr); - ifp->if_baudrate = IF_Gbps(10); /* arbitrary maximum */ - ifp->if_transmit = epair_transmit; /* Swap the name and finish initialization of interface b. */ *dp = 'b'; + epair_setup_ifp(scb, name, unit); + ifp = scb->ifp; - ifp->if_softc = scb; - strlcpy(ifp->if_xname, name, IFNAMSIZ); - ifp->if_dname = epairname; - ifp->if_dunit = unit; - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_flags |= IFF_KNOWSEPOCH; - ifp->if_capabilities = IFCAP_VLAN_MTU; - ifp->if_capenable = IFCAP_VLAN_MTU; - ifp->if_start = epair_start; - ifp->if_ioctl = epair_ioctl; - ifp->if_init = epair_init; - if_setsendqlen(ifp, ifqmaxlen); - if_setsendqready(ifp); /* We need to play some tricks here for the second interface. */ strlcpy(name, epairname, len); - /* Correctly set the name for the cloner list. */ strlcpy(name, scb->ifp->if_xname, len); - epair_clone_add(ifc, scb); - ifp->if_baudrate = IF_Gbps(10); /* arbitrary maximum */ - ifp->if_transmit = epair_transmit; + epair_clone_add(ifc, scb); /* * Restore name to a as the ifp for this will go into the @@ -751,27 +767,11 @@ epair_clone_destroy(struct if_clone *ifc, struct ifnet *ifp) if (error) panic("%s: if_clone_destroyif() for our 2nd iface failed: %d", __func__, error); - if_free(oifp); - ifmedia_removeall(&scb->media); - for (int i = 0; i < scb->num_queues; i++) { - struct epair_queue *q = &scb->queues[i]; - buf_ring_free(q->rxring[0], M_EPAIR); - buf_ring_free(q->rxring[1], M_EPAIR); - } - free(scb->queues, M_EPAIR); - free(scb, M_EPAIR); + epair_free_sc(scb); CURVNET_RESTORE(); epair_drain_rings(sca); - if_free(ifp); - ifmedia_removeall(&sca->media); - for (int i = 0; i < sca->num_queues; i++) { - struct epair_queue *q = &sca->queues[i]; - buf_ring_free(q->rxring[0], M_EPAIR); - buf_ring_free(q->rxring[1], M_EPAIR); - } - free(sca->queues, M_EPAIR); - free(sca, M_EPAIR); + epair_free_sc(sca); /* Last free the cloner unit. */ ifc_free_unit(ifc, unit);