1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
4 * Authors: Leon Romanovsky <leonro@mellanox.com>
10 static const char *path_mig_to_str(uint8_t idx
)
12 static const char *const path_mig_str
[] = { "MIGRATED", "REARM",
15 if (idx
< ARRAY_SIZE(path_mig_str
))
16 return path_mig_str
[idx
];
20 static const char *qp_states_to_str(uint8_t idx
)
22 static const char *const qp_states_str
[] = { "RESET", "INIT", "RTR",
26 if (idx
< ARRAY_SIZE(qp_states_str
))
27 return qp_states_str
[idx
];
31 static void print_rqpn(struct rd
*rd
, uint32_t val
, struct nlattr
**nla_line
)
33 if (!nla_line
[RDMA_NLDEV_ATTR_RES_RQPN
])
37 jsonw_uint_field(rd
->jw
, "rqpn", val
);
39 pr_out("rqpn %u ", val
);
42 static void print_type(struct rd
*rd
, uint32_t val
)
45 jsonw_string_field(rd
->jw
, "type", qp_types_to_str(val
));
47 pr_out("type %s ", qp_types_to_str(val
));
50 static void print_state(struct rd
*rd
, uint32_t val
)
53 jsonw_string_field(rd
->jw
, "state", qp_states_to_str(val
));
55 pr_out("state %s ", qp_states_to_str(val
));
58 static void print_rqpsn(struct rd
*rd
, uint32_t val
, struct nlattr
**nla_line
)
60 if (!nla_line
[RDMA_NLDEV_ATTR_RES_RQ_PSN
])
64 jsonw_uint_field(rd
->jw
, "rq-psn", val
);
66 pr_out("rq-psn %u ", val
);
69 static void print_pathmig(struct rd
*rd
, uint32_t val
, struct nlattr
**nla_line
)
71 if (!nla_line
[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE
])
75 jsonw_string_field(rd
->jw
, "path-mig-state",
76 path_mig_to_str(val
));
78 pr_out("path-mig-state %s ", path_mig_to_str(val
));
81 static int res_qp_line(struct rd
*rd
, const char *name
, int idx
,
82 struct nlattr
*nla_entry
)
84 struct nlattr
*nla_line
[RDMA_NLDEV_ATTR_MAX
] = {};
85 uint32_t lqpn
, rqpn
= 0, rq_psn
= 0, sq_psn
;
86 uint8_t type
, state
, path_mig_state
= 0;
87 uint32_t port
= 0, pid
= 0;
92 err
= mnl_attr_parse_nested(nla_entry
, rd_attr_cb
, nla_line
);
96 if (!nla_line
[RDMA_NLDEV_ATTR_RES_LQPN
] ||
97 !nla_line
[RDMA_NLDEV_ATTR_RES_SQ_PSN
] ||
98 !nla_line
[RDMA_NLDEV_ATTR_RES_TYPE
] ||
99 !nla_line
[RDMA_NLDEV_ATTR_RES_STATE
] ||
100 (!nla_line
[RDMA_NLDEV_ATTR_RES_PID
] &&
101 !nla_line
[RDMA_NLDEV_ATTR_RES_KERN_NAME
])) {
105 if (nla_line
[RDMA_NLDEV_ATTR_PORT_INDEX
])
106 port
= mnl_attr_get_u32(nla_line
[RDMA_NLDEV_ATTR_PORT_INDEX
]);
108 if (port
!= rd
->port_idx
)
111 lqpn
= mnl_attr_get_u32(nla_line
[RDMA_NLDEV_ATTR_RES_LQPN
]);
112 if (rd_check_is_filtered(rd
, "lqpn", lqpn
))
115 if (nla_line
[RDMA_NLDEV_ATTR_RES_PDN
])
116 pdn
= mnl_attr_get_u32(nla_line
[RDMA_NLDEV_ATTR_RES_PDN
]);
117 if (rd_check_is_filtered(rd
, "pdn", pdn
))
120 if (nla_line
[RDMA_NLDEV_ATTR_RES_RQPN
]) {
121 rqpn
= mnl_attr_get_u32(nla_line
[RDMA_NLDEV_ATTR_RES_RQPN
]);
122 if (rd_check_is_filtered(rd
, "rqpn", rqpn
))
125 if (rd_check_is_key_exist(rd
, "rqpn"))
129 if (nla_line
[RDMA_NLDEV_ATTR_RES_RQ_PSN
]) {
130 rq_psn
= mnl_attr_get_u32(nla_line
[RDMA_NLDEV_ATTR_RES_RQ_PSN
]);
131 if (rd_check_is_filtered(rd
, "rq-psn", rq_psn
))
134 if (rd_check_is_key_exist(rd
, "rq-psn"))
138 sq_psn
= mnl_attr_get_u32(nla_line
[RDMA_NLDEV_ATTR_RES_SQ_PSN
]);
139 if (rd_check_is_filtered(rd
, "sq-psn", sq_psn
))
142 if (nla_line
[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE
]) {
143 path_mig_state
= mnl_attr_get_u8(
144 nla_line
[RDMA_NLDEV_ATTR_RES_PATH_MIG_STATE
]);
145 if (rd_check_is_string_filtered(rd
, "path-mig-state",
146 path_mig_to_str(path_mig_state
)))
149 if (rd_check_is_key_exist(rd
, "path-mig-state"))
153 type
= mnl_attr_get_u8(nla_line
[RDMA_NLDEV_ATTR_RES_TYPE
]);
154 if (rd_check_is_string_filtered(rd
, "type", qp_types_to_str(type
)))
157 state
= mnl_attr_get_u8(nla_line
[RDMA_NLDEV_ATTR_RES_STATE
]);
158 if (rd_check_is_string_filtered(rd
, "state", qp_states_to_str(state
)))
161 if (nla_line
[RDMA_NLDEV_ATTR_RES_PID
]) {
162 pid
= mnl_attr_get_u32(nla_line
[RDMA_NLDEV_ATTR_RES_PID
]);
163 comm
= get_task_name(pid
);
166 if (rd_check_is_filtered(rd
, "pid", pid
))
169 if (nla_line
[RDMA_NLDEV_ATTR_RES_KERN_NAME
])
170 /* discard const from mnl_attr_get_str */
171 comm
= (char *)mnl_attr_get_str(
172 nla_line
[RDMA_NLDEV_ATTR_RES_KERN_NAME
]);
175 jsonw_start_array(rd
->jw
);
177 print_link(rd
, idx
, name
, port
, nla_line
);
179 res_print_uint(rd
, "lqpn", lqpn
, nla_line
[RDMA_NLDEV_ATTR_RES_LQPN
]);
180 print_rqpn(rd
, rqpn
, nla_line
);
182 print_type(rd
, type
);
183 print_state(rd
, state
);
185 print_rqpsn(rd
, rq_psn
, nla_line
);
186 res_print_uint(rd
, "sq-psn", sq_psn
,
187 nla_line
[RDMA_NLDEV_ATTR_RES_SQ_PSN
]);
189 print_pathmig(rd
, path_mig_state
, nla_line
);
190 res_print_uint(rd
, "pdn", pdn
, nla_line
[RDMA_NLDEV_ATTR_RES_PDN
]);
191 res_print_uint(rd
, "pid", pid
, nla_line
[RDMA_NLDEV_ATTR_RES_PID
]);
192 print_comm(rd
, comm
, nla_line
);
194 print_driver_table(rd
, nla_line
[RDMA_NLDEV_ATTR_DRIVER
]);
197 if (nla_line
[RDMA_NLDEV_ATTR_RES_PID
])
202 int res_qp_parse_cb(const struct nlmsghdr
*nlh
, void *data
)
204 struct nlattr
*tb
[RDMA_NLDEV_ATTR_MAX
] = {};
205 struct nlattr
*nla_table
, *nla_entry
;
206 struct rd
*rd
= data
;
211 mnl_attr_parse(nlh
, 0, rd_attr_cb
, tb
);
212 if (!tb
[RDMA_NLDEV_ATTR_DEV_INDEX
] || !tb
[RDMA_NLDEV_ATTR_DEV_NAME
] ||
213 !tb
[RDMA_NLDEV_ATTR_RES_QP
])
216 name
= mnl_attr_get_str(tb
[RDMA_NLDEV_ATTR_DEV_NAME
]);
217 idx
= mnl_attr_get_u32(tb
[RDMA_NLDEV_ATTR_DEV_INDEX
]);
218 nla_table
= tb
[RDMA_NLDEV_ATTR_RES_QP
];
220 mnl_attr_for_each_nested(nla_entry
, nla_table
) {
221 ret
= res_qp_line(rd
, name
, idx
, nla_entry
);
223 if (ret
!= MNL_CB_OK
)