summaryrefslogtreecommitdiffstats
path: root/sys/dev/hyperv/vmbus
diff options
context:
space:
mode:
authorsephe <sephe@FreeBSD.org>2016-02-29 05:24:29 +0000
committersephe <sephe@FreeBSD.org>2016-02-29 05:24:29 +0000
commit8b886cf3a72e7ac9a7a9b625f43e0deb76ed2952 (patch)
tree8e930a6f2e9e13195b507c200f6e4d00dcc7eade /sys/dev/hyperv/vmbus
parent77e3b4f157e3cdacd1a05938fff6478f8da56d35 (diff)
downloadFreeBSD-src-8b886cf3a72e7ac9a7a9b625f43e0deb76ed2952.zip
FreeBSD-src-8b886cf3a72e7ac9a7a9b625f43e0deb76ed2952.tar.gz
hyperv/channel: Add debug sysctl nodes for channel indices
It would serve as a debug tool, if the shared buffer ring's indices stopped updating. Submitted by: HongJiang Zhang <honzhan microsoft com> Reviewed by: sephe, Jun Su <junsu microsoft com> Modified by: sephe MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D5402
Diffstat (limited to 'sys/dev/hyperv/vmbus')
-rw-r--r--sys/dev/hyperv/vmbus/hv_channel.c66
-rw-r--r--sys/dev/hyperv/vmbus/hv_ring_buffer.c42
-rw-r--r--sys/dev/hyperv/vmbus/hv_vmbus_priv.h8
3 files changed, 116 insertions, 0 deletions
diff --git a/sys/dev/hyperv/vmbus/hv_channel.c b/sys/dev/hyperv/vmbus/hv_channel.c
index 9f97530..fa37bd5 100644
--- a/sys/dev/hyperv/vmbus/hv_channel.c
+++ b/sys/dev/hyperv/vmbus/hv_channel.c
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mbuf.h>
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <sys/sysctl.h>
#include <machine/bus.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
@@ -80,6 +81,68 @@ vmbus_channel_set_event(hv_vmbus_channel *channel)
}
+static void
+hv_vmbus_channel_stat(hv_vmbus_channel* channel)
+{
+ device_t dev;
+ struct sysctl_oid *devch_sysctl;
+ struct sysctl_oid *devch_id_sysctl, *devch_sub_sysctl;
+ struct sysctl_oid *devch_id_in_sysctl, *devch_id_out_sysctl;
+ struct sysctl_ctx_list *ctx;
+ uint32_t ch_id;
+ uint16_t sub_ch_id;
+ char name[16];
+
+ hv_vmbus_channel* primary_ch = channel->primary_channel;
+
+ if (primary_ch == NULL) {
+ dev = channel->device->device;
+ ch_id = channel->offer_msg.child_rel_id;
+ } else {
+ dev = primary_ch->device->device;
+ ch_id = primary_ch->offer_msg.child_rel_id;
+ sub_ch_id = channel->offer_msg.offer.sub_channel_index;
+ }
+ ctx = device_get_sysctl_ctx(dev);
+ /* This creates dev.DEVNAME.DEVUNIT.channel tree */
+ devch_sysctl = SYSCTL_ADD_NODE(ctx,
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "channel", CTLFLAG_RD, 0, "");
+ /* This creates dev.DEVNAME.DEVUNIT.channel.CHANID tree */
+ snprintf(name, sizeof(name), "%d", ch_id);
+ devch_id_sysctl = SYSCTL_ADD_NODE(ctx,
+ SYSCTL_CHILDREN(devch_sysctl),
+ OID_AUTO, name, CTLFLAG_RD, 0, "");
+
+ if (primary_ch != NULL) {
+ devch_sub_sysctl = SYSCTL_ADD_NODE(ctx,
+ SYSCTL_CHILDREN(devch_id_sysctl),
+ OID_AUTO, "sub", CTLFLAG_RD, 0, "");
+ snprintf(name, sizeof(name), "%d", sub_ch_id);
+ devch_id_sysctl = SYSCTL_ADD_NODE(ctx,
+ SYSCTL_CHILDREN(devch_sub_sysctl),
+ OID_AUTO, name, CTLFLAG_RD, 0, "");
+ }
+
+ devch_id_in_sysctl = SYSCTL_ADD_NODE(ctx,
+ SYSCTL_CHILDREN(devch_id_sysctl),
+ OID_AUTO,
+ "in",
+ CTLFLAG_RD, 0, "");
+ devch_id_out_sysctl = SYSCTL_ADD_NODE(ctx,
+ SYSCTL_CHILDREN(devch_id_sysctl),
+ OID_AUTO,
+ "out",
+ CTLFLAG_RD, 0, "");
+ hv_ring_buffer_stat(ctx,
+ SYSCTL_CHILDREN(devch_id_in_sysctl),
+ &(channel->inbound),
+ "inbound ring buffer stats");
+ hv_ring_buffer_stat(ctx,
+ SYSCTL_CHILDREN(devch_id_out_sysctl),
+ &(channel->outbound),
+ "outbound ring buffer stats");
+}
/**
* @brief Open the specified channel
*/
@@ -143,6 +206,9 @@ hv_vmbus_channel_open(
in,
recv_ring_buffer_size);
+ /* setup statistic tracking for this channel */
+ hv_vmbus_channel_stat(new_channel);
+
/**
* Establish the gpadl for the ring buffer
*/
diff --git a/sys/dev/hyperv/vmbus/hv_ring_buffer.c b/sys/dev/hyperv/vmbus/hv_ring_buffer.c
index 5e4f52a..765a693 100644
--- a/sys/dev/hyperv/vmbus/hv_ring_buffer.c
+++ b/sys/dev/hyperv/vmbus/hv_ring_buffer.c
@@ -30,6 +30,7 @@
#include <sys/param.h>
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <sys/sysctl.h>
#include "hv_vmbus_priv.h"
@@ -37,6 +38,47 @@
#define HV_BYTES_AVAIL_TO_WRITE(r, w, z) ((w) >= (r))? \
((z) - ((w) - (r))):((r) - (w))
+static int
+hv_rbi_sysctl_stats(SYSCTL_HANDLER_ARGS)
+{
+ hv_vmbus_ring_buffer_info* rbi;
+ uint32_t read_index, write_index, interrupt_mask, sz;
+ uint32_t read_avail, write_avail;
+ char rbi_stats[256];
+
+ rbi = (hv_vmbus_ring_buffer_info*)arg1;
+ read_index = rbi->ring_buffer->read_index;
+ write_index = rbi->ring_buffer->write_index;
+ interrupt_mask = rbi->ring_buffer->interrupt_mask;
+ sz = rbi->ring_data_size;
+ write_avail = HV_BYTES_AVAIL_TO_WRITE(read_index,
+ write_index, sz);
+ read_avail = sz - write_avail;
+ snprintf(rbi_stats, sizeof(rbi_stats),
+ "r_idx:%d "
+ "w_idx:%d "
+ "int_mask:%d "
+ "r_avail:%d "
+ "w_avail:%d",
+ read_index, write_index, interrupt_mask,
+ read_avail, write_avail);
+
+ return (sysctl_handle_string(oidp, rbi_stats,
+ sizeof(rbi_stats), req));
+}
+
+void
+hv_ring_buffer_stat(
+ struct sysctl_ctx_list *ctx,
+ struct sysctl_oid_list *tree_node,
+ hv_vmbus_ring_buffer_info *rbi,
+ const char *desc)
+{
+ SYSCTL_ADD_PROC(ctx, tree_node, OID_AUTO,
+ "ring_buffer_stats",
+ CTLTYPE_STRING|CTLFLAG_RD, rbi, 0,
+ hv_rbi_sysctl_stats, "A", desc);
+}
/**
* @brief Get number of bytes available to read and to write to
* for the specified ring buffer
diff --git a/sys/dev/hyperv/vmbus/hv_vmbus_priv.h b/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
index 5f62072..62fa22a 100644
--- a/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
+++ b/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
@@ -639,6 +639,14 @@ extern hv_vmbus_channel_msg_table_entry g_channel_message_table[];
/*
* Private, VM Bus functions
*/
+struct sysctl_ctx_list;
+struct sysctl_oid_list;
+
+void hv_ring_buffer_stat(
+ struct sysctl_ctx_list *ctx,
+ struct sysctl_oid_list *tree_node,
+ hv_vmbus_ring_buffer_info *rbi,
+ const char *desc);
int hv_vmbus_ring_buffer_init(
hv_vmbus_ring_buffer_info *ring_info,
OpenPOWER on IntegriCloud