Date: Mon, 21 Oct 2019 18:11:11 +0000 (UTC) From: Gleb Smirnoff <glebius@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r353841 - head/sys/dev/cxgbe Message-ID: <201910211811.x9LIBB7m067481@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: glebius Date: Mon Oct 21 18:11:11 2019 New Revision: 353841 URL: https://svnweb.freebsd.org/changeset/base/353841 Log: Convert to if_foreach_llmaddr() KPI. Modified: head/sys/dev/cxgbe/t4_main.c Modified: head/sys/dev/cxgbe/t4_main.c ============================================================================== --- head/sys/dev/cxgbe/t4_main.c Mon Oct 21 18:11:08 2019 (r353840) +++ head/sys/dev/cxgbe/t4_main.c Mon Oct 21 18:11:11 2019 (r353841) @@ -4782,7 +4782,55 @@ apply_link_config(struct port_info *pi) } #define FW_MAC_EXACT_CHUNK 7 +struct mcaddr_ctx { + struct ifnet *ifp; + const uint8_t *mcaddr[FW_MAC_EXACT_CHUNK]; + uint64_t hash; + int i; + int del; + int rc; +}; +static u_int +add_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt) +{ + struct mcaddr_ctx *ctx = arg; + struct vi_info *vi = ctx->ifp->if_softc; + struct port_info *pi = vi->pi; + struct adapter *sc = pi->adapter; + + if (ctx->rc < 0) + return (0); + + ctx->mcaddr[ctx->i] = LLADDR(sdl); + MPASS(ETHER_IS_MULTICAST(ctx->mcaddr[ctx->i])); + ctx->i++; + + if (ctx->i == FW_MAC_EXACT_CHUNK) { + ctx->rc = t4_alloc_mac_filt(sc, sc->mbox, vi->viid, ctx->del, + ctx->i, ctx->mcaddr, NULL, &ctx->hash, 0); + if (ctx->rc < 0) { + int j; + + for (j = 0; j < ctx->i; j++) { + if_printf(ctx->ifp, + "failed to add mc address" + " %02x:%02x:%02x:" + "%02x:%02x:%02x rc=%d\n", + ctx->mcaddr[j][0], ctx->mcaddr[j][1], + ctx->mcaddr[j][2], ctx->mcaddr[j][3], + ctx->mcaddr[j][4], ctx->mcaddr[j][5], + -ctx->rc); + } + return (0); + } + ctx->del = 0; + ctx->i = 0; + } + + return (1); +} + /* * Program the port's XGMAC based on parameters in ifnet. The caller also * indicates which parameters should be programmed (the rest are left alone). @@ -4838,66 +4886,51 @@ update_mac_settings(struct ifnet *ifp, int flags) } if (flags & XGMAC_MCADDRS) { - const uint8_t *mcaddr[FW_MAC_EXACT_CHUNK]; - int del = 1; - uint64_t hash = 0; - struct ifmultiaddr *ifma; - int i = 0, j; + struct epoch_tracker et; + struct mcaddr_ctx ctx; + int j; - if_maddr_rlock(ifp); - CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - mcaddr[i] = - LLADDR((struct sockaddr_dl *)ifma->ifma_addr); - MPASS(ETHER_IS_MULTICAST(mcaddr[i])); - i++; - - if (i == FW_MAC_EXACT_CHUNK) { - rc = t4_alloc_mac_filt(sc, sc->mbox, vi->viid, - del, i, mcaddr, NULL, &hash, 0); - if (rc < 0) { - rc = -rc; - for (j = 0; j < i; j++) { - if_printf(ifp, - "failed to add mc address" - " %02x:%02x:%02x:" - "%02x:%02x:%02x rc=%d\n", - mcaddr[j][0], mcaddr[j][1], - mcaddr[j][2], mcaddr[j][3], - mcaddr[j][4], mcaddr[j][5], - rc); - } - goto mcfail; - } - del = 0; - i = 0; - } + ctx.ifp = ifp; + ctx.hash = 0; + ctx.i = 0; + ctx.del = 1; + /* + * Unlike other drivers, we accumulate list of pointers into + * interface address lists and we need to keep it safe even + * after if_foreach_llmaddr() returns, thus we must enter the + * network epoch. + */ + NET_EPOCH_ENTER(et); + if_foreach_llmaddr(ifp, add_maddr, &ctx); + if (ctx.rc < 0) { + NET_EPOCH_EXIT(et); + rc = -ctx.rc; + return (rc); } - if (i > 0) { - rc = t4_alloc_mac_filt(sc, sc->mbox, vi->viid, del, i, - mcaddr, NULL, &hash, 0); + if (ctx.i > 0) { + rc = t4_alloc_mac_filt(sc, sc->mbox, vi->viid, + ctx.del, ctx.i, ctx.mcaddr, NULL, &ctx.hash, 0); + NET_EPOCH_EXIT(et); if (rc < 0) { rc = -rc; - for (j = 0; j < i; j++) { + for (j = 0; j < ctx.i; j++) { if_printf(ifp, "failed to add mc address" " %02x:%02x:%02x:" "%02x:%02x:%02x rc=%d\n", - mcaddr[j][0], mcaddr[j][1], - mcaddr[j][2], mcaddr[j][3], - mcaddr[j][4], mcaddr[j][5], + ctx.mcaddr[j][0], ctx.mcaddr[j][1], + ctx.mcaddr[j][2], ctx.mcaddr[j][3], + ctx.mcaddr[j][4], ctx.mcaddr[j][5], rc); } - goto mcfail; + return (rc); } - } + } else + NET_EPOCH_EXIT(et); - rc = -t4_set_addr_hash(sc, sc->mbox, vi->viid, 0, hash, 0); + rc = -t4_set_addr_hash(sc, sc->mbox, vi->viid, 0, ctx.hash, 0); if (rc != 0) if_printf(ifp, "failed to set mc address hash: %d", rc); -mcfail: - if_maddr_runlock(ifp); } return (rc);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201910211811.x9LIBB7m067481>