Author: sephe
Date: Mon Feb 29 05:24:29 2016
New Revision: 296181
URL: https://svnweb.freebsd.org/changeset/base/296181

Log:
  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

Modified:
  head/sys/dev/hyperv/vmbus/hv_channel.c
  head/sys/dev/hyperv/vmbus/hv_ring_buffer.c
  head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h

Modified: head/sys/dev/hyperv/vmbus/hv_channel.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_channel.c      Mon Feb 29 04:58:40 2016        
(r296180)
+++ head/sys/dev/hyperv/vmbus/hv_channel.c      Mon Feb 29 05:24:29 2016        
(r296181)
@@ -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
 
 }
 
+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
         */

Modified: head/sys/dev/hyperv/vmbus/hv_ring_buffer.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_ring_buffer.c  Mon Feb 29 04:58:40 2016        
(r296180)
+++ head/sys/dev/hyperv/vmbus/hv_ring_buffer.c  Mon Feb 29 05:24:29 2016        
(r296181)
@@ -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

Modified: head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h   Mon Feb 29 04:58:40 2016        
(r296180)
+++ head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h   Mon Feb 29 05:24:29 2016        
(r296181)
@@ -639,6 +639,14 @@ extern hv_vmbus_channel_msg_table_entry    
 /*
  * 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,
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to