Skip to content

Commit 916035d

Browse files
committed
Merge branch 'mlx4-vf-counters'
Or Gerlitz says: ==================== mlx4 driver update (+ new VF ndo) This series from Eran and Hadar is further dealing with traffic counters in the mlx4 driver, this time mostly around SRIOV. We added a new ndo to read the VF counters through the PF netdev netlink infrastructure plus mlx4 implementation for that ndo. changes from V0: - applied feedback from John to use nested netlink encoding for the VF counters so we can extend it later - add handling of single ported VFs in the mlx4_en driver new ndo - avoid chopping the FW counters from 64 to 32 bits in mlx4_en PF flow ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents b4ad7ba + 62a8905 commit 916035d

File tree

20 files changed

+587
-70
lines changed

20 files changed

+587
-70
lines changed

drivers/infiniband/hw/mlx4/mad.c

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,6 @@ enum {
6464
#define GUID_TBL_BLK_NUM_ENTRIES 8
6565
#define GUID_TBL_BLK_SIZE (GUID_TBL_ENTRY_SIZE * GUID_TBL_BLK_NUM_ENTRIES)
6666

67-
/* Counters should be saturate once they reach their maximum value */
68-
#define ASSIGN_32BIT_COUNTER(counter, value) do {\
69-
if ((value) > U32_MAX) \
70-
counter = cpu_to_be32(U32_MAX); \
71-
else \
72-
counter = cpu_to_be32(value); \
73-
} while (0)
74-
7567
struct mlx4_mad_rcv_buf {
7668
struct ib_grh grh;
7769
u8 payload[256];
@@ -828,51 +820,45 @@ static int iboe_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
828820
struct ib_wc *in_wc, struct ib_grh *in_grh,
829821
struct ib_mad *in_mad, struct ib_mad *out_mad)
830822
{
831-
struct mlx4_cmd_mailbox *mailbox;
823+
struct mlx4_counter counter_stats;
832824
struct mlx4_ib_dev *dev = to_mdev(ibdev);
833825
int err;
834-
u32 inmod = dev->counters[port_num - 1] & 0xffff;
835-
u8 mode;
836826

837827
if (in_mad->mad_hdr.mgmt_class != IB_MGMT_CLASS_PERF_MGMT)
838828
return -EINVAL;
839829

840-
mailbox = mlx4_alloc_cmd_mailbox(dev->dev);
841-
if (IS_ERR(mailbox))
842-
return IB_MAD_RESULT_FAILURE;
843-
844-
err = mlx4_cmd_box(dev->dev, 0, mailbox->dma, inmod, 0,
845-
MLX4_CMD_QUERY_IF_STAT, MLX4_CMD_TIME_CLASS_C,
846-
MLX4_CMD_WRAPPED);
830+
memset(&counter_stats, 0, sizeof(counter_stats));
831+
err = mlx4_get_counter_stats(dev->dev,
832+
dev->counters[port_num - 1].index,
833+
&counter_stats, 0);
847834
if (err)
848835
err = IB_MAD_RESULT_FAILURE;
849836
else {
850837
memset(out_mad->data, 0, sizeof out_mad->data);
851-
mode = ((struct mlx4_counter *)mailbox->buf)->counter_mode;
852-
switch (mode & 0xf) {
838+
switch (counter_stats.counter_mode & 0xf) {
853839
case 0:
854-
edit_counter(mailbox->buf,
855-
(void *)(out_mad->data + 40));
840+
edit_counter(&counter_stats,
841+
(void *)(out_mad->data + 40));
856842
err = IB_MAD_RESULT_SUCCESS | IB_MAD_RESULT_REPLY;
857843
break;
858844
default:
859845
err = IB_MAD_RESULT_FAILURE;
860846
}
861847
}
862848

863-
mlx4_free_cmd_mailbox(dev->dev, mailbox);
864-
865849
return err;
866850
}
867851

868852
int mlx4_ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
869853
struct ib_wc *in_wc, struct ib_grh *in_grh,
870854
struct ib_mad *in_mad, struct ib_mad *out_mad)
871855
{
856+
struct mlx4_ib_dev *dev = to_mdev(ibdev);
872857
switch (rdma_port_get_link_layer(ibdev, port_num)) {
873858
case IB_LINK_LAYER_INFINIBAND:
874-
return ib_process_mad(ibdev, mad_flags, port_num, in_wc,
875-
in_grh, in_mad, out_mad);
859+
if (!mlx4_is_slave(dev->dev))
860+
return ib_process_mad(ibdev, mad_flags, port_num, in_wc,
861+
in_grh, in_mad, out_mad);
876862
case IB_LINK_LAYER_ETHERNET:
877863
return iboe_process_mad(ibdev, mad_flags, port_num, in_wc,
878864
in_grh, in_mad, out_mad);

drivers/infiniband/hw/mlx4/main.c

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2098,6 +2098,8 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
20982098
struct mlx4_ib_iboe *iboe;
20992099
int ib_num_ports = 0;
21002100
int num_req_counters;
2101+
int allocated;
2102+
u32 counter_index;
21012103

21022104
pr_info_once("%s", mlx4_ib_version);
21032105

@@ -2263,19 +2265,31 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
22632265
num_req_counters = mlx4_is_bonded(dev) ? 1 : ibdev->num_ports;
22642266
for (i = 0; i < num_req_counters; ++i) {
22652267
mutex_init(&ibdev->qp1_proxy_lock[i]);
2268+
allocated = 0;
22662269
if (mlx4_ib_port_link_layer(&ibdev->ib_dev, i + 1) ==
22672270
IB_LINK_LAYER_ETHERNET) {
2268-
err = mlx4_counter_alloc(ibdev->dev, &ibdev->counters[i]);
2271+
err = mlx4_counter_alloc(ibdev->dev, &counter_index);
2272+
/* if failed to allocate a new counter, use default */
22692273
if (err)
2270-
ibdev->counters[i] = -1;
2271-
} else {
2272-
ibdev->counters[i] = -1;
2274+
counter_index =
2275+
mlx4_get_default_counter_index(dev,
2276+
i + 1);
2277+
else
2278+
allocated = 1;
2279+
} else { /* IB_LINK_LAYER_INFINIBAND use the default counter */
2280+
counter_index = mlx4_get_default_counter_index(dev,
2281+
i + 1);
22732282
}
2283+
ibdev->counters[i].index = counter_index;
2284+
ibdev->counters[i].allocated = allocated;
2285+
pr_info("counter index %d for port %d allocated %d\n",
2286+
counter_index, i + 1, allocated);
22742287
}
22752288
if (mlx4_is_bonded(dev))
2276-
for (i = 1; i < ibdev->num_ports ; ++i)
2277-
ibdev->counters[i] = ibdev->counters[0];
2278-
2289+
for (i = 1; i < ibdev->num_ports ; ++i) {
2290+
ibdev->counters[i].index = ibdev->counters[0].index;
2291+
ibdev->counters[i].allocated = 0;
2292+
}
22792293

22802294
mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_IB)
22812295
ib_num_ports++;
@@ -2415,10 +2429,12 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
24152429
mlx4_qp_release_range(dev, ibdev->steer_qpn_base,
24162430
ibdev->steer_qpn_count);
24172431
err_counter:
2418-
for (; i; --i)
2419-
if (ibdev->counters[i - 1] != -1)
2420-
mlx4_counter_free(ibdev->dev, ibdev->counters[i - 1]);
2421-
2432+
for (i = 0; i < ibdev->num_ports; ++i) {
2433+
if (ibdev->counters[i].index != -1 &&
2434+
ibdev->counters[i].allocated)
2435+
mlx4_counter_free(ibdev->dev,
2436+
ibdev->counters[i].index);
2437+
}
24222438
err_map:
24232439
iounmap(ibdev->uar_map);
24242440

@@ -2535,8 +2551,9 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void *ibdev_ptr)
25352551

25362552
iounmap(ibdev->uar_map);
25372553
for (p = 0; p < ibdev->num_ports; ++p)
2538-
if (ibdev->counters[p] != -1)
2539-
mlx4_counter_free(ibdev->dev, ibdev->counters[p]);
2554+
if (ibdev->counters[p].index != -1 &&
2555+
ibdev->counters[p].allocated)
2556+
mlx4_counter_free(ibdev->dev, ibdev->counters[p].index);
25402557
mlx4_foreach_port(p, dev, MLX4_PORT_TYPE_IB)
25412558
mlx4_CLOSE_PORT(dev, p);
25422559

drivers/infiniband/hw/mlx4/mlx4_ib.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,11 @@ struct mlx4_ib_iov_port {
503503
struct mlx4_ib_iov_sysfs_attr mcg_dentry;
504504
};
505505

506+
struct counter_index {
507+
u32 index;
508+
u8 allocated;
509+
};
510+
506511
struct mlx4_ib_dev {
507512
struct ib_device ib_dev;
508513
struct mlx4_dev *dev;
@@ -521,7 +526,7 @@ struct mlx4_ib_dev {
521526
struct mutex cap_mask_mutex;
522527
bool ib_active;
523528
struct mlx4_ib_iboe iboe;
524-
int counters[MLX4_MAX_PORTS];
529+
struct counter_index counters[MLX4_MAX_PORTS];
525530
int *eq_table;
526531
struct kobject *iov_parent;
527532
struct kobject *ports_parent;

drivers/infiniband/hw/mlx4/qp.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,12 +1539,13 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
15391539
}
15401540

15411541
if (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR) {
1542-
if (dev->counters[qp->port - 1] != -1) {
1542+
if (dev->counters[qp->port - 1].index != -1) {
15431543
context->pri_path.counter_index =
1544-
dev->counters[qp->port - 1];
1544+
dev->counters[qp->port - 1].index;
15451545
optpar |= MLX4_QP_OPTPAR_COUNTER_INDEX;
15461546
} else
1547-
context->pri_path.counter_index = 0xff;
1547+
context->pri_path.counter_index =
1548+
MLX4_SINK_COUNTER_INDEX(dev->dev);
15481549

15491550
if (qp->flags & MLX4_IB_QP_NETIF) {
15501551
mlx4_ib_steer_qp_reg(dev, qp, 1);

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

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include "mlx4.h"
5050
#include "fw.h"
5151
#include "fw_qos.h"
52+
#include "mlx4_stats.h"
5253

5354
#define CMD_POLL_TOKEN 0xffff
5455
#define INBOX_MASK 0xffffffffffffff00ULL
@@ -3166,6 +3167,92 @@ int mlx4_set_vf_link_state(struct mlx4_dev *dev, int port, int vf, int link_stat
31663167
}
31673168
EXPORT_SYMBOL_GPL(mlx4_set_vf_link_state);
31683169

3170+
int mlx4_get_counter_stats(struct mlx4_dev *dev, int counter_index,
3171+
struct mlx4_counter *counter_stats, int reset)
3172+
{
3173+
struct mlx4_cmd_mailbox *mailbox = NULL;
3174+
struct mlx4_counter *tmp_counter;
3175+
int err;
3176+
u32 if_stat_in_mod;
3177+
3178+
if (!counter_stats)
3179+
return -EINVAL;
3180+
3181+
if (counter_index == MLX4_SINK_COUNTER_INDEX(dev))
3182+
return 0;
3183+
3184+
mailbox = mlx4_alloc_cmd_mailbox(dev);
3185+
if (IS_ERR(mailbox))
3186+
return PTR_ERR(mailbox);
3187+
3188+
memset(mailbox->buf, 0, sizeof(struct mlx4_counter));
3189+
if_stat_in_mod = counter_index;
3190+
if (reset)
3191+
if_stat_in_mod |= MLX4_QUERY_IF_STAT_RESET;
3192+
err = mlx4_cmd_box(dev, 0, mailbox->dma,
3193+
if_stat_in_mod, 0,
3194+
MLX4_CMD_QUERY_IF_STAT,
3195+
MLX4_CMD_TIME_CLASS_C,
3196+
MLX4_CMD_NATIVE);
3197+
if (err) {
3198+
mlx4_dbg(dev, "%s: failed to read statistics for counter index %d\n",
3199+
__func__, counter_index);
3200+
goto if_stat_out;
3201+
}
3202+
tmp_counter = (struct mlx4_counter *)mailbox->buf;
3203+
counter_stats->counter_mode = tmp_counter->counter_mode;
3204+
if (counter_stats->counter_mode == 0) {
3205+
counter_stats->rx_frames =
3206+
cpu_to_be64(be64_to_cpu(counter_stats->rx_frames) +
3207+
be64_to_cpu(tmp_counter->rx_frames));
3208+
counter_stats->tx_frames =
3209+
cpu_to_be64(be64_to_cpu(counter_stats->tx_frames) +
3210+
be64_to_cpu(tmp_counter->tx_frames));
3211+
counter_stats->rx_bytes =
3212+
cpu_to_be64(be64_to_cpu(counter_stats->rx_bytes) +
3213+
be64_to_cpu(tmp_counter->rx_bytes));
3214+
counter_stats->tx_bytes =
3215+
cpu_to_be64(be64_to_cpu(counter_stats->tx_bytes) +
3216+
be64_to_cpu(tmp_counter->tx_bytes));
3217+
}
3218+
3219+
if_stat_out:
3220+
mlx4_free_cmd_mailbox(dev, mailbox);
3221+
3222+
return err;
3223+
}
3224+
EXPORT_SYMBOL_GPL(mlx4_get_counter_stats);
3225+
3226+
int mlx4_get_vf_stats(struct mlx4_dev *dev, int port, int vf_idx,
3227+
struct ifla_vf_stats *vf_stats)
3228+
{
3229+
struct mlx4_counter tmp_vf_stats;
3230+
int slave;
3231+
int err = 0;
3232+
3233+
if (!vf_stats)
3234+
return -EINVAL;
3235+
3236+
if (!mlx4_is_master(dev))
3237+
return -EPROTONOSUPPORT;
3238+
3239+
slave = mlx4_get_slave_indx(dev, vf_idx);
3240+
if (slave < 0)
3241+
return -EINVAL;
3242+
3243+
port = mlx4_slaves_closest_port(dev, slave, port);
3244+
err = mlx4_calc_vf_counters(dev, slave, port, &tmp_vf_stats);
3245+
if (!err && tmp_vf_stats.counter_mode == 0) {
3246+
vf_stats->rx_packets = be64_to_cpu(tmp_vf_stats.rx_frames);
3247+
vf_stats->tx_packets = be64_to_cpu(tmp_vf_stats.tx_frames);
3248+
vf_stats->rx_bytes = be64_to_cpu(tmp_vf_stats.rx_bytes);
3249+
vf_stats->tx_bytes = be64_to_cpu(tmp_vf_stats.tx_bytes);
3250+
}
3251+
3252+
return err;
3253+
}
3254+
EXPORT_SYMBOL_GPL(mlx4_get_vf_stats);
3255+
31693256
int mlx4_vf_smi_enabled(struct mlx4_dev *dev, int slave, int port)
31703257
{
31713258
struct mlx4_priv *priv = mlx4_priv(dev);

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,12 @@ static const char main_strings[][ETH_GSTRING_LEN] = {
119119
"queue_stopped", "wake_queue", "tx_timeout", "rx_alloc_failed",
120120
"rx_csum_good", "rx_csum_none", "rx_csum_complete", "tx_chksum_offload",
121121

122+
/* pf statistics */
123+
"pf_rx_packets",
124+
"pf_rx_bytes",
125+
"pf_tx_packets",
126+
"pf_tx_bytes",
127+
122128
/* priority flow control statistics rx */
123129
"rx_pause_prio_0", "rx_pause_duration_prio_0",
124130
"rx_pause_transition_prio_0",
@@ -368,6 +374,11 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev,
368374
if (bitmap_iterator_test(&it))
369375
data[index++] = ((unsigned long *)&priv->port_stats)[i];
370376

377+
for (i = 0; i < NUM_PF_STATS; i++, bitmap_iterator_inc(&it))
378+
if (bitmap_iterator_test(&it))
379+
data[index++] =
380+
((unsigned long *)&priv->pf_stats)[i];
381+
371382
for (i = 0; i < NUM_FLOW_PRIORITY_STATS_RX;
372383
i++, bitmap_iterator_inc(&it))
373384
if (bitmap_iterator_test(&it))
@@ -448,6 +459,12 @@ static void mlx4_en_get_strings(struct net_device *dev,
448459
strcpy(data + (index++) * ETH_GSTRING_LEN,
449460
main_strings[strings]);
450461

462+
for (i = 0; i < NUM_PF_STATS; i++, strings++,
463+
bitmap_iterator_inc(&it))
464+
if (bitmap_iterator_test(&it))
465+
strcpy(data + (index++) * ETH_GSTRING_LEN,
466+
main_strings[strings]);
467+
451468
for (i = 0; i < NUM_FLOW_STATS; i++, strings++,
452469
bitmap_iterator_inc(&it))
453470
if (bitmap_iterator_test(&it))

0 commit comments

Comments
 (0)