svn commit: r301915 - in stable/10/sys/dev/hyperv: netvsc vmbus
Sepherosa Ziehau
sephe at FreeBSD.org
Wed Jun 15 05:57:08 UTC 2016
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,
More information about the svn-src-all
mailing list