From 777c9f5a38100652ba864ebf2cf20127d41aade7 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Mon, 10 Aug 2020 17:01:59 +0000 Subject: [PATCH 01/96] fortune, strfile: Improve validation of command-line arguments. - Avoid potential overflow when parsing a percentage. - Avoid truncation when copying file paths. PR: 246050 Submitted by: Akos Somfai (original) MFC after: 1 week --- usr.bin/fortune/fortune/fortune.c | 9 +++++---- usr.bin/fortune/strfile/strfile.c | 18 ++++++++++++++---- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/usr.bin/fortune/fortune/fortune.c b/usr.bin/fortune/fortune/fortune.c index af408d6dff1d..724fb4a2372e 100644 --- a/usr.bin/fortune/fortune/fortune.c +++ b/usr.bin/fortune/fortune/fortune.c @@ -400,11 +400,12 @@ form_file_list(char **files, int file_cnt) sp = files[i]; else { percent = 0; - for (sp = files[i]; isdigit((unsigned char)*sp); sp++) + for (sp = files[i]; isdigit((unsigned char)*sp); sp++) { percent = percent * 10 + *sp - '0'; - if (percent > 100) { - fprintf(stderr, "percentages must be <= 100\n"); - return (FALSE); + if (percent > 100) { + fprintf(stderr, "percentages must be <= 100\n"); + return (FALSE); + } } if (*sp == '.') { fprintf(stderr, "percentages must be integers\n"); diff --git a/usr.bin/fortune/strfile/strfile.c b/usr.bin/fortune/strfile/strfile.c index ce28e274fd55..f6cda6cd3900 100644 --- a/usr.bin/fortune/strfile/strfile.c +++ b/usr.bin/fortune/strfile/strfile.c @@ -295,16 +295,26 @@ getargs(int argc, char **argv) if (*argv) { Infile = *argv; - if (*++argv) - strcpy(Outfile, *argv); + if (*++argv) { + if (strlcpy(Outfile, *argv, sizeof(Outfile)) >= + sizeof(Outfile)) { + fprintf(stderr, + "output_file path is too long\n"); + exit(1); + } + } } if (!Infile) { puts("No input file name"); usage(); } if (*Outfile == '\0') { - strlcpy(Outfile, Infile, sizeof(Outfile)); - strlcat(Outfile, ".dat", sizeof(Outfile)); + if ((size_t)snprintf(Outfile, sizeof(Outfile), "%s.dat", + Infile) >= sizeof(Outfile)) { + fprintf(stderr, + "generated output_file path is too long\n"); + exit(1); + } } } From 25e42ee2172b437d2bf833da3c45fb3d426cd3d3 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik Date: Mon, 10 Aug 2020 18:11:00 +0000 Subject: [PATCH 02/96] vfs: drop the hello world stat probes from the vfs provider Interested parties can get the same information by hoooking on vop_stat. --- sys/kern/vfs_lookup.c | 2 +- sys/kern/vfs_syscalls.c | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index e78fc25ec343..eb352acc5418 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -70,7 +70,7 @@ __FBSDID("$FreeBSD$"); #define NAMEI_DIAGNOSTIC 1 #undef NAMEI_DIAGNOSTIC -SDT_PROVIDER_DECLARE(vfs); +SDT_PROVIDER_DEFINE(vfs); SDT_PROBE_DEFINE4(vfs, namei, lookup, entry, "struct vnode *", "char *", "unsigned long", "bool"); SDT_PROBE_DEFINE3(vfs, namei, lookup, return, "int", "struct vnode *", "bool"); diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 69a6be798208..68e2082d681b 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -91,10 +91,6 @@ __FBSDID("$FreeBSD$"); MALLOC_DEFINE(M_FADVISE, "fadvise", "posix_fadvise(2) information"); -SDT_PROVIDER_DEFINE(vfs); -SDT_PROBE_DEFINE2(vfs, , stat, mode, "char *", "int"); -SDT_PROBE_DEFINE2(vfs, , stat, reg, "char *", "int"); - static int kern_chflagsat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, u_long flags, int atflag); static int setfflags(struct thread *td, struct vnode *, u_long); @@ -2383,9 +2379,6 @@ kern_statat(struct thread *td, int flag, int fd, const char *path, return (error); error = VOP_STAT(nd.ni_vp, sbp, td->td_ucred, NOCRED, td); if (error == 0) { - SDT_PROBE2(vfs, , stat, mode, path, sbp->st_mode); - if (S_ISREG(sbp->st_mode)) - SDT_PROBE2(vfs, , stat, reg, path, pathseg); if (__predict_false(hook != NULL)) hook(nd.ni_vp, sbp); } From 824cfb472932d2a4c27c601170ec5bd44327aa22 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Mon, 10 Aug 2020 19:37:06 +0000 Subject: [PATCH 03/96] Improve Rockchip's integration of if_dwc - Do not rely on U-Boot for clocks configuration, enable and set frequencies in the driver's attach method. - Adjust MAC settings according to detected linespeed on RK3399 and RK3328. - Add support for RMII PHY mode on RK3328. Reviewed by: manu Differential Revision: https://reviews.freebsd.org/D26006 --- sys/arm64/rockchip/if_dwc_rk.c | 540 +++++++++++++++++++++++++++++---- sys/dev/dwc/if_dwc.c | 24 +- sys/dev/dwc/if_dwc.h | 4 + sys/dev/dwc/if_dwc_if.m | 14 + sys/dev/dwc/if_dwcvar.h | 1 + 5 files changed, 527 insertions(+), 56 deletions(-) diff --git a/sys/arm64/rockchip/if_dwc_rk.c b/sys/arm64/rockchip/if_dwc_rk.c index 7ce13d01d3eb..eafd9e00caf0 100644 --- a/sys/arm64/rockchip/if_dwc_rk.c +++ b/sys/arm64/rockchip/if_dwc_rk.c @@ -23,7 +23,7 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - */ +*/ #include __FBSDID("$FreeBSD$"); @@ -33,94 +33,347 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include +#include +#include + #include #include #include #include #include +#include #include - #include +#include "if_dwc_if.h" #include "syscon_if.h" -#include "if_dwc_if.h" - #define RK3328_GRF_MAC_CON0 0x0900 -#define RK3328_GRF_MAC_CON0_TX_MASK 0x7F -#define RK3328_GRF_MAC_CON0_TX_SHIFT 0 -#define RK3328_GRF_MAC_CON0_RX_MASK 0x7F -#define RK3328_GRF_MAC_CON0_RX_SHIFT 7 +#define MAC_CON0_GMAC2IO_TX_DL_CFG_MASK 0x7F +#define MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT 0 +#define MAC_CON0_GMAC2IO_RX_DL_CFG_MASK 0x7F +#define MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT 7 #define RK3328_GRF_MAC_CON1 0x0904 -#define RK3328_GRF_MAC_CON1_RX_ENA (1 << 1) -#define RK3328_GRF_MAC_CON1_TX_ENA (1 << 0) +#define MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA (1 << 0) +#define MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA (1 << 1) +#define MAC_CON1_GMAC2IO_GMII_CLK_SEL_MASK (3 << 11) +#define MAC_CON1_GMAC2IO_GMII_CLK_SEL_125 (0 << 11) +#define MAC_CON1_GMAC2IO_GMII_CLK_SEL_25 (3 << 11) +#define MAC_CON1_GMAC2IO_GMII_CLK_SEL_2_5 (2 << 11) +#define MAC_CON1_GMAC2IO_RMII_MODE_MASK (1 << 9) +#define MAC_CON1_GMAC2IO_RMII_MODE (1 << 9) +#define MAC_CON1_GMAC2IO_INTF_SEL_MASK (7 << 4) +#define MAC_CON1_GMAC2IO_INTF_RMII (4 << 4) +#define MAC_CON1_GMAC2IO_INTF_RGMII (1 << 4) +#define MAC_CON1_GMAC2IO_RMII_CLK_SEL_MASK (1 << 7) +#define MAC_CON1_GMAC2IO_RMII_CLK_SEL_25 (1 << 7) +#define MAC_CON1_GMAC2IO_RMII_CLK_SEL_2_5 (0 << 7) +#define MAC_CON1_GMAC2IO_MAC_SPEED_MASK (1 << 2) +#define MAC_CON1_GMAC2IO_MAC_SPEED_100 (1 << 2) +#define MAC_CON1_GMAC2IO_MAC_SPEED_10 (0 << 2) #define RK3328_GRF_MAC_CON2 0x0908 #define RK3328_GRF_MACPHY_CON0 0x0B00 +#define MACPHY_CON0_CLK_50M_MASK (1 << 14) +#define MACPHY_CON0_CLK_50M (1 << 14) +#define MACPHY_CON0_RMII_MODE_MASK (3 << 6) +#define MACPHY_CON0_RMII_MODE (1 << 6) #define RK3328_GRF_MACPHY_CON1 0x0B04 +#define MACPHY_CON1_RMII_MODE_MASK (1 << 9) +#define MACPHY_CON1_RMII_MODE (1 << 9) #define RK3328_GRF_MACPHY_CON2 0x0B08 #define RK3328_GRF_MACPHY_CON3 0x0B0C #define RK3328_GRF_MACPHY_STATUS 0x0B10 +#define RK3399_GRF_SOC_CON5 0xc214 +#define SOC_CON5_GMAC_CLK_SEL_MASK (3 << 4) +#define SOC_CON5_GMAC_CLK_SEL_125 (0 << 4) +#define SOC_CON5_GMAC_CLK_SEL_25 (3 << 4) +#define SOC_CON5_GMAC_CLK_SEL_2_5 (2 << 4) +#define RK3399_GRF_SOC_CON6 0xc218 +#define SOC_CON6_GMAC_TXCLK_DLY_ENA (1 << 7) +#define SOC_CON6_TX_DL_CFG_MASK 0x7F +#define SOC_CON6_TX_DL_CFG_SHIFT 0 +#define SOC_CON6_RX_DL_CFG_MASK 0x7F +#define SOC_CON6_GMAC_RXCLK_DLY_ENA (1 << 15) +#define SOC_CON6_RX_DL_CFG_SHIFT 8 + +struct if_dwc_rk_softc; + +typedef void (*if_dwc_rk_set_delaysfn_t)(struct if_dwc_rk_softc *); +typedef int (*if_dwc_rk_set_speedfn_t)(struct if_dwc_rk_softc *, int); +typedef void (*if_dwc_rk_set_phy_modefn_t)(struct if_dwc_rk_softc *); +typedef void (*if_dwc_rk_phy_powerupfn_t)(struct if_dwc_rk_softc *); + +struct if_dwc_rk_ops { + if_dwc_rk_set_delaysfn_t set_delays; + if_dwc_rk_set_speedfn_t set_speed; + if_dwc_rk_set_phy_modefn_t set_phy_mode; + if_dwc_rk_phy_powerupfn_t phy_powerup; +}; + +struct if_dwc_rk_softc { + struct dwc_softc base; + uint32_t tx_delay; + uint32_t rx_delay; + bool integrated_phy; + bool clock_in; + phandle_t phy_node; + struct syscon *grf; + struct if_dwc_rk_ops *ops; + /* Common clocks */ + clk_t mac_clk_rx; + clk_t mac_clk_tx; + clk_t aclk_mac; + clk_t pclk_mac; + clk_t clk_stmmaceth; + /* RMII clocks */ + clk_t clk_mac_ref; + clk_t clk_mac_refout; + /* PHY clock */ + clk_t clk_phy; +}; + +static void rk3328_set_delays(struct if_dwc_rk_softc *sc); +static int rk3328_set_speed(struct if_dwc_rk_softc *sc, int speed); +static void rk3328_set_phy_mode(struct if_dwc_rk_softc *sc); +static void rk3328_phy_powerup(struct if_dwc_rk_softc *sc); + +static void rk3399_set_delays(struct if_dwc_rk_softc *sc); +static int rk3399_set_speed(struct if_dwc_rk_softc *sc, int speed); + +static struct if_dwc_rk_ops rk3288_ops = { +}; + +static struct if_dwc_rk_ops rk3328_ops = { + .set_delays = rk3328_set_delays, + .set_speed = rk3328_set_speed, + .set_phy_mode = rk3328_set_phy_mode, + .phy_powerup = rk3328_phy_powerup, +}; + +static struct if_dwc_rk_ops rk3399_ops = { + .set_delays = rk3399_set_delays, + .set_speed = rk3399_set_speed, +}; + static struct ofw_compat_data compat_data[] = { - {"rockchip,rk3288-gmac", 1}, - {"rockchip,rk3328-gmac", 1}, - {"rockchip,rk3399-gmac", 1}, + {"rockchip,rk3288-gmac", (uintptr_t)&rk3288_ops}, + {"rockchip,rk3328-gmac", (uintptr_t)&rk3328_ops}, + {"rockchip,rk3399-gmac", (uintptr_t)&rk3399_ops}, {NULL, 0} }; static void -rk3328_set_delays(struct syscon *grf, phandle_t node) +rk3328_set_delays(struct if_dwc_rk_softc *sc) { + uint32_t reg; uint32_t tx, rx; - if (OF_getencprop(node, "tx_delay", &tx, sizeof(tx)) <= 0) - tx = 0x30; - if (OF_getencprop(node, "rx_delay", &rx, sizeof(rx)) <= 0) - rx = 0x10; + if (sc->base.phy_mode != PHY_MODE_RGMII) + return; - if (bootverbose) - printf("setting RK3328 RX/TX delays: %d/%d\n", rx, tx); - tx = ((tx & RK3328_GRF_MAC_CON0_TX_MASK) << - RK3328_GRF_MAC_CON0_TX_SHIFT); - rx = ((rx & RK3328_GRF_MAC_CON0_TX_MASK) << - RK3328_GRF_MAC_CON0_RX_SHIFT); + reg = SYSCON_READ_4(sc->grf, RK3328_GRF_MAC_CON0); + tx = ((reg >> MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT) & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK); + rx = ((reg >> MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT) & MAC_CON0_GMAC2IO_RX_DL_CFG_MASK); - SYSCON_WRITE_4(grf, RK3328_GRF_MAC_CON0, tx | rx | 0xFFFF0000); - SYSCON_WRITE_4(grf, RK3328_GRF_MAC_CON1, RK3328_GRF_MAC_CON1_TX_ENA | RK3328_GRF_MAC_CON1_RX_ENA | - ((RK3328_GRF_MAC_CON1_TX_ENA | RK3328_GRF_MAC_CON1_RX_ENA) << 16)); + reg = SYSCON_READ_4(sc->grf, RK3328_GRF_MAC_CON1); + if (bootverbose) { + device_printf(sc->base.dev, "current delays settings: tx=%u(%s) rx=%u(%s)\n", + tx, ((reg & MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA) ? "enabled" : "disabled"), + rx, ((reg & MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA) ? "enabled" : "disabled")); + + device_printf(sc->base.dev, "setting new RK3328 RX/TX delays: %d/%d\n", + sc->tx_delay, sc->rx_delay); + } + + reg = (MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA | MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA) << 16; + reg |= (MAC_CON1_GMAC2IO_GMAC_TXCLK_DLY_ENA | MAC_CON1_GMAC2IO_GMAC_RXCLK_DLY_ENA); + SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1, reg); + + reg = 0xffff << 16; + reg |= ((sc->tx_delay & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK) << + MAC_CON0_GMAC2IO_TX_DL_CFG_SHIFT); + reg |= ((sc->rx_delay & MAC_CON0_GMAC2IO_TX_DL_CFG_MASK) << + MAC_CON0_GMAC2IO_RX_DL_CFG_SHIFT); + SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON0, reg); } -#define RK3399_GRF_SOC_CON6 0xc218 -#define RK3399_GRF_SOC_CON6_TX_ENA (1 << 7) -#define RK3399_GRF_SOC_CON6_TX_MASK 0x7F -#define RK3399_GRF_SOC_CON6_TX_SHIFT 0 -#define RK3399_GRF_SOC_CON6_RX_MASK 0x7F -#define RK3399_GRF_SOC_CON6_RX_ENA (1 << 15) -#define RK3399_GRF_SOC_CON6_RX_SHIFT 8 +static int +rk3328_set_speed(struct if_dwc_rk_softc *sc, int speed) +{ + uint32_t reg; + + switch (sc->base.phy_mode) { + case PHY_MODE_RGMII: + switch (speed) { + case IFM_1000_T: + case IFM_1000_SX: + reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_125; + break; + case IFM_100_TX: + reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_25; + break; + case IFM_10_T: + reg = MAC_CON1_GMAC2IO_GMII_CLK_SEL_2_5; + break; + default: + device_printf(sc->base.dev, "unsupported RGMII media %u\n", speed); + return (-1); + } + + SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1, + ((MAC_CON1_GMAC2IO_GMII_CLK_SEL_MASK << 16) | reg)); + break; + case PHY_MODE_RMII: + switch (speed) { + case IFM_100_TX: + reg = MAC_CON1_GMAC2IO_RMII_CLK_SEL_25 | + MAC_CON1_GMAC2IO_MAC_SPEED_100; + break; + case IFM_10_T: + reg = MAC_CON1_GMAC2IO_RMII_CLK_SEL_2_5 | + MAC_CON1_GMAC2IO_MAC_SPEED_10; + break; + default: + device_printf(sc->base.dev, "unsupported RMII media %u\n", speed); + return (-1); + } + + SYSCON_WRITE_4(sc->grf, + sc->integrated_phy ? RK3328_GRF_MAC_CON2 : RK3328_GRF_MAC_CON1, + reg | + ((MAC_CON1_GMAC2IO_RMII_CLK_SEL_MASK | MAC_CON1_GMAC2IO_MAC_SPEED_MASK) << 16)); + break; + } + + return (0); +} static void -rk3399_set_delays(struct syscon *grf, phandle_t node) +rk3328_set_phy_mode(struct if_dwc_rk_softc *sc) { - uint32_t tx, rx; - if (OF_getencprop(node, "tx_delay", &tx, sizeof(tx)) <= 0) - tx = 0x30; - if (OF_getencprop(node, "rx_delay", &rx, sizeof(rx)) <= 0) - rx = 0x10; + switch (sc->base.phy_mode) { + case PHY_MODE_RGMII: + SYSCON_WRITE_4(sc->grf, RK3328_GRF_MAC_CON1, + ((MAC_CON1_GMAC2IO_INTF_SEL_MASK | MAC_CON1_GMAC2IO_RMII_MODE_MASK) << 16) | + MAC_CON1_GMAC2IO_INTF_RGMII); + break; + case PHY_MODE_RMII: + SYSCON_WRITE_4(sc->grf, sc->integrated_phy ? RK3328_GRF_MAC_CON2 : RK3328_GRF_MAC_CON1, + ((MAC_CON1_GMAC2IO_INTF_SEL_MASK | MAC_CON1_GMAC2IO_RMII_MODE_MASK) << 16) | + MAC_CON1_GMAC2IO_INTF_RMII | MAC_CON1_GMAC2IO_RMII_MODE); + break; + } +} - if (bootverbose) - printf("setting RK3399 RX/TX delays: %d/%d\n", rx, tx); - tx = ((tx & RK3399_GRF_SOC_CON6_TX_MASK) << - RK3399_GRF_SOC_CON6_TX_SHIFT) | RK3399_GRF_SOC_CON6_TX_ENA; - rx = ((rx & RK3399_GRF_SOC_CON6_TX_MASK) << - RK3399_GRF_SOC_CON6_RX_SHIFT) | RK3399_GRF_SOC_CON6_RX_ENA; +static void +rk3328_phy_powerup(struct if_dwc_rk_softc *sc) +{ + SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON1, + (MACPHY_CON1_RMII_MODE_MASK << 16) | + MACPHY_CON1_RMII_MODE); +} - SYSCON_WRITE_4(grf, RK3399_GRF_SOC_CON6, tx | rx | 0xFFFF0000); +static void +rk3399_set_delays(struct if_dwc_rk_softc *sc) +{ + uint32_t reg, tx, rx; + + if (sc->base.phy_mode != PHY_MODE_RGMII) + return; + + reg = SYSCON_READ_4(sc->grf, RK3399_GRF_SOC_CON6); + tx = ((reg >> SOC_CON6_TX_DL_CFG_SHIFT) & SOC_CON6_TX_DL_CFG_MASK); + rx = ((reg >> SOC_CON6_RX_DL_CFG_SHIFT) & SOC_CON6_RX_DL_CFG_MASK); + + if (bootverbose) { + device_printf(sc->base.dev, "current delays settings: tx=%u(%s) rx=%u(%s)\n", + tx, ((reg & SOC_CON6_GMAC_TXCLK_DLY_ENA) ? "enabled" : "disabled"), + rx, ((reg & SOC_CON6_GMAC_RXCLK_DLY_ENA) ? "enabled" : "disabled")); + + device_printf(sc->base.dev, "setting new RK3399 RX/TX delays: %d/%d\n", + sc->rx_delay, sc->tx_delay); + } + + reg = 0xFFFF << 16; + reg |= ((sc->tx_delay & SOC_CON6_TX_DL_CFG_MASK) << + SOC_CON6_TX_DL_CFG_SHIFT); + reg |= ((sc->rx_delay & SOC_CON6_RX_DL_CFG_MASK) << + SOC_CON6_RX_DL_CFG_SHIFT); + reg |= SOC_CON6_GMAC_TXCLK_DLY_ENA | SOC_CON6_GMAC_RXCLK_DLY_ENA; + + SYSCON_WRITE_4(sc->grf, RK3399_GRF_SOC_CON6, reg); +} + +static int +rk3399_set_speed(struct if_dwc_rk_softc *sc, int speed) +{ + uint32_t reg; + + switch (speed) { + case IFM_1000_T: + case IFM_1000_SX: + reg = SOC_CON5_GMAC_CLK_SEL_125; + break; + case IFM_100_TX: + reg = SOC_CON5_GMAC_CLK_SEL_25; + break; + case IFM_10_T: + reg = SOC_CON5_GMAC_CLK_SEL_2_5; + break; + default: + device_printf(sc->base.dev, "unsupported media %u\n", speed); + return (-1); + } + + SYSCON_WRITE_4(sc->grf, RK3399_GRF_SOC_CON5, + ((SOC_CON5_GMAC_CLK_SEL_MASK << 16) | reg)); + return (0); +} + +static int +if_dwc_rk_sysctl_delays(SYSCTL_HANDLER_ARGS) +{ + struct if_dwc_rk_softc *sc; + int rv; + uint32_t rxtx; + + sc = arg1; + rxtx = ((sc->rx_delay << 8) | sc->tx_delay); + + rv = sysctl_handle_int(oidp, &rxtx, 0, req); + if (rv != 0 || req->newptr == NULL) + return (rv); + sc->tx_delay = rxtx & 0xff; + sc->rx_delay = (rxtx >> 8) & 0xff; + + if (sc->ops->set_delays) + sc->ops->set_delays(sc); + + return (0); +} + +static int +if_dwc_rk_init_sysctl(struct if_dwc_rk_softc *sc) +{ + struct sysctl_oid *child; + struct sysctl_ctx_list *ctx_list; + + ctx_list = device_get_sysctl_ctx(sc->base.dev); + child = device_get_sysctl_tree(sc->base.dev); + SYSCTL_ADD_PROC(ctx_list, + SYSCTL_CHILDREN(child), OID_AUTO, "delays", + CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, sc, 0, + if_dwc_rk_sysctl_delays, "", "RGMII RX/TX delays: ((rx << 8) | tx)"); + + return (0); } static int @@ -136,26 +389,189 @@ if_dwc_rk_probe(device_t dev) return (BUS_PROBE_DEFAULT); } +static int +if_dwc_rk_init_clocks(device_t dev) +{ + struct if_dwc_rk_softc *sc; + int error; + + sc = device_get_softc(dev); + error = clk_set_assigned(dev, ofw_bus_get_node(dev)); + if (error != 0) { + device_printf(dev, "clk_set_assigned failed\n"); + return (error); + } + + /* Enable clocks */ + error = clk_get_by_ofw_name(dev, 0, "stmmaceth", &sc->clk_stmmaceth); + if (error != 0) { + device_printf(dev, "could not find clock stmmaceth\n"); + return (error); + } + + if (clk_get_by_ofw_name(dev, 0, "mac_clk_rx", &sc->mac_clk_rx) != 0) { + device_printf(sc->base.dev, "could not get mac_clk_rx clock\n"); + sc->mac_clk_rx = NULL; + } + + if (clk_get_by_ofw_name(dev, 0, "mac_clk_tx", &sc->mac_clk_tx) != 0) { + device_printf(sc->base.dev, "could not get mac_clk_tx clock\n"); + sc->mac_clk_tx = NULL; + } + + if (clk_get_by_ofw_name(dev, 0, "aclk_mac", &sc->aclk_mac) != 0) { + device_printf(sc->base.dev, "could not get aclk_mac clock\n"); + sc->aclk_mac = NULL; + } + + if (clk_get_by_ofw_name(dev, 0, "pclk_mac", &sc->pclk_mac) != 0) { + device_printf(sc->base.dev, "could not get pclk_mac clock\n"); + sc->pclk_mac = NULL; + } + + if (sc->base.phy_mode == PHY_MODE_RGMII) { + if (clk_get_by_ofw_name(dev, 0, "clk_mac_ref", &sc->clk_mac_ref) != 0) { + device_printf(sc->base.dev, "could not get clk_mac_ref clock\n"); + sc->clk_mac_ref = NULL; + } + + if (!sc->clock_in) { + if (clk_get_by_ofw_name(dev, 0, "clk_mac_refout", &sc->clk_mac_refout) != 0) { + device_printf(sc->base.dev, "could not get clk_mac_refout clock\n"); + sc->clk_mac_refout = NULL; + } + + clk_set_freq(sc->clk_stmmaceth, 50000000, 0); + } + } + + if ((sc->phy_node != 0) && sc->integrated_phy) { + if (clk_get_by_ofw_index(dev, sc->phy_node, 0, &sc->clk_phy) != 0) { + device_printf(sc->base.dev, "could not get PHY clock\n"); + sc->clk_phy = NULL; + } + + if (sc->clk_phy) { + clk_set_freq(sc->clk_phy, 50000000, 0); + } + } + + if (sc->base.phy_mode == PHY_MODE_RMII) { + if (sc->mac_clk_rx) + clk_enable(sc->mac_clk_rx); + if (sc->clk_mac_ref) + clk_enable(sc->clk_mac_ref); + if (sc->clk_mac_refout) + clk_enable(sc->clk_mac_refout); + } + if (sc->clk_phy) + clk_enable(sc->clk_phy); + if (sc->aclk_mac) + clk_enable(sc->aclk_mac); + if (sc->pclk_mac) + clk_enable(sc->pclk_mac); + if (sc->mac_clk_tx) + clk_enable(sc->mac_clk_tx); + + DELAY(50); + + return (0); +} + static int if_dwc_rk_init(device_t dev) { + struct if_dwc_rk_softc *sc; phandle_t node; - struct syscon *grf = NULL; + uint32_t rx, tx; + int err; + pcell_t phy_handle; + char *clock_in_out; + hwreset_t phy_reset; + regulator_t phy_supply; + sc = device_get_softc(dev); node = ofw_bus_get_node(dev); + sc->ops = (struct if_dwc_rk_ops *)ofw_bus_search_compatible(dev, compat_data)->ocd_data; if (OF_hasprop(node, "rockchip,grf") && syscon_get_by_ofw_property(dev, node, - "rockchip,grf", &grf) != 0) { + "rockchip,grf", &sc->grf) != 0) { device_printf(dev, "cannot get grf driver handle\n"); return (ENXIO); } - if (ofw_bus_is_compatible(dev, "rockchip,rk3399-gmac")) - rk3399_set_delays(grf, node); - else if (ofw_bus_is_compatible(dev, "rockchip,rk3328-gmac")) - rk3328_set_delays(grf, node); + if (OF_getencprop(node, "tx_delay", &tx, sizeof(tx)) <= 0) + tx = 0x30; + if (OF_getencprop(node, "rx_delay", &rx, sizeof(rx)) <= 0) + rx = 0x10; + sc->tx_delay = tx; + sc->rx_delay = rx; - /* Mode should be set according to dtb property */ + sc->clock_in = true; + if (OF_getprop_alloc(node, "clock_in_out", (void **)&clock_in_out)) { + if (strcmp(clock_in_out, "input") == 0) + sc->clock_in = true; + else + sc->clock_in = false; + OF_prop_free(clock_in_out); + } + + if (OF_getencprop(node, "phy-handle", (void *)&phy_handle, + sizeof(phy_handle)) > 0) + sc->phy_node = OF_node_from_xref(phy_handle); + + if (sc->phy_node) + sc->integrated_phy = OF_hasprop(sc->phy_node, "phy-is-integrated"); + + if (sc->integrated_phy) + device_printf(sc->base.dev, "PHY is integrated\n"); + + if_dwc_rk_init_clocks(dev); + + if (sc->ops->set_phy_mode) + sc->ops->set_phy_mode(sc); + + if (sc->ops->set_delays) + sc->ops->set_delays(sc); + + /* + * this also sets delays if tunable is defined + */ + err = if_dwc_rk_init_sysctl(sc); + if (err != 0) + return (err); + + if (regulator_get_by_ofw_property(sc->base.dev, 0, + "phy-supply", &phy_supply) == 0) { + if (regulator_enable(phy_supply)) { + device_printf(sc->base.dev, + "cannot enable 'phy' regulator\n"); + } + } + else + device_printf(sc->base.dev, "no phy-supply property\n"); + + /* Power up */ + if (sc->integrated_phy) { + if (sc->ops->phy_powerup) + sc->ops->phy_powerup(sc); + + SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON0, + (MACPHY_CON0_CLK_50M_MASK << 16) | + MACPHY_CON0_CLK_50M); + SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON0, + (MACPHY_CON0_RMII_MODE_MASK << 16) | + MACPHY_CON0_RMII_MODE); + SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON2, 0xffff1234); + SYSCON_WRITE_4(sc->grf, RK3328_GRF_MACPHY_CON3, 0x003f0035); + + if (hwreset_get_by_ofw_idx(dev, sc->phy_node, 0, &phy_reset) == 0) { + hwreset_assert(phy_reset); + DELAY(20); + hwreset_deassert(phy_reset); + DELAY(20); + } + } return (0); } @@ -175,12 +591,26 @@ if_dwc_rk_mii_clk(device_t dev) return (GMAC_MII_CLK_150_250M_DIV102); } +static int +if_dwc_rk_set_speed(device_t dev, int speed) +{ + struct if_dwc_rk_softc *sc; + + sc = device_get_softc(dev); + + if (sc->ops->set_speed) + return sc->ops->set_speed(sc, speed); + + return (0); +} + static device_method_t if_dwc_rk_methods[] = { DEVMETHOD(device_probe, if_dwc_rk_probe), DEVMETHOD(if_dwc_init, if_dwc_rk_init), DEVMETHOD(if_dwc_mac_type, if_dwc_rk_mac_type), DEVMETHOD(if_dwc_mii_clk, if_dwc_rk_mii_clk), + DEVMETHOD(if_dwc_set_speed, if_dwc_rk_set_speed), DEVMETHOD_END }; @@ -190,6 +620,6 @@ static devclass_t dwc_rk_devclass; extern driver_t dwc_driver; DEFINE_CLASS_1(dwc, dwc_rk_driver, if_dwc_rk_methods, - sizeof(struct dwc_softc), dwc_driver); + sizeof(struct if_dwc_rk_softc), dwc_driver); DRIVER_MODULE(dwc_rk, simplebus, dwc_rk_driver, dwc_rk_devclass, 0, 0); MODULE_DEPEND(dwc_rk, dwc, 1, 1, 1); diff --git a/sys/dev/dwc/if_dwc.c b/sys/dev/dwc/if_dwc.c index 44350ae087cc..16e26793188a 100644 --- a/sys/dev/dwc/if_dwc.c +++ b/sys/dev/dwc/if_dwc.c @@ -1209,14 +1209,22 @@ dwc_clock_init(device_t dev) hwreset_t rst; clk_t clk; int error; + int64_t freq; - /* Enable clock */ + /* Enable clocks */ if (clk_get_by_ofw_name(dev, 0, "stmmaceth", &clk) == 0) { error = clk_enable(clk); if (error != 0) { device_printf(dev, "could not enable main clock\n"); return (error); } + if (bootverbose) { + clk_get_freq(clk, &freq); + device_printf(dev, "MAC clock(%s) freq: %ld\n", clk_get_name(clk), freq); + } + } + else { + device_printf(dev, "could not find clock stmmaceth\n"); } /* De-assert reset */ @@ -1254,6 +1262,8 @@ dwc_attach(device_t dev) struct ifnet *ifp; int error, i; uint32_t reg; + char *phy_mode; + phandle_t node; sc = device_get_softc(dev); sc->dev = dev; @@ -1262,6 +1272,15 @@ dwc_attach(device_t dev) sc->mii_clk = IF_DWC_MII_CLK(dev); sc->mactype = IF_DWC_MAC_TYPE(dev); + node = ofw_bus_get_node(dev); + if (OF_getprop_alloc(node, "phy-mode", (void **)&phy_mode)) { + if (strcmp(phy_mode, "rgmii") == 0) + sc->phy_mode = PHY_MODE_RGMII; + if (strcmp(phy_mode, "rmii") == 0) + sc->phy_mode = PHY_MODE_RMII; + OF_prop_free(phy_mode); + } + if (IF_DWC_INIT(dev) != 0) return (ENXIO); @@ -1475,6 +1494,9 @@ dwc_miibus_statchg(device_t dev) else reg &= ~(CONF_DM); WRITE4(sc, MAC_CONFIGURATION, reg); + + IF_DWC_SET_SPEED(dev, IFM_SUBTYPE(mii->mii_media_active)); + } static device_method_t dwc_methods[] = { diff --git a/sys/dev/dwc/if_dwc.h b/sys/dev/dwc/if_dwc.h index d20f35d74ce5..045072abe611 100644 --- a/sys/dev/dwc/if_dwc.h +++ b/sys/dev/dwc/if_dwc.h @@ -37,6 +37,10 @@ #ifndef __IF_DWC_H__ #define __IF_DWC_H__ +#define PHY_MODE_UNKNOWN 0x0 +#define PHY_MODE_RMII 0x1 +#define PHY_MODE_RGMII 0x2 + #define MAC_CONFIGURATION 0x0 #define CONF_JD (1 << 22) /* jabber timer disable */ #define CONF_BE (1 << 21) /* Frame Burst Enable */ diff --git a/sys/dev/dwc/if_dwc_if.m b/sys/dev/dwc/if_dwc_if.m index 733f83545cf4..dae429c55e8a 100644 --- a/sys/dev/dwc/if_dwc_if.m +++ b/sys/dev/dwc/if_dwc_if.m @@ -49,6 +49,12 @@ CODE { { return (GMAC_MII_CLK_25_35M_DIV16); } + + static int + if_dwc_default_set_speed(device_t dev, int speed) + { + return (0); + } }; HEADER { @@ -74,3 +80,11 @@ METHOD int mac_type { METHOD int mii_clk { device_t dev; } DEFAULT if_dwc_default_mii_clk; + +# +# Signal media change to a specific hardware +# +METHOD int set_speed { + device_t dev; + int speed; +} DEFAULT if_dwc_default_set_speed; diff --git a/sys/dev/dwc/if_dwcvar.h b/sys/dev/dwc/if_dwcvar.h index 9db24c14f328..0470b29cb0e1 100644 --- a/sys/dev/dwc/if_dwcvar.h +++ b/sys/dev/dwc/if_dwcvar.h @@ -71,6 +71,7 @@ struct dwc_softc { boolean_t is_detaching; int tx_watchdog_count; int stats_harvest_count; + int phy_mode; /* RX */ bus_dma_tag_t rxdesc_tag; From cf8a49ab6e9d2b5b944245d008c89e5ed8300da6 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Mon, 10 Aug 2020 20:24:48 +0000 Subject: [PATCH 04/96] Fix the following issues related to the TCP SYN-cache: * Let the accepted TCP/IPv4 socket inherit the configured TTL and TOS value. * Let the accepted TCP/IPv6 socket inherit the configured Hop Limit. * Use the configured Hop Limit and Traffic Class when sending IPv6 packets. Reviewed by: rrs, lutz_donnerhacke.de MFC after: 1 week Sponsored by: Netflix, Inc. Differential Revision: https://reviews.freebsd.org/D25909 --- sys/netinet/tcp_syncache.c | 41 ++++++++++++++++++++++++++------------ sys/netinet/tcp_syncache.h | 4 ++-- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c index e564540b007d..a9c7dea39954 100644 --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -831,6 +831,8 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m) inp->inp_vflag &= ~INP_IPV6; inp->inp_vflag |= INP_IPV4; #endif + inp->inp_ip_ttl = sc->sc_ip_ttl; + inp->inp_ip_tos = sc->sc_ip_tos; inp->inp_laddr = sc->sc_inc.inc_laddr; #ifdef INET6 } @@ -866,6 +868,7 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m) if (oinp->in6p_outputopts) inp->in6p_outputopts = ip6_copypktopts(oinp->in6p_outputopts, M_NOWAIT); + inp->in6p_hops = oinp->in6p_hops; } if (sc->sc_inc.inc_flags & INC_ISIPV6) { @@ -1389,12 +1392,28 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, cred = crhold(so->so_cred); #ifdef INET6 - if ((inc->inc_flags & INC_ISIPV6) && - (inp->inp_flags & IN6P_AUTOFLOWLABEL)) - autoflowlabel = 1; + if (inc->inc_flags & INC_ISIPV6) { + if (inp->inp_flags & IN6P_AUTOFLOWLABEL) { + autoflowlabel = 1; + } + ip_ttl = in6_selecthlim(inp, NULL); + if ((inp->in6p_outputopts == NULL) || + (inp->in6p_outputopts->ip6po_tclass == -1)) { + ip_tos = 0; + } else { + ip_tos = inp->in6p_outputopts->ip6po_tclass; + } + } +#endif +#if defined(INET6) && defined(INET) + else +#endif +#ifdef INET + { + ip_ttl = inp->inp_ip_ttl; + ip_tos = inp->inp_ip_tos; + } #endif - ip_ttl = inp->inp_ip_ttl; - ip_tos = inp->inp_ip_tos; win = so->sol_sbrcv_hiwat; ltflags = (tp->t_flags & (TF_NOOPT | TF_SIGNATURE)); @@ -1599,13 +1618,8 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, cred = NULL; sc->sc_ipopts = ipopts; bcopy(inc, &sc->sc_inc, sizeof(struct in_conninfo)); -#ifdef INET6 - if (!(inc->inc_flags & INC_ISIPV6)) -#endif - { - sc->sc_ip_tos = ip_tos; - sc->sc_ip_ttl = ip_ttl; - } + sc->sc_ip_tos = ip_tos; + sc->sc_ip_ttl = ip_ttl; #ifdef TCP_OFFLOAD sc->sc_tod = tod; sc->sc_todctx = todctx; @@ -1807,6 +1821,7 @@ syncache_respond(struct syncache *sc, const struct mbuf *m0, int flags) /* Zero out traffic class and flow label. */ ip6->ip6_flow &= ~IPV6_FLOWINFO_MASK; ip6->ip6_flow |= sc->sc_flowlabel; + ip6->ip6_flow |= htonl(sc->sc_ip_tos << 20); th = (struct tcphdr *)(ip6 + 1); } @@ -1935,7 +1950,7 @@ syncache_respond(struct syncache *sc, const struct mbuf *m0, int flags) m->m_pkthdr.csum_flags = CSUM_TCP_IPV6; th->th_sum = in6_cksum_pseudo(ip6, tlen + optlen - hlen, IPPROTO_TCP, 0); - ip6->ip6_hlim = in6_selecthlim(NULL, NULL); + ip6->ip6_hlim = sc->sc_ip_ttl; #ifdef TCP_OFFLOAD if (ADDED_BY_TOE(sc)) { struct toedev *tod = sc->sc_tod; diff --git a/sys/netinet/tcp_syncache.h b/sys/netinet/tcp_syncache.h index 27cbad42f9ae..37575a14467c 100644 --- a/sys/netinet/tcp_syncache.h +++ b/sys/netinet/tcp_syncache.h @@ -63,8 +63,8 @@ struct syncache { struct mbuf *sc_ipopts; /* source route */ u_int16_t sc_peer_mss; /* peer's MSS */ u_int16_t sc_wnd; /* advertised window */ - u_int8_t sc_ip_ttl; /* IPv4 TTL */ - u_int8_t sc_ip_tos; /* IPv4 TOS */ + u_int8_t sc_ip_ttl; /* TTL / Hop Limit */ + u_int8_t sc_ip_tos; /* TOS / Traffic Class */ u_int8_t sc_requested_s_scale:4, sc_requested_r_scale:4; u_int16_t sc_flags; From af32cefd7ce83d5eb62d7f392146386518d07bc0 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Mon, 10 Aug 2020 20:34:45 +0000 Subject: [PATCH 05/96] Check the UMA zone's full bucket cache before short-circuiting an alloc. The global "bucketdisable" flag indicates that we are in a low memory situation and should avoid allocating buckets. However, in the allocation path we were checking it before the full bucket cache and bailing even if the cache is non-empty. Defer the check so that we have a shot at allocating from the cache. This came up because M_NOWAIT allocations from the buf trie node zone must always succeed. In one scenario, all of the preallocated trie nodes were in the bucket list, and a new slab allocation could not succeed due to a memory shortage. The short-circuiting caused an allocation failure which triggered a panic. Reported by: pho Reviewed by: cem Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D25980 --- sys/vm/uma_core.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c index d90423bd9c5f..9d0786c1d754 100644 --- a/sys/vm/uma_core.c +++ b/sys/vm/uma_core.c @@ -3429,12 +3429,6 @@ cache_alloc(uma_zone_t zone, uma_cache_t cache, void *udata, int flags) bucket_free(zone, bucket, udata); } - /* Short-circuit for zones without buckets and low memory. */ - if (zone->uz_bucket_size == 0 || bucketdisable) { - critical_enter(); - return (false); - } - /* * Attempt to retrieve the item from the per-CPU cache has failed, so * we must go back to the zone. This requires the zdom lock, so we @@ -3449,11 +3443,12 @@ cache_alloc(uma_zone_t zone, uma_cache_t cache, void *udata, int flags) VM_DOMAIN_EMPTY(domain)) domain = zone_domain_highest(zone, domain); bucket = cache_fetch_bucket(zone, cache, domain); - if (bucket == NULL) { + if (bucket == NULL && zone->uz_bucket_size != 0 && !bucketdisable) { bucket = zone_alloc_bucket(zone, udata, domain, flags); new = true; - } else + } else { new = false; + } CTR3(KTR_UMA, "uma_zalloc: zone %s(%p) bucket zone returned %p", zone->uz_name, zone, bucket); From cc321ccd753c1be80e689e5c30057963154ba66c Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Mon, 10 Aug 2020 21:41:49 +0000 Subject: [PATCH 06/96] Export scandir_b from libc. Apparently it was not exported, because scandir_b.c was not included into libc SRCS. Export it with the CURRENT-13 version. Also, because it was not exported before ino64, clean up scandir-compat11.c. PR: 248572 Reported by: Alex S Reviewed by: emaste Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D26020 --- lib/libc/gen/Makefile.inc | 1 + lib/libc/gen/Symbol.map | 2 +- lib/libc/gen/scandir-compat11.c | 31 +++++++++---------------------- lib/libc/gen/scandir.c | 5 +++-- 4 files changed, 14 insertions(+), 25 deletions(-) diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc index f86c7b04b92b..779b418e9340 100644 --- a/lib/libc/gen/Makefile.inc +++ b/lib/libc/gen/Makefile.inc @@ -120,6 +120,7 @@ SRCS+= __getosreldate.c \ recvmmsg.c \ rewinddir.c \ scandir.c \ + scandir_b.c \ scandir-compat11.c \ seed48.c \ seekdir.c \ diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map index f9d4f158ed30..e17d74d1a151 100644 --- a/lib/libc/gen/Symbol.map +++ b/lib/libc/gen/Symbol.map @@ -416,7 +416,6 @@ FBSD_1.5 { readdir; readdir_r; scandir; - scandir_b; sem_clockwait_np; setproctitle_fast; timespec_get; @@ -424,6 +423,7 @@ FBSD_1.5 { FBSD_1.6 { memalign; + scandir_b; sigandset; sigisemptyset; sigorset; diff --git a/lib/libc/gen/scandir-compat11.c b/lib/libc/gen/scandir-compat11.c index 712d14ee9c04..b1c0ecb83622 100644 --- a/lib/libc/gen/scandir-compat11.c +++ b/lib/libc/gen/scandir-compat11.c @@ -49,32 +49,25 @@ __FBSDID("$FreeBSD$"); #include "gen-compat.h" -#ifdef I_AM_SCANDIR_B -#include "block_abi.h" -#define SELECT(x) CALL_BLOCK(select, x) -#ifndef __BLOCKS__ -void -qsort_b(void *, size_t, size_t, void*); -#endif -#else +/* + * scandir_b@FBSD_1.4 was never exported from libc.so.7 due to a + * mistake, so there is no use of exporting it now with some earlier + * symbol version. As result, we do not need to implement compat + * function freebsd11_scandir_b(). + */ + #define SELECT(x) select(x) -#endif + +void qsort_b(void *, size_t, size_t, void *); static int freebsd11_alphasort_thunk(void *thunk, const void *p1, const void *p2); int -#ifdef I_AM_SCANDIR_B -freebsd11_scandir_b(const char *dirname, struct freebsd11_dirent ***namelist, - DECLARE_BLOCK(int, select, const struct freebsd11_dirent *), - DECLARE_BLOCK(int, dcomp, const struct freebsd11_dirent **, - const struct freebsd11_dirent **)) -#else freebsd11_scandir(const char *dirname, struct freebsd11_dirent ***namelist, int (*select)(const struct freebsd11_dirent *), int (*dcomp)(const struct freebsd11_dirent **, const struct freebsd11_dirent **)) -#endif { struct freebsd11_dirent *d, *p, **names = NULL; size_t arraysz, numitems; @@ -124,13 +117,8 @@ freebsd11_scandir(const char *dirname, struct freebsd11_dirent ***namelist, } closedir(dirp); if (numitems && dcomp != NULL) -#ifdef I_AM_SCANDIR_B - qsort_b(names, numitems, sizeof(struct freebsd11_dirent *), - (void*)dcomp); -#else qsort_r(names, numitems, sizeof(struct freebsd11_dirent *), &dcomp, freebsd11_alphasort_thunk); -#endif *namelist = names; return (numitems); @@ -168,4 +156,3 @@ freebsd11_alphasort_thunk(void *thunk, const void *p1, const void *p2) __sym_compat(alphasort, freebsd11_alphasort, FBSD_1.0); __sym_compat(scandir, freebsd11_scandir, FBSD_1.0); -__sym_compat(scandir_b, freebsd11_scandir_b, FBSD_1.4); diff --git a/lib/libc/gen/scandir.c b/lib/libc/gen/scandir.c index 036a0166d48b..7e5bcce905fb 100644 --- a/lib/libc/gen/scandir.c +++ b/lib/libc/gen/scandir.c @@ -50,8 +50,7 @@ __FBSDID("$FreeBSD$"); #include "block_abi.h" #define SELECT(x) CALL_BLOCK(select, x) #ifndef __BLOCKS__ -void -qsort_b(void *, size_t, size_t, void*); +void qsort_b(void *, size_t, size_t, void *); #endif #else #define SELECT(x) select(x) @@ -134,6 +133,7 @@ scandir(const char *dirname, struct dirent ***namelist, return (-1); } +#ifndef I_AM_SCANDIR_B /* * Alphabetic order comparison routine for those who want it. * POSIX 2008 requires that alphasort() uses strcoll(). @@ -153,3 +153,4 @@ alphasort_thunk(void *thunk, const void *p1, const void *p2) dc = *(int (**)(const struct dirent **, const struct dirent **))thunk; return (dc((const struct dirent **)p1, (const struct dirent **)p2)); } +#endif From 02511d2112f403ae8ff4a8ce31bf4e8c9e868137 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Tue, 11 Aug 2020 00:26:45 +0000 Subject: [PATCH 07/96] Add an argument to newnfs_connect() that indicates use TLS for the connection. For NFSv4.0, the server creates a server->client TCP connection for callbacks. If the client mount on the server is using TLS, enable TLS for this callback TCP connection. TLS connections from clients will not be supported until the kernel RPC changes are committed. Since this changes the internal ABI between the NFS kernel modules that will require a version bump, delete newnfs_trimtrailing(), which is no longer used. Since LCL_TLSCB is not yet set, these changes should not have any semantic affect at this time. --- sys/fs/nfs/nfs.h | 1 + sys/fs/nfs/nfs_commonkrpc.c | 6 ++++-- sys/fs/nfs/nfs_commonsubs.c | 21 +-------------------- sys/fs/nfs/nfs_var.h | 4 +--- sys/fs/nfsclient/nfs_clrpcops.c | 2 +- sys/fs/nfsclient/nfs_clvfsops.c | 4 ++-- sys/fs/nfsserver/nfs_nfsdstate.c | 8 ++++++-- sys/rpc/clnt.h | 2 ++ sys/sys/param.h | 2 +- 9 files changed, 19 insertions(+), 31 deletions(-) diff --git a/sys/fs/nfs/nfs.h b/sys/fs/nfs/nfs.h index 29d5373b5966..70b2536245ff 100644 --- a/sys/fs/nfs/nfs.h +++ b/sys/fs/nfs/nfs.h @@ -336,6 +336,7 @@ struct nfsreferral { #define LCL_DONEBINDCONN 0x00040000 #define LCL_RECLAIMONEFS 0x00080000 #define LCL_NFSV42 0x00100000 +#define LCL_TLSCB 0x00200000 #define LCL_GSS LCL_KERBV /* Or of all mechs */ diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index 334d46e05c23..79c6067c9866 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -167,7 +167,7 @@ static int nfsv2_procid[NFS_V3NPROCS] = { */ int newnfs_connect(struct nfsmount *nmp, struct nfssockreq *nrp, - struct ucred *cred, NFSPROC_T *p, int callback_retry_mult) + struct ucred *cred, NFSPROC_T *p, int callback_retry_mult, bool dotls) { int rcvreserve, sndreserve; int pktscale, pktscalesav; @@ -374,6 +374,8 @@ newnfs_connect(struct nfsmount *nmp, struct nfssockreq *nrp, } else { retries = NFSV4_CALLBACKRETRY * callback_retry_mult; } + if (dotls) + CLNT_CONTROL(client, CLSET_TLS, &one); } CLNT_CONTROL(client, CLSET_RETRIES, &retries); @@ -586,7 +588,7 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, * and let clnt_reconnect_create handle reconnects. */ if (nrp->nr_client == NULL) - newnfs_connect(nmp, nrp, cred, td, 0); + newnfs_connect(nmp, nrp, cred, td, 0, false); /* * For a client side mount, nmp is != NULL and clp == NULL. For diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index d9e03cf7b791..1fc4e2a4d757 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -1057,25 +1057,6 @@ nfsaddr2_match(NFSSOCKADDR_T nam1, NFSSOCKADDR_T nam2) return (0); } -/* - * Trim trailing data off the mbuf list being built. - */ -void -newnfs_trimtrailing(nd, mb, bpos) - struct nfsrv_descript *nd; - struct mbuf *mb; - caddr_t bpos; -{ - - if (mb->m_next) { - m_freem(mb->m_next); - mb->m_next = NULL; - } - mb->m_len = bpos - mtod(mb, caddr_t); - nd->nd_mb = mb; - nd->nd_bpos = bpos; -} - /* * Dissect a file handle on the client. */ @@ -3650,7 +3631,7 @@ nfsrv_nfsuserdport(struct nfsuserd_args *nargs, NFSPROC_T *p) } rp->nr_vers = RPCNFSUSERD_VERS; if (error == 0) - error = newnfs_connect(NULL, rp, NFSPROCCRED(p), p, 0); + error = newnfs_connect(NULL, rp, NFSPROCCRED(p), p, 0, false); if (error == 0) { NFSLOCKNAMEID(); nfsrv_nfsuserd = RUNNING; diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index 7bf89011d2fd..695c72f74ad3 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -324,8 +324,6 @@ int nfsm_mbufuio(struct nfsrv_descript *, struct uio *, int); int nfsm_fhtom(struct nfsrv_descript *, u_int8_t *, int, int); int nfsm_advance(struct nfsrv_descript *, int, int); void *nfsm_dissct(struct nfsrv_descript *, int, int); -void newnfs_trimtrailing(struct nfsrv_descript *, struct mbuf *, - caddr_t); void newnfs_copycred(struct nfscred *, struct ucred *); void newnfs_copyincred(struct ucred *, struct nfscred *); int nfsrv_dissectacl(struct nfsrv_descript *, NFSACL_T *, int *, @@ -766,7 +764,7 @@ int newnfs_request(struct nfsrv_descript *, struct nfsmount *, struct ucred *, u_int32_t, u_int32_t, u_char *, int, u_int64_t *, struct nfsclsession *); int newnfs_connect(struct nfsmount *, struct nfssockreq *, - struct ucred *, NFSPROC_T *, int); + struct ucred *, NFSPROC_T *, int, bool); void newnfs_disconnect(struct nfssockreq *); int newnfs_sigintr(struct nfsmount *, NFSPROC_T *); diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index 33065249315f..f64615df7f8f 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -5617,7 +5617,7 @@ nfsrpc_fillsa(struct nfsmount *nmp, struct sockaddr_in *sin, * unmount, but I did it anyhow. */ nrp->nr_cred = crhold(nmp->nm_sockreq.nr_cred); - error = newnfs_connect(nmp, nrp, NULL, p, 0); + error = newnfs_connect(nmp, nrp, NULL, p, 0, false); NFSCL_DEBUG(3, "DS connect=%d\n", error); dsp = NULL; diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c index 7124c10573fa..e97d42f4a381 100644 --- a/sys/fs/nfsclient/nfs_clvfsops.c +++ b/sys/fs/nfsclient/nfs_clvfsops.c @@ -718,7 +718,7 @@ nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp, nmp->nm_soproto = argp->proto; if (nmp->nm_sotype == SOCK_DGRAM) while (newnfs_connect(nmp, &nmp->nm_sockreq, - cred, td, 0)) { + cred, td, 0, false)) { printf("newnfs_args: retrying connect\n"); (void) nfs_catnap(PSOCK, 0, "nfscon"); } @@ -1527,7 +1527,7 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam, nmp->nm_sockreq.nr_vers = NFS_VER2; - if ((error = newnfs_connect(nmp, &nmp->nm_sockreq, cred, td, 0))) + if ((error = newnfs_connect(nmp, &nmp->nm_sockreq, cred, td, 0, false))) goto bad; /* For NFSv4.1, get the clientid now. */ if (nmp->nm_minorvers > 0) { diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index 5d15c68c4ead..68216a6f50f5 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -4423,6 +4423,7 @@ nfsrv_docallback(struct nfsclient *clp, int procnum, nfsv4stateid_t *stateidp, u_int32_t callback; struct nfsdsession *sep = NULL; uint64_t tval; + bool dotls; nd = malloc(sizeof(*nd), M_TEMP, M_WAITOK | M_ZERO); cred = newnfs_getcred(); @@ -4547,6 +4548,9 @@ nfsrv_docallback(struct nfsclient *clp, int procnum, nfsv4stateid_t *stateidp, /* * Call newnfs_connect(), as required, and then newnfs_request(). */ + dotls = false; + if ((clp->lc_flags & LCL_TLSCB) != 0) + dotls = true; (void) newnfs_sndlock(&clp->lc_req.nr_lock); if (clp->lc_req.nr_client == NULL) { if ((clp->lc_flags & LCL_NFSV41) != 0) { @@ -4554,10 +4558,10 @@ nfsrv_docallback(struct nfsclient *clp, int procnum, nfsv4stateid_t *stateidp, nfsrv_freesession(sep, NULL); } else if (nd->nd_procnum == NFSV4PROC_CBNULL) error = newnfs_connect(NULL, &clp->lc_req, cred, - NULL, 1); + NULL, 1, dotls); else error = newnfs_connect(NULL, &clp->lc_req, cred, - NULL, 3); + NULL, 3, dotls); } newnfs_sndunlock(&clp->lc_req.nr_lock); NFSD_DEBUG(4, "aft sndunlock=%d\n", error); diff --git a/sys/rpc/clnt.h b/sys/rpc/clnt.h index 26a21cf13187..23c92103edff 100644 --- a/sys/rpc/clnt.h +++ b/sys/rpc/clnt.h @@ -357,6 +357,8 @@ enum clnt_stat clnt_call_private(CLIENT *, struct rpc_callextra *, rpcproc_t, #define CLSET_PRIVPORT 27 /* set privileged source port flag */ #define CLGET_PRIVPORT 28 /* get privileged source port flag */ #define CLSET_BACKCHANNEL 29 /* set backchannel for socket */ +#define CLSET_TLS 30 /* set TLS for socket */ +#define CLSET_BLOCKRCV 31 /* Temporarily block reception */ #endif diff --git a/sys/sys/param.h b/sys/sys/param.h index cdb5495ed335..605a9793e961 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -60,7 +60,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1300105 /* Master, propagated to newvers */ +#define __FreeBSD_version 1300106 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, From 8d2105da1660dd79e4e287cb14c34651bc086bf9 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Tue, 11 Aug 2020 01:09:06 +0000 Subject: [PATCH 08/96] fusefs: fix the FUSE_FORGET unit test after r364064 Thanks to r364064, the name cache now returns a hit where previously it would miss. Adjust the expectations accordingly. PR: 248583 Reported by: lwhsu MFC with: r364064 --- tests/sys/fs/fusefs/forget.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/sys/fs/fusefs/forget.cc b/tests/sys/fs/fusefs/forget.cc index 8a53ac0ecaa6..c138b7acc4aa 100644 --- a/tests/sys/fs/fusefs/forget.cc +++ b/tests/sys/fs/fusefs/forget.cc @@ -116,6 +116,7 @@ TEST_F(Forget, invalidate_names) int err; EXPECT_LOOKUP(FUSE_ROOT_ID, DNAME) + .Times(2) .WillRepeatedly(Invoke( ReturnImmediate([=](auto in __unused, auto& out) { SET_OUT_HEADER_LEN(out, entry); @@ -142,7 +143,7 @@ TEST_F(Forget, invalidate_names) out.body.entry.attr_valid = UINT64_MAX; out.body.entry.entry_valid = UINT64_MAX; }))); - expect_forget(dir_ino, 2); + expect_forget(dir_ino, 1); /* Access the file to cache its name */ ASSERT_EQ(0, access(FULLFPATH, F_OK)) << strerror(errno); From 2d0631dd08ddca6eaba593148a4533313dedfddd Mon Sep 17 00:00:00 2001 From: Mateusz Guzik Date: Tue, 11 Aug 2020 01:34:40 +0000 Subject: [PATCH 09/96] vfs: stricter validation for flags passed to namei in cn_flags namei de facto expects that the naimeidata object is properly initialized, but at the same time it mixes consumer-passable and internal flags, while tolerating this part by explicitly clearing some of them. Tighten the interface instead. While here renumber the flags and denote the gap between the 2 variants. Try to piggy back th renumber on the just bumped __FreeBSD_version. --- sys/kern/vfs_lookup.c | 9 ++++++--- sys/sys/namei.h | 39 ++++++++++++++++++++++++--------------- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index eb352acc5418..a392c128fd01 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -61,6 +61,9 @@ __FBSDID("$FreeBSD$"); #ifdef KTRACE #include #endif +#ifdef INVARIANTS +#include +#endif #include #include @@ -484,15 +487,15 @@ namei(struct nameidata *ndp) ("namei: nameiop contaminated with flags")); KASSERT((cnp->cn_flags & OPMASK) == 0, ("namei: flags contaminated with nameiops")); + KASSERT((cnp->cn_flags & NAMEI_INTERNAL_FLAGS) == 0, + ("namei: unexpected flags: %" PRIx64 "\n", + cnp->cn_flags & NAMEI_INTERNAL_FLAGS)); if (cnp->cn_flags & NOCACHE) KASSERT(cnp->cn_nameiop != LOOKUP, ("%s: NOCACHE passed with LOOKUP", __func__)); MPASS(ndp->ni_startdir == NULL || ndp->ni_startdir->v_type == VDIR || ndp->ni_startdir->v_type == VBAD); - /* We will set this ourselves if we need it. */ - cnp->cn_flags &= ~TRAILINGSLASH; - ndp->ni_lcf = 0; ndp->ni_vp = NULL; diff --git a/sys/sys/namei.h b/sys/sys/namei.h index 784eb79311c0..42d39e7330ab 100644 --- a/sys/sys/namei.h +++ b/sys/sys/namei.h @@ -152,23 +152,32 @@ int cache_fplookup(struct nameidata *ndp, enum cache_fpl_status *status, #define HASBUF 0x00000400 /* has allocated pathname buffer */ #define SAVENAME 0x00000800 /* save pathname buffer */ #define SAVESTART 0x00001000 /* save starting directory */ -#define ISDOTDOT 0x00002000 /* current component name is .. */ -#define MAKEENTRY 0x00004000 /* entry is to be added to name cache */ -#define ISLASTCN 0x00008000 /* this is last component of pathname */ -#define ISSYMLINK 0x00010000 /* symlink needs interpretation */ -#define ISWHITEOUT 0x00020000 /* found whiteout */ -#define DOWHITEOUT 0x00040000 /* do whiteouts */ -#define WILLBEDIR 0x00080000 /* new files will be dirs; allow trailing / */ -#define ISOPEN 0x00200000 /* caller is opening; return a real vnode. */ -#define NOCROSSMOUNT 0x00400000 /* do not cross mount points */ -#define NOMACCHECK 0x00800000 /* do not perform MAC checks */ -#define AUDITVNODE1 0x04000000 /* audit the looked up vnode information */ -#define AUDITVNODE2 0x08000000 /* audit the looked up vnode information */ -#define TRAILINGSLASH 0x10000000 /* path ended in a slash */ -#define NOCAPCHECK 0x20000000 /* do not perform capability checks */ -#define NOEXECCHECK 0x40000000 /* do not perform exec check on dir */ +#define ISWHITEOUT 0x00002000 /* found whiteout */ +#define DOWHITEOUT 0x00004000 /* do whiteouts */ +#define WILLBEDIR 0x00008000 /* new files will be dirs; allow trailing / */ +#define ISOPEN 0x00010000 /* caller is opening; return a real vnode. */ +#define NOCROSSMOUNT 0x00020000 /* do not cross mount points */ +#define NOMACCHECK 0x00040000 /* do not perform MAC checks */ +#define AUDITVNODE1 0x00080000 /* audit the looked up vnode information */ +#define AUDITVNODE2 0x00100000 /* audit the looked up vnode information */ +#define NOCAPCHECK 0x00200000 /* do not perform capability checks */ +/* UNUSED 0x00400000 */ +/* UNUSED 0x00800000 */ +/* UNUSED 0x01000000 */ +#define NOEXECCHECK 0x02000000 /* do not perform exec check on dir */ +#define MAKEENTRY 0x04000000 /* entry is to be added to name cache */ +#define ISSYMLINK 0x08000000 /* symlink needs interpretation */ +#define ISLASTCN 0x10000000 /* this is last component of pathname */ +#define ISDOTDOT 0x20000000 /* current component name is .. */ +#define TRAILINGSLASH 0x40000000 /* path ended in a slash */ #define PARAMASK 0x7ffffe00 /* mask of parameter descriptors */ +/* + * Flags which must not be passed in by callers. + */ +#define NAMEI_INTERNAL_FLAGS \ + (NOEXECCHECK | MAKEENTRY | ISSYMLINK | ISLASTCN | ISDOTDOT | TRAILINGSLASH) + /* * Namei results flags */ From 6d56f524a74aa677559e91885e695ce8aef6a3da Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Tue, 11 Aug 2020 02:05:09 +0000 Subject: [PATCH 10/96] Add an UPDATING entry for r364092, since it did a version bump. --- UPDATING | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/UPDATING b/UPDATING index 206953b5b37b..5f0377ebe822 100644 --- a/UPDATING +++ b/UPDATING @@ -26,6 +26,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 13.x IS SLOW: disable the most expensive debugging functionality run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +20200810: + r364092 modified the internal ABI used between the kernel NFS + modules. As such, all of these modules need to be rebuilt + from sources, so a version bump was done. + 20200807: Makefile.inc has been updated to work around the issue documented in 20200729. It was a case where the optimization of using symbolic links From fc254a2e4ac6f5338e265b2daed88c0e675568e6 Mon Sep 17 00:00:00 2001 From: Li-Wen Hsu Date: Tue, 11 Aug 2020 05:17:10 +0000 Subject: [PATCH 11/96] Fix armv{6,7} build after r364088 Sponsored by: The FreeBSD Foundation --- sys/dev/dwc/if_dwc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/dev/dwc/if_dwc.c b/sys/dev/dwc/if_dwc.c index 16e26793188a..0b38439b3e12 100644 --- a/sys/dev/dwc/if_dwc.c +++ b/sys/dev/dwc/if_dwc.c @@ -1220,7 +1220,8 @@ dwc_clock_init(device_t dev) } if (bootverbose) { clk_get_freq(clk, &freq); - device_printf(dev, "MAC clock(%s) freq: %ld\n", clk_get_name(clk), freq); + device_printf(dev, "MAC clock(%s) freq: %jd\n", + clk_get_name(clk), (intmax_t)freq); } } else { From 9a00f6d06757fb180e55bc18b65430fef8527bb6 Mon Sep 17 00:00:00 2001 From: "Alexander V. Chernikov" Date: Tue, 11 Aug 2020 07:05:30 +0000 Subject: [PATCH 12/96] Fix rib_subscribe() waitok flag by performing allocation outside epoch. Make in6_inithead() use rib_subscribe with waitok to achieve reliable subscription allocation. Reviewed by: glebius --- sys/net/route/route_ctl.c | 13 +++++++------ sys/net/route/route_ctl.h | 2 +- sys/netinet6/in6_rmx.c | 11 ++++------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/sys/net/route/route_ctl.c b/sys/net/route/route_ctl.c index ade0b2a96b24..5d8bdee01bd9 100644 --- a/sys/net/route/route_ctl.c +++ b/sys/net/route/route_ctl.c @@ -743,26 +743,26 @@ rib_notify(struct rib_head *rnh, enum rib_subscription_type type, /* * Subscribe for the changes in the routing table specified by @fibnum and * @family. - * Needs to be run in network epoch. * * Returns pointer to the subscription structure on success. */ struct rib_subscription * rib_subscribe(uint32_t fibnum, int family, rib_subscription_cb_t *f, void *arg, - enum rib_subscription_type type, int waitok) + enum rib_subscription_type type, bool waitok) { struct rib_head *rnh; struct rib_subscription *rs; + struct epoch_tracker et; int flags = M_ZERO | (waitok ? M_WAITOK : 0); - NET_EPOCH_ASSERT(); - KASSERT((fibnum < rt_numfibs), ("%s: bad fibnum", __func__)); - rnh = rt_tables_get_rnh(fibnum, family); - rs = malloc(sizeof(struct rib_subscription), M_RTABLE, flags); if (rs == NULL) return (NULL); + NET_EPOCH_ENTER(et); + KASSERT((fibnum < rt_numfibs), ("%s: bad fibnum", __func__)); + rnh = rt_tables_get_rnh(fibnum, family); + rs->func = f; rs->arg = arg; rs->type = type; @@ -770,6 +770,7 @@ rib_subscribe(uint32_t fibnum, int family, rib_subscription_cb_t *f, void *arg, RIB_WLOCK(rnh); CK_STAILQ_INSERT_TAIL(&rnh->rnh_subscribers, rs, next); RIB_WUNLOCK(rnh); + NET_EPOCH_EXIT(et); return (rs); } diff --git a/sys/net/route/route_ctl.h b/sys/net/route/route_ctl.h index b06eb2c30e5d..a7f445a21c53 100644 --- a/sys/net/route/route_ctl.h +++ b/sys/net/route/route_ctl.h @@ -78,7 +78,7 @@ typedef void rib_subscription_cb_t(struct rib_head *rnh, struct rib_cmd_info *rc struct rib_subscription *rib_subscribe(uint32_t fibnum, int family, rib_subscription_cb_t *f, void *arg, enum rib_subscription_type type, - int waitok); + bool waitok); int rib_unsibscribe(uint32_t fibnum, int family, struct rib_subscription *rs); #endif diff --git a/sys/netinet6/in6_rmx.c b/sys/netinet6/in6_rmx.c index 357292c5c59d..f705c91602f4 100644 --- a/sys/netinet6/in6_rmx.c +++ b/sys/netinet6/in6_rmx.c @@ -150,8 +150,8 @@ rib6_preadd(u_int fibnum, const struct sockaddr *addr, const struct sockaddr *ma int in6_inithead(void **head, int off, u_int fibnum) { - struct epoch_tracker et; struct rib_head *rh; + struct rib_subscription *rs; rh = rt_table_init(offsetof(struct sockaddr_in6, sin6_addr) << 3, AF_INET6, fibnum); @@ -164,12 +164,9 @@ in6_inithead(void **head, int off, u_int fibnum) #endif *head = (void *)rh; - NET_EPOCH_ENTER(et); - if (rib_subscribe(fibnum, AF_INET6, nd6_subscription_cb, NULL, - RIB_NOTIFY_IMMEDIATE, M_NOWAIT) == NULL) - log(LOG_ERR, "in6_inithead(): unable to subscribe to fib %u\n", - fibnum); - NET_EPOCH_EXIT(et); + rs = rib_subscribe(fibnum, AF_INET6, nd6_subscription_cb, NULL, + RIB_NOTIFY_IMMEDIATE, true); + KASSERT(rs != NULL, ("Unable to subscribe to fib %u\n", fibnum)); return (1); } From 136a1f8da8f2bc9c3d33c4d46589c952de251d7e Mon Sep 17 00:00:00 2001 From: "Alexander V. Chernikov" Date: Tue, 11 Aug 2020 07:21:32 +0000 Subject: [PATCH 13/96] Make _route() static to finish the transition to the new kpi. Discussed with: glebius --- sys/net/route/route_ctl.c | 12 +++++++++--- sys/net/route/route_var.h | 6 ------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/sys/net/route/route_ctl.c b/sys/net/route/route_ctl.c index 5d8bdee01bd9..b855438d6008 100644 --- a/sys/net/route/route_ctl.c +++ b/sys/net/route/route_ctl.c @@ -76,6 +76,12 @@ struct rib_subscription { struct epoch_context epoch_ctx; }; +static int add_route(struct rib_head *rnh, struct rt_addrinfo *info, + struct rib_cmd_info *rc); +static int del_route(struct rib_head *rnh, struct rt_addrinfo *info, + struct rib_cmd_info *rc); +static int change_route(struct rib_head *, struct rt_addrinfo *, + struct rib_cmd_info *rc); static void rib_notify(struct rib_head *rnh, enum rib_subscription_type type, struct rib_cmd_info *rc); @@ -128,7 +134,7 @@ rib_add_route(uint32_t fibnum, struct rt_addrinfo *info, return (add_route(rnh, info, rc)); } -int +static int add_route(struct rib_head *rnh, struct rt_addrinfo *info, struct rib_cmd_info *rc) { @@ -389,7 +395,7 @@ rt_unlinkrte(struct rib_head *rnh, struct rt_addrinfo *info, int *perror) return (rt); } -int +static int del_route(struct rib_head *rnh, struct rt_addrinfo *info, struct rib_cmd_info *rc) { @@ -566,7 +572,7 @@ change_route_one(struct rib_head *rnh, struct rt_addrinfo *info, return (0); } -int +static int change_route(struct rib_head *rnh, struct rt_addrinfo *info, struct rib_cmd_info *rc) { diff --git a/sys/net/route/route_var.h b/sys/net/route/route_var.h index 4427ac046ee8..3632aaf07c42 100644 --- a/sys/net/route/route_var.h +++ b/sys/net/route/route_var.h @@ -113,12 +113,6 @@ struct radix_node *rt_mpath_unlink(struct rib_head *rnh, struct rt_addrinfo *info, struct rtentry *rto, int *perror); #endif struct rib_cmd_info; -int add_route(struct rib_head *rnh, struct rt_addrinfo *info, - struct rib_cmd_info *rc); -int del_route(struct rib_head *rnh, struct rt_addrinfo *info, - struct rib_cmd_info *rc); -int change_route(struct rib_head *, struct rt_addrinfo *, - struct rib_cmd_info *rc); VNET_PCPUSTAT_DECLARE(struct rtstat, rtstat); #define RTSTAT_ADD(name, val) \ From 8a0917c35b7cea1cd935ad5dca86c1ee0f58b2e0 Mon Sep 17 00:00:00 2001 From: "Alexander V. Chernikov" Date: Tue, 11 Aug 2020 07:23:07 +0000 Subject: [PATCH 14/96] Do not enter epoch in add_route(), as it is already called in epoch. Reviewed by: glebius --- sys/net/route/route_ctl.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sys/net/route/route_ctl.c b/sys/net/route/route_ctl.c index b855438d6008..7debef06ce8d 100644 --- a/sys/net/route/route_ctl.c +++ b/sys/net/route/route_ctl.c @@ -144,7 +144,6 @@ add_route(struct rib_head *rnh, struct rt_addrinfo *info, struct radix_node *rn; struct ifaddr *ifa; int error, flags; - struct epoch_tracker et; dst = info->rti_info[RTAX_DST]; gateway = info->rti_info[RTAX_GATEWAY]; @@ -168,9 +167,7 @@ add_route(struct rib_head *rnh, struct rt_addrinfo *info, ifa_ref(info->rti_ifa); } - NET_EPOCH_ENTER(et); error = nhop_create_from_info(rnh, info, &nh); - NET_EPOCH_EXIT(et); if (error != 0) { ifa_free(info->rti_ifa); return (error); From b453d3d239d0dddd47740530389be1ceb70d9566 Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Tue, 11 Aug 2020 08:31:40 +0000 Subject: [PATCH 15/96] Use a static initializer for the multicast free tasks. This makes the SYSINIT() function updated in r364072 superfluous. Suggested by: glebius@ MFC after: 1 week Sponsored by: Mellanox Technologies --- sys/netinet/in_mcast.c | 9 +-------- sys/netinet6/in6_mcast.c | 9 +-------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/sys/netinet/in_mcast.c b/sys/netinet/in_mcast.c index cf624e8a3157..99efb4bdb3e4 100644 --- a/sys/netinet/in_mcast.c +++ b/sys/netinet/in_mcast.c @@ -229,16 +229,9 @@ inm_is_ifp_detached(const struct in_multi *inm) * dedicated thread to avoid deadlocks when draining inm_release tasks. */ TASKQUEUE_DEFINE_THREAD(inm_free); -static struct task inm_free_task; static struct in_multi_head inm_free_list = SLIST_HEAD_INITIALIZER(); static void inm_release_task(void *arg __unused, int pending __unused); - -static void -inm_init(void *arg __unused) -{ - TASK_INIT(&inm_free_task, 0, inm_release_task, NULL); -} -SYSINIT(inm_init, SI_SUB_TASKQ, SI_ORDER_ANY, inm_init, NULL); +static struct task inm_free_task = TASK_INITIALIZER(0, inm_release_task, NULL); void inm_release_wait(void *arg __unused) diff --git a/sys/netinet6/in6_mcast.c b/sys/netinet6/in6_mcast.c index 2433dc2ee194..fde7e5dad165 100644 --- a/sys/netinet6/in6_mcast.c +++ b/sys/netinet6/in6_mcast.c @@ -516,16 +516,9 @@ in6m_release(struct in6_multi *inm) * dedicated thread to avoid deadlocks when draining in6m_release tasks. */ TASKQUEUE_DEFINE_THREAD(in6m_free); -static struct task in6m_free_task; static struct in6_multi_head in6m_free_list = SLIST_HEAD_INITIALIZER(); static void in6m_release_task(void *arg __unused, int pending __unused); - -static void -in6m_init(void *arg __unused) -{ - TASK_INIT(&in6m_free_task, 0, in6m_release_task, NULL); -} -SYSINIT(in6m_init, SI_SUB_TASKQ, SI_ORDER_ANY, in6m_init, NULL); +static struct task in6m_free_task = TASK_INITIALIZER(0, in6m_release_task, NULL); void in6m_release_list_deferred(struct in6_multi_head *inmh) From 82087d4b689e2478d2dcc00408d4c7f471cd88f1 Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Tue, 11 Aug 2020 08:42:24 +0000 Subject: [PATCH 16/96] pkgbase: Add PKG_NAME_PREFIX, PKG_MAINTAINER and PKG_WWW This is useful for downstream users to customize the packages. Reviewed by: emaste Differential Revision: https://reviews.freebsd.org/D26019 --- Makefile.inc1 | 13 +++++++++++++ release/packages/binutils.ucl | 6 +++--- release/packages/caroot.ucl | 6 +++--- release/packages/clang.ucl | 6 +++--- release/packages/gdb.ucl | 6 +++--- release/packages/generate-ucl.sh | 3 +++ release/packages/groff.ucl | 6 +++--- release/packages/jail.ucl | 6 +++--- release/packages/kernel.ucl | 6 +++--- release/packages/lld.ucl | 6 +++--- release/packages/lldb.ucl | 6 +++--- release/packages/runtime.ucl | 6 +++--- release/packages/ssh.ucl | 6 +++--- release/packages/svn.ucl | 6 +++--- release/packages/template.ucl | 6 +++--- release/packages/unbound.ucl | 6 +++--- release/packages/utilities.ucl | 6 +++--- 17 files changed, 61 insertions(+), 45 deletions(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index 00abab63d24b..cc2fb0d698d8 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -552,6 +552,13 @@ SOURCE_DATE_EPOCH= ${TIMEEPOCHNOW:gmtime} SOURCE_DATE_EPOCH= ${PKG_TIMESTAMP} .endif +PKG_NAME_PREFIX?= FreeBSD +PKG_MAINTAINER?= re@FreeBSD.org +PKG_WWW?= https://www.FreeBSD.org +.export PKG_NAME_PREFIX +.export PKG_MAINTAINER +.export PKG_WWW + .if !defined(_MKSHOWCONFIG) _CPUTYPE!= MAKEFLAGS= CPUTYPE=${_TARGET_CPUTYPE} ${MAKE} -f /dev/null \ -m ${.CURDIR}/share/mk MK_AUTO_OBJ=no -V CPUTYPE @@ -1906,6 +1913,9 @@ create-kernel-packages-flavor${flavor:C,^""$,${_default_flavor},}: _pkgbootstrap -e "s/%COMMENT%/FreeBSD ${INSTALLKERNEL} kernel ${flavor}/" \ -e "s/%DESC%/FreeBSD ${INSTALLKERNEL} kernel ${flavor}/" \ -e "s/ %VCS_REVISION%/${VCS_REVISION}/" \ + -e "s/%PKG_NAME_PREFIX%/${PKG_NAME_PREFIX}/" \ + -e "s/%PKG_MAINTAINER%/${PKG_MAINTAINER}/" \ + -e "s/%PKG_WWW%/${PKG_WWW}/" \ ${SRCDIR}/release/packages/kernel.ucl \ > ${KSTAGEDIR}/${DISTDIR}/kernel.${INSTALLKERNEL}${flavor}.ucl ; \ awk -F\" ' \ @@ -1939,6 +1949,9 @@ create-kernel-packages-extra-flavor${flavor:C,^""$,${_default_flavor},}-${_kerne -e "s/%COMMENT%/FreeBSD ${_kernel} kernel ${flavor}/" \ -e "s/%DESC%/FreeBSD ${_kernel} kernel ${flavor}/" \ -e "s/ %VCS_REVISION%/${VCS_REVISION}/" \ + -e "s/%PKG_NAME_PREFIX%/${PKG_NAME_PREFIX}/" \ + -e "s/%PKG_MAINTAINER%/${PKG_MAINTAINER}/" \ + -e "s/%PKG_WWW%/${PKG_WWW}/" \ ${SRCDIR}/release/packages/kernel.ucl \ > ${KSTAGEDIR}/kernel.${_kernel}/kernel.${_kernel}${flavor}.ucl ; \ awk -F\" ' \ diff --git a/release/packages/binutils.ucl b/release/packages/binutils.ucl index fcf05b313b38..ec246dfacd75 100644 --- a/release/packages/binutils.ucl +++ b/release/packages/binutils.ucl @@ -2,13 +2,13 @@ # $FreeBSD$ # -name = "FreeBSD-%PKGNAME%" +name = "%PKG_NAME_PREFIX%-%PKGNAME%" origin = "base" version = "%VERSION%" comment = "%COMMENT%" categories = [ base ] -maintainer = "re@FreeBSD.org" -www = "https://www.FreeBSD.org" +maintainer = "%PKG_MAINTAINER%" +www = "%PKG_WWW%" prefix = "/" licenselogic = "single" licenses = [ GPLv2 ] diff --git a/release/packages/caroot.ucl b/release/packages/caroot.ucl index f0d1730f9976..bc298efcabf4 100644 --- a/release/packages/caroot.ucl +++ b/release/packages/caroot.ucl @@ -2,13 +2,13 @@ # $FreeBSD$ # -name = "FreeBSD-%PKGNAME%" +name = "%PKG_NAME_PREFIX%-%PKGNAME%" origin = "base" version = "%VERSION%" comment = "%COMMENT%" categories = [ base ] -maintainer = "re@FreeBSD.org" -www = "https://www.FreeBSD.org" +maintainer = %PKG_MAINTAINER% +www = "%PKG_WWW%" prefix = "/" licenselogic = "single" licenses = [ BSD2CLAUSE ] diff --git a/release/packages/clang.ucl b/release/packages/clang.ucl index 3f8820abcbdf..0642f21d1daa 100644 --- a/release/packages/clang.ucl +++ b/release/packages/clang.ucl @@ -2,13 +2,13 @@ # $FreeBSD$ # -name = "FreeBSD-%PKGNAME%" +name = "%PKG_NAME_PREFIX%-%PKGNAME%" origin = "base" version = "%VERSION%" comment = "%COMMENT%" categories = [ base ] -maintainer = "re@FreeBSD.org" -www = "https://www.FreeBSD.org" +maintainer = "%PKG_MAINTAINER%" +www = "%PKG_WWW%" prefix = "/" licenselogic = "single" licenses = [ NCSA ] diff --git a/release/packages/gdb.ucl b/release/packages/gdb.ucl index fcf05b313b38..ec246dfacd75 100644 --- a/release/packages/gdb.ucl +++ b/release/packages/gdb.ucl @@ -2,13 +2,13 @@ # $FreeBSD$ # -name = "FreeBSD-%PKGNAME%" +name = "%PKG_NAME_PREFIX%-%PKGNAME%" origin = "base" version = "%VERSION%" comment = "%COMMENT%" categories = [ base ] -maintainer = "re@FreeBSD.org" -www = "https://www.FreeBSD.org" +maintainer = "%PKG_MAINTAINER%" +www = "%PKG_WWW%" prefix = "/" licenselogic = "single" licenses = [ GPLv2 ] diff --git a/release/packages/generate-ucl.sh b/release/packages/generate-ucl.sh index 38bbb992d454..d9c791da290e 100755 --- a/release/packages/generate-ucl.sh +++ b/release/packages/generate-ucl.sh @@ -146,6 +146,9 @@ EOF -e "s/%COMMENT%/${comment}/" \ -e "s/%DESC%/${desc}/" \ -e "s/%CAP_MKDB_ENDIAN%/${cap_arg}/g" \ + -e "s/%PKG_NAME_PREFIX%/${PKG_NAME_PREFIX}/" \ + -e "s/%PKG_WWW%/${PKG_WWW}/" \ + -e "s/%PKG_MAINTAINER%/${PKG_MAINTAINER}/" \ ${uclfile} return 0 } diff --git a/release/packages/groff.ucl b/release/packages/groff.ucl index fcf05b313b38..ec246dfacd75 100644 --- a/release/packages/groff.ucl +++ b/release/packages/groff.ucl @@ -2,13 +2,13 @@ # $FreeBSD$ # -name = "FreeBSD-%PKGNAME%" +name = "%PKG_NAME_PREFIX%-%PKGNAME%" origin = "base" version = "%VERSION%" comment = "%COMMENT%" categories = [ base ] -maintainer = "re@FreeBSD.org" -www = "https://www.FreeBSD.org" +maintainer = "%PKG_MAINTAINER%" +www = "%PKG_WWW%" prefix = "/" licenselogic = "single" licenses = [ GPLv2 ] diff --git a/release/packages/jail.ucl b/release/packages/jail.ucl index fcb9a567125b..8448a15ebf7b 100644 --- a/release/packages/jail.ucl +++ b/release/packages/jail.ucl @@ -2,13 +2,13 @@ # $FreeBSD$ # -name = "FreeBSD-%PKGNAME%" +name = "%PKG_NAME_PREFIX%-%PKGNAME%" origin = "base" version = "%VERSION%" comment = "%COMMENT%" categories = [ base ] -maintainer = "re@FreeBSD.org" -www = "https://www.FreeBSD.org" +maintainer = "%PKG_MAINTAINER%" +www = "%PKG_WWW%" prefix = "/" vital = true licenselogic = "single" diff --git a/release/packages/kernel.ucl b/release/packages/kernel.ucl index d7684a6d889d..b7317cae507c 100644 --- a/release/packages/kernel.ucl +++ b/release/packages/kernel.ucl @@ -2,13 +2,13 @@ # $FreeBSD$ # -name = "FreeBSD-%PKGNAME%" +name = "%PKG_NAME_PREFIX%-%PKGNAME%" origin = "base" version = "%VERSION%" comment = "%COMMENT%" categories = [ base ] -maintainer = "re@FreeBSD.org" -www = "https://www.FreeBSD.org" +maintainer = "%PKG_MAINTAINER%" +www = "%PKG_WWW%" prefix = "/" licenselogic = "single" licenses = [ BSD2CLAUSE ] diff --git a/release/packages/lld.ucl b/release/packages/lld.ucl index 3f8820abcbdf..0642f21d1daa 100644 --- a/release/packages/lld.ucl +++ b/release/packages/lld.ucl @@ -2,13 +2,13 @@ # $FreeBSD$ # -name = "FreeBSD-%PKGNAME%" +name = "%PKG_NAME_PREFIX%-%PKGNAME%" origin = "base" version = "%VERSION%" comment = "%COMMENT%" categories = [ base ] -maintainer = "re@FreeBSD.org" -www = "https://www.FreeBSD.org" +maintainer = "%PKG_MAINTAINER%" +www = "%PKG_WWW%" prefix = "/" licenselogic = "single" licenses = [ NCSA ] diff --git a/release/packages/lldb.ucl b/release/packages/lldb.ucl index 3f8820abcbdf..0642f21d1daa 100644 --- a/release/packages/lldb.ucl +++ b/release/packages/lldb.ucl @@ -2,13 +2,13 @@ # $FreeBSD$ # -name = "FreeBSD-%PKGNAME%" +name = "%PKG_NAME_PREFIX%-%PKGNAME%" origin = "base" version = "%VERSION%" comment = "%COMMENT%" categories = [ base ] -maintainer = "re@FreeBSD.org" -www = "https://www.FreeBSD.org" +maintainer = "%PKG_MAINTAINER%" +www = "%PKG_WWW%" prefix = "/" licenselogic = "single" licenses = [ NCSA ] diff --git a/release/packages/runtime.ucl b/release/packages/runtime.ucl index b17971acb2eb..6b51c830ab5c 100644 --- a/release/packages/runtime.ucl +++ b/release/packages/runtime.ucl @@ -2,13 +2,13 @@ # $FreeBSD$ # -name = "FreeBSD-%PKGNAME%" +name = "%PKG_NAME_PREFIX%-%PKGNAME%" origin = "base" version = "%VERSION%" comment = "%COMMENT%" categories = [ base ] -maintainer = "re@FreeBSD.org" -www = "https://www.FreeBSD.org" +maintainer = "%PKG_MAINTAINER%" +www = "%PKG_WWW%" prefix = "/" vital = true licenselogic = "single" diff --git a/release/packages/ssh.ucl b/release/packages/ssh.ucl index faf264e00f10..415094e9d69f 100644 --- a/release/packages/ssh.ucl +++ b/release/packages/ssh.ucl @@ -2,13 +2,13 @@ # $FreeBSD$ # -name = "FreeBSD-%PKGNAME%" +name = "%PKG_NAME_PREFIX%-%PKGNAME%" origin = "base" version = "%VERSION%" comment = "%COMMENT%" categories = [ base ] -maintainer = "re@FreeBSD.org" -www = "https://www.FreeBSD.org" +maintainer = "%PKG_MAINTAINER%" +www = "%PKG_WWW%" prefix = "/" licenselogic = "single" licenses = [ ISCL ] diff --git a/release/packages/svn.ucl b/release/packages/svn.ucl index 5211101e9e8c..f80da47be55b 100644 --- a/release/packages/svn.ucl +++ b/release/packages/svn.ucl @@ -2,13 +2,13 @@ # $FreeBSD$ # -name = "FreeBSD-%PKGNAME%" +name = "%PKG_NAME_PREFIX%-%PKGNAME%" origin = "base" version = "%VERSION%" comment = "%COMMENT%" categories = [ base ] -maintainer = "re@FreeBSD.org" -www = "https://www.FreeBSD.org" +maintainer = "%PKG_MAINTAINER%" +www = "%PKG_WWW%" prefix = "/" licenselogic = "single" licenses = [ APACHE20 ] diff --git a/release/packages/template.ucl b/release/packages/template.ucl index 38844f0f0898..f7cea7af8893 100644 --- a/release/packages/template.ucl +++ b/release/packages/template.ucl @@ -2,13 +2,13 @@ # $FreeBSD$ # -name = "FreeBSD-%PKGNAME%" +name = "%PKG_NAME_PREFIX%-%PKGNAME%" origin = "base" version = "%VERSION%" comment = "%COMMENT%" categories = [ base ] -maintainer = "re@FreeBSD.org" -www = "https://www.FreeBSD.org" +maintainer = "%PKG_MAINTAINER%" +www = "%PKG_WWW%" prefix = "/" licenselogic = "single" licenses = [ BSD2CLAUSE ] diff --git a/release/packages/unbound.ucl b/release/packages/unbound.ucl index 1ba9560abf12..d250e76752f9 100644 --- a/release/packages/unbound.ucl +++ b/release/packages/unbound.ucl @@ -2,13 +2,13 @@ # $FreeBSD$ # -name = "FreeBSD-%PKGNAME%" +name = "%PKG_NAME_PREFIX%-%PKGNAME%" origin = "base" version = "%VERSION%" comment = "%COMMENT%" categories = [ base ] -maintainer = "re@FreeBSD.org" -www = "https://www.FreeBSD.org" +maintainer = "%PKG_MAINTAINER%" +www = "%PKG_WWW%" prefix = "/" licenselogic = "single" licenses = [ BSD4CLAUSE ] diff --git a/release/packages/utilities.ucl b/release/packages/utilities.ucl index 936b46e4cb4c..ab5725d1c1d8 100644 --- a/release/packages/utilities.ucl +++ b/release/packages/utilities.ucl @@ -2,13 +2,13 @@ # $FreeBSD$ # -name = "FreeBSD-%PKGNAME%" +name = "%PKG_NAME_PREFIX%-%PKGNAME%" origin = "base" version = "%VERSION%" comment = "%COMMENT% %VCS_REVISION%" categories = [ base ] -maintainer = "re@FreeBSD.org" -www = "https://www.FreeBSD.org" +maintainer = "%PKG_MAINTAINER%" +www = "%PKG_WWW%" prefix = "/" vital = true licenselogic = "single" From a90022d4d13a34b889081ca0ba9b9af4c78bd78d Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Tue, 11 Aug 2020 10:07:59 +0000 Subject: [PATCH 17/96] pkgbase: Replace / with | for PKG_WWW PKG_WWW contain / char, replace the delimiter by a '|'. Reported by: 0mp --- Makefile.inc1 | 4 ++-- release/packages/generate-ucl.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index cc2fb0d698d8..313adf85cb92 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -1915,7 +1915,7 @@ create-kernel-packages-flavor${flavor:C,^""$,${_default_flavor},}: _pkgbootstrap -e "s/ %VCS_REVISION%/${VCS_REVISION}/" \ -e "s/%PKG_NAME_PREFIX%/${PKG_NAME_PREFIX}/" \ -e "s/%PKG_MAINTAINER%/${PKG_MAINTAINER}/" \ - -e "s/%PKG_WWW%/${PKG_WWW}/" \ + -e "s|%PKG_WWW%|${PKG_WWW}|" \ ${SRCDIR}/release/packages/kernel.ucl \ > ${KSTAGEDIR}/${DISTDIR}/kernel.${INSTALLKERNEL}${flavor}.ucl ; \ awk -F\" ' \ @@ -1951,7 +1951,7 @@ create-kernel-packages-extra-flavor${flavor:C,^""$,${_default_flavor},}-${_kerne -e "s/ %VCS_REVISION%/${VCS_REVISION}/" \ -e "s/%PKG_NAME_PREFIX%/${PKG_NAME_PREFIX}/" \ -e "s/%PKG_MAINTAINER%/${PKG_MAINTAINER}/" \ - -e "s/%PKG_WWW%/${PKG_WWW}/" \ + -e "s|%PKG_WWW%|${PKG_WWW}|" \ ${SRCDIR}/release/packages/kernel.ucl \ > ${KSTAGEDIR}/kernel.${_kernel}/kernel.${_kernel}${flavor}.ucl ; \ awk -F\" ' \ diff --git a/release/packages/generate-ucl.sh b/release/packages/generate-ucl.sh index d9c791da290e..b3d76eb4019d 100755 --- a/release/packages/generate-ucl.sh +++ b/release/packages/generate-ucl.sh @@ -147,7 +147,7 @@ EOF -e "s/%DESC%/${desc}/" \ -e "s/%CAP_MKDB_ENDIAN%/${cap_arg}/g" \ -e "s/%PKG_NAME_PREFIX%/${PKG_NAME_PREFIX}/" \ - -e "s/%PKG_WWW%/${PKG_WWW}/" \ + -e "s|%PKG_WWW%|${PKG_WWW}|" \ -e "s/%PKG_MAINTAINER%/${PKG_MAINTAINER}/" \ ${uclfile} return 0 From 6ae240797f8b497f802b4380a28ddbaf9048ca74 Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Tue, 11 Aug 2020 12:17:46 +0000 Subject: [PATCH 18/96] Need to clone the task struct fields related to RCU aswell in the LinuxKPI after r359727. This fixes a minor regression issue. Else the priority tracking won't work properly when both sleepable and non-sleepable RCU is in use on the same thread. Bump the __FreeBSD_version to force recompilation of external kernel modules. PR: 242272 MFC after: 1 week Sponsored by: Mellanox Technologies --- .../linuxkpi/common/include/linux/sched.h | 5 +++-- sys/compat/linuxkpi/common/src/linux_rcu.c | 18 +++++++++++------- sys/sys/param.h | 2 +- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/sys/compat/linuxkpi/common/include/linux/sched.h b/sys/compat/linuxkpi/common/include/linux/sched.h index 0545710a61d7..da38d89eb639 100644 --- a/sys/compat/linuxkpi/common/include/linux/sched.h +++ b/sys/compat/linuxkpi/common/include/linux/sched.h @@ -76,8 +76,9 @@ struct task_struct { unsigned bsd_ioctl_len; struct completion parked; struct completion exited; - TAILQ_ENTRY(task_struct) rcu_entry; - int rcu_recurse; +#define TS_RCU_TYPE_MAX 2 + TAILQ_ENTRY(task_struct) rcu_entry[TS_RCU_TYPE_MAX]; + int rcu_recurse[TS_RCU_TYPE_MAX]; int bsd_interrupt_value; struct work_struct *work; /* current work struct, if set */ struct task_struct *group_leader; diff --git a/sys/compat/linuxkpi/common/src/linux_rcu.c b/sys/compat/linuxkpi/common/src/linux_rcu.c index 32ace5cf0c99..5e698739ab09 100644 --- a/sys/compat/linuxkpi/common/src/linux_rcu.c +++ b/sys/compat/linuxkpi/common/src/linux_rcu.c @@ -74,6 +74,7 @@ struct linux_epoch_record { ck_epoch_record_t epoch_record; TAILQ_HEAD(, task_struct) ts_head; int cpuid; + int type; } __aligned(CACHE_LINE_SIZE); /* @@ -90,6 +91,8 @@ CTASSERT(sizeof(struct rcu_head) == sizeof(struct callback_head)); */ CTASSERT(offsetof(struct linux_epoch_record, epoch_record) == 0); +CTASSERT(TS_RCU_TYPE_MAX == RCU_TYPE_MAX); + static ck_epoch_t linux_epoch[RCU_TYPE_MAX]; static struct linux_epoch_head linux_epoch_head[RCU_TYPE_MAX]; DPCPU_DEFINE_STATIC(struct linux_epoch_record, linux_epoch_record[RCU_TYPE_MAX]); @@ -118,6 +121,7 @@ linux_rcu_runtime_init(void *arg __unused) record = &DPCPU_ID_GET(i, linux_epoch_record[j]); record->cpuid = i; + record->type = j; ck_epoch_register(&linux_epoch[j], &record->epoch_record, NULL); TAILQ_INIT(&record->ts_head); @@ -201,9 +205,9 @@ linux_rcu_read_lock(unsigned type) */ critical_enter(); ck_epoch_begin(&record->epoch_record, NULL); - ts->rcu_recurse++; - if (ts->rcu_recurse == 1) - TAILQ_INSERT_TAIL(&record->ts_head, ts, rcu_entry); + ts->rcu_recurse[type]++; + if (ts->rcu_recurse[type] == 1) + TAILQ_INSERT_TAIL(&record->ts_head, ts, rcu_entry[type]); critical_exit(); } @@ -227,9 +231,9 @@ linux_rcu_read_unlock(unsigned type) */ critical_enter(); ck_epoch_end(&record->epoch_record, NULL); - ts->rcu_recurse--; - if (ts->rcu_recurse == 0) - TAILQ_REMOVE(&record->ts_head, ts, rcu_entry); + ts->rcu_recurse[type]--; + if (ts->rcu_recurse[type] == 0) + TAILQ_REMOVE(&record->ts_head, ts, rcu_entry[type]); critical_exit(); sched_unpin(); @@ -254,7 +258,7 @@ linux_synchronize_rcu_cb(ck_epoch_t *epoch __unused, ck_epoch_record_t *epoch_re * the threads in the queue are CPU-pinned and cannot * go anywhere while the current thread is locked. */ - TAILQ_FOREACH(ts, &record->ts_head, rcu_entry) { + TAILQ_FOREACH(ts, &record->ts_head, rcu_entry[record->type]) { if (ts->task_thread->td_priority > prio) prio = ts->task_thread->td_priority; is_sleeping |= (ts->task_thread->td_inhibitors != 0); diff --git a/sys/sys/param.h b/sys/sys/param.h index 605a9793e961..b947c1d6b394 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -60,7 +60,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1300106 /* Master, propagated to newvers */ +#define __FreeBSD_version 1300107 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, From 74d3a63559e0ab55db91e8a67171917a4f0fb3ea Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Tue, 11 Aug 2020 12:41:40 +0000 Subject: [PATCH 19/96] Use atomic_clear_rel_long() to implement clear_bit_unlock() in the LinuxKPI after r363842. Suggested by: alc@ MFC after: 1 week Sponsored by: Mellanox Technologies --- sys/compat/linuxkpi/common/include/linux/bitops.h | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/sys/compat/linuxkpi/common/include/linux/bitops.h b/sys/compat/linuxkpi/common/include/linux/bitops.h index 7e259760f7c3..1bcbd681203c 100644 --- a/sys/compat/linuxkpi/common/include/linux/bitops.h +++ b/sys/compat/linuxkpi/common/include/linux/bitops.h @@ -272,16 +272,12 @@ find_next_zero_bit(const unsigned long *addr, unsigned long size, #define clear_bit(i, a) \ atomic_clear_long(&((volatile unsigned long *)(a))[BIT_WORD(i)], BIT_MASK(i)) +#define clear_bit_unlock(i, a) \ + atomic_clear_rel_long(&((volatile unsigned long *)(a))[BIT_WORD(i)], BIT_MASK(i)) + #define test_bit(i, a) \ !!(READ_ONCE(((volatile const unsigned long *)(a))[BIT_WORD(i)]) & BIT_MASK(i)) -static inline void -clear_bit_unlock(long bit, volatile unsigned long *var) -{ - clear_bit(bit, var); - wmb(); -} - static inline int test_and_clear_bit(long bit, volatile unsigned long *var) { From 8bc30d2afda0dae4b708b298c6b1e9d8ec2b8a7d Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Tue, 11 Aug 2020 14:19:05 +0000 Subject: [PATCH 20/96] script: Minor cleanups. - Instead of using isatty() to decide whether to call tcgetattr(), just call tcgetattr() directly, since that's all that isatty() does anyway. - Simplify error handling in termset(). Check for errno != ENOTTY from tcgetattr() to handle errors that may be raised while running script(1) under a debugger. PR: 248377 Submitted by: Soumendra Ganguly MFC after: 1 week --- usr.bin/script/script.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/usr.bin/script/script.c b/usr.bin/script/script.c index 8d22ea4251e7..149458baa331 100644 --- a/usr.bin/script/script.c +++ b/usr.bin/script/script.c @@ -176,16 +176,16 @@ main(int argc, char *argv[]) if (pflg) playback(fscript); - if ((ttyflg = isatty(STDIN_FILENO)) != 0) { - if (tcgetattr(STDIN_FILENO, &tt) == -1) - err(1, "tcgetattr"); - if (ioctl(STDIN_FILENO, TIOCGWINSZ, &win) == -1) - err(1, "ioctl"); - if (openpty(&master, &slave, NULL, &tt, &win) == -1) - err(1, "openpty"); - } else { + if (tcgetattr(STDIN_FILENO, &tt) == -1 || + ioctl(STDIN_FILENO, TIOCGWINSZ, &win) == -1) { + if (errno != ENOTTY) /* For debugger. */ + err(1, "tcgetattr/ioctl"); if (openpty(&master, &slave, NULL, NULL, NULL) == -1) err(1, "openpty"); + } else { + if (openpty(&master, &slave, NULL, &tt, &win) == -1) + err(1, "openpty"); + ttyflg = 1; } if (rawout) @@ -433,9 +433,8 @@ termset(void) struct termios traw; if (tcgetattr(STDOUT_FILENO, &tt) == -1) { - if (errno == EBADF) - err(1, "%d not valid fd", STDOUT_FILENO); - /* errno == ENOTTY */ + if (errno != ENOTTY) /* For debugger. */ + err(1, "tcgetattr"); return; } ttyflg = 1; From 3b44443626603f65bba2804f08a7dfa6e6675bb4 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik Date: Tue, 11 Aug 2020 14:27:57 +0000 Subject: [PATCH 21/96] devfs: rework si_usecount to track opens This removes a lot of special casing from the VFS layer. Reviewed by: kib (previous version) Tested by: pho (previous version) Differential Revision: https://reviews.freebsd.org/D25612 --- sys/fs/devfs/devfs.h | 5 + sys/fs/devfs/devfs_vnops.c | 162 +++++++++++++++++++++++++++---- sys/kern/kern_proc.c | 4 +- sys/kern/tty.c | 4 +- sys/kern/vfs_subr.c | 190 ------------------------------------- sys/kern/vfs_syscalls.c | 4 +- sys/sys/vnode.h | 1 - 7 files changed, 159 insertions(+), 211 deletions(-) diff --git a/sys/fs/devfs/devfs.h b/sys/fs/devfs/devfs.h index 673d94999169..aef291601289 100644 --- a/sys/fs/devfs/devfs.h +++ b/sys/fs/devfs/devfs.h @@ -153,6 +153,7 @@ struct devfs_dirent { struct timespec de_ctime; struct vnode *de_vnode; char *de_symlink; + int de_usecount; }; struct devfs_mount { @@ -203,6 +204,10 @@ struct devfs_dirent *devfs_vmkdir(struct devfs_mount *, char *, int, struct devfs_dirent *devfs_find(struct devfs_dirent *, const char *, int, int); +void devfs_ctty_ref(struct vnode *); +void devfs_ctty_unref(struct vnode *); +int devfs_usecount(struct vnode *); + #endif /* _KERNEL */ #endif /* !_FS_DEVFS_DEVFS_H_ */ diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c index f9e29e0b1c74..983bfc803999 100644 --- a/sys/fs/devfs/devfs_vnops.c +++ b/sys/fs/devfs/devfs_vnops.c @@ -222,6 +222,115 @@ devfs_clear_cdevpriv(void) devfs_fpdrop(fp); } +static void +devfs_usecount_add(struct vnode *vp) +{ + struct devfs_dirent *de; + struct cdev *dev; + + mtx_lock(&devfs_de_interlock); + VI_LOCK(vp); + VNPASS(vp->v_type == VCHR || vp->v_type == VBAD, vp); + if (VN_IS_DOOMED(vp)) { + goto out_unlock; + } + + de = vp->v_data; + dev = vp->v_rdev; + MPASS(de != NULL); + MPASS(dev != NULL); + dev->si_usecount++; + de->de_usecount++; +out_unlock: + VI_UNLOCK(vp); + mtx_unlock(&devfs_de_interlock); +} + +static void +devfs_usecount_subl(struct vnode *vp) +{ + struct devfs_dirent *de; + struct cdev *dev; + + mtx_assert(&devfs_de_interlock, MA_OWNED); + ASSERT_VI_LOCKED(vp, __func__); + VNPASS(vp->v_type == VCHR || vp->v_type == VBAD, vp); + + de = vp->v_data; + dev = vp->v_rdev; + if (de == NULL) + return; + if (dev == NULL) { + MPASS(de->de_usecount == 0); + return; + } + if (dev->si_usecount < de->de_usecount) + panic("%s: si_usecount underflow for dev %p " + "(has %ld, dirent has %d)\n", + __func__, dev, dev->si_usecount, de->de_usecount); + if (VN_IS_DOOMED(vp)) { + dev->si_usecount -= de->de_usecount; + de->de_usecount = 0; + } else { + if (de->de_usecount == 0) + panic("%s: de_usecount underflow for dev %p\n", + __func__, dev); + dev->si_usecount--; + de->de_usecount--; + } +} + +static void +devfs_usecount_sub(struct vnode *vp) +{ + + mtx_lock(&devfs_de_interlock); + VI_LOCK(vp); + devfs_usecount_subl(vp); + VI_UNLOCK(vp); + mtx_unlock(&devfs_de_interlock); +} + +static int +devfs_usecountl(struct vnode *vp) +{ + + VNPASS(vp->v_type == VCHR, vp); + mtx_assert(&devfs_de_interlock, MA_OWNED); + ASSERT_VI_LOCKED(vp, __func__); + return (vp->v_rdev->si_usecount); +} + +int +devfs_usecount(struct vnode *vp) +{ + int count; + + VNPASS(vp->v_type == VCHR, vp); + mtx_lock(&devfs_de_interlock); + VI_LOCK(vp); + count = devfs_usecountl(vp); + VI_UNLOCK(vp); + mtx_unlock(&devfs_de_interlock); + return (count); +} + +void +devfs_ctty_ref(struct vnode *vp) +{ + + vrefact(vp); + devfs_usecount_add(vp); +} + +void +devfs_ctty_unref(struct vnode *vp) +{ + + devfs_usecount_sub(vp); + vrele(vp); +} + /* * On success devfs_populate_vp() returns with dmp->dm_lock held. */ @@ -487,7 +596,6 @@ devfs_allocv(struct devfs_dirent *de, struct mount *mp, int lockmode, /* XXX: v_rdev should be protect by vnode lock */ vp->v_rdev = dev; VNPASS(vp->v_usecount == 1, vp); - dev->si_usecount++; /* Special casing of ttys for deadfs. Probably redundant. */ dsw = dev->si_devsw; if (dsw != NULL && (dsw->d_flags & D_TTY) != 0) @@ -569,6 +677,7 @@ devfs_close(struct vop_close_args *ap) struct proc *p; struct cdev *dev = vp->v_rdev; struct cdevsw *dsw; + struct devfs_dirent *de = vp->v_data; int dflags, error, ref, vp_locked; /* @@ -587,7 +696,7 @@ devfs_close(struct vop_close_args *ap) * if the reference count is 2 (this last descriptor * plus the session), release the reference from the session. */ - if (vp->v_usecount == 2 && td != NULL) { + if (de->de_usecount == 2 && td != NULL) { p = td->td_proc; PROC_LOCK(p); if (vp == p->p_session->s_ttyvp) { @@ -596,19 +705,20 @@ devfs_close(struct vop_close_args *ap) sx_xlock(&proctree_lock); if (vp == p->p_session->s_ttyvp) { SESS_LOCK(p->p_session); + mtx_lock(&devfs_de_interlock); VI_LOCK(vp); - if (vp->v_usecount == 2 && vcount(vp) == 1 && - !VN_IS_DOOMED(vp)) { + if (devfs_usecountl(vp) == 2 && !VN_IS_DOOMED(vp)) { p->p_session->s_ttyvp = NULL; p->p_session->s_ttydp = NULL; oldvp = vp; } VI_UNLOCK(vp); + mtx_unlock(&devfs_de_interlock); SESS_UNLOCK(p->p_session); } sx_xunlock(&proctree_lock); if (oldvp != NULL) - vrele(oldvp); + devfs_ctty_unref(oldvp); } else PROC_UNLOCK(p); } @@ -625,9 +735,12 @@ devfs_close(struct vop_close_args *ap) if (dsw == NULL) return (ENXIO); dflags = 0; + mtx_lock(&devfs_de_interlock); VI_LOCK(vp); - if (vp->v_usecount == 1 && vcount(vp) == 1) + if (devfs_usecountl(vp) == 1) dflags |= FLASTCLOSE; + devfs_usecount_subl(vp); + mtx_unlock(&devfs_de_interlock); if (VN_IS_DOOMED(vp)) { /* Forced close. */ dflags |= FREVOKE | FNONBLOCK; @@ -850,7 +963,7 @@ devfs_ioctl(struct vop_ioctl_args *ap) return (0); } - vrefact(vp); + devfs_ctty_ref(vp); SESS_LOCK(sess); vpold = sess->s_ttyvp; sess->s_ttyvp = vp; @@ -1159,6 +1272,9 @@ devfs_open(struct vop_open_args *ap) return (ENXIO); } + if (vp->v_type == VCHR) + devfs_usecount_add(vp); + vlocked = VOP_ISLOCKED(vp); VOP_UNLOCK(vp); @@ -1178,6 +1294,9 @@ devfs_open(struct vop_open_args *ap) td->td_fpop = fpop; vn_lock(vp, vlocked | LK_RETRY); + if (error != 0 && vp->v_type == VCHR) + devfs_usecount_sub(vp); + dev_relthread(dev, ref); if (error != 0) { if (error == ERESTART) @@ -1406,19 +1525,28 @@ devfs_readlink(struct vop_readlink_args *ap) return (uiomove(de->de_symlink, strlen(de->de_symlink), ap->a_uio)); } +static void +devfs_reclaiml(struct vnode *vp) +{ + struct devfs_dirent *de; + + mtx_assert(&devfs_de_interlock, MA_OWNED); + de = vp->v_data; + if (de != NULL) { + MPASS(de->de_usecount == 0); + de->de_vnode = NULL; + vp->v_data = NULL; + } +} + static int devfs_reclaim(struct vop_reclaim_args *ap) { struct vnode *vp; - struct devfs_dirent *de; vp = ap->a_vp; mtx_lock(&devfs_de_interlock); - de = vp->v_data; - if (de != NULL) { - de->de_vnode = NULL; - vp->v_data = NULL; - } + devfs_reclaiml(vp); mtx_unlock(&devfs_de_interlock); return (0); } @@ -1432,14 +1560,14 @@ devfs_reclaim_vchr(struct vop_reclaim_args *ap) vp = ap->a_vp; MPASS(vp->v_type == VCHR); - devfs_reclaim(ap); - + mtx_lock(&devfs_de_interlock); VI_LOCK(vp); + devfs_usecount_subl(vp); + devfs_reclaiml(vp); + mtx_unlock(&devfs_de_interlock); dev_lock(); dev = vp->v_rdev; vp->v_rdev = NULL; - if (dev != NULL) - dev->si_usecount -= (vp->v_usecount > 0); dev_unlock(); VI_UNLOCK(vp); if (dev != NULL) diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index ce9554b6dfaa..50449938c5c1 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -88,6 +88,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #ifdef COMPAT_FREEBSD32 #include #include @@ -858,7 +860,7 @@ killjobc(void) VOP_REVOKE(ttyvp, REVOKEALL); VOP_UNLOCK(ttyvp); } - vrele(ttyvp); + devfs_ctty_unref(ttyvp); sx_xlock(&proctree_lock); } } diff --git a/sys/kern/tty.c b/sys/kern/tty.c index 4c11ff56000b..a6ed98f86297 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -67,6 +67,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include static MALLOC_DEFINE(M_TTY, "tty", "tty device"); @@ -1256,7 +1258,7 @@ tty_drop_ctty(struct tty *tp, struct proc *p) * is either changed or released. */ if (vp != NULL) - vrele(vp); + devfs_ctty_unref(vp); return (0); } diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 4df6be9ace71..86b9c748740e 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -108,8 +108,6 @@ static int flushbuflist(struct bufv *bufv, int flags, struct bufobj *bo, static void syncer_shutdown(void *arg, int howto); static int vtryrecycle(struct vnode *vp); static void v_init_counters(struct vnode *); -static void v_incr_devcount(struct vnode *); -static void v_decr_devcount(struct vnode *); static void vgonel(struct vnode *); static void vfs_knllock(void *arg); static void vfs_knlunlock(void *arg); @@ -2793,59 +2791,6 @@ v_init_counters(struct vnode *vp) refcount_init(&vp->v_usecount, 1); } -/* - * Increment si_usecount of the associated device, if any. - */ -static void -v_incr_devcount(struct vnode *vp) -{ - - ASSERT_VI_LOCKED(vp, __FUNCTION__); - if (vp->v_type == VCHR && vp->v_rdev != NULL) { - dev_lock(); - vp->v_rdev->si_usecount++; - dev_unlock(); - } -} - -/* - * Decrement si_usecount of the associated device, if any. - * - * The caller is required to hold the interlock when transitioning a VCHR use - * count to zero. This prevents a race with devfs_reclaim_vchr() that would - * leak a si_usecount reference. The vnode lock will also prevent this race - * if it is held while dropping the last ref. - * - * The race is: - * - * CPU1 CPU2 - * devfs_reclaim_vchr - * make v_usecount == 0 - * VI_LOCK - * sees v_usecount == 0, no updates - * vp->v_rdev = NULL; - * ... - * VI_UNLOCK - * VI_LOCK - * v_decr_devcount - * sees v_rdev == NULL, no updates - * - * In this scenario si_devcount decrement is not performed. - */ -static void -v_decr_devcount(struct vnode *vp) -{ - - ASSERT_VOP_LOCKED(vp, __func__); - ASSERT_VI_LOCKED(vp, __FUNCTION__); - if (vp->v_type == VCHR && vp->v_rdev != NULL) { - dev_lock(); - VNPASS(vp->v_rdev->si_usecount > 0, vp); - vp->v_rdev->si_usecount--; - dev_unlock(); - } -} - /* * Grab a particular vnode from the free list, increment its * reference count and lock it. VIRF_DOOMED is set if the vnode @@ -2921,41 +2866,6 @@ vget(struct vnode *vp, int flags, struct thread *td) return (vget_finish(vp, flags, vs)); } -static void __noinline -vget_finish_vchr(struct vnode *vp) -{ - - VNASSERT(vp->v_type == VCHR, vp, ("type != VCHR)")); - - /* - * See the comment in vget_finish before usecount bump. - */ - if (refcount_acquire_if_not_zero(&vp->v_usecount)) { -#ifdef INVARIANTS - int old = atomic_fetchadd_int(&vp->v_holdcnt, -1); - VNASSERT(old > 0, vp, ("%s: wrong hold count %d", __func__, old)); -#else - refcount_release(&vp->v_holdcnt); -#endif - return; - } - - VI_LOCK(vp); - if (refcount_acquire_if_not_zero(&vp->v_usecount)) { -#ifdef INVARIANTS - int old = atomic_fetchadd_int(&vp->v_holdcnt, -1); - VNASSERT(old > 1, vp, ("%s: wrong hold count %d", __func__, old)); -#else - refcount_release(&vp->v_holdcnt); -#endif - VI_UNLOCK(vp); - return; - } - v_incr_devcount(vp); - refcount_acquire(&vp->v_usecount); - VI_UNLOCK(vp); -} - int vget_finish(struct vnode *vp, int flags, enum vgetstate vs) { @@ -2993,11 +2903,6 @@ vget_finish_ref(struct vnode *vp, enum vgetstate vs) if (vs == VGET_USECOUNT) return; - if (__predict_false(vp->v_type == VCHR)) { - vget_finish_vchr(vp); - return; - } - /* * We hold the vnode. If the usecount is 0 it will be utilized to keep * the vnode around. Otherwise someone else lended their hold count and @@ -3019,61 +2924,12 @@ vget_finish_ref(struct vnode *vp, enum vgetstate vs) * Increase the reference (use) and hold count of a vnode. * This will also remove the vnode from the free list if it is presently free. */ -static void __noinline -vref_vchr(struct vnode *vp, bool interlock) -{ - - /* - * See the comment in vget_finish before usecount bump. - */ - if (!interlock) { - if (refcount_acquire_if_not_zero(&vp->v_usecount)) { - VNODE_REFCOUNT_FENCE_ACQ(); - VNASSERT(vp->v_holdcnt > 0, vp, - ("%s: active vnode not held", __func__)); - return; - } - VI_LOCK(vp); - /* - * By the time we get here the vnode might have been doomed, at - * which point the 0->1 use count transition is no longer - * protected by the interlock. Since it can't bounce back to - * VCHR and requires vref semantics, punt it back - */ - if (__predict_false(vp->v_type == VBAD)) { - VI_UNLOCK(vp); - vref(vp); - return; - } - } - VNASSERT(vp->v_type == VCHR, vp, ("type != VCHR)")); - if (refcount_acquire_if_not_zero(&vp->v_usecount)) { - VNODE_REFCOUNT_FENCE_ACQ(); - VNASSERT(vp->v_holdcnt > 0, vp, - ("%s: active vnode not held", __func__)); - if (!interlock) - VI_UNLOCK(vp); - return; - } - vhold(vp); - v_incr_devcount(vp); - refcount_acquire(&vp->v_usecount); - if (!interlock) - VI_UNLOCK(vp); - return; -} - void vref(struct vnode *vp) { int old; CTR2(KTR_VFS, "%s: vp %p", __func__, vp); - if (__predict_false(vp->v_type == VCHR)) { - vref_vchr(vp, false); - return; - } - if (refcount_acquire_if_not_zero(&vp->v_usecount)) { VNODE_REFCOUNT_FENCE_ACQ(); VNASSERT(vp->v_holdcnt > 0, vp, @@ -3102,10 +2958,6 @@ vrefl(struct vnode *vp) ASSERT_VI_LOCKED(vp, __func__); CTR2(KTR_VFS, "%s: vp %p", __func__, vp); - if (__predict_false(vp->v_type == VCHR)) { - vref_vchr(vp, true); - return; - } vref(vp); } @@ -3246,9 +3098,6 @@ enum vput_op { VRELE, VPUT, VUNREF }; * By releasing the last usecount we take ownership of the hold count which * provides liveness of the vnode, meaning we have to vdrop. * - * If the vnode is of type VCHR we may need to decrement si_usecount, see - * v_decr_devcount for details. - * * For all vnodes we may need to perform inactive processing. It requires an * exclusive lock on the vnode, while it is legal to call here with only a * shared lock (or no locks). If locking the vnode in an expected manner fails, @@ -3269,8 +3118,6 @@ vput_final(struct vnode *vp, enum vput_op func) VNPASS(vp->v_holdcnt > 0, vp); VI_LOCK(vp); - if (__predict_false(vp->v_type == VCHR && func != VRELE)) - v_decr_devcount(vp); /* * By the time we got here someone else might have transitioned @@ -3358,28 +3205,9 @@ vput_final(struct vnode *vp, enum vput_op func) * Releasing the last use count requires additional processing, see vput_final * above for details. * - * Note that releasing use count without the vnode lock requires special casing - * for VCHR, see v_decr_devcount for details. - * * Comment above each variant denotes lock state on entry and exit. */ -static void __noinline -vrele_vchr(struct vnode *vp) -{ - - if (refcount_release_if_not_last(&vp->v_usecount)) - return; - VI_LOCK(vp); - if (!refcount_release(&vp->v_usecount)) { - VI_UNLOCK(vp); - return; - } - v_decr_devcount(vp); - VI_UNLOCK(vp); - vput_final(vp, VRELE); -} - /* * in: any * out: same as passed in @@ -3389,10 +3217,6 @@ vrele(struct vnode *vp) { ASSERT_VI_UNLOCKED(vp, __func__); - if (__predict_false(vp->v_type == VCHR)) { - vrele_vchr(vp); - return; - } if (!refcount_release(&vp->v_usecount)) return; vput_final(vp, VRELE); @@ -4143,20 +3967,6 @@ vgonel(struct vnode *vp) vp->v_type = VBAD; } -/* - * Calculate the total number of references to a special device. - */ -int -vcount(struct vnode *vp) -{ - int count; - - dev_lock(); - count = vp->v_rdev->si_usecount; - dev_unlock(); - return (count); -} - /* * Print out a description of a vnode. */ diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 68e2082d681b..f44b440be661 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -87,6 +87,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include MALLOC_DEFINE(M_FADVISE, "fadvise", "posix_fadvise(2) information"); @@ -4213,7 +4215,7 @@ sys_revoke(struct thread *td, struct revoke_args *uap) if (error != 0) goto out; } - if (vp->v_usecount > 1 || vcount(vp) > 1) + if (devfs_usecount(vp) > 0) VOP_REVOKE(vp, REVOKEALL); out: vput(vp); diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 87c01a962064..2e21833c0359 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -676,7 +676,6 @@ int vaccess_acl_posix1e(enum vtype type, uid_t file_uid, gid_t file_gid, struct acl *acl, accmode_t accmode, struct ucred *cred); void vattr_null(struct vattr *vap); -int vcount(struct vnode *vp); void vlazy(struct vnode *); void vdrop(struct vnode *); void vdropl(struct vnode *); From 825398f946221045c565363a0349f68d054d6455 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Tue, 11 Aug 2020 15:46:22 +0000 Subject: [PATCH 22/96] ipfw: make the "frag" keyword accept additional options "mf", "df", "rf" and "offset". This allows to match on specific bits of ip_off field. For compatibility reasons lack of keyword means "offset". Reviewed by: ae Differential Revision: https://reviews.freebsd.org/D26021 --- sbin/ipfw/ipfw.8 | 33 +++++++++++++++++++++++++-------- sbin/ipfw/ipfw2.c | 20 ++++++++++++++++++-- sys/netpfil/ipfw/ip_fw2.c | 18 +++++++++++++++++- 3 files changed, 60 insertions(+), 11 deletions(-) diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8 index ea35a2767845..58bc3662fcc7 100644 --- a/sbin/ipfw/ipfw.8 +++ b/sbin/ipfw/ipfw.8 @@ -1,7 +1,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 21, 2019 +.Dd August 10, 2020 .Dt IPFW 8 .Os .Sh NAME @@ -600,7 +600,7 @@ See Section By name or address .It Misc. IP header fields Version, type of service, datagram length, identification, -fragment flag (non-zero IP offset), +fragmentation flags, Time To Live .It IP options .It IPv6 Extension headers @@ -1602,12 +1602,29 @@ Matches IPv6 packets containing any of the flow labels given in .Ar labels . .Ar labels is a comma separated list of numeric flow labels. -.It Cm frag -Matches packets that are fragments and not the first -fragment of an IP datagram. -Note that these packets will not have -the next protocol header (e.g.\& TCP, UDP) so options that look into -these headers cannot match. +.It Cm frag Ar spec +Matches IPv4 packets whose +.Cm ip_off +field contains the comma separated list of IPv4 fragmentation +options specified in +.Ar spec . +The recognized options are: +.Cm df +.Pq Dv don't fragment , +.Cm mf +.Pq Dv more fragments , +.Cm rf +.Pq Dv reserved fragment bit +.Cm offset +.Pq Dv non-zero fragment offset . +The absence of a particular options may be denoted +with a +.Ql \&! . +.Pp +Empty list of options defaults to matching on non-zero fragment offset. +Such rule would match all not the first fragment datagrams, +both IPv4 and IPv6. +This is a backward compatibility with older rulesets. .It Cm gid Ar group Matches all TCP or UDP packets sent by or received for a .Ar group . diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c index d4c81d5e4d66..830b35d2f723 100644 --- a/sbin/ipfw/ipfw2.c +++ b/sbin/ipfw/ipfw2.c @@ -168,6 +168,14 @@ static struct _s_x f_iptos[] = { { NULL, 0 } }; +static struct _s_x f_ipoff[] = { + { "rf", IP_RF >> 8 }, + { "df", IP_DF >> 8 }, + { "mf", IP_MF >> 8 }, + { "offset", 0x1 }, + { NULL, 0} +}; + struct _s_x f_ipdscp[] = { { "af11", IPTOS_DSCP_AF11 >> 2 }, /* 001010 */ { "af12", IPTOS_DSCP_AF12 >> 2 }, /* 001100 */ @@ -1531,7 +1539,7 @@ print_instruction(struct buf_pr *bp, const struct format_opts *fo, IPPROTO_ETHERTYPE, cmd->opcode); break; case O_FRAG: - bprintf(bp, " frag"); + print_flags(bp, "frag", cmd, f_ipoff); break; case O_FIB: bprintf(bp, " fib %u", cmd->arg1); @@ -4553,7 +4561,15 @@ compile_rule(char *av[], uint32_t *rbuf, int *rbufsize, struct tidx *tstate) break; case TOK_FRAG: - fill_cmd(cmd, O_FRAG, 0, 0); + fill_flags_cmd(cmd, O_FRAG, f_ipoff, *av); + /* + * Compatibility: no argument after "frag" + * keyword equals to "frag offset". + */ + if (cmd->arg1 == 0) + cmd->arg1 = 0x1; + else + av++; break; case TOK_LAYER2: diff --git a/sys/netpfil/ipfw/ip_fw2.c b/sys/netpfil/ipfw/ip_fw2.c index bbdbcc88a038..bfce77f40c3f 100644 --- a/sys/netpfil/ipfw/ip_fw2.c +++ b/sys/netpfil/ipfw/ip_fw2.c @@ -1944,7 +1944,23 @@ do { \ break; case O_FRAG: - match = (offset != 0); + if (is_ipv4) { + /* + * Since flags_match() works with + * uint8_t we pack ip_off into 8 bits. + * For this match offset is a boolean. + */ + match = flags_match(cmd, + ((ntohs(ip->ip_off) & ~IP_OFFMASK) + >> 8) | (offset != 0)); + } else { + /* + * Compatiblity: historically bare + * "frag" would match IPv6 fragments. + */ + match = (cmd->arg1 == 0x1 && + (offset != 0)); + } break; case O_IN: /* "out" is "not in" */ From aa5dbc89530716be934372503a7132ef1c9962e2 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Tue, 11 Aug 2020 16:40:09 +0000 Subject: [PATCH 23/96] Remove sys/compat/netbsd. It contained only a header used by ncv(4), which was mainly used on pc98 systems. Both ncv(4) and pc98 support have long been removed. --- sys/compat/netbsd/dvcfg.h | 67 --------------------------------------- 1 file changed, 67 deletions(-) delete mode 100644 sys/compat/netbsd/dvcfg.h diff --git a/sys/compat/netbsd/dvcfg.h b/sys/compat/netbsd/dvcfg.h deleted file mode 100644 index 809c14a95aff..000000000000 --- a/sys/compat/netbsd/dvcfg.h +++ /dev/null @@ -1,67 +0,0 @@ -/* $FreeBSD$ */ -/* $NetBSD$ */ -/*- - * SPDX-License-Identifier: BSD-3-Clause - * - * [NetBSD for NEC PC98 series] - * Copyright (c) 1996 NetBSD/pc98 porting staff. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Copyright (c) 1996 Naofumi HONDA. All rights reserved. - */ - -#ifndef _COMPAT_NETBSD_DVCFG_H_ -#define _COMPAT_NETBSD_DVCFG_H_ - -typedef void *dvcfg_hw_t; - -struct dvcfg_hwsel { - int cfg_max; - - dvcfg_hw_t *cfg_sel; -}; - -#define DVCFG_MAJOR(dvcfg) (((u_int)(dvcfg)) >> 16) -#define DVCFG_MINOR(dvcfg) (((u_int)(dvcfg)) & 0xffff) - -#define DVCFG_MKCFG(major, minor) ((((u_int)(major)) << 16) | ((minor) & 0xffff)) - -#define DVCFG_HWSEL_SZ(array) (sizeof(array) / sizeof(dvcfg_hw_t)) - -static __inline dvcfg_hw_t dvcfg_hw(struct dvcfg_hwsel *, u_int); - -static __inline dvcfg_hw_t -dvcfg_hw(selp, num) - struct dvcfg_hwsel *selp; - u_int num; -{ - - return ((num >= selp->cfg_max) ? 0 : selp->cfg_sel[num]); -} - -#define DVCFG_HW(SELP, NUM) dvcfg_hw((SELP), (NUM)) -#endif /* _COMPAT_NETBSD_DVCFG_H_ */ From 1a18ab420b6098b92f3a16db68e482682a506688 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Tue, 11 Aug 2020 16:46:27 +0000 Subject: [PATCH 24/96] Allow overriding the tool used for stripping binaries Since the make variable STRIP is already used for other purposes, this uses STRIPBIN (which is also used for the same purpose by install(1). This allows using LLVM objcopy to strip binaries instead of the in-tree elftoolchain objcopy. We make use of this in CheriBSD since passing binaries generated by our toolchain to elftoolchain strip sometimes results in assertion failures. This allows working around https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=248516 by specifying STRIPBIN=/path/to/llvm-strip Obtained from: CheriBSD Reviewed By: emaste, brooks Differential Revision: https://reviews.freebsd.org/D25988 --- Makefile.inc1 | 4 ++-- share/mk/sys.mk | 1 + stand/i386/loader/Makefile | 2 +- sys/modules/linux/Makefile | 4 ++-- sys/modules/linux64/Makefile | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index 313adf85cb92..f85f0326da25 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -180,7 +180,7 @@ MK_SYSTEM_LINKER= no .if defined(CROSS_TOOLCHAIN_PREFIX) CROSS_BINUTILS_PREFIX?=${CROSS_TOOLCHAIN_PREFIX} .endif -XBINUTILS= AS AR LD NM OBJCOPY RANLIB SIZE STRINGS +XBINUTILS= AS AR LD NM OBJCOPY RANLIB SIZE STRINGS STRIPBIN .for BINUTIL in ${XBINUTILS} .if defined(CROSS_BINUTILS_PREFIX) && \ exists(${CROSS_BINUTILS_PREFIX}/${${BINUTIL}}) @@ -755,7 +755,7 @@ CROSSENV+= CC="${XCC} ${XCFLAGS}" CXX="${XCXX} ${XCXXFLAGS} ${XCFLAGS}" \ AS="${XAS}" AR="${XAR}" LD="${XLD}" LLVM_LINK="${XLLVM_LINK}" \ NM=${XNM} OBJCOPY="${XOBJCOPY}" \ RANLIB=${XRANLIB} STRINGS=${XSTRINGS} \ - SIZE="${XSIZE}" + SIZE="${XSIZE}" STRIPBIN="${XSTRIPBIN}" .if defined(CROSS_BINUTILS_PREFIX) && exists(${CROSS_BINUTILS_PREFIX}) # In the case of xdev-build tools, CROSS_BINUTILS_PREFIX won't be a diff --git a/share/mk/sys.mk b/share/mk/sys.mk index 2248d64f6580..215b04563e23 100644 --- a/share/mk/sys.mk +++ b/share/mk/sys.mk @@ -275,6 +275,7 @@ SHELL ?= sh .if !defined(%POSIX) SIZE ?= size +STRIPBIN ?= strip .endif YACC ?= yacc diff --git a/stand/i386/loader/Makefile b/stand/i386/loader/Makefile index b74ef9007d97..3c0357b7b7a7 100644 --- a/stand/i386/loader/Makefile +++ b/stand/i386/loader/Makefile @@ -64,7 +64,7 @@ ${LOADER}: ${LOADER}.bin ${BTXLDR} ${BTXKERN} -b ${BTXKERN} ${LOADER}.bin ${LOADER}.bin: ${LOADER}.sym - strip -R .comment -R .note -o ${.TARGET} ${.ALLSRC} + ${STRIPBIN} -R .comment -R .note -o ${.TARGET} ${.ALLSRC} .if ${MK_LOADER_ZFS} == "yes" && ${LOADER_INTERP} == ${LOADER_DEFAULT_INTERP} LINKS+= ${BINDIR}/${LOADER} ${BINDIR}/zfsloader diff --git a/sys/modules/linux/Makefile b/sys/modules/linux/Makefile index 7065c1f0f6cd..c91dfbdaf380 100644 --- a/sys/modules/linux/Makefile +++ b/sys/modules/linux/Makefile @@ -69,12 +69,12 @@ linux${SFX}_support.o: linux${SFX}_assym.h assym.inc ${VDSO}.so: linux${SFX}_locore.o ${OBJCOPY} --input-target binary --output-target elf64-x86-64-freebsd \ --binary-architecture i386 linux${SFX}_locore.o ${.TARGET} - strip -N _binary_linux${SFX}_locore_o_size ${.TARGET} + ${STRIPBIN} -N _binary_linux${SFX}_locore_o_size ${.TARGET} .else ${VDSO}.so: linux${SFX}_locore.o ${OBJCOPY} --input-target binary --output-target elf32-i386-freebsd \ --binary-architecture i386 linux${SFX}_locore.o ${.TARGET} - strip -N _binary_linux_locore_o_size ${.TARGET} + ${STRIPBIN} -N _binary_linux_locore_o_size ${.TARGET} .endif linux${SFX}_genassym.o: offset.inc diff --git a/sys/modules/linux64/Makefile b/sys/modules/linux64/Makefile index 046eeeda30f2..33dccc907709 100644 --- a/sys/modules/linux64/Makefile +++ b/sys/modules/linux64/Makefile @@ -46,7 +46,7 @@ OBJCOPY_TARGET=--output-target elf64-x86-64 --binary-architecture i386:x86-64 ${VDSO}.so: linux_locore.o ${OBJCOPY} --input-target binary ${OBJCOPY_TARGET} -S -g \ linux_locore.o ${.TARGET} - strip -N _binary_linux_locore_o_size ${.TARGET} + ${STRIPBIN} -N _binary_linux_locore_o_size ${.TARGET} linux_support.o: assym.inc linux_assym.h ${CC} -c -x assembler-with-cpp -DLOCORE ${CFLAGS} \ From 313232ddf95d018e0682b82c8f8f1479d5dab94a Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Tue, 11 Aug 2020 16:46:33 +0000 Subject: [PATCH 25/96] Fix bootstrapping ldd after r362152 r362152 started using DF_1_PIE, which is not present in older versions of sys/elf_common.h. To fix this include the ELF headers as part of -legacy. --- tools/build/Makefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/build/Makefile b/tools/build/Makefile index 73eeac3ee09a..599ddee21456 100644 --- a/tools/build/Makefile +++ b/tools/build/Makefile @@ -92,6 +92,12 @@ DISKINCS+= ${SRCTOP}/sys/sys/disk/bsd.h SYSINCS+= ${SRCTOP}/sys/sys/nv.h ${SRCTOP}/sys/sys/cnv.h \ ${SRCTOP}/sys/sys/dnv.h +# Needed when bootstrapping ldd (since it uses DF_1_PIE) +SYSINCS+= ${SRCTOP}/sys/sys/elf32.h +SYSINCS+= ${SRCTOP}/sys/sys/elf64.h +SYSINCS+= ${SRCTOP}/sys/sys/elf_common.h +SYSINCS+= ${SRCTOP}/sys/sys/elf_generic.h + # vtfontcvt is using sys/font.h SYSINCS+= ${SRCTOP}/sys/sys/font.h From b05fc77a36028619e670205f3860e64f10ed10a8 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Tue, 11 Aug 2020 16:46:38 +0000 Subject: [PATCH 26/96] Fix bootstrapping of pwd_mkdb after r364049 I moved the bootstrap pwd.h to a subdirectory in r364049 but forgot to adjust the #include path. --- usr.sbin/pwd_mkdb/bootstrap/pwd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/pwd_mkdb/bootstrap/pwd.h b/usr.sbin/pwd_mkdb/bootstrap/pwd.h index a3b595881e21..bc196e2c0fd0 100644 --- a/usr.sbin/pwd_mkdb/bootstrap/pwd.h +++ b/usr.sbin/pwd_mkdb/bootstrap/pwd.h @@ -60,7 +60,7 @@ typedef uint64_t _bootstrap_time_t; #define uid_t _bootstrap_uid_t #define time_t _bootstrap_time_t #define passwd _bootstrap_passwd -#include "../../include/pwd.h" +#include "../../../include/pwd.h" #undef gid_t #undef uid_t #undef time_t From 14267d398f875341144c3ad66a5bc690bd14b475 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Tue, 11 Aug 2020 16:46:43 +0000 Subject: [PATCH 27/96] Add CLANG/LLD/LLD to BROKEN_OPTIONS when building on non-FreeBSD These tools require a bootstrap llvm-tblgen/clang-tblgen and that cannot be built with the current make infrastructure: the config header is not correct for Linux/macOS and we don't include the CMakeLists.txt in contrib so we can't generate one that would be correct. Reviewed By: emaste, imp, dim Differential Revision: https://reviews.freebsd.org/D14245 --- share/mk/src.opts.mk | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk index e596f216c258..234b13205c67 100644 --- a/share/mk/src.opts.mk +++ b/share/mk/src.opts.mk @@ -365,6 +365,14 @@ __DEFAULT_YES_OPTIONS+=OPENMP __DEFAULT_NO_OPTIONS+=OPENMP .endif +.if ${.MAKE.OS} != "FreeBSD" +# Building the target compiler requires building tablegen on the host +# which is (currently) not possible on non-FreeBSD. +BROKEN_OPTIONS+=CLANG LLD LLDB +# The same also applies to the bootstrap LLVM. +BROKEN_OPTIONS+=CLANG_BOOTSTRAP LLD_BOOTSTRAP +.endif + .include # From f57b27e3f85b468033c3c91c7f2f2e90aa2e8a04 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Tue, 11 Aug 2020 16:46:48 +0000 Subject: [PATCH 28/96] Fix -DBUILD_WITH_STRICT_TMPPATH dtrace builds Some of the scripts used for libdtrace invoke nawk instead of awk (for example cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh). When bootstrapping all tools, we get the nawk -> awk link while building usr.bin/awk, but when linking/copying the dependencies from the host we were only adding awk but not nawk. This was silently generating invalid files when building libdtrace with BUILD_WITH_STRICT_TMPPATH=1 since those scripts invoke nawk instead of awk. In addition to adding the missing link this commit also adds set -e to those scripts to catch errors like this in the future. Reviewed By: markj, emaste Differential Revision: https://reviews.freebsd.org/D26025 --- Makefile.inc1 | 6 +++++- cddl/contrib/opensolaris/lib/libdtrace/common/mkerrno.sh | 1 + cddl/contrib/opensolaris/lib/libdtrace/common/mkerrtags.sh | 1 + cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh | 1 + cddl/contrib/opensolaris/lib/libdtrace/common/mksignal.sh | 1 + 5 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index f85f0326da25..9223123b1e1b 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -2240,9 +2240,13 @@ ${_bt}-usr.bin/mandoc: ${_bt}-lib/libopenbsd _basic_bootstrap_tools_multilink=usr.bin/grep grep,egrep,fgrep _basic_bootstrap_tools_multilink+=bin/test test,[ # bootstrap tools needed by buildworld: -_basic_bootstrap_tools=usr.bin/awk usr.bin/cut bin/expr usr.bin/gencat \ +_basic_bootstrap_tools=usr.bin/cut bin/expr usr.bin/gencat \ usr.bin/join usr.bin/mktemp bin/rmdir usr.bin/sed usr.bin/sort \ usr.bin/truncate usr.bin/tsort +# Some build scripts use nawk instead of awk (this happens at least in +# cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh) so we need both awk +# and nawk in ${WORLDTMP}/legacy/bin. +_basic_bootstrap_tools_multilink+=usr.bin/awk awk,nawk # file2c is required for building usr.sbin/config: _basic_bootstrap_tools+=usr.bin/file2c # uuencode/uudecode required for share/tabset diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrno.sh b/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrno.sh index 50b7f1c1b908..c9fb9e04fe00 100755 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrno.sh +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrno.sh @@ -25,6 +25,7 @@ # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" +set -e echo "\ /*\n\ diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrtags.sh b/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrtags.sh index d5651ff727fc..cc3ef3cc9617 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrtags.sh +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrtags.sh @@ -25,6 +25,7 @@ # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" +set -e BSDECHO=-e diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh b/cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh index 2fdc2fa636d5..5bb47cb1781f 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh @@ -25,6 +25,7 @@ # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" +set -e BSDECHO=-e diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/mksignal.sh b/cddl/contrib/opensolaris/lib/libdtrace/common/mksignal.sh index 1bffa6468c2b..dce06a0e1797 100755 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/mksignal.sh +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/mksignal.sh @@ -25,6 +25,7 @@ # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" +set -e echo "\ /*\n\ From fded98749a40d1adcdff10bceba9de6cf90b3097 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Tue, 11 Aug 2020 16:46:54 +0000 Subject: [PATCH 29/96] Fix libdtrace build with zsh as /bin/sh When zsh runs in POSIX sh mode it does not support the -e flag to echo. Use printf instead of echo to avoid the "-e" characters being printed. Obtained from: CheriBSD Reviewed By: markj Differential Revision: https://reviews.freebsd.org/D26026 --- .../lib/libdtrace/common/mkerrno.sh | 15 ++++---- .../lib/libdtrace/common/mkerrtags.sh | 33 ++++++++--------- .../lib/libdtrace/common/mknames.sh | 37 +++++++++---------- .../lib/libdtrace/common/mksignal.sh | 15 ++++---- 4 files changed, 46 insertions(+), 54 deletions(-) diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrno.sh b/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrno.sh index c9fb9e04fe00..de4b86270efa 100755 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrno.sh +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrno.sh @@ -24,16 +24,15 @@ # Copyright 2003 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -#ident "%Z%%M% %I% %E% SMI" set -e -echo "\ -/*\n\ - * Copyright 2003 Sun Microsystems, Inc. All rights reserved.\n\ - * Use is subject to license terms.\n\ - */\n\ -\n\ -#pragma ident\t\"%Z%%M%\t%I%\t%E% SMI\"\n" +printf "%s" " +/* + * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +" pattern='^#define[ ]\(E[A-Z0-9]*\)[ ]*\([A-Z0-9]*\).*$' replace='inline int \1 = \2;@#pragma D binding "1.0" \1' diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrtags.sh b/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrtags.sh index cc3ef3cc9617..11b327cbff17 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrtags.sh +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/mkerrtags.sh @@ -24,37 +24,34 @@ # Copyright 2003 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -#ident "%Z%%M% %I% %E% SMI" set -e -BSDECHO=-e +printf "%s" " +/* + * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ -echo ${BSDECHO} "\ -/*\n\ - * Copyright 2003 Sun Microsystems, Inc. All rights reserved.\n\ - * Use is subject to license terms.\n\ - */\n\ -\n\ -#pragma ident\t\"%Z%%M%\t%I%\t%E% SMI\"\n\ -\n\ #include -\n\ -static const char *const _dt_errtags[] = {" + +static const char *const _dt_errtags[] = { +" pattern='^ \(D_[A-Z0-9_]*\),*' replace=' "\1",' sed -n "s/$pattern/$replace/p" || exit 1 -echo ${BSDECHO} "\ -};\n\ -\n\ -static const int _dt_ntag = sizeof (_dt_errtags) / sizeof (_dt_errtags[0]);\n\ -\n\ +printf "%s" " +}; + +static const int _dt_ntag = sizeof (_dt_errtags) / sizeof (_dt_errtags[0]); + const char * dt_errtag(dt_errtag_t tag) { return (_dt_errtags[(tag > 0 && tag < _dt_ntag) ? tag : 0]); -}" +} +" exit 0 diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh b/cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh index 5bb47cb1781f..c7c28e75364e 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/mknames.sh @@ -24,33 +24,30 @@ # Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -#ident "%Z%%M% %I% %E% SMI" set -e -BSDECHO=-e +printf "%s" " +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include -echo ${BSDECHO} "\ -/*\n\ - * Copyright 2005 Sun Microsystems, Inc. All rights reserved.\n\ - * Use is subject to license terms.\n\ - */\n\ -\n\ -#pragma ident\t\"%Z%%M%\t%I%\t%E% SMI\"\n\ -\n\ -#include \n\ -\n\ /*ARGSUSED*/ -const char *\n\ -dtrace_subrstr(dtrace_hdl_t *dtp, int subr)\n\ -{\n\ - switch (subr) {" +const char * +dtrace_subrstr(dtrace_hdl_t *dtp, int subr) +{ + switch (subr) { +" nawk ' /^#define[ ]*DIF_SUBR_/ && $2 != "DIF_SUBR_MAX" { printf("\tcase %s: return (\"%s\");\n", $2, tolower(substr($2, 10))); }' -echo ${BSDECHO} "\ - default: return (\"unknown\");\n\ - }\n\ -}" +printf "%s" " + default: return (\"unknown\"); + } +} +" diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/mksignal.sh b/cddl/contrib/opensolaris/lib/libdtrace/common/mksignal.sh index dce06a0e1797..2bd5ec92b43e 100755 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/mksignal.sh +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/mksignal.sh @@ -24,16 +24,15 @@ # Copyright 2003 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -#ident "%Z%%M% %I% %E% SMI" set -e -echo "\ -/*\n\ - * Copyright 2003 Sun Microsystems, Inc. All rights reserved.\n\ - * Use is subject to license terms.\n\ - */\n\ -\n\ -#pragma ident\t\"%Z%%M%\t%I%\t%E% SMI\"\n" +printf "%s" " +/* + * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +" pattern='^#define[ ]*_*\(SIG[A-Z0-9]*\)[ ]\{1,\}\([A-Z0-9]*\).*$' replace='inline int \1 = \2;@#pragma D binding "1.0" \1' From 91b31c100b5eb30c59f2f78dd10922e7e0b2c6e2 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Tue, 11 Aug 2020 16:47:00 +0000 Subject: [PATCH 30/96] Allow linking the kernel with a linker that doesn't support -z ifunc-noplt This can happen when linking with upstream LLD < 9.0. Reviewed By: markj Differential Revision: https://reviews.freebsd.org/D25985 --- share/mk/bsd.linker.mk | 3 +++ sys/conf/kern.pre.mk | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/share/mk/bsd.linker.mk b/share/mk/bsd.linker.mk index 1a2339390990..5ecd6b8b969c 100644 --- a/share/mk/bsd.linker.mk +++ b/share/mk/bsd.linker.mk @@ -94,6 +94,9 @@ ${X_}LINKER_FEATURES+= riscv-relaxations .if ${${X_}LINKER_TYPE} == "lld" && ${${X_}LINKER_VERSION} >= 60000 ${X_}LINKER_FEATURES+= retpoline .endif +.if ${${X_}LINKER_TYPE} == "lld" && ${${X_}LINKER_VERSION} >= 90000 +${X_}LINKER_FEATURES+= ifunc-noplt +.endif .endif .else # Use LD's values diff --git a/sys/conf/kern.pre.mk b/sys/conf/kern.pre.mk index 2436269c893c..16910042af8b 100644 --- a/sys/conf/kern.pre.mk +++ b/sys/conf/kern.pre.mk @@ -166,9 +166,13 @@ LDFLAGS+= -z max-page-size=2097152 .if ${LINKER_TYPE} != "lld" LDFLAGS+= -z common-page-size=4096 .else +.if defined(LINKER_FEATURES) && !${LINKER_FEATURES:Mifunc-noplt} +.warning "Linker ${LD} does not support -z ifunc-noplt -> ifunc calls are unoptimized." +.else LDFLAGS+= -z notext -z ifunc-noplt .endif .endif +.endif # ${MACHINE_CPUARCH} == "amd64" .if ${MACHINE_CPUARCH} == "riscv" # Hack: Work around undefined weak symbols being out of range when linking with From 0292c54bdb080ea25c56db45b6c5557769e55ad8 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Tue, 11 Aug 2020 20:37:45 +0000 Subject: [PATCH 31/96] Add support for multithreading the inactive queue pageout within a domain. In very high throughput workloads, the inactive scan can become overwhelmed as you have many cores producing pages and a single core freeing. Since Mark's introduction of batched pagequeue operations, we can now run multiple inactive threads working on independent batches. To avoid confusing the pid and other control algorithms, I (Jeff) do this in a mpi-like fan out and collect model that is driven from the primary page daemon. It decides whether the shortfall can be overcome with a single thread and if not dispatches multiple threads and waits for their results. The heuristic is based on timing the pageout activity and averaging a pages-per-second variable which is exponentially decayed. This is visible in sysctl and may be interesting for other purposes. I (Jeff) have verified that this does indeed double our paging throughput when used with two threads. With four we tend to run into other contention problems. For now I would like to commit this infrastructure with only a single thread enabled. The number of worker threads per domain can be controlled with the 'vm.pageout_threads_per_domain' tunable. Submitted by: jeff (earlier version) Discussed with: markj Tested by: pho Sponsored by: probably Netflix (based on contemporary commits) Differential Revision: https://reviews.freebsd.org/D21629 --- sys/vm/vm_meter.c | 3 + sys/vm/vm_page.c | 4 +- sys/vm/vm_page.h | 1 + sys/vm/vm_pageout.c | 214 +++++++++++++++++++++++++++++++++++++----- sys/vm/vm_pagequeue.h | 9 ++ 5 files changed, 204 insertions(+), 27 deletions(-) diff --git a/sys/vm/vm_meter.c b/sys/vm/vm_meter.c index e316dd5cae0d..d7d4d8986f15 100644 --- a/sys/vm/vm_meter.c +++ b/sys/vm/vm_meter.c @@ -552,6 +552,9 @@ vm_domain_stats_init(struct vm_domain *vmd, struct sysctl_oid *parent) SYSCTL_ADD_UINT(NULL, SYSCTL_CHILDREN(oid), OID_AUTO, "free_severe", CTLFLAG_RD, &vmd->vmd_free_severe, 0, "Severe free pages"); + SYSCTL_ADD_UINT(NULL, SYSCTL_CHILDREN(oid), OID_AUTO, + "inactive_pps", CTLFLAG_RD, &vmd->vmd_inactive_pps, 0, + "inactive pages freed/second"); } diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 593af4b5a2e4..036d0075ca7e 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -421,7 +421,7 @@ sysctl_vm_page_blacklist(SYSCTL_HANDLER_ARGS) * In principle, this function only needs to set the flag PG_MARKER. * Nonetheless, it write busies the page as a safety precaution. */ -static void +void vm_page_init_marker(vm_page_t marker, int queue, uint16_t aflags) { @@ -2488,7 +2488,7 @@ vm_page_zone_import(void *arg, void **store, int cnt, int domain, int flags) * main purpose is to replenish the store of free pages. */ if (vmd->vmd_severeset || curproc == pageproc || - !_vm_domain_allocate(vmd, VM_ALLOC_NORMAL, cnt)) + !_vm_domain_allocate(vmd, VM_ALLOC_SYSTEM, cnt)) return (0); domain = vmd->vmd_domain; vm_domain_free_lock(vmd); diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h index 039e467491d0..a44e31f506d0 100644 --- a/sys/vm/vm_page.h +++ b/sys/vm/vm_page.h @@ -630,6 +630,7 @@ vm_page_t vm_page_find_least(vm_object_t, vm_pindex_t); void vm_page_free_invalid(vm_page_t); vm_page_t vm_page_getfake(vm_paddr_t paddr, vm_memattr_t memattr); void vm_page_initfake(vm_page_t m, vm_paddr_t paddr, vm_memattr_t memattr); +void vm_page_init_marker(vm_page_t marker, int queue, uint16_t aflags); int vm_page_insert (vm_page_t, vm_object_t, vm_pindex_t); void vm_page_invalid(vm_page_t m); void vm_page_launder(vm_page_t m); diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index db2aa5f1c1cf..286528905eaa 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -82,6 +82,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -163,6 +164,12 @@ SYSCTL_INT(_vm, OID_AUTO, panic_on_oom, SYSCTL_INT(_vm, OID_AUTO, pageout_update_period, CTLFLAG_RWTUN, &vm_pageout_update_period, 0, "Maximum active LRU update period"); + +/* Access with get_pageout_threads_per_domain(). */ +static int pageout_threads_per_domain = 1; +SYSCTL_INT(_vm, OID_AUTO, pageout_threads_per_domain, CTLFLAG_RDTUN, + &pageout_threads_per_domain, 0, + "Number of worker threads comprising each per-domain pagedaemon"); SYSCTL_INT(_vm, OID_AUTO, lowmem_period, CTLFLAG_RWTUN, &lowmem_period, 0, "Low memory callback period"); @@ -1414,22 +1421,22 @@ vm_pageout_reinsert_inactive(struct scan_state *ss, struct vm_batchqueue *bq, vm_batchqueue_init(bq); } -/* - * Attempt to reclaim the requested number of pages from the inactive queue. - * Returns true if the shortage was addressed. - */ -static int -vm_pageout_scan_inactive(struct vm_domain *vmd, int shortage, - int *addl_shortage) +static void +vm_pageout_scan_inactive(struct vm_domain *vmd, int page_shortage) { + struct timeval start, end; struct scan_state ss; struct vm_batchqueue rq; + struct vm_page marker_page; vm_page_t m, marker; struct vm_pagequeue *pq; vm_object_t object; vm_page_astate_t old, new; - int act_delta, addl_page_shortage, deficit, page_shortage, refs; - int starting_page_shortage; + int act_delta, addl_page_shortage, starting_page_shortage, refs; + + object = NULL; + vm_batchqueue_init(&rq); + getmicrouptime(&start); /* * The addl_page_shortage is an estimate of the number of temporarily @@ -1439,25 +1446,15 @@ vm_pageout_scan_inactive(struct vm_domain *vmd, int shortage, */ addl_page_shortage = 0; - /* - * vmd_pageout_deficit counts the number of pages requested in - * allocations that failed because of a free page shortage. We assume - * that the allocations will be reattempted and thus include the deficit - * in our scan target. - */ - deficit = atomic_readandclear_int(&vmd->vmd_pageout_deficit); - starting_page_shortage = page_shortage = shortage + deficit; - - object = NULL; - vm_batchqueue_init(&rq); - /* * Start scanning the inactive queue for pages that we can free. The * scan will stop when we reach the target or we have scanned the * entire queue. (Note that m->a.act_count is not used to make * decisions for the inactive queue, only for the active queue.) */ - marker = &vmd->vmd_markers[PQ_INACTIVE]; + starting_page_shortage = page_shortage; + marker = &marker_page; + vm_page_init_marker(marker, PQ_INACTIVE, 0); pq = &vmd->vmd_pagequeues[PQ_INACTIVE]; vm_pagequeue_lock(pq); vm_pageout_init_scan(&ss, pq, marker, NULL, pq->pq_cnt); @@ -1637,7 +1634,97 @@ vm_pageout_scan_inactive(struct vm_domain *vmd, int shortage, vm_pageout_end_scan(&ss); vm_pagequeue_unlock(pq); - VM_CNT_ADD(v_dfree, starting_page_shortage - page_shortage); + /* + * Record the remaining shortage and the progress and rate it was made. + */ + atomic_add_int(&vmd->vmd_addl_shortage, addl_page_shortage); + getmicrouptime(&end); + timevalsub(&end, &start); + atomic_add_int(&vmd->vmd_inactive_us, + end.tv_sec * 1000000 + end.tv_usec); + atomic_add_int(&vmd->vmd_inactive_freed, + starting_page_shortage - page_shortage); +} + +/* + * Dispatch a number of inactive threads according to load and collect the + * results to prevent a coherent (CEM: incoherent?) view of paging activity on + * this domain. + */ +static int +vm_pageout_inactive_dispatch(struct vm_domain *vmd, int shortage) +{ + u_int freed, pps, threads, us; + + vmd->vmd_inactive_shortage = shortage; + + /* + * If we have more work than we can do in a quarter of our interval, we + * fire off multiple threads to process it. + */ + if (vmd->vmd_inactive_threads > 1 && vmd->vmd_inactive_pps != 0 && + shortage > vmd->vmd_inactive_pps / VM_INACT_SCAN_RATE / 4) { + threads = vmd->vmd_inactive_threads; + vm_domain_pageout_lock(vmd); + vmd->vmd_inactive_shortage /= threads; + blockcount_acquire(&vmd->vmd_inactive_starting, threads - 1); + blockcount_acquire(&vmd->vmd_inactive_running, threads - 1); + wakeup(&vmd->vmd_inactive_shortage); + vm_domain_pageout_unlock(vmd); + } + + /* Run the local thread scan. */ + vm_pageout_scan_inactive(vmd, vmd->vmd_inactive_shortage); + + /* + * Block until helper threads report results and then accumulate + * totals. + */ + blockcount_wait(&vmd->vmd_inactive_running, NULL, "vmpoid", PVM); + freed = atomic_readandclear_int(&vmd->vmd_inactive_freed); + VM_CNT_ADD(v_dfree, freed); + + /* + * Calculate the per-thread paging rate with an exponential decay of + * prior results. Careful to avoid integer rounding errors with large + * us values. + */ + us = max(atomic_readandclear_int(&vmd->vmd_inactive_us), 1); + if (us > 1000000) + /* Keep rounding to tenths */ + pps = (freed * 10) / ((us * 10) / 1000000); + else + pps = (1000000 / us) * freed; + vmd->vmd_inactive_pps = (vmd->vmd_inactive_pps / 2) + (pps / 2); + + return (shortage - freed); +} + +/* + * Attempt to reclaim the requested number of pages from the inactive queue. + * Returns true if the shortage was addressed. + */ +static int +vm_pageout_inactive(struct vm_domain *vmd, int shortage, int *addl_shortage) +{ + struct vm_pagequeue *pq; + u_int addl_page_shortage, deficit, page_shortage; + u_int starting_page_shortage; + + /* + * vmd_pageout_deficit counts the number of pages requested in + * allocations that failed because of a free page shortage. We assume + * that the allocations will be reattempted and thus include the deficit + * in our scan target. + */ + deficit = atomic_readandclear_int(&vmd->vmd_pageout_deficit); + starting_page_shortage = shortage + deficit; + + /* + * Run the inactive scan on as many threads as is necessary. + */ + page_shortage = vm_pageout_inactive_dispatch(vmd, starting_page_shortage); + addl_page_shortage = atomic_readandclear_int(&vmd->vmd_addl_shortage); /* * Wake up the laundry thread so that it can perform any needed @@ -2066,7 +2153,7 @@ vm_pageout_worker(void *arg) if (vm_pageout_lowmem() && vmd->vmd_free_count > ofree) shortage -= min(vmd->vmd_free_count - ofree, (u_int)shortage); - target_met = vm_pageout_scan_inactive(vmd, shortage, + target_met = vm_pageout_inactive(vmd, shortage, &addl_shortage); } else addl_shortage = 0; @@ -2081,6 +2168,72 @@ vm_pageout_worker(void *arg) } } +/* + * vm_pageout_helper runs additional pageout daemons in times of high paging + * activity. + */ +static void +vm_pageout_helper(void *arg) +{ + struct vm_domain *vmd; + int domain; + + domain = (uintptr_t)arg; + vmd = VM_DOMAIN(domain); + + vm_domain_pageout_lock(vmd); + for (;;) { + msleep(&vmd->vmd_inactive_shortage, + vm_domain_pageout_lockptr(vmd), PVM, "psleep", 0); + blockcount_release(&vmd->vmd_inactive_starting, 1); + + vm_domain_pageout_unlock(vmd); + vm_pageout_scan_inactive(vmd, vmd->vmd_inactive_shortage); + vm_domain_pageout_lock(vmd); + + /* + * Release the running count while the pageout lock is held to + * prevent wakeup races. + */ + blockcount_release(&vmd->vmd_inactive_running, 1); + } +} + +static int +get_pageout_threads_per_domain(void) +{ + static bool resolved = false; + int half_cpus_per_dom; + + /* + * This is serialized externally by the sorted autoconfig portion of + * boot. + */ + if (__predict_true(resolved)) + return (pageout_threads_per_domain); + + /* + * Semi-arbitrarily constrain pagedaemon threads to less than half the + * total number of threads in the system as an insane upper limit. + */ + half_cpus_per_dom = (mp_ncpus / vm_ndomains) / 2; + + if (pageout_threads_per_domain < 1) { + printf("Invalid tuneable vm.pageout_threads_per_domain value: " + "%d out of valid range: [1-%d]; clamping to 1\n", + pageout_threads_per_domain, half_cpus_per_dom); + pageout_threads_per_domain = 1; + } else if (pageout_threads_per_domain > half_cpus_per_dom) { + printf("Invalid tuneable vm.pageout_threads_per_domain value: " + "%d out of valid range: [1-%d]; clamping to %d\n", + pageout_threads_per_domain, half_cpus_per_dom, + half_cpus_per_dom); + pageout_threads_per_domain = half_cpus_per_dom; + } + resolved = true; + return (pageout_threads_per_domain); +} + /* * Initialize basic pageout daemon settings. See the comment above the * definition of vm_domain for some explanation of how these thresholds are @@ -2134,6 +2287,8 @@ vm_pageout_init_domain(int domain) oid = SYSCTL_ADD_NODE(NULL, SYSCTL_CHILDREN(vmd->vmd_oid), OID_AUTO, "pidctrl", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, ""); pidctrl_init_sysctl(&vmd->vmd_pid, SYSCTL_CHILDREN(oid)); + + vmd->vmd_inactive_threads = get_pageout_threads_per_domain(); } static void @@ -2184,10 +2339,11 @@ vm_pageout(void) { struct proc *p; struct thread *td; - int error, first, i; + int error, first, i, j, pageout_threads; p = curproc; td = curthread; + pageout_threads = get_pageout_threads_per_domain(); mtx_init(&vm_oom_ratelim_mtx, "vmoomr", NULL, MTX_DEF); swap_pager_swap_init(); @@ -2207,6 +2363,14 @@ vm_pageout(void) panic("starting pageout for domain %d: %d\n", i, error); } + for (j = 0; j < pageout_threads - 1; j++) { + error = kthread_add(vm_pageout_helper, + (void *)(uintptr_t)i, p, NULL, 0, 0, + "dom%d helper%d", i, j); + if (error != 0) + panic("starting pageout helper %d for domain " + "%d: %d\n", j, i, error); + } error = kthread_add(vm_pageout_laundry_worker, (void *)(uintptr_t)i, p, NULL, 0, 0, "laundry: dom%d", i); if (error != 0) diff --git a/sys/vm/vm_pagequeue.h b/sys/vm/vm_pagequeue.h index 0573457db675..0e5d1c911b8d 100644 --- a/sys/vm/vm_pagequeue.h +++ b/sys/vm/vm_pagequeue.h @@ -84,6 +84,7 @@ struct vm_batchqueue { } __aligned(CACHE_LINE_SIZE); #include +#include #include struct sysctl_oid; @@ -254,6 +255,14 @@ struct vm_domain { /* Paging control variables, used within single threaded page daemon. */ struct pidctrl vmd_pid; /* Pageout controller. */ boolean_t vmd_oom; + u_int vmd_inactive_threads; + u_int vmd_inactive_shortage; /* Per-thread shortage. */ + blockcount_t vmd_inactive_running; /* Number of inactive threads. */ + blockcount_t vmd_inactive_starting; /* Number of threads started. */ + volatile u_int vmd_addl_shortage; /* Shortage accumulator. */ + volatile u_int vmd_inactive_freed; /* Successful inactive frees. */ + volatile u_int vmd_inactive_us; /* Microseconds for above. */ + u_int vmd_inactive_pps; /* Exponential decay frees/second. */ int vmd_oom_seq; int vmd_last_active_scan; struct vm_page vmd_markers[PQ_COUNT]; /* (q) markers for queue scans */ From 6eecc07f65f3a6ed5d87880d89c0b5e750c984f2 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Tue, 11 Aug 2020 20:42:21 +0000 Subject: [PATCH 32/96] smp.h: Reconcile definition and declaration of smp_ncpus The variable is defined unconditionally; declare it unconditionally as well. It is already initialized to the correct value (1) for !SMP builds. No functional change. --- sys/sys/smp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/sys/smp.h b/sys/sys/smp.h index a7ca84e92bc7..a971ffbbd91b 100644 --- a/sys/sys/smp.h +++ b/sys/sys/smp.h @@ -154,7 +154,6 @@ struct cpu_group *smp_topo_2level(int l2share, int l2count, int l1share, struct cpu_group *smp_topo_find(struct cpu_group *top, int cpu); extern void (*cpustop_restartfunc)(void); -extern int smp_cpus; /* The suspend/resume cpusets are x86 only, but minimize ifdefs. */ extern volatile cpuset_t resuming_cpus; /* woken up cpus in suspend pen */ extern volatile cpuset_t started_cpus; /* cpus to let out of stop pen */ @@ -169,6 +168,7 @@ extern u_int mp_maxid; extern int mp_maxcpus; extern int mp_ncores; extern int mp_ncpus; +extern int smp_cpus; extern volatile int smp_started; extern int smp_threads_per_core; From 48bd73d9f5516b746332681f7686aa58d447e9c8 Mon Sep 17 00:00:00 2001 From: Gordon Bergling Date: Tue, 11 Aug 2020 21:44:43 +0000 Subject: [PATCH 33/96] tput(1): Several enhancements for the manual page - a couple of descriptions are incomplete - synopsis doesn't show that all arguments are optional - missing an ENVIRONMENT section with TERM mentioned PR: 84670 Submitted by: Gary W. Swearingen Reviewed by: bcr Approved by: bcr MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D26009 --- usr.bin/tput/tput.1 | 63 +++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/usr.bin/tput/tput.1 b/usr.bin/tput/tput.1 index ad91f7d38106..996575bb622e 100644 --- a/usr.bin/tput/tput.1 +++ b/usr.bin/tput/tput.1 @@ -38,22 +38,24 @@ .Sh SYNOPSIS .Nm .Op Fl T Ar term -.Ar attribute ... +.Op Ar attribute ... .Nm clear .Sh DESCRIPTION The .Nm utility makes terminal-dependent information available to users or shell applications. -When invoked as the +.Pp +The .Nm clear -utility, the screen will be cleared as if +utility executes the .Dl tput clear -had been executed. -The options to +command, ignoring any arguments. +.Pp +The only option to .Nm -are as follows: -.Bl -tag -width Ds +is: +.Bl -tag -width 2n .It Fl T The terminal name as specified in the .Xr termcap 5 @@ -65,7 +67,9 @@ If not specified, .Nm retrieves the .Dq Ev TERM -variable from the environment. +variable from the environment unless that too is not specified, +in which case an error message will be sent to standard error and +the error status will be 2. .El .Pp The @@ -83,28 +87,37 @@ If an is of type string, and takes arguments (e.g.\& cursor movement, the termcap .Dq cm -sequence) the arguments are taken from the command line immediately +capability) the arguments are taken from the command line immediately following the attribute. .Pp -The following special attributes are available: +The following special attributes are available. +The first three use the capabilities of the specified terminal, +and only work if compatible with the utility's terminal. .Bl -tag -width Ar .It Cm clear Clear the screen (the .Xr termcap 5 .Dq cl -sequence). +capability). .It Cm init Initialize the terminal (the .Xr termcap 5 .Dq is -sequence). -.It Cm longname -Print the descriptive name of the user's terminal type. +capability). .It Cm reset Reset the terminal (the .Xr termcap 5 .Dq rs -sequence). +capability). +.It Cm longname +Print the descriptive name of the user's terminal type. +.El +.Sh ENVIRONMENT +.Bl -tag -width ".Ev TERM" +.It Ev TERM +The terminal name, if set and +.Fl T +is not used. .El .Sh EXIT STATUS The exit status of @@ -112,16 +125,28 @@ The exit status of is as follows: .Bl -tag -width indent .It 0 -If the last attribute +If the last .Ar attribute -argument is of type string or integer, its value was successfully written +is of type string or integer, its value was successfully written to standard output. -If the argument is of type boolean, the terminal has this attribute. +If the +.Ar attribute +is of type boolean, the terminal does have the +.Ar attribute . +Otherwise, no +.Ar attribute +was specified. .It 1 -This terminal does not have the specified boolean +If the last +.Ar attribute +is of type boolean, +this terminal does not have the .Ar attribute . .It 2 Usage error. +For example, see +.Fl T +description. .It 3 No information is available about the specified terminal type. .El From af593945362018207d01cd91668a2f4f5fe6712d Mon Sep 17 00:00:00 2001 From: John-Mark Gurney Date: Tue, 11 Aug 2020 22:33:56 +0000 Subject: [PATCH 34/96] since kld_deb.py was removed a while back, this script isn't useful anymore... --- tools/debugscripts/kgdb | 67 ----------------------------------------- 1 file changed, 67 deletions(-) delete mode 100644 tools/debugscripts/kgdb diff --git a/tools/debugscripts/kgdb b/tools/debugscripts/kgdb deleted file mode 100644 index ae580b301d41..000000000000 --- a/tools/debugscripts/kgdb +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/sh - -# -# Copyright 2004 John-Mark Gurney -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# $FreeBSD$ - -crashpath="/var/crash" -kld_debpy="kld_deb.py" - -if [ x"$1" = x"-?" -o x"$1" = x"-h" ]; then - echo "Usage: $0 [ [ ] ]" - echo "" - echo "Path for crash dumps: $crashpath" - exit 1 -fi - -if [ x"$1" = x"" ]; then - echo "Need core number." - exit 1 -fi -corenum="$1" -shift - -cmd_file="" -if [ x"$2" != x"" ]; then - cmd_file="-x $2" - shift -fi - -core="$crashpath/vmcore.$corenum" -info="$crashpath/info.$corenum" - -#Get the kernel source compile dir from the info file -kernsrc="`awk 'i == 1 { split($0, a, ":"); print a[2]; i = 0 } $1 == "Versionstring:" { i = 1 }' < "$info"`" - -tmpfile="/tmp/kgdb.asf.$$" -# -mapped (broken?) -# -x command_file -echo "Kernel Source: $kernsrc" -echo "Getting KLD information and locations..." -python $kld_debpy "$kernsrc" "$core" $@ > "$tmpfile" && -echo "Please run the following command to load module symbols:" -echo "source $tmpfile" -(cd "$kernsrc"; kgdb "$kernsrc/kernel.debug" "$core") -rm "$tmpfile" From 51da4b19be15e6c1862e40565d7a3b310c566679 Mon Sep 17 00:00:00 2001 From: Cy Schubert Date: Tue, 11 Aug 2020 23:36:38 +0000 Subject: [PATCH 35/96] When booting a system with WITHOUT_IPFILTER the following errors are encountered at boot time: rcorder: requirement `ipfs' in file `/etc/rc.d/netif' has no providers. rcorder: requirement `ipfilter' in file `/etc/rc.d/netif' has no providers. rcorder: requirement `ipfilter' in file `/etc/rc.d/netwait' has no providers. rcorder: requirement `ipfilter' in file `/etc/rc.d/net_watchdog' has no providers. rcorder: requirement `ipfilter' in file `/etc/rc.d/securelevel' has no providers. Listing its own requrements in BEFORE rather than use REQUIRE of non-optional scripts resolves this issue. The issue was discovered and patched by glebius at Netflix. Submitted by: glebius Reported by: glebius MFC after: 1 week --- libexec/rc/rc.d/ipfilter | 1 + libexec/rc/rc.d/ipmon | 2 +- libexec/rc/rc.d/ipnat | 1 - libexec/rc/rc.d/netif | 2 +- libexec/rc/rc.d/netwait | 2 +- libexec/rc/rc.d/securelevel | 2 +- 6 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libexec/rc/rc.d/ipfilter b/libexec/rc/rc.d/ipfilter index 6a430b55d897..fe328308e622 100755 --- a/libexec/rc/rc.d/ipfilter +++ b/libexec/rc/rc.d/ipfilter @@ -5,6 +5,7 @@ # PROVIDE: ipfilter # REQUIRE: FILESYSTEMS +# BEFORE: ipmon ipnat netif netwait securelevel # KEYWORD: nojailvnet . /etc/rc.subr diff --git a/libexec/rc/rc.d/ipmon b/libexec/rc/rc.d/ipmon index a742daa363d5..56b64f8c8271 100755 --- a/libexec/rc/rc.d/ipmon +++ b/libexec/rc/rc.d/ipmon @@ -4,7 +4,7 @@ # # PROVIDE: ipmon -# REQUIRE: FILESYSTEMS hostname sysctl ipfilter +# REQUIRE: FILESYSTEMS hostname sysctl # BEFORE: SERVERS # KEYWORD: nojailvnet diff --git a/libexec/rc/rc.d/ipnat b/libexec/rc/rc.d/ipnat index bff94154dc65..d4fa6b65dff4 100755 --- a/libexec/rc/rc.d/ipnat +++ b/libexec/rc/rc.d/ipnat @@ -4,7 +4,6 @@ # # PROVIDE: ipnat -# REQUIRE: ipfilter # KEYWORD: nojailvnet . /etc/rc.subr diff --git a/libexec/rc/rc.d/netif b/libexec/rc/rc.d/netif index a1543e63e704..eb1efc4d6274 100755 --- a/libexec/rc/rc.d/netif +++ b/libexec/rc/rc.d/netif @@ -27,7 +27,7 @@ # PROVIDE: netif # REQUIRE: FILESYSTEMS iovctl serial sppp sysctl -# REQUIRE: hostid ipfilter ipfs +# REQUIRE: hostid ipfs # KEYWORD: nojailvnet . /etc/rc.subr diff --git a/libexec/rc/rc.d/netwait b/libexec/rc/rc.d/netwait index ab80cec50576..92f124cd4f27 100755 --- a/libexec/rc/rc.d/netwait +++ b/libexec/rc/rc.d/netwait @@ -3,7 +3,7 @@ # $FreeBSD$ # # PROVIDE: netwait -# REQUIRE: devd ipfilter ipfw pf routing +# REQUIRE: devd ipfw pf routing # KEYWORD: nojail # # The netwait script helps handle two situations: diff --git a/libexec/rc/rc.d/securelevel b/libexec/rc/rc.d/securelevel index c42a03534675..24dbf269df3f 100755 --- a/libexec/rc/rc.d/securelevel +++ b/libexec/rc/rc.d/securelevel @@ -4,7 +4,7 @@ # # PROVIDE: securelevel -# REQUIRE: adjkerntz ipfw ipfilter pf +# REQUIRE: adjkerntz ipfw pf . /etc/rc.subr From b7883452d4704354bf52f0b03aedd719421308f7 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Wed, 12 Aug 2020 00:21:30 +0000 Subject: [PATCH 36/96] Back out unrelated change Reported by: kib, markj X-MFC-With: r364129 --- sys/vm/vm_page.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 036d0075ca7e..1e6a392d862c 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -2488,7 +2488,7 @@ vm_page_zone_import(void *arg, void **store, int cnt, int domain, int flags) * main purpose is to replenish the store of free pages. */ if (vmd->vmd_severeset || curproc == pageproc || - !_vm_domain_allocate(vmd, VM_ALLOC_SYSTEM, cnt)) + !_vm_domain_allocate(vmd, VM_ALLOC_NORMAL, cnt)) return (0); domain = vmd->vmd_domain; vm_domain_free_lock(vmd); From 0ac9e27ba964b4d29ed180d5e546873de638822c Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Wed, 12 Aug 2020 00:32:31 +0000 Subject: [PATCH 37/96] devfs: Abstract locking assertions The conversion was largely mechanical: sed(1) with: -e 's|mtx_assert(&devmtx, MA_OWNED)|dev_lock_assert_locked()|g' -e 's|mtx_assert(&devmtx, MA_NOTOWNED)|dev_lock_assert_unlocked()|g' The definitions of these abstractions in fs/devfs/devfs_int.h are the only non-mechanical change. No functional change. --- sys/fs/devfs/devfs_devs.c | 6 +++--- sys/fs/devfs/devfs_int.h | 3 +++ sys/kern/kern_conf.c | 30 +++++++++++++++--------------- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/sys/fs/devfs/devfs_devs.c b/sys/fs/devfs/devfs_devs.c index 3929cc8b1e80..e3d86cf902bf 100644 --- a/sys/fs/devfs/devfs_devs.c +++ b/sys/fs/devfs/devfs_devs.c @@ -156,7 +156,7 @@ devfs_dev_exists(const char *name) { struct cdev_priv *cdp; - mtx_assert(&devmtx, MA_OWNED); + dev_lock_assert_locked(); TAILQ_FOREACH(cdp, &cdevp_list, cdp_list) { if ((cdp->cdp_flags & CDP_ACTIVE) == 0) @@ -707,7 +707,7 @@ devfs_create(struct cdev *dev) { struct cdev_priv *cdp; - mtx_assert(&devmtx, MA_OWNED); + dev_lock_assert_locked(); cdp = cdev2priv(dev); cdp->cdp_flags |= CDP_ACTIVE; cdp->cdp_inode = alloc_unrl(devfs_inos); @@ -721,7 +721,7 @@ devfs_destroy(struct cdev *dev) { struct cdev_priv *cdp; - mtx_assert(&devmtx, MA_OWNED); + dev_lock_assert_locked(); cdp = cdev2priv(dev); cdp->cdp_flags &= ~CDP_ACTIVE; devfs_generation++; diff --git a/sys/fs/devfs/devfs_int.h b/sys/fs/devfs/devfs_int.h index 4b23e4fce272..5c3cb17eca61 100644 --- a/sys/fs/devfs/devfs_int.h +++ b/sys/fs/devfs/devfs_int.h @@ -95,6 +95,9 @@ extern struct sx clone_drain_lock; extern struct mtx cdevpriv_mtx; extern TAILQ_HEAD(cdev_priv_list, cdev_priv) cdevp_list; +#define dev_lock_assert_locked() mtx_assert(&devmtx, MA_OWNED) +#define dev_lock_assert_unlocked() mtx_assert(&devmtx, MA_NOTOWNED) + #endif /* _KERNEL */ #endif /* !_FS_DEVFS_DEVFS_INT_H_ */ diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c index cbaf992052a8..2d14081c0e3c 100644 --- a/sys/kern/kern_conf.c +++ b/sys/kern/kern_conf.c @@ -88,7 +88,7 @@ dev_unlock_and_free(void) struct cdev_priv *cdp; struct cdevsw *csw; - mtx_assert(&devmtx, MA_OWNED); + dev_lock_assert_locked(); /* * Make the local copy of the list heads while the dev_mtx is @@ -116,7 +116,7 @@ dev_free_devlocked(struct cdev *cdev) { struct cdev_priv *cdp; - mtx_assert(&devmtx, MA_OWNED); + dev_lock_assert_locked(); cdp = cdev2priv(cdev); KASSERT((cdp->cdp_flags & CDP_UNREF_DTR) == 0, ("destroy_dev() was not called after delist_dev(%p)", cdev)); @@ -127,7 +127,7 @@ static void cdevsw_free_devlocked(struct cdevsw *csw) { - mtx_assert(&devmtx, MA_OWNED); + dev_lock_assert_locked(); SLIST_INSERT_HEAD(&cdevsw_gt_post_list, csw, d_postfree_list); } @@ -142,7 +142,7 @@ void dev_ref(struct cdev *dev) { - mtx_assert(&devmtx, MA_NOTOWNED); + dev_lock_assert_unlocked(); mtx_lock(&devmtx); dev->si_refcount++; mtx_unlock(&devmtx); @@ -152,7 +152,7 @@ void dev_refl(struct cdev *dev) { - mtx_assert(&devmtx, MA_OWNED); + dev_lock_assert_locked(); dev->si_refcount++; } @@ -161,7 +161,7 @@ dev_rel(struct cdev *dev) { int flag = 0; - mtx_assert(&devmtx, MA_NOTOWNED); + dev_lock_assert_unlocked(); dev_lock(); dev->si_refcount--; KASSERT(dev->si_refcount >= 0, @@ -181,7 +181,7 @@ dev_refthread(struct cdev *dev, int *ref) struct cdevsw *csw; struct cdev_priv *cdp; - mtx_assert(&devmtx, MA_NOTOWNED); + dev_lock_assert_unlocked(); if ((dev->si_flags & SI_ETERNAL) != 0) { *ref = 0; return (dev->si_devsw); @@ -208,7 +208,7 @@ devvn_refthread(struct vnode *vp, struct cdev **devp, int *ref) struct cdev_priv *cdp; struct cdev *dev; - mtx_assert(&devmtx, MA_NOTOWNED); + dev_lock_assert_unlocked(); if ((vp->v_vflag & VV_ETERNALDEV) != 0) { dev = vp->v_rdev; if (dev == NULL) @@ -249,7 +249,7 @@ void dev_relthread(struct cdev *dev, int ref) { - mtx_assert(&devmtx, MA_NOTOWNED); + dev_lock_assert_unlocked(); if (!ref) return; KASSERT(dev->si_threadcount > 0, @@ -570,7 +570,7 @@ newdev(struct make_dev_args *args, struct cdev *si) struct cdev *si2; struct cdevsw *csw; - mtx_assert(&devmtx, MA_OWNED); + dev_lock_assert_locked(); csw = args->mda_devsw; si2 = NULL; if (csw->d_flags & D_NEEDMINOR) { @@ -629,7 +629,7 @@ prep_cdevsw(struct cdevsw *devsw, int flags) { struct cdevsw *dsw2; - mtx_assert(&devmtx, MA_OWNED); + dev_lock_assert_locked(); if (devsw->d_flags & D_INIT) return (0); if (devsw->d_flags & D_NEEDGIANT) { @@ -714,7 +714,7 @@ prep_devname(struct cdev *dev, const char *fmt, va_list ap) int len; char *from, *q, *s, *to; - mtx_assert(&devmtx, MA_OWNED); + dev_lock_assert_locked(); len = vsnrprintf(dev->si_name, sizeof(dev->si_name), 32, fmt, ap); if (len > sizeof(dev->si_name) - 1) @@ -1098,7 +1098,7 @@ destroy_devl(struct cdev *dev) struct cdev_privdata *p; struct cdev_priv *cdp; - mtx_assert(&devmtx, MA_OWNED); + dev_lock_assert_locked(); KASSERT(dev->si_flags & SI_NAMED, ("WARNING: Driver mistake: destroy_dev on %d\n", dev2unit(dev))); KASSERT((dev->si_flags & SI_ETERNAL) == 0, @@ -1200,7 +1200,7 @@ delist_dev_locked(struct cdev *dev) struct cdev_priv *cdp; struct cdev *child; - mtx_assert(&devmtx, MA_OWNED); + dev_lock_assert_locked(); cdp = cdev2priv(dev); if ((cdp->cdp_flags & CDP_UNREF_DTR) != 0) return; @@ -1464,7 +1464,7 @@ destroy_dev_sched_cbl(struct cdev *dev, void (*cb)(void *), void *arg) { struct cdev_priv *cp; - mtx_assert(&devmtx, MA_OWNED); + dev_lock_assert_locked(); cp = cdev2priv(dev); if (cp->cdp_flags & CDP_SCHED_DTR) { dev_unlock(); From 90cf38f22e0902b796120e6a6983a7876276a431 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Wed, 12 Aug 2020 04:35:49 +0000 Subject: [PATCH 38/96] Fix a bug introduced by r363001 for the ext_pgs case. r363001 added support for ext_pgs mbufs to nfsm_uiombuf(). By inspection, I noticed that "mlen" was not set non-zero and, as such, there would be an iteration of the loop that did nothing. This patch sets it. This bug would have no effect on the system, since the ext_pgs mbuf code is not yet enabled. --- sys/fs/nfsclient/nfs_clcomsubs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/fs/nfsclient/nfs_clcomsubs.c b/sys/fs/nfsclient/nfs_clcomsubs.c index f4a6b8dfa90b..b93facfbe264 100644 --- a/sys/fs/nfsclient/nfs_clcomsubs.c +++ b/sys/fs/nfsclient/nfs_clcomsubs.c @@ -92,7 +92,7 @@ nfsm_uiombuf(struct nfsrv_descript *nd, struct uio *uiop, int siz) nd->nd_maxextsiz, &nd->nd_bextpg); mcp = (char *)(void *)PHYS_TO_DMAP( mp->m_epg_pa[nd->nd_bextpg]); - nd->nd_bextpgsiz = PAGE_SIZE; + nd->nd_bextpgsiz = mlen = PAGE_SIZE; } else { if (clflg) NFSMCLGET(mp, M_WAITOK); From 6883f07e97becc3c80e8cda70ff343fec41164c0 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik Date: Wed, 12 Aug 2020 04:52:35 +0000 Subject: [PATCH 39/96] vfs: reimplement vref on top of vget No change in generated assembly. --- sys/kern/vfs_subr.c | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 86b9c748740e..21244d6b1549 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -2920,36 +2920,14 @@ vget_finish_ref(struct vnode *vp, enum vgetstate vs) } } -/* - * Increase the reference (use) and hold count of a vnode. - * This will also remove the vnode from the free list if it is presently free. - */ void vref(struct vnode *vp) { - int old; + enum vgetstate vs; CTR2(KTR_VFS, "%s: vp %p", __func__, vp); - if (refcount_acquire_if_not_zero(&vp->v_usecount)) { - VNODE_REFCOUNT_FENCE_ACQ(); - VNASSERT(vp->v_holdcnt > 0, vp, - ("%s: active vnode not held", __func__)); - return; - } - vhold(vp); - /* - * See the comment in vget_finish. - */ - old = atomic_fetchadd_int(&vp->v_usecount, 1); - VNASSERT(old >= 0, vp, ("%s: wrong use count %d", __func__, old)); - if (old != 0) { -#ifdef INVARIANTS - old = atomic_fetchadd_int(&vp->v_holdcnt, -1); - VNASSERT(old > 1, vp, ("%s: wrong hold count %d", __func__, old)); -#else - refcount_release(&vp->v_holdcnt); -#endif - } + vs = vget_prep(vp); + vget_finish_ref(vp, vs); } void From 4c2d103a02118d40feecc36c9a4276ecc5c0157c Mon Sep 17 00:00:00 2001 From: Mateusz Guzik Date: Wed, 12 Aug 2020 04:53:02 +0000 Subject: [PATCH 40/96] vfs: garbage collect vrefactn --- sys/kern/vfs_subr.c | 13 ------------- sys/sys/vnode.h | 1 - 2 files changed, 14 deletions(-) diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 21244d6b1549..1b6eb6801556 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -2952,19 +2952,6 @@ vrefact(struct vnode *vp) #endif } -void -vrefactn(struct vnode *vp, u_int n) -{ - - CTR2(KTR_VFS, "%s: vp %p", __func__, vp); -#ifdef INVARIANTS - int old = atomic_fetchadd_int(&vp->v_usecount, n); - VNASSERT(old > 0, vp, ("%s: wrong use count %d", __func__, old)); -#else - atomic_add_int(&vp->v_usecount, n); -#endif -} - /* * Return reference count of a vnode. * diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 2e21833c0359..55bb0864156e 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -967,7 +967,6 @@ void vrele(struct vnode *vp); void vref(struct vnode *vp); void vrefl(struct vnode *vp); void vrefact(struct vnode *vp); -void vrefactn(struct vnode *vp, u_int n); int vrefcnt(struct vnode *vp); void v_addpollinfo(struct vnode *vp); From 36f47512d99f79470147d779e58b55635c1f3c18 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik Date: Wed, 12 Aug 2020 04:53:20 +0000 Subject: [PATCH 41/96] vfs: inline vrefcnt --- sys/kern/vfs_subr.c | 16 ---------------- sys/sys/vnode.h | 7 ++++++- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 1b6eb6801556..03bfa129b16c 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -2952,22 +2952,6 @@ vrefact(struct vnode *vp) #endif } -/* - * Return reference count of a vnode. - * - * The results of this call are only guaranteed when some mechanism is used to - * stop other processes from gaining references to the vnode. This may be the - * case if the caller holds the only reference. This is also useful when stale - * data is acceptable as race conditions may be accounted for by some other - * means. - */ -int -vrefcnt(struct vnode *vp) -{ - - return (vp->v_usecount); -} - void vlazy(struct vnode *vp) { diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 55bb0864156e..9d736483d008 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -967,8 +967,13 @@ void vrele(struct vnode *vp); void vref(struct vnode *vp); void vrefl(struct vnode *vp); void vrefact(struct vnode *vp); -int vrefcnt(struct vnode *vp); void v_addpollinfo(struct vnode *vp); +static __inline int +vrefcnt(struct vnode *vp) +{ + + return (vp->v_usecount); +} int vnode_create_vobject(struct vnode *vp, off_t size, struct thread *td); void vnode_destroy_vobject(struct vnode *vp); From ef32901b2585328b79766969863c9c45c1d8e012 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Wed, 12 Aug 2020 09:07:07 +0000 Subject: [PATCH 42/96] cp2112: a number of cleanups and improvements - hoist all request / response structures from function level to top level - replace magic numeric literals with constants - regroup types, data and functions - remove setting of the id field in responses as they are completely overwritten with data from the device - centralize setting of the id field as it is always set to the value of request type - fix setting and querying of open-drain vs push-pull configuration of an output pin -- it's always in one of those configurations - detect special pin configurations: a pin in a special configuration is neither general purpose input or output - there is still no support for setting special configurations MFC after: 2 weeks --- sys/dev/usb/misc/cp2112.c | 680 +++++++++++++++++++++----------------- 1 file changed, 379 insertions(+), 301 deletions(-) diff --git a/sys/dev/usb/misc/cp2112.c b/sys/dev/usb/misc/cp2112.c index 0430fdbfe56f..a2ead7d5371e 100644 --- a/sys/dev/usb/misc/cp2112.c +++ b/sys/dev/usb/misc/cp2112.c @@ -66,6 +66,8 @@ __FBSDID("$FreeBSD$"); #define USB_DEBUG_VAR usb_debug #include +#define SIZEOF_FIELD(_s, _f) sizeof(((struct _s *)NULL)->_f) + #define CP2112GPIO_LOCK(sc) sx_xlock(&sc->gpio_lock) #define CP2112GPIO_UNLOCK(sc) sx_xunlock(&sc->gpio_lock) #define CP2112GPIO_LOCKED(sc) sx_assert(&sc->gpio_lock, SX_XLOCKED) @@ -93,8 +95,13 @@ __FBSDID("$FreeBSD$"); #define CP2112_REQ_LOCK 0x20 #define CP2112_REQ_USB_CFG 0x21 +#define CP2112_IIC_MAX_READ_LEN 512 #define CP2112_IIC_REPSTART_VER 2 /* Erratum CP2112_E10. */ +#define CP2112_GPIO_SPEC_CLK7 1 /* Pin 7 is clock output. */ +#define CP2112_GPIO_SPEC_TX0 2 /* Pin 0 pulses on USB TX. */ +#define CP2112_GPIO_SPEC_RX1 4 /* Pin 1 pulses on USB RX. */ + #define CP2112_IIC_STATUS0_IDLE 0 #define CP2112_IIC_STATUS0_BUSY 1 #define CP2112_IIC_STATUS0_CMP 2 @@ -104,6 +111,111 @@ __FBSDID("$FreeBSD$"); #define CP2112_IIC_STATUS1_TIMEOUT_BUS 1 #define CP2112_IIC_STATUS1_ARB_LOST 2 +/* CP2112_REQ_VERSION */ +struct version_request { + uint8_t id; + uint8_t part_num; + uint8_t version; +} __packed; + +/* CP2112_REQ_GPIO_GET */ +struct gpio_get_req { + uint8_t id; + uint8_t state; +} __packed; + +/* CP2112_REQ_GPIO_SET */ +struct gpio_set_req { + uint8_t id; + uint8_t state; + uint8_t mask; +} __packed; + +/* CP2112_REQ_GPIO_CFG */ +struct gpio_config_req { + uint8_t id; + uint8_t output; + uint8_t pushpull; + uint8_t special; + uint8_t divider; +} __packed; + +/* CP2112_REQ_SMB_XFER_STATUS_REQ */ +struct i2c_xfer_status_req { + uint8_t id; + uint8_t request; +} __packed; + +/* CP2112_REQ_SMB_XFER_STATUS_RESP */ +struct i2c_xfer_status_resp { + uint8_t id; + uint8_t status0; + uint8_t status1; + uint16_t status2; + uint16_t status3; +} __packed; + +/* CP2112_REQ_SMB_READ_FORCE_SEND */ +struct i2c_data_read_force_send_req { + uint8_t id; + uint16_t len; +} __packed; + +/* CP2112_REQ_SMB_READ_RESPONSE */ +struct i2c_data_read_resp { + uint8_t id; + uint8_t status; + uint8_t len; + uint8_t data[61]; +} __packed; + +/* CP2112_REQ_SMB_READ */ +struct i2c_write_read_req { + uint8_t id; + uint8_t slave; + uint16_t rlen; + uint8_t wlen; + uint8_t wdata[16]; +} __packed; + +/* CP2112_REQ_SMB_WRITE */ +struct i2c_read_req { + uint8_t id; + uint8_t slave; + uint16_t len; +} __packed; + +/* CP2112_REQ_SMB_WRITE_READ */ +struct i2c_write_req { + uint8_t id; + uint8_t slave; + uint8_t len; + uint8_t data[61]; +} __packed; + +/* CP2112_REQ_SMB_CFG */ +struct i2c_cfg_req { + uint8_t id; + uint32_t speed; /* Hz */ + uint8_t slave_addr; /* ACK only */ + uint8_t auto_send_read; /* boolean */ + uint16_t write_timeout; /* 0-1000 ms, 0 ~ no timeout */ + uint16_t read_timeout; /* 0-1000 ms, 0 ~ no timeout */ + uint8_t scl_low_timeout;/* boolean */ + uint16_t retry_count; /* 1-1000, 0 ~ forever */ +} __packed; + +enum cp2112_out_mode { + OUT_OD, + OUT_PP, + OUT_KEEP +}; + +enum { + CP2112_INTR_OUT = 0, + CP2112_INTR_IN, + CP2112_N_TRANSFER, +}; struct cp2112_softc { device_t sc_gpio_dev; @@ -120,10 +232,38 @@ struct cp2112gpio_softc { struct gpio_pin pins[CP2112_GPIO_COUNT]; }; +struct cp2112iic_softc { + device_t dev; + device_t iicbus_dev; + struct usb_xfer *xfers[CP2112_N_TRANSFER]; + u_char own_addr; + struct { + struct mtx lock; + struct cv cv; + struct { + uint8_t *data; + int len; + int done; + int error; + } in; + struct { + const uint8_t *data; + int len; + int done; + int error; + } out; + } io; +}; + static int cp2112_detach(device_t dev); static int cp2112gpio_detach(device_t dev); static int cp2112iic_detach(device_t dev); +static const STRUCT_USB_HOST_ID cp2112_devs[] = { + { USB_VP(USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP2112) }, + { USB_VP(0x1009, USB_PRODUCT_SILABS_CP2112) }, /* XXX */ +}; + static int cp2112_get_report(device_t dev, uint8_t id, void *data, uint16_t len) { @@ -143,25 +283,103 @@ cp2112_set_report(device_t dev, uint8_t id, void *data, uint16_t len) int err; sc = device_get_softc(dev); + *(uint8_t *)data = id; err = usbd_req_set_report(sc->sc_udev, NULL, data, len, sc->sc_iface_index, UHID_FEATURE_REPORT, id); return (err); } +static int +cp2112_probe(device_t dev) +{ + struct usb_attach_arg *uaa; + + uaa = device_get_ivars(dev); + if (uaa->usb_mode != USB_MODE_HOST) + return (ENXIO); + if (uaa->info.bInterfaceClass != UICLASS_HID) + return (ENXIO); + + if (usbd_lookup_id_by_uaa(cp2112_devs, sizeof(cp2112_devs), uaa) == 0) + return (BUS_PROBE_DEFAULT); + return (ENXIO); +} + +static int +cp2112_attach(device_t dev) +{ + struct version_request vdata; + struct usb_attach_arg *uaa; + struct cp2112_softc *sc; + int err; + + uaa = device_get_ivars(dev); + sc = device_get_softc(dev); + + device_set_usb_desc(dev); + + sc->sc_udev = uaa->device; + sc->sc_iface_index = uaa->info.bIfaceIndex; + + err = cp2112_get_report(dev, CP2112_REQ_VERSION, &vdata, sizeof(vdata)); + if (err != 0) + goto detach; + device_printf(dev, "part number 0x%02x, version 0x%02x\n", + vdata.part_num, vdata.version); + if (vdata.part_num != CP2112_PART_NUM) { + device_printf(dev, "unsupported part number\n"); + goto detach; + } + sc->sc_version = vdata.version; + sc->sc_gpio_dev = device_add_child(dev, "gpio", -1); + if (sc->sc_gpio_dev != NULL) { + err = device_probe_and_attach(sc->sc_gpio_dev); + if (err != 0) { + device_printf(dev, "failed to attach gpio child\n"); + } + } else { + device_printf(dev, "failed to create gpio child\n"); + } + + sc->sc_iic_dev = device_add_child(dev, "iichb", -1); + if (sc->sc_iic_dev != NULL) { + err = device_probe_and_attach(sc->sc_iic_dev); + if (err != 0) { + device_printf(dev, "failed to attach iic child\n"); + } + } else { + device_printf(dev, "failed to create iic child\n"); + } + + return (0); + +detach: + cp2112_detach(dev); + return (ENXIO); +} + +static int +cp2112_detach(device_t dev) +{ + int err; + + err = bus_generic_detach(dev); + if (err != 0) + return (err); + device_delete_children(dev); + return (0); +} + static int cp2112_gpio_read_pin(device_t dev, uint32_t pin_num, bool *on) { - struct { - uint8_t id; - uint8_t state; - } __packed data; + struct gpio_get_req data; struct cp2112gpio_softc *sc; int err; sc = device_get_softc(dev); CP2112GPIO_LOCKED(sc); - data.id = CP2112_REQ_GPIO_GET; err = cp2112_get_report(device_get_parent(dev), CP2112_REQ_GPIO_GET, &data, sizeof(data)); if (err != 0) @@ -174,11 +392,7 @@ cp2112_gpio_read_pin(device_t dev, uint32_t pin_num, bool *on) static int cp2112_gpio_write_pin(device_t dev, uint32_t pin_num, bool on) { - struct { - uint8_t id; - uint8_t state; - uint8_t mask; - } __packed data; + struct gpio_set_req data; struct cp2112gpio_softc *sc; int err; bool actual; @@ -186,10 +400,8 @@ cp2112_gpio_write_pin(device_t dev, uint32_t pin_num, bool on) sc = device_get_softc(dev); CP2112GPIO_LOCKED(sc); - data.id = CP2112_REQ_GPIO_SET; data.state = (uint8_t)on << pin_num; data.mask = (uint8_t)1 << pin_num; - err = cp2112_set_report(device_get_parent(dev), CP2112_REQ_GPIO_SET, &data, sizeof(data)); if (err != 0) @@ -204,15 +416,9 @@ cp2112_gpio_write_pin(device_t dev, uint32_t pin_num, bool on) static int cp2112_gpio_configure_write_pin(device_t dev, uint32_t pin_num, - bool output, bool pushpull) + bool output, enum cp2112_out_mode *mode) { - struct { - uint8_t id; - uint8_t output; - uint8_t pushpull; - uint8_t special; - uint8_t divider; - } __packed data; + struct gpio_config_req data; struct cp2112gpio_softc *sc; int err; uint8_t mask; @@ -220,21 +426,26 @@ cp2112_gpio_configure_write_pin(device_t dev, uint32_t pin_num, sc = device_get_softc(dev); CP2112GPIO_LOCKED(sc); - mask = (uint8_t)1 << pin_num; - data.id = CP2112_REQ_GPIO_CFG; err = cp2112_get_report(device_get_parent(dev), CP2112_REQ_GPIO_CFG, &data, sizeof(data)); if (err != 0) return (err); + + mask = (uint8_t)1 << pin_num; if (output) { data.output |= mask; - if (pushpull) + switch (*mode) { + case OUT_PP: data.pushpull |= mask; - else + break; + case OUT_OD: data.pushpull &= ~mask; + break; + default: + break; + } } else { data.output &= ~mask; - data.pushpull &= ~mask; } err = cp2112_set_report(device_get_parent(dev), @@ -247,10 +458,25 @@ cp2112_gpio_configure_write_pin(device_t dev, uint32_t pin_num, CP2112_REQ_GPIO_CFG, &data, sizeof(data)); if (err != 0) return (err); + if (((data.output & mask) != 0) != output) return (EIO); - if (((data.pushpull & mask) != 0) != pushpull) - return (EIO); + if (output) { + switch (*mode) { + case OUT_PP: + if ((data.pushpull & mask) == 0) + return (EIO); + break; + case OUT_OD: + if ((data.pushpull & mask) != 0) + return (EIO); + break; + default: + *mode = (data.pushpull & mask) != 0 ? + OUT_PP : OUT_OD; + break; + } + } return (0); } @@ -381,6 +607,7 @@ cp2112_gpio_pin_setflags(device_t dev, uint32_t pin_num, uint32_t flags) { struct cp2112gpio_softc *sc; struct gpio_pin *pin; + enum cp2112_out_mode out_mode; int err; if (pin_num >= CP2112_GPIO_COUNT) @@ -405,117 +632,44 @@ cp2112_gpio_pin_setflags(device_t dev, uint32_t pin_num, uint32_t flags) return (EINVAL); } - CP2112GPIO_LOCK(sc); - pin = &sc->pins[pin_num]; - /* - * If neither push-pull or opendrain is explcitely requested, then + * If neither push-pull or open-drain is explicitly requested, then * preserve the current state. */ - if ((flags & GPIO_PIN_OUTPUT) != 0 && - (flags & (GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL)) == 0) - flags |= pin->gp_flags & (GPIO_PIN_OPENDRAIN|GPIO_PIN_PUSHPULL); + out_mode = OUT_KEEP; + if ((flags & GPIO_PIN_OUTPUT) != 0) { + if ((flags & GPIO_PIN_OPENDRAIN) != 0) + out_mode = OUT_OD; + if ((flags & GPIO_PIN_PUSHPULL) != 0) + out_mode = OUT_PP; + } + + CP2112GPIO_LOCK(sc); + pin = &sc->pins[pin_num]; err = cp2112_gpio_configure_write_pin(dev, pin_num, - (flags & GPIO_PIN_OUTPUT) != 0, - (flags & GPIO_PIN_PUSHPULL) != 0); - if (err == 0) + (flags & GPIO_PIN_OUTPUT) != 0, &out_mode); + if (err == 0) { + /* + * If neither open-drain or push-pull was requested, then see + * what hardware actually had. Otherwise, it has been + * reconfigured as requested. + */ + if ((flags & GPIO_PIN_OUTPUT) != 0 && + (flags & (GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL)) == 0) { + KASSERT(out_mode != OUT_KEEP, + ("impossible current output mode")); + if (out_mode == OUT_OD) + flags |= GPIO_PIN_OPENDRAIN; + else + flags |= GPIO_PIN_PUSHPULL; + } pin->gp_flags = flags; + } CP2112GPIO_UNLOCK(sc); return (err); } -static const STRUCT_USB_HOST_ID cp2112_devs[] = { - { USB_VP(USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP2112) }, - { USB_VP(0x1009, USB_PRODUCT_SILABS_CP2112) }, /* XXX */ -}; - -static int -cp2112_probe(device_t dev) -{ - struct usb_attach_arg *uaa; - - uaa = device_get_ivars(dev); - if (uaa->usb_mode != USB_MODE_HOST) - return (ENXIO); - if (uaa->info.bInterfaceClass != UICLASS_HID) - return (ENXIO); - - if (usbd_lookup_id_by_uaa(cp2112_devs, sizeof(cp2112_devs), uaa) == 0) - return (BUS_PROBE_DEFAULT); - return (ENXIO); -} - -static int -cp2112_attach(device_t dev) -{ - struct { - uint8_t id; - uint8_t part_num; - uint8_t version; - } __packed vdata; - struct usb_attach_arg *uaa; - struct cp2112_softc *sc; - int err; - - uaa = device_get_ivars(dev); - sc = device_get_softc(dev); - - device_set_usb_desc(dev); - - sc->sc_udev = uaa->device; - sc->sc_iface_index = uaa->info.bIfaceIndex; - - vdata.id = CP2112_REQ_VERSION; - err = cp2112_get_report(dev, CP2112_REQ_VERSION, &vdata, sizeof(vdata)); - if (err != 0) - goto detach; - device_printf(dev, "part number 0x%02x, version 0x%02x\n", - vdata.part_num, vdata.version); - if (vdata.part_num != CP2112_PART_NUM) { - device_printf(dev, "unsupported part number\n"); - goto detach; - } - sc->sc_version = vdata.version; - sc->sc_gpio_dev = device_add_child(dev, "gpio", -1); - if (sc->sc_gpio_dev != NULL) { - err = device_probe_and_attach(sc->sc_gpio_dev); - if (err != 0) { - device_printf(dev, "failed to attach gpio child\n"); - } - } else { - device_printf(dev, "failed to create gpio child\n"); - } - - sc->sc_iic_dev = device_add_child(dev, "iichb", -1); - if (sc->sc_iic_dev != NULL) { - err = device_probe_and_attach(sc->sc_iic_dev); - if (err != 0) { - device_printf(dev, "failed to attach iic child\n"); - } - } else { - device_printf(dev, "failed to create iic child\n"); - } - - return (0); - -detach: - cp2112_detach(dev); - return (ENXIO); -} - -static int -cp2112_detach(device_t dev) -{ - int err; - - err = bus_generic_detach(dev); - if (err != 0) - return (err); - device_delete_children(dev); - return (0); -} - static int cp2112gpio_probe(device_t dev) { @@ -526,13 +680,7 @@ cp2112gpio_probe(device_t dev) static int cp2112gpio_attach(device_t dev) { - struct { - uint8_t id; - uint8_t output; - uint8_t pushpull; - uint8_t special; - uint8_t divider; - } __packed data; + struct gpio_config_req data; struct cp2112gpio_softc *sc; device_t cp2112; int err; @@ -546,7 +694,6 @@ cp2112gpio_attach(device_t dev) sc->gpio_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL; - data.id = CP2112_REQ_GPIO_CFG; err = cp2112_get_report(cp2112, CP2112_REQ_GPIO_CFG, &data, sizeof(data)); if (err != 0) @@ -562,7 +709,11 @@ cp2112gpio_attach(device_t dev) snprintf(pin->gp_name, GPIOMAXNAME, "GPIO%u", i); pin->gp_name[GPIOMAXNAME - 1] = '\0'; - if ((data.output & mask) != 0) { + if ((i == 0 && (data.special & CP2112_GPIO_SPEC_TX0) != 0) || + (i == 1 && (data.special & CP2112_GPIO_SPEC_RX1) != 0) || + (i == 7 && (data.special & CP2112_GPIO_SPEC_CLK7) != 0)) { + /* Special mode means that a pin is not for GPIO. */ + } else if ((data.output & mask) != 0) { pin->gp_flags |= GPIO_PIN_OUTPUT; if ((data.pushpull & mask) != 0) pin->gp_flags |= GPIO_PIN_PUSHPULL; @@ -597,94 +748,6 @@ cp2112gpio_detach(device_t dev) return (0); } -static device_method_t cp2112hid_methods[] = { - DEVMETHOD(device_probe, cp2112_probe), - DEVMETHOD(device_attach, cp2112_attach), - DEVMETHOD(device_detach, cp2112_detach), - - DEVMETHOD_END -}; - -static device_method_t cp2112gpio_methods[] = { - /* Device */ - DEVMETHOD(device_probe, cp2112gpio_probe), - DEVMETHOD(device_attach, cp2112gpio_attach), - DEVMETHOD(device_detach, cp2112gpio_detach), - - /* GPIO */ - DEVMETHOD(gpio_get_bus, cp2112_gpio_get_bus), - DEVMETHOD(gpio_pin_max, cp2112_gpio_pin_max), - DEVMETHOD(gpio_pin_get, cp2112_gpio_pin_get), - DEVMETHOD(gpio_pin_set, cp2112_gpio_pin_set), - DEVMETHOD(gpio_pin_toggle, cp2112_gpio_pin_toggle), - DEVMETHOD(gpio_pin_getname, cp2112_gpio_pin_getname), - DEVMETHOD(gpio_pin_getcaps, cp2112_gpio_pin_getcaps), - DEVMETHOD(gpio_pin_getflags, cp2112_gpio_pin_getflags), - DEVMETHOD(gpio_pin_setflags, cp2112_gpio_pin_setflags), - - DEVMETHOD_END -}; - -static driver_t cp2112hid_driver = { - .name = "cp2112hid", - .methods = cp2112hid_methods, - .size = sizeof(struct cp2112_softc), -}; - -static devclass_t cp2112hid_devclass; -DRIVER_MODULE(cp2112hid, uhub, cp2112hid_driver, cp2112hid_devclass, - NULL, NULL); -MODULE_DEPEND(cp2112hid, usb, 1, 1, 1); -MODULE_VERSION(cp2112hid, 1); -USB_PNP_HOST_INFO(cp2112_devs); - -static driver_t cp2112gpio_driver = { - .name = "gpio", - .methods = cp2112gpio_methods, - .size = sizeof(struct cp2112gpio_softc), -}; - -static devclass_t cp2112gpio_devclass; -DRIVER_MODULE(cp2112gpio, cp2112hid, cp2112gpio_driver, cp2112gpio_devclass, - NULL, NULL); -MODULE_DEPEND(cp2112gpio, cp2112hid, 1, 1, 1); -MODULE_DEPEND(cp2112gpio, gpiobus, 1, 1, 1); -MODULE_VERSION(cp2112gpio, 1); - - - -/* CP2112 I2C driver code. */ - - -enum { - CP2112_INTR_OUT = 0, - CP2112_INTR_IN, - CP2112_N_TRANSFER, -}; - -struct cp2112iic_softc { - device_t dev; - device_t iicbus_dev; - struct usb_xfer *xfers[CP2112_N_TRANSFER]; - u_char own_addr; - struct { - struct mtx lock; - struct cv cv; - struct { - uint8_t *data; - int len; - int done; - int error; - } in; - struct { - const uint8_t *data; - int len; - int done; - int error; - } out; - } io; -}; - static void cp2112iic_intr_write_callback(struct usb_xfer *xfer, usb_error_t error) { @@ -890,17 +953,8 @@ cp2112iic_req_resp(struct cp2112iic_softc *sc, const void *req_data, static int cp2112iic_check_req_status(struct cp2112iic_softc *sc) { - struct { - uint8_t id; - uint8_t request; - } __packed xfer_status_req; - struct { - uint8_t id; - uint8_t status0; - uint8_t status1; - uint16_t status2; - uint16_t status3; - } __packed xfer_status_resp; + struct i2c_xfer_status_req xfer_status_req; + struct i2c_xfer_status_resp xfer_status_resp; int err; mtx_assert(&sc->io.lock, MA_OWNED); @@ -971,16 +1025,8 @@ static int cp2112iic_read_data(struct cp2112iic_softc *sc, void *data, uint16_t in_len, uint16_t *out_len) { - struct { - uint8_t id; - uint16_t length; - } __packed data_read_force_send; - struct { - uint8_t id; - uint8_t status; - uint8_t length; - uint8_t data[61]; - } __packed data_read_resp; + struct i2c_data_read_force_send_req data_read_force_send; + struct i2c_data_read_resp data_read_resp; int err; mtx_assert(&sc->io.lock, MA_OWNED); @@ -993,7 +1039,7 @@ cp2112iic_read_data(struct cp2112iic_softc *sc, void *data, uint16_t in_len, if (in_len > sizeof(data_read_resp.data)) in_len = sizeof(data_read_resp.data); data_read_force_send.id = CP2112_REQ_SMB_READ_FORCE_SEND; - data_read_force_send.length = htobe16(in_len); + data_read_force_send.len = htobe16(in_len); err = cp2112iic_req_resp(sc, &data_read_force_send, sizeof(data_read_force_send), &data_read_resp, sizeof(data_read_resp)); @@ -1009,7 +1055,7 @@ cp2112iic_read_data(struct cp2112iic_softc *sc, void *data, uint16_t in_len, } DTRACE_PROBE2(read__response, uint8_t, data_read_resp.status, - uint8_t, data_read_resp.length); + uint8_t, data_read_resp.len); /* * We expect either the request completed status or, more typical for @@ -1021,13 +1067,13 @@ cp2112iic_read_data(struct cp2112iic_softc *sc, void *data, uint16_t in_len, err = IIC_EBUSERR; goto out; } - if (data_read_resp.length > in_len) { + if (data_read_resp.len > in_len) { device_printf(sc->dev, "device returns more data than asked\n"); err = IIC_EOVERFLOW; goto out; } - *out_len = data_read_resp.length; + *out_len = data_read_resp.len; if (*out_len > 0) memcpy(data, data_read_resp.data, *out_len); out: @@ -1070,11 +1116,13 @@ cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) reason = "message with no data"; break; } - if ((msgs[i].flags & IIC_M_RD) != 0 && msgs[i].len > 512) { + if ((msgs[i].flags & IIC_M_RD) != 0 && + msgs[i].len > CP2112_IIC_MAX_READ_LEN) { reason = "too long read"; break; } - if ((msgs[i].flags & IIC_M_RD) == 0 && msgs[i].len > 61) { + if ((msgs[i].flags & IIC_M_RD) == 0 && + msgs[i].len > SIZEOF_FIELD(i2c_write_req, data)) { reason = "too long write"; break; } @@ -1092,7 +1140,8 @@ cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) reason = "write without stop"; break; } - if ((msgs[i].flags & IIC_M_NOSTOP) != 0 && msgs[i].len > 16) { + if ((msgs[i].flags & IIC_M_NOSTOP) != 0 && + msgs[i].len > SIZEOF_FIELD(i2c_write_read_req, wdata)) { reason = "too long write without stop"; break; } @@ -1120,22 +1169,16 @@ cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) for (i = 0; i < nmsgs; i++) { if (i + 1 < nmsgs && (msgs[i].flags & IIC_M_NOSTOP) != 0) { - KASSERT((msgs[i].flags & IIC_M_RD) == 0, - ("read without stop")); - KASSERT((msgs[i + 1].flags & IIC_M_RD) != 0, - ("write after write without stop")); /* * Combine into a single * CP2112 operation. */ - struct { - uint8_t id; - uint8_t slave; - uint16_t rlen; - uint8_t wlen; - uint8_t wdata[16]; - } __packed req; + struct i2c_write_read_req req; + KASSERT((msgs[i].flags & IIC_M_RD) == 0, + ("read without stop")); + KASSERT((msgs[i + 1].flags & IIC_M_RD) != 0, + ("write after write without stop")); req.id = CP2112_REQ_SMB_WRITE_READ; req.slave = msgs[i].slave & ~LSB; to_read = msgs[i + 1].len; @@ -1150,11 +1193,7 @@ cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) */ i++; } else if ((msgs[i].flags & IIC_M_RD) != 0) { - struct { - uint8_t id; - uint8_t slave; - uint16_t len; - } __packed req; + struct i2c_read_req req; req.id = CP2112_REQ_SMB_READ; req.slave = msgs[i].slave & ~LSB; @@ -1162,12 +1201,7 @@ cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) req.len = htobe16(to_read); err = cp2112iic_send_req(sc, &req, sizeof(req)); } else { - struct { - uint8_t id; - uint8_t slave; - uint8_t len; - uint8_t data[61]; - } __packed req; + struct i2c_write_req req; req.id = CP2112_REQ_SMB_WRITE; req.slave = msgs[i].slave & ~LSB; @@ -1207,16 +1241,7 @@ cp2112iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) static int cp2112iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) { - struct { - uint8_t id; - uint32_t speed; /* Hz */ - uint8_t slave_addr; /* ACK only */ - uint8_t auto_send_read; /* boolean */ - uint16_t write_timeout; /* 0-1000 ms, 0 ~ no timeout */ - uint16_t read_timeout; /* 0-1000 ms, 0 ~ no timeout */ - uint8_t scl_low_timeout;/* boolean */ - uint16_t retry_count; /* 1-1000, 0 ~ forever */ - } __packed smb_cfg; + struct i2c_cfg_req i2c_cfg; struct cp2112iic_softc *sc; device_t cp2112; u_int busfreq; @@ -1229,16 +1254,15 @@ cp2112iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) else busfreq = IICBUS_GET_FREQUENCY(sc->iicbus_dev, speed); - smb_cfg.id = CP2112_REQ_SMB_CFG; err = cp2112_get_report(cp2112, CP2112_REQ_SMB_CFG, - &smb_cfg, sizeof(smb_cfg)); + &i2c_cfg, sizeof(i2c_cfg)); if (err != 0) { device_printf(dev, "failed to get CP2112_REQ_SMB_CFG report\n"); return (err); } if (oldaddr != NULL) - *oldaddr = smb_cfg.slave_addr; + *oldaddr = i2c_cfg.slave_addr; /* * For simplicity we do not enable Auto Send Read * because of erratum CP2112_E101 (fixed in version 3). @@ -1251,28 +1275,28 @@ cp2112iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) * TODO: should the device reset request (0x01) be sent? * If the device disconnects as a result, then no. */ - smb_cfg.speed = htobe32(busfreq); + i2c_cfg.speed = htobe32(busfreq); if (addr != 0) - smb_cfg.slave_addr = addr; - smb_cfg.auto_send_read = 0; - smb_cfg.retry_count = htobe16(1); - smb_cfg.scl_low_timeout = 0; + i2c_cfg.slave_addr = addr; + i2c_cfg.auto_send_read = 0; + i2c_cfg.retry_count = htobe16(1); + i2c_cfg.scl_low_timeout = 0; if (bootverbose) { - device_printf(dev, "speed %d Hz\n", be32toh(smb_cfg.speed)); - device_printf(dev, "slave addr 0x%02x\n", smb_cfg.slave_addr); + device_printf(dev, "speed %d Hz\n", be32toh(i2c_cfg.speed)); + device_printf(dev, "slave addr 0x%02x\n", i2c_cfg.slave_addr); device_printf(dev, "auto send read %s\n", - smb_cfg.auto_send_read ? "on" : "off"); + i2c_cfg.auto_send_read ? "on" : "off"); device_printf(dev, "write timeout %d ms (0 - disabled)\n", - be16toh(smb_cfg.write_timeout)); + be16toh(i2c_cfg.write_timeout)); device_printf(dev, "read timeout %d ms (0 - disabled)\n", - be16toh(smb_cfg.read_timeout)); + be16toh(i2c_cfg.read_timeout)); device_printf(dev, "scl low timeout %s\n", - smb_cfg.scl_low_timeout ? "on" : "off"); + i2c_cfg.scl_low_timeout ? "on" : "off"); device_printf(dev, "retry count %d (0 - no limit)\n", - be16toh(smb_cfg.retry_count)); + be16toh(i2c_cfg.retry_count)); } err = cp2112_set_report(cp2112, CP2112_REQ_SMB_CFG, - &smb_cfg, sizeof(smb_cfg)); + &i2c_cfg, sizeof(i2c_cfg)); if (err != 0) { device_printf(dev, "failed to set CP2112_REQ_SMB_CFG report\n"); return (err); @@ -1353,6 +1377,60 @@ cp2112iic_detach(device_t dev) return (0); } +static device_method_t cp2112hid_methods[] = { + DEVMETHOD(device_probe, cp2112_probe), + DEVMETHOD(device_attach, cp2112_attach), + DEVMETHOD(device_detach, cp2112_detach), + + DEVMETHOD_END +}; + +static driver_t cp2112hid_driver = { + .name = "cp2112hid", + .methods = cp2112hid_methods, + .size = sizeof(struct cp2112_softc), +}; + +static devclass_t cp2112hid_devclass; +DRIVER_MODULE(cp2112hid, uhub, cp2112hid_driver, cp2112hid_devclass, + NULL, NULL); +MODULE_DEPEND(cp2112hid, usb, 1, 1, 1); +MODULE_VERSION(cp2112hid, 1); +USB_PNP_HOST_INFO(cp2112_devs); + +static device_method_t cp2112gpio_methods[] = { + /* Device */ + DEVMETHOD(device_probe, cp2112gpio_probe), + DEVMETHOD(device_attach, cp2112gpio_attach), + DEVMETHOD(device_detach, cp2112gpio_detach), + + /* GPIO */ + DEVMETHOD(gpio_get_bus, cp2112_gpio_get_bus), + DEVMETHOD(gpio_pin_max, cp2112_gpio_pin_max), + DEVMETHOD(gpio_pin_get, cp2112_gpio_pin_get), + DEVMETHOD(gpio_pin_set, cp2112_gpio_pin_set), + DEVMETHOD(gpio_pin_toggle, cp2112_gpio_pin_toggle), + DEVMETHOD(gpio_pin_getname, cp2112_gpio_pin_getname), + DEVMETHOD(gpio_pin_getcaps, cp2112_gpio_pin_getcaps), + DEVMETHOD(gpio_pin_getflags, cp2112_gpio_pin_getflags), + DEVMETHOD(gpio_pin_setflags, cp2112_gpio_pin_setflags), + + DEVMETHOD_END +}; + +static driver_t cp2112gpio_driver = { + .name = "gpio", + .methods = cp2112gpio_methods, + .size = sizeof(struct cp2112gpio_softc), +}; + +static devclass_t cp2112gpio_devclass; +DRIVER_MODULE(cp2112gpio, cp2112hid, cp2112gpio_driver, cp2112gpio_devclass, + NULL, NULL); +MODULE_DEPEND(cp2112gpio, cp2112hid, 1, 1, 1); +MODULE_DEPEND(cp2112gpio, gpiobus, 1, 1, 1); +MODULE_VERSION(cp2112gpio, 1); + static device_method_t cp2112iic_methods[] = { /* Device interface */ DEVMETHOD(device_probe, cp2112iic_probe), From 470d07d41757eabf464b2e451e9d989ea46b978d Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Wed, 12 Aug 2020 09:42:05 +0000 Subject: [PATCH 43/96] add a manual page for cp2112 MFC after: 1 week --- share/man/man4/cp2112.4 | 87 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 share/man/man4/cp2112.4 diff --git a/share/man/man4/cp2112.4 b/share/man/man4/cp2112.4 new file mode 100644 index 000000000000..39ac8dba114e --- /dev/null +++ b/share/man/man4/cp2112.4 @@ -0,0 +1,87 @@ +.\" +.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD +.\" +.\" Copyright (c) 2020 Andriy Gapon +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd August 12, 2020 +.Dt CP2112 4 +.Os +.Sh NAME +.Nm cp2112 +.Nd driver for a USB GPIO and I2C peripheral device +.Sh SYNOPSIS +To compile this driver into the kernel, +place the following lines in your +kernel configuration file: +.Bd -ragged -offset indent +.Cd "device cp2112" +.Cd "device usb" +.Cd "device gpio" +.Cd "device iicbus" +.Ed +.Pp +Alternatively, to load the driver as a +module at boot time, place the following line in +.Xr loader.conf 5 : +.Bd -literal -offset indent +cp2112_load="YES" +.Ed +.Sh DESCRIPTION +The +.Nm +driver provides support for Silicon Labs CP2112 device. +The device has 8 general purpose I/O pins and an I2C controller that supports +a subset of the I2C protocol. +.Pp +All pins support both input and output modes. +An output pin can be configured either for open-drain or push-pull operation. +Pins 0, 1 and 7 support special functions: I2C transmit indication, +I2C receive indication and clock output respectively. +At the moment the +.Nm +driver does not provide a way to enable and configure the special functions. +.Pp +The I2C controller supports read transactions with up to 512 bytes of data, +write transactions with up to 61 bytes of data and a write followed by +the repeated start followed by a read transactions where the write can be +up to 16 bytes and the read can be up to 512 bytes. +Zero length transfers are not supported. +The +.Nm +driver creates a +.Xr gpio 4 +and +.Xr iicbus 4 +child buses to expose the respective functions. +.Sh SEE ALSO +.Xr gpio 4 , +.Xr iicbus 4 , +.Xr usb 4 +.Sh HISTORY +The +.Nm +driver and this manual page was written by +.An Andriy Gapon Aq Mt avg@FreeBSD.org . From 2ad1660ae4cd23b976ec74296f8608792833016c Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Wed, 12 Aug 2020 09:49:25 +0000 Subject: [PATCH 44/96] gpiokeys: add evdev support Only linux,code is supported as it maps 1:1 to evdev key codes. No reverse mapping for freebsd,code yet. Reviewed by: wulf MFC after: 3 weeks Differential Revision: https://reviews.freebsd.org/D25940 --- sys/dev/gpio/gpiokeys.c | 94 ++++++++++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 25 deletions(-) diff --git a/sys/dev/gpio/gpiokeys.c b/sys/dev/gpio/gpiokeys.c index 714bca6e61fb..6fd1edddab44 100644 --- a/sys/dev/gpio/gpiokeys.c +++ b/sys/dev/gpio/gpiokeys.c @@ -29,6 +29,7 @@ __FBSDID("$FreeBSD$"); #include "opt_platform.h" #include "opt_kbd.h" +#include "opt_evdev.h" #include #include @@ -56,6 +57,11 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef EVDEV_SUPPORT +#include +#include +#endif + #define KBD_DRIVER_NAME "gpiokeys" #define GPIOKEYS_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) @@ -99,6 +105,9 @@ struct gpiokey struct resource *irq_res; void *intr_hl; struct mtx mtx; +#ifdef EVDEV_SUPPORT + uint32_t evcode; +#endif uint32_t keycode; int autorepeat; struct callout debounce_callout; @@ -115,6 +124,9 @@ struct gpiokeys_softc struct gpiokey *sc_keys; int sc_total_keys; +#ifdef EVDEV_SUPPORT + struct evdev_dev *sc_evdev; +#endif keyboard_t sc_kbd; keymap_t sc_keymap; accentmap_t sc_accmap; @@ -171,26 +183,34 @@ gpiokeys_put_key(struct gpiokeys_softc *sc, uint32_t key) } static void -gpiokeys_key_event(struct gpiokeys_softc *sc, uint16_t keycode, int pressed) +gpiokeys_key_event(struct gpiokeys_softc *sc, struct gpiokey *key, int pressed) { - uint32_t key; - - - key = keycode & SCAN_KEYCODE_MASK; - - if (!pressed) - key |= KEY_RELEASE; + uint32_t code; GPIOKEYS_LOCK(sc); - if (keycode & SCAN_PREFIX_E0) - gpiokeys_put_key(sc, 0xe0); - else if (keycode & SCAN_PREFIX_E1) - gpiokeys_put_key(sc, 0xe1); +#ifdef EVDEV_SUPPORT + if (key->evcode != GPIOKEY_NONE && + (evdev_rcpt_mask & EVDEV_RCPT_HW_KBD) != 0) { + evdev_push_key(sc->sc_evdev, key->evcode, pressed); + evdev_sync(sc->sc_evdev); + } +#endif + if (key->keycode != GPIOKEY_NONE) { + code = key->keycode & SCAN_KEYCODE_MASK; + if (!pressed) + code |= KEY_RELEASE; - gpiokeys_put_key(sc, key); + if (key->keycode & SCAN_PREFIX_E0) + gpiokeys_put_key(sc, 0xe0); + else if (key->keycode & SCAN_PREFIX_E1) + gpiokeys_put_key(sc, 0xe1); + + gpiokeys_put_key(sc, code); + } GPIOKEYS_UNLOCK(sc); - gpiokeys_event_keyinput(sc); + if (key->keycode != GPIOKEY_NONE) + gpiokeys_event_keyinput(sc); } static void @@ -200,10 +220,7 @@ gpiokey_autorepeat(void *arg) key = arg; - if (key->keycode == GPIOKEY_NONE) - return; - - gpiokeys_key_event(key->parent_sc, key->keycode, 1); + gpiokeys_key_event(key->parent_sc, key, 1); callout_reset(&key->repeat_callout, key->repeat, gpiokey_autorepeat, key); @@ -217,12 +234,9 @@ gpiokey_debounced_intr(void *arg) key = arg; - if (key->keycode == GPIOKEY_NONE) - return; - gpio_pin_is_active(key->pin, &active); if (active) { - gpiokeys_key_event(key->parent_sc, key->keycode, 1); + gpiokeys_key_event(key->parent_sc, key, 1); if (key->autorepeat) { callout_reset(&key->repeat_callout, key->repeat_delay, gpiokey_autorepeat, key); @@ -232,7 +246,7 @@ gpiokey_debounced_intr(void *arg) if (key->autorepeat && callout_pending(&key->repeat_callout)) callout_stop(&key->repeat_callout); - gpiokeys_key_event(key->parent_sc, key->keycode, 0); + gpiokeys_key_event(key->parent_sc, key, 0); } } @@ -301,6 +315,10 @@ gpiokeys_attach_key(struct gpiokeys_softc *sc, phandle_t node, if (key->keycode == GPIOKEY_NONE) device_printf(sc->sc_dev, "<%s> failed to map linux,code value 0x%x\n", key_name, code); +#ifdef EVDEV_SUPPORT + key->evcode = code; + evdev_support_key(sc->sc_evdev, code); +#endif } else device_printf(sc->sc_dev, "<%s> no linux,code or freebsd,code property\n", @@ -365,7 +383,6 @@ gpiokeys_detach_key(struct gpiokeys_softc *sc, struct gpiokey *key) if (key->pin) gpio_pin_release(key->pin); GPIOKEY_UNLOCK(key); - GPIOKEY_LOCK_DESTROY(key); } @@ -383,11 +400,14 @@ gpiokeys_probe(device_t dev) static int gpiokeys_attach(device_t dev) { - int unit; struct gpiokeys_softc *sc; keyboard_t *kbd; +#ifdef EVDEV_SUPPORT + char *name; +#endif phandle_t keys, child; int total_keys; + int unit; if ((keys = ofw_bus_get_node(dev)) == -1) return (ENXIO); @@ -435,6 +455,19 @@ gpiokeys_attach(device_t dev) kbdd_diag(kbd, 1); } +#ifdef EVDEV_SUPPORT + sc->sc_evdev = evdev_alloc(); + evdev_set_name(sc->sc_evdev, device_get_desc(dev)); + + OF_getprop_alloc(keys, "name", (void **)&name); + evdev_set_phys(sc->sc_evdev, name != NULL ? name : "unknown"); + OF_prop_free(name); + + evdev_set_id(sc->sc_evdev, BUS_VIRTUAL, 0, 0, 0); + evdev_support_event(sc->sc_evdev, EV_SYN); + evdev_support_event(sc->sc_evdev, EV_KEY); +#endif + total_keys = 0; /* Traverse the 'gpio-keys' node and count keys */ @@ -458,6 +491,13 @@ gpiokeys_attach(device_t dev) } } +#ifdef EVDEV_SUPPORT + if (evdev_register_mtx(sc->sc_evdev, &sc->sc_mtx) != 0) { + device_printf(dev, "failed to register evdev device\n"); + goto detach; + } +#endif + return (0); detach: @@ -485,6 +525,10 @@ gpiokeys_detach(device_t dev) #endif kbd_unregister(kbd); +#ifdef EVDEV_SUPPORT + evdev_free(sc->sc_evdev); +#endif + GPIOKEYS_LOCK_DESTROY(sc); if (sc->sc_keys) free(sc->sc_keys, M_DEVBUF); From 012fba460ac07b36b3e756a2be41529b08c2c214 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Wed, 12 Aug 2020 09:52:12 +0000 Subject: [PATCH 45/96] aw_cir: add support for allwinner,sun6i-a31-ir (found, e.g., on h3) MFC after: 1 week --- sys/arm/allwinner/aw_cir.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sys/arm/allwinner/aw_cir.c b/sys/arm/allwinner/aw_cir.c index 1531e2fe9d47..6bd41b74315f 100644 --- a/sys/arm/allwinner/aw_cir.c +++ b/sys/arm/allwinner/aw_cir.c @@ -134,8 +134,11 @@ __FBSDID("$FreeBSD$"); #define INV_CODE_MASK 0xff00ff00 #define VALID_CODE_MASK 0x00ff0000 -#define A10_IR 1 -#define A13_IR 2 +enum { + A10_IR = 1, + A13_IR, + A31_IR, +}; #define AW_IR_RAW_BUF_SIZE 128 @@ -158,6 +161,7 @@ static struct resource_spec aw_ir_spec[] = { static struct ofw_compat_data compat_data[] = { { "allwinner,sun4i-a10-ir", A10_IR }, { "allwinner,sun5i-a13-ir", A13_IR }, + { "allwinner,sun6i-a31-ir", A31_IR }, { NULL, 0 } }; @@ -414,6 +418,7 @@ aw_ir_attach(device_t dev) sc->fifo_size = 16; break; case A13_IR: + case A31_IR: sc->fifo_size = 64; break; } From 8b616b263d1d9223180f5a14de7ca2560b95b74c Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Wed, 12 Aug 2020 09:52:39 +0000 Subject: [PATCH 46/96] aw_cir: minor cleanups MFC after: 1 week --- sys/arm/allwinner/aw_cir.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/arm/allwinner/aw_cir.c b/sys/arm/allwinner/aw_cir.c index 6bd41b74315f..c22a11fec770 100644 --- a/sys/arm/allwinner/aw_cir.c +++ b/sys/arm/allwinner/aw_cir.c @@ -368,7 +368,7 @@ aw_ir_intr(void *arg) device_printf(sc->dev, "IR code status: %d\n", stat); } - sc->dcnt = 0; + aw_ir_buf_reset(sc); } if (val & AW_IR_RXINT_ROI_EN) { /* RX FIFO overflow */ @@ -469,7 +469,8 @@ aw_ir_attach(device_t dev) &sc->intrhand)) { bus_release_resources(dev, aw_ir_spec, sc->res); device_printf(dev, "cannot setup interrupt handler\n"); - return (ENXIO); + err = ENXIO; + goto error; } /* Enable CIR Mode */ From 852d1357918224c84b1f45009e69d612da9bb956 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Wed, 12 Aug 2020 09:56:21 +0000 Subject: [PATCH 47/96] aw_cir: lower activation threshold to support NECx protocol In NECx the leading mark has length of 8T as opposed to 16T in NEC, where T is 562.5 us. So, 4.5 ms. Our threshold was set to 128 * 42.7 us (derived from the sampling frequency of 3/128 MHz). So, ~5.5 ms. The new threshold is set to AW_IR_L1_MIN. I think that's a good enough lower bound for detecting the leading pulse. Also, calculations of active_delay (which is activation delay) are fixed. Previously they would be wrong if AW_IR_ACTIVE_T was anything but zero, because the value was already bit-shifted. Finally, I am not sure why the activation delay was divided by two when calculating the initial pulse length. I have not found anything that would explain or justify it. So, I removed that division. MFC after: 3 weeks --- sys/arm/allwinner/aw_cir.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sys/arm/allwinner/aw_cir.c b/sys/arm/allwinner/aw_cir.c index c22a11fec770..8eb6a9f711d5 100644 --- a/sys/arm/allwinner/aw_cir.c +++ b/sys/arm/allwinner/aw_cir.c @@ -126,8 +126,10 @@ __FBSDID("$FreeBSD$"); #define AW_IR_DMAX 53 /* Active Thresholds */ -#define AW_IR_ACTIVE_T ((0 & 0xff) << 16) -#define AW_IR_ACTIVE_T_C ((1 & 0xff) << 23) +#define AW_IR_ACTIVE_T_VAL AW_IR_L1_MIN +#define AW_IR_ACTIVE_T (((AW_IR_ACTIVE_T_VAL - 1) & 0xff) << 16) +#define AW_IR_ACTIVE_T_C_VAL 0 +#define AW_IR_ACTIVE_T_C ((AW_IR_ACTIVE_T_C_VAL & 0xff) << 23) /* Code masks */ #define CODE_MASK 0x00ff00ff @@ -209,9 +211,9 @@ aw_ir_decode_packets(struct aw_ir_softc *sc) device_printf(sc->dev, "sc->dcnt = %d\n", sc->dcnt); /* Find Lead 1 (bit separator) */ - active_delay = (AW_IR_ACTIVE_T + 1) * (AW_IR_ACTIVE_T_C != 0 ? 128 : 1); - len = 0; - len += (active_delay >> 1); + active_delay = AW_IR_ACTIVE_T_VAL * + (AW_IR_ACTIVE_T_C_VAL != 0 ? 128 : 1); + len = active_delay; if (bootverbose) device_printf(sc->dev, "Initial len: %ld\n", len); for (i = 0; i < sc->dcnt; i++) { From d9fe3aed75275a25a18f14140481691e59f8158d Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Wed, 12 Aug 2020 09:57:28 +0000 Subject: [PATCH 48/96] aw_cir: in the pulse encoding the actual length is one greater than value While here change type of some variables from long to int, it's sufficient. Also, add length reporting to a couple of debug printfs. MFC after: 3 weeks --- sys/arm/allwinner/aw_cir.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/sys/arm/allwinner/aw_cir.c b/sys/arm/allwinner/aw_cir.c index 8eb6a9f711d5..eabab4cba8f2 100644 --- a/sys/arm/allwinner/aw_cir.c +++ b/sys/arm/allwinner/aw_cir.c @@ -202,9 +202,9 @@ aw_ir_read_data(struct aw_ir_softc *sc) static unsigned long aw_ir_decode_packets(struct aw_ir_softc *sc) { - unsigned long len, code; - unsigned char val, last; + unsigned int len, code; unsigned int active_delay; + unsigned char val, last; int i, bitcount; if (bootverbose) @@ -215,11 +215,11 @@ aw_ir_decode_packets(struct aw_ir_softc *sc) (AW_IR_ACTIVE_T_C_VAL != 0 ? 128 : 1); len = active_delay; if (bootverbose) - device_printf(sc->dev, "Initial len: %ld\n", len); + device_printf(sc->dev, "Initial len: %d\n", len); for (i = 0; i < sc->dcnt; i++) { val = sc->buf[i]; if (val & VAL_MASK) - len += val & PERIOD_MASK; + len += (val & PERIOD_MASK) + 1; else { if (len > AW_IR_L1_MIN) break; @@ -227,7 +227,7 @@ aw_ir_decode_packets(struct aw_ir_softc *sc) } } if (bootverbose) - device_printf(sc->dev, "len = %ld\n", len); + device_printf(sc->dev, "len = %d\n", len); if ((val & VAL_MASK) || (len <= AW_IR_L1_MIN)) { if (bootverbose) device_printf(sc->dev, "Bit separator error\n"); @@ -243,7 +243,7 @@ aw_ir_decode_packets(struct aw_ir_softc *sc) break; len = 0; } else - len += val & PERIOD_MASK; + len += (val & PERIOD_MASK) + 1; } if ((!(val & VAL_MASK)) || (len <= AW_IR_L0_MIN)) { if (bootverbose) @@ -260,23 +260,25 @@ aw_ir_decode_packets(struct aw_ir_softc *sc) val = sc->buf[i]; if (last) { if (val & VAL_MASK) - len += val & PERIOD_MASK; + len += (val & PERIOD_MASK) + 1; else { if (len > AW_IR_PMAX) { if (bootverbose) device_printf(sc->dev, - "Pulse error\n"); + "Pulse error, len=%d\n", + len); goto error_code; } last = 0; - len = val & PERIOD_MASK; + len = (val & PERIOD_MASK) + 1; } } else { if (val & VAL_MASK) { if (len > AW_IR_DMAX) { if (bootverbose) device_printf(sc->dev, - "Distant error\n"); + "Distance error, len=%d\n", + len); goto error_code; } else { if (len > AW_IR_DMID) { @@ -288,9 +290,9 @@ aw_ir_decode_packets(struct aw_ir_softc *sc) break; /* Finish decoding */ } last = 1; - len = val & PERIOD_MASK; + len = (val & PERIOD_MASK) + 1; } else - len += val & PERIOD_MASK; + len += (val & PERIOD_MASK) + 1; } } return (code); From da11e1f9ee3c4d9df111c31b207f67aac824541c Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Wed, 12 Aug 2020 10:17:17 +0000 Subject: [PATCH 49/96] Add support for Cortex-A76/Neoverse-N1 to hwpmc This adds support for the Cortex-A76 and Neoverse-N1 PMU counters to pmc. While here add more PMCR_IDCODE values and check the implementers code is correct before setting the PMU type. Reviewed by: bz, emaste (looks reasonable to me) Sponsored by: Innovate UK Differential Revision: https://reviews.freebsd.org/D25959 --- lib/libpmc/libpmc.c | 22 +++++++++++++++++++ sys/arm64/include/armreg.h | 15 ++++++++++--- sys/dev/hwpmc/hwpmc_arm64.c | 24 +++++++++++++++------ sys/dev/hwpmc/pmc_events.h | 43 ++++++++++++++++++++++++++++++++----- sys/sys/pmc.h | 3 ++- 5 files changed, 92 insertions(+), 15 deletions(-) diff --git a/lib/libpmc/libpmc.c b/lib/libpmc/libpmc.c index 6e39373c1cb4..7d435cab0ff0 100644 --- a/lib/libpmc/libpmc.c +++ b/lib/libpmc/libpmc.c @@ -176,6 +176,11 @@ static const struct pmc_event_descr cortex_a57_event_table[] = __PMC_EV_ALIAS_ARMV8_CORTEX_A57() }; +static const struct pmc_event_descr cortex_a76_event_table[] = +{ + __PMC_EV_ALIAS_ARMV8_CORTEX_A76() +}; + /* * PMC_MDEP_TABLE(NAME, PRIMARYCLASS, ADDITIONAL_CLASSES...) * @@ -193,6 +198,7 @@ PMC_MDEP_TABLE(cortex_a8, ARMV7, PMC_CLASS_SOFT, PMC_CLASS_ARMV7); PMC_MDEP_TABLE(cortex_a9, ARMV7, PMC_CLASS_SOFT, PMC_CLASS_ARMV7); PMC_MDEP_TABLE(cortex_a53, ARMV8, PMC_CLASS_SOFT, PMC_CLASS_ARMV8); PMC_MDEP_TABLE(cortex_a57, ARMV8, PMC_CLASS_SOFT, PMC_CLASS_ARMV8); +PMC_MDEP_TABLE(cortex_a76, ARMV8, PMC_CLASS_SOFT, PMC_CLASS_ARMV8); PMC_MDEP_TABLE(mips24k, MIPS24K, PMC_CLASS_SOFT, PMC_CLASS_MIPS24K); PMC_MDEP_TABLE(mips74k, MIPS74K, PMC_CLASS_SOFT, PMC_CLASS_MIPS74K); PMC_MDEP_TABLE(octeon, OCTEON, PMC_CLASS_SOFT, PMC_CLASS_OCTEON); @@ -235,6 +241,7 @@ PMC_CLASS_TABLE_DESC(cortex_a9, ARMV7, cortex_a9, armv7); #if defined(__aarch64__) PMC_CLASS_TABLE_DESC(cortex_a53, ARMV8, cortex_a53, arm64); PMC_CLASS_TABLE_DESC(cortex_a57, ARMV8, cortex_a57, arm64); +PMC_CLASS_TABLE_DESC(cortex_a76, ARMV8, cortex_a76, arm64); #endif #if defined(__mips__) PMC_CLASS_TABLE_DESC(beri, BERI, beri, mips); @@ -817,6 +824,9 @@ static struct pmc_event_alias cortex_a53_aliases[] = { static struct pmc_event_alias cortex_a57_aliases[] = { EV_ALIAS(NULL, NULL) }; +static struct pmc_event_alias cortex_a76_aliases[] = { + EV_ALIAS(NULL, NULL) +}; static int arm64_allocate_pmc(enum pmc_event pe, char *ctrspec __unused, struct pmc_op_pmcallocate *pmc_config __unused) @@ -1273,6 +1283,10 @@ pmc_event_names_of_class(enum pmc_class cl, const char ***eventnames, ev = cortex_a57_event_table; count = PMC_EVENT_TABLE_SIZE(cortex_a57); break; + case PMC_CPU_ARMV8_CORTEX_A76: + ev = cortex_a76_event_table; + count = PMC_EVENT_TABLE_SIZE(cortex_a76); + break; } break; case PMC_CLASS_BERI: @@ -1518,6 +1532,10 @@ pmc_init(void) PMC_MDEP_INIT(cortex_a57); pmc_class_table[n] = &cortex_a57_class_table_descr; break; + case PMC_CPU_ARMV8_CORTEX_A76: + PMC_MDEP_INIT(cortex_a76); + pmc_class_table[n] = &cortex_a76_class_table_descr; + break; #endif #if defined(__mips__) case PMC_CPU_MIPS_BERI: @@ -1658,6 +1676,10 @@ _pmc_name_of_event(enum pmc_event pe, enum pmc_cputype cpu) ev = cortex_a57_event_table; evfence = cortex_a57_event_table + PMC_EVENT_TABLE_SIZE(cortex_a57); break; + case PMC_CPU_ARMV8_CORTEX_A76: + ev = cortex_a76_event_table; + evfence = cortex_a76_event_table + PMC_EVENT_TABLE_SIZE(cortex_a76); + break; default: /* Unknown CPU type. */ break; } diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h index c5091e93efe2..9cac6fce439b 100644 --- a/sys/arm64/include/armreg.h +++ b/sys/arm64/include/armreg.h @@ -857,11 +857,20 @@ #define PMCR_LC (1 << 6) /* Long cycle count enable */ #define PMCR_IMP_SHIFT 24 /* Implementer code */ #define PMCR_IMP_MASK (0xff << PMCR_IMP_SHIFT) +#define PMCR_IMP_ARM 0x41 #define PMCR_IDCODE_SHIFT 16 /* Identification code */ #define PMCR_IDCODE_MASK (0xff << PMCR_IDCODE_SHIFT) -#define PMCR_IDCODE_CORTEX_A57 0x01 -#define PMCR_IDCODE_CORTEX_A72 0x02 -#define PMCR_IDCODE_CORTEX_A53 0x03 +#define PMCR_IDCODE_CORTEX_A57 0x01 +#define PMCR_IDCODE_CORTEX_A72 0x02 +#define PMCR_IDCODE_CORTEX_A53 0x03 +#define PMCR_IDCODE_CORTEX_A73 0x04 +#define PMCR_IDCODE_CORTEX_A35 0x0a +#define PMCR_IDCODE_CORTEX_A76 0x0b +#define PMCR_IDCODE_NEOVERSE_N1 0x0c +#define PMCR_IDCODE_CORTEX_A77 0x10 +#define PMCR_IDCODE_CORTEX_A55 0x45 +#define PMCR_IDCODE_NEOVERSE_E1 0x46 +#define PMCR_IDCODE_CORTEX_A75 0x4a #define PMCR_N_SHIFT 11 /* Number of counters implemented */ #define PMCR_N_MASK (0x1f << PMCR_N_SHIFT) diff --git a/sys/dev/hwpmc/hwpmc_arm64.c b/sys/dev/hwpmc/hwpmc_arm64.c index 2618a889e86f..4ae8645abaf6 100644 --- a/sys/dev/hwpmc/hwpmc_arm64.c +++ b/sys/dev/hwpmc/hwpmc_arm64.c @@ -479,11 +479,12 @@ pmc_arm64_initialize() { struct pmc_mdep *pmc_mdep; struct pmc_classdep *pcd; - int idcode; + int idcode, impcode; int reg; reg = arm64_pmcr_read(); arm64_npmcs = (reg & PMCR_N_MASK) >> PMCR_N_SHIFT; + impcode = (reg & PMCR_IMP_MASK) >> PMCR_IMP_SHIFT; idcode = (reg & PMCR_IDCODE_MASK) >> PMCR_IDCODE_SHIFT; PMCDBG1(MDP, INI, 1, "arm64-init npmcs=%d", arm64_npmcs); @@ -498,13 +499,24 @@ pmc_arm64_initialize() /* Just one class */ pmc_mdep = pmc_mdep_alloc(1); - switch (idcode) { - case PMCR_IDCODE_CORTEX_A57: - case PMCR_IDCODE_CORTEX_A72: - pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A57; + switch(impcode) { + case PMCR_IMP_ARM: + switch (idcode) { + case PMCR_IDCODE_CORTEX_A76: + case PMCR_IDCODE_NEOVERSE_N1: + pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A76; + break; + case PMCR_IDCODE_CORTEX_A57: + case PMCR_IDCODE_CORTEX_A72: + pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A57; + break; + default: + case PMCR_IDCODE_CORTEX_A53: + pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A53; + break; + } break; default: - case PMCR_IDCODE_CORTEX_A53: pmc_mdep->pmd_cputype = PMC_CPU_ARMV8_CORTEX_A53; break; } diff --git a/sys/dev/hwpmc/pmc_events.h b/sys/dev/hwpmc/pmc_events.h index 6f7282f8ea55..cb3c299b3aab 100644 --- a/sys/dev/hwpmc/pmc_events.h +++ b/sys/dev/hwpmc/pmc_events.h @@ -955,7 +955,7 @@ __PMC_EV_ALIAS("unhalted-core-cycles", IAP_ARCH_UNH_COR_CYC) __PMC_EV_ALIAS("BR_RETURN_RETIRED", ARMV8_EVENT_0EH) \ __PMC_EV_ALIAS("UNALIGNED_LDST_RETIRED",ARMV8_EVENT_0FH) -#define __PMC_EV_ALIAS_ARMV8_CORTEX_A57() \ +#define __PMC_EV_ALIAS_ARMV8_CORTEX_A57_A76() \ __PMC_EV_ALIAS_ARMV8_COMMON() \ __PMC_EV_ALIAS("INST_SPEC", ARMV8_EVENT_1BH) \ __PMC_EV_ALIAS("TTBR_WRITE_RETIRED", ARMV8_EVENT_1CH) \ @@ -975,10 +975,6 @@ __PMC_EV_ALIAS("unhalted-core-cycles", IAP_ARCH_UNH_COR_CYC) __PMC_EV_ALIAS("L2D_CACHE_WB_VICTIM", ARMV8_EVENT_56H) \ __PMC_EV_ALIAS("L2D_CACHE_WB_CLEAN", ARMV8_EVENT_57H) \ __PMC_EV_ALIAS("L2D_CACHE_INVAL", ARMV8_EVENT_58H) \ - __PMC_EV_ALIAS("BUS_ACCESS_SHARED", ARMV8_EVENT_62H) \ - __PMC_EV_ALIAS("BUS_ACCESS_NOT_SHARED", ARMV8_EVENT_63H) \ - __PMC_EV_ALIAS("BUS_ACCESS_NORMAL", ARMV8_EVENT_64H) \ - __PMC_EV_ALIAS("BUS_ACCESS_PERIPH", ARMV8_EVENT_65H) \ __PMC_EV_ALIAS("MEM_ACCESS_LD", ARMV8_EVENT_66H) \ __PMC_EV_ALIAS("MEM_ACCESS_ST", ARMV8_EVENT_67H) \ __PMC_EV_ALIAS("UNALIGNED_LD_SPEC", ARMV8_EVENT_68H) \ @@ -1014,6 +1010,43 @@ __PMC_EV_ALIAS("unhalted-core-cycles", IAP_ARCH_UNH_COR_CYC) __PMC_EV_ALIAS("RC_LD_SPEC", ARMV8_EVENT_90H) \ __PMC_EV_ALIAS("RC_ST_SPEC", ARMV8_EVENT_91H) +#define __PMC_EV_ALIAS_ARMV8_CORTEX_A57() \ + __PMC_EV_ALIAS_ARMV8_CORTEX_A57_A76() \ + __PMC_EV_ALIAS("BUS_ACCESS_SHARED", ARMV8_EVENT_62H) \ + __PMC_EV_ALIAS("BUS_ACCESS_NOT_SHARED", ARMV8_EVENT_63H) \ + __PMC_EV_ALIAS("BUS_ACCESS_NORMAL", ARMV8_EVENT_64H) \ + __PMC_EV_ALIAS("BUS_ACCESS_PERIPH", ARMV8_EVENT_65H) + +#define __PMC_EV_ALIAS_ARMV8_CORTEX_A76() \ + __PMC_EV_ALIAS_ARMV8_CORTEX_A57_A76() \ + __PMC_EV_ALIAS("L2D_CACHE_ALLOCATE", ARMV8_EVENT_20H) \ + __PMC_EV_ALIAS("BR_RETIRED", ARMV8_EVENT_21H) \ + __PMC_EV_ALIAS("BR_MIS_PRED_RETIRED", ARMV8_EVENT_22H) \ + __PMC_EV_ALIAS("STALL_FRONTEND", ARMV8_EVENT_23H) \ + __PMC_EV_ALIAS("STALL_BACKEND", ARMV8_EVENT_24H) \ + __PMC_EV_ALIAS("L1D_TLB", ARMV8_EVENT_25H) \ + __PMC_EV_ALIAS("L1I_TLB", ARMV8_EVENT_26H) \ + __PMC_EV_ALIAS("L3D_CACHE_ALLOCATE", ARMV8_EVENT_29H) \ + __PMC_EV_ALIAS("L3D_CACHE_REFILL", ARMV8_EVENT_2AH) \ + __PMC_EV_ALIAS("L3D_CACHE", ARMV8_EVENT_2BH) \ + __PMC_EV_ALIAS("L2D_TLB_REFILL", ARMV8_EVENT_2DH) \ + __PMC_EV_ALIAS("L2D_TLB", ARMV8_EVENT_2FH) \ + __PMC_EV_ALIAS("REMOTE_ACCESS", ARMV8_EVENT_31H) \ + __PMC_EV_ALIAS("DTLB_WALK", ARMV8_EVENT_34H) \ + __PMC_EV_ALIAS("ITLB_WALK", ARMV8_EVENT_35H) \ + __PMC_EV_ALIAS("LL_CACHE_RD", ARMV8_EVENT_36H) \ + __PMC_EV_ALIAS("LL_CACHE_MISS_RD", ARMV8_EVENT_37H) \ + __PMC_EV_ALIAS("L1D_CACHE_REFILL_INNER", ARMV8_EVENT_44H) \ + __PMC_EV_ALIAS("L1D_CACHE_REFILL_OUTER", ARMV8_EVENT_45H) \ + __PMC_EV_ALIAS("L1D_TLB_RD", ARMV8_EVENT_4EH) \ + __PMC_EV_ALIAS("L1D_TLB_WR", ARMV8_EVENT_4FH) \ + __PMC_EV_ALIAS("L2D_TLB_REFILL_RD", ARMV8_EVENT_5CH) \ + __PMC_EV_ALIAS("L2D_TLB_REFILL_WR", ARMV8_EVENT_5DH) \ + __PMC_EV_ALIAS("L2D_TLB_RD", ARMV8_EVENT_5EH) \ + __PMC_EV_ALIAS("L2D_TLB_WR", ARMV8_EVENT_5FH) \ + __PMC_EV_ALIAS("STREX_SPEC", ARMV8_EVENT_6FH) \ + __PMC_EV_ALIAS("L3_CACHE_RD", ARMV8_EVENT_A0H) + /* * MIPS Events from "Programming the MIPS32 24K Core Family", * Document Number: MD00355 Revision 04.63 December 19, 2008 diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h index 7e14df30bff8..224d84c484f4 100644 --- a/sys/sys/pmc.h +++ b/sys/sys/pmc.h @@ -127,7 +127,8 @@ extern char pmc_cpuid[PMC_CPUID_LEN]; __PMC_CPU(ARMV7_CORTEX_A15, 0x504, "ARMv7 Cortex A15") \ __PMC_CPU(ARMV7_CORTEX_A17, 0x505, "ARMv7 Cortex A17") \ __PMC_CPU(ARMV8_CORTEX_A53, 0x600, "ARMv8 Cortex A53") \ - __PMC_CPU(ARMV8_CORTEX_A57, 0x601, "ARMv8 Cortex A57") + __PMC_CPU(ARMV8_CORTEX_A57, 0x601, "ARMv8 Cortex A57") \ + __PMC_CPU(ARMV8_CORTEX_A76, 0x602, "ARMv8 Cortex A76") enum pmc_cputype { #undef __PMC_CPU From 758fac8f871b348f5c2f700aeee0e20c170bb1b8 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Wed, 12 Aug 2020 11:36:09 +0000 Subject: [PATCH 50/96] hook gpiokeys.4 to the build Reported by: 0mp MFC after: 3 days X-MFC with: r363905 --- share/man/man4/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 9049f3feb5e3..41c08f6e2e7a 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -171,6 +171,7 @@ MAN= aac.4 \ gif.4 \ gpio.4 \ gpioiic.4 \ + gpiokeys.4 \ gpioled.4 \ gpioths.4 \ gre.4 \ From a089fa298dbe7ac1b164e941753ec762530715cd Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Wed, 12 Aug 2020 11:37:28 +0000 Subject: [PATCH 51/96] hook cp2112.4 to the build Reported by: 0mp MFC after: 1 week X-MFC with: r364144 --- share/man/man4/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 41c08f6e2e7a..95ed799361f2 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -113,6 +113,7 @@ MAN= aac.4 \ cloudabi.4 \ cmx.4 \ ${_coretemp.4} \ + cp2112.4 \ ${_cpuctl.4} \ cpufreq.4 \ crypto.4 \ From 530960be8d6f1a1b74e92ab1eed9b3225fcf6a4b Mon Sep 17 00:00:00 2001 From: Vincenzo Maffione Date: Wed, 12 Aug 2020 14:17:38 +0000 Subject: [PATCH 52/96] iflib: refactor netmap_fl_refill and fix off-by-one issue First, fix the initialization of the fl->ifl_rxd_idxs array, which was affected by an off-by-one bug. Once there, refactor the function to use better names for local variables, optimize the variable assignments, and merge the bus_dmamap_sync() inner loop with the outer one. PR: 248494 MFC after: 3 weeks --- sys/net/iflib.c | 48 +++++++++++++++++++++--------------------------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/sys/net/iflib.c b/sys/net/iflib.c index b7cc308d22f2..a8f04e662aa5 100644 --- a/sys/net/iflib.c +++ b/sys/net/iflib.c @@ -838,39 +838,41 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring *kring, uint32_t nm_i, boo struct if_rxd_update iru; if_ctx_t ctx = rxq->ifr_ctx; iflib_fl_t fl = &rxq->ifr_fl[0]; - uint32_t refill_pidx, nic_i; + uint32_t nic_i_first, nic_i; + int i; #if IFLIB_DEBUG_COUNTERS int rf_count = 0; #endif if (nm_i == head && __predict_true(!init)) - return 0; + return (0); + iru_init(&iru, rxq, 0 /* flid */); map = fl->ifl_sds.ifsd_map; - refill_pidx = netmap_idx_k2n(kring, nm_i); + nic_i = netmap_idx_k2n(kring, nm_i); /* * IMPORTANT: we must leave one free slot in the ring, * so move head back by one unit */ head = nm_prev(head, lim); - nic_i = UINT_MAX; DBG_COUNTER_INC(fl_refills); while (nm_i != head) { #if IFLIB_DEBUG_COUNTERS if (++rf_count == 9) DBG_COUNTER_INC(fl_refills_large); #endif - for (int tmp_pidx = 0; tmp_pidx < IFLIB_MAX_RX_REFRESH && nm_i != head; tmp_pidx++) { + nic_i_first = nic_i; + for (i = 0; i < IFLIB_MAX_RX_REFRESH && nm_i != head; i++) { struct netmap_slot *slot = &ring->slot[nm_i]; - void *addr = PNMB(na, slot, &fl->ifl_bus_addrs[tmp_pidx]); - uint32_t nic_i_dma = refill_pidx; - nic_i = netmap_idx_k2n(kring, nm_i); + void *addr = PNMB(na, slot, &fl->ifl_bus_addrs[i]); - MPASS(tmp_pidx < IFLIB_MAX_RX_REFRESH); + MPASS(i < IFLIB_MAX_RX_REFRESH); if (addr == NETMAP_BUF_BASE(na)) /* bad buf */ return netmap_ring_reinit(kring); + fl->ifl_rxd_idxs[i] = nic_i; + if (__predict_false(init)) { netmap_load_map(na, fl->ifl_buf_tag, map[nic_i], addr); @@ -879,33 +881,25 @@ netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring *kring, uint32_t nm_i, boo netmap_reload_map(na, fl->ifl_buf_tag, map[nic_i], addr); } + bus_dmamap_sync(fl->ifl_buf_tag, map[nic_i], + BUS_DMASYNC_PREREAD); slot->flags &= ~NS_BUF_CHANGED; nm_i = nm_next(nm_i, lim); - fl->ifl_rxd_idxs[tmp_pidx] = nic_i = nm_next(nic_i, lim); - if (nm_i != head && tmp_pidx < IFLIB_MAX_RX_REFRESH-1) - continue; - - iru.iru_pidx = refill_pidx; - iru.iru_count = tmp_pidx+1; - ctx->isc_rxd_refill(ctx->ifc_softc, &iru); - refill_pidx = nic_i; - for (int n = 0; n < iru.iru_count; n++) { - bus_dmamap_sync(fl->ifl_buf_tag, map[nic_i_dma], - BUS_DMASYNC_PREREAD); - /* XXX - change this to not use the netmap func*/ - nic_i_dma = nm_next(nic_i_dma, lim); - } + nic_i = nm_next(nic_i, lim); } + + iru.iru_pidx = nic_i_first; + iru.iru_count = i; + ctx->isc_rxd_refill(ctx->ifc_softc, &iru); } kring->nr_hwcur = head; bus_dmamap_sync(fl->ifl_ifdi->idi_tag, fl->ifl_ifdi->idi_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - if (__predict_true(nic_i != UINT_MAX)) { - ctx->isc_rxd_flush(ctx->ifc_softc, rxq->ifr_id, fl->ifl_id, nic_i); - DBG_COUNTER_INC(rxd_flush); - } + ctx->isc_rxd_flush(ctx->ifc_softc, rxq->ifr_id, fl->ifl_id, nic_i); + DBG_COUNTER_INC(rxd_flush); + return (0); } From 6d84e76a25fd52200d6f197d8784ea784c6f5784 Mon Sep 17 00:00:00 2001 From: Vincenzo Maffione Date: Wed, 12 Aug 2020 14:45:31 +0000 Subject: [PATCH 53/96] iflib: netmap: improve rxsync to support IFLIB_HAS_RXCQ For drivers with IFLIB_HAS_RXCQ set, there is a separate completion queue. In this case, the netmap rxsync routine needs to update rxq->ifr_cq_cidx in the same way it is updated by iflib_rxeof(). This improves the situation for vmx(4) and bnxt(4) drivers, which use iflib and have the IFLIB_HAS_RXCQ bit set. PR: 248494 MFC after: 3 weeks --- sys/net/iflib.c | 38 ++++++++++++++++++++++++++++---------- sys/net/iflib.h | 4 ++-- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/sys/net/iflib.c b/sys/net/iflib.c index a8f04e662aa5..fd3384a5175d 100644 --- a/sys/net/iflib.c +++ b/sys/net/iflib.c @@ -424,7 +424,7 @@ struct iflib_rxq { struct pfil_head *pfil; /* * If there is a separate completion queue (IFLIB_HAS_RXCQ), this is - * the command queue consumer index. Otherwise it's unused. + * the completion queue consumer index. Otherwise it's unused. */ qidx_t ifr_cq_cidx; uint16_t ifr_id; @@ -1077,9 +1077,12 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int flags) int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR; if_ctx_t ctx = ifp->if_softc; + if_shared_ctx_t sctx = ctx->ifc_sctx; + if_softc_ctx_t scctx = &ctx->ifc_softc_ctx; iflib_rxq_t rxq = &ctx->ifc_rxqs[kring->ring_id]; iflib_fl_t fl = &rxq->ifr_fl[0]; struct if_rxd_info ri; + qidx_t *cidxp; /* * netmap only uses free list 0, to avoid out of order consumption @@ -1093,40 +1096,56 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int flags) * First part: import newly received packets. * * nm_i is the index of the next free slot in the netmap ring, - * nic_i is the index of the next received packet in the NIC ring, - * and they may differ in case if_init() has been called while + * nic_i is the index of the next received packet in the NIC ring + * (or in the free list 0 if IFLIB_HAS_RXCQ is set), and they may + * differ in case if_init() has been called while * in netmap mode. For the receive ring we have * - * nic_i = rxr->next_check; + * nic_i = fl->ifl_cidx; * nm_i = kring->nr_hwtail (previous) * and * nm_i == (nic_i + kring->nkr_hwofs) % ring_size * - * rxr->next_check is set to 0 on a ring reinit + * fl->ifl_cidx is set to 0 on a ring reinit */ if (netmap_no_pendintr || force_update) { uint32_t hwtail_lim = nm_prev(kring->nr_hwcur, lim); + bool have_rxcq = sctx->isc_flags & IFLIB_HAS_RXCQ; int crclen = iflib_crcstrip ? 0 : 4; int error, avail; + /* + * For the free list consumer index, we use the same + * logic as in iflib_rxeof(). + */ + if (have_rxcq) + cidxp = &rxq->ifr_cq_cidx; + else + cidxp = &fl->ifl_cidx; + avail = ctx->isc_rxd_available(ctx->ifc_softc, + rxq->ifr_id, *cidxp, USHRT_MAX); + nic_i = fl->ifl_cidx; nm_i = netmap_idx_n2k(kring, nic_i); - avail = ctx->isc_rxd_available(ctx->ifc_softc, - rxq->ifr_id, nic_i, USHRT_MAX); for (n = 0; avail > 0 && nm_i != hwtail_lim; n++, avail--) { rxd_info_zero(&ri); ri.iri_frags = rxq->ifr_frags; ri.iri_qsidx = kring->ring_id; ri.iri_ifp = ctx->ifc_ifp; - ri.iri_cidx = nic_i; + ri.iri_cidx = *cidxp; error = ctx->isc_rxd_pkt_get(ctx->ifc_softc, &ri); ring->slot[nm_i].len = error ? 0 : ri.iri_len - crclen; ring->slot[nm_i].flags = 0; + if (have_rxcq) { + *cidxp = ri.iri_cidx; + while (*cidxp >= scctx->isc_nrxd[0]) + *cidxp -= scctx->isc_nrxd[0]; + } bus_dmamap_sync(fl->ifl_buf_tag, fl->ifl_sds.ifsd_map[nic_i], BUS_DMASYNC_POSTREAD); nm_i = nm_next(nm_i, lim); - nic_i = nm_next(nic_i, lim); + fl->ifl_cidx = nic_i = nm_next(nic_i, lim); } if (n) { /* update the state variables */ if (netmap_no_pendintr && !force_update) { @@ -1134,7 +1153,6 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int flags) iflib_rx_miss ++; iflib_rx_miss_bufs += n; } - fl->ifl_cidx = nic_i; kring->nr_hwtail = nm_i; } kring->nr_kflags &= ~NKR_PENDINTR; diff --git a/sys/net/iflib.h b/sys/net/iflib.h index 99f13438f800..e2d32c563513 100644 --- a/sys/net/iflib.h +++ b/sys/net/iflib.h @@ -297,7 +297,7 @@ typedef enum { } iflib_intr_type_t; /* - * Interface has a separate command queue for RX + * Interface has a separate completion queue for RX */ #define IFLIB_HAS_RXCQ 0x01 /* @@ -309,7 +309,7 @@ typedef enum { */ #define IFLIB_IS_VF 0x04 /* - * Interface has a separate command queue for TX + * Interface has a separate completion queue for TX */ #define IFLIB_HAS_TXCQ 0x08 /* From 188d6f4bc6bd8fd2e5c777b733164fb8b2782dd2 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Wed, 12 Aug 2020 15:49:06 +0000 Subject: [PATCH 54/96] Fix crunchgen usage of mkstemp() On Glibc systems mkstemp can only be used once with the same template string since it will be modified in-place and no longer contain any 'X' chars. It is fine to reuse the same file here but we need to be explicit and use open() instead of mkstemp() on the second use. While touching this file also avoid a hardcoded /bin/pwd since that may not work when building on non-FreeBSD systems. Reviewed By: brooks Differential Revision: https://reviews.freebsd.org/D25990 --- usr.sbin/crunch/crunchgen/crunchgen.c | 36 +++++++++++++++++++-------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/usr.sbin/crunch/crunchgen/crunchgen.c b/usr.sbin/crunch/crunchgen/crunchgen.c index dc0510e24e6a..e408b5884b55 100644 --- a/usr.sbin/crunch/crunchgen/crunchgen.c +++ b/usr.sbin/crunch/crunchgen/crunchgen.c @@ -39,10 +39,13 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include +#include #include #include #include +#include #include #define CRUNCH_VERSION "0.2" @@ -91,6 +94,7 @@ prog_t *progs = NULL; char confname[MAXPATHLEN], infilename[MAXPATHLEN]; char outmkname[MAXPATHLEN], outcfname[MAXPATHLEN], execfname[MAXPATHLEN]; char tempfname[MAXPATHLEN], cachename[MAXPATHLEN], curfilename[MAXPATHLEN]; +bool tempfname_initialized = false; char outhdrname[MAXPATHLEN] ; /* user-supplied header for *.mk */ char *objprefix; /* where are the objects ? */ char *path_make; @@ -216,6 +220,7 @@ main(int argc, char **argv) snprintf(cachename, sizeof(cachename), "%s.cache", confname); snprintf(tempfname, sizeof(tempfname), "%s/crunchgen_%sXXXXXX", getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP, confname); + tempfname_initialized = false; parse_conf_file(); if (list_mode) @@ -648,8 +653,7 @@ fillin_program(prog_t *p) /* Determine the actual srcdir (maybe symlinked). */ if (p->srcdir) { - snprintf(line, MAXLINELEN, "cd %s && echo -n `/bin/pwd`", - p->srcdir); + snprintf(line, MAXLINELEN, "cd %s && pwd", p->srcdir); f = popen(line,"r"); if (!f) errx(1, "Can't execute: %s\n", line); @@ -721,14 +725,26 @@ fillin_program_objs(prog_t *p, char *path) /* discover the objs from the srcdir Makefile */ - if ((fd = mkstemp(tempfname)) == -1) { - perror(tempfname); - exit(1); + /* + * We reuse the same temporary file name for multiple objects. However, + * some libc implementations (such as glibc) return EINVAL if there + * are no XXXXX characters in the template. This happens after the + * first call to mkstemp since the argument is modified in-place. + * To avoid this error we use open() instead of mkstemp() after the + * call to mkstemp(). + */ + if (tempfname_initialized) { + if ((fd = open(tempfname, O_CREAT | O_EXCL | O_RDWR, 0600)) == -1) { + err(EX_OSERR, "open(%s)", tempfname); + } + } else if ((fd = mkstemp(tempfname)) == -1) { + err(EX_OSERR, "mkstemp(%s)", tempfname); } + tempfname_initialized = true; if ((f = fdopen(fd, "w")) == NULL) { - warn("%s", tempfname); + warn("fdopen(%s)", tempfname); goterror = 1; - return; + goto out; } if (p->objvar) objvar = p->objvar; @@ -763,14 +779,14 @@ fillin_program_objs(prog_t *p, char *path) if ((f = popen(line, "r")) == NULL) { warn("submake pipe"); goterror = 1; - return; + goto out; } while(fgets(line, MAXLINELEN, f)) { if (strncmp(line, "OBJS= ", 6)) { warnx("make error: %s", line); goterror = 1; - continue; + goto out; } cp = line + 6; @@ -793,7 +809,7 @@ fillin_program_objs(prog_t *p, char *path) warnx("make error: make returned %d", rc); goterror = 1; } - +out: unlink(tempfname); } From cad2917baf6e8d90720f5bfb2463dfa7be35f568 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Wed, 12 Aug 2020 15:49:10 +0000 Subject: [PATCH 55/96] Fix stand/newvers.sh with zsh in sh mode When building on macOS with sh==zsh, newvers.sh was producing an unterminated string literal due to \\n being turned as a newline. Fix this by using a here document instead. Reviewed By: imp Differential Revision: https://reviews.freebsd.org/D26036 --- stand/common/newvers.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/stand/common/newvers.sh b/stand/common/newvers.sh index 75efeceab26b..714adba6c9cb 100755 --- a/stand/common/newvers.sh +++ b/stand/common/newvers.sh @@ -55,6 +55,8 @@ if [ -n "${include_metadata}" ]; then bootprog_info="$bootprog_info(${t} ${u}@${h})\\n" fi -echo "char bootprog_info[] = \"$bootprog_info\";" > $tempfile -echo "unsigned bootprog_rev = ${r%%.*}${r##*.};" >> $tempfile +cat > $tempfile < Date: Wed, 12 Aug 2020 16:08:44 +0000 Subject: [PATCH 56/96] linprocfs: Fix some inaccuracies in meminfo. - Fill out MemFree correctly. Delete an ancient comment suggesting that we don't want to advertise the true quantity of free memory. - Populate the Buffers field by reading vfs.bufspace. - The page cache consists of all pages in page queues, not just the inactive queue. PR: 248463 Reported and tested by: danfe MFC after: 1 week Sponsored by: The FreeBSD Foundation --- sys/compat/linprocfs/linprocfs.c | 40 ++++++++++++++------------------ 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c index 2dd9b43ac017..f2e5d2ba36e1 100644 --- a/sys/compat/linprocfs/linprocfs.c +++ b/sys/compat/linprocfs/linprocfs.c @@ -145,41 +145,35 @@ static int linprocfs_domeminfo(PFS_FILL_ARGS) { unsigned long memtotal; /* total memory in bytes */ - unsigned long memused; /* used memory in bytes */ unsigned long memfree; /* free memory in bytes */ - unsigned long buffers, cached; /* buffer / cache memory ??? */ + unsigned long cached; /* page cache */ + unsigned long buffers; /* buffer cache */ unsigned long long swaptotal; /* total swap space in bytes */ unsigned long long swapused; /* used swap space in bytes */ unsigned long long swapfree; /* free swap space in bytes */ - int i, j; + size_t sz; + int error, i, j; memtotal = physmem * PAGE_SIZE; - /* - * The correct thing here would be: - * - memfree = vm_free_count() * PAGE_SIZE; - memused = memtotal - memfree; - * - * but it might mislead linux binaries into thinking there - * is very little memory left, so we cheat and tell them that - * all memory that isn't wired down is free. - */ - memused = vm_wire_count() * PAGE_SIZE; - memfree = memtotal - memused; + memfree = (unsigned long)vm_free_count() * PAGE_SIZE; swap_pager_status(&i, &j); swaptotal = (unsigned long long)i * PAGE_SIZE; swapused = (unsigned long long)j * PAGE_SIZE; swapfree = swaptotal - swapused; + /* - * We'd love to be able to write: - * - buffers = bufspace; - * - * but bufspace is internal to vfs_bio.c and we don't feel - * like unstaticizing it just for linprocfs's sake. + * This value may exclude wired pages, but we have no good way of + * accounting for that. */ - buffers = 0; - cached = vm_inactive_count() * PAGE_SIZE; + cached = + (vm_active_count() + vm_inactive_count() + vm_laundry_count()) * + PAGE_SIZE; + + sz = sizeof(buffers); + error = kernel_sysctlbyname(curthread, "vfs.bufspace", &buffers, &sz, + NULL, 0, 0, 0); + if (error != 0) + buffers = 0; sbuf_printf(sb, "MemTotal: %9lu kB\n" From f7d79f6c6d50b5ddba2ca9936345bf6f07837c1a Mon Sep 17 00:00:00 2001 From: Mitchell Horne Date: Wed, 12 Aug 2020 16:43:20 +0000 Subject: [PATCH 57/96] Correctly set error in rt_mpath_unlink It is possible for rn_delete() to return NULL. If this happens, then set *perror to ESRCH, as is done in the rest of the function. Sponsored by: NetApp, Inc. Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D25871 --- sys/net/route.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/net/route.c b/sys/net/route.c index f24200a88e40..8795dde43725 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -1107,7 +1107,11 @@ rt_mpath_unlink(struct rib_head *rnh, struct rt_addrinfo *info, rn = rnh->rnh_deladdr(info->rti_info[RTAX_DST], info->rti_info[RTAX_NETMASK], &rnh->head); - *perror = 0; + if (rn != NULL) { + *perror = 0; + } else { + *perror = ESRCH; + } return (rn); } From d5c62a6f032e9fac5cf108d4a3ef0126a54dea19 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Wed, 12 Aug 2020 17:27:24 +0000 Subject: [PATCH 58/96] Use env pwd instead of pwd in crunchgen.c In r364166 I changed /bin/pwd to pwd, but pwd can be shell builtin that may not correctly return a real path. To ensure that all symlinks are resolved use `env pwd -P` instead (the -P flag is part of POSIX so should be supported everywhere). Reported By: rgrimes Suggested By: jrtc27 --- usr.sbin/crunch/crunchgen/crunchgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/crunch/crunchgen/crunchgen.c b/usr.sbin/crunch/crunchgen/crunchgen.c index e408b5884b55..914795be7a21 100644 --- a/usr.sbin/crunch/crunchgen/crunchgen.c +++ b/usr.sbin/crunch/crunchgen/crunchgen.c @@ -653,7 +653,7 @@ fillin_program(prog_t *p) /* Determine the actual srcdir (maybe symlinked). */ if (p->srcdir) { - snprintf(line, MAXLINELEN, "cd %s && pwd", p->srcdir); + snprintf(line, MAXLINELEN, "cd %s && env pwd -P", p->srcdir); f = popen(line,"r"); if (!f) errx(1, "Can't execute: %s\n", line); From 90699f2a767445c0b2eaaaeed582b8e86ccc9601 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 12 Aug 2020 18:45:36 +0000 Subject: [PATCH 59/96] Correct padding length for RISC-V PCPU data. There was an additional 7 bytes of compiler-inserted padding at the end of the structure visible via 'ptype /o' in gdb. Reviewed by: mhorne Obtained from: CheriBSD Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D25867 --- sys/riscv/include/pcpu.h | 2 +- sys/riscv/include/pcpu_aux.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/riscv/include/pcpu.h b/sys/riscv/include/pcpu.h index 46b258380a10..5068596462fc 100644 --- a/sys/riscv/include/pcpu.h +++ b/sys/riscv/include/pcpu.h @@ -48,7 +48,7 @@ struct pmap *pc_curpmap; /* Currently active pmap */ \ uint32_t pc_pending_ipis; /* IPIs pending to this CPU */ \ uint32_t pc_hart; /* Hart ID */ \ - char __pad[49] + char __pad[56] /* Pad to factor of PAGE_SIZE */ #ifdef _KERNEL diff --git a/sys/riscv/include/pcpu_aux.h b/sys/riscv/include/pcpu_aux.h index 3d4c70c491d6..9fecd25c67cb 100644 --- a/sys/riscv/include/pcpu_aux.h +++ b/sys/riscv/include/pcpu_aux.h @@ -46,6 +46,9 @@ * be a multiple of the size of struct pcpu. */ _Static_assert(PAGE_SIZE % sizeof(struct pcpu) == 0, "fix pcpu size"); +_Static_assert(offsetof(struct pcpu, __pad) + + sizeof(((struct pcpu *)0)->__pad) == sizeof(struct pcpu), + "fix pcpu padding"); extern struct pcpu __pcpu[]; From e8cc9e1d844ab1a747a7bde1d6be68c3f7615804 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 12 Aug 2020 19:11:53 +0000 Subject: [PATCH 60/96] Report attachment for nvd same as reported for nda. MFC after: 1 week --- sys/dev/nvd/nvd.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/sys/dev/nvd/nvd.c b/sys/dev/nvd/nvd.c index 8ac8c2bf9963..1e8488867844 100644 --- a/sys/dev/nvd/nvd.c +++ b/sys/dev/nvd/nvd.c @@ -3,7 +3,7 @@ * * Copyright (C) 2012-2016 Intel Corporation * All rights reserved. - * Copyright (C) 2018 Alexander Motin + * Copyright (C) 2018-2020 Alexander Motin * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -45,6 +45,9 @@ __FBSDID("$FreeBSD$"); #include #include +#include + +#include #define NVD_STR "nvd" @@ -92,7 +95,7 @@ struct nvd_disk { }; struct nvd_controller { - + struct nvme_controller *ctrlr; TAILQ_ENTRY(nvd_controller) tailq; TAILQ_HEAD(, nvd_disk) disk_head; }; @@ -401,6 +404,7 @@ nvd_new_controller(struct nvme_controller *ctrlr) nvd_ctrlr = malloc(sizeof(struct nvd_controller), M_NVD, M_ZERO | M_WAITOK); + nvd_ctrlr->ctrlr = ctrlr; TAILQ_INIT(&nvd_ctrlr->disk_head); mtx_lock(&nvd_lock); TAILQ_INSERT_TAIL(&ctrlr_head, nvd_ctrlr, tailq); @@ -416,6 +420,7 @@ nvd_new_disk(struct nvme_namespace *ns, void *ctrlr_arg) struct nvd_disk *ndisk, *tnd; struct disk *disk; struct nvd_controller *ctrlr = ctrlr_arg; + device_t dev = ctrlr->ctrlr->dev; int unit; ndisk = malloc(sizeof(struct nvd_disk), M_NVD, M_ZERO | M_WAITOK); @@ -479,7 +484,13 @@ nvd_new_disk(struct nvme_namespace *ns, void *ctrlr_arg) NVME_MODEL_NUMBER_LENGTH); strlcpy(disk->d_descr, descr, sizeof(descr)); + disk->d_hba_vendor = pci_get_vendor(dev); + disk->d_hba_device = pci_get_device(dev); + disk->d_hba_subvendor = pci_get_subvendor(dev); + disk->d_hba_subdevice = pci_get_subdevice(dev); disk->d_rotation_rate = DISK_RR_NON_ROTATING; + strlcpy(disk->d_attachment, device_get_nameunit(dev), + sizeof(disk->d_attachment)); disk_create(disk, DISK_VERSION); From 1c7decd4dedc3a41956ffe5717fed230c8f107f2 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 12 Aug 2020 19:37:57 +0000 Subject: [PATCH 61/96] Report proper stripesize for nda(4). Same as for nvd(4) report NPWG if present, otherise NOIOB. MFC after: 1 week --- sys/cam/nvme/nvme_da.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/cam/nvme/nvme_da.c b/sys/cam/nvme/nvme_da.c index 367c943f0dce..892dee5a9959 100644 --- a/sys/cam/nvme/nvme_da.c +++ b/sys/cam/nvme/nvme_da.c @@ -943,7 +943,11 @@ ndaregister(struct cam_periph *periph, void *arg) disk->d_hba_subdevice = cpi.hba_subdevice; snprintf(disk->d_attachment, sizeof(disk->d_attachment), "%s%d", cpi.dev_name, cpi.unit_number); - disk->d_stripesize = disk->d_sectorsize; + if (((nsd->nsfeat >> NVME_NS_DATA_NSFEAT_NPVALID_SHIFT) & + NVME_NS_DATA_NSFEAT_NPVALID_MASK) != 0 && nsd->npwg != 0) + disk->d_stripesize = ((nsd->npwg + 1) * disk->d_sectorsize); + else + disk->d_stripesize = nsd->noiob * disk->d_sectorsize; disk->d_stripeoffset = 0; disk->d_devstat = devstat_new_entry(periph->periph_name, periph->unit_number, disk->d_sectorsize, From 97dc595da247caa1a1928abcd66f2308c6214ffb Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 12 Aug 2020 20:05:43 +0000 Subject: [PATCH 62/96] Report cpi->hba_* for nda(4) because why not. MFC after: 1 week --- sys/dev/nvme/nvme_sim.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/dev/nvme/nvme_sim.c b/sys/dev/nvme/nvme_sim.c index c9d8d94543d7..efec8d34868a 100644 --- a/sys/dev/nvme/nvme_sim.c +++ b/sys/dev/nvme/nvme_sim.c @@ -197,8 +197,12 @@ nvme_sim_action(struct cam_sim *sim, union ccb *ccb) cpi->xport_specific.nvme.slot = pci_get_slot(dev); cpi->xport_specific.nvme.function = pci_get_function(dev); cpi->xport_specific.nvme.extra = 0; - strncpy(cpi->xport_specific.nvme.dev_name, device_get_nameunit(ctrlr->dev), + strncpy(cpi->xport_specific.nvme.dev_name, device_get_nameunit(dev), sizeof(cpi->xport_specific.nvme.dev_name)); + cpi->hba_vendor = pci_get_vendor(dev); + cpi->hba_device = pci_get_device(dev); + cpi->hba_subvendor = pci_get_subvendor(dev); + cpi->hba_subdevice = pci_get_subdevice(dev); cpi->ccb_h.status = CAM_REQ_CMP; break; } From 367de39efa784fad89fe424d073cebdb2a1091c6 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 12 Aug 2020 20:29:49 +0000 Subject: [PATCH 63/96] Use uintptr_t instead of uint64_t for pointers in stack frames. Reviewed by: mhorne Obtained from: CheriBSD Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D25995 --- sys/riscv/include/stack.h | 6 +++--- sys/riscv/riscv/db_trace.c | 18 +++++++++--------- sys/riscv/riscv/stack_machdep.c | 6 +++--- sys/riscv/riscv/unwind.c | 6 +++--- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/sys/riscv/include/stack.h b/sys/riscv/include/stack.h index 7f4be068ec27..40183afb9f4d 100644 --- a/sys/riscv/include/stack.h +++ b/sys/riscv/include/stack.h @@ -41,9 +41,9 @@ (va) <= VM_MAX_KERNEL_ADDRESS) struct unwind_state { - uint64_t fp; - uint64_t sp; - uint64_t pc; + uintptr_t fp; + uintptr_t sp; + uintptr_t pc; }; int unwind_frame(struct unwind_state *); diff --git a/sys/riscv/riscv/db_trace.c b/sys/riscv/riscv/db_trace.c index 2a783b2ed0f0..6d7b6b934d43 100644 --- a/sys/riscv/riscv/db_trace.c +++ b/sys/riscv/riscv/db_trace.c @@ -108,9 +108,9 @@ db_stack_trace_cmd(struct unwind_state *frame) db_printf("--- exception %ld, tval = %#lx\n", tf->tf_scause & EXCP_MASK, tf->tf_stval); - frame->sp = (uint64_t)tf->tf_sp; - frame->fp = (uint64_t)tf->tf_s[0]; - frame->pc = (uint64_t)tf->tf_sepc; + frame->sp = tf->tf_sp; + frame->fp = tf->tf_s[0]; + frame->pc = tf->tf_sepc; if (!INKERNEL(frame->fp)) break; continue; @@ -132,9 +132,9 @@ db_trace_thread(struct thread *thr, int count) ctx = kdb_thr_ctx(thr); - frame.sp = (uint64_t)ctx->pcb_sp; - frame.fp = (uint64_t)ctx->pcb_s[0]; - frame.pc = (uint64_t)ctx->pcb_ra; + frame.sp = ctx->pcb_sp; + frame.fp = ctx->pcb_s[0]; + frame.pc = ctx->pcb_ra; db_stack_trace_cmd(&frame); return (0); } @@ -143,12 +143,12 @@ void db_trace_self(void) { struct unwind_state frame; - uint64_t sp; + uintptr_t sp; __asm __volatile("mv %0, sp" : "=&r" (sp)); frame.sp = sp; - frame.fp = (uint64_t)__builtin_frame_address(0); - frame.pc = (uint64_t)db_trace_self; + frame.fp = (uintptr_t)__builtin_frame_address(0); + frame.pc = (uintptr_t)db_trace_self; db_stack_trace_cmd(&frame); } diff --git a/sys/riscv/riscv/stack_machdep.c b/sys/riscv/riscv/stack_machdep.c index 2e016f537f91..0fd88695b512 100644 --- a/sys/riscv/riscv/stack_machdep.c +++ b/sys/riscv/riscv/stack_machdep.c @@ -86,13 +86,13 @@ void stack_save(struct stack *st) { struct unwind_state frame; - uint64_t sp; + uintptr_t sp; __asm __volatile("mv %0, sp" : "=&r" (sp)); frame.sp = sp; - frame.fp = (uint64_t)__builtin_frame_address(0); - frame.pc = (uint64_t)stack_save; + frame.fp = (uintptr_t)__builtin_frame_address(0); + frame.pc = (uintptr_t)stack_save; stack_capture(st, &frame); } diff --git a/sys/riscv/riscv/unwind.c b/sys/riscv/riscv/unwind.c index 18fc1e250c9b..8b0cdeca2903 100644 --- a/sys/riscv/riscv/unwind.c +++ b/sys/riscv/riscv/unwind.c @@ -42,7 +42,7 @@ __FBSDID("$FreeBSD$"); int unwind_frame(struct unwind_state *frame) { - uint64_t fp; + uintptr_t fp; fp = frame->fp; @@ -50,8 +50,8 @@ unwind_frame(struct unwind_state *frame) return (-1); frame->sp = fp; - frame->fp = *(uint64_t *)(fp - 16); - frame->pc = *(uint64_t *)(fp - 8) - 4; + frame->fp = ((uintptr_t *)fp)[-2]; + frame->pc = ((uintptr_t *)fp)[-1] - 4; return (0); } From 40db51b42fe39e335c1c4d5abcc7f1adf862356e Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 12 Aug 2020 20:33:29 +0000 Subject: [PATCH 64/96] Check that the frame pointer is within the current stack. This same check is used on other architectures. Previously this would permit a stack frame to unwind into any arbitrary kernel address (including unmapped addresses). Reviewed by: mhorne Obtained from: CheriBSD Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D25996 --- sys/riscv/riscv/stack_machdep.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/sys/riscv/riscv/stack_machdep.c b/sys/riscv/riscv/stack_machdep.c index 0fd88695b512..d4939dbda041 100644 --- a/sys/riscv/riscv/stack_machdep.c +++ b/sys/riscv/riscv/stack_machdep.c @@ -47,15 +47,18 @@ __FBSDID("$FreeBSD$"); #include static void -stack_capture(struct stack *st, struct unwind_state *frame) +stack_capture(struct thread *td, struct stack *st, struct unwind_state *frame) { stack_zero(st); while (1) { + if ((vm_offset_t)frame->fp < td->td_kstack || + (vm_offset_t)frame->fp >= td->td_kstack + + td->td_kstack_pages * PAGE_SIZE) + break; unwind_frame(frame); - if (!INKERNEL((vm_offset_t)frame->fp) || - !INKERNEL((vm_offset_t)frame->pc)) + if (!INKERNEL((vm_offset_t)frame->pc)) break; if (stack_put(st, frame->pc) == -1) break; @@ -78,7 +81,7 @@ stack_save_td(struct stack *st, struct thread *td) frame.fp = td->td_pcb->pcb_s[0]; frame.pc = td->td_pcb->pcb_ra; - stack_capture(st, &frame); + stack_capture(td, st, &frame); return (0); } @@ -94,5 +97,5 @@ stack_save(struct stack *st) frame.fp = (uintptr_t)__builtin_frame_address(0); frame.pc = (uintptr_t)stack_save; - stack_capture(st, &frame); + stack_capture(curthread, st, &frame); } From bceabe277e1286ec694e34c186a73e7bf2c9de4f Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Thu, 13 Aug 2020 00:19:05 +0000 Subject: [PATCH 65/96] flua: initial support for "require" in the base system Use /usr not /usr/local for base system components. Use /usr/lib/flua and /usr/share/flua (not lua) for consistency and to avoid the possibility that other software accidentally finds our base system modules. Also drop the version from the path, as flua represents an unspecified lua version that corresponds to the FreeBSD version it comes with. LUA_USE_DLOPEN is not yet enabled because some additional changes are needed wrt symbol visibility. Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D24605 --- etc/mtree/BSD.usr.dist | 4 ++++ lib/liblua/luaconf.h | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/etc/mtree/BSD.usr.dist b/etc/mtree/BSD.usr.dist index e3164c7d76ba..bf51fd5718cb 100644 --- a/etc/mtree/BSD.usr.dist +++ b/etc/mtree/BSD.usr.dist @@ -68,6 +68,8 @@ .. engines .. + flua + .. i18n .. libxo @@ -370,6 +372,8 @@ .. firmware .. + flua + .. games fortune .. diff --git a/lib/liblua/luaconf.h b/lib/liblua/luaconf.h index b24645b8915f..db6f3222f101 100644 --- a/lib/liblua/luaconf.h +++ b/lib/liblua/luaconf.h @@ -205,9 +205,9 @@ #else /* }{ */ -#define LUA_ROOT "/usr/local/" -#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR "/" -#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR "/" +#define LUA_ROOT "/usr/" +#define LUA_LDIR LUA_ROOT "share/flua/" +#define LUA_CDIR LUA_ROOT "lib/flua/" #if !defined(LUA_PATH_DEFAULT) #define LUA_PATH_DEFAULT \ LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ From 654f53ab6a9793a931e19ec598b7c496a17f6af8 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Thu, 13 Aug 2020 02:32:46 +0000 Subject: [PATCH 66/96] Fill device serial_num and device_id in NVMe XPT. It allows to report GEOM::lunid for nda(4) same as for nvd(4). Since NVMe now allows multiple LUs (namespaces) with multiple paths unique LU identification is important. The serial_num field is filled same as before with the controller serial number, while device_id is based on namespace GUID and/or EUI64 fields as recommended by "NVM Express: SCSI Translation Reference" and matching nvd(4) at the end. MFC after: 1 week --- sys/cam/nvme/nvme_xpt.c | 70 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/sys/cam/nvme/nvme_xpt.c b/sys/cam/nvme/nvme_xpt.c index 687da220325a..fbb9cf19d839 100644 --- a/sys/cam/nvme/nvme_xpt.c +++ b/sys/cam/nvme/nvme_xpt.c @@ -310,9 +310,11 @@ nvme_probe_done(struct cam_periph *periph, union ccb *done_ccb) struct nvme_controller_data *nvme_cdata; nvme_probe_softc *softc; struct cam_path *path; + struct scsi_vpd_device_id *did; + struct scsi_vpd_id_descriptor *idd; cam_status status; u_int32_t priority; - int found = 1; + int found = 1, e, g, len; CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("nvme_probe_done\n")); @@ -369,6 +371,21 @@ device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) bcopy(&softc->cd, nvme_cdata, sizeof(*nvme_cdata)); path->device->nvme_cdata = nvme_cdata; + /* Save/update serial number. */ + if (path->device->serial_num != NULL) { + free(path->device->serial_num, M_CAMXPT); + path->device->serial_num = NULL; + path->device->serial_num_len = 0; + } + path->device->serial_num = (u_int8_t *) + malloc(NVME_SERIAL_NUMBER_LENGTH + 1, M_CAMXPT, M_NOWAIT); + if (path->device->serial_num != NULL) { + cam_strvis(path->device->serial_num, nvme_cdata->sn, + NVME_SERIAL_NUMBER_LENGTH, NVME_SERIAL_NUMBER_LENGTH + 1); + path->device->serial_num_len = + strlen(path->device->serial_num); + } + // nvme_find_quirk(path->device); nvme_device_transport(path); NVME_PROBE_SET_ACTION(softc, NVME_PROBE_IDENTIFY_NS); @@ -394,6 +411,53 @@ device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) bcopy(&softc->ns, nvme_data, sizeof(*nvme_data)); path->device->nvme_data = nvme_data; + /* Save/update device_id based on NGUID and/or EUI64. */ + if (path->device->device_id != NULL) { + free(path->device->device_id, M_CAMXPT); + path->device->device_id = NULL; + path->device->device_id_len = 0; + } + len = 0; + for (g = 0; g < sizeof(nvme_data->nguid); g++) { + if (nvme_data->nguid[g] != 0) + break; + } + if (g < sizeof(nvme_data->nguid)) + len += sizeof(struct scsi_vpd_id_descriptor) + 16; + for (e = 0; e < sizeof(nvme_data->eui64); e++) { + if (nvme_data->eui64[e] != 0) + break; + } + if (e < sizeof(nvme_data->eui64)) + len += sizeof(struct scsi_vpd_id_descriptor) + 8; + if (len > 0) { + path->device->device_id = (u_int8_t *) + malloc(SVPD_DEVICE_ID_HDR_LEN + len, + M_CAMXPT, M_NOWAIT); + } + if (path->device->device_id != NULL) { + did = (struct scsi_vpd_device_id *)path->device->device_id; + did->device = SID_QUAL_LU_CONNECTED | T_DIRECT; + did->page_code = SVPD_DEVICE_ID; + scsi_ulto2b(len, did->length); + idd = (struct scsi_vpd_id_descriptor *)(did + 1); + if (g < sizeof(nvme_data->nguid)) { + idd->proto_codeset = SVPD_ID_CODESET_BINARY; + idd->id_type = SVPD_ID_ASSOC_LUN | SVPD_ID_TYPE_EUI64; + idd->length = 16; + bcopy(nvme_data->nguid, idd->identifier, 16); + idd = (struct scsi_vpd_id_descriptor *) + &idd->identifier[16]; + } + if (e < sizeof(nvme_data->eui64)) { + idd->proto_codeset = SVPD_ID_CODESET_BINARY; + idd->id_type = SVPD_ID_ASSOC_LUN | SVPD_ID_TYPE_EUI64; + idd->length = 8; + bcopy(nvme_data->eui64, idd->identifier, 8); + } + path->device->device_id_len = SVPD_DEVICE_ID_HDR_LEN + len; + } + if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) { path->device->flags &= ~CAM_DEV_UNCONFIGURED; xpt_acquire_device(path->device); @@ -546,9 +610,9 @@ nvme_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id) device->maxtags = 0; device->inq_flags = 0; device->queue_flags = 0; - device->device_id = NULL; /* XXX Need to set this somewhere */ + device->device_id = NULL; device->device_id_len = 0; - device->serial_num = NULL; /* XXX Need to set this somewhere */ + device->serial_num = NULL; device->serial_num_len = 0; return (device); } From cf518995644bbb3b67d876eaffc9f5856228a7cf Mon Sep 17 00:00:00 2001 From: Eugene Grosbein Date: Thu, 13 Aug 2020 06:32:39 +0000 Subject: [PATCH 67/96] ifconfig(8): plug memory leak after r361790 by me. MFC after: 3 days --- sbin/ifconfig/ifconfig.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index 0aa73b095a57..65847ad5954b 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -748,6 +748,7 @@ group_member(const char *ifname, const char *match, const char *nomatch) if (nomatch) nomatched &= fnmatch(nomatch, ifg->ifgrq_group, 0); } + free(ifgr.ifgr_groups); if (match && !nomatch) return (matched); From b38ad2683abb11bc129943ccdd2ec56b51a8cff9 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik Date: Thu, 13 Aug 2020 10:24:45 +0000 Subject: [PATCH 68/96] vfs: add missing pwd_drop on error in namei_setup Reported by: pho --- sys/kern/vfs_lookup.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index a392c128fd01..43b36dccb028 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -431,6 +431,7 @@ namei_setup(struct nameidata *ndp, struct vnode **dpp, struct pwd **pwdp) if (error != 0) { if (*dpp != NULL) vrele(*dpp); + pwd_drop(pwd); return (error); } MPASS((ndp->ni_lcf & (NI_LCF_BENEATH_ABS | NI_LCF_LATCH)) != From 54f7867b83b0345de77c5d4db49b6e6deadce34c Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Thu, 13 Aug 2020 14:14:46 +0000 Subject: [PATCH 69/96] Add pwd to the list of tools that are linked to $WORLDTMP/legacy After r364166 and r364174, crunchgen needs a pwd binary in $PATH instead of using a hardcoded absolute path. This commit is needed for BUILD_WITH_STRICT_TMPPATH builds (currently not on by default). --- tools/build/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/build/Makefile b/tools/build/Makefile index 599ddee21456..c78dbbdbbd4e 100644 --- a/tools/build/Makefile +++ b/tools/build/Makefile @@ -113,8 +113,8 @@ SYSINCS+= ${SRCTOP}/sys/sys/font.h # Linux/MacOS since we only use flags that are supported by all of them. _host_tools_to_symlink= basename bzip2 bunzip2 chmod chown cmp comm cp date dd \ dirname echo env false find fmt gzip gunzip head hostname id ln ls \ - mkdir mv nice patch rm realpath sh sleep stat tee touch tr true uname \ - uniq wc which + mkdir mv nice patch pwd rm realpath sh sleep stat tee touch tr true \ + uname uniq wc which # We also need a symlink to the absolute path to the make binary used for # the toplevel makefile. This is not necessarily the same as `which make` From 01c4f3a763ed9e6cc1ebc3beca76f29b9b6ebfb3 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Thu, 13 Aug 2020 14:14:51 +0000 Subject: [PATCH 70/96] Make bsd.linker.mk work with the MacOS linker This is not strictly required for crossbuilding but having lots of warnings from bsd.linker.mk in the output was making it hard to see the actual warning messages. Reviewed By: imp Differential Revision: https://reviews.freebsd.org/D14318 --- share/mk/bsd.linker.mk | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/share/mk/bsd.linker.mk b/share/mk/bsd.linker.mk index 5ecd6b8b969c..ae867502c6f2 100644 --- a/share/mk/bsd.linker.mk +++ b/share/mk/bsd.linker.mk @@ -58,7 +58,7 @@ ${var}= ${${var}__${${X_}_ld_hash}} .if ${ld} == "LD" || (${ld} == "XLD" && ${XLD} != ${LD}) .if !defined(${X_}LINKER_TYPE) || !defined(${X_}LINKER_VERSION) -_ld_version!= (${${ld}} --version || echo none) | sed -n 1p +_ld_version!= (${${ld}} -v 2>&1 || echo none) | sed -n 1p .if ${_ld_version} == "none" .warning Unable to determine linker type from ${ld}=${${ld}} .endif @@ -74,6 +74,17 @@ ${X_}LINKER_FREEBSD_VERSION:= ${_ld_version:[4]:C/.*-([^-]*)\)/\1/} .else ${X_}LINKER_FREEBSD_VERSION= 0 .endif +.elif ${_ld_version:[1]} == "@(\#)PROGRAM:ld" +# bootstrap linker on MacOS +${X_}LINKER_TYPE= mac +_v= ${_ld_version:[2]:S/PROJECT:ld64-//} +# Convert version 409.12 to 409.12.0 so that the echo + awk below works +.if empty(_v:M[1-9]*.[0-9]*.[0-9]*) && !empty(_v:M[1-9]*.[0-9]*) +_v:=${_v}.0 +.else +# Some versions do not contain a minor version so we need to append .0.0 there +_v:=${_v}.0.0 +.endif .else .warning Unknown linker from ${ld}=${${ld}}: ${_ld_version}, defaulting to bfd ${X_}LINKER_TYPE= bfd From 99c9fdd09aebc43593019f42b8ffd868c1032a4f Mon Sep 17 00:00:00 2001 From: Mitchell Horne Date: Thu, 13 Aug 2020 14:17:36 +0000 Subject: [PATCH 71/96] Small fixes in locore.S - Properly set up the frame pointer - Hang if we return from mi_startup - Whitespace Clearing the frame pointer marks the end of the backtrace. This fixes "bt 0" in ddb, which previously would unwind one frame too far. Reviewed by: jhb Differential Revision: https://reviews.freebsd.org/D26016 --- sys/riscv/riscv/locore.S | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/sys/riscv/riscv/locore.S b/sys/riscv/riscv/locore.S index 4a5b01df85b7..86eaab6d533b 100644 --- a/sys/riscv/riscv/locore.S +++ b/sys/riscv/riscv/locore.S @@ -223,19 +223,21 @@ va: csrw sscratch, t0 /* Initialize stack pointer */ - la s3, initstack_end - mv sp, s3 + la sp, initstack_end + + /* Clear frame pointer */ + mv s0, zero /* Allocate space for thread0 PCB and riscv_bootparams */ addi sp, sp, -(PCB_SIZE + RISCV_BOOTPARAMS_SIZE) & ~STACKALIGNBYTES /* Clear BSS */ - la s0, _C_LABEL(__bss_start) - la s1, _C_LABEL(_end) + la t0, _C_LABEL(__bss_start) + la t1, _C_LABEL(_end) 1: - sd zero, 0(s0) - addi s0, s0, 8 - bltu s0, s1, 1b + sd zero, 0(t0) + addi t0, t0, 8 + bltu t0, t1, 1b /* Fill riscv_bootparams */ la t0, pagetable_l1 @@ -259,6 +261,11 @@ va: call _C_LABEL(initriscv) /* Off we go */ call _C_LABEL(mi_startup) + /* We should never reach here, but if so just hang. */ +2: + wfi + j 2b + /* * Get the physical address the kernel is loaded to. Returned in s9. */ @@ -350,7 +357,7 @@ ENTRY(mpentry) ld sp, 0(t0) /* Get the kernel's load address */ - jal get_physmem + jal get_physmem /* Setup supervisor trap vector */ lla t0, mpva From 958a094323005f8ddd4013b037ffd6cbbd5e61ad Mon Sep 17 00:00:00 2001 From: Mitchell Horne Date: Thu, 13 Aug 2020 14:21:05 +0000 Subject: [PATCH 72/96] Enable interrupts while handling traps I observed hangs post-r362977 in QEMU with -smp 2, in which one thread would acquire write access to an rm_lock (sysctllock) and get stuck waiting in smp_rendezvous_cpus while the other CPU was servicing a trap. The other thread was waiting for read access to the same lock, thus causing deadlock. It's clear that this is just one symptom of a larger problem. The general expectation of MI kernel code is that interrupts are enabled. Violating this assumption will at best create some additional latency, but otherwise might cause locking or other unforeseen issues. All other architectures do so for some subset of trap values, but this somehow got missed in the RISC-V port. Enable interrupts now during kernel page faults and for all user trap types. The code in exception.S already knows to disable interrupts while handling the return from exception, so there are no changes required there. Reviewed by: jhb, markj MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D26017 --- sys/riscv/riscv/trap.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/sys/riscv/riscv/trap.c b/sys/riscv/riscv/trap.c index aa9ec534669d..dabd84e822e9 100644 --- a/sys/riscv/riscv/trap.c +++ b/sys/riscv/riscv/trap.c @@ -198,14 +198,22 @@ data_abort(struct trapframe *frame, int usermode) "Kernel page fault") != 0) goto fatal; - if (usermode) - map = &td->td_proc->p_vmspace->vm_map; - else if (stval >= VM_MAX_USER_ADDRESS) - map = kernel_map; - else { - if (pcb->pcb_onfault == 0) - goto fatal; + if (usermode) { map = &td->td_proc->p_vmspace->vm_map; + } else { + /* + * Enable interrupts for the duration of the page fault. For + * user faults this was done already in do_trap_user(). + */ + intr_enable(); + + if (stval >= VM_MAX_USER_ADDRESS) { + map = kernel_map; + } else { + if (pcb->pcb_onfault == 0) + goto fatal; + map = &td->td_proc->p_vmspace->vm_map; + } } va = trunc_page(stval); @@ -324,6 +332,7 @@ do_trap_user(struct trapframe *frame) riscv_cpu_intr(frame); return; } + intr_enable(); CTR3(KTR_TRAP, "do_trap_user: curthread: %p, sepc: %lx, frame: %p", curthread, frame->tf_sepc, frame); From f359d6ebbcced08a13060c07168856ffe6c9f734 Mon Sep 17 00:00:00 2001 From: Richard Scheffenegger Date: Thu, 13 Aug 2020 16:30:09 +0000 Subject: [PATCH 73/96] Improve SACK support code for RFC6675 and PRR Adding proper accounting of sacked_bytes and (per-ACK) delivered data to the SACK scoreboard. This will allow more aspects of RFC6675 to be implemented as well as Proportional Rate Reduction (RFC6937). Prior to this change, the pipe calculation controlled with net.inet.tcp.rfc6675_pipe was also susceptible to incorrect results when more than 3 (or 4) holes in the sequence space were present, which can no longer all fit into a single ACK's SACK option. Reviewed by: kbowling, rgrimes (mentor) Approved by: rgrimes (mentor, blanket) MFC after: 3 weeks Sponsored by: NetApp, Inc. Differential Revision: https://reviews.freebsd.org/D18624 --- sys/netinet/tcp_input.c | 11 +++++++++-- sys/netinet/tcp_sack.c | 31 +++++++++++++++++++++++-------- sys/netinet/tcp_var.h | 8 ++++---- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 337871e8fdc2..9bf6f52855a7 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -2673,9 +2673,16 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, tp->t_dupacks = 0; /* * If this ack also has new SACK info, increment the - * counter as per rfc6675. + * counter as per rfc6675. The variable + * sack_changed tracks all changes to the SACK + * scoreboard, including when partial ACKs without + * SACK options are received, and clear the scoreboard + * from the left side. Such partial ACKs should not be + * counted as dupacks here. */ - if ((tp->t_flags & TF_SACK_PERMIT) && sack_changed) + if ((tp->t_flags & TF_SACK_PERMIT) && + (to.to_flags & TOF_SACK) && + sack_changed) tp->t_dupacks++; } diff --git a/sys/netinet/tcp_sack.c b/sys/netinet/tcp_sack.c index 423836afb621..b7879269966d 100644 --- a/sys/netinet/tcp_sack.c +++ b/sys/netinet/tcp_sack.c @@ -535,9 +535,7 @@ tcp_sackhole_remove(struct tcpcb *tp, struct sackhole *hole) * tp->snd_holes is an ordered list of holes (oldest to newest, in terms of * the sequence space). * Returns 1 if incoming ACK has previously unknown SACK information, - * 0 otherwise. Note: We treat (snd_una, th_ack) as a sack block so any changes - * to that (i.e. left edge moving) would also be considered a change in SACK - * information which is slightly different than rfc6675. + * 0 otherwise. */ int tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) @@ -545,16 +543,21 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) struct sackhole *cur, *temp; struct sackblk sack, sack_blocks[TCP_MAX_SACK + 1], *sblkp; int i, j, num_sack_blks, sack_changed; + int delivered_data, left_edge_delta; INP_WLOCK_ASSERT(tp->t_inpcb); num_sack_blks = 0; sack_changed = 0; + delivered_data = 0; + left_edge_delta = 0; /* * If SND.UNA will be advanced by SEG.ACK, and if SACK holes exist, * treat [SND.UNA, SEG.ACK) as if it is a SACK block. + * Account changes to SND.UNA always in delivered data. */ if (SEQ_LT(tp->snd_una, th_ack) && !TAILQ_EMPTY(&tp->snd_holes)) { + left_edge_delta = th_ack - tp->snd_una; sack_blocks[num_sack_blks].start = tp->snd_una; sack_blocks[num_sack_blks++].end = th_ack; } @@ -563,7 +566,6 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) * received new blocks from the other side. */ if (to->to_flags & TOF_SACK) { - tp->sackhint.sacked_bytes = 0; /* reset */ for (i = 0; i < to->to_nsacks; i++) { bcopy((to->to_sacks + i * TCPOLEN_SACK), &sack, sizeof(sack)); @@ -576,8 +578,6 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) SEQ_GT(sack.end, tp->snd_una) && SEQ_LEQ(sack.end, tp->snd_max)) { sack_blocks[num_sack_blks++] = sack; - tp->sackhint.sacked_bytes += - (sack.end-sack.start); } } } @@ -602,7 +602,7 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) } } } - if (TAILQ_EMPTY(&tp->snd_holes)) + if (TAILQ_EMPTY(&tp->snd_holes)) { /* * Empty scoreboard. Need to initialize snd_fack (it may be * uninitialized or have a bogus value). Scoreboard holes @@ -611,6 +611,8 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) * scoreboard). */ tp->snd_fack = SEQ_MAX(tp->snd_una, th_ack); + tp->sackhint.sacked_bytes = 0; /* reset */ + } /* * In the while-loop below, incoming SACK blocks (sack_blocks[]) and * SACK holes (snd_holes) are traversed from their tails with just @@ -634,6 +636,7 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) */ temp = tcp_sackhole_insert(tp, tp->snd_fack,sblkp->start,NULL); if (temp != NULL) { + delivered_data += sblkp->end - sblkp->start; tp->snd_fack = sblkp->end; /* Go to the previous sack block. */ sblkp--; @@ -651,11 +654,15 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) SEQ_LT(tp->snd_fack, sblkp->start)) sblkp--; if (sblkp >= sack_blocks && - SEQ_LT(tp->snd_fack, sblkp->end)) + SEQ_LT(tp->snd_fack, sblkp->end)) { + delivered_data += sblkp->end - tp->snd_fack; tp->snd_fack = sblkp->end; + sack_changed = 1; + } } } else if (SEQ_LT(tp->snd_fack, sblkp->end)) { /* fack is advanced. */ + delivered_data += sblkp->end - tp->snd_fack; tp->snd_fack = sblkp->end; sack_changed = 1; } @@ -689,6 +696,7 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) /* Data acks at least the beginning of hole. */ if (SEQ_GEQ(sblkp->end, cur->end)) { /* Acks entire hole, so delete hole. */ + delivered_data += (cur->end - cur->start); temp = cur; cur = TAILQ_PREV(cur, sackhole_head, scblink); tcp_sackhole_remove(tp, temp); @@ -700,6 +708,7 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) continue; } else { /* Move start of hole forward. */ + delivered_data += (sblkp->end - cur->start); cur->start = sblkp->end; cur->rxmit = SEQ_MAX(cur->rxmit, cur->start); } @@ -707,6 +716,7 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) /* Data acks at least the end of hole. */ if (SEQ_GEQ(sblkp->end, cur->end)) { /* Move end of hole backward. */ + delivered_data += (cur->end - sblkp->start); cur->end = sblkp->start; cur->rxmit = SEQ_MIN(cur->rxmit, cur->end); } else { @@ -726,6 +736,7 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) cur->end = sblkp->start; cur->rxmit = SEQ_MIN(cur->rxmit, cur->end); + delivered_data += (sblkp->end - sblkp->start); } } } @@ -740,6 +751,10 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) else sblkp--; } + tp->sackhint.delivered_data = delivered_data; + tp->sackhint.sacked_bytes += delivered_data - left_edge_delta; + KASSERT((delivered_data >= 0), ("delivered_data < 0")); + KASSERT((tp->sackhint.sacked_bytes >= 0), ("sacked_bytes < 0")); return (sack_changed); } diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index c1fb25853836..d79ac73525d9 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -105,12 +105,12 @@ struct sackhole { struct sackhint { struct sackhole *nexthole; - int sack_bytes_rexmit; + int32_t sack_bytes_rexmit; tcp_seq last_sack_ack; /* Most recent/largest sacked ack */ - int ispare; /* explicit pad for 64bit alignment */ - int sacked_bytes; /* - * Total sacked bytes reported by the + int32_t delivered_data; /* Newly acked data from last SACK */ + + int32_t sacked_bytes; /* Total sacked bytes reported by the * receiver via sack option */ uint32_t _pad1[1]; /* TBD */ From 2bb6dfabbe2b43e774a1964ba0e825f4c6af0589 Mon Sep 17 00:00:00 2001 From: Richard Scheffenegger Date: Thu, 13 Aug 2020 16:38:51 +0000 Subject: [PATCH 74/96] TCP Cubic: After leaving slowstart fix unintended cwnd jump. Initializing K to zero in D23655 introduced a miscalculation, where cwnd would suddenly jump to cwnd_max instead of gradually increasing, after leaving slow-start. Properly calculating K instead of resetting it to zero resolves this issue. Also making sure, that cwnd is recalculated at the earliest opportunity once slow-start is over. Reported by: chengc_netapp.com Reviewed by: chengc_netapp.com, tuexen (mentor), rgrimes (mentor) Approved by: tuexen (mentor), rgrimes (mentor) MFC after: 3 weeks Sponsored by: NetApp, Inc. Differential Revision: https://reviews.freebsd.org/D25746 --- sys/netinet/cc/cc_cubic.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/sys/netinet/cc/cc_cubic.c b/sys/netinet/cc/cc_cubic.c index cbd2e7189326..e0daaeeda82d 100644 --- a/sys/netinet/cc/cc_cubic.c +++ b/sys/netinet/cc/cc_cubic.c @@ -132,19 +132,29 @@ cubic_ack_received(struct cc_var *ccv, uint16_t type) /* * Regular ACK and we're not in cong/fast recovery and we're cwnd - * limited and we're either not doing ABC or are slow starting or are - * doing ABC and we've sent a cwnd's worth of bytes. + * limited and we're either not doing ABC or are just coming out + * from slow-start or were application limited or are slow starting + * or are doing ABC and we've sent a cwnd's worth of bytes. */ if (type == CC_ACK && !IN_RECOVERY(CCV(ccv, t_flags)) && (ccv->flags & CCF_CWND_LIMITED) && (!V_tcp_do_rfc3465 || + (cubic_data->flags & (CUBICFLAG_IN_SLOWSTART | CUBICFLAG_IN_APPLIMIT)) || CCV(ccv, snd_cwnd) <= CCV(ccv, snd_ssthresh) || - (V_tcp_do_rfc3465 && ccv->flags & CCF_ABC_SENTAWND))) { + (V_tcp_do_rfc3465 && (ccv->flags & CCF_ABC_SENTAWND)))) { /* Use the logic in NewReno ack_received() for slow start. */ if (CCV(ccv, snd_cwnd) <= CCV(ccv, snd_ssthresh) || cubic_data->min_rtt_ticks == TCPTV_SRTTBASE) { cubic_data->flags |= CUBICFLAG_IN_SLOWSTART; newreno_cc_algo.ack_received(ccv, type); } else { + if (cubic_data->flags & (CUBICFLAG_IN_SLOWSTART | + CUBICFLAG_IN_APPLIMIT)) { + cubic_data->flags &= ~(CUBICFLAG_IN_SLOWSTART | + CUBICFLAG_IN_APPLIMIT); + cubic_data->t_last_cong = ticks; + cubic_data->K = cubic_k(cubic_data->max_cwnd / + CCV(ccv, t_maxseg)); + } if ((ticks_since_cong = ticks - cubic_data->t_last_cong) < 0) { /* @@ -153,14 +163,6 @@ cubic_ack_received(struct cc_var *ccv, uint16_t type) ticks_since_cong = INT_MAX; cubic_data->t_last_cong = ticks - INT_MAX; } - - if (cubic_data->flags & (CUBICFLAG_IN_SLOWSTART | - CUBICFLAG_IN_APPLIMIT)) { - cubic_data->flags &= ~(CUBICFLAG_IN_SLOWSTART | - CUBICFLAG_IN_APPLIMIT); - cubic_data->t_last_cong = ticks; - cubic_data->K = 0; - } /* * The mean RTT is used to best reflect the equations in * the I-D. Using min_rtt in the tf_cwnd calculation From a459638fc430cf0450f7450fd8576a62305d316f Mon Sep 17 00:00:00 2001 From: Richard Scheffenegger Date: Thu, 13 Aug 2020 16:45:55 +0000 Subject: [PATCH 75/96] TCP Cubic: Have Fast Convergence Heuristic work for ECN, and align concave region The Cubic concave region was not aligned nicely for the very first exit from slow start, where a 50% cwnd reduction is done instead of the normal 30%. This addresses an issue, where a short line-rate burst could result from that sudden jump of cwnd. In addition, the Fast Convergence Heuristic has been expanded to work also with ECN induced congestion response. Submitted by: chengc_netapp.com Reported by: chengc_netapp.com Reviewed by: tuexen (mentor), rgrimes (mentor) Approved by: tuexen (mentor), rgrimes (mentor) MFC after: 3 weeks Sponsored by: NetApp, Inc. Differential Revision: https://reviews.freebsd.org/D25976 --- sys/netinet/cc/cc_cubic.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/sys/netinet/cc/cc_cubic.c b/sys/netinet/cc/cc_cubic.c index e0daaeeda82d..a905033c458d 100644 --- a/sys/netinet/cc/cc_cubic.c +++ b/sys/netinet/cc/cc_cubic.c @@ -286,8 +286,7 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type) if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) { cubic_ssthresh_update(ccv); cubic_data->flags |= CUBICFLAG_CONG_EVENT; - cubic_data->prev_max_cwnd = cubic_data->max_cwnd; - cubic_data->max_cwnd = CCV(ccv, snd_cwnd); + cubic_data->t_last_cong = ticks; cubic_data->K = cubic_k(cubic_data->max_cwnd / CCV(ccv, t_maxseg)); } ENTER_RECOVERY(CCV(ccv, t_flags)); @@ -298,8 +297,6 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type) if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) { cubic_ssthresh_update(ccv); cubic_data->flags |= CUBICFLAG_CONG_EVENT; - cubic_data->prev_max_cwnd = cubic_data->max_cwnd; - cubic_data->max_cwnd = CCV(ccv, snd_cwnd); cubic_data->t_last_cong = ticks; cubic_data->K = cubic_k(cubic_data->max_cwnd / CCV(ccv, t_maxseg)); CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh); @@ -361,11 +358,6 @@ cubic_post_recovery(struct cc_var *ccv) cubic_data = ccv->cc_data; pipe = 0; - /* Fast convergence heuristic. */ - if (cubic_data->max_cwnd < cubic_data->prev_max_cwnd) - cubic_data->max_cwnd = (cubic_data->max_cwnd * CUBIC_FC_FACTOR) - >> CUBIC_SHIFT; - if (IN_FASTRECOVERY(CCV(ccv, t_flags))) { /* * If inflight data is less than ssthresh, set cwnd @@ -392,7 +384,6 @@ cubic_post_recovery(struct cc_var *ccv) CUBIC_BETA) >> CUBIC_SHIFT, 2 * CCV(ccv, t_maxseg)); } - cubic_data->t_last_cong = ticks; /* Calculate the average RTT between congestion epochs. */ if (cubic_data->epoch_ack_count > 0 && @@ -403,7 +394,6 @@ cubic_post_recovery(struct cc_var *ccv) cubic_data->epoch_ack_count = 0; cubic_data->sum_rtt_ticks = 0; - cubic_data->K = cubic_k(cubic_data->max_cwnd / CCV(ccv, t_maxseg)); } /* @@ -457,18 +447,32 @@ cubic_ssthresh_update(struct cc_var *ccv) { struct cubic *cubic_data; uint32_t ssthresh; + uint32_t cwnd; cubic_data = ccv->cc_data; + cwnd = CCV(ccv, snd_cwnd); + + /* Fast convergence heuristic. */ + if (cwnd < cubic_data->max_cwnd) { + cwnd = ((uint64_t)cwnd * CUBIC_FC_FACTOR) >> CUBIC_SHIFT; + } + cubic_data->prev_max_cwnd = cubic_data->max_cwnd; + cubic_data->max_cwnd = cwnd; /* - * On the first congestion event, set ssthresh to cwnd * 0.5, on - * subsequent congestion events, set it to cwnd * beta. + * On the first congestion event, set ssthresh to cwnd * 0.5 + * and reduce max_cwnd to cwnd * beta. This aligns the cubic concave + * region appropriately. On subsequent congestion events, set + * ssthresh to cwnd * beta. */ - if ((cubic_data->flags & CUBICFLAG_CONG_EVENT) == 0) - ssthresh = CCV(ccv, snd_cwnd) >> 1; - else - ssthresh = ((uint64_t)CCV(ccv, snd_cwnd) * + if ((cubic_data->flags & CUBICFLAG_CONG_EVENT) == 0) { + ssthresh = cwnd >> 1; + cubic_data->max_cwnd = ((uint64_t)cwnd * CUBIC_BETA) >> CUBIC_SHIFT; + } else { + ssthresh = ((uint64_t)cwnd * + CUBIC_BETA) >> CUBIC_SHIFT; + } CCV(ccv, snd_ssthresh) = max(ssthresh, 2 * CCV(ccv, t_maxseg)); } From 6cbadc42341b0cb4b0aa32fa96129c56138afcf7 Mon Sep 17 00:00:00 2001 From: "Alexander V. Chernikov" Date: Thu, 13 Aug 2020 18:35:29 +0000 Subject: [PATCH 76/96] Move rtzone handling code to net/route_ctl.c After moving the route control plane code from net/route.c, all rtzone users ended up being in net/route_ctl.c. Move uma(9) rtzone setup/teardown code to net/route_ctl.c as well to have everything in a single place. While here, remove custom initializers from the zone. It was added originally to avoid setup/teardown of costy per-cpu couters. With these counters removed, the only remaining job was avoiding rte mutex setup/teardown. Mutex setup is relatively cheap. Additionally, this mutex will soon be removed. With that in mind, there is no sense in keeping custom zone callbacks. Differential Revision: https://reviews.freebsd.org/D26051 --- sys/net/route.c | 96 +-------------------------------------- sys/net/route.h | 9 ---- sys/net/route/route_ctl.c | 76 ++++++++++++++++++++++++++++++- sys/net/route/route_var.h | 4 ++ sys/net/route/shared.h | 3 -- 5 files changed, 81 insertions(+), 107 deletions(-) diff --git a/sys/net/route.c b/sys/net/route.c index 8795dde43725..2f9baa685520 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -122,14 +122,10 @@ VNET_DEFINE(struct rib_head *, rt_tables); #define V_rt_tables VNET(rt_tables) -VNET_DEFINE(uma_zone_t, rtzone); /* Routing table UMA zone. */ -#define V_rtzone VNET(rtzone) - EVENTHANDLER_LIST_DEFINE(rt_addrmsg); static int rt_ifdelroute(const struct rtentry *rt, const struct nhop_object *, void *arg); -static void destroy_rtentry_epoch(epoch_context_t ctx); static int rt_exportinfo(struct rtentry *rt, struct rt_addrinfo *info, int flags); @@ -207,43 +203,6 @@ route_init(void) } SYSINIT(route_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, route_init, NULL); -static int -rtentry_zinit(void *mem, int size, int how) -{ - struct rtentry *rt = mem; - - RT_LOCK_INIT(rt); - - return (0); -} - -static void -rtentry_zfini(void *mem, int size) -{ - struct rtentry *rt = mem; - - RT_LOCK_DESTROY(rt); -} - -static int -rtentry_ctor(void *mem, int size, void *arg, int how) -{ - struct rtentry *rt = mem; - - bzero(rt, offsetof(struct rtentry, rt_endzero)); - rt->rt_chain = NULL; - - return (0); -} - -static void -rtentry_dtor(void *mem, int size, void *arg) -{ - struct rtentry *rt = mem; - - RT_UNLOCK_COND(rt); -} - static void vnet_route_init(const void *unused __unused) { @@ -255,9 +214,7 @@ vnet_route_init(const void *unused __unused) V_rt_tables = malloc(rt_numfibs * (AF_MAX+1) * sizeof(struct rib_head *), M_RTABLE, M_WAITOK|M_ZERO); - V_rtzone = uma_zcreate("rtentry", sizeof(struct rtentry), - rtentry_ctor, rtentry_dtor, - rtentry_zinit, rtentry_zfini, UMA_ALIGN_PTR, 0); + vnet_rtzone_init(); for (dom = domains; dom; dom = dom->dom_next) { if (dom->dom_rtattach == NULL) continue; @@ -314,7 +271,7 @@ vnet_route_uninit(const void *unused __unused) epoch_drain_callbacks(net_epoch_preempt); free(V_rt_tables, M_RTABLE); - uma_zdestroy(V_rtzone); + vnet_rtzone_destroy(); } VNET_SYSUNINIT(vnet_route_uninit, SI_SUB_PROTO_DOMAIN, SI_ORDER_FIRST, vnet_route_uninit, 0); @@ -405,55 +362,6 @@ sys_setfib(struct thread *td, struct setfib_args *uap) return (0); } -/* - * Remove a reference count from an rtentry. - * If the count gets low enough, take it out of the routing table - */ -void -rtfree(struct rtentry *rt) -{ - - KASSERT(rt != NULL,("%s: NULL rt", __func__)); - - RT_LOCK_ASSERT(rt); - - RT_UNLOCK(rt); - epoch_call(net_epoch_preempt, destroy_rtentry_epoch, - &rt->rt_epoch_ctx); -} - -static void -destroy_rtentry(struct rtentry *rt) -{ - - /* - * At this moment rnh, nh_control may be already freed. - * nhop interface may have been migrated to a different vnet. - * Use vnet stored in the nexthop to delete the entry. - */ - CURVNET_SET(nhop_get_vnet(rt->rt_nhop)); - - /* Unreference nexthop */ - nhop_free(rt->rt_nhop); - - uma_zfree(V_rtzone, rt); - - CURVNET_RESTORE(); -} - -/* - * Epoch callback indicating rtentry is safe to destroy - */ -static void -destroy_rtentry_epoch(epoch_context_t ctx) -{ - struct rtentry *rt; - - rt = __containerof(ctx, struct rtentry, rt_epoch_ctx); - - destroy_rtentry(rt); -} - /* * Adds a temporal redirect entry to the routing table. * @fibnum: fib number diff --git a/sys/net/route.h b/sys/net/route.h index 1ffabcbc86df..b8a98007a41e 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -387,16 +387,7 @@ int rtsock_routemsg_info(int, struct rt_addrinfo *, int); struct sockaddr *rtsock_fix_netmask(const struct sockaddr *dst, const struct sockaddr *smask, struct sockaddr_storage *dmask); -/* - * Note the following locking behavior: - * - * rtfree() and RTFREE_LOCKED() require a locked rtentry - * - * RTFREE() uses an unlocked entry. - */ -void rtfree(struct rtentry *); -void rtfree_func(struct rtentry *); void rt_updatemtu(struct ifnet *); void rt_flushifroutes_af(struct ifnet *, int); diff --git a/sys/net/route/route_ctl.c b/sys/net/route/route_ctl.c index 7debef06ce8d..212f5b51e5b5 100644 --- a/sys/net/route/route_ctl.c +++ b/sys/net/route/route_ctl.c @@ -87,6 +87,77 @@ static void rib_notify(struct rib_head *rnh, enum rib_subscription_type type, static void destroy_subscription_epoch(epoch_context_t ctx); +/* Routing table UMA zone */ +VNET_DEFINE_STATIC(uma_zone_t, rtzone); +#define V_rtzone VNET(rtzone) + +void +vnet_rtzone_init() +{ + + V_rtzone = uma_zcreate("rtentry", sizeof(struct rtentry), + NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); +} + +#ifdef VIMAGE +void +vnet_rtzone_destroy() +{ + + uma_zdestroy(V_rtzone); +} +#endif + +static void +destroy_rtentry(struct rtentry *rt) +{ + + /* + * At this moment rnh, nh_control may be already freed. + * nhop interface may have been migrated to a different vnet. + * Use vnet stored in the nexthop to delete the entry. + */ + CURVNET_SET(nhop_get_vnet(rt->rt_nhop)); + + /* Unreference nexthop */ + nhop_free(rt->rt_nhop); + + uma_zfree(V_rtzone, rt); + + CURVNET_RESTORE(); +} + +/* + * Epoch callback indicating rtentry is safe to destroy + */ +static void +destroy_rtentry_epoch(epoch_context_t ctx) +{ + struct rtentry *rt; + + rt = __containerof(ctx, struct rtentry, rt_epoch_ctx); + + destroy_rtentry(rt); +} + +/* + * Schedule rtentry deletion + */ +static void +rtfree(struct rtentry *rt) +{ + + KASSERT(rt != NULL, ("%s: NULL rt", __func__)); + + RT_LOCK_ASSERT(rt); + + RT_UNLOCK(rt); + epoch_call(net_epoch_preempt, destroy_rtentry_epoch, + &rt->rt_epoch_ctx); +} + + + static struct rib_head * get_rnh(uint32_t fibnum, const struct rt_addrinfo *info) { @@ -173,12 +244,13 @@ add_route(struct rib_head *rnh, struct rt_addrinfo *info, return (error); } - rt = uma_zalloc(V_rtzone, M_NOWAIT); + rt = uma_zalloc(V_rtzone, M_NOWAIT | M_ZERO); if (rt == NULL) { ifa_free(info->rti_ifa); nhop_free(nh); return (ENOBUFS); } + RT_LOCK_INIT(rt); rt->rt_flags = RTF_UP | flags; rt->rt_nhop = nh; @@ -219,6 +291,7 @@ add_route(struct rib_head *rnh, struct rt_addrinfo *info, RIB_WUNLOCK(rnh); nhop_free(nh); + RT_LOCK_DESTROY(rt); uma_zfree(V_rtzone, rt); return (EEXIST); } @@ -286,6 +359,7 @@ add_route(struct rib_head *rnh, struct rt_addrinfo *info, */ if (rn == NULL) { nhop_free(nh); + RT_LOCK_DESTROY(rt); uma_zfree(V_rtzone, rt); return (EEXIST); } diff --git a/sys/net/route/route_var.h b/sys/net/route/route_var.h index 3632aaf07c42..a55835ffa9d6 100644 --- a/sys/net/route/route_var.h +++ b/sys/net/route/route_var.h @@ -237,4 +237,8 @@ void tmproutes_update(struct rib_head *rnh, struct rtentry *rt); void tmproutes_init(struct rib_head *rh); void tmproutes_destroy(struct rib_head *rh); +/* route_ctl.c */ +void vnet_rtzone_init(void); +void vnet_rtzone_destroy(void); + #endif diff --git a/sys/net/route/shared.h b/sys/net/route/shared.h index 4ea20c5e011e..3d68f5db0c8e 100644 --- a/sys/net/route/shared.h +++ b/sys/net/route/shared.h @@ -72,9 +72,6 @@ void rib_init_subscriptions(struct rib_head *rnh); void rib_destroy_subscriptions(struct rib_head *rnh); /* route */ -VNET_DECLARE(uma_zone_t, rtzone); /* Routing table UMA zone. */ -#define V_rtzone VNET(rtzone) - struct rtentry *rt_unlinkrte(struct rib_head *rnh, struct rt_addrinfo *info, int *perror); From 1e04d9ff3e2565a402e449eb59b30b826bb2894a Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 13 Aug 2020 20:28:35 +0000 Subject: [PATCH 77/96] Fix a typo in the cpp macro defined for PIC. In practice this isn't used in OpenSSL outside of some sparc-specific code. Reviewed by: delphij Differential Revision: https://reviews.freebsd.org/D26058 --- secure/lib/libssl/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/secure/lib/libssl/Makefile b/secure/lib/libssl/Makefile index d97775b9afe4..e201cfa36e31 100644 --- a/secure/lib/libssl/Makefile +++ b/secure/lib/libssl/Makefile @@ -31,7 +31,7 @@ CFLAGS+= -I${.OBJDIR:H}/libcrypto .include -PICFLAG+= -DOPENSS_PIC +PICFLAG+= -DOPENSSL_PIC .PATH: ${LCRYPTO_SRC}/ssl \ ${LCRYPTO_SRC}/ssl/record \ From 8a0edc914ffdda876987add5128da3ee236a6a12 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Thu, 13 Aug 2020 20:48:14 +0000 Subject: [PATCH 78/96] Add prng(9) API Add prng(9) as a replacement for random(9) in the kernel. There are two major differences from random(9) and random(3): - General prng(9) APIs (prng32(9), etc) do not guarantee an implementation or particular sequence; they should not be used for repeatable simulations. - However, specific named API families are also exposed (for now: PCG), and those are expected to be repeatable (when so-guaranteed by the named algorithm). Some minor differences from random(3) and earlier random(9): - PRNG state for the general prng(9) APIs is per-CPU; this eliminates contention on PRNG state in SMP workloads. Each PCPU generator in an SMP system produces a unique sequence. - Better statistical properties than the Park-Miller ("minstd") PRNG (longer period, uniform distribution in all bits, passes BigCrush/PractRand analysis). - Faster than Park-Miller ("minstd") PRNG -- no division is required to step PCG-family PRNGs. For now, random(9) becomes a thin shim around prng32(). Eventually I would like to mechanically switch consumers over to the explicit API. Reviewed by: kib, markj (previous version both) Discussed with: markm Differential Revision: https://reviews.freebsd.org/D25916 --- share/man/man9/Makefile | 5 + share/man/man9/prng.9 | 99 +++++++++++++++++ sys/conf/files | 1 + sys/contrib/pcg-c/include/pcg_variants.h | 44 +++----- sys/kern/subr_prng.c | 131 +++++++++++++++++++++++ sys/libkern/random.c | 35 +----- sys/sys/prng.h | 20 ++++ 7 files changed, 272 insertions(+), 63 deletions(-) create mode 100644 share/man/man9/prng.9 create mode 100644 sys/kern/subr_prng.c create mode 100644 sys/sys/prng.h diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index 33e162d5fae0..993f65188543 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -272,6 +272,7 @@ MAN= accept_filter.9 \ printf.9 \ prison_check.9 \ priv.9 \ + prng.9 \ proc_rwmem.9 \ pseudofs.9 \ psignal.9 \ @@ -1745,6 +1746,10 @@ MLINKS+=printf.9 log.9 \ printf.9 uprintf.9 MLINKS+=priv.9 priv_check.9 \ priv.9 priv_check_cred.9 +MLINKS+=prng.9 prng32.9 \ + prng.9 prng32_bounded.9 \ + prng.9 prng64.9 \ + prng.9 prng64_bounded.9 MLINKS+=proc_rwmem.9 proc_readmem.9 \ proc_rwmem.9 proc_writemem.9 MLINKS+=psignal.9 gsignal.9 \ diff --git a/share/man/man9/prng.9 b/share/man/man9/prng.9 new file mode 100644 index 000000000000..63132c28c198 --- /dev/null +++ b/share/man/man9/prng.9 @@ -0,0 +1,99 @@ +.\"- +.\" Copyright 2020 Conrad Meyer . All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd August 5, 2020 +.Dt PRNG 9 +.Os +.Sh NAME +.Nm prng +.Nd "Kernel pseudo-random number generators" +.Sh SYNOPSIS +.In sys/prng.h +.Ft uint32_t +.Fn prng32 void +.Ft uint32_t +.Fn prng32_bounded "uint32_t bound" +.Ft uint64_t +.Fn prng64 void +.Ft uint64_t +.Fn prng64_bounded "uint64_t bound" +.Sh DESCRIPTION +.Ss GENERIC PRNG ROUTINES +.Nm +is a family of fast, +.Em non-cryptographic +pseudo-random number generators. +Unlike +.Xr random 9 , +.Fn prng32 , +.Fn prng32_bounded , +.Fn prng64 , +and +.Fn prng64_bounded +avoid shared global state, removing unnecessary contention on SMP +systems. +The routines are not explicitly tied to any specific implementation, and +may produce different specific sequences on different hosts, reboots, or +versions of +.Fx . +Different CPUs in SMP systems are guaranteed to produce different sequences of +integers. +.Pp +For +.Em cryptographically secure +random numbers generated by the +.Xr random 4 +kernel cryptographically secure random number generator subsystem, see +.Xr arc4random 9 . +.Pp +.Bl -tag -width indent +.It Fn prng32 +Generate a 32-bit integer uniformly distributed in [0, 2^32-1]. +.It Fn prng32_bounded bound +Generate an integer uniformly in the range [0, bound-1]. +.It Fn prng64 +Generate a 64-bit integer uniformly distributed in [0, 2^64-1]. +.It Fn prng64_bounded bound +Generate an integer uniformly in the range [0, bound-1]. +.El +.Pp +These routines are not reentrant; they are not safe to use in interrupt +handlers ("interrupt filters" in +.Xr bus_setup_intr 9 +terminology). +They are safe to use in all other kernel contexts, including interrupt threads +("ithreads"). +.Ss REPRODUCIBLE PRNG APIS +In addition to these per-CPU helpers, the +.In sys/prng.h +header also exposes the entire API of the PCG family of PRNGs as inline +functions. +The PCG-C API is described in full at +.Lk https://www.pcg-random.org/using-pcg-c.html . +.Sh HISTORY +.Nm +was introduced in +.Fx 13 . diff --git a/sys/conf/files b/sys/conf/files index 04e224437f93..052e8c238f43 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -3834,6 +3834,7 @@ kern/subr_pctrie.c standard kern/subr_pidctrl.c standard kern/subr_power.c standard kern/subr_prf.c standard +kern/subr_prng.c standard kern/subr_prof.c standard kern/subr_rangeset.c standard kern/subr_rman.c standard diff --git a/sys/contrib/pcg-c/include/pcg_variants.h b/sys/contrib/pcg-c/include/pcg_variants.h index 768fb75ae93b..14f8e7aa2cf8 100644 --- a/sys/contrib/pcg-c/include/pcg_variants.h +++ b/sys/contrib/pcg-c/include/pcg_variants.h @@ -36,22 +36,16 @@ #ifndef PCG_VARIANTS_H_INCLUDED #define PCG_VARIANTS_H_INCLUDED 1 -#include - -#if __SIZEOF_INT128__ +#if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__ typedef __uint128_t pcg128_t; #define PCG_128BIT_CONSTANT(high,low) \ ((((pcg128_t)high) << 64) + low) #define PCG_HAS_128BIT_OPS 1 +#else + #define PCG_HAS_128BIT_OPS 0 #endif -#if __GNUC_GNU_INLINE__ && !defined(__cplusplus) - #error Nonstandard GNU inlining semantics. Compile with -std=c99 or better. - /* We could instead use macros PCG_INLINE and PCG_EXTERN_INLINE - but better to just reject ancient C code. */ -#endif - -#if __cplusplus +#ifdef __cplusplus extern "C" { #endif @@ -65,8 +59,8 @@ inline uint8_t pcg_rotr_8(uint8_t value, unsigned int rot) * recognizing idiomatic rotate code, so for clang we actually provide * assembler directives (enabled with PCG_USE_INLINE_ASM). Boo, hiss. */ -#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__) - asm ("rorb %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); +#if PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__)) + __asm__ ("rorb %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); return value; #else return (value >> rot) | (value << ((- rot) & 7)); @@ -75,8 +69,8 @@ inline uint8_t pcg_rotr_8(uint8_t value, unsigned int rot) inline uint16_t pcg_rotr_16(uint16_t value, unsigned int rot) { -#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__) - asm ("rorw %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); +#if PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__)) + __asm__ ("rorw %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); return value; #else return (value >> rot) | (value << ((- rot) & 15)); @@ -85,8 +79,8 @@ inline uint16_t pcg_rotr_16(uint16_t value, unsigned int rot) inline uint32_t pcg_rotr_32(uint32_t value, unsigned int rot) { -#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__) - asm ("rorl %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); +#if PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__)) + __asm__ ("rorl %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); return value; #else return (value >> rot) | (value << ((- rot) & 31)); @@ -95,10 +89,10 @@ inline uint32_t pcg_rotr_32(uint32_t value, unsigned int rot) inline uint64_t pcg_rotr_64(uint64_t value, unsigned int rot) { -#if 0 && PCG_USE_INLINE_ASM && __clang__ && __x86_64__ +#if 0 && PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__)) /* For whatever reason, clang actually *does* generate rotq by itself, so we don't need this code. */ - asm ("rorq %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); + __asm__ ("rorq %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); return value; #else return (value >> rot) | (value << ((- rot) & 63)); @@ -2491,18 +2485,6 @@ typedef struct pcg_state_setseq_128 pcg128i_random_t; #define pcg128i_advance_r pcg_setseq_128_advance_r #endif -extern uint32_t pcg32_random(void); -extern uint32_t pcg32_boundedrand(uint32_t bound); -extern void pcg32_srandom(uint64_t seed, uint64_t seq); -extern void pcg32_advance(uint64_t delta); - -#if PCG_HAS_128BIT_OPS -extern uint64_t pcg64_random(void); -extern uint64_t pcg64_boundedrand(uint64_t bound); -extern void pcg64_srandom(pcg128_t seed, pcg128_t seq); -extern void pcg64_advance(pcg128_t delta); -#endif - /* * Static initialization constants (if you can't call srandom for some * bizarre reason). @@ -2536,7 +2518,7 @@ extern void pcg64_advance(pcg128_t delta); #define PCG128I_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER #endif -#if __cplusplus +#ifdef __cplusplus } #endif diff --git a/sys/kern/subr_prng.c b/sys/kern/subr_prng.c new file mode 100644 index 000000000000..124a56e0e4ea --- /dev/null +++ b/sys/kern/subr_prng.c @@ -0,0 +1,131 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright 2020 Conrad Meyer . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#if !PCG_HAS_128BIT_OPS +/* On 32-bit platforms, gang together two 32-bit generators. */ +typedef struct { + pcg32u_random_t states[2]; +} pcg64u_random_t; + +static inline void +pcg64u_srandom_r(pcg64u_random_t *state64, uint64_t seed) +{ + pcg32u_srandom_r(&state64->states[0], seed); + pcg32u_srandom_r(&state64->states[1], seed); +} + +static inline uint64_t +pcg64u_random_r(pcg64u_random_t *state64) +{ + return ((((uint64_t)pcg32u_random_r(&state64->states[0])) << 32) | + pcg32u_random_r(&state64->states[1])); +} + +static inline uint64_t +pcg64u_boundedrand_r(pcg64u_random_t *state64, uint64_t bound) +{ + uint64_t threshold = -bound % bound; + for (;;) { + uint64_t r = pcg64u_random_r(state64); + if (r >= threshold) + return (r % bound); + } +} +#endif + +DPCPU_DEFINE_STATIC(pcg32u_random_t, pcpu_prng32_state); +DPCPU_DEFINE_STATIC(pcg64u_random_t, pcpu_prng64_state); + +static void +prng_init(void *dummy __unused) +{ + pcg32u_random_t *state; + pcg64u_random_t *state64; + int i; + + CPU_FOREACH(i) { + state = DPCPU_ID_PTR(i, pcpu_prng32_state); + pcg32u_srandom_r(state, 1); + state64 = DPCPU_ID_PTR(i, pcpu_prng64_state); + pcg64u_srandom_r(state64, 1); + } +} +SYSINIT(prng_init, SI_SUB_CPU, SI_ORDER_ANY, prng_init, NULL); + +uint32_t +prng32(void) +{ + uint32_t r; + + critical_enter(); + r = pcg32u_random_r(DPCPU_PTR(pcpu_prng32_state)); + critical_exit(); + return (r); +} + +uint32_t +prng32_bounded(uint32_t bound) +{ + uint32_t r; + + critical_enter(); + r = pcg32u_boundedrand_r(DPCPU_PTR(pcpu_prng32_state), bound); + critical_exit(); + return (r); +} + +uint64_t +prng64(void) +{ + uint64_t r; + + critical_enter(); + r = pcg64u_random_r(DPCPU_PTR(pcpu_prng64_state)); + critical_exit(); + return (r); +} + +uint64_t +prng64_bounded(uint64_t bound) +{ + uint64_t r; + + critical_enter(); + r = pcg64u_boundedrand_r(DPCPU_PTR(pcpu_prng64_state), bound); + critical_exit(); + return (r); +} diff --git a/sys/libkern/random.c b/sys/libkern/random.c index e5e9de6108e1..23a8887fa49b 100644 --- a/sys/libkern/random.c +++ b/sys/libkern/random.c @@ -36,43 +36,14 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include -static u_long randseed = 937186357; /* after srandom(1), NSHUFF counted */ - /* - * Pseudo-random number generator for perturbing the profiling clock, - * and whatever else we might use it for. The result is uniform on - * [0, 2^31 - 1]. + * Pseudo-random number generator. The result is uniform in [0, 2^31 - 1]. */ u_long random(void) { - static bool warned = false; - - long x, hi, lo, t; - - /* Warn only once, or it gets very spammy. */ - if (!warned) { - gone_in(13, - "random(9) is the obsolete Park-Miller LCG from 1988"); - warned = true; - } - - /* - * Compute x[n + 1] = (7^5 * x[n]) mod (2^31 - 1). - * From "Random number generators: good ones are hard to find", - * Park and Miller, Communications of the ACM, vol. 31, no. 10, - * October 1988, p. 1195. - */ - /* Can't be initialized with 0, so use another value. */ - if ((x = randseed) == 0) - x = 123459876; - hi = x / 127773; - lo = x % 127773; - t = 16807 * lo - 2836 * hi; - if (t < 0) - t += 0x7fffffff; - randseed = t; - return (t); + return (prng32()); } diff --git a/sys/sys/prng.h b/sys/sys/prng.h new file mode 100644 index 000000000000..a1abe6ad1a11 --- /dev/null +++ b/sys/sys/prng.h @@ -0,0 +1,20 @@ +/*- + * This file is in the public domain. + * + * $FreeBSD$ + */ + +#ifndef _SYS_PRNG_H_ +#define _SYS_PRNG_H_ + +#define PCG_USE_INLINE_ASM 1 +#include + +#ifdef _KERNEL +__uint32_t prng32(void); +__uint32_t prng32_bounded(__uint32_t bound); +__uint64_t prng64(void); +__uint64_t prng64_bounded(__uint64_t bound); +#endif + +#endif From 3869d414658817a8ebc926647f7d809efa48491f Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Thu, 13 Aug 2020 22:06:27 +0000 Subject: [PATCH 79/96] lagg: Avoid adding a port to a lagg device being destroyed. The lagg_clone_destroy() handles detach and waiting for ifconfig callers to drain already. This narrows the race for 2 panics that the tests triggered. Both were a consequence of adding a port to the lagg device after it had already detached from all of its ports. The link state task would run after lagg_clone_destroy() free'd the lagg softc. kernel:trap_fatal+0xa4 kernel:trap_pfault+0x61 kernel:trap+0x316 kernel:witness_checkorder+0x6d kernel:_sx_xlock+0x72 if_lagg.ko:lagg_port_state+0x3b kernel:if_down+0x144 kernel:if_detach+0x659 if_tap.ko:tap_destroy+0x46 kernel:if_clone_destroyif+0x1b7 kernel:if_clone_destroy+0x8d kernel:ifioctl+0x29c kernel:kern_ioctl+0x2bd kernel:sys_ioctl+0x16d kernel:amd64_syscall+0x337 kernel:trap_fatal+0xa4 kernel:trap_pfault+0x61 kernel:trap+0x316 kernel:witness_checkorder+0x6d kernel:_sx_xlock+0x72 if_lagg.ko:lagg_port_state+0x3b kernel:do_link_state_change+0x9b kernel:taskqueue_run_locked+0x10b kernel:taskqueue_run+0x49 kernel:ithread_loop+0x19c kernel:fork_exit+0x83 PR: 244168 Reviewed by: markj MFC after: 2 weeks Sponsored by: Dell EMC Differential Revision: https://reviews.freebsd.org/D25284 --- sys/net/if_lagg.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c index 814a5b5b14c7..4930e1820f3b 100644 --- a/sys/net/if_lagg.c +++ b/sys/net/if_lagg.c @@ -679,6 +679,9 @@ lagg_port_create(struct lagg_softc *sc, struct ifnet *ifp) return (EINVAL); } + if (sc->sc_destroying == 1) + return (ENXIO); + /* Limit the maximal number of lagg ports */ if (sc->sc_count >= LAGG_MAX_PORTS) return (ENOSPC); @@ -1191,6 +1194,8 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) bzero(&rpbuf, sizeof(rpbuf)); + /* XXX: This can race with lagg_clone_destroy. */ + switch (cmd) { case SIOCGLAGG: LAGG_XLOCK(sc); From b2e98945d72cf3d9edabd0d2209c2951d6ccceca Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Thu, 13 Aug 2020 22:42:24 +0000 Subject: [PATCH 80/96] Add test to for FreeBSD-SA-19:20.bsnmp Submitted by: Darrick Lew Reviewed by: cem Sponsored by: Dell EMC Differential Revision: https://reviews.freebsd.org/D26037 --- lib/libbsnmp/Makefile | 1 + lib/libbsnmp/tests/Makefile | 11 +++++++ lib/libbsnmp/tests/bsnmpd_test.c | 53 ++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 lib/libbsnmp/tests/Makefile create mode 100644 lib/libbsnmp/tests/bsnmpd_test.c diff --git a/lib/libbsnmp/Makefile b/lib/libbsnmp/Makefile index 22821c7bcb5a..453cba29ddf5 100644 --- a/lib/libbsnmp/Makefile +++ b/lib/libbsnmp/Makefile @@ -1,5 +1,6 @@ # $FreeBSD$ SUBDIR= libbsnmp +SUBDIR.${MK_TESTS}+= tests .include diff --git a/lib/libbsnmp/tests/Makefile b/lib/libbsnmp/tests/Makefile new file mode 100644 index 000000000000..74fbec52ec13 --- /dev/null +++ b/lib/libbsnmp/tests/Makefile @@ -0,0 +1,11 @@ +# $FreeBSD$ + +.include + +ATF_TESTS_C+= bsnmpd_test + +SRCS.bsmpd_test= bsnmpd_test.c + +LIBADD+= bsnmp + +.include diff --git a/lib/libbsnmp/tests/bsnmpd_test.c b/lib/libbsnmp/tests/bsnmpd_test.c new file mode 100644 index 000000000000..c6e4bfd385b5 --- /dev/null +++ b/lib/libbsnmp/tests/bsnmpd_test.c @@ -0,0 +1,53 @@ +/*- + * Copyright (c) 2020 Dell EMC + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include + +#include + +ATF_TC_WITHOUT_HEAD(sa_19_20_bsnmp_test); +ATF_TC_BODY(sa_19_20_bsnmp_test, tc) +{ + struct asn_buf b = {}; + char test_buf[] = { 0x25, 0x7f }; + enum asn_err err; + asn_len_t len; + u_char type; + + b.asn_cptr = test_buf; + b.asn_len = sizeof(test_buf); + + err = asn_get_header(&b, &type, &len); + ATF_CHECK_EQ(ASN_ERR_EOBUF, err); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, sa_19_20_bsnmp_test); + return (atf_no_error()); +} From 3bd8419597b44dc3da2b1e6ffc2c7ee9cf4aa195 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Thu, 13 Aug 2020 23:13:05 +0000 Subject: [PATCH 81/96] flua: support "require" for binary objects in the base system Export symbols from flua, and enable dlopen. Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D26059 --- lib/liblua/luaconf.h | 1 + libexec/flua/Makefile | 2 ++ 2 files changed, 3 insertions(+) diff --git a/lib/liblua/luaconf.h b/lib/liblua/luaconf.h index db6f3222f101..6226e8ab1e84 100644 --- a/lib/liblua/luaconf.h +++ b/lib/liblua/luaconf.h @@ -75,6 +75,7 @@ /* Local modifications: need io.popen */ #ifdef __FreeBSD__ #define LUA_USE_POSIX +#define LUA_USE_DLOPEN #endif /* diff --git a/libexec/flua/Makefile b/libexec/flua/Makefile index a4dc916e7834..3efb75044b09 100644 --- a/libexec/flua/Makefile +++ b/libexec/flua/Makefile @@ -38,4 +38,6 @@ SRCS+= lua_ucl.c CFLAGS+= -I${UCLSRC}/include -I${UCLSRC}/src -I${UCLSRC}/uthash LIBADD+= ucl +LDFLAGS+= -Wl,-E + .include From 2933cd31845432dbaac67917e6babc516d2a57d1 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Fri, 14 Aug 2020 00:18:18 +0000 Subject: [PATCH 82/96] syslog(3): Send proper NILVALUE if gethostname(3) fails. RFC5424 defines NILVALUE as '-'. Replace its usage with a macro and separate out the fields to be more clear. fputs(3) is used in some places to avoid hiding possible format string problems in a macro. Reviewed by: cem, vangyzen (earlier version) Sponsored by: Dell EMC --- lib/libc/gen/syslog.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/libc/gen/syslog.c b/lib/libc/gen/syslog.c index a0f1ddc97535..19d44db0075a 100644 --- a/lib/libc/gen/syslog.c +++ b/lib/libc/gen/syslog.c @@ -75,6 +75,9 @@ static pthread_mutex_t syslog_mutex = PTHREAD_MUTEX_INITIALIZER; if (__isthreaded) _pthread_mutex_unlock(&syslog_mutex); \ } while(0) +/* RFC5424 defined value. */ +#define NILVALUE "-" + static void disconnectlog(void); /* disconnect from syslogd */ static void connectlog(void); /* (re)connect to syslogd */ static void openlog_unlocked(const char *, int, int); @@ -190,25 +193,30 @@ vsyslog1(int pri, const char *fmt, va_list ap) tm.tm_hour, tm.tm_min, tm.tm_sec, now.tv_usec, tz_sign, tz_offset / 3600, (tz_offset % 3600) / 60); } else - (void)fprintf(fp, "- "); + (void)fputs(NILVALUE " ", fp); /* Hostname. */ (void)gethostname(hostname, sizeof(hostname)); - (void)fprintf(fp, "%s ", hostname); + (void)fprintf(fp, "%s ", + hostname[0] == '\0' ? NILVALUE : hostname); if (LogStat & LOG_PERROR) { /* Transfer to string buffer */ (void)fflush(fp); stdp = tbuf + (sizeof(tbuf) - tbuf_cookie.left); } + /* Application name. */ + if (LogTag == NULL) + LogTag = _getprogname(); + (void)fprintf(fp, "%s ", LogTag == NULL ? NILVALUE : LogTag); /* - * Application name, process ID, message ID and structured data. * Provide the process ID regardless of whether LOG_PID has been * specified, as it provides valuable information. Many * applications tend not to use this, even though they should. */ - if (LogTag == NULL) - LogTag = _getprogname(); - (void)fprintf(fp, "%s %d - - ", - LogTag == NULL ? "-" : LogTag, getpid()); + (void)fprintf(fp, "%d ", getpid()); + /* Message ID. */ + (void)fputs(NILVALUE " ", fp); + /* Structured data. */ + (void)fputs(NILVALUE " ", fp); /* Check to see if we can skip expanding the %m */ if (strstr(fmt, "%m")) { @@ -251,6 +259,7 @@ vsyslog1(int pri, const char *fmt, va_list ap) fmt = fmt_cpy; } + /* Message. */ (void)vfprintf(fp, fmt, ap); (void)fclose(fp); From c2a2b4f3cf11e770892a524df637f671f5989719 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Fri, 14 Aug 2020 02:22:19 +0000 Subject: [PATCH 83/96] flua: don't allow dlopen, et al., for bootstrap flua There are some logistics issues that need to be sorted out here before we can actually allow this to work. --- lib/liblua/luaconf.h | 2 ++ libexec/flua/Makefile | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/liblua/luaconf.h b/lib/liblua/luaconf.h index 6226e8ab1e84..bc7f5bb6e141 100644 --- a/lib/liblua/luaconf.h +++ b/lib/liblua/luaconf.h @@ -75,8 +75,10 @@ /* Local modifications: need io.popen */ #ifdef __FreeBSD__ #define LUA_USE_POSIX +#ifndef BOOTSTRAPPING #define LUA_USE_DLOPEN #endif +#endif /* @@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for diff --git a/libexec/flua/Makefile b/libexec/flua/Makefile index 3efb75044b09..c852bd4fe499 100644 --- a/libexec/flua/Makefile +++ b/libexec/flua/Makefile @@ -30,6 +30,10 @@ CFLAGS+= -DLUA_PROGNAME="\"${PROG}\"" CFLAGS+= -DLUA_USE_READLINE CFLAGS+= -I${SRCTOP}/lib/libedit -I${SRCTOP}/contrib/libedit LIBADD+= edit +LDFLAGS+= -Wl,-E +.else +# We don't support dynamic libs on bootstrap builds. +CFLAGS+= -DBOOTSTRAPPING .endif UCLSRC?= ${SRCTOP}/contrib/libucl @@ -38,6 +42,4 @@ SRCS+= lua_ucl.c CFLAGS+= -I${UCLSRC}/include -I${UCLSRC}/src -I${UCLSRC}/uthash LIBADD+= ucl -LDFLAGS+= -Wl,-E - .include From 967fbfd9e2b7a015d5cba1491badcdf9044b28b9 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Fri, 14 Aug 2020 02:40:17 +0000 Subject: [PATCH 84/96] Properly disable LUA_USE_DLOPEN for bootstrap flua flua does have some specific bits that will include luaconf.h, but the definition of LUA_USE_DLOPEN for those won't matter. This belongs in liblua instead. To expand on my previous commit, which was a little sparse with details, it's not really safe to allow LUA_USE_DLOPEN with host lib paths being used. The host system could have an entirely different lua version and this could cause us to crash and burn. If we want to revive this later, we need to make sure to define c module paths inside OBJDIR that are compiled against whatever version we've bootstrapped. Pointy hat: kevans --- lib/liblua/Makefile | 2 ++ libexec/flua/Makefile | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/liblua/Makefile b/lib/liblua/Makefile index 28fc05a9aa71..e5f5e3c5960a 100644 --- a/lib/liblua/Makefile +++ b/lib/liblua/Makefile @@ -29,6 +29,8 @@ CFLAGS+= -DLUA_PROGNAME="\"${PROG}\"" .if defined(BOOTSTRAPPING) CFLAGS+= -DLUA_PATH_DEFAULT="\"/nonexistent/?.lua\"" CFLAGS+= -DLUA_CPATH_DEFAULT="\"/nonexistent/?.so\"" +# We don't support dynamic libs on bootstrap builds. +CFLAGS+= -DBOOTSTRAPPING .endif .include diff --git a/libexec/flua/Makefile b/libexec/flua/Makefile index c852bd4fe499..cfa1f2460f5f 100644 --- a/libexec/flua/Makefile +++ b/libexec/flua/Makefile @@ -31,9 +31,6 @@ CFLAGS+= -DLUA_USE_READLINE CFLAGS+= -I${SRCTOP}/lib/libedit -I${SRCTOP}/contrib/libedit LIBADD+= edit LDFLAGS+= -Wl,-E -.else -# We don't support dynamic libs on bootstrap builds. -CFLAGS+= -DBOOTSTRAPPING .endif UCLSRC?= ${SRCTOP}/contrib/libucl From 0e123c13fef68ed92a70c47b07660681dbd22ac1 Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Fri, 14 Aug 2020 08:48:17 +0000 Subject: [PATCH 85/96] linuxkpi: Add a few wait_bit functions The linux function does a lot more than that as multiple waitqueue could be fetch from a static table based on the hash of the argument but since in DRM it's only used in one place just add a single variable. We will probably need to change that in the futur but it's ok with DRM even with current linux. Reviewed by: hselasky MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D26054 --- .../linuxkpi/common/include/linux/wait.h | 1 + .../linuxkpi/common/include/linux/wait_bit.h | 64 +++++++++++++++++++ sys/compat/linuxkpi/common/src/linux_compat.c | 6 ++ 3 files changed, 71 insertions(+) create mode 100644 sys/compat/linuxkpi/common/include/linux/wait_bit.h diff --git a/sys/compat/linuxkpi/common/include/linux/wait.h b/sys/compat/linuxkpi/common/include/linux/wait.h index 7723910316ae..348464fb27df 100644 --- a/sys/compat/linuxkpi/common/include/linux/wait.h +++ b/sys/compat/linuxkpi/common/include/linux/wait.h @@ -36,6 +36,7 @@ #include #include #include +#include #include diff --git a/sys/compat/linuxkpi/common/include/linux/wait_bit.h b/sys/compat/linuxkpi/common/include/linux/wait_bit.h new file mode 100644 index 000000000000..e3dddaade498 --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/wait_bit.h @@ -0,0 +1,64 @@ +/*- + * Copyright (c) 2020 The FreeBSD Foundation + * + * This software was developed by Emmanuel Vadot under sponsorship + * from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef __LINUX_WAITBIT_H__ +#define __LINUX_WAITBIT_H__ + +#include +#include + +extern wait_queue_head_t linux_bit_waitq; +extern wait_queue_head_t linux_var_waitq; + +#define wait_var_event_killable(var, cond) \ + wait_event_killable(linux_var_waitq, cond) + +static inline void +clear_and_wake_up_bit(int bit, void *word) +{ + clear_bit_unlock(bit, word); + wake_up_bit(word, bit); +} + +static inline wait_queue_head_t * +bit_waitqueue(void *word, int bit) +{ + + return (&linux_bit_waitq); +} + +static inline void +wake_up_var(void *var) +{ + + wake_up(&linux_var_waitq); +} + +#endif /* __LINUX_WAITBIT_H__ */ diff --git a/sys/compat/linuxkpi/common/src/linux_compat.c b/sys/compat/linuxkpi/common/src/linux_compat.c index 0d5e14b9d027..b3c2475b223f 100644 --- a/sys/compat/linuxkpi/common/src/linux_compat.c +++ b/sys/compat/linuxkpi/common/src/linux_compat.c @@ -86,6 +86,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #if defined(__i386__) || defined(__amd64__) #include @@ -119,6 +120,9 @@ spinlock_t pci_lock; unsigned long linux_timer_hz_mask; +wait_queue_head_t linux_bit_waitq; +wait_queue_head_t linux_var_waitq; + int panic_cmp(struct rb_node *one, struct rb_node *two) { @@ -2523,6 +2527,8 @@ linux_compat_init(void *arg) mtx_init(&vmmaplock, "IO Map lock", NULL, MTX_DEF); for (i = 0; i < VMMAP_HASH_SIZE; i++) LIST_INIT(&vmmaphead[i]); + init_waitqueue_head(&linux_bit_waitq); + init_waitqueue_head(&linux_var_waitq); } SYSINIT(linux_compat, SI_SUB_DRIVERS, SI_ORDER_SECOND, linux_compat_init, NULL); From 9b9210015db6f63ab47b5b8eace1adf484630949 Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Fri, 14 Aug 2020 08:49:40 +0000 Subject: [PATCH 86/96] Bump __FreeBSD_version after r364232 We now have everything needed for DRM from Linux v5.4, let the ports tree know that. --- sys/sys/param.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/sys/param.h b/sys/sys/param.h index b947c1d6b394..171300319991 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -60,7 +60,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1300107 /* Master, propagated to newvers */ +#define __FreeBSD_version 1300108 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, From 0d5e65186195325557d4b0a8331d066a85818e01 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Fri, 14 Aug 2020 09:45:41 +0000 Subject: [PATCH 87/96] crunchgen: use pwd -P without env The -P flag is required by POSIX so we don't have to care whether pwd is a shell builtin or not. This also allows removing pwd from the list of bootstrap tools since all shells we care about for building have a builtin pwd command. This effectively reverts r364190. Suggested By: rgrimes, jrtc27 --- tools/build/Makefile | 2 +- usr.sbin/crunch/crunchgen/crunchgen.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/build/Makefile b/tools/build/Makefile index c78dbbdbbd4e..23bd6cc1896f 100644 --- a/tools/build/Makefile +++ b/tools/build/Makefile @@ -113,7 +113,7 @@ SYSINCS+= ${SRCTOP}/sys/sys/font.h # Linux/MacOS since we only use flags that are supported by all of them. _host_tools_to_symlink= basename bzip2 bunzip2 chmod chown cmp comm cp date dd \ dirname echo env false find fmt gzip gunzip head hostname id ln ls \ - mkdir mv nice patch pwd rm realpath sh sleep stat tee touch tr true \ + mkdir mv nice patch rm realpath sh sleep stat tee touch tr true \ uname uniq wc which # We also need a symlink to the absolute path to the make binary used for diff --git a/usr.sbin/crunch/crunchgen/crunchgen.c b/usr.sbin/crunch/crunchgen/crunchgen.c index 914795be7a21..5a3200ed7fac 100644 --- a/usr.sbin/crunch/crunchgen/crunchgen.c +++ b/usr.sbin/crunch/crunchgen/crunchgen.c @@ -653,7 +653,7 @@ fillin_program(prog_t *p) /* Determine the actual srcdir (maybe symlinked). */ if (p->srcdir) { - snprintf(line, MAXLINELEN, "cd %s && env pwd -P", p->srcdir); + snprintf(line, MAXLINELEN, "cd %s && pwd -P", p->srcdir); f = popen(line,"r"); if (!f) errx(1, "Can't execute: %s\n", line); From 85232c2ff13625a6d3223fd796360be8cc3244d2 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Fri, 14 Aug 2020 14:50:41 +0000 Subject: [PATCH 88/96] Rename the pipe_map field of struct pipe. This is to avoid conflicts with a upcoming macro. pipe_pages is a more accurate name since the field tracks pages wired into the kernel as part of a process-to-process copy operation. Reviewed by: alc, kib MFC after: 1 week Sponsored by: The FreeBSD Foundation --- sys/kern/sys_pipe.c | 60 ++++++++++++++++++++++----------------------- sys/sys/pipe.h | 2 +- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index a19b6efb0271..ad390e0a0c98 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -749,19 +749,19 @@ pipe_read(struct file *fp, struct uio *uio, struct ucred *active_cred, /* * Direct copy, bypassing a kernel buffer. */ - } else if ((size = rpipe->pipe_map.cnt) != 0) { + } else if ((size = rpipe->pipe_pages.cnt) != 0) { if (size > uio->uio_resid) size = (u_int) uio->uio_resid; PIPE_UNLOCK(rpipe); - error = uiomove_fromphys(rpipe->pipe_map.ms, - rpipe->pipe_map.pos, size, uio); + error = uiomove_fromphys(rpipe->pipe_pages.ms, + rpipe->pipe_pages.pos, size, uio); PIPE_LOCK(rpipe); if (error) break; nread += size; - rpipe->pipe_map.pos += size; - rpipe->pipe_map.cnt -= size; - if (rpipe->pipe_map.cnt == 0) { + rpipe->pipe_pages.pos += size; + rpipe->pipe_pages.cnt -= size; + if (rpipe->pipe_pages.cnt == 0) { rpipe->pipe_state &= ~PIPE_WANTW; wakeup(rpipe); } @@ -865,7 +865,7 @@ pipe_build_write_buffer(struct pipe *wpipe, struct uio *uio) PIPE_LOCK_ASSERT(wpipe, MA_OWNED); KASSERT((wpipe->pipe_state & PIPE_DIRECTW) == 0, ("%s: PIPE_DIRECTW set on %p", __func__, wpipe)); - KASSERT(wpipe->pipe_map.cnt == 0, + KASSERT(wpipe->pipe_pages.cnt == 0, ("%s: pipe map for %p contains residual data", __func__, wpipe)); if (uio->uio_iov->iov_len > wpipe->pipe_buffer.size) @@ -877,17 +877,17 @@ pipe_build_write_buffer(struct pipe *wpipe, struct uio *uio) PIPE_UNLOCK(wpipe); i = vm_fault_quick_hold_pages(&curproc->p_vmspace->vm_map, (vm_offset_t)uio->uio_iov->iov_base, size, VM_PROT_READ, - wpipe->pipe_map.ms, PIPENPAGES); + wpipe->pipe_pages.ms, PIPENPAGES); PIPE_LOCK(wpipe); if (i < 0) { wpipe->pipe_state &= ~PIPE_DIRECTW; return (EFAULT); } - wpipe->pipe_map.npages = i; - wpipe->pipe_map.pos = + wpipe->pipe_pages.npages = i; + wpipe->pipe_pages.pos = ((vm_offset_t) uio->uio_iov->iov_base) & PAGE_MASK; - wpipe->pipe_map.cnt = size; + wpipe->pipe_pages.cnt = size; uio->uio_iov->iov_len -= size; uio->uio_iov->iov_base = (char *)uio->uio_iov->iov_base + size; @@ -908,12 +908,12 @@ pipe_destroy_write_buffer(struct pipe *wpipe) PIPE_LOCK_ASSERT(wpipe, MA_OWNED); KASSERT((wpipe->pipe_state & PIPE_DIRECTW) != 0, ("%s: PIPE_DIRECTW not set on %p", __func__, wpipe)); - KASSERT(wpipe->pipe_map.cnt == 0, + KASSERT(wpipe->pipe_pages.cnt == 0, ("%s: pipe map for %p contains residual data", __func__, wpipe)); wpipe->pipe_state &= ~PIPE_DIRECTW; - vm_page_unhold_pages(wpipe->pipe_map.ms, wpipe->pipe_map.npages); - wpipe->pipe_map.npages = 0; + vm_page_unhold_pages(wpipe->pipe_pages.ms, wpipe->pipe_pages.npages); + wpipe->pipe_pages.npages = 0; } /* @@ -933,9 +933,9 @@ pipe_clone_write_buffer(struct pipe *wpipe) KASSERT((wpipe->pipe_state & PIPE_DIRECTW) != 0, ("%s: PIPE_DIRECTW not set on %p", __func__, wpipe)); - size = wpipe->pipe_map.cnt; - pos = wpipe->pipe_map.pos; - wpipe->pipe_map.cnt = 0; + size = wpipe->pipe_pages.cnt; + pos = wpipe->pipe_pages.pos; + wpipe->pipe_pages.cnt = 0; wpipe->pipe_buffer.in = size; wpipe->pipe_buffer.out = 0; @@ -951,7 +951,7 @@ pipe_clone_write_buffer(struct pipe *wpipe) uio.uio_segflg = UIO_SYSSPACE; uio.uio_rw = UIO_READ; uio.uio_td = curthread; - uiomove_fromphys(wpipe->pipe_map.ms, pos, size, &uio); + uiomove_fromphys(wpipe->pipe_pages.ms, pos, size, &uio); PIPE_LOCK(wpipe); pipe_destroy_write_buffer(wpipe); } @@ -1015,7 +1015,7 @@ pipe_direct_write(struct pipe *wpipe, struct uio *uio) goto error1; } - while (wpipe->pipe_map.cnt != 0 && + while (wpipe->pipe_pages.cnt != 0 && (wpipe->pipe_state & PIPE_EOF) == 0) { if (wpipe->pipe_state & PIPE_WANTR) { wpipe->pipe_state &= ~PIPE_WANTR; @@ -1032,7 +1032,7 @@ pipe_direct_write(struct pipe *wpipe, struct uio *uio) } if ((wpipe->pipe_state & PIPE_EOF) != 0) { - wpipe->pipe_map.cnt = 0; + wpipe->pipe_pages.cnt = 0; pipe_destroy_write_buffer(wpipe); pipeselwakeup(wpipe); error = EPIPE; @@ -1157,7 +1157,7 @@ pipe_write(struct file *fp, struct uio *uio, struct ucred *active_cred, * pipe buffer. We break out if a signal occurs or the * reader goes away. */ - if (wpipe->pipe_map.cnt != 0) { + if (wpipe->pipe_pages.cnt != 0) { if (wpipe->pipe_state & PIPE_WANTR) { wpipe->pipe_state &= ~PIPE_WANTR; wakeup(wpipe); @@ -1375,8 +1375,8 @@ pipe_ioctl(struct file *fp, u_long cmd, void *data, struct ucred *active_cred, PIPE_UNLOCK(mpipe); return (0); } - if (mpipe->pipe_map.cnt != 0) - *(int *)data = mpipe->pipe_map.cnt; + if (mpipe->pipe_pages.cnt != 0) + *(int *)data = mpipe->pipe_pages.cnt; else *(int *)data = mpipe->pipe_buffer.cnt; break; @@ -1431,7 +1431,7 @@ pipe_poll(struct file *fp, int events, struct ucred *active_cred, goto locked_error; #endif if (fp->f_flag & FREAD && events & (POLLIN | POLLRDNORM)) - if (rpipe->pipe_map.cnt > 0 || rpipe->pipe_buffer.cnt > 0) + if (rpipe->pipe_pages.cnt > 0 || rpipe->pipe_buffer.cnt > 0) revents |= events & (POLLIN | POLLRDNORM); if (fp->f_flag & FWRITE && events & (POLLOUT | POLLWRNORM)) @@ -1513,8 +1513,8 @@ pipe_stat(struct file *fp, struct stat *ub, struct ucred *active_cred, bzero(ub, sizeof(*ub)); ub->st_mode = S_IFIFO; ub->st_blksize = PAGE_SIZE; - if (pipe->pipe_map.cnt != 0) - ub->st_size = pipe->pipe_map.cnt; + if (pipe->pipe_pages.cnt != 0) + ub->st_size = pipe->pipe_pages.cnt; else ub->st_size = pipe->pipe_buffer.cnt; ub->st_blocks = howmany(ub->st_size, ub->st_blksize); @@ -1604,9 +1604,9 @@ pipe_free_kmem(struct pipe *cpipe) } #ifndef PIPE_NODIRECT { - cpipe->pipe_map.cnt = 0; - cpipe->pipe_map.pos = 0; - cpipe->pipe_map.npages = 0; + cpipe->pipe_pages.cnt = 0; + cpipe->pipe_pages.pos = 0; + cpipe->pipe_pages.npages = 0; } #endif } @@ -1752,7 +1752,7 @@ filt_piperead(struct knote *kn, long hint) PIPE_LOCK_ASSERT(rpipe, MA_OWNED); kn->kn_data = rpipe->pipe_buffer.cnt; if (kn->kn_data == 0) - kn->kn_data = rpipe->pipe_map.cnt; + kn->kn_data = rpipe->pipe_pages.cnt; if ((rpipe->pipe_state & PIPE_EOF) != 0 && ((rpipe->pipe_state & PIPE_NAMED) == 0 || diff --git a/sys/sys/pipe.h b/sys/sys/pipe.h index 4e633262191d..2f1568ab6637 100644 --- a/sys/sys/pipe.h +++ b/sys/sys/pipe.h @@ -103,7 +103,7 @@ struct pipemapping { */ struct pipe { struct pipebuf pipe_buffer; /* data storage */ - struct pipemapping pipe_map; /* pipe mapping for direct I/O */ + struct pipemapping pipe_pages; /* wired pages for direct I/O */ struct selinfo pipe_sel; /* for compat with select */ struct timespec pipe_atime; /* time of last access */ struct timespec pipe_mtime; /* time of last modify */ From ea7b737a6fe72565f53471d2a1e1b03a0348c642 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Fri, 14 Aug 2020 18:48:48 +0000 Subject: [PATCH 89/96] vm_pageout: Correct threshold calculation on single-CPU systems Reported by: Michael Butler X-MFC-With: r364129 --- sys/vm/vm_pageout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index 286528905eaa..a882a17f3f39 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -2216,7 +2216,7 @@ get_pageout_threads_per_domain(void) * Semi-arbitrarily constrain pagedaemon threads to less than half the * total number of threads in the system as an insane upper limit. */ - half_cpus_per_dom = (mp_ncpus / vm_ndomains) / 2; + half_cpus_per_dom = howmany(mp_ncpus / vm_ndomains, 2); if (pageout_threads_per_domain < 1) { printf("Invalid tuneable vm.pageout_threads_per_domain value: " From 2f23f45b20ace184ddc5183d298a9f47cd9c2e33 Mon Sep 17 00:00:00 2001 From: "Alexander V. Chernikov" Date: Fri, 14 Aug 2020 21:29:56 +0000 Subject: [PATCH 90/96] Simplify dom_. Remove unused arguments from dom_rtattach/dom_rtdetach functions and make them return/accept 'struct rib_head' instead of 'void **'. Declare inet/inet6 implementations in the relevant _var.h headers similar to domifattach / domifdetach. Add rib_subscribe_internal() function to accept subscriptions to the rnh directly. Differential Revision: https://reviews.freebsd.org/D26053 --- sys/net/route.c | 4 ++-- sys/net/route/route_ctl.c | 44 +++++++++++++++++++++++++++++++++------ sys/net/route/route_ctl.h | 3 +++ sys/netinet/in_proto.c | 3 --- sys/netinet/in_rmx.c | 24 +++++++-------------- sys/netinet/in_var.h | 7 +++++-- sys/netinet6/in6_proto.c | 5 ----- sys/netinet6/in6_rmx.c | 24 +++++++-------------- sys/netinet6/in6_var.h | 3 +++ sys/sys/domain.h | 9 ++++---- 10 files changed, 71 insertions(+), 55 deletions(-) diff --git a/sys/net/route.c b/sys/net/route.c index 2f9baa685520..4167df8d0cce 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -227,7 +227,7 @@ vnet_route_init(const void *unused __unused) rnh = rt_tables_get_rnh_ptr(table, fam); if (rnh == NULL) panic("%s: rnh NULL", __func__); - dom->dom_rtattach((void **)rnh, 0, table); + *rnh = dom->dom_rtattach(table); } } } @@ -256,7 +256,7 @@ vnet_route_uninit(const void *unused __unused) rnh = rt_tables_get_rnh_ptr(table, fam); if (rnh == NULL) panic("%s: rnh NULL", __func__); - dom->dom_rtdetach((void **)rnh, 0); + dom->dom_rtdetach(*rnh); } } diff --git a/sys/net/route/route_ctl.c b/sys/net/route/route_ctl.c index 212f5b51e5b5..f448bcef1b8d 100644 --- a/sys/net/route/route_ctl.c +++ b/sys/net/route/route_ctl.c @@ -817,6 +817,25 @@ rib_notify(struct rib_head *rnh, enum rib_subscription_type type, } } +static struct rib_subscription * +allocate_subscription(rib_subscription_cb_t *f, void *arg, + enum rib_subscription_type type, bool waitok) +{ + struct rib_subscription *rs; + int flags = M_ZERO | (waitok ? M_WAITOK : 0); + + rs = malloc(sizeof(struct rib_subscription), M_RTABLE, flags); + if (rs == NULL) + return (NULL); + + rs->func = f; + rs->arg = arg; + rs->type = type; + + return (rs); +} + + /* * Subscribe for the changes in the routing table specified by @fibnum and * @family. @@ -830,20 +849,33 @@ rib_subscribe(uint32_t fibnum, int family, rib_subscription_cb_t *f, void *arg, struct rib_head *rnh; struct rib_subscription *rs; struct epoch_tracker et; - int flags = M_ZERO | (waitok ? M_WAITOK : 0); - rs = malloc(sizeof(struct rib_subscription), M_RTABLE, flags); - if (rs == NULL) + if ((rs = allocate_subscription(f, arg, type, waitok)) == NULL) return (NULL); NET_EPOCH_ENTER(et); KASSERT((fibnum < rt_numfibs), ("%s: bad fibnum", __func__)); rnh = rt_tables_get_rnh(fibnum, family); - rs->func = f; - rs->arg = arg; - rs->type = type; + RIB_WLOCK(rnh); + CK_STAILQ_INSERT_TAIL(&rnh->rnh_subscribers, rs, next); + RIB_WUNLOCK(rnh); + NET_EPOCH_EXIT(et); + return (rs); +} + +struct rib_subscription * +rib_subscribe_internal(struct rib_head *rnh, rib_subscription_cb_t *f, void *arg, + enum rib_subscription_type type, bool waitok) +{ + struct rib_subscription *rs; + struct epoch_tracker et; + + if ((rs = allocate_subscription(f, arg, type, waitok)) == NULL) + return (NULL); + + NET_EPOCH_ENTER(et); RIB_WLOCK(rnh); CK_STAILQ_INSERT_TAIL(&rnh->rnh_subscribers, rs, next); RIB_WUNLOCK(rnh); diff --git a/sys/net/route/route_ctl.h b/sys/net/route/route_ctl.h index a7f445a21c53..62208609cd4d 100644 --- a/sys/net/route/route_ctl.h +++ b/sys/net/route/route_ctl.h @@ -79,6 +79,9 @@ typedef void rib_subscription_cb_t(struct rib_head *rnh, struct rib_cmd_info *rc struct rib_subscription *rib_subscribe(uint32_t fibnum, int family, rib_subscription_cb_t *f, void *arg, enum rib_subscription_type type, bool waitok); +struct rib_subscription *rib_subscribe_internal(struct rib_head *rnh, + rib_subscription_cb_t *f, void *arg, enum rib_subscription_type type, + bool waitok); int rib_unsibscribe(uint32_t fibnum, int family, struct rib_subscription *rs); #endif diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c index 2288a4c36abe..4133ded92a82 100644 --- a/sys/netinet/in_proto.c +++ b/sys/netinet/in_proto.c @@ -294,9 +294,6 @@ IPPROTOSPACER, }, }; -extern int in_inithead(void **, int, u_int); -extern int in_detachhead(void **, int); - struct domain inetdomain = { .dom_family = AF_INET, .dom_name = "internet", diff --git a/sys/netinet/in_rmx.c b/sys/netinet/in_rmx.c index 38a9d9232a8a..21f2e67b15bd 100644 --- a/sys/netinet/in_rmx.c +++ b/sys/netinet/in_rmx.c @@ -54,10 +54,6 @@ __FBSDID("$FreeBSD$"); #include #include -extern int in_inithead(void **head, int off, u_int fibnum); -#ifdef VIMAGE -extern int in_detachhead(void **head, int off); -#endif static int rib4_preadd(u_int fibnum, const struct sockaddr *addr, const struct sockaddr *mask, @@ -121,38 +117,32 @@ rib4_preadd(u_int fibnum, const struct sockaddr *addr, const struct sockaddr *ma return (0); } -static int _in_rt_was_here; /* * Initialize our routing tree. */ -int -in_inithead(void **head, int off, u_int fibnum) +struct rib_head * +in_inithead(uint32_t fibnum) { struct rib_head *rh; rh = rt_table_init(32, AF_INET, fibnum); if (rh == NULL) - return (0); + return (NULL); rh->rnh_preadd = rib4_preadd; #ifdef RADIX_MPATH rt_mpath_init_rnh(rh); #endif - *head = (void *)rh; - if (_in_rt_was_here == 0 ) { - _in_rt_was_here = 1; - } - return 1; + return (rh); } #ifdef VIMAGE -int -in_detachhead(void **head, int off) +void +in_detachhead(struct rib_head *rh) { - rt_table_destroy((struct rib_head *)(*head)); - return (1); + rt_table_destroy(rh); } #endif diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h index 9babe5d053d9..fabd8e1ab50c 100644 --- a/sys/netinet/in_var.h +++ b/sys/netinet/in_var.h @@ -436,8 +436,7 @@ inm_rele_locked(struct in_multi_head *inmh, struct in_multi *inm) #define MCAST_NOTSMEMBER 2 /* This host excluded source */ #define MCAST_MUTED 3 /* [deprecated] */ -struct rtentry; -struct route; +struct rib_head; struct ip_moptions; struct in_multi *inm_lookup_locked(struct ifnet *, const struct in_addr); @@ -471,6 +470,10 @@ void in_ifadown(struct ifaddr *ifa, int); struct mbuf *ip_tryforward(struct mbuf *); void *in_domifattach(struct ifnet *); void in_domifdetach(struct ifnet *, void *); +struct rib_head *in_inithead(uint32_t fibnum); +#ifdef VIMAGE +void in_detachhead(struct rib_head *rh); +#endif #endif /* _KERNEL */ diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c index ea7a468ac72b..9f9c9b9dbbf8 100644 --- a/sys/netinet6/in6_proto.c +++ b/sys/netinet6/in6_proto.c @@ -333,11 +333,6 @@ IP6PROTOSPACER, }, }; -extern int in6_inithead(void **, int, u_int); -#ifdef VIMAGE -extern int in6_detachhead(void **, int); -#endif - struct domain inet6domain = { .dom_family = AF_INET6, .dom_name = "internet6", diff --git a/sys/netinet6/in6_rmx.c b/sys/netinet6/in6_rmx.c index f705c91602f4..c026bf4a057c 100644 --- a/sys/netinet6/in6_rmx.c +++ b/sys/netinet6/in6_rmx.c @@ -101,11 +101,6 @@ __FBSDID("$FreeBSD$"); #include #include -extern int in6_inithead(void **head, int off, u_int fibnum); -#ifdef VIMAGE -extern int in6_detachhead(void **head, int off); -#endif - static int rib6_preadd(u_int fibnum, const struct sockaddr *addr, const struct sockaddr *mask, struct nhop_object *nh) @@ -147,8 +142,8 @@ rib6_preadd(u_int fibnum, const struct sockaddr *addr, const struct sockaddr *ma * Initialize our routing tree. */ -int -in6_inithead(void **head, int off, u_int fibnum) +struct rib_head * +in6_inithead(uint32_t fibnum) { struct rib_head *rh; struct rib_subscription *rs; @@ -156,29 +151,26 @@ in6_inithead(void **head, int off, u_int fibnum) rh = rt_table_init(offsetof(struct sockaddr_in6, sin6_addr) << 3, AF_INET6, fibnum); if (rh == NULL) - return (0); + return (NULL); rh->rnh_preadd = rib6_preadd; #ifdef RADIX_MPATH rt_mpath_init_rnh(rh); #endif - *head = (void *)rh; - rs = rib_subscribe(fibnum, AF_INET6, nd6_subscription_cb, NULL, + rs = rib_subscribe_internal(rh, nd6_subscription_cb, NULL, RIB_NOTIFY_IMMEDIATE, true); KASSERT(rs != NULL, ("Unable to subscribe to fib %u\n", fibnum)); - return (1); + return (rh); } #ifdef VIMAGE -int -in6_detachhead(void **head, int off) +void +in6_detachhead(struct rib_head *rh) { - rt_table_destroy((struct rib_head *)(*head)); - - return (1); + rt_table_destroy(rh); } #endif diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h index 7381ff68064a..f5e6a931ae64 100644 --- a/sys/netinet6/in6_var.h +++ b/sys/netinet6/in6_var.h @@ -857,6 +857,7 @@ in6m_rele_locked(struct in6_multi_head *inmh, struct in6_multi *inm) struct ip6_moptions; struct sockopt; struct inpcbinfo; +struct rib_head; /* Multicast KPIs. */ int im6o_mc_filter(const struct ip6_moptions *, const struct ifnet *, @@ -891,6 +892,8 @@ void in6_savemkludge(struct in6_ifaddr *); void *in6_domifattach(struct ifnet *); void in6_domifdetach(struct ifnet *, void *); int in6_domifmtu(struct ifnet *); +struct rib_head *in6_inithead(uint32_t fibnum); +void in6_detachhead(struct rib_head *rh); void in6_setmaxmtu(void); int in6_if2idlen(struct ifnet *); struct in6_ifaddr *in6ifa_ifpforlinklocal(struct ifnet *, int); diff --git a/sys/sys/domain.h b/sys/sys/domain.h index e83dd0f4afc5..3d17879f1ccd 100644 --- a/sys/sys/domain.h +++ b/sys/sys/domain.h @@ -45,6 +45,7 @@ struct mbuf; struct ifnet; struct socket; +struct rib_head; struct domain { int dom_family; /* AF_xxx */ @@ -59,10 +60,10 @@ struct domain { (struct socket *); struct protosw *dom_protosw, *dom_protoswNPROTOSW; struct domain *dom_next; - int (*dom_rtattach) /* initialize routing table */ - (void **, int, u_int); - int (*dom_rtdetach) /* clean up routing table */ - (void **, int); + struct rib_head *(*dom_rtattach) /* initialize routing table */ + (uint32_t); + void (*dom_rtdetach) /* clean up routing table */ + (struct rib_head *); void *(*dom_ifattach)(struct ifnet *); void (*dom_ifdetach)(struct ifnet *, void *); int (*dom_ifmtu)(struct ifnet *); From f3ba85ccc84991e40e866e6e552d3d6960a16c28 Mon Sep 17 00:00:00 2001 From: "Jason A. Harmening" Date: Fri, 14 Aug 2020 21:37:38 +0000 Subject: [PATCH 91/96] kenv: avoid sleepable alloc for integer tunables Avoid performing a potentially-blocking malloc for kenv lookups that will only perform non-destructive integer conversions on the returned buffer. Instead, perform the strtoq() in-place with the kenv lock held. While here, factor the logic around kenv_lock acquire and release into kenv_acquire() and kenv_release(), and use these functions for some light cleanup. Collapse getenv_string_buffer() into kern_getenv(), as the former no longer has any other callers and the only additional task performed by the latter is a WITNESS check that hasn't been useful since r362231. PR: 248250 Reported by: gbe Reviewed by: mjg Tested by: gbe Differential Revision: https://reviews.freebsd.org/D26010 --- sys/kern/kern_environment.c | 124 +++++++++++++++++++----------------- 1 file changed, 67 insertions(+), 57 deletions(-) diff --git a/sys/kern/kern_environment.c b/sys/kern/kern_environment.c index 312440ab509e..f906f3c6c838 100644 --- a/sys/kern/kern_environment.c +++ b/sys/kern/kern_environment.c @@ -59,6 +59,9 @@ __FBSDID("$FreeBSD$"); static char *_getenv_dynamic_locked(const char *name, int *idx); static char *_getenv_dynamic(const char *name, int *idx); +static char *kenv_acquire(const char *name); +static void kenv_release(const char *buf); + static MALLOC_DEFINE(M_KENV, "kenv", "kernel environment"); #define KENV_SIZE 512 /* Maximum number of environment strings */ @@ -88,8 +91,6 @@ bool dynamic_kenv; #define KENV_CHECK if (!dynamic_kenv) \ panic("%s: called before SI_SUB_KMEM", __func__) -static char *getenv_string_buffer(const char *); - int sys_kenv(td, uap) struct thread *td; @@ -482,16 +483,24 @@ _getenv_static(const char *name) char * kern_getenv(const char *name) { - char *ret; + char *cp, *ret; + int len; if (dynamic_kenv) { - ret = getenv_string_buffer(name); - if (ret == NULL) { - WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, - "getenv"); + len = KENV_MNAMELEN + 1 + kenv_mvallen + 1; + ret = uma_zalloc(kenv_zone, M_WAITOK | M_ZERO); + mtx_lock(&kenv_lock); + cp = _getenv_dynamic(name, NULL); + if (cp != NULL) + strlcpy(ret, cp, len); + mtx_unlock(&kenv_lock); + if (cp == NULL) { + uma_zfree(kenv_zone, ret); + ret = NULL; } } else ret = _getenv_static(name); + return (ret); } @@ -503,12 +512,9 @@ testenv(const char *name) { char *cp; - if (dynamic_kenv) { - mtx_lock(&kenv_lock); - cp = _getenv_dynamic(name, NULL); - mtx_unlock(&kenv_lock); - } else - cp = _getenv_static(name); + cp = kenv_acquire(name); + kenv_release(cp); + if (cp != NULL) return (1); return (0); @@ -615,30 +621,33 @@ kern_unsetenv(const char *name) } /* - * Return a buffer containing the string value from an environment variable + * Return the internal kenv buffer for the variable name, if it exists. + * If the dynamic kenv is initialized and the name is present, return + * with kenv_lock held. */ static char * -getenv_string_buffer(const char *name) +kenv_acquire(const char *name) { - char *cp, *ret; - int len; + char *value; if (dynamic_kenv) { - len = KENV_MNAMELEN + 1 + kenv_mvallen + 1; - ret = uma_zalloc(kenv_zone, M_WAITOK | M_ZERO); mtx_lock(&kenv_lock); - cp = _getenv_dynamic(name, NULL); - if (cp != NULL) - strlcpy(ret, cp, len); - mtx_unlock(&kenv_lock); - if (cp == NULL) { - uma_zfree(kenv_zone, ret); - ret = NULL; - } + value = _getenv_dynamic(name, NULL); + if (value == NULL) + mtx_unlock(&kenv_lock); + return (value); } else - ret = _getenv_static(name); + return (_getenv_static(name)); +} - return (ret); +/* + * Undo a previous kenv_acquire() operation + */ +static void +kenv_release(const char *buf) +{ + if ((buf != NULL) && dynamic_kenv) + mtx_unlock(&kenv_lock); } /* @@ -649,17 +658,13 @@ getenv_string(const char *name, char *data, int size) { char *cp; - if (dynamic_kenv) { - mtx_lock(&kenv_lock); - cp = _getenv_dynamic(name, NULL); - if (cp != NULL) - strlcpy(data, cp, size); - mtx_unlock(&kenv_lock); - } else { - cp = _getenv_static(name); - if (cp != NULL) - strlcpy(data, cp, size); - } + cp = kenv_acquire(name); + + if (cp != NULL) + strlcpy(data, cp, size); + + kenv_release(cp); + return (cp != NULL); } @@ -673,16 +678,18 @@ getenv_array(const char *name, void *pdata, int size, int *psize, uint8_t shift; int64_t value; int64_t old; - char *buf; + const char *buf; char *end; - char *ptr; + const char *ptr; int n; int rc; - if ((buf = getenv_string_buffer(name)) == NULL) - return (0); - rc = 0; /* assume failure */ + + buf = kenv_acquire(name); + if (buf == NULL) + goto error; + /* get maximum number of elements */ size /= type_size; @@ -797,8 +804,7 @@ getenv_array(const char *name, void *pdata, int size, int *psize, if (n != 0) rc = 1; /* success */ error: - if (dynamic_kenv) - uma_zfree(kenv_zone, buf); + kenv_release(buf); return (rc); } @@ -898,18 +904,21 @@ getenv_ulong(const char *name, unsigned long *data) int getenv_quad(const char *name, quad_t *data) { - char *value, *vtp; - quad_t iv; + const char *value; + char suffix, *vtp; + quad_t iv; - value = getenv_string_buffer(name); - if (value == NULL) - return (0); + value = kenv_acquire(name); + if (value == NULL) { + goto error; + } iv = strtoq(value, &vtp, 0); if (vtp == value || (vtp[0] != '\0' && vtp[1] != '\0')) { - freeenv(value); - return (0); + goto error; } - switch (vtp[0]) { + suffix = vtp[0]; + kenv_release(value); + switch (suffix) { case 't': case 'T': iv *= 1024; /* FALLTHROUGH */ @@ -924,12 +933,13 @@ getenv_quad(const char *name, quad_t *data) case '\0': break; default: - freeenv(value); return (0); } - freeenv(value); *data = iv; return (1); +error: + kenv_release(value); + return (0); } /* From 60f3863fa21d3d612d6372031abc260c60684a04 Mon Sep 17 00:00:00 2001 From: Li-Wen Hsu Date: Sat, 15 Aug 2020 03:20:39 +0000 Subject: [PATCH 92/96] Remove redeclaration found by gcc build Reviewed by: erj Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D25953 --- sys/dev/ice/ice_common.h | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/sys/dev/ice/ice_common.h b/sys/dev/ice/ice_common.h index 1cff7efb8150..bba7f2699b22 100644 --- a/sys/dev/ice/ice_common.h +++ b/sys/dev/ice/ice_common.h @@ -46,16 +46,6 @@ enum ice_fw_modes { ICE_FW_MODE_ROLLBACK }; -/* prototype for functions used for SW locks */ -void ice_free_list(struct LIST_HEAD_TYPE *list); -void ice_init_lock(struct ice_lock *lock); -void ice_acquire_lock(struct ice_lock *lock); -void ice_release_lock(struct ice_lock *lock); -void ice_destroy_lock(struct ice_lock *lock); - -void *ice_alloc_dma_mem(struct ice_hw *hw, struct ice_dma_mem *m, u64 size); -void ice_free_dma_mem(struct ice_hw *hw, struct ice_dma_mem *m); - void ice_idle_aq(struct ice_hw *hw, struct ice_ctl_q_info *cq); bool ice_sq_done(struct ice_hw *hw, struct ice_ctl_q_info *cq); @@ -78,13 +68,6 @@ enum ice_status ice_get_link_status(struct ice_port_info *pi, bool *link_up); enum ice_status ice_update_link_info(struct ice_port_info *pi); enum ice_status -ice_acquire_nvm(struct ice_hw *hw, enum ice_aq_res_access_type access); -void ice_release_nvm(struct ice_hw *hw); -enum ice_status -ice_aq_read_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset, u16 length, - void *data, bool last_command, bool read_shadow_ram, - struct ice_sq_cd *cd); -enum ice_status ice_acquire_res(struct ice_hw *hw, enum ice_aq_res_ids res, enum ice_aq_res_access_type access, u32 timeout); void ice_release_res(struct ice_hw *hw, enum ice_aq_res_ids res); From fc4c42c9e37d667f5f682aea643b8047763f72e0 Mon Sep 17 00:00:00 2001 From: Li-Wen Hsu Date: Sat, 15 Aug 2020 03:26:00 +0000 Subject: [PATCH 93/96] Remove redeclaration found by gcc build Reviewed by: Jacob Keller Suggested editing from: Krzysztof Galazka Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D25954 --- sys/dev/ixl/i40e_prototype.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/dev/ixl/i40e_prototype.h b/sys/dev/ixl/i40e_prototype.h index 51021ed28e6a..6e86e68eb8db 100644 --- a/sys/dev/ixl/i40e_prototype.h +++ b/sys/dev/ixl/i40e_prototype.h @@ -606,6 +606,4 @@ enum i40e_status_code i40e_read_phy_register(struct i40e_hw *hw, enum i40e_status_code i40e_write_phy_register(struct i40e_hw *hw, u8 page, u16 reg, u8 phy_addr, u16 value); u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num); -enum i40e_status_code i40e_blink_phy_link_led(struct i40e_hw *hw, - u32 time, u32 interval); #endif /* _I40E_PROTOTYPE_H_ */ From 84fa0ef97db9dd72693f10a1fa72c766f2b0838f Mon Sep 17 00:00:00 2001 From: Hiroki Sato Date: Sat, 15 Aug 2020 07:19:37 +0000 Subject: [PATCH 94/96] - Update to Unicode CLDR v35 (Unicode 12.0). - Update tools/tools/locale to add make targets to automatically generate locale source files. With this change, just typing "make obj && make -j4" will rebuild them. Check README for more details. - Fix issues in ja_JP ctypedef and range specification support in utf8-rollup.pl. - Add a temporary patch for UnicodeData.txt to fix code ranges of CJK Ideograph Extension A and Extension B. - tools/cldr2def.pl: Use eucJP for ja_JP ctypedef because eucJP is not compatible with UTF-8. - tools/convert_map.pl: Add a verbose error message. - tools/utf8-rollup.pl: Normalize entries to use Unicode, not UTF-8. Reviewed by: bapt Differential Revision: https://reviews.freebsd.org/D25503 --- tools/tools/locale/Makefile | 193 ++++-- tools/tools/locale/README | 80 ++- tools/tools/locale/etc/final-maps/map.UTF-8 | 554 ++++++++++++++++++ .../tools/locale/patch/patch-UnicodeData.txt | 29 + tools/tools/locale/tools/cldr2def.pl | 5 + tools/tools/locale/tools/convert_map.pl | 5 +- tools/tools/locale/tools/finalize | 38 +- tools/tools/locale/tools/utf8-rollup.pl | 31 +- 8 files changed, 821 insertions(+), 114 deletions(-) create mode 100644 tools/tools/locale/patch/patch-UnicodeData.txt diff --git a/tools/tools/locale/Makefile b/tools/tools/locale/Makefile index 508034d19695..aad2c2160bb5 100644 --- a/tools/tools/locale/Makefile +++ b/tools/tools/locale/Makefile @@ -7,19 +7,30 @@ # # Modified by John Marino to suit DragonFly needs # - -.OBJDIR: . - -.if !defined(UNIDIR) -.error UNIDIR is not set +.if ${.CURDIR} == ${.OBJDIR} +.error Do make obj first. .endif -PASSON= UNIDIR="${UNIDIR}" -ETCDIR= ${.CURDIR}/etc +LOCALESRCDIR?= ${DESTDIR}/usr/src/share +TMPDIR?= /tmp + +BASEDIR= ${.CURDIR} +ETCDIR= ${BASEDIR}/etc +TOOLSDIR= ${BASEDIR}/tools +PATCHDIR= ${BASEDIR}/patch +UNIDIR= ${.OBJDIR:tA}/unicode + +PKGS= openjdk8 \ + apache-ant \ + p5-XML-Parser \ + p5-Tie-IxHash \ + p5-Text-Iconv +tools-test: + pkg info -e ${PKGS} + @echo tools ok. KNOWN= monetdef numericdef msgdef colldef ctypedef # timedef TYPES?= ${KNOWN} -LOCALE_DESTDIR?= /tmp/generated-locales/ COLLATION_SPECIAL?= \ cs_CZ ISO8859-2 \ @@ -44,65 +55,79 @@ COLLATION_SPECIAL?= \ .for area enc in ${COLLATION_SPECIAL} COLLATIONS_SPECIAL_ENV+= ${area}.${enc} .endfor -PASSON+= COLLATIONS_SPECIAL="${COLLATIONS_SPECIAL_ENV}" +SETENV= env -i \ + PATH="${PATH}" \ + TMPDIR="${TMPDIR}" \ + COLLATIONS_SPECIAL="${COLLATIONS_SPECIAL_ENV}" \ + UNIDIR="${UNIDIR}" \ + BASEDIR="${BASEDIR}" \ + TOOLSDIR="${TOOLSDIR}" \ + ETCDIR="${ETCDIR}" -all: -.for t in ${TYPES} -. if ${KNOWN:M${t}} - test -d ${t} || mkdir ${t} - make build-${t} -. endif -.endfor +all: posix build afterbuild +.ORDER: posix build afterbuild + +afterbuild: build @echo "" @find . -name *failed .for t in ${TYPES} +. if ${KNOWN:M${t}} +build: build-${t} +.ORDER: build-${t} afterbuild +. endif +.endfor + +diff: +.for t in ${TYPES} +. if ${KNOWN:M${t}} +diff: diff-${t} +diff-${t}: + -/usr/bin/diff -ruN -x Makefile -x Makefile.depend \ + ${LOCALESRCDIR}/${t} ${t} +. endif +.endfor + +install: +.for t in ${TYPES} +. if ${KNOWN:M${t}} install: install-${t} install-${t}: -. if ${KNOWN:M${t}} - rm -rf ${.CURDIR}/${t}.draft - rm -f ${.CURDIR}/../../../share/${t}/Makefile - rm -f ${.CURDIR}/../../../share/${t}/*.src - mv ${.CURDIR}/${t}/* ${.CURDIR}/../../../share/${t}/ + cd ${LOCALESRCDIR}/${t} && \ + rm -f Makefile *.src && \ + install -c ${t}/* ${LOCALESRCDIR}/${t} . endif .endfor post-install: .for t in ${TYPES} . if ${KNOWN:M${t}} - (cd ${.CURDIR}/../../../share/${t} && \ - make && make install && make clean) + cd ${LOCALSRCDIR}/${t} && \ + make && make install && make clean . endif .endfor .for t in ${TYPES} -gen-${t}: - mkdir -p ${t} ${t}.draft - perl -I tools tools/cldr2def.pl \ - --unidir=$$(realpath ${UNIDIR}) \ - --etc=$$(realpath ${ETCDIR}) \ +CLEANDIRS+= ${t} ${t}.draft +${t}: + mkdir -p ${t} ${t}.draft && \ + perl -I ${TOOLSDIR} ${TOOLSDIR}/cldr2def.pl \ + --unidir=${UNIDIR:tA} \ + --etc=${ETCDIR:tA} \ --type=${t} -build-${t}: gen-${t} - env ${PASSON} tools/finalize ${t} +build-${t}: ${t} + ${SETENV} OUTBASEDIR="${.OBJDIR}/${t}" ${TOOLSDIR}/finalize ${t} .endfor -gen-ctypedef: ctype-rollup -static-colldef: gen-colldef +static-colldef: colldef build-colldef: static-colldef static-colldef: .for area enc in ${COLLATION_SPECIAL} - awk -f tools/extract-colldef.awk ${UNIDIR}/posix/${area}.${enc}.src > \ - colldef.draft/${area}.${enc}.src -.endfor - -ctype-rollup: - perl -I tools tools/utf8-rollup.pl --unidir=$$(realpath ${UNIDIR}) - -clean: -.for t in ${TYPES} - rm -rf ${t} ${t}.draft +colldef.draft/${area}.${enc}.src: posix/${area}.${enc}.src + awk -f ${TOOLSDIR}/extract-colldef.awk \ + ${.ALLSRC} > ${.TARGET} || (rm -f ${.TARGET} && false) .endfor BASE_LOCALES_OF_INTEREST?= \ @@ -145,31 +170,71 @@ ENCODINGS= Big5 \ US-ASCII \ UTF-8 -POSIX: posixsrc posixcol posixcm -.if !exists(${UNIDIR}/tools/java/cldr.jar) -.error check README about building cldr.jar +# CLDR files +CLDRFILES_CORE= https://unicode.org/Public/cldr/35/core.zip +CLDRFILES_KEY= https://unicode.org/Public/cldr/35/keyboards.zip +CLDRFILES_TOOLS=https://unicode.org/Public/cldr/35/tools.zip +CLDRFILES_UCD= http://www.unicode.org/Public/zipped/latest/UCD.zip + +# fetch and extract targets +${UNIDIR}: + mkdir -p ${UNIDIR} +.for N in CORE KEY TOOLS UCD +${CLDRFILES_${N}:T}: + fetch ${CLDRFILES_${N}} +fetch: ${CLDRFILES_${N}:T} +extract-${CLDRFILES_${N}:T}:: ${CLDRFILES_${N}:T} ${UNIDIR} + cd ${UNIDIR} && unzip -o ../${CLDRFILES_${N}:T} +extract: extract-${CLDRFILES_${N}:T} +.endfor +patch:: +.if exists(${PATCHDIR}) + cd ${UNIDIR} && cat ${PATCHDIR}/patch-* | patch .endif + +.if !exists(${UNIDIR}/tools/java/cldr.jar) +.ORDER: extract patch +build-tools: extract patch tools-test ${UNIDIR} + cd ${UNIDIR}/tools/java && ${SETENV} ant all jar +.else +build-tools: + @echo cldr.jar is ready. +.endif + +JAVA_CLDR= java -DCLDR_DIR=${UNIDIR:Q} -jar ${UNIDIR}/tools/java/cldr.jar + +posix: posixcm post-posixcm posixsrc posixcol +.ORDER: posixcm post-posixcm posixsrc posixcol +${UNIDIR}/posix: + ln -s -f ../posix ${.TARGET} +clean-posix: + rm -rf posix ${UNIDIR}/posix +post-posixcm: ${UNIDIR}/posix + perl -I ${TOOLSDIR} ${TOOLSDIR}/utf8-rollup.pl \ + --unidir=${UNIDIR} +.for enc in ${ENCODINGS} +posixcm: build-tools posix/${enc}.cm +.ORDER: build-tools posix/${enc}.cm +posix/${enc}.cm: + mkdir -p posix && \ + ${JAVA_CLDR} org.unicode.cldr.posix.GenerateCharmap \ + -d posix -c ${enc} +.endfor .for area in ${BASE_LOCALES_OF_INTEREST} -posixsrc: ${UNIDIR}/posix/${area}.UTF-8.src -${UNIDIR}/posix/${area}.UTF-8.src: - java -DCLDR_DIR=${UNIDIR:Q} -jar ${UNIDIR}/tools/java/cldr.jar \ - org.unicode.cldr.posix.GeneratePOSIX \ - -d ${UNIDIR}/posix -m ${area} -c UTF-8 +posixsrc: build-tools posix/${area}.UTF-8.src +.ORDER: build-tools posix/${area}.UTF-8.src +posix/${area}.UTF-8.src: + mkdir -p posix && \ + ${JAVA_CLDR} org.unicode.cldr.posix.GeneratePOSIX \ + -d posix -m ${area} -c UTF-8 .endfor .for area encoding in ${COLLATION_SPECIAL} -posixcol: ${UNIDIR}/posix/${area}.${encoding}.src -${UNIDIR}/posix/${area}.${encoding}.src: - java -DCLDR_DIR=${UNIDIR:Q} -jar ${UNIDIR}/tools/java/cldr.jar \ - org.unicode.cldr.posix.GeneratePOSIX \ - -d ${UNIDIR}/posix -m ${area} -c ${encoding} -.endfor -.for enc in ${ENCODINGS} -posixcm: ${UNIDIR}/posix/${enc}.cm -${UNIDIR}/posix/${enc}.cm: - java -DCLDR_DIR=${UNIDIR:Q} -jar ${UNIDIR}/tools/java/cldr.jar \ - org.unicode.cldr.posix.GenerateCharmap \ - -d ${UNIDIR}/posix -c ${enc} +posixcol: build-tools posix/${area}.${encoding}.src +.ORDER: build-tools posix/${area}.${encoding}.src +posix/${area}.${encoding}.src: + mkdir -p posix && \ + ${JAVA_CLDR} org.unicode.cldr.posix.GeneratePOSIX \ + -d posix -m ${area} -c ${encoding} .endfor -clean-POSIX: - rm -f ${UNIDIR}/posix/* +.include diff --git a/tools/tools/locale/README b/tools/tools/locale/README index 60357d4d8dfe..8dc8c2a25fc1 100644 --- a/tools/tools/locale/README +++ b/tools/tools/locale/README @@ -1,32 +1,58 @@ # $FreeBSD$ -To generate the locales: +Files in this directory are used to generate locale source files +from files in CLDR (Unicode Common Locale Data Repository). -Tools needed: - java (openjdk >= 8) - perl - converters/p5-Text-Iconv - devel/apache-ant - devel/p5-Tie-IxHash - textproc/p5-XML-Parser +To generate the files, do the following: -1. Fetch CLDR data from: http://unicode.org/Public/cldr/. You need all of the -core.zip, keyboards.zip, and tools.zip. -2. Fetch unidata (UCD.zip) from http://www.unicode.org/Public/zipped/latest. -3. Extract: - mkdir -p ~/unicode - cd ~/unicode - unzip ~/core.zip - unzip ~/keyboards.zip - unzip ~/tools.zip - unzip ~/UCD.zip -4. Export variable: - UNIDIR=~/unicode; export UNIDIR -5. Build the CLDR tools: - cd $UNIDIR/tools/java - ant jar -6. Build POSIX data files from CLDR data: - make POSIX -7. Build and install new locale data: - make + cd /usr/src/tools/tools/locale + make obj (mandatory) + make -j16 (-jN recommended) + make diff (check if the changes are reasonable) make install + +"make" downloads the necessary files, build them, and install the +results into /usr/src/share/* as source files for locales. + +More details are as follows: + +Variables: + LOCALESRCDIR + Destination path for the generated locale files. + Default: $DESTDIR/usr/src/share. + TMPDIR + Temporary directory. + Default: /tmp + +Targets: + make obj + Create a temporary directory for building. + + make clean + Clean up the obj directories. + + make cleandir + Remove the obj directories completely. + + make tools-test + Check if necessary tools are installed or not. + If something is missing, install them. + + make fetch + Download necessary files from CLDR. + + make build-tools + Build a tool to generate locale source files. + + make posix + Build POSIX locale source files. + + make build + Build locale files. + + make diff + Run diff(1) the build results against $LOCALESRCDIR. + + make install + Install the build results into $LOCALESRCDIR. +[EOF] diff --git a/tools/tools/locale/etc/final-maps/map.UTF-8 b/tools/tools/locale/etc/final-maps/map.UTF-8 index 031b8545982d..ad0dfd2c7de6 100644 --- a/tools/tools/locale/etc/final-maps/map.UTF-8 +++ b/tools/tools/locale/etc/final-maps/map.UTF-8 @@ -2969,6 +2969,7 @@ CHARMAP \xE0\xB1\xAD \xE0\xB1\xAE \xE0\xB1\xAF + \xE0\xB1\xB7 \xE0\xB1\xB8 \xE0\xB1\xB9 \xE0\xB1\xBA @@ -3363,14 +3364,24 @@ CHARMAP \xE0\xBA\x81 \xE0\xBA\x82 \xE0\xBA\x84 + \xE0\xBA\x86 \xE0\xBA\x87 \xE0\xBA\x88 + \xE0\xBA\x89 \xE0\xBA\x8A + \xE0\xBA\x8C \xE0\xBA\x8D + \xE0\xBA\x8E + \xE0\xBA\x8F + \xE0\xBA\x90 + \xE0\xBA\x91 + \xE0\xBA\x92 + \xE0\xBA\x93 \xE0\xBA\x94 \xE0\xBA\x95 \xE0\xBA\x96 \xE0\xBA\x97 + \xE0\xBA\x98 \xE0\xBA\x99 \xE0\xBA\x9A \xE0\xBA\x9B @@ -3378,13 +3389,17 @@ CHARMAP \xE0\xBA\x9D \xE0\xBA\x9E \xE0\xBA\x9F + \xE0\xBA\xA0 \xE0\xBA\xA1 \xE0\xBA\xA2 \xE0\xBA\xA3 \xE0\xBA\xA5 \xE0\xBA\xA7 + \xE0\xBA\xA8 + \xE0\xBA\xA9 \xE0\xBA\xAA \xE0\xBA\xAB + \xE0\xBA\xAC \xE0\xBA\xAD \xE0\xBA\xAE \xE0\xBA\xAF @@ -3398,6 +3413,7 @@ CHARMAP \xE0\xBA\xB7 \xE0\xBA\xB8 \xE0\xBA\xB9 + \xE0\xBA\xBA \xE0\xBA\xBB \xE0\xBA\xBC \xE0\xBA\xBD @@ -6656,6 +6672,7 @@ CHARMAP \xE1\xB3\xB7 \xE1\xB3\xB8 \xE1\xB3\xB9 + \xE1\xB3\xBA \xE1\xB4\x80 \xE1\xB4\x81 \xE1\xB4\x82 @@ -10325,6 +10342,7 @@ CHARMAP \xE2\xAF\x86 \xE2\xAF\x87 \xE2\xAF\x88 + \xE2\xAF\x89 \xE2\xAF\x8A \xE2\xAF\x8B \xE2\xAF\x8C @@ -10378,6 +10396,7 @@ CHARMAP \xE2\xAF\xBC \xE2\xAF\xBD \xE2\xAF\xBE + \xE2\xAF\xBF \xE2\xB0\x80 \xE2\xB0\x81 \xE2\xB0\x82 @@ -10916,6 +10935,7 @@ CHARMAP \xE2\xB9\x8C \xE2\xB9\x8D \xE2\xB9\x8E + \xE2\xB9\x8F \xE2\xBA\x80 \xE2\xBA\x81 \xE2\xBA\x82 @@ -41812,6 +41832,17 @@ CHARMAP \xEA\x9E\xB7 \xEA\x9E\xB8 \xEA\x9E\xB9 + \xEA\x9E\xBA + \xEA\x9E\xBB + \xEA\x9E\xBC + \xEA\x9E\xBD + \xEA\x9E\xBE + \xEA\x9E\xBF + \xEA\x9F\x82 + \xEA\x9F\x83 + \xEA\x9F\x84 + \xEA\x9F\x85 + \xEA\x9F\x86 \xEA\x9F\xB7 \xEA\x9F\xB8 \xEA\x9F\xB9 @@ -42577,6 +42608,8 @@ CHARMAP \xEA\xAD\xA3 \xEA\xAD\xA4 \xEA\xAD\xA5 + \xEA\xAD\xA6 + \xEA\xAD\xA7 \xEA\xAD\xB0 \xEA\xAD\xB1 \xEA\xAD\xB2 @@ -64381,6 +64414,29 @@ CHARMAP \xF0\x90\xBD\x97 \xF0\x90\xBD\x98 \xF0\x90\xBD\x99 + \xF0\x90\xBF\xA0 + \xF0\x90\xBF\xA1 + \xF0\x90\xBF\xA2 + \xF0\x90\xBF\xA3 + \xF0\x90\xBF\xA4 + \xF0\x90\xBF\xA5 + \xF0\x90\xBF\xA6 + \xF0\x90\xBF\xA7 + \xF0\x90\xBF\xA8 + \xF0\x90\xBF\xA9 + \xF0\x90\xBF\xAA + \xF0\x90\xBF\xAB + \xF0\x90\xBF\xAC + \xF0\x90\xBF\xAD + \xF0\x90\xBF\xAE + \xF0\x90\xBF\xAF + \xF0\x90\xBF\xB0 + \xF0\x90\xBF\xB1 + \xF0\x90\xBF\xB2 + \xF0\x90\xBF\xB3 + \xF0\x90\xBF\xB4 + \xF0\x90\xBF\xB5 + \xF0\x90\xBF\xB6 \xF0\x91\x80\x80 \xF0\x91\x80\x81 \xF0\x91\x80\x82 @@ -65163,6 +65219,7 @@ CHARMAP \xF0\x91\x91\x9B \xF0\x91\x91\x9D \xF0\x91\x91\x9E + \xF0\x91\x91\x9F \xF0\x91\x92\x80 \xF0\x91\x92\x81 \xF0\x91\x92\x82 @@ -65485,6 +65542,7 @@ CHARMAP \xF0\x91\x9A\xB5 \xF0\x91\x9A\xB6 \xF0\x91\x9A\xB7 + \xF0\x91\x9A\xB8 \xF0\x91\x9B\x80 \xF0\x91\x9B\x81 \xF0\x91\x9B\x82 @@ -65697,6 +65755,71 @@ CHARMAP \xF0\x91\xA3\xB1 \xF0\x91\xA3\xB2 \xF0\x91\xA3\xBF + \xF0\x91\xA6\xA0 + \xF0\x91\xA6\xA1 + \xF0\x91\xA6\xA2 + \xF0\x91\xA6\xA3 + \xF0\x91\xA6\xA4 + \xF0\x91\xA6\xA5 + \xF0\x91\xA6\xA6 + \xF0\x91\xA6\xA7 + \xF0\x91\xA6\xAA + \xF0\x91\xA6\xAB + \xF0\x91\xA6\xAC + \xF0\x91\xA6\xAD + \xF0\x91\xA6\xAE + \xF0\x91\xA6\xAF + \xF0\x91\xA6\xB0 + \xF0\x91\xA6\xB1 + \xF0\x91\xA6\xB2 + \xF0\x91\xA6\xB3 + \xF0\x91\xA6\xB4 + \xF0\x91\xA6\xB5 + \xF0\x91\xA6\xB6 + \xF0\x91\xA6\xB7 + \xF0\x91\xA6\xB8 + \xF0\x91\xA6\xB9 + \xF0\x91\xA6\xBA + \xF0\x91\xA6\xBB + \xF0\x91\xA6\xBC + \xF0\x91\xA6\xBD + \xF0\x91\xA6\xBE + \xF0\x91\xA6\xBF + \xF0\x91\xA7\x80 + \xF0\x91\xA7\x81 + \xF0\x91\xA7\x82 + \xF0\x91\xA7\x83 + \xF0\x91\xA7\x84 + \xF0\x91\xA7\x85 + \xF0\x91\xA7\x86 + \xF0\x91\xA7\x87 + \xF0\x91\xA7\x88 + \xF0\x91\xA7\x89 + \xF0\x91\xA7\x8A + \xF0\x91\xA7\x8B + \xF0\x91\xA7\x8C + \xF0\x91\xA7\x8D + \xF0\x91\xA7\x8E + \xF0\x91\xA7\x8F + \xF0\x91\xA7\x90 + \xF0\x91\xA7\x91 + \xF0\x91\xA7\x92 + \xF0\x91\xA7\x93 + \xF0\x91\xA7\x94 + \xF0\x91\xA7\x95 + \xF0\x91\xA7\x96 + \xF0\x91\xA7\x97 + \xF0\x91\xA7\x9A + \xF0\x91\xA7\x9B + \xF0\x91\xA7\x9C + \xF0\x91\xA7\x9D + \xF0\x91\xA7\x9E + \xF0\x91\xA7\x9F + \xF0\x91\xA7\xA0 + \xF0\x91\xA7\xA1 + \xF0\x91\xA7\xA2 + \xF0\x91\xA7\xA3 + \xF0\x91\xA7\xA4 \xF0\x91\xA8\x80 \xF0\x91\xA8\x81 \xF0\x91\xA8\x82 @@ -65821,6 +65944,8 @@ CHARMAP \xF0\x91\xAA\x81 \xF0\x91\xAA\x82 \xF0\x91\xAA\x83 + \xF0\x91\xAA\x84 + \xF0\x91\xAA\x85 \xF0\x91\xAA\x86 \xF0\x91\xAA\x87 \xF0\x91\xAA\x88 @@ -66235,6 +66360,57 @@ CHARMAP \xF0\x91\xBB\xB6 \xF0\x91\xBB\xB7 \xF0\x91\xBB\xB8 + \xF0\x91\xBF\x80 + \xF0\x91\xBF\x81 + \xF0\x91\xBF\x82 + \xF0\x91\xBF\x83 + \xF0\x91\xBF\x84 + \xF0\x91\xBF\x85 + \xF0\x91\xBF\x86 + \xF0\x91\xBF\x87 + \xF0\x91\xBF\x88 + \xF0\x91\xBF\x89 + \xF0\x91\xBF\x8A + \xF0\x91\xBF\x8B + \xF0\x91\xBF\x8C + \xF0\x91\xBF\x8D + \xF0\x91\xBF\x8E + \xF0\x91\xBF\x8F + \xF0\x91\xBF\x90 + \xF0\x91\xBF\x91 + \xF0\x91\xBF\x92 + \xF0\x91\xBF\x93 + \xF0\x91\xBF\x94 + \xF0\x91\xBF\x95 + \xF0\x91\xBF\x96 + \xF0\x91\xBF\x97 + \xF0\x91\xBF\x98 + \xF0\x91\xBF\x99 + \xF0\x91\xBF\x9A + \xF0\x91\xBF\x9B + \xF0\x91\xBF\x9C + \xF0\x91\xBF\x9D + \xF0\x91\xBF\x9E + \xF0\x91\xBF\x9F + \xF0\x91\xBF\xA0 + \xF0\x91\xBF\xA1 + \xF0\x91\xBF\xA2 + \xF0\x91\xBF\xA3 + \xF0\x91\xBF\xA4 + \xF0\x91\xBF\xA5 + \xF0\x91\xBF\xA6 + \xF0\x91\xBF\xA7 + \xF0\x91\xBF\xA8 + \xF0\x91\xBF\xA9 + \xF0\x91\xBF\xAA + \xF0\x91\xBF\xAB + \xF0\x91\xBF\xAC + \xF0\x91\xBF\xAD + \xF0\x91\xBF\xAE + \xF0\x91\xBF\xAF + \xF0\x91\xBF\xB0 + \xF0\x91\xBF\xB1 + \xF0\x91\xBF\xBF \xF0\x92\x80\x80 \xF0\x92\x80\x81 \xF0\x92\x80\x82 @@ -68540,6 +68716,15 @@ CHARMAP \xF0\x93\x90\xAC \xF0\x93\x90\xAD \xF0\x93\x90\xAE + \xF0\x93\x90\xB0 + \xF0\x93\x90\xB1 + \xF0\x93\x90\xB2 + \xF0\x93\x90\xB3 + \xF0\x93\x90\xB4 + \xF0\x93\x90\xB5 + \xF0\x93\x90\xB6 + \xF0\x93\x90\xB7 + \xF0\x93\x90\xB8 \xF0\x94\x90\x80 \xF0\x94\x90\x81 \xF0\x94\x90\x82 @@ -70058,6 +70243,13 @@ CHARMAP \xF0\x96\xBD\x82 \xF0\x96\xBD\x83 \xF0\x96\xBD\x84 + \xF0\x96\xBD\x85 + \xF0\x96\xBD\x86 + \xF0\x96\xBD\x87 + \xF0\x96\xBD\x88 + \xF0\x96\xBD\x89 + \xF0\x96\xBD\x8A + \xF0\x96\xBD\x8F \xF0\x96\xBD\x90 \xF0\x96\xBD\x91 \xF0\x96\xBD\x92 @@ -70105,6 +70297,15 @@ CHARMAP \xF0\x96\xBD\xBC \xF0\x96\xBD\xBD \xF0\x96\xBD\xBE + \xF0\x96\xBD\xBF + \xF0\x96\xBE\x80 + \xF0\x96\xBE\x81 + \xF0\x96\xBE\x82 + \xF0\x96\xBE\x83 + \xF0\x96\xBE\x84 + \xF0\x96\xBE\x85 + \xF0\x96\xBE\x86 + \xF0\x96\xBE\x87 \xF0\x96\xBE\x8F \xF0\x96\xBE\x90 \xF0\x96\xBE\x91 @@ -70124,6 +70325,8 @@ CHARMAP \xF0\x96\xBE\x9F \xF0\x96\xBF\xA0 \xF0\x96\xBF\xA1 + \xF0\x96\xBF\xA2 + \xF0\x96\xBF\xA3 \xF0\x97\x80\x80 \xF0\x97\x80\x81 \xF0\x97\x80\x82 @@ -76254,6 +76457,12 @@ CHARMAP \xF0\x98\x9F\xAF \xF0\x98\x9F\xB0 \xF0\x98\x9F\xB1 + \xF0\x98\x9F\xB2 + \xF0\x98\x9F\xB3 + \xF0\x98\x9F\xB4 + \xF0\x98\x9F\xB5 + \xF0\x98\x9F\xB6 + \xF0\x98\x9F\xB7 \xF0\x98\xA0\x80 \xF0\x98\xA0\x81 \xF0\x98\xA0\x82 @@ -77296,6 +77505,13 @@ CHARMAP \xF0\x9B\x84\x9C \xF0\x9B\x84\x9D \xF0\x9B\x84\x9E + \xF0\x9B\x85\x90 + \xF0\x9B\x85\x91 + \xF0\x9B\x85\x92 + \xF0\x9B\x85\xA4 + \xF0\x9B\x85\xA5 + \xF0\x9B\x85\xA6 + \xF0\x9B\x85\xA7 \xF0\x9B\x85\xB0 \xF0\x9B\x85\xB1 \xF0\x9B\x85\xB2 @@ -80224,6 +80440,136 @@ CHARMAP \xF0\x9E\x80\xA8 \xF0\x9E\x80\xA9 \xF0\x9E\x80\xAA + \xF0\x9E\x84\x80 + \xF0\x9E\x84\x81 + \xF0\x9E\x84\x82 + \xF0\x9E\x84\x83 + \xF0\x9E\x84\x84 + \xF0\x9E\x84\x85 + \xF0\x9E\x84\x86 + \xF0\x9E\x84\x87 + \xF0\x9E\x84\x88 + \xF0\x9E\x84\x89 + \xF0\x9E\x84\x8A + \xF0\x9E\x84\x8B + \xF0\x9E\x84\x8C + \xF0\x9E\x84\x8D + \xF0\x9E\x84\x8E + \xF0\x9E\x84\x8F + \xF0\x9E\x84\x90 + \xF0\x9E\x84\x91 + \xF0\x9E\x84\x92 + \xF0\x9E\x84\x93 + \xF0\x9E\x84\x94 + \xF0\x9E\x84\x95 + \xF0\x9E\x84\x96 + \xF0\x9E\x84\x97 + \xF0\x9E\x84\x98 + \xF0\x9E\x84\x99 + \xF0\x9E\x84\x9A + \xF0\x9E\x84\x9B + \xF0\x9E\x84\x9C + \xF0\x9E\x84\x9D + \xF0\x9E\x84\x9E + \xF0\x9E\x84\x9F + \xF0\x9E\x84\xA0 + \xF0\x9E\x84\xA1 + \xF0\x9E\x84\xA2 + \xF0\x9E\x84\xA3 + \xF0\x9E\x84\xA4 + \xF0\x9E\x84\xA5 + \xF0\x9E\x84\xA6 + \xF0\x9E\x84\xA7 + \xF0\x9E\x84\xA8 + \xF0\x9E\x84\xA9 + \xF0\x9E\x84\xAA + \xF0\x9E\x84\xAB + \xF0\x9E\x84\xAC + \xF0\x9E\x84\xB0 + \xF0\x9E\x84\xB1 + \xF0\x9E\x84\xB2 + \xF0\x9E\x84\xB3 + \xF0\x9E\x84\xB4 + \xF0\x9E\x84\xB5 + \xF0\x9E\x84\xB6 + \xF0\x9E\x84\xB7 + \xF0\x9E\x84\xB8 + \xF0\x9E\x84\xB9 + \xF0\x9E\x84\xBA + \xF0\x9E\x84\xBB + \xF0\x9E\x84\xBC + \xF0\x9E\x84\xBD + \xF0\x9E\x85\x80 + \xF0\x9E\x85\x81 + \xF0\x9E\x85\x82 + \xF0\x9E\x85\x83 + \xF0\x9E\x85\x84 + \xF0\x9E\x85\x85 + \xF0\x9E\x85\x86 + \xF0\x9E\x85\x87 + \xF0\x9E\x85\x88 + \xF0\x9E\x85\x89 + \xF0\x9E\x85\x8E + \xF0\x9E\x85\x8F + \xF0\x9E\x8B\x80 + \xF0\x9E\x8B\x81 + \xF0\x9E\x8B\x82 + \xF0\x9E\x8B\x83 + \xF0\x9E\x8B\x84 + \xF0\x9E\x8B\x85 + \xF0\x9E\x8B\x86 + \xF0\x9E\x8B\x87 + \xF0\x9E\x8B\x88 + \xF0\x9E\x8B\x89 + \xF0\x9E\x8B\x8A + \xF0\x9E\x8B\x8B + \xF0\x9E\x8B\x8C + \xF0\x9E\x8B\x8D + \xF0\x9E\x8B\x8E + \xF0\x9E\x8B\x8F + \xF0\x9E\x8B\x90 + \xF0\x9E\x8B\x91 + \xF0\x9E\x8B\x92 + \xF0\x9E\x8B\x93 + \xF0\x9E\x8B\x94 + \xF0\x9E\x8B\x95 + \xF0\x9E\x8B\x96 + \xF0\x9E\x8B\x97 + \xF0\x9E\x8B\x98 + \xF0\x9E\x8B\x99 + \xF0\x9E\x8B\x9A + \xF0\x9E\x8B\x9B + \xF0\x9E\x8B\x9C + \xF0\x9E\x8B\x9D + \xF0\x9E\x8B\x9E + \xF0\x9E\x8B\x9F + \xF0\x9E\x8B\xA0 + \xF0\x9E\x8B\xA1 + \xF0\x9E\x8B\xA2 + \xF0\x9E\x8B\xA3 + \xF0\x9E\x8B\xA4 + \xF0\x9E\x8B\xA5 + \xF0\x9E\x8B\xA6 + \xF0\x9E\x8B\xA7 + \xF0\x9E\x8B\xA8 + \xF0\x9E\x8B\xA9 + \xF0\x9E\x8B\xAA + \xF0\x9E\x8B\xAB + \xF0\x9E\x8B\xAC + \xF0\x9E\x8B\xAD + \xF0\x9E\x8B\xAE + \xF0\x9E\x8B\xAF + \xF0\x9E\x8B\xB0 + \xF0\x9E\x8B\xB1 + \xF0\x9E\x8B\xB2 + \xF0\x9E\x8B\xB3 + \xF0\x9E\x8B\xB4 + \xF0\x9E\x8B\xB5 + \xF0\x9E\x8B\xB6 + \xF0\x9E\x8B\xB7 + \xF0\x9E\x8B\xB8 + \xF0\x9E\x8B\xB9 + \xF0\x9E\x8B\xBF \xF0\x9E\xA0\x80 \xF0\x9E\xA0\x81 \xF0\x9E\xA0\x82 @@ -80512,6 +80858,7 @@ CHARMAP \xF0\x9E\xA5\x88 \xF0\x9E\xA5\x89 \xF0\x9E\xA5\x8A + \xF0\x9E\xA5\x8B \xF0\x9E\xA5\x90 \xF0\x9E\xA5\x91 \xF0\x9E\xA5\x92 @@ -80592,6 +80939,67 @@ CHARMAP \xF0\x9E\xB2\xB2 \xF0\x9E\xB2\xB3 \xF0\x9E\xB2\xB4 + \xF0\x9E\xB4\x81 + \xF0\x9E\xB4\x82 + \xF0\x9E\xB4\x83 + \xF0\x9E\xB4\x84 + \xF0\x9E\xB4\x85 + \xF0\x9E\xB4\x86 + \xF0\x9E\xB4\x87 + \xF0\x9E\xB4\x88 + \xF0\x9E\xB4\x89 + \xF0\x9E\xB4\x8A + \xF0\x9E\xB4\x8B + \xF0\x9E\xB4\x8C + \xF0\x9E\xB4\x8D + \xF0\x9E\xB4\x8E + \xF0\x9E\xB4\x8F + \xF0\x9E\xB4\x90 + \xF0\x9E\xB4\x91 + \xF0\x9E\xB4\x92 + \xF0\x9E\xB4\x93 + \xF0\x9E\xB4\x94 + \xF0\x9E\xB4\x95 + \xF0\x9E\xB4\x96 + \xF0\x9E\xB4\x97 + \xF0\x9E\xB4\x98 + \xF0\x9E\xB4\x99 + \xF0\x9E\xB4\x9A + \xF0\x9E\xB4\x9B + \xF0\x9E\xB4\x9C + \xF0\x9E\xB4\x9D + \xF0\x9E\xB4\x9E + \xF0\x9E\xB4\x9F + \xF0\x9E\xB4\xA0 + \xF0\x9E\xB4\xA1 + \xF0\x9E\xB4\xA2 + \xF0\x9E\xB4\xA3 + \xF0\x9E\xB4\xA4 + \xF0\x9E\xB4\xA5 + \xF0\x9E\xB4\xA6 + \xF0\x9E\xB4\xA7 + \xF0\x9E\xB4\xA8 + \xF0\x9E\xB4\xA9 + \xF0\x9E\xB4\xAA + \xF0\x9E\xB4\xAB + \xF0\x9E\xB4\xAC + \xF0\x9E\xB4\xAD + \xF0\x9E\xB4\xAE + \xF0\x9E\xB4\xAF + \xF0\x9E\xB4\xB0 + \xF0\x9E\xB4\xB1 + \xF0\x9E\xB4\xB2 + \xF0\x9E\xB4\xB3 + \xF0\x9E\xB4\xB4 + \xF0\x9E\xB4\xB5 + \xF0\x9E\xB4\xB6 + \xF0\x9E\xB4\xB7 + \xF0\x9E\xB4\xB8 + \xF0\x9E\xB4\xB9 + \xF0\x9E\xB4\xBA + \xF0\x9E\xB4\xBB + \xF0\x9E\xB4\xBC + \xF0\x9E\xB4\xBD \xF0\x9E\xB8\x80 \xF0\x9E\xB8\x81 \xF0\x9E\xB8\x82 @@ -81066,6 +81474,7 @@ CHARMAP \xF0\x9F\x85\xA9 \xF0\x9F\x85\xAA \xF0\x9F\x85\xAB + \xF0\x9F\x85\xAC \xF0\x9F\x85\xB0 \xF0\x9F\x85\xB1 \xF0\x9F\x85\xB2 @@ -82198,6 +82607,7 @@ CHARMAP \xF0\x9F\x9B\x92 \xF0\x9F\x9B\x93 \xF0\x9F\x9B\x94 + \xF0\x9F\x9B\x95 \xF0\x9F\x9B\xA0 \xF0\x9F\x9B\xA1 \xF0\x9F\x9B\xA2 @@ -82221,6 +82631,7 @@ CHARMAP \xF0\x9F\x9B\xB7 \xF0\x9F\x9B\xB8 \xF0\x9F\x9B\xB9 + \xF0\x9F\x9B\xBA \xF0\x9F\x9C\x80 \xF0\x9F\x9C\x81 \xF0\x9F\x9C\x82 @@ -82426,6 +82837,18 @@ CHARMAP \xF0\x9F\x9F\x96 \xF0\x9F\x9F\x97 \xF0\x9F\x9F\x98 + \xF0\x9F\x9F\xA0 + \xF0\x9F\x9F\xA1 + \xF0\x9F\x9F\xA2 + \xF0\x9F\x9F\xA3 + \xF0\x9F\x9F\xA4 + \xF0\x9F\x9F\xA5 + \xF0\x9F\x9F\xA6 + \xF0\x9F\x9F\xA7 + \xF0\x9F\x9F\xA8 + \xF0\x9F\x9F\xA9 + \xF0\x9F\x9F\xAA + \xF0\x9F\x9F\xAB \xF0\x9F\xA0\x80 \xF0\x9F\xA0\x81 \xF0\x9F\xA0\x82 @@ -82586,6 +83009,9 @@ CHARMAP \xF0\x9F\xA4\x89 \xF0\x9F\xA4\x8A \xF0\x9F\xA4\x8B + \xF0\x9F\xA4\x8D + \xF0\x9F\xA4\x8E + \xF0\x9F\xA4\x8F \xF0\x9F\xA4\x90 \xF0\x9F\xA4\x91 \xF0\x9F\xA4\x92 @@ -82633,6 +83059,7 @@ CHARMAP \xF0\x9F\xA4\xBC \xF0\x9F\xA4\xBD \xF0\x9F\xA4\xBE + \xF0\x9F\xA4\xBF \xF0\x9F\xA5\x80 \xF0\x9F\xA5\x81 \xF0\x9F\xA5\x82 @@ -82682,11 +83109,13 @@ CHARMAP \xF0\x9F\xA5\xAE \xF0\x9F\xA5\xAF \xF0\x9F\xA5\xB0 + \xF0\x9F\xA5\xB1 \xF0\x9F\xA5\xB3 \xF0\x9F\xA5\xB4 \xF0\x9F\xA5\xB5 \xF0\x9F\xA5\xB6 \xF0\x9F\xA5\xBA + \xF0\x9F\xA5\xBB \xF0\x9F\xA5\xBC \xF0\x9F\xA5\xBD \xF0\x9F\xA5\xBE @@ -82726,6 +83155,14 @@ CHARMAP \xF0\x9F\xA6\xA0 \xF0\x9F\xA6\xA1 \xF0\x9F\xA6\xA2 + \xF0\x9F\xA6\xA5 + \xF0\x9F\xA6\xA6 + \xF0\x9F\xA6\xA7 + \xF0\x9F\xA6\xA8 + \xF0\x9F\xA6\xA9 + \xF0\x9F\xA6\xAA + \xF0\x9F\xA6\xAE + \xF0\x9F\xA6\xAF \xF0\x9F\xA6\xB0 \xF0\x9F\xA6\xB1 \xF0\x9F\xA6\xB2 @@ -82736,9 +83173,26 @@ CHARMAP \xF0\x9F\xA6\xB7 \xF0\x9F\xA6\xB8 \xF0\x9F\xA6\xB9 + \xF0\x9F\xA6\xBA + \xF0\x9F\xA6\xBB + \xF0\x9F\xA6\xBC + \xF0\x9F\xA6\xBD + \xF0\x9F\xA6\xBE + \xF0\x9F\xA6\xBF \xF0\x9F\xA7\x80 \xF0\x9F\xA7\x81 \xF0\x9F\xA7\x82 + \xF0\x9F\xA7\x83 + \xF0\x9F\xA7\x84 + \xF0\x9F\xA7\x85 + \xF0\x9F\xA7\x86 + \xF0\x9F\xA7\x87 + \xF0\x9F\xA7\x88 + \xF0\x9F\xA7\x89 + \xF0\x9F\xA7\x8A + \xF0\x9F\xA7\x8D + \xF0\x9F\xA7\x8E + \xF0\x9F\xA7\x8F \xF0\x9F\xA7\x90 \xF0\x9F\xA7\x91 \xF0\x9F\xA7\x92 @@ -82787,6 +83241,90 @@ CHARMAP \xF0\x9F\xA7\xBD \xF0\x9F\xA7\xBE \xF0\x9F\xA7\xBF + \xF0\x9F\xA8\x80 + \xF0\x9F\xA8\x81 + \xF0\x9F\xA8\x82 + \xF0\x9F\xA8\x83 + \xF0\x9F\xA8\x84 + \xF0\x9F\xA8\x85 + \xF0\x9F\xA8\x86 + \xF0\x9F\xA8\x87 + \xF0\x9F\xA8\x88 + \xF0\x9F\xA8\x89 + \xF0\x9F\xA8\x8A + \xF0\x9F\xA8\x8B + \xF0\x9F\xA8\x8C + \xF0\x9F\xA8\x8D + \xF0\x9F\xA8\x8E + \xF0\x9F\xA8\x8F + \xF0\x9F\xA8\x90 + \xF0\x9F\xA8\x91 + \xF0\x9F\xA8\x92 + \xF0\x9F\xA8\x93 + \xF0\x9F\xA8\x94 + \xF0\x9F\xA8\x95 + \xF0\x9F\xA8\x96 + \xF0\x9F\xA8\x97 + \xF0\x9F\xA8\x98 + \xF0\x9F\xA8\x99 + \xF0\x9F\xA8\x9A + \xF0\x9F\xA8\x9B + \xF0\x9F\xA8\x9C + \xF0\x9F\xA8\x9D + \xF0\x9F\xA8\x9E + \xF0\x9F\xA8\x9F + \xF0\x9F\xA8\xA0 + \xF0\x9F\xA8\xA1 + \xF0\x9F\xA8\xA2 + \xF0\x9F\xA8\xA3 + \xF0\x9F\xA8\xA4 + \xF0\x9F\xA8\xA5 + \xF0\x9F\xA8\xA6 + \xF0\x9F\xA8\xA7 + \xF0\x9F\xA8\xA8 + \xF0\x9F\xA8\xA9 + \xF0\x9F\xA8\xAA + \xF0\x9F\xA8\xAB + \xF0\x9F\xA8\xAC + \xF0\x9F\xA8\xAD + \xF0\x9F\xA8\xAE + \xF0\x9F\xA8\xAF + \xF0\x9F\xA8\xB0 + \xF0\x9F\xA8\xB1 + \xF0\x9F\xA8\xB2 + \xF0\x9F\xA8\xB3 + \xF0\x9F\xA8\xB4 + \xF0\x9F\xA8\xB5 + \xF0\x9F\xA8\xB6 + \xF0\x9F\xA8\xB7 + \xF0\x9F\xA8\xB8 + \xF0\x9F\xA8\xB9 + \xF0\x9F\xA8\xBA + \xF0\x9F\xA8\xBB + \xF0\x9F\xA8\xBC + \xF0\x9F\xA8\xBD + \xF0\x9F\xA8\xBE + \xF0\x9F\xA8\xBF + \xF0\x9F\xA9\x80 + \xF0\x9F\xA9\x81 + \xF0\x9F\xA9\x82 + \xF0\x9F\xA9\x83 + \xF0\x9F\xA9\x84 + \xF0\x9F\xA9\x85 + \xF0\x9F\xA9\x86 + \xF0\x9F\xA9\x87 + \xF0\x9F\xA9\x88 + \xF0\x9F\xA9\x89 + \xF0\x9F\xA9\x8A + \xF0\x9F\xA9\x8B + \xF0\x9F\xA9\x8C + \xF0\x9F\xA9\x8D + \xF0\x9F\xA9\x8E + \xF0\x9F\xA9\x8F + \xF0\x9F\xA9\x90 + \xF0\x9F\xA9\x91 + \xF0\x9F\xA9\x92 + \xF0\x9F\xA9\x93 \xF0\x9F\xA9\xA0 \xF0\x9F\xA9\xA1 \xF0\x9F\xA9\xA2 @@ -82801,6 +83339,22 @@ CHARMAP \xF0\x9F\xA9\xAB \xF0\x9F\xA9\xAC \xF0\x9F\xA9\xAD + \xF0\x9F\xA9\xB0 + \xF0\x9F\xA9\xB1 + \xF0\x9F\xA9\xB2 + \xF0\x9F\xA9\xB3 + \xF0\x9F\xA9\xB8 + \xF0\x9F\xA9\xB9 + \xF0\x9F\xA9\xBA + \xF0\x9F\xAA\x80 + \xF0\x9F\xAA\x81 + \xF0\x9F\xAA\x82 + \xF0\x9F\xAA\x90 + \xF0\x9F\xAA\x91 + \xF0\x9F\xAA\x92 + \xF0\x9F\xAA\x93 + \xF0\x9F\xAA\x94 + \xF0\x9F\xAA\x95 \xF0\xA0\x80\x80 \xF0\xA0\x80\x81 \xF0\xA0\x80\x82 diff --git a/tools/tools/locale/patch/patch-UnicodeData.txt b/tools/tools/locale/patch/patch-UnicodeData.txt new file mode 100644 index 000000000000..fe65ebacd16a --- /dev/null +++ b/tools/tools/locale/patch/patch-UnicodeData.txt @@ -0,0 +1,29 @@ +--- UnicodeData.txt.orig 2020-06-29 14:05:49.483379000 +0900 ++++ UnicodeData.txt 2020-06-29 14:12:09.808622000 +0900 +@@ -12138,7 +12138,7 @@ + 33FE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE;So;0;L; 0033 0031 65E5;;;;N;;;;; + 33FF;SQUARE GAL;So;0;ON; 0067 0061 006C;;;;N;;;;; + 3400;;Lo;0;L;;;;;N;;;;; +-4DBF;;Lo;0;L;;;;;N;;;;; ++4DB5;;Lo;0;L;;;;;N;;;;; + 4DC0;HEXAGRAM FOR THE CREATIVE HEAVEN;So;0;ON;;;;;N;;;;; + 4DC1;HEXAGRAM FOR THE RECEPTIVE EARTH;So;0;ON;;;;;N;;;;; + 4DC2;HEXAGRAM FOR DIFFICULTY AT THE BEGINNING;So;0;ON;;;;;N;;;;; +@@ -12204,7 +12204,7 @@ + 4DFE;HEXAGRAM FOR AFTER COMPLETION;So;0;ON;;;;;N;;;;; + 4DFF;HEXAGRAM FOR BEFORE COMPLETION;So;0;ON;;;;;N;;;;; + 4E00;;Lo;0;L;;;;;N;;;;; +-9FFC;;Lo;0;L;;;;;N;;;;; ++9FEF;;Lo;0;L;;;;;N;;;;; + A000;YI SYLLABLE IT;Lo;0;L;;;;;N;;;;; + A001;YI SYLLABLE IX;Lo;0;L;;;;;N;;;;; + A002;YI SYLLABLE I;Lo;0;L;;;;;N;;;;; +@@ -32901,7 +32901,7 @@ + 1FBF8;SEGMENTED DIGIT EIGHT;Nd;0;EN; 0038;8;8;8;N;;;;; + 1FBF9;SEGMENTED DIGIT NINE;Nd;0;EN; 0039;9;9;9;N;;;;; + 20000;;Lo;0;L;;;;;N;;;;; +-2A6DD;;Lo;0;L;;;;;N;;;;; ++2A6D6;;Lo;0;L;;;;;N;;;;; + 2A700;;Lo;0;L;;;;;N;;;;; + 2B734;;Lo;0;L;;;;;N;;;;; + 2B740;;Lo;0;L;;;;;N;;;;; diff --git a/tools/tools/locale/tools/cldr2def.pl b/tools/tools/locale/tools/cldr2def.pl index 3a6f8ac79d18..5f756cc3895a 100755 --- a/tools/tools/locale/tools/cldr2def.pl +++ b/tools/tools/locale/tools/cldr2def.pl @@ -460,6 +460,11 @@ sub transform_ctypes { foreach my $enc (sort keys(%{$languages{$l}{$f}{data}{$c}})) { next if ($enc eq $DEFENCODING); $filename = "$UNIDIR/posix/$file.$DEFENCODING.src"; + if ($file eq 'ja_JP') { + # Override $filename for ja_JP because + # its CTYPE is not compatible with UTF-8. + $filename = "$UNIDIR/posix/$file.eucJP.src"; + } if (! -f $filename) { print STDERR "Cannot open $filename\n"; next; diff --git a/tools/tools/locale/tools/convert_map.pl b/tools/tools/locale/tools/convert_map.pl index 88222531d064..8b54ff33381b 100755 --- a/tools/tools/locale/tools/convert_map.pl +++ b/tools/tools/locale/tools/convert_map.pl @@ -87,7 +87,7 @@ sub load_utf8_cm { my $file = shift; - open(UTF8, "$file") || die "open"; + open(UTF8, "$file") || die "$!: open: $file"; while () { next if (/^#/); @@ -158,7 +158,8 @@ $mf = shift(@ARGV); $codeset = shift(@ARGV); my $max_mb; -load_utf8_cm("etc/final-maps/map.UTF-8"); +my $etcdir = (exists $ENV{'ETCDIR'}) ? $ENV{'ETCDIR'} : "etc"; +load_utf8_cm("${etcdir}/final-maps/map.UTF-8"); load_map($mf); diff --git a/tools/tools/locale/tools/finalize b/tools/tools/locale/tools/finalize index f4dfd7d0892f..88dfcad0cb24 100755 --- a/tools/tools/locale/tools/finalize +++ b/tools/tools/locale/tools/finalize @@ -47,15 +47,21 @@ usage () $1 = "numericdef" -o $1 = "timedef" -o $1 = "ctypedef" ] || usage self=$(realpath $0) -base=$(dirname ${self}) -old=${base}/../${1}.draft -new=${base}/../${1} -TEMP=/tmp/${1}.locales -TEMP2=/tmp/${1}.hashes -TEMP3=/tmp/${1}.symlinks -TEMP4=/tmp/${1}.mapped -FULLMAP=/tmp/utf8-map -FULLEXTRACT=/tmp/extracted-names +base=${BASEDIR:-$(dirname ${self})} +: ${ETCDIR:=${base}/../etc} +: ${TOOLSDIR:=${base}} +: ${OUTBASEDIR:=${base}/../${1}} +: ${OLD_DIR:=${OUTBASEDIR}.draft} +: ${NEW_DIR:=${OUTBASEDIR}} +old=${OLD_DIR} +new=${NEW_DIR} +: ${TMPDIR:=/tmp} +TEMP=${TMPDIR}/${1}.locales +TEMP2=${TMPDIR}/${1}.hashes +TEMP3=${TMPDIR}/${1}.symlinks +TEMP4=${TMPDIR}/${1}.mapped +FULLMAP=${TMPDIR}/utf8-map +FULLEXTRACT=${TMPDIR}/extracted-names AWKCMD="/## PLACEHOLDER/ { \ while ( getline line < \"${TEMP}\" ) {print line} } \ /## SYMPAIRS/ { \ @@ -65,6 +71,7 @@ AWKCMD="/## PLACEHOLDER/ { \ !/## / { print \$0 }" # Rename the sources with 3 components name into the POSIX version of the name using @modifier +mkdir -p $old $new cd $old pwd for i in *_*_*.*.src; do @@ -142,13 +149,13 @@ then rm -f ${TEMP2} /usr/bin/sed -E -e 's/[ ]+/ /g' \ ${UNIDIR}/posix/UTF-8.cm \ - > ${base}/../etc/final-maps/map.UTF-8 + > ${ETCDIR}/final-maps/map.UTF-8 /usr/bin/sed -E -e 's/[ ]+/ /g' \ ${UNIDIR}/posix/eucCN.cm \ - > ${base}/../etc/final-maps/map.eucCN + > ${ETCDIR}/final-maps/map.eucCN /usr/bin/sed -E -e 's/[ ]+/ /g' \ ${UNIDIR}/posix/eucCN.cm \ - > ${base}/../etc/final-maps/map.GB2312 + > ${ETCDIR}/final-maps/map.GB2312 # GB18030 and Big5 are pre-generated from CLDR data CHARMAPS="ARMSCII-8 CP1131 CP1251 \ @@ -160,10 +167,11 @@ then for map in ${CHARMAPS} do encoding=${map} - /usr/local/bin/perl ${base}/convert_map.pl \ - ${base}/../etc/charmaps/${map}.TXT ${encoding} \ + env ETCDIR="${ETCDIR}" \ + /usr/local/bin/perl ${TOOLSDIR}/convert_map.pl \ + ${ETCDIR}/charmaps/${map}.TXT ${encoding} \ | /usr/bin/sed -E -e 's/ +/ /g' \ - > ${base}/../etc/final-maps/map.${map} + > ${ETCDIR}/final-maps/map.${map} echo map ${map} converted. done diff --git a/tools/tools/locale/tools/utf8-rollup.pl b/tools/tools/locale/tools/utf8-rollup.pl index da93d2f4398a..b275828d52c9 100755 --- a/tools/tools/locale/tools/utf8-rollup.pl +++ b/tools/tools/locale/tools/utf8-rollup.pl @@ -30,6 +30,7 @@ use strict; use Getopt::Long; +use Encode qw(encode decode); if ($#ARGV != 0) { print "Usage: $0 --unidir=\n"; @@ -52,6 +53,23 @@ generate_footer (); ############################ +sub utf8to32 { + my @kl = split /\\x/, $_[0]; + + shift @kl if ($kl[0] eq ''); + my $k = pack('H2' x scalar @kl, @kl); + my $ux = encode('UTF-32BE', decode('UTF-8', $k)); + my $u = uc(unpack('H*', $ux)); + # Remove BOM + $u =~ s/^0000FEFF//; + # Remove heading bytes of 0 + while ($u =~ m/^0/ and length($u) > 4) { + $u =~ s/^0//; + } + + return $u; +} + sub get_utf8map { my $file = shift; @@ -75,9 +93,10 @@ sub get_utf8map { last if ($l eq "END CHARMAP"); $l =~ /^(<[^\s]+>)\s+(.*)/; - my $k = $2; + my $k = utf8to32($2); # UTF-8 char code my $v = $1; - $k =~ s/\\x//g; # UTF-8 char code + +# print STDERR "register: $k - $v\n"; $utf8map{$k} = $v; } } @@ -143,7 +162,7 @@ sub parse_unidata { foreach my $l (@lines) { my @d = split(/;/, $l, -1); - my $mb = wctomb($d[0]); + my $mb = $d[0]; my $cat; # XXX There are code points present in UnicodeData.txt @@ -180,9 +199,9 @@ sub parse_unidata { # Check if there's upper/lower mapping if ($d[12] ne "") { - $data{'toupper'}{$mb} = wctomb($d[12]); + $data{'toupper'}{$mb} = $d[12]; } elsif ($d[13] ne "") { - $data{'tolower'}{$mb} = wctomb($d[13]); + $data{'tolower'}{$mb} = $d[13]; } } @@ -193,7 +212,7 @@ sub parse_unidata { foreach my $cat (sort keys (%data)) { print FOUT "$cat\t"; $first = 1; - foreach my $mb (sort keys (%{$data{$cat}})) { + foreach my $mb (sort {hex($a) <=> hex($b)} keys (%{$data{$cat}})) { if ($first == 1) { $first = 0; } elsif ($inrange == 1) { From 04996cb74b187184e2d7b9015bb193e834985044 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Sat, 15 Aug 2020 11:22:07 +0000 Subject: [PATCH 95/96] Enter epoch earlier. This is needed because we are exiting it also in error cases. MFC after: 1 week --- sys/netinet/sctputil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 41c202c0d62f..74e645660096 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -1727,6 +1727,7 @@ sctp_timeout_handler(void *t) stcb = (struct sctp_tcb *)tmr->tcb; net = (struct sctp_nets *)tmr->net; CURVNET_SET((struct vnet *)tmr->vnet); + NET_EPOCH_ENTER(et); did_output = 1; released_asoc_reference = false; @@ -1786,7 +1787,6 @@ sctp_timeout_handler(void *t) /* Record in stopped_from which timeout occurred. */ tmr->stopped_from = type; - NET_EPOCH_ENTER(et); /* mark as being serviced now */ if (SCTP_OS_TIMER_PENDING(&tmr->timer)) { /* From bec053ffe01ddc571fb09d1758708c407c33ddfd Mon Sep 17 00:00:00 2001 From: "Alexander V. Chernikov" Date: Sat, 15 Aug 2020 11:37:44 +0000 Subject: [PATCH 96/96] Make net.inet6.ip6.deembed_scopeid behaviour default & remove sysctl. Submitted by: Neel Chauhan Differential Revision: https://reviews.freebsd.org/D25637 --- sys/net/rtsock.c | 10 +++++----- sys/netinet6/in6.c | 3 +-- sys/netinet6/scope6.c | 4 ---- sys/netinet6/scope6_var.h | 3 --- 4 files changed, 6 insertions(+), 14 deletions(-) diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 8e00c95942ac..0b8edf452c23 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -900,7 +900,7 @@ route_output(struct mbuf *m, struct socket *so, ...) error = lla_rt_output(rtm, &info); #ifdef INET6 if (error == 0) - rti_need_deembed = (V_deembed_scopeid) ? 1 : 0; + rti_need_deembed = 1; #endif goto flush; } @@ -915,7 +915,7 @@ route_output(struct mbuf *m, struct socket *so, ...) error = rib_action(fibnum, rtm->rtm_type, &info, &rc); if (error == 0) { #ifdef INET6 - rti_need_deembed = (V_deembed_scopeid) ? 1 : 0; + rti_need_deembed = 1; #endif rtm->rtm_index = rc.rc_nh_new->nh_ifp->if_index; nh = rc.rc_nh_new; @@ -930,7 +930,7 @@ route_output(struct mbuf *m, struct socket *so, ...) } #ifdef INET6 /* rt_msg2() will not be used when RTM_DELETE fails. */ - rti_need_deembed = (V_deembed_scopeid) ? 1 : 0; + rti_need_deembed = 1; #endif break; @@ -1192,7 +1192,7 @@ rtsock_msg_mbuf(int type, struct rt_addrinfo *rtinfo) rtinfo->rti_addrs |= (1 << i); dlen = SA_SIZE(sa); #ifdef INET6 - if (V_deembed_scopeid && sa->sa_family == AF_INET6) { + if (sa->sa_family == AF_INET6) { sin6 = (struct sockaddr_in6 *)&ss; bcopy(sa, sin6, sizeof(*sin6)); if (sa6_recoverscope(sin6) == 0) @@ -1298,7 +1298,7 @@ rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo, struct walkarg *w, int * dlen = SA_SIZE(sa); if (cp != NULL && buflen >= dlen) { #ifdef INET6 - if (V_deembed_scopeid && sa->sa_family == AF_INET6) { + if (sa->sa_family == AF_INET6) { sin6 = (struct sockaddr_in6 *)&ss; bcopy(sa, sin6, sizeof(*sin6)); if (sa6_recoverscope(sin6) == 0) diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index fb53adb86e82..31cb54aef6a0 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -2374,8 +2374,7 @@ in6_lltable_dump_entry(struct lltable *llt, struct llentry *lle, ndpc.rtm.rtm_type = RTM_GET; ndpc.rtm.rtm_flags = RTF_UP; ndpc.rtm.rtm_addrs = RTA_DST | RTA_GATEWAY; - if (V_deembed_scopeid) - sa6_recoverscope(&ndpc.sin6); + sa6_recoverscope(&ndpc.sin6); /* publish */ if (lle->la_flags & LLE_PUB) diff --git a/sys/netinet6/scope6.c b/sys/netinet6/scope6.c index 42d999be6a8d..f99585dc1789 100644 --- a/sys/netinet6/scope6.c +++ b/sys/netinet6/scope6.c @@ -60,11 +60,7 @@ VNET_DEFINE(int, ip6_use_defzone) = 1; #else VNET_DEFINE(int, ip6_use_defzone) = 0; #endif -VNET_DEFINE(int, deembed_scopeid) = 1; SYSCTL_DECL(_net_inet6_ip6); -SYSCTL_INT(_net_inet6_ip6, OID_AUTO, deembed_scopeid, CTLFLAG_VNET | CTLFLAG_RW, - &VNET_NAME(deembed_scopeid), 0, - "Extract embedded zone ID and set it to sin6_scope_id in sockaddr_in6."); /* * The scope6_lock protects the global sid default stored in diff --git a/sys/netinet6/scope6_var.h b/sys/netinet6/scope6_var.h index cdb2b9572bc2..181e30afe6f8 100644 --- a/sys/netinet6/scope6_var.h +++ b/sys/netinet6/scope6_var.h @@ -47,9 +47,6 @@ struct scope6_id { uint32_t s6id_list[IPV6_ADDR_SCOPES_COUNT]; }; -VNET_DECLARE(int, deembed_scopeid); -#define V_deembed_scopeid VNET(deembed_scopeid) - void scope6_init(void); struct scope6_id *scope6_ifattach(struct ifnet *); void scope6_ifdetach(struct scope6_id *);