brintos

brintos / linux-shallow public Read only

0
0
Text · 4.7 KiB · affcf8f Raw
209 lines · c
1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB2/*3 * Copyright (c) 2019-2020, Mellanox Technologies Ltd. All rights reserved.4 */5 6#include <uapi/rdma/rdma_netlink.h>7#include <linux/mlx5/rsc_dump.h>8#include <rdma/ib_umem_odp.h>9#include <rdma/restrack.h>10#include "mlx5_ib.h"11#include "restrack.h"12 13#define MAX_DUMP_SIZE 102414 15static int dump_rsc(struct mlx5_core_dev *dev, enum mlx5_sgmt_type type,16		    int index, void *data, int *data_len)17{18	struct mlx5_core_dev *mdev = dev;19	struct mlx5_rsc_dump_cmd *cmd;20	struct mlx5_rsc_key key = {};21	struct page *page;22	int offset = 0;23	int err = 0;24	int cmd_err;25	int size;26 27	page = alloc_page(GFP_KERNEL);28	if (!page)29		return -ENOMEM;30 31	key.size = PAGE_SIZE;32	key.rsc = type;33	key.index1 = index;34	key.num_of_obj1 = 1;35 36	cmd = mlx5_rsc_dump_cmd_create(mdev, &key);37	if (IS_ERR(cmd)) {38		err = PTR_ERR(cmd);39		goto free_page;40	}41 42	do {43		cmd_err = mlx5_rsc_dump_next(mdev, cmd, page, &size);44		if (cmd_err < 0 || size + offset > MAX_DUMP_SIZE) {45			err = cmd_err;46			goto destroy_cmd;47		}48		memcpy(data + offset, page_address(page), size);49		offset += size;50	} while (cmd_err > 0);51	*data_len = offset;52 53destroy_cmd:54	mlx5_rsc_dump_cmd_destroy(cmd);55free_page:56	__free_page(page);57	return err;58}59 60static int fill_res_raw(struct sk_buff *msg, struct mlx5_ib_dev *dev,61			enum mlx5_sgmt_type type, u32 key)62{63	int len = 0;64	void *data;65	int err;66 67	data = kzalloc(MAX_DUMP_SIZE, GFP_KERNEL);68	if (!data)69		return -ENOMEM;70 71	err = dump_rsc(dev->mdev, type, key, data, &len);72	if (err)73		goto out;74 75	err = nla_put(msg, RDMA_NLDEV_ATTR_RES_RAW, len, data);76out:77	kfree(data);78	return err;79}80 81static int fill_stat_mr_entry(struct sk_buff *msg, struct ib_mr *ibmr)82{83	struct mlx5_ib_mr *mr = to_mmr(ibmr);84	struct nlattr *table_attr;85 86	if (!(mr->access_flags & IB_ACCESS_ON_DEMAND))87		return 0;88 89	table_attr = nla_nest_start(msg,90				    RDMA_NLDEV_ATTR_STAT_HWCOUNTERS);91 92	if (!table_attr)93		goto err;94 95	if (rdma_nl_stat_hwcounter_entry(msg, "page_faults",96					 atomic64_read(&mr->odp_stats.faults)))97		goto err_table;98	if (rdma_nl_stat_hwcounter_entry(99		    msg, "page_invalidations",100		    atomic64_read(&mr->odp_stats.invalidations)))101		goto err_table;102	if (rdma_nl_stat_hwcounter_entry(msg, "page_prefetch",103					 atomic64_read(&mr->odp_stats.prefetch)))104		goto err_table;105 106	nla_nest_end(msg, table_attr);107	return 0;108 109err_table:110	nla_nest_cancel(msg, table_attr);111err:112	return -EMSGSIZE;113}114 115static int fill_res_mr_entry_raw(struct sk_buff *msg, struct ib_mr *ibmr)116{117	struct mlx5_ib_mr *mr = to_mmr(ibmr);118 119	return fill_res_raw(msg, mr_to_mdev(mr), MLX5_SGMT_TYPE_PRM_QUERY_MKEY,120			    mlx5_mkey_to_idx(mr->mmkey.key));121}122 123static int fill_res_mr_entry(struct sk_buff *msg, struct ib_mr *ibmr)124{125	struct mlx5_ib_mr *mr = to_mmr(ibmr);126	struct nlattr *table_attr;127 128	if (!(mr->access_flags & IB_ACCESS_ON_DEMAND))129		return 0;130 131	table_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_DRIVER);132	if (!table_attr)133		goto err;134 135	if (mr->is_odp_implicit) {136		if (rdma_nl_put_driver_string(msg, "odp", "implicit"))137			goto err;138	} else {139		if (rdma_nl_put_driver_string(msg, "odp", "explicit"))140			goto err;141	}142 143	nla_nest_end(msg, table_attr);144	return 0;145 146err:147	nla_nest_cancel(msg, table_attr);148	return -EMSGSIZE;149}150 151static int fill_res_cq_entry_raw(struct sk_buff *msg, struct ib_cq *ibcq)152{153	struct mlx5_ib_dev *dev = to_mdev(ibcq->device);154	struct mlx5_ib_cq *cq = to_mcq(ibcq);155 156	return fill_res_raw(msg, dev, MLX5_SGMT_TYPE_PRM_QUERY_CQ, cq->mcq.cqn);157}158 159static int fill_res_qp_entry(struct sk_buff *msg, struct ib_qp *ibqp)160{161	struct mlx5_ib_qp *qp = to_mqp(ibqp);162	int ret;163 164	if (qp->type < IB_QPT_DRIVER)165		return 0;166 167	switch (qp->type) {168	case MLX5_IB_QPT_REG_UMR:169		ret = nla_put_string(msg, RDMA_NLDEV_ATTR_RES_SUBTYPE,170				     "REG_UMR");171		break;172	case MLX5_IB_QPT_DCT:173		ret = nla_put_string(msg, RDMA_NLDEV_ATTR_RES_SUBTYPE, "DCT");174		break;175	case MLX5_IB_QPT_DCI:176		ret = nla_put_string(msg, RDMA_NLDEV_ATTR_RES_SUBTYPE, "DCI");177		break;178	default:179		return 0;180	}181	if (ret)182		return ret;183 184	return nla_put_u8(msg, RDMA_NLDEV_ATTR_RES_TYPE, IB_QPT_DRIVER);185}186 187static int fill_res_qp_entry_raw(struct sk_buff *msg, struct ib_qp *ibqp)188{189	struct mlx5_ib_dev *dev = to_mdev(ibqp->device);190 191	return fill_res_raw(msg, dev, MLX5_SGMT_TYPE_PRM_QUERY_QP,192			    ibqp->qp_num);193}194 195static const struct ib_device_ops restrack_ops = {196	.fill_res_cq_entry_raw = fill_res_cq_entry_raw,197	.fill_res_mr_entry = fill_res_mr_entry,198	.fill_res_mr_entry_raw = fill_res_mr_entry_raw,199	.fill_res_qp_entry = fill_res_qp_entry,200	.fill_res_qp_entry_raw = fill_res_qp_entry_raw,201	.fill_stat_mr_entry = fill_stat_mr_entry,202};203 204int mlx5_ib_restrack_init(struct mlx5_ib_dev *dev)205{206	ib_set_device_ops(&dev->ib_dev, &restrack_ops);207	return 0;208}209