+ /*
+ * completion for the monitor thread. The monitor thread takes care of
+ * checking routes, timedout messages and resending messages.
+ */
+ struct completion ln_mt_wait_complete;
+
+ /* per-cpt resend queues */
+ struct list_head **ln_mt_resendqs;
+ /* local NIs to recover */
+ struct list_head ln_mt_localNIRecovq;
+ /* local NIs to recover */
+ struct list_head ln_mt_peerNIRecovq;
+ /*
+ * An array of queues for GET/PUT waiting for REPLY/ACK respectively.
+ * There are CPT number of queues. Since response trackers will be
+ * added on the fast path we can't afford to grab the exclusive
+ * net lock to protect these queues. The CPT will be calculated
+ * based on the mdh cookie.
+ */
+ struct list_head **ln_mt_rstq;
+ /*
+ * A response tracker becomes a zombie when the associated MD is queued
+ * for unlink before the response tracker is detached from the MD. An
+ * entry on a zombie list can be freed when either the remaining
+ * operations on the MD complete or when LNet has shut down.
+ */
+ struct list_head **ln_mt_zombie_rstqs;
+ /* recovery handler */
+ lnet_handler_t ln_mt_handler;
+
+ /*
+ * Completed when the discovery and monitor threads can enter their
+ * work loops
+ */
+ struct completion ln_started;
+ /* UDSP list */
+ struct list_head ln_udsp_list;
+};
+
+static const struct nla_policy scalar_attr_policy[LN_SCALAR_CNT + 1] = {
+ [LN_SCALAR_ATTR_LIST] = { .type = NLA_NESTED },
+ [LN_SCALAR_ATTR_LIST_SIZE] = { .type = NLA_U16 },
+ [LN_SCALAR_ATTR_INDEX] = { .type = NLA_U16 },
+ [LN_SCALAR_ATTR_NLA_TYPE] = { .type = NLA_U16 },
+ [LN_SCALAR_ATTR_VALUE] = { .type = NLA_STRING },
+ [LN_SCALAR_ATTR_KEY_FORMAT] = { .type = NLA_U16 },
+};
+
+int lnet_genl_send_scalar_list(struct sk_buff *msg, u32 portid, u32 seq,
+ const struct genl_family *family, int flags,
+ u8 cmd, const struct ln_key_list *data[]);
+
+/* Special workaround for pre-4.19 kernels to send error messages
+ * from dumpit routines. Newer kernels will send message with
+ * NL_SET_ERR_MSG information by default if NETLINK_EXT_ACK is set.
+ */
+static inline int lnet_nl_send_error(struct sk_buff *msg, int portid, int seq,
+ int error)
+{
+#ifndef HAVE_NL_DUMP_WITH_EXT_ACK
+ struct nlmsghdr *nlh;
+
+ if (!error)
+ return 0;
+
+ nlh = nlmsg_put(msg, portid, seq, NLMSG_ERROR, sizeof(error), 0);
+ if (!nlh)
+ return -ENOMEM;
+#ifdef HAVE_NL_PARSE_WITH_EXT_ACK
+ netlink_ack(msg, nlh, error, NULL);
+#else
+ netlink_ack(msg, nlh, error);
+#endif
+ return nlmsg_len(nlh);
+#else
+ return error;
+#endif
+}