Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

IB/mlx4: Fix use of flow-counters for process_mad

For IB links, reading HCA flow counters through iboe_process_mad() should
be used when mlx4_ib_process_mad() is invoked only for VFs PMA queries and
exactly nothing else.

Fixes: 7193a141eb74 ('IB/mlx4: Set VF to read from QP counters')
Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>

authored by

Or Gerlitz and committed by
Doug Ledford
43bfb972 cb1ff431

+19 -10
+19 -10
drivers/infiniband/hw/mlx4/mad.c
··· 860 860 struct mlx4_ib_dev *dev = to_mdev(ibdev); 861 861 const struct ib_mad *in_mad = (const struct ib_mad *)in; 862 862 struct ib_mad *out_mad = (struct ib_mad *)out; 863 + enum rdma_link_layer link = rdma_port_get_link_layer(ibdev, port_num); 863 864 864 865 if (WARN_ON_ONCE(in_mad_size != sizeof(*in_mad) || 865 866 *out_mad_size != sizeof(*out_mad))) 866 867 return IB_MAD_RESULT_FAILURE; 867 868 868 - switch (rdma_port_get_link_layer(ibdev, port_num)) { 869 - case IB_LINK_LAYER_INFINIBAND: 870 - if (!mlx4_is_slave(dev->dev)) 871 - return ib_process_mad(ibdev, mad_flags, port_num, in_wc, 872 - in_grh, in_mad, out_mad); 873 - case IB_LINK_LAYER_ETHERNET: 874 - return iboe_process_mad(ibdev, mad_flags, port_num, in_wc, 875 - in_grh, in_mad, out_mad); 876 - default: 877 - return -EINVAL; 869 + /* iboe_process_mad() which uses the HCA flow-counters to implement IB PMA 870 + * queries, should be called only by VFs and for that specific purpose 871 + */ 872 + if (link == IB_LINK_LAYER_INFINIBAND) { 873 + if (mlx4_is_slave(dev->dev) && 874 + in_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_PERF_MGMT && 875 + in_mad->mad_hdr.attr_id == IB_PMA_PORT_COUNTERS) 876 + return iboe_process_mad(ibdev, mad_flags, port_num, in_wc, 877 + in_grh, in_mad, out_mad); 878 + 879 + return ib_process_mad(ibdev, mad_flags, port_num, in_wc, 880 + in_grh, in_mad, out_mad); 878 881 } 882 + 883 + if (link == IB_LINK_LAYER_ETHERNET) 884 + return iboe_process_mad(ibdev, mad_flags, port_num, in_wc, 885 + in_grh, in_mad, out_mad); 886 + 887 + return -EINVAL; 879 888 } 880 889 881 890 static void send_handler(struct ib_mad_agent *agent,