kiblnd_peer_decref(peer_ni);
}
+
+static void
+kiblnd_debug_rx(struct kib_rx *rx)
+{
+ CDEBUG(D_CONSOLE, " %p msg_type %x cred %d\n",
+ rx, rx->rx_msg->ibm_type,
+ rx->rx_msg->ibm_credits);
+}
+
+static void
+kiblnd_debug_tx(struct kib_tx *tx)
+{
+ CDEBUG(D_CONSOLE, " %p snd %d q %d w %d rc %d dl %lld "
+ "cookie %#llx msg %s%s type %x cred %d\n",
+ tx, tx->tx_sending, tx->tx_queued, tx->tx_waiting,
+ tx->tx_status, ktime_to_ns(tx->tx_deadline), tx->tx_cookie,
+ tx->tx_lntmsg[0] == NULL ? "-" : "!",
+ tx->tx_lntmsg[1] == NULL ? "-" : "!",
+ tx->tx_msg->ibm_type, tx->tx_msg->ibm_credits);
+}
+
+static void
+kiblnd_debug_conn(struct kib_conn *conn)
+{
+ struct list_head *tmp;
+ int i;
+
+ spin_lock(&conn->ibc_lock);
+
+ CDEBUG(D_CONSOLE, "conn[%d] %p [version %x] -> %s:\n",
+ atomic_read(&conn->ibc_refcount), conn,
+ conn->ibc_version, libcfs_nid2str(conn->ibc_peer->ibp_nid));
+ CDEBUG(D_CONSOLE, " state %d nposted %d/%d cred %d o_cred %d "
+ " r_cred %d\n", conn->ibc_state, conn->ibc_noops_posted,
+ conn->ibc_nsends_posted, conn->ibc_credits,
+ conn->ibc_outstanding_credits, conn->ibc_reserved_credits);
+ CDEBUG(D_CONSOLE, " comms_err %d\n", conn->ibc_comms_error);
+
+ CDEBUG(D_CONSOLE, " early_rxs:\n");
+ list_for_each(tmp, &conn->ibc_early_rxs)
+ kiblnd_debug_rx(list_entry(tmp, struct kib_rx, rx_list));
+
+ CDEBUG(D_CONSOLE, " tx_noops:\n");
+ list_for_each(tmp, &conn->ibc_tx_noops)
+ kiblnd_debug_tx(list_entry(tmp, struct kib_tx, tx_list));
+
+ CDEBUG(D_CONSOLE, " tx_queue_nocred:\n");
+ list_for_each(tmp, &conn->ibc_tx_queue_nocred)
+ kiblnd_debug_tx(list_entry(tmp, struct kib_tx, tx_list));
+
+ CDEBUG(D_CONSOLE, " tx_queue_rsrvd:\n");
+ list_for_each(tmp, &conn->ibc_tx_queue_rsrvd)
+ kiblnd_debug_tx(list_entry(tmp, struct kib_tx, tx_list));
+
+ CDEBUG(D_CONSOLE, " tx_queue:\n");
+ list_for_each(tmp, &conn->ibc_tx_queue)
+ kiblnd_debug_tx(list_entry(tmp, struct kib_tx, tx_list));
+
+ CDEBUG(D_CONSOLE, " active_txs:\n");
+ list_for_each(tmp, &conn->ibc_active_txs)
+ kiblnd_debug_tx(list_entry(tmp, struct kib_tx, tx_list));
+
+ CDEBUG(D_CONSOLE, " rxs:\n");
+ for (i = 0; i < IBLND_RX_MSGS(conn); i++)
+ kiblnd_debug_rx(&conn->ibc_rxs[i]);
+
+ spin_unlock(&conn->ibc_lock);
+}
+
+static void
+kiblnd_dump_peer_debug_info(struct kib_peer_ni *peer_ni)
+{
+ struct kib_conn *conn;
+ struct kib_conn *cnxt;
+ int count = 0;
+
+ CDEBUG(D_CONSOLE, "[last_alive, races, reconnected, error]: %lld, %d, %d, %d\n",
+ peer_ni->ibp_last_alive,
+ peer_ni->ibp_races,
+ peer_ni->ibp_reconnected,
+ peer_ni->ibp_error);
+ list_for_each_entry_safe(conn, cnxt, &peer_ni->ibp_conns,
+ ibc_list) {
+ CDEBUG(D_CONSOLE, "Conn %d:\n", count);
+ kiblnd_debug_conn(conn);
+ count++;
+ }
+}
+
+
static int
-kiblnd_get_peer_info(struct lnet_ni *ni, int index,
+kiblnd_get_peer_info(struct lnet_ni *ni, lnet_nid_t nid, int index,
lnet_nid_t *nidp, int *count)
{
struct kib_peer_ni *peer_ni;
for (i = 0; i < kiblnd_data.kib_peer_hash_size; i++) {
list_for_each(ptmp, &kiblnd_data.kib_peers[i]) {
-
peer_ni = list_entry(ptmp, struct kib_peer_ni, ibp_list);
LASSERT(!kiblnd_peer_idle(peer_ni));
if (peer_ni->ibp_ni != ni)
continue;
+ if (peer_ni->ibp_nid == nid)
+ kiblnd_dump_peer_debug_info(peer_ni);
+
if (index-- > 0)
continue;
}
static void
-kiblnd_debug_rx(struct kib_rx *rx)
-{
- CDEBUG(D_CONSOLE, " %p msg_type %x cred %d\n",
- rx, rx->rx_msg->ibm_type,
- rx->rx_msg->ibm_credits);
-}
-
-static void
-kiblnd_debug_tx(struct kib_tx *tx)
-{
- CDEBUG(D_CONSOLE, " %p snd %d q %d w %d rc %d dl %lld "
- "cookie %#llx msg %s%s type %x cred %d\n",
- tx, tx->tx_sending, tx->tx_queued, tx->tx_waiting,
- tx->tx_status, ktime_to_ns(tx->tx_deadline), tx->tx_cookie,
- tx->tx_lntmsg[0] == NULL ? "-" : "!",
- tx->tx_lntmsg[1] == NULL ? "-" : "!",
- tx->tx_msg->ibm_type, tx->tx_msg->ibm_credits);
-}
-
-void
-kiblnd_debug_conn(struct kib_conn *conn)
-{
- struct list_head *tmp;
- int i;
-
- spin_lock(&conn->ibc_lock);
-
- CDEBUG(D_CONSOLE, "conn[%d] %p [version %x] -> %s:\n",
- atomic_read(&conn->ibc_refcount), conn,
- conn->ibc_version, libcfs_nid2str(conn->ibc_peer->ibp_nid));
- CDEBUG(D_CONSOLE, " state %d nposted %d/%d cred %d o_cred %d "
- " r_cred %d\n", conn->ibc_state, conn->ibc_noops_posted,
- conn->ibc_nsends_posted, conn->ibc_credits,
- conn->ibc_outstanding_credits, conn->ibc_reserved_credits);
- CDEBUG(D_CONSOLE, " comms_err %d\n", conn->ibc_comms_error);
-
- CDEBUG(D_CONSOLE, " early_rxs:\n");
- list_for_each(tmp, &conn->ibc_early_rxs)
- kiblnd_debug_rx(list_entry(tmp, struct kib_rx, rx_list));
-
- CDEBUG(D_CONSOLE, " tx_noops:\n");
- list_for_each(tmp, &conn->ibc_tx_noops)
- kiblnd_debug_tx(list_entry(tmp, struct kib_tx, tx_list));
-
- CDEBUG(D_CONSOLE, " tx_queue_nocred:\n");
- list_for_each(tmp, &conn->ibc_tx_queue_nocred)
- kiblnd_debug_tx(list_entry(tmp, struct kib_tx, tx_list));
-
- CDEBUG(D_CONSOLE, " tx_queue_rsrvd:\n");
- list_for_each(tmp, &conn->ibc_tx_queue_rsrvd)
- kiblnd_debug_tx(list_entry(tmp, struct kib_tx, tx_list));
-
- CDEBUG(D_CONSOLE, " tx_queue:\n");
- list_for_each(tmp, &conn->ibc_tx_queue)
- kiblnd_debug_tx(list_entry(tmp, struct kib_tx, tx_list));
-
- CDEBUG(D_CONSOLE, " active_txs:\n");
- list_for_each(tmp, &conn->ibc_active_txs)
- kiblnd_debug_tx(list_entry(tmp, struct kib_tx, tx_list));
-
- CDEBUG(D_CONSOLE, " rxs:\n");
- for (i = 0; i < IBLND_RX_MSGS(conn); i++)
- kiblnd_debug_rx(&conn->ibc_rxs[i]);
-
- spin_unlock(&conn->ibc_lock);
-}
-
-static void
kiblnd_setup_mtu_locked(struct rdma_cm_id *cmid)
{
/* XXX There is no path record for iWARP, set by netdev->change_mtu? */
lnet_nid_t nid = 0;
int count = 0;
- rc = kiblnd_get_peer_info(ni, data->ioc_count,
+ rc = kiblnd_get_peer_info(ni, data->ioc_nid, data->ioc_count,
&nid, &count);
data->ioc_nid = nid;
data->ioc_count = count;
ksocknal_peer_decref(peer_ni);
}
+
+static void
+ksocknal_dump_peer_debug_info(struct ksock_peer_ni *peer_ni)
+{
+ struct ksock_conn *conn;
+ struct list_head *ctmp;
+ struct list_head *txtmp;
+ int ccount = 0;
+ int txcount = 0;
+
+ list_for_each(ctmp, &peer_ni->ksnp_conns) {
+ conn = list_entry(ctmp, struct ksock_conn, ksnc_list);
+
+ if (!list_empty(&conn->ksnc_tx_queue))
+ list_for_each(txtmp, &conn->ksnc_tx_queue) txcount++;
+
+ CDEBUG(D_CONSOLE, "Conn %d [type, closing, crefcnt, srefcnt]: %d, %d, %d, %d\n",
+ ccount,
+ conn->ksnc_type,
+ conn->ksnc_closing,
+ refcount_read(&conn->ksnc_conn_refcount),
+ refcount_read(&conn->ksnc_sock_refcount));
+ CDEBUG(D_CONSOLE, "Conn %d rx [scheduled, ready, state]: %d, %d, %d\n",
+ ccount,
+ conn->ksnc_rx_scheduled,
+ conn->ksnc_rx_ready,
+ conn->ksnc_rx_state);
+ CDEBUG(D_CONSOLE, "Conn %d tx [txqcnt, scheduled, last_post, ready, deadline]: %d, %d, %lld, %d, %lld\n",
+ ccount,
+ txcount,
+ conn->ksnc_tx_scheduled,
+ conn->ksnc_tx_last_post,
+ conn->ksnc_rx_ready,
+ conn->ksnc_rx_deadline);
+
+ if (conn->ksnc_scheduler)
+ CDEBUG(D_CONSOLE, "Conn %d sched [nconns, cpt]: %d, %d\n",
+ ccount,
+ conn->ksnc_scheduler->kss_nconns,
+ conn->ksnc_scheduler->kss_cpt);
+
+ txcount = 0;
+ ccount++;
+ }
+}
+
static int
ksocknal_get_peer_info(struct lnet_ni *ni, int index,
struct lnet_process_id *id, __u32 *myip, __u32 *peer_ip,
if (index-- > 0)
continue;
+ ksocknal_dump_peer_debug_info(peer_ni);
conn_cb = peer_ni->ksnp_conn_cb;
*id = peer_ni->ksnp_id;
static int jt_set_recovery_limit(int argc, char **argv);
static int jt_setup_mrrouting(int argc, char **argv);
static int jt_calc_cpt_of_nid(int argc, char **argv);
+static int jt_show_peer_debug_info(int argc, char **argv);
command_t cmd_list[] = {
{"lnet", jt_lnet, 0, "lnet {configure | unconfigure} [--all]"},
{"import", jt_import, 0, "import FILE.yaml"},
{"export", jt_export, 0, "export FILE.yaml"},
{"stats", jt_stats, 0, "stats {show | help}"},
- {"debug", jt_debug, 0, "debug recovery {local | peer}"},
+ {"debug", jt_debug, 0, "debug {recovery {local | peer} | peer}"},
{"global", jt_global, 0, "global {show | help}"},
{"peer", jt_peers, 0, "peer {add | del | show | list | set | help}"},
{"ping", jt_ping, 0, "ping nid,[nid,...]"},
{"recovery", jt_show_recovery, 0, "list recovery queues\n"
"\t--local : list local recovery queue\n"
"\t--peer : list peer recovery queue\n"},
+ {"peer", jt_show_peer_debug_info, 0, "show peer debug info\n"
+ "\t--nid: peer's NID\n"},
{ 0, 0, 0, NULL }
};
{
int rc, opt;
struct cYAML *err_rc = NULL, *show_rc = NULL;
-
const char *const short_options = "lp";
static const struct option long_options[] = {
{ .name = "local", .has_arg = no_argument, .val = 'l' },
{ .name = "peer", .has_arg = no_argument, .val = 'p' },
{ .name = NULL } };
- rc = check_cmd(debug_cmds, "recovery", NULL, 0, argc, argv);
+ rc = check_cmd(debug_cmds, "debug", "recovery", 0, argc, argv);
if (rc)
return rc;
return rc;
}
+static int jt_show_peer_debug_info(int argc, char **argv)
+{
+ int rc, opt;
+ struct cYAML *err_rc = NULL;
+ char *peer_nid = optarg;
+ const char *const short_opts = "k";
+ const struct option long_opts[] = {
+ { .name = "nid", .has_arg = required_argument, .val = 'k' },
+ { .name = NULL } };
+
+ rc = check_cmd(debug_cmds, "debug", "peer", 0, argc, argv);
+
+ if (rc)
+ return rc;
+
+ while ((opt = getopt_long(argc, argv, short_opts,
+ long_opts, NULL)) != -1) {
+ switch (opt) {
+ case 'k':
+ peer_nid = optarg;
+ break;
+ default:
+ return 0;
+ }
+ }
+
+ rc = lustre_lnet_show_peer_debug_info(peer_nid, -1, &err_rc);
+
+ if (rc != LUSTRE_CFG_RC_NO_ERR)
+ cYAML_print_tree2file(stderr, err_rc);
+
+ cYAML_free_tree(err_rc);
+
+ return rc;
+}
+
static int jt_show_net(int argc, char **argv)
{
char *network = NULL;
{
int rc;
- rc = check_cmd(debug_cmds, "recovery", NULL, 2, argc, argv);
+ rc = check_cmd(debug_cmds, "debug", NULL, 2, argc, argv);
if (rc)
return rc;