Message ID | 20211125154813.579169-5-maxime.chevallier@bootlin.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | net: mvneta: mqprio cleanups and shaping support | expand |
Context | Check | Description |
---|---|---|
netdev/tree_selection | success | Clearly marked for net-next |
netdev/fixes_present | success | Fixes tag not required for -next series |
netdev/subject_prefix | success | Link |
netdev/cover_letter | success | Series has a cover letter |
netdev/patch_count | success | Link |
netdev/header_inline | success | No static functions without inline keyword in header files |
netdev/build_32bit | fail | Errors and warnings before: 2 this patch: 7 |
netdev/cc_maintainers | warning | 1 maintainers not CCed: kuba@kernel.org |
netdev/build_clang | success | Errors and warnings before: 0 this patch: 0 |
netdev/module_param | success | Was 0 now: 0 |
netdev/verify_signedoff | success | Signed-off-by tag matches author and committer |
netdev/verify_fixes | success | No Fixes tag |
netdev/build_allmodconfig_warn | success | Errors and warnings before: 2 this patch: 2 |
netdev/checkpatch | warning | WARNING: line length of 85 exceeds 80 columns |
netdev/kdoc | success | Errors and warnings before: 0 this patch: 0 |
netdev/source_inline | success | Was 0 now: 0 |
On Thu, 25 Nov 2021 16:48:13 +0100 Maxime Chevallier wrote: > The mvneta controller is able to do some tocken-bucket per-queue traffic > shaping. This commit adds support for setting these using the TC mqprio > interface. > > The token-bucket parameters are customisable, but the current > implementation configures them to have a 10kbps resolution for the > rate limitation, since it allows to cover the whole range of max_rate > values from 10kbps to 5Gbps with 10kbps increments. > > Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com> Breaks 32bit build, please make sure you use division helpers for 64b.
Hi Maxime,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on net-next/master]
url: https://github.com/0day-ci/linux/commits/Maxime-Chevallier/net-mvneta-mqprio-cleanups-and-shaping-support/20211125-235035
base: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 305e95bb893cc50f7c59edf2b47d95effe73498a
config: arm-defconfig (https://download.01.org/0day-ci/archive/20211126/202111261722.xQYnccxe-lkp@intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/789fe6c5e8c95ee076c1476c860591c00fa06555
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Maxime-Chevallier/net-mvneta-mqprio-cleanups-and-shaping-support/20211125-235035
git checkout 789fe6c5e8c95ee076c1476c860591c00fa06555
# save the config file to linux build tree
mkdir build_dir
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arm SHELL=/bin/bash
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
arm-linux-gnueabi-ld: drivers/net/ethernet/marvell/mvneta.o: in function `mvneta_setup_mqprio':
>> mvneta.c:(.text+0x2a3c): undefined reference to `__aeabi_uldivmod'
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hello Jakub, On Thu, 25 Nov 2021 09:50:29 -0800 Jakub Kicinski <kuba@kernel.org> wrote: >On Thu, 25 Nov 2021 16:48:13 +0100 Maxime Chevallier wrote: >> The mvneta controller is able to do some tocken-bucket per-queue traffic >> shaping. This commit adds support for setting these using the TC mqprio >> interface. >> >> The token-bucket parameters are customisable, but the current >> implementation configures them to have a 10kbps resolution for the >> rate limitation, since it allows to cover the whole range of max_rate >> values from 10kbps to 5Gbps with 10kbps increments. >> >> Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com> > >Breaks 32bit build, please make sure you use division helpers for 64b. My bad, I'll update to use the proper helpers then (and compile-test for 32bits this time too, sorry about that) Thanks, Maxime
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index aba452e8abfe..ca7b3c5cfe0a 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -248,12 +248,39 @@ #define MVNETA_TXQ_SENT_DESC_MASK 0x3fff0000 #define MVNETA_PORT_TX_RESET 0x3cf0 #define MVNETA_PORT_TX_DMA_RESET BIT(0) +#define MVNETA_TXQ_CMD1_REG 0x3e00 +#define MVNETA_TXQ_CMD1_BW_LIM_SEL_V1 BIT(3) +#define MVNETA_TXQ_CMD1_BW_LIM_EN BIT(0) +#define MVNETA_REFILL_NUM_CLK_REG 0x3e08 +#define MVNETA_REFILL_MAX_NUM_CLK 0x0000ffff #define MVNETA_TX_MTU 0x3e0c #define MVNETA_TX_TOKEN_SIZE 0x3e14 #define MVNETA_TX_TOKEN_SIZE_MAX 0xffffffff +#define MVNETA_TXQ_BUCKET_REFILL_REG(q) (0x3e20 + ((q) << 2)) +#define MVNETA_TXQ_BUCKET_REFILL_PERIOD_MASK 0x3ff00000 +#define MVNETA_TXQ_BUCKET_REFILL_PERIOD_SHIFT 20 +#define MVNETA_TXQ_BUCKET_REFILL_VALUE_MAX 0x0007ffff #define MVNETA_TXQ_TOKEN_SIZE_REG(q) (0x3e40 + ((q) << 2)) #define MVNETA_TXQ_TOKEN_SIZE_MAX 0x7fffffff +/* The values of the bucket refill base period and refill period are taken from + * the reference manual, and adds up to a base resolution of 10Kbps. This allows + * to cover all rate-limit values from 10Kbps up to 5Gbps + */ + +/* Base period for the rate limit algorithm */ +#define MVNETA_TXQ_BUCKET_REFILL_BASE_PERIOD_NS 100 + +/* Number of Base Period to wait between each bucket refill */ +#define MVNETA_TXQ_BUCKET_REFILL_PERIOD 1000 + +/* The base resolution for rate limiting, in bps. Any max_rate value should be + * a multiple of that value. + */ +#define MVNETA_TXQ_RATE_LIMIT_RESOLUTION (NSEC_PER_SEC / \ + (MVNETA_TXQ_BUCKET_REFILL_BASE_PERIOD_NS * \ + MVNETA_TXQ_BUCKET_REFILL_PERIOD)) + #define MVNETA_LPI_CTRL_0 0x2cc0 #define MVNETA_LPI_CTRL_1 0x2cc4 #define MVNETA_LPI_REQUEST_ENABLE BIT(0) @@ -4906,11 +4933,75 @@ static void mvneta_map_vlan_prio_to_rxq(struct mvneta_port *pp, u8 pri, u8 rxq) mvreg_write(pp, MVNETA_VLAN_PRIO_TO_RXQ, val); } +static int mvneta_enable_per_queue_rate_limit(struct mvneta_port *pp) +{ + unsigned long core_clk_rate; + u32 refill_cycles; + u32 val; + + core_clk_rate = clk_get_rate(pp->clk); + if (!core_clk_rate) + return -EINVAL; + + refill_cycles = MVNETA_TXQ_BUCKET_REFILL_BASE_PERIOD_NS / + (NSEC_PER_SEC / core_clk_rate); + + if (refill_cycles > MVNETA_REFILL_MAX_NUM_CLK) + return -EINVAL; + + /* Enable bw limit algorithm version 3 */ + val = mvreg_read(pp, MVNETA_TXQ_CMD1_REG); + val &= ~(MVNETA_TXQ_CMD1_BW_LIM_SEL_V1 | MVNETA_TXQ_CMD1_BW_LIM_EN); + mvreg_write(pp, MVNETA_TXQ_CMD1_REG, val); + + /* Set the base refill rate */ + mvreg_write(pp, MVNETA_REFILL_NUM_CLK_REG, refill_cycles); + + return 0; +} + +static void mvneta_disable_per_queue_rate_limit(struct mvneta_port *pp) +{ + u32 val = mvreg_read(pp, MVNETA_TXQ_CMD1_REG); + + val |= (MVNETA_TXQ_CMD1_BW_LIM_SEL_V1 | MVNETA_TXQ_CMD1_BW_LIM_EN); + mvreg_write(pp, MVNETA_TXQ_CMD1_REG, val); +} + +static int mvneta_setup_queue_rates(struct mvneta_port *pp, int queue, + u64 min_rate, u64 max_rate) +{ + u32 refill_val; + u32 val = 0; + + /* Convert to from Bps to bps */ + max_rate *= 8; + + if (min_rate) + return -EINVAL; + + if (max_rate % MVNETA_TXQ_RATE_LIMIT_RESOLUTION) + return -EINVAL; + + refill_val = max_rate / MVNETA_TXQ_RATE_LIMIT_RESOLUTION; + + if (refill_val == 0 || refill_val > MVNETA_TXQ_BUCKET_REFILL_VALUE_MAX) + return -EINVAL; + + val = refill_val; + val |= (MVNETA_TXQ_BUCKET_REFILL_PERIOD << + MVNETA_TXQ_BUCKET_REFILL_PERIOD_SHIFT); + + mvreg_write(pp, MVNETA_TXQ_BUCKET_REFILL_REG(queue), val); + + return 0; +} + static int mvneta_setup_mqprio(struct net_device *dev, struct tc_mqprio_qopt_offload *mqprio) { struct mvneta_port *pp = netdev_priv(dev); - int rxq, tc; + int rxq, txq, tc, ret; u8 num_tc; if (mqprio->qopt.hw != TC_MQPRIO_HW_OFFLOAD_TCS) @@ -4924,6 +5015,7 @@ static int mvneta_setup_mqprio(struct net_device *dev, mvneta_clear_rx_prio_map(pp); if (!num_tc) { + mvneta_disable_per_queue_rate_limit(pp); netdev_reset_tc(dev); return 0; } @@ -4944,6 +5036,33 @@ static int mvneta_setup_mqprio(struct net_device *dev, } } + if (mqprio->shaper != TC_MQPRIO_SHAPER_BW_RATE) { + mvneta_disable_per_queue_rate_limit(pp); + return 0; + } + + if (mqprio->qopt.num_tc > txq_number) + return -EINVAL; + + ret = mvneta_enable_per_queue_rate_limit(pp); + if (ret) + return ret; + + for (tc = 0; tc < mqprio->qopt.num_tc; tc++) { + for (txq = mqprio->qopt.offset[tc]; + txq < mqprio->qopt.count[tc] + mqprio->qopt.offset[tc]; + txq++) { + if (txq >= txq_number) + return -EINVAL; + + ret = mvneta_setup_queue_rates(pp, txq, + mqprio->min_rate[tc], + mqprio->max_rate[tc]); + if (ret) + return ret; + } + } + return 0; }
The mvneta controller is able to do some tocken-bucket per-queue traffic shaping. This commit adds support for setting these using the TC mqprio interface. The token-bucket parameters are customisable, but the current implementation configures them to have a 10kbps resolution for the rate limitation, since it allows to cover the whole range of max_rate values from 10kbps to 5Gbps with 10kbps increments. Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com> --- drivers/net/ethernet/marvell/mvneta.c | 121 +++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 1 deletion(-)