1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2 /* 3 * Copyright (c) 2019, Mellanox Technologies inc. All rights reserved. 4 */ 5 6 #include <uapi/rdma/rdma_netlink.h> 7 #include <rdma/ib_umem_odp.h> 8 #include <rdma/restrack.h> 9 #include "mlx5_ib.h" 10 11 static int fill_stat_mr_entry(struct sk_buff *msg, 12 struct rdma_restrack_entry *res) 13 { 14 struct ib_mr *ibmr = container_of(res, struct ib_mr, res); 15 struct mlx5_ib_mr *mr = to_mmr(ibmr); 16 struct nlattr *table_attr; 17 18 if (!(mr->access_flags & IB_ACCESS_ON_DEMAND)) 19 return 0; 20 21 table_attr = nla_nest_start(msg, 22 RDMA_NLDEV_ATTR_STAT_HWCOUNTERS); 23 24 if (!table_attr) 25 goto err; 26 27 if (rdma_nl_stat_hwcounter_entry(msg, "page_faults", 28 atomic64_read(&mr->odp_stats.faults))) 29 goto err_table; 30 if (rdma_nl_stat_hwcounter_entry( 31 msg, "page_invalidations", 32 atomic64_read(&mr->odp_stats.invalidations))) 33 goto err_table; 34 35 nla_nest_end(msg, table_attr); 36 return 0; 37 38 err_table: 39 nla_nest_cancel(msg, table_attr); 40 err: 41 return -EMSGSIZE; 42 } 43 44 static int fill_res_mr_entry(struct sk_buff *msg, 45 struct rdma_restrack_entry *res) 46 { 47 struct ib_mr *ibmr = container_of(res, struct ib_mr, res); 48 struct mlx5_ib_mr *mr = to_mmr(ibmr); 49 struct nlattr *table_attr; 50 51 if (!(mr->access_flags & IB_ACCESS_ON_DEMAND)) 52 return 0; 53 54 table_attr = nla_nest_start(msg, RDMA_NLDEV_ATTR_DRIVER); 55 if (!table_attr) 56 goto err; 57 58 if (mr->is_odp_implicit) { 59 if (rdma_nl_put_driver_string(msg, "odp", "implicit")) 60 goto err; 61 } else { 62 if (rdma_nl_put_driver_string(msg, "odp", "explicit")) 63 goto err; 64 } 65 66 nla_nest_end(msg, table_attr); 67 return 0; 68 69 err: 70 nla_nest_cancel(msg, table_attr); 71 return -EMSGSIZE; 72 } 73 74 int mlx5_ib_fill_res_entry(struct sk_buff *msg, 75 struct rdma_restrack_entry *res) 76 { 77 if (res->type == RDMA_RESTRACK_MR) 78 return fill_res_mr_entry(msg, res); 79 80 return 0; 81 } 82 83 int mlx5_ib_fill_stat_entry(struct sk_buff *msg, 84 struct rdma_restrack_entry *res) 85 { 86 if (res->type == RDMA_RESTRACK_MR) 87 return fill_stat_mr_entry(msg, res); 88 89 return 0; 90 } 91