diff options
Diffstat (limited to 'sys/dev/hyperv')
-rw-r--r-- | sys/dev/hyperv/vmbus/hv_channel.c | 66 | ||||
-rw-r--r-- | sys/dev/hyperv/vmbus/hv_ring_buffer.c | 42 | ||||
-rw-r--r-- | sys/dev/hyperv/vmbus/hv_vmbus_priv.h | 8 |
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, |