From ed052504713d1db49531454a87055b2ee54399f0 Mon Sep 17 00:00:00 2001 From: Amir Shehata Date: Thu, 2 Feb 2017 14:01:15 -0800 Subject: [PATCH] LU-9480 lnet: add enhanced statistics Added statistics to track the different types of LNet messages which are sent/received/dropped Test-Parameters: trivial Signed-off-by: Amir Shehata Signed-off-by: Olaf Weber Change-Id: I7e1fc991a56df20181f9e55a794765349a4d2cb9 Reviewed-on: https://review.whamcloud.com/25795 --- lnet/include/lnet/lib-lnet.h | 11 ++- lnet/include/lnet/lib-types.h | 20 ++++- lnet/include/uapi/linux/lnet/libcfs_ioctl.h | 3 +- lnet/lnet/api-ni.c | 47 +++++++++- lnet/lnet/lib-move.c | 113 +++++++++++++++++++++++-- lnet/lnet/lib-msg.c | 16 +++- lnet/lnet/net_fault.c | 3 +- lnet/lnet/peer.c | 32 ++++--- lnet/utils/lnetconfig/liblnetconfig.c | 127 +++++++++++++++++++++++++--- lnet/utils/lnetctl.c | 41 ++++++--- 10 files changed, 362 insertions(+), 51 deletions(-) diff --git a/lnet/include/lnet/lib-lnet.h b/lnet/include/lnet/lib-lnet.h index 7159bd5..8228e55 100644 --- a/lnet/include/lnet/lib-lnet.h +++ b/lnet/include/lnet/lib-lnet.h @@ -680,7 +680,7 @@ void lnet_set_reply_msg_len(struct lnet_ni *ni, struct lnet_msg *msg, void lnet_finalize(struct lnet_msg *msg, int rc); void lnet_drop_message(struct lnet_ni *ni, int cpt, void *private, - unsigned int nob); + unsigned int nob, __u32 msg_type); void lnet_drop_delayed_msg_list(struct list_head *head, char *reason); void lnet_recv_delayed_msg_list(struct list_head *head); @@ -984,4 +984,13 @@ lnet_peer_needs_push(struct lnet_peer *lp) return false; } +void lnet_incr_stats(struct lnet_element_stats *stats, lnet_msg_type_t msg_type, + enum lnet_stats_type stats_type); + +__u32 lnet_sum_stats(struct lnet_element_stats *stats, + enum lnet_stats_type stats_type); + +void lnet_usr_translate_stats(struct lnet_ioctl_element_msg_stats *msg_stats, + struct lnet_element_stats *stats); + #endif diff --git a/lnet/include/lnet/lib-types.h b/lnet/include/lnet/lib-types.h index e4cf950..7c7a9bd 100644 --- a/lnet/include/lnet/lib-types.h +++ b/lnet/include/lnet/lib-types.h @@ -294,10 +294,24 @@ enum lnet_ni_state { LNET_NI_STATE_DELETING }; +enum lnet_stats_type { + LNET_STATS_TYPE_SEND = 0, + LNET_STATS_TYPE_RECV, + LNET_STATS_TYPE_DROP +}; + +struct lnet_comm_count { + atomic_t co_get_count; + atomic_t co_put_count; + atomic_t co_reply_count; + atomic_t co_ack_count; + atomic_t co_hello_count; +}; + struct lnet_element_stats { - atomic_t send_count; - atomic_t recv_count; - atomic_t drop_count; + struct lnet_comm_count el_send_stats; + struct lnet_comm_count el_recv_stats; + struct lnet_comm_count el_drop_stats; }; struct lnet_net { diff --git a/lnet/include/uapi/linux/lnet/libcfs_ioctl.h b/lnet/include/uapi/linux/lnet/libcfs_ioctl.h index 5e81123..6fe78ca 100644 --- a/lnet/include/uapi/linux/lnet/libcfs_ioctl.h +++ b/lnet/include/uapi/linux/lnet/libcfs_ioctl.h @@ -146,7 +146,8 @@ struct libcfs_debug_ioctl_data { #define IOC_LIBCFS_SET_NUMA_RANGE _IOWR(IOC_LIBCFS_TYPE, 98, IOCTL_CONFIG_SIZE) #define IOC_LIBCFS_GET_NUMA_RANGE _IOWR(IOC_LIBCFS_TYPE, 99, IOCTL_CONFIG_SIZE) #define IOC_LIBCFS_GET_PEER_LIST _IOWR(IOC_LIBCFS_TYPE, 100, IOCTL_CONFIG_SIZE) -#define IOC_LIBCFS_MAX_NR 100 +#define IOC_LIBCFS_GET_LOCAL_NI_MSG_STATS _IOWR(IOC_LIBCFS_TYPE, 101, IOCTL_CONFIG_SIZE) +#define IOC_LIBCFS_MAX_NR 101 extern int libcfs_ioctl_data_adjust(struct libcfs_ioctl_data *data); diff --git a/lnet/lnet/api-ni.c b/lnet/lnet/api-ni.c index ad39363..63eeaca 100644 --- a/lnet/lnet/api-ni.c +++ b/lnet/lnet/api-ni.c @@ -2331,8 +2331,12 @@ lnet_fill_ni_info(struct lnet_ni *ni, struct lnet_ioctl_config_ni *cfg_ni, memcpy(&tun->lt_cmn, &ni->ni_net->net_tunables, sizeof(tun->lt_cmn)); if (stats) { - stats->iel_send_count = atomic_read(&ni->ni_stats.send_count); - stats->iel_recv_count = atomic_read(&ni->ni_stats.recv_count); + stats->iel_send_count = lnet_sum_stats(&ni->ni_stats, + LNET_STATS_TYPE_SEND); + stats->iel_recv_count = lnet_sum_stats(&ni->ni_stats, + LNET_STATS_TYPE_RECV); + stats->iel_drop_count = lnet_sum_stats(&ni->ni_stats, + LNET_STATS_TYPE_DROP); } /* @@ -2559,6 +2563,29 @@ lnet_get_ni_config(struct lnet_ioctl_config_ni *cfg_ni, return rc; } +int lnet_get_ni_stats(struct lnet_ioctl_element_msg_stats *msg_stats) +{ + struct lnet_ni *ni; + int cpt; + int rc = -ENOENT; + + if (!msg_stats) + return -EINVAL; + + cpt = lnet_net_lock_current(); + + ni = lnet_get_ni_idx_locked(msg_stats->im_idx); + + if (ni) { + lnet_usr_translate_stats(msg_stats, &ni->ni_stats); + rc = 0; + } + + lnet_net_unlock(cpt); + + return rc; +} + static int lnet_add_net_common(struct lnet_net *net, struct lnet_ioctl_config_lnd_tunables *tun) { @@ -3026,9 +3053,10 @@ LNetCtl(unsigned int cmd, void *arg) __u32 tun_size; cfg_ni = arg; + /* get the tunables if they are available */ if (cfg_ni->lic_cfg_hdr.ioc_len < - sizeof(*cfg_ni) + sizeof(*stats)+ sizeof(*tun)) + sizeof(*cfg_ni) + sizeof(*stats) + sizeof(*tun)) return -EINVAL; stats = (struct lnet_ioctl_element_stats *) @@ -3045,6 +3073,19 @@ LNetCtl(unsigned int cmd, void *arg) return rc; } + case IOC_LIBCFS_GET_LOCAL_NI_MSG_STATS: { + struct lnet_ioctl_element_msg_stats *msg_stats = arg; + + if (msg_stats->im_hdr.ioc_len != sizeof(*msg_stats)) + return -EINVAL; + + mutex_lock(&the_lnet.ln_api_mutex); + rc = lnet_get_ni_stats(msg_stats); + mutex_unlock(&the_lnet.ln_api_mutex); + + return rc; + } + case IOC_LIBCFS_GET_NET: { size_t total = sizeof(*config) + sizeof(struct lnet_ioctl_net_config); diff --git a/lnet/lnet/lib-move.c b/lnet/lnet/lib-move.c index e9b7953..7309d43 100644 --- a/lnet/lnet/lib-move.c +++ b/lnet/lnet/lib-move.c @@ -44,6 +44,101 @@ static int local_nid_dist_zero = 1; module_param(local_nid_dist_zero, int, 0444); MODULE_PARM_DESC(local_nid_dist_zero, "Reserved"); +static inline struct lnet_comm_count * +get_stats_counts(struct lnet_element_stats *stats, + enum lnet_stats_type stats_type) +{ + switch (stats_type) { + case LNET_STATS_TYPE_SEND: + return &stats->el_send_stats; + case LNET_STATS_TYPE_RECV: + return &stats->el_recv_stats; + case LNET_STATS_TYPE_DROP: + return &stats->el_drop_stats; + default: + CERROR("Unknown stats type\n"); + } + + return NULL; +} + +void lnet_incr_stats(struct lnet_element_stats *stats, lnet_msg_type_t msg_type, + enum lnet_stats_type stats_type) +{ + struct lnet_comm_count *counts = get_stats_counts(stats, stats_type); + if (!counts) + return; + + switch (msg_type) { + case LNET_MSG_ACK: + atomic_inc(&counts->co_ack_count); + break; + case LNET_MSG_PUT: + atomic_inc(&counts->co_put_count); + break; + case LNET_MSG_GET: + atomic_inc(&counts->co_get_count); + break; + case LNET_MSG_REPLY: + atomic_inc(&counts->co_reply_count); + break; + case LNET_MSG_HELLO: + atomic_inc(&counts->co_hello_count); + break; + default: + CERROR("There is a BUG in the code. Unknown message type\n"); + break; + } +} + +__u32 lnet_sum_stats(struct lnet_element_stats *stats, + enum lnet_stats_type stats_type) +{ + struct lnet_comm_count *counts = get_stats_counts(stats, stats_type); + if (!counts) + return 0; + + return (atomic_read(&counts->co_ack_count) + + atomic_read(&counts->co_put_count) + + atomic_read(&counts->co_get_count) + + atomic_read(&counts->co_reply_count) + + atomic_read(&counts->co_hello_count)); +} + +static inline void assign_stats(struct lnet_ioctl_comm_count *msg_stats, + struct lnet_comm_count *counts) +{ + msg_stats->ico_get_count = atomic_read(&counts->co_get_count); + msg_stats->ico_put_count = atomic_read(&counts->co_put_count); + msg_stats->ico_reply_count = atomic_read(&counts->co_reply_count); + msg_stats->ico_ack_count = atomic_read(&counts->co_ack_count); + msg_stats->ico_hello_count = atomic_read(&counts->co_hello_count); +} + +void lnet_usr_translate_stats(struct lnet_ioctl_element_msg_stats *msg_stats, + struct lnet_element_stats *stats) +{ + struct lnet_comm_count *counts; + + LASSERT(msg_stats); + LASSERT(stats); + + counts = get_stats_counts(stats, LNET_STATS_TYPE_SEND); + if (!counts) + return; + assign_stats(&msg_stats->im_send_stats, counts); + + counts = get_stats_counts(stats, LNET_STATS_TYPE_RECV); + if (!counts) + return; + assign_stats(&msg_stats->im_recv_stats, counts); + + counts = get_stats_counts(stats, LNET_STATS_TYPE_DROP); + if (!counts) + return; + assign_stats(&msg_stats->im_drop_stats, counts); +} + int lnet_fail_nid(lnet_nid_t nid, unsigned int threshold) { @@ -824,9 +919,13 @@ lnet_post_send_locked(struct lnet_msg *msg, int do_send) the_lnet.ln_counters[cpt]->drop_length += msg->msg_len; lnet_net_unlock(cpt); if (msg->msg_txpeer) - atomic_inc(&msg->msg_txpeer->lpni_stats.drop_count); + lnet_incr_stats(&msg->msg_txpeer->lpni_stats, + msg->msg_type, + LNET_STATS_TYPE_DROP); if (msg->msg_txni) - atomic_inc(&msg->msg_txni->ni_stats.drop_count); + lnet_incr_stats(&msg->msg_txni->ni_stats, + msg->msg_type, + LNET_STATS_TYPE_DROP); CNETERR("Dropping message for %s: peer not alive\n", libcfs_id2str(msg->msg_target)); @@ -2040,9 +2139,11 @@ lnet_send(lnet_nid_t src_nid, struct lnet_msg *msg, lnet_nid_t rtr_nid) } void -lnet_drop_message(struct lnet_ni *ni, int cpt, void *private, unsigned int nob) +lnet_drop_message(struct lnet_ni *ni, int cpt, void *private, unsigned int nob, + __u32 msg_type) { lnet_net_lock(cpt); + lnet_incr_stats(&ni->ni_stats, msg_type, LNET_STATS_TYPE_DROP); the_lnet.ln_counters[cpt]->drop_count++; the_lnet.ln_counters[cpt]->drop_length += nob; lnet_net_unlock(cpt); @@ -2699,7 +2800,7 @@ lnet_parse(struct lnet_ni *ni, struct lnet_hdr *hdr, lnet_nid_t from_nid, lnet_finalize(msg, rc); drop: - lnet_drop_message(ni, cpt, private, payload_length); + lnet_drop_message(ni, cpt, private, payload_length, type); return 0; } EXPORT_SYMBOL(lnet_parse); @@ -2735,7 +2836,8 @@ lnet_drop_delayed_msg_list(struct list_head *head, char *reason) * until that's done */ lnet_drop_message(msg->msg_rxni, msg->msg_rx_cpt, - msg->msg_private, msg->msg_len); + msg->msg_private, msg->msg_len, + msg->msg_type); /* * NB: message will not generate event because w/o attached MD, * but we still should give error code so lnet_msg_decommit() @@ -2975,6 +3077,7 @@ lnet_create_reply_msg(struct lnet_ni *ni, struct lnet_msg *getmsg) cpt = lnet_cpt_of_nid(peer_id.nid, ni); lnet_net_lock(cpt); + lnet_incr_stats(&ni->ni_stats, LNET_MSG_GET, LNET_STATS_TYPE_DROP); the_lnet.ln_counters[cpt]->drop_count++; the_lnet.ln_counters[cpt]->drop_length += getmd->md_length; lnet_net_unlock(cpt); diff --git a/lnet/lnet/lib-msg.c b/lnet/lnet/lib-msg.c index 736bea1..069bb71 100644 --- a/lnet/lnet/lib-msg.c +++ b/lnet/lnet/lib-msg.c @@ -219,9 +219,13 @@ lnet_msg_decommit_tx(struct lnet_msg *msg, int status) incr_stats: if (msg->msg_txpeer) - atomic_inc(&msg->msg_txpeer->lpni_stats.send_count); + lnet_incr_stats(&msg->msg_txpeer->lpni_stats, + msg->msg_type, + LNET_STATS_TYPE_SEND); if (msg->msg_txni) - atomic_inc(&msg->msg_txni->ni_stats.send_count); + lnet_incr_stats(&msg->msg_txni->ni_stats, + msg->msg_type, + LNET_STATS_TYPE_SEND); out: lnet_return_tx_credits_locked(msg); msg->msg_tx_committed = 0; @@ -276,9 +280,13 @@ lnet_msg_decommit_rx(struct lnet_msg *msg, int status) incr_stats: if (msg->msg_rxpeer) - atomic_inc(&msg->msg_rxpeer->lpni_stats.recv_count); + lnet_incr_stats(&msg->msg_rxpeer->lpni_stats, + msg->msg_type, + LNET_STATS_TYPE_RECV); if (msg->msg_rxni) - atomic_inc(&msg->msg_rxni->ni_stats.recv_count); + lnet_incr_stats(&msg->msg_rxni->ni_stats, + msg->msg_type, + LNET_STATS_TYPE_RECV); if (ev->type == LNET_EVENT_PUT || ev->type == LNET_EVENT_REPLY) counters->recv_length += msg->msg_wanted; diff --git a/lnet/lnet/net_fault.c b/lnet/lnet/net_fault.c index 0fe3947..89b1eb4 100644 --- a/lnet/lnet/net_fault.c +++ b/lnet/lnet/net_fault.c @@ -645,7 +645,8 @@ delayed_msg_process(struct list_head *msg_list, bool drop) } } - lnet_drop_message(ni, cpt, msg->msg_private, msg->msg_len); + lnet_drop_message(ni, cpt, msg->msg_private, msg->msg_len, + msg->msg_type); lnet_finalize(msg, rc); } } diff --git a/lnet/lnet/peer.c b/lnet/lnet/peer.c index 0a626fb..eb78fc7 100644 --- a/lnet/lnet/peer.c +++ b/lnet/lnet/peer.c @@ -3304,6 +3304,7 @@ int lnet_get_peer_info(lnet_nid_t *primary_nid, lnet_nid_t *nidp, void __user *bulk) { struct lnet_ioctl_element_stats *lpni_stats; + struct lnet_ioctl_element_msg_stats *lpni_msg_stats; struct lnet_peer_ni_credit_info *lpni_info; struct lnet_peer_ni *lpni; struct lnet_peer *lp; @@ -3318,7 +3319,8 @@ int lnet_get_peer_info(lnet_nid_t *primary_nid, lnet_nid_t *nidp, goto out; } - size = sizeof(nid) + sizeof(*lpni_info) + sizeof(*lpni_stats); + size = sizeof(nid) + sizeof(*lpni_info) + sizeof(*lpni_stats) + + sizeof(*lpni_msg_stats); size *= lp->lp_nnis; if (size > *sizep) { *sizep = size; @@ -3340,13 +3342,17 @@ int lnet_get_peer_info(lnet_nid_t *primary_nid, lnet_nid_t *nidp, LIBCFS_ALLOC(lpni_stats, sizeof(*lpni_stats)); if (!lpni_stats) goto out_free_info; + LIBCFS_ALLOC(lpni_msg_stats, sizeof(*lpni_msg_stats)); + if (!lpni_msg_stats) + goto out_free_stats; + lpni = NULL; rc = -EFAULT; while ((lpni = lnet_get_next_peer_ni_locked(lp, NULL, lpni)) != NULL) { nid = lpni->lpni_nid; if (copy_to_user(bulk, &nid, sizeof(nid))) - goto out_free_stats; + goto out_free_msg_stats; bulk += sizeof(nid); memset(lpni_info, 0, sizeof(*lpni_info)); @@ -3365,22 +3371,28 @@ int lnet_get_peer_info(lnet_nid_t *primary_nid, lnet_nid_t *nidp, lpni_info->cr_peer_min_tx_credits = lpni->lpni_mintxcredits; lpni_info->cr_peer_tx_qnob = lpni->lpni_txqnob; if (copy_to_user(bulk, lpni_info, sizeof(*lpni_info))) - goto out_free_stats; + goto out_free_msg_stats; bulk += sizeof(*lpni_info); memset(lpni_stats, 0, sizeof(*lpni_stats)); - lpni_stats->iel_send_count = - atomic_read(&lpni->lpni_stats.send_count); - lpni_stats->iel_recv_count = - atomic_read(&lpni->lpni_stats.recv_count); - lpni_stats->iel_drop_count = - atomic_read(&lpni->lpni_stats.drop_count); + lpni_stats->iel_send_count = lnet_sum_stats(&lpni->lpni_stats, + LNET_STATS_TYPE_SEND); + lpni_stats->iel_recv_count = lnet_sum_stats(&lpni->lpni_stats, + LNET_STATS_TYPE_RECV); + lpni_stats->iel_drop_count = lnet_sum_stats(&lpni->lpni_stats, + LNET_STATS_TYPE_DROP); if (copy_to_user(bulk, lpni_stats, sizeof(*lpni_stats))) - goto out_free_stats; + goto out_free_msg_stats; bulk += sizeof(*lpni_stats); + lnet_usr_translate_stats(lpni_msg_stats, &lpni->lpni_stats); + if (copy_to_user(bulk, lpni_msg_stats, sizeof(*lpni_msg_stats))) + goto out_free_msg_stats; + bulk += sizeof(*lpni_msg_stats); } rc = 0; +out_free_msg_stats: + LIBCFS_FREE(lpni_msg_stats, sizeof(*lpni_msg_stats)); out_free_stats: LIBCFS_FREE(lpni_stats, sizeof(*lpni_stats)); out_free_info: diff --git a/lnet/utils/lnetconfig/liblnetconfig.c b/lnet/utils/lnetconfig/liblnetconfig.c index 99ce6a8..f172698 100644 --- a/lnet/utils/lnetconfig/liblnetconfig.c +++ b/lnet/utils/lnetconfig/liblnetconfig.c @@ -63,6 +63,9 @@ #define modparam_path "/sys/module/lnet/parameters/" +const char *gmsg_stat_names[] = {"sent_stats", "received_stats", + "dropped_stats"}; + /* * lustre_lnet_ip_range_descr * Describes an IP range. @@ -1748,6 +1751,47 @@ out: return rc; } +static bool +add_msg_stats_to_yaml_blk(struct cYAML *yaml, + struct lnet_ioctl_comm_count *counts) +{ + if (cYAML_create_number(yaml, "put", + counts->ico_put_count) + == NULL) + return false; + if (cYAML_create_number(yaml, "get", + counts->ico_get_count) + == NULL) + return false; + if (cYAML_create_number(yaml, "reply", + counts->ico_reply_count) + == NULL) + return false; + if (cYAML_create_number(yaml, "ack", + counts->ico_ack_count) + == NULL) + return false; + if (cYAML_create_number(yaml, "hello", + counts->ico_hello_count) + == NULL) + return false; + + return true; +} + +static struct lnet_ioctl_comm_count * +get_counts(struct lnet_ioctl_element_msg_stats *msg_stats, int idx) +{ + if (idx == 0) + return &msg_stats->im_send_stats; + if (idx == 1) + return &msg_stats->im_recv_stats; + if (idx == 2) + return &msg_stats->im_drop_stats; + + return NULL; +} + int lustre_lnet_show_net(char *nw, int detail, int seq_no, struct cYAML **show_rc, struct cYAML **err_rc) { @@ -1755,6 +1799,7 @@ int lustre_lnet_show_net(char *nw, int detail, int seq_no, struct lnet_ioctl_config_ni *ni_data; struct lnet_ioctl_config_lnd_tunables *lnd; struct lnet_ioctl_element_stats *stats; + struct lnet_ioctl_element_msg_stats msg_stats; __u32 net = LNET_NIDNET(LNET_NID_ANY); __u32 prev_net = LNET_NIDNET(LNET_NID_ANY); int rc = LUSTRE_CFG_RC_OUT_OF_MEM, i, j; @@ -1891,6 +1936,7 @@ int lustre_lnet_show_net(char *nw, int detail, int seq_no, if (detail) { char *limit; + int k; statistics = cYAML_create_object(item, "statistics"); if (statistics == NULL) @@ -1911,6 +1957,40 @@ int lustre_lnet_show_net(char *nw, int detail, int seq_no, == NULL) goto out; + if (detail < 2) + goto continue_without_msg_stats; + + LIBCFS_IOC_INIT_V2(msg_stats, im_hdr); + msg_stats.im_hdr.ioc_len = sizeof(msg_stats); + msg_stats.im_idx = i; + + rc = l_ioctl(LNET_DEV_ID, + IOC_LIBCFS_GET_LOCAL_NI_MSG_STATS, + &msg_stats); + if (rc != 0) { + l_errno = errno; + goto continue_without_msg_stats; + } + + for (k = 0; k < 3; k++) { + struct lnet_ioctl_comm_count *counts; + struct cYAML *msg_statistics = NULL; + + msg_statistics = cYAML_create_object(item, + (char *)gmsg_stat_names[k]); + if (msg_statistics == NULL) + goto out; + + counts = get_counts(&msg_stats, k); + if (counts == NULL) + goto out; + + if (!add_msg_stats_to_yaml_blk(msg_statistics, + counts)) + goto out; + } + +continue_without_msg_stats: tunables = cYAML_create_object(item, "tunables"); if (!tunables) goto out; @@ -2308,15 +2388,16 @@ int lustre_lnet_show_peer(char *knid, int detail, int seq_no, struct lnet_ioctl_peer_cfg peer_info; struct lnet_peer_ni_credit_info *lpni_cri; struct lnet_ioctl_element_stats *lpni_stats; + struct lnet_ioctl_element_msg_stats *msg_stats; lnet_nid_t *nidp; int rc = LUSTRE_CFG_RC_OUT_OF_MEM; - int i; - int j; + int i, j, k; int l_errno = 0; __u32 count; __u32 size; struct cYAML *root = NULL, *peer = NULL, *peer_ni = NULL, - *first_seq = NULL, *peer_root = NULL, *tmp = NULL; + *first_seq = NULL, *peer_root = NULL, *tmp = NULL, + *msg_statistics = NULL, *statistics = NULL; char err_str[LNET_MAX_STR_LEN]; lnet_process_id_t *list = NULL; void *data = NULL; @@ -2441,7 +2522,8 @@ int lustre_lnet_show_peer(char *knid, int detail, int seq_no, nidp = lpni_data; lpni_cri = (void*)nidp + sizeof(nidp); lpni_stats = (void *)lpni_cri + sizeof(*lpni_cri); - lpni_data = (void *)lpni_stats + sizeof(*lpni_stats); + msg_stats = (void *)lpni_stats + sizeof(*lpni_stats); + lpni_data = (void *)msg_stats + sizeof(*msg_stats); peer_ni = cYAML_create_seq_item(tmp); if (peer_ni == NULL) @@ -2490,24 +2572,49 @@ int lustre_lnet_show_peer(char *knid, int detail, int seq_no, == NULL) goto out; - if (cYAML_create_number(peer_ni, "send_count", + if (cYAML_create_number(peer_ni, "refcount", + lpni_cri->cr_refcount) == NULL) + goto out; + + statistics = cYAML_create_object(peer_ni, "statistics"); + if (statistics == NULL) + goto out; + + if (cYAML_create_number(statistics, "send_count", lpni_stats->iel_send_count) == NULL) goto out; - if (cYAML_create_number(peer_ni, "recv_count", + if (cYAML_create_number(statistics, "recv_count", lpni_stats->iel_recv_count) == NULL) goto out; - if (cYAML_create_number(peer_ni, "drop_count", + if (cYAML_create_number(statistics, "drop_count", lpni_stats->iel_drop_count) == NULL) goto out; - if (cYAML_create_number(peer_ni, "refcount", - lpni_cri->cr_refcount) == NULL) - goto out; + if (detail < 2) + continue; + + for (k = 0; k < 3; k++) { + struct lnet_ioctl_comm_count *counts; + + msg_statistics = cYAML_create_object(peer_ni, + (char *) gmsg_stat_names[k]); + if (msg_statistics == NULL) + goto out; + + counts = get_counts(msg_stats, k); + if (counts == NULL) + goto out; + + if (!add_msg_stats_to_yaml_blk(msg_statistics, + counts)) + goto out; + } + } } diff --git a/lnet/utils/lnetctl.c b/lnet/utils/lnetctl.c index 252d8c4..947e5aa 100644 --- a/lnet/utils/lnetctl.c +++ b/lnet/utils/lnetctl.c @@ -101,7 +101,8 @@ command_t net_cmds[] = { "\t--if: physical interface (e.g. eth0)\n"}, {"show", jt_show_net, 0, "show networks\n" "\t--net: net name (e.g. tcp0) to filter on\n" - "\t--verbose: display detailed output per network\n"}, + "\t--verbose: display detailed output per network." + "optional argument of 2 outputs more stats\n"}, { 0, 0, 0, NULL } }; @@ -154,7 +155,8 @@ command_t peer_cmds[] = { "\t peer is deleted\n"}, {"show", jt_show_peer, 0, "show peer information\n" "\t--nid: NID of peer to filter on.\n" - "\t--verbose: Include extended statistics\n"}, + "\t--verbose: display detailed output per peer." + "optional argument of 2 outputs more stats\n"}, {"list", jt_list_peer, 0, "list all peers\n"}, { 0, 0, 0, NULL } }; @@ -801,13 +803,14 @@ static int jt_show_route(int argc, char **argv) static int jt_show_net(int argc, char **argv) { char *network = NULL; - int detail = 0, rc, opt; + int rc, opt; struct cYAML *err_rc = NULL, *show_rc = NULL; + long int detail = 0; const char *const short_options = "n:vh"; static const struct option long_options[] = { { .name = "net", .has_arg = required_argument, .val = 'n' }, - { .name = "verbose", .has_arg = no_argument, .val = 'v' }, + { .name = "verbose", .has_arg = optional_argument, .val = 'v' }, { .name = "help", .has_arg = no_argument, .val = 'h' }, { .name = NULL } }; @@ -818,7 +821,13 @@ static int jt_show_net(int argc, char **argv) network = optarg; break; case 'v': - detail = 1; + if ((!optarg) && (argv[optind] != NULL) && + (argv[optind][0] != '-')) { + if (parse_long(argv[optind++], &detail) != 0) + detail = 1; + } else { + detail = 1; + } break; case 'h': print_help(net_cmds, "net", "show"); @@ -828,7 +837,7 @@ static int jt_show_net(int argc, char **argv) } } - rc = lustre_lnet_show_net(network, detail, -1, &show_rc, &err_rc); + rc = lustre_lnet_show_net(network, (int) detail, -1, &show_rc, &err_rc); if (rc != LUSTRE_CFG_RC_NO_ERR) cYAML_print_tree2file(stderr, err_rc); @@ -1130,7 +1139,7 @@ static int jt_export(int argc, char **argv) } else f = stdout; - rc = lustre_lnet_show_net(NULL, 1, -1, &show_rc, &err_rc); + rc = lustre_lnet_show_net(NULL, 2, -1, &show_rc, &err_rc); if (rc != LUSTRE_CFG_RC_NO_ERR) { cYAML_print_tree2file(stderr, err_rc); cYAML_free_tree(err_rc); @@ -1152,7 +1161,7 @@ static int jt_export(int argc, char **argv) err_rc = NULL; } - rc = lustre_lnet_show_peer(NULL, 1, -1, &show_rc, &err_rc); + rc = lustre_lnet_show_peer(NULL, 2, -1, &show_rc, &err_rc); if (rc != LUSTRE_CFG_RC_NO_ERR) { cYAML_print_tree2file(stderr, err_rc); cYAML_free_tree(err_rc); @@ -1312,12 +1321,12 @@ static int jt_show_peer(int argc, char **argv) char *nid = NULL; int rc, opt; struct cYAML *err_rc = NULL, *show_rc = NULL; - int detail = 0; + long int detail = 0; - const char *const short_options = "n:vh"; + const char *const short_options = "n:v::h"; const struct option long_options[] = { { "nid", 1, NULL, 'n' }, - { "verbose", 0, NULL, 'v' }, + { "verbose", 2, NULL, 'v' }, { "help", 0, NULL, 'h' }, { NULL, 0, NULL, 0 }, }; @@ -1329,7 +1338,13 @@ static int jt_show_peer(int argc, char **argv) nid = optarg; break; case 'v': - detail = 1; + if ((!optarg) && (argv[optind] != NULL) && + (argv[optind][0] != '-')) { + if (parse_long(argv[optind++], &detail) != 0) + detail = 1; + } else { + detail = 1; + } break; case 'h': print_help(peer_cmds, "peer", "show"); @@ -1339,7 +1354,7 @@ static int jt_show_peer(int argc, char **argv) } } - rc = lustre_lnet_show_peer(nid, detail, -1, &show_rc, &err_rc); + rc = lustre_lnet_show_peer(nid, (int) detail, -1, &show_rc, &err_rc); if (rc != LUSTRE_CFG_RC_NO_ERR) cYAML_print_tree2file(stderr, err_rc); -- 1.8.3.1