Skip to content

Commit 8f6320d

Browse files
committed
Merge branch 'txq_max_rate'
Or Gerlitz says: ==================== Add max rate TXQ attribute Add the ability to set a max-rate limitation for TX queues. The attribute name is maxrate and the units are Mbs, to make it similar to the existing max-rate limitation knobs (ETS and SRIOV ndo calls). changes from V2: - added Documentation (thanks Florian and Tom) - rebased to latest net-next to comply with the swdev ndo removal - addressed more feedback from Dave on the comments style changes from V1: - addressed feedback from Dave changes from V0: - addressed feedback from Sergei John Fastabend (1): net: Add max rate tx queue attribute ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents b65885d + c10e4fc commit 8f6320d

File tree

12 files changed

+181
-18
lines changed

12 files changed

+181
-18
lines changed

Documentation/ABI/testing/sysfs-class-net-queues

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ Description:
2424
Indicates the number of transmit timeout events seen by this
2525
network interface transmit queue.
2626

27+
What: /sys/class/<iface>/queues/tx-<queue>/tx_maxrate
28+
Date: March 2015
29+
KernelVersion: 4.1
30+
31+
Description:
32+
A Mbps max-rate set for the queue, a value of zero means disabled,
33+
default is disabled.
34+
2735
What: /sys/class/<iface>/queues/tx-<queue>/xps_cpus
2836
Date: November 2010
2937
KernelVersion: 2.6.38

Documentation/networking/scaling.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,15 @@ best CPUs to share a given queue are probably those that share the cache
421421
with the CPU that processes transmit completions for that queue
422422
(transmit interrupts).
423423

424+
Per TX Queue rate limitation:
425+
=============================
426+
427+
These are rate-limitation mechanisms implemented by HW, where currently
428+
a max-rate attribute is supported, by setting a Mbps value to
429+
430+
/sys/class/net/<dev>/queues/tx-<n>/tx_maxrate
431+
432+
A value of zero means disabled, and this is the default.
424433

425434
Further Information
426435
===================

drivers/net/ethernet/mellanox/mlx4/en_netdev.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2379,6 +2379,33 @@ static netdev_features_t mlx4_en_features_check(struct sk_buff *skb,
23792379
}
23802380
#endif
23812381

2382+
int mlx4_en_set_tx_maxrate(struct net_device *dev, int queue_index, u32 maxrate)
2383+
{
2384+
struct mlx4_en_priv *priv = netdev_priv(dev);
2385+
struct mlx4_en_tx_ring *tx_ring = priv->tx_ring[queue_index];
2386+
struct mlx4_update_qp_params params;
2387+
int err;
2388+
2389+
if (!(priv->mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_QP_RATE_LIMIT))
2390+
return -EOPNOTSUPP;
2391+
2392+
/* rate provided to us in Mbs, check if it fits into 12 bits, if not use Gbs */
2393+
if (maxrate >> 12) {
2394+
params.rate_unit = MLX4_QP_RATE_LIMIT_GBS;
2395+
params.rate_val = maxrate / 1000;
2396+
} else if (maxrate) {
2397+
params.rate_unit = MLX4_QP_RATE_LIMIT_MBS;
2398+
params.rate_val = maxrate;
2399+
} else { /* zero serves to revoke the QP rate-limitation */
2400+
params.rate_unit = 0;
2401+
params.rate_val = 0;
2402+
}
2403+
2404+
err = mlx4_update_qp(priv->mdev->dev, tx_ring->qpn, MLX4_UPDATE_QP_RATE_LIMIT,
2405+
&params);
2406+
return err;
2407+
}
2408+
23822409
static const struct net_device_ops mlx4_netdev_ops = {
23832410
.ndo_open = mlx4_en_open,
23842411
.ndo_stop = mlx4_en_close,
@@ -2410,6 +2437,7 @@ static const struct net_device_ops mlx4_netdev_ops = {
24102437
.ndo_del_vxlan_port = mlx4_en_del_vxlan_port,
24112438
.ndo_features_check = mlx4_en_features_check,
24122439
#endif
2440+
.ndo_set_tx_maxrate = mlx4_en_set_tx_maxrate,
24132441
};
24142442

24152443
static const struct net_device_ops mlx4_netdev_ops_master = {
@@ -2444,6 +2472,7 @@ static const struct net_device_ops mlx4_netdev_ops_master = {
24442472
.ndo_del_vxlan_port = mlx4_en_del_vxlan_port,
24452473
.ndo_features_check = mlx4_en_features_check,
24462474
#endif
2475+
.ndo_set_tx_maxrate = mlx4_en_set_tx_maxrate,
24472476
};
24482477

24492478
struct mlx4_en_bond {

drivers/net/ethernet/mellanox/mlx4/fw.c

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,8 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags)
144144
[19] = "Performance optimized for limited rule configuration flow steering support",
145145
[20] = "Recoverable error events support",
146146
[21] = "Port Remap support",
147-
[22] = "QCN support"
147+
[22] = "QCN support",
148+
[23] = "QP rate limiting support"
148149
};
149150
int i;
150151

@@ -697,6 +698,10 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
697698
#define QUERY_DEV_CAP_MAD_DEMUX_OFFSET 0xb0
698699
#define QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_BASE_OFFSET 0xa8
699700
#define QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_RANGE_OFFSET 0xac
701+
#define QUERY_DEV_CAP_QP_RATE_LIMIT_NUM_OFFSET 0xcc
702+
#define QUERY_DEV_CAP_QP_RATE_LIMIT_MAX_OFFSET 0xd0
703+
#define QUERY_DEV_CAP_QP_RATE_LIMIT_MIN_OFFSET 0xd2
704+
700705

701706
dev_cap->flags2 = 0;
702707
mailbox = mlx4_alloc_cmd_mailbox(dev);
@@ -904,6 +909,18 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
904909
QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_RANGE_OFFSET);
905910
dev_cap->dmfs_high_rate_qpn_range &= MGM_QPN_MASK;
906911

912+
MLX4_GET(size, outbox, QUERY_DEV_CAP_QP_RATE_LIMIT_NUM_OFFSET);
913+
dev_cap->rl_caps.num_rates = size;
914+
if (dev_cap->rl_caps.num_rates) {
915+
dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_QP_RATE_LIMIT;
916+
MLX4_GET(size, outbox, QUERY_DEV_CAP_QP_RATE_LIMIT_MAX_OFFSET);
917+
dev_cap->rl_caps.max_val = size & 0xfff;
918+
dev_cap->rl_caps.max_unit = size >> 14;
919+
MLX4_GET(size, outbox, QUERY_DEV_CAP_QP_RATE_LIMIT_MIN_OFFSET);
920+
dev_cap->rl_caps.min_val = size & 0xfff;
921+
dev_cap->rl_caps.min_unit = size >> 14;
922+
}
923+
907924
MLX4_GET(field32, outbox, QUERY_DEV_CAP_EXT_2_FLAGS_OFFSET);
908925
if (field32 & (1 << 16))
909926
dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_UPDATE_QP;
@@ -979,6 +996,15 @@ void mlx4_dev_cap_dump(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
979996
dev_cap->dmfs_high_rate_qpn_base);
980997
mlx4_dbg(dev, "DMFS high rate steer QPn range: %d\n",
981998
dev_cap->dmfs_high_rate_qpn_range);
999+
1000+
if (dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_QP_RATE_LIMIT) {
1001+
struct mlx4_rate_limit_caps *rl_caps = &dev_cap->rl_caps;
1002+
1003+
mlx4_dbg(dev, "QP Rate-Limit: #rates %d, unit/val max %d/%d, min %d/%d\n",
1004+
rl_caps->num_rates, rl_caps->max_unit, rl_caps->max_val,
1005+
rl_caps->min_unit, rl_caps->min_val);
1006+
}
1007+
9821008
dump_dev_cap_flags(dev, dev_cap->flags);
9831009
dump_dev_cap_flags2(dev, dev_cap->flags2);
9841010
}
@@ -1075,6 +1101,7 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
10751101
u64 flags;
10761102
int err = 0;
10771103
u8 field;
1104+
u16 field16;
10781105
u32 bmme_flags, field32;
10791106
int real_port;
10801107
int slave_port;
@@ -1158,6 +1185,10 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
11581185
field &= 0xfe;
11591186
MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_ECN_QCN_VER_OFFSET);
11601187

1188+
/* turn off QP max-rate limiting for guests */
1189+
field16 = 0;
1190+
MLX4_PUT(outbox->buf, field16, QUERY_DEV_CAP_QP_RATE_LIMIT_NUM_OFFSET);
1191+
11611192
return 0;
11621193
}
11631194

drivers/net/ethernet/mellanox/mlx4/fw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ struct mlx4_dev_cap {
127127
u32 max_counters;
128128
u32 dmfs_high_rate_qpn_base;
129129
u32 dmfs_high_rate_qpn_range;
130+
struct mlx4_rate_limit_caps rl_caps;
130131
struct mlx4_port_cap port_cap[MLX4_MAX_PORTS + 1];
131132
};
132133

drivers/net/ethernet/mellanox/mlx4/main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,8 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
489489
dev->caps.dmfs_high_rate_qpn_range = MLX4_A0_STEERING_TABLE_SIZE;
490490
}
491491

492+
dev->caps.rl_caps = dev_cap->rl_caps;
493+
492494
dev->caps.reserved_qps_cnt[MLX4_QP_REGION_RSS_RAW_ETH] =
493495
dev->caps.dmfs_high_rate_qpn_range;
494496

drivers/net/ethernet/mellanox/mlx4/qp.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,11 @@ int mlx4_update_qp(struct mlx4_dev *dev, u32 qpn,
442442
cmd->qp_context.param3 |= cpu_to_be32(MLX4_STRIP_VLAN);
443443
}
444444

445+
if (attr & MLX4_UPDATE_QP_RATE_LIMIT) {
446+
qp_mask |= 1ULL << MLX4_UPD_QP_MASK_RATE_LIMIT;
447+
cmd->qp_context.rate_limit_params = cpu_to_be16((params->rate_unit << 14) | params->rate_val);
448+
}
449+
445450
cmd->primary_addr_path_mask = cpu_to_be64(pri_addr_path_mask);
446451
cmd->qp_mask = cpu_to_be64(qp_mask);
447452

drivers/net/ethernet/mellanox/mlx4/resource_tracker.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2947,8 +2947,12 @@ static int verify_qp_parameters(struct mlx4_dev *dev,
29472947
qp_type = (be32_to_cpu(qp_ctx->flags) >> 16) & 0xff;
29482948
optpar = be32_to_cpu(*(__be32 *) inbox->buf);
29492949

2950-
if (slave != mlx4_master_func_num(dev))
2950+
if (slave != mlx4_master_func_num(dev)) {
29512951
qp_ctx->params2 &= ~MLX4_QP_BIT_FPP;
2952+
/* setting QP rate-limit is disallowed for VFs */
2953+
if (qp_ctx->rate_limit_params)
2954+
return -EPERM;
2955+
}
29522956

29532957
switch (qp_type) {
29542958
case MLX4_QP_ST_RC:

include/linux/mlx4/device.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ enum {
205205
MLX4_DEV_CAP_FLAG2_RECOVERABLE_ERROR_EVENT = 1LL << 20,
206206
MLX4_DEV_CAP_FLAG2_PORT_REMAP = 1LL << 21,
207207
MLX4_DEV_CAP_FLAG2_QCN = 1LL << 22,
208+
MLX4_DEV_CAP_FLAG2_QP_RATE_LIMIT = 1LL << 23
208209
};
209210

210211
enum {
@@ -450,6 +451,21 @@ enum mlx4_module_id {
450451
MLX4_MODULE_ID_QSFP28 = 0x11,
451452
};
452453

454+
enum { /* rl */
455+
MLX4_QP_RATE_LIMIT_NONE = 0,
456+
MLX4_QP_RATE_LIMIT_KBS = 1,
457+
MLX4_QP_RATE_LIMIT_MBS = 2,
458+
MLX4_QP_RATE_LIMIT_GBS = 3
459+
};
460+
461+
struct mlx4_rate_limit_caps {
462+
u16 num_rates; /* Number of different rates */
463+
u8 min_unit;
464+
u16 min_val;
465+
u8 max_unit;
466+
u16 max_val;
467+
};
468+
453469
static inline u64 mlx4_fw_ver(u64 major, u64 minor, u64 subminor)
454470
{
455471
return (major << 32) | (minor << 16) | subminor;
@@ -565,6 +581,7 @@ struct mlx4_caps {
565581
u32 dmfs_high_rate_qpn_base;
566582
u32 dmfs_high_rate_qpn_range;
567583
u32 vf_caps;
584+
struct mlx4_rate_limit_caps rl_caps;
568585
};
569586

570587
struct mlx4_buf_list {

include/linux/mlx4/qp.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,14 +207,16 @@ struct mlx4_qp_context {
207207
__be32 msn;
208208
__be16 rq_wqe_counter;
209209
__be16 sq_wqe_counter;
210-
u32 reserved3[2];
210+
u32 reserved3;
211+
__be16 rate_limit_params;
212+
__be16 reserved4;
211213
__be32 param3;
212214
__be32 nummmcpeers_basemkey;
213215
u8 log_page_size;
214-
u8 reserved4[2];
216+
u8 reserved5[2];
215217
u8 mtt_base_addr_h;
216218
__be32 mtt_base_addr_l;
217-
u32 reserved5[10];
219+
u32 reserved6[10];
218220
};
219221

220222
struct mlx4_update_qp_context {
@@ -229,6 +231,7 @@ struct mlx4_update_qp_context {
229231
enum {
230232
MLX4_UPD_QP_MASK_PM_STATE = 32,
231233
MLX4_UPD_QP_MASK_VSD = 33,
234+
MLX4_UPD_QP_MASK_RATE_LIMIT = 35,
232235
};
233236

234237
enum {
@@ -428,7 +431,8 @@ struct mlx4_wqe_inline_seg {
428431
enum mlx4_update_qp_attr {
429432
MLX4_UPDATE_QP_SMAC = 1 << 0,
430433
MLX4_UPDATE_QP_VSD = 1 << 1,
431-
MLX4_UPDATE_QP_SUPPORTED_ATTRS = (1 << 2) - 1
434+
MLX4_UPDATE_QP_RATE_LIMIT = 1 << 2,
435+
MLX4_UPDATE_QP_SUPPORTED_ATTRS = (1 << 3) - 1
432436
};
433437

434438
enum mlx4_update_qp_params_flags {
@@ -438,6 +442,8 @@ enum mlx4_update_qp_params_flags {
438442
struct mlx4_update_qp_params {
439443
u8 smac_index;
440444
u32 flags;
445+
u16 rate_unit;
446+
u16 rate_val;
441447
};
442448

443449
int mlx4_update_qp(struct mlx4_dev *dev, u32 qpn,

include/linux/netdevice.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,7 @@ struct netdev_queue {
587587
#ifdef CONFIG_BQL
588588
struct dql dql;
589589
#endif
590+
unsigned long tx_maxrate;
590591
} ____cacheline_aligned_in_smp;
591592

592593
static inline int netdev_queue_numa_node_read(const struct netdev_queue *q)
@@ -1022,6 +1023,10 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
10221023
* be otherwise expressed by feature flags. The check is called with
10231024
* the set of features that the stack has calculated and it returns
10241025
* those the driver believes to be appropriate.
1026+
* int (*ndo_set_tx_maxrate)(struct net_device *dev,
1027+
* int queue_index, u32 maxrate);
1028+
* Called when a user wants to set a max-rate limitation of specific
1029+
* TX queue.
10251030
*/
10261031
struct net_device_ops {
10271032
int (*ndo_init)(struct net_device *dev);
@@ -1178,6 +1183,9 @@ struct net_device_ops {
11781183
netdev_features_t (*ndo_features_check) (struct sk_buff *skb,
11791184
struct net_device *dev,
11801185
netdev_features_t features);
1186+
int (*ndo_set_tx_maxrate)(struct net_device *dev,
1187+
int queue_index,
1188+
u32 maxrate);
11811189
};
11821190

11831191
/**

0 commit comments

Comments
 (0)