Module Name: src Committed By: msaitoh Date: Tue Feb 27 04:58:27 UTC 2018
Modified Files: src/sys/dev/pci/ixgbe: ixv.c Log Message: Add hw.ixvM.q[01].{interrupt_rate,[tr]xd_head,[tr]xd_tail} sysctls as ixg(4). To generate a diff of this commit: cvs rdiff -u -r1.82 -r1.83 src/sys/dev/pci/ixgbe/ixv.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/ixgbe/ixv.c diff -u src/sys/dev/pci/ixgbe/ixv.c:1.82 src/sys/dev/pci/ixgbe/ixv.c:1.83 --- src/sys/dev/pci/ixgbe/ixv.c:1.82 Mon Feb 26 08:14:01 2018 +++ src/sys/dev/pci/ixgbe/ixv.c Tue Feb 27 04:58:27 2018 @@ -1,4 +1,4 @@ -/*$NetBSD: ixv.c,v 1.82 2018/02/26 08:14:01 knakahara Exp $*/ +/*$NetBSD: ixv.c,v 1.83 2018/02/27 04:58:27 msaitoh Exp $*/ /****************************************************************************** @@ -131,8 +131,16 @@ static void ixv_save_stats(struct adapte static void ixv_init_stats(struct adapter *); static void ixv_update_stats(struct adapter *); static void ixv_add_stats_sysctls(struct adapter *); + + +/* Sysctl handlers */ static void ixv_set_sysctl_value(struct adapter *, const char *, const char *, int *, int); +static int ixv_sysctl_interrupt_rate_handler(SYSCTLFN_PROTO); +static int ixv_sysctl_rdh_handler(SYSCTLFN_PROTO); +static int ixv_sysctl_rdt_handler(SYSCTLFN_PROTO); +static int ixv_sysctl_tdt_handler(SYSCTLFN_PROTO); +static int ixv_sysctl_tdh_handler(SYSCTLFN_PROTO); /* The MSI-X Interrupt handlers */ static int ixv_msix_que(void *); @@ -181,6 +189,9 @@ TUNABLE_INT("hw.ixv.num_queues", &ixv_nu static bool ixv_enable_aim = false; TUNABLE_INT("hw.ixv.enable_aim", &ixv_enable_aim); +static int ixv_max_interrupt_rate = (4000000 / IXGBE_LOW_LATENCY); +TUNABLE_INT("hw.ixv.max_interrupt_rate", &ixv_max_interrupt_rate); + /* How many packets rxeof tries to clean at a time */ static int ixv_rx_process_limit = 256; TUNABLE_INT("hw.ixv.rx_process_limit", &ixv_rx_process_limit); @@ -1785,6 +1796,86 @@ ixv_initialize_receive_units(struct adap } /* ixv_initialize_receive_units */ /************************************************************************ + * ixv_sysctl_tdh_handler - Transmit Descriptor Head handler function + * + * Retrieves the TDH value from the hardware + ************************************************************************/ +static int +ixv_sysctl_tdh_handler(SYSCTLFN_ARGS) +{ + struct sysctlnode node = *rnode; + struct tx_ring *txr = (struct tx_ring *)node.sysctl_data; + uint32_t val; + + if (!txr) + return (0); + + val = IXGBE_READ_REG(&txr->adapter->hw, IXGBE_VFTDH(txr->me)); + node.sysctl_data = &val; + return sysctl_lookup(SYSCTLFN_CALL(&node)); +} /* ixv_sysctl_tdh_handler */ + +/************************************************************************ + * ixgbe_sysctl_tdt_handler - Transmit Descriptor Tail handler function + * + * Retrieves the TDT value from the hardware + ************************************************************************/ +static int +ixv_sysctl_tdt_handler(SYSCTLFN_ARGS) +{ + struct sysctlnode node = *rnode; + struct tx_ring *txr = (struct tx_ring *)node.sysctl_data; + uint32_t val; + + if (!txr) + return (0); + + val = IXGBE_READ_REG(&txr->adapter->hw, IXGBE_VFTDT(txr->me)); + node.sysctl_data = &val; + return sysctl_lookup(SYSCTLFN_CALL(&node)); +} /* ixv_sysctl_tdt_handler */ + +/************************************************************************ + * ixv_sysctl_rdh_handler - Receive Descriptor Head handler function + * + * Retrieves the RDH value from the hardware + ************************************************************************/ +static int +ixv_sysctl_rdh_handler(SYSCTLFN_ARGS) +{ + struct sysctlnode node = *rnode; + struct rx_ring *rxr = (struct rx_ring *)node.sysctl_data; + uint32_t val; + + if (!rxr) + return (0); + + val = IXGBE_READ_REG(&rxr->adapter->hw, IXGBE_VFRDH(rxr->me)); + node.sysctl_data = &val; + return sysctl_lookup(SYSCTLFN_CALL(&node)); +} /* ixv_sysctl_rdh_handler */ + +/************************************************************************ + * ixv_sysctl_rdt_handler - Receive Descriptor Tail handler function + * + * Retrieves the RDT value from the hardware + ************************************************************************/ +static int +ixv_sysctl_rdt_handler(SYSCTLFN_ARGS) +{ + struct sysctlnode node = *rnode; + struct rx_ring *rxr = (struct rx_ring *)node.sysctl_data; + uint32_t val; + + if (!rxr) + return (0); + + val = IXGBE_READ_REG(&rxr->adapter->hw, IXGBE_VFRDT(rxr->me)); + node.sysctl_data = &val; + return sysctl_lookup(SYSCTLFN_CALL(&node)); +} /* ixv_sysctl_rdt_handler */ + +/************************************************************************ * ixv_setup_vlan_support ************************************************************************/ static void @@ -2111,6 +2202,55 @@ ixv_update_stats(struct adapter *adapter */ } /* ixv_update_stats */ +/************************************************************************ + * ixv_sysctl_interrupt_rate_handler + ************************************************************************/ +static int +ixv_sysctl_interrupt_rate_handler(SYSCTLFN_ARGS) +{ + struct sysctlnode node = *rnode; + struct ix_queue *que = (struct ix_queue *)node.sysctl_data; + struct adapter *adapter = que->adapter; + uint32_t reg, usec, rate; + int error; + + if (que == NULL) + return 0; + reg = IXGBE_READ_REG(&que->adapter->hw, IXGBE_VTEITR(que->msix)); + usec = ((reg & 0x0FF8) >> 3); + if (usec > 0) + rate = 500000 / usec; + else + rate = 0; + node.sysctl_data = &rate; + error = sysctl_lookup(SYSCTLFN_CALL(&node)); + if (error || newp == NULL) + return error; + reg &= ~0xfff; /* default, no limitation */ + if (rate > 0 && rate < 500000) { + if (rate < 1000) + rate = 1000; + reg |= ((4000000/rate) & 0xff8); + /* + * When RSC is used, ITR interval must be larger than + * RSC_DELAY. Currently, we use 2us for RSC_DELAY. + * The minimum value is always greater than 2us on 100M + * (and 10M?(not documented)), but it's not on 1G and higher. + */ + if ((adapter->link_speed != IXGBE_LINK_SPEED_100_FULL) + && (adapter->link_speed != IXGBE_LINK_SPEED_10_FULL)) { + if ((adapter->num_queues > 1) + && (reg < IXGBE_MIN_RSC_EITR_10G1G)) + return EINVAL; + } + ixv_max_interrupt_rate = rate; + } else + ixv_max_interrupt_rate = 0; + ixv_eitr_write(que, reg); + + return (0); +} /* ixv_sysctl_interrupt_rate_handler */ + const struct sysctlnode * ixv_sysctl_instance(struct adapter *adapter) { @@ -2173,7 +2313,7 @@ ixv_add_stats_sysctls(struct adapter *ad struct rx_ring *rxr = adapter->rx_rings; struct ixgbevf_hw_stats *stats = &adapter->stats.vf; struct ixgbe_hw *hw = &adapter->hw; - const struct sysctlnode *rnode; + const struct sysctlnode *rnode, *cnode; struct sysctllog **log = &adapter->sysctllog; const char *xname = device_xname(dev); @@ -2221,35 +2361,36 @@ ixv_add_stats_sysctls(struct adapter *ad NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL) != 0) break; -#if 0 /* not yet */ if (sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE, CTLTYPE_INT, "interrupt_rate", SYSCTL_DESCR("Interrupt Rate"), - ixgbe_sysctl_interrupt_rate_handler, 0, + ixv_sysctl_interrupt_rate_handler, 0, (void *)&adapter->queues[i], 0, CTL_CREATE, CTL_EOL) != 0) break; +#if 0 if (sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READONLY, CTLTYPE_QUAD, "irqs", SYSCTL_DESCR("irqs on this queue"), NULL, 0, &(adapter->queues[i].irqs), 0, CTL_CREATE, CTL_EOL) != 0) break; +#endif if (sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READONLY, CTLTYPE_INT, "txd_head", SYSCTL_DESCR("Transmit Descriptor Head"), - ixgbe_sysctl_tdh_handler, 0, (void *)txr, + ixv_sysctl_tdh_handler, 0, (void *)txr, 0, CTL_CREATE, CTL_EOL) != 0) break; if (sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READONLY, CTLTYPE_INT, "txd_tail", SYSCTL_DESCR("Transmit Descriptor Tail"), - ixgbe_sysctl_tdt_handler, 0, (void *)txr, + ixv_sysctl_tdt_handler, 0, (void *)txr, 0, CTL_CREATE, CTL_EOL) != 0) break; -#endif + evcnt_attach_dynamic(&adapter->queues[i].irqs, EVCNT_TYPE_INTR, NULL, adapter->queues[i].evnamebuf, "IRQs on queue"); evcnt_attach_dynamic(&txr->tso_tx, EVCNT_TYPE_MISC, @@ -2270,12 +2411,11 @@ ixv_add_stats_sysctls(struct adapter *ad struct lro_ctrl *lro = &rxr->lro; #endif /* LRO */ -#if 0 /* not yet */ if (sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READONLY, CTLTYPE_INT, "rxd_head", SYSCTL_DESCR("Receive Descriptor Head"), - ixgbe_sysctl_rdh_handler, 0, (void *)rxr, 0, + ixv_sysctl_rdh_handler, 0, (void *)rxr, 0, CTL_CREATE, CTL_EOL) != 0) break; @@ -2283,10 +2423,9 @@ ixv_add_stats_sysctls(struct adapter *ad CTLFLAG_READONLY, CTLTYPE_INT, "rxd_tail", SYSCTL_DESCR("Receive Descriptor Tail"), - ixgbe_sysctl_rdt_handler, 0, (void *)rxr, 0, + ixv_sysctl_rdt_handler, 0, (void *)rxr, 0, CTL_CREATE, CTL_EOL) != 0) break; -#endif evcnt_attach_dynamic(&rxr->rx_packets, EVCNT_TYPE_MISC, NULL, adapter->queues[i].evnamebuf, "Queue Packets Received");