Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Jun 2016 05:57:07 +0000 (UTC)
From:      Sepherosa Ziehau <sephe@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r301915 - in stable/10/sys/dev/hyperv: netvsc vmbus
Message-ID:  <201606150557.u5F5v7kL010539@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sephe
Date: Wed Jun 15 05:57:06 2016
New Revision: 301915
URL: https://svnweb.freebsd.org/changeset/base/301915

Log:
  MFC 296181,296184,296187,296188,296252,296253,296289,296290
  
  296181
      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
  
  296184
      hyperv/hn: Switch to if_transmit by default after r296178
  
      MFC after:  1 week
      Sponsored by:       Microsoft OSTC
      Differential Revision:      https://reviews.freebsd.org/D5485
  
  296187
      hyperv/hn: Utilize mbuf flowid
  
      MFC after:  1 week
      Sponsored by:       Microsoft OSTC
      Differential Revision:      https://reviews.freebsd.org/D5488
  
  296188
      hyperv/channel: Add sysctl node for channel owner cpu
  
      And add sysctl node for sub-channel's channel id.
  
      MFC after:  1 week
      Sponsored by:       Microsoft OSTC
      Differential Revision:      https://reviews.freebsd.org/D5489
  
  296252
      hyperv/hn: Set hash per-packet-info for each packet transmission
  
      So that the host could dispatch the TX done back to this TX ring's
      owner channel
  
      MFC after:  1 week
      Sponsored by:       Microsoft OSTC
      Differential Revision:      https://reviews.freebsd.org/D5498
  
  296253
      hyperv/channel: Nuke useless stack variable
  
      MFC after:  1 week
      Sponsored by:       Microsoft OSTC
      Differential Revision:      https://reviews.freebsd.org/D5499
  
  296289
      hyperv/chan: Add sysctl node to check whether monitor is allocated or not
  
      MFC after:  1 week
      Sponsored by:       Microsoft OSTC
      Differential Revision:      https://reviews.freebsd.org/D5502
  
  296290
      hyperv/chan: Function renaming; no functional change
  
      The renamed function create a sysctl tree for channel, and many
      non-statistics nodes exists, so don't claim it only adds sysctl
      nodes for statistics.
  
      MFC after:  1 week
      Sponsored by:       Microsoft OSTC
      Differential Revision:      https://reviews.freebsd.org/D5503

Modified:
  stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h
  stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
  stable/10/sys/dev/hyperv/netvsc/hv_rndis.h
  stable/10/sys/dev/hyperv/vmbus/hv_channel.c
  stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c
  stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h	Wed Jun 15 05:31:35 2016	(r301914)
+++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h	Wed Jun 15 05:57:06 2016	(r301915)
@@ -1000,10 +1000,11 @@ struct buf_ring;
 
 struct hn_rx_ring {
 	struct ifnet	*hn_ifp;
-	struct lro_ctrl	hn_lro;
+	int		hn_rx_idx;
 
 	/* Trust csum verification on host side */
 	int		hn_trust_hcsum;	/* HN_TRUST_HCSUM_ */
+	struct lro_ctrl	hn_lro;
 
 	u_long		hn_csum_ip;
 	u_long		hn_csum_tcp;
@@ -1038,6 +1039,7 @@ struct hn_tx_ring {
 
 	struct buf_ring	*hn_mbuf_br;
 	int		hn_oactive;
+	int		hn_tx_idx;
 
 	struct mtx	hn_tx_lock;
 	struct hn_softc	*hn_sc;

Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c	Wed Jun 15 05:31:35 2016	(r301914)
+++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c	Wed Jun 15 05:57:06 2016	(r301915)
@@ -140,6 +140,7 @@ __FBSDID("$FreeBSD$");
 
 #define HN_RNDIS_MSG_LEN		\
     (sizeof(rndis_msg) +		\
+     RNDIS_HASH_PPI_SIZE +		\
      RNDIS_VLAN_PPI_SIZE +		\
      RNDIS_TSO_PPI_SIZE +		\
      RNDIS_CSUM_PPI_SIZE)
@@ -276,7 +277,7 @@ static int hn_bind_tx_taskq = -1;
 SYSCTL_INT(_hw_hn, OID_AUTO, bind_tx_taskq, CTLFLAG_RDTUN,
     &hn_bind_tx_taskq, 0, "Bind TX taskqueue to the specified cpu");
 
-static int hn_use_if_start = 1;
+static int hn_use_if_start = 0;
 SYSCTL_INT(_hw_hn, OID_AUTO, use_if_start, CTLFLAG_RDTUN,
     &hn_use_if_start, 0, "Use if_start TX method");
 
@@ -757,6 +758,7 @@ hn_encap(struct hn_tx_ring *txr, struct 
 	rndis_msg *rndis_mesg;
 	rndis_packet *rndis_pkt;
 	rndis_per_packet_info *rppi;
+	struct ndis_hash_info *hash_info;
 	uint32_t rndis_msg_size;
 
 	packet = &txd->netvsc_pkt;
@@ -781,6 +783,18 @@ hn_encap(struct hn_tx_ring *txr, struct 
 
 	rndis_msg_size = RNDIS_MESSAGE_SIZE(rndis_packet);
 
+	/*
+	 * Set the hash info for this packet, so that the host could
+	 * dispatch the TX done event for this packet back to this TX
+	 * ring's channel.
+	 */
+	rndis_msg_size += RNDIS_HASH_PPI_SIZE;
+	rppi = hv_set_rppi_data(rndis_mesg, RNDIS_HASH_PPI_SIZE,
+	    nbl_hash_value);
+	hash_info = (struct ndis_hash_info *)((uint8_t *)rppi +
+	    rppi->per_packet_info_offset);
+	hash_info->hash = txr->hn_tx_idx;
+
 	if (m_head->m_flags & M_VLANTAG) {
 		ndis_8021q_info *rppi_vlan_info;
 
@@ -1307,6 +1321,9 @@ skip:
 		m_new->m_flags |= M_VLANTAG;
 	}
 
+	m_new->m_pkthdr.flowid = rxr->hn_rx_idx;
+	M_HASHTYPE_SET(m_new, M_HASHTYPE_OPAQUE);
+
 	/*
 	 * Note:  Moved RX completion back to hv_nv_on_receive() so all
 	 * messages (not just data messages) will trigger a response.
@@ -2085,6 +2102,7 @@ hn_create_rx_data(struct hn_softc *sc)
 		if (hn_trust_hostip)
 			rxr->hn_trust_hcsum |= HN_TRUST_HCSUM_IP;
 		rxr->hn_ifp = sc->hn_ifp;
+		rxr->hn_rx_idx = i;
 
 		/*
 		 * Initialize LRO.
@@ -2202,6 +2220,7 @@ hn_create_tx_ring(struct hn_softc *sc, i
 	int error, i;
 
 	txr->hn_sc = sc;
+	txr->hn_tx_idx = id;
 
 #ifndef HN_USE_TXDESC_BUFRING
 	mtx_init(&txr->hn_txlist_spin, "hn txlist", NULL, MTX_SPIN);
@@ -2625,10 +2644,14 @@ hn_transmit(struct ifnet *ifp, struct mb
 {
 	struct hn_softc *sc = ifp->if_softc;
 	struct hn_tx_ring *txr;
-	int error;
+	int error, idx = 0;
 
-	/* TODO: vRSS, TX ring selection */
-	txr = &sc->hn_tx_ring[0];
+	/*
+	 * Select the TX ring based on flowid
+	 */
+	if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE)
+		idx = m->m_pkthdr.flowid % sc->hn_tx_ring_cnt;
+	txr = &sc->hn_tx_ring[idx];
 
 	error = drbr_enqueue(ifp, txr->hn_mbuf_br, m);
 	if (error)

Modified: stable/10/sys/dev/hyperv/netvsc/hv_rndis.h
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hv_rndis.h	Wed Jun 15 05:31:35 2016	(r301914)
+++ stable/10/sys/dev/hyperv/netvsc/hv_rndis.h	Wed Jun 15 05:57:06 2016	(r301915)
@@ -608,6 +608,8 @@ typedef enum ndis_per_pkt_infotype_ {
 	max_perpkt_info
 } ndis_per_pkt_infotype;
 
+#define nbl_hash_value	pkt_cancel_id
+
 typedef struct ndis_8021q_info_ {
 	union {
 		struct {
@@ -620,6 +622,10 @@ typedef struct ndis_8021q_info_ {
 	} u1;
 } ndis_8021q_info;
 
+struct ndis_hash_info {
+	uint32_t	hash;
+} __packed;
+
 struct rndis_object_header {
 	uint8_t type;
 	uint8_t revision;
@@ -713,6 +719,9 @@ typedef struct rndis_tcp_tso_info_ {
 	};
 } rndis_tcp_tso_info;
 
+#define RNDIS_HASH_PPI_SIZE	(sizeof(rndis_per_packet_info) + \
+				sizeof(struct ndis_hash_info))
+
 #define RNDIS_VLAN_PPI_SIZE	(sizeof(rndis_per_packet_info) + \
 				sizeof(ndis_8021q_info))
 

Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_channel.c	Wed Jun 15 05:31:35 2016	(r301914)
+++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c	Wed Jun 15 05:57:06 2016	(r301915)
@@ -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,90 @@ vmbus_channel_set_event(hv_vmbus_channel
 
 }
 
+static int
+vmbus_channel_sysctl_monalloc(SYSCTL_HANDLER_ARGS)
+{
+	struct hv_vmbus_channel *chan = arg1;
+	int alloc = 0;
+
+	if (chan->offer_msg.monitor_allocated)
+		alloc = 1;
+	return sysctl_handle_int(oidp, &alloc, 0, req);
+}
+
+static void
+vmbus_channel_sysctl_create(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, "");
+
+		SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(devch_id_sysctl),
+		    OID_AUTO, "chanid", CTLFLAG_RD,
+		    &channel->offer_msg.child_rel_id, 0, "channel id");
+	}
+	SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(devch_id_sysctl), OID_AUTO,
+	    "cpu", CTLFLAG_RD, &channel->target_cpu, 0, "owner CPU id");
+	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(devch_id_sysctl), OID_AUTO,
+	    "monitor_allocated", CTLTYPE_INT | CTLFLAG_RD, channel, 0,
+	    vmbus_channel_sysctl_monalloc, "I",
+	    "is monitor allocated to this channel");
+
+	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 +228,9 @@ hv_vmbus_channel_open(
 		in,
 		recv_ring_buffer_size);
 
+	/* Create sysctl tree for this channel */
+	vmbus_channel_sysctl_create(new_channel);
+
 	/**
 	 * Establish the gpadl for the ring buffer
 	 */
@@ -856,7 +944,6 @@ hv_vmbus_channel_recv_packet_raw(
 {
 	int		ret;
 	uint32_t	packetLen;
-	uint32_t	userLen;
 	hv_vm_packet_descriptor	desc;
 
 	*buffer_actual_len = 0;
@@ -870,8 +957,6 @@ hv_vmbus_channel_recv_packet_raw(
 	    return (0);
 
 	packetLen = desc.length8 << 3;
-	userLen = packetLen - (desc.data_offset8 << 3);
-
 	*buffer_actual_len = packetLen;
 
 	if (packetLen > buffer_len)

Modified: stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c	Wed Jun 15 05:31:35 2016	(r301914)
+++ stable/10/sys/dev/hyperv/vmbus/hv_ring_buffer.c	Wed Jun 15 05:57:06 2016	(r301915)
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
+#include <sys/sysctl.h>
 
 #include "hv_vmbus_priv.h"
 
@@ -39,6 +40,47 @@ __FBSDID("$FreeBSD$");
 #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: stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h	Wed Jun 15 05:31:35 2016	(r301914)
+++ stable/10/sys/dev/hyperv/vmbus/hv_vmbus_priv.h	Wed Jun 15 05:57:06 2016	(r301915)
@@ -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,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201606150557.u5F5v7kL010539>