Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 17 Oct 2016 03:27:23 +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-11@freebsd.org
Subject:   svn commit: r307462 - stable/11/sys/dev/hyperv/vmbus
Message-ID:  <201610170327.u9H3RNHM017027@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sephe
Date: Mon Oct 17 03:27:23 2016
New Revision: 307462
URL: https://svnweb.freebsd.org/changeset/base/307462

Log:
  MFC 303178,303180,303182
  
  303178
      hyperv/vmbus: Cosmetic bufring cleanup.
  
      Sponsored by:   Microsoft OSTC
      Differential Revision:  https://reviews.freebsd.org/D7267
  
  303180
      hyperv/vmbus: Cleanup and augment bufring sysctl tree creation
  
      Binary state node is added, so that userland programs do not have
      to parse human readable state string.
  
      Sponsored by:   Microsoft OSTC
      Differential Revision:  https://reviews.freebsd.org/D7268
  
  303182
      hyperv/vmbus: Move vmbus bufring definition to vmbus_reg.h
  
      And add more comment about its fields.
  
      Sponsored by:   Microsoft OSTC
      Differential Revision:  https://reviews.freebsd.org/D7269

Modified:
  stable/11/sys/dev/hyperv/vmbus/hv_ring_buffer.c
  stable/11/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
  stable/11/sys/dev/hyperv/vmbus/vmbus_chan.c
  stable/11/sys/dev/hyperv/vmbus/vmbus_chanvar.h
  stable/11/sys/dev/hyperv/vmbus/vmbus_reg.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/dev/hyperv/vmbus/hv_ring_buffer.c
==============================================================================
--- stable/11/sys/dev/hyperv/vmbus/hv_ring_buffer.c	Mon Oct 17 03:24:03 2016	(r307461)
+++ stable/11/sys/dev/hyperv/vmbus/hv_ring_buffer.c	Mon Oct 17 03:27:23 2016	(r307462)
@@ -26,123 +26,154 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-
 #include <sys/param.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
 #include <sys/sysctl.h>
 
 #include "hv_vmbus_priv.h"
+#include <dev/hyperv/vmbus/vmbus_reg.h>
 
 /* Amount of space to write to */
-#define	HV_BYTES_AVAIL_TO_WRITE(r, w, z) ((w) >= (r))? \
-				((z) - ((w) - (r))):((r) - (w))
+#define	HV_BYTES_AVAIL_TO_WRITE(r, w, z)	\
+	((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w))
+
+static uint32_t	copy_to_ring_buffer(hv_vmbus_ring_buffer_info *ring_info,
+		    uint32_t start_write_offset, const uint8_t *src,
+		    uint32_t src_len);
+static uint32_t copy_from_ring_buffer(hv_vmbus_ring_buffer_info *ring_info,
+		    char *dest, uint32_t dest_len, uint32_t start_read_offset);
 
 static int
-hv_rbi_sysctl_stats(SYSCTL_HANDLER_ARGS)
+vmbus_br_sysctl_state(SYSCTL_HANDLER_ARGS)
+{
+	const hv_vmbus_ring_buffer_info *br = arg1;
+	uint32_t rindex, windex, intr_mask, ravail, wavail;
+	char state[256];
+
+	rindex = br->ring_buffer->br_rindex;
+	windex = br->ring_buffer->br_windex;
+	intr_mask = br->ring_buffer->br_imask;
+	wavail = HV_BYTES_AVAIL_TO_WRITE(rindex, windex, br->ring_data_size);
+	ravail = br->ring_data_size - wavail;
+
+	snprintf(state, sizeof(state),
+	    "rindex:%u windex:%u intr_mask:%u ravail:%u wavail:%u",
+	    rindex, windex, intr_mask, ravail, wavail);
+	return sysctl_handle_string(oidp, state, sizeof(state), req);
+}
+
+/*
+ * Binary bufring states.
+ */
+static int
+vmbus_br_sysctl_state_bin(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);
+#define BR_STATE_RIDX	0
+#define BR_STATE_WIDX	1
+#define BR_STATE_IMSK	2
+#define BR_STATE_RSPC	3
+#define BR_STATE_WSPC	4
+#define BR_STATE_MAX	5
+
+	const hv_vmbus_ring_buffer_info *br = arg1;
+	uint32_t rindex, windex, wavail, state[BR_STATE_MAX];
+
+	rindex = br->ring_buffer->br_rindex;
+	windex = br->ring_buffer->br_windex;
+	wavail = HV_BYTES_AVAIL_TO_WRITE(rindex, windex, br->ring_data_size);
+
+	state[BR_STATE_RIDX] = rindex;
+	state[BR_STATE_WIDX] = windex;
+	state[BR_STATE_IMSK] = br->ring_buffer->br_imask;
+	state[BR_STATE_WSPC] = wavail;
+	state[BR_STATE_RSPC] = br->ring_data_size - wavail;
 
-	return (sysctl_handle_string(oidp, rbi_stats,
-			sizeof(rbi_stats), req));
+	return sysctl_handle_opaque(oidp, state, sizeof(state), 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|CTLFLAG_MPSAFE, rbi, 0,
-	    hv_rbi_sysctl_stats, "A", desc);
+vmbus_br_sysctl_create(struct sysctl_ctx_list *ctx, struct sysctl_oid *br_tree,
+    hv_vmbus_ring_buffer_info *br, const char *name)
+{
+	struct sysctl_oid *tree;
+	char desc[64];
+
+	tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(br_tree), OID_AUTO,
+	    name, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "");
+	if (tree == NULL)
+		return;
+
+	snprintf(desc, sizeof(desc), "%s state", name);
+	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "state",
+	    CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
+	    br, 0, vmbus_br_sysctl_state, "A", desc);
+
+	snprintf(desc, sizeof(desc), "%s binary state", name);
+	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "state_bin",
+	    CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE,
+	    br, 0, vmbus_br_sysctl_state_bin, "IU", desc);
 }
+
 /**
  * @brief Get number of bytes available to read and to write to
  * for the specified ring buffer
  */
-static inline void
-get_ring_buffer_avail_bytes(
-	    hv_vmbus_ring_buffer_info*	rbi,
-	    uint32_t*			read,
-	    uint32_t*			write)
+static __inline void
+get_ring_buffer_avail_bytes(hv_vmbus_ring_buffer_info *rbi, uint32_t *read,
+    uint32_t *write)
 {
 	uint32_t read_loc, write_loc;
 
 	/*
 	 * Capture the read/write indices before they changed
 	 */
-	read_loc = rbi->ring_buffer->read_index;
-	write_loc = rbi->ring_buffer->write_index;
+	read_loc = rbi->ring_buffer->br_rindex;
+	write_loc = rbi->ring_buffer->br_windex;
 
-	*write = HV_BYTES_AVAIL_TO_WRITE(
-		read_loc, write_loc, rbi->ring_data_size);
+	*write = HV_BYTES_AVAIL_TO_WRITE(read_loc, write_loc,
+	    rbi->ring_data_size);
 	*read = rbi->ring_data_size - *write;
 }
 
 /**
  * @brief Get the next write location for the specified ring buffer
  */
-static inline uint32_t
-get_next_write_location(hv_vmbus_ring_buffer_info* ring_info) 
+static __inline uint32_t
+get_next_write_location(hv_vmbus_ring_buffer_info *ring_info)
 {
-	uint32_t next = ring_info->ring_buffer->write_index;
-	return (next);
+	return ring_info->ring_buffer->br_windex;
 }
 
 /**
  * @brief Set the next write location for the specified ring buffer
  */
-static inline void
-set_next_write_location(
-	hv_vmbus_ring_buffer_info*	ring_info,
-	uint32_t			next_write_location)
+static __inline void
+set_next_write_location(hv_vmbus_ring_buffer_info *ring_info,
+    uint32_t next_write_location)
 {
-	ring_info->ring_buffer->write_index = next_write_location;
+	ring_info->ring_buffer->br_windex = next_write_location;
 }
 
 /**
  * @brief Get the next read location for the specified ring buffer
  */
-static inline uint32_t
-get_next_read_location(hv_vmbus_ring_buffer_info* ring_info) 
+static __inline uint32_t
+get_next_read_location(hv_vmbus_ring_buffer_info *ring_info)
 {
-	uint32_t next = ring_info->ring_buffer->read_index;
-	return (next);
+	return ring_info->ring_buffer->br_rindex;
 }
 
 /**
  * @brief Get the next read location + offset for the specified ring buffer.
  * This allows the caller to skip.
  */
-static inline uint32_t
-get_next_read_location_with_offset(
-	hv_vmbus_ring_buffer_info*	ring_info,
-	uint32_t			offset)
+static __inline uint32_t
+get_next_read_location_with_offset(hv_vmbus_ring_buffer_info *ring_info,
+    uint32_t offset)
 {
-	uint32_t next = ring_info->ring_buffer->read_index;
+	uint32_t next = ring_info->ring_buffer->br_rindex;
+
 	next += offset;
 	next %= ring_info->ring_data_size;
 	return (next);
@@ -151,28 +182,27 @@ get_next_read_location_with_offset(
 /**
  * @brief Set the next read location for the specified ring buffer
  */
-static inline void
-set_next_read_location(
-	hv_vmbus_ring_buffer_info*	ring_info,
-	uint32_t			next_read_location)
+static __inline void
+set_next_read_location(hv_vmbus_ring_buffer_info *ring_info,
+    uint32_t next_read_location)
 {
-	ring_info->ring_buffer->read_index = next_read_location;
+	ring_info->ring_buffer->br_rindex = next_read_location;
 }
 
 /**
  * @brief Get the start of the ring buffer
  */
-static inline void *
-get_ring_buffer(hv_vmbus_ring_buffer_info* ring_info) 
+static __inline void *
+get_ring_buffer(hv_vmbus_ring_buffer_info *ring_info)
 {
-	return (void *) ring_info->ring_buffer->buffer;
+	return ring_info->ring_buffer->br_data;
 }
 
 /**
  * @brief Get the size of the ring buffer.
  */
-static inline uint32_t
-get_ring_buffer_size(hv_vmbus_ring_buffer_info* ring_info) 
+static __inline uint32_t
+get_ring_buffer_size(hv_vmbus_ring_buffer_info *ring_info)
 {
 	return ring_info->ring_data_size;
 }
@@ -180,27 +210,25 @@ get_ring_buffer_size(hv_vmbus_ring_buffe
 /**
  * Get the read and write indices as uint64_t of the specified ring buffer.
  */
-static inline uint64_t
-get_ring_buffer_indices(hv_vmbus_ring_buffer_info* ring_info) 
+static __inline uint64_t
+get_ring_buffer_indices(hv_vmbus_ring_buffer_info *ring_info)
 {
-	return (uint64_t) ring_info->ring_buffer->write_index << 32;
+	return ((uint64_t)ring_info->ring_buffer->br_windex) << 32;
 }
 
 void
-hv_ring_buffer_read_begin(
-	hv_vmbus_ring_buffer_info*	ring_info)
+hv_ring_buffer_read_begin(hv_vmbus_ring_buffer_info *ring_info)
 {
-	ring_info->ring_buffer->interrupt_mask = 1;
+	ring_info->ring_buffer->br_imask = 1;
 	mb();
 }
 
 uint32_t
-hv_ring_buffer_read_end(
-	hv_vmbus_ring_buffer_info*	ring_info)
+hv_ring_buffer_read_end(hv_vmbus_ring_buffer_info *ring_info)
 {
-	uint32_t read, write;	
+	uint32_t read, write;
 
-	ring_info->ring_buffer->interrupt_mask = 0;
+	ring_info->ring_buffer->br_imask = 0;
 	mb();
 
 	/*
@@ -209,7 +237,6 @@ hv_ring_buffer_read_end(
 	 * incoming messages.
 	 */
 	get_ring_buffer_avail_bytes(ring_info, &read, &write);
-
 	return (read);
 }
 
@@ -229,12 +256,11 @@ hv_ring_buffer_read_end(
  *	   arrived.
  */
 static boolean_t
-hv_ring_buffer_needsig_on_write(
-	uint32_t			old_write_location,
-	hv_vmbus_ring_buffer_info*	rbi)
+hv_ring_buffer_needsig_on_write(uint32_t old_write_location,
+    hv_vmbus_ring_buffer_info *rbi)
 {
 	mb();
-	if (rbi->ring_buffer->interrupt_mask)
+	if (rbi->ring_buffer->br_imask)
 		return (FALSE);
 
 	/* Read memory barrier */
@@ -243,41 +269,26 @@ hv_ring_buffer_needsig_on_write(
 	 * This is the only case we need to signal when the
 	 * ring transitions from being empty to non-empty.
 	 */
-	if (old_write_location == rbi->ring_buffer->read_index)
+	if (old_write_location == rbi->ring_buffer->br_rindex)
 		return (TRUE);
 
 	return (FALSE);
 }
 
-static uint32_t	copy_to_ring_buffer(
-			hv_vmbus_ring_buffer_info*	ring_info,
-			uint32_t			start_write_offset,
-			const uint8_t			*src,
-			uint32_t			src_len);
-
-static uint32_t copy_from_ring_buffer(
-			hv_vmbus_ring_buffer_info*	ring_info,
-			char*				dest,
-			uint32_t			dest_len,
-			uint32_t			start_read_offset);
-
 /**
  * @brief Initialize the ring buffer.
  */
 int
-hv_vmbus_ring_buffer_init(
-	hv_vmbus_ring_buffer_info*	ring_info,
-	void*				buffer,
-	uint32_t			buffer_len)
+hv_vmbus_ring_buffer_init(hv_vmbus_ring_buffer_info *ring_info, void *buffer,
+    uint32_t buffer_len)
 {
 	memset(ring_info, 0, sizeof(hv_vmbus_ring_buffer_info));
 
-	ring_info->ring_buffer = (hv_vmbus_ring_buffer*) buffer;
-	ring_info->ring_buffer->read_index =
-	    ring_info->ring_buffer->write_index = 0;
-
-	ring_info->ring_data_size = buffer_len - sizeof(hv_vmbus_ring_buffer);
+	ring_info->ring_buffer = buffer;
+	ring_info->ring_buffer->br_rindex = 0;
+	ring_info->ring_buffer->br_windex = 0;
 
+	ring_info->ring_data_size = buffer_len - sizeof(struct vmbus_bufring);
 	mtx_init(&ring_info->ring_lock, "vmbus ring buffer", NULL, MTX_SPIN);
 
 	return (0);
@@ -286,7 +297,8 @@ hv_vmbus_ring_buffer_init(
 /**
  * @brief Cleanup the ring buffer.
  */
-void hv_ring_buffer_cleanup(hv_vmbus_ring_buffer_info* ring_info) 
+void
+hv_ring_buffer_cleanup(hv_vmbus_ring_buffer_info *ring_info) 
 {
 	mtx_destroy(&ring_info->ring_lock);
 }
@@ -295,24 +307,19 @@ void hv_ring_buffer_cleanup(hv_vmbus_rin
  * @brief Write to the ring buffer.
  */
 int
-hv_ring_buffer_write(
-	hv_vmbus_ring_buffer_info*	out_ring_info,
-	const struct iovec		iov[],
-	uint32_t			iovlen,
-	boolean_t			*need_sig)
+hv_ring_buffer_write(hv_vmbus_ring_buffer_info *out_ring_info,
+    const struct iovec iov[], uint32_t iovlen, boolean_t *need_sig)
 {
 	int i = 0;
 	uint32_t byte_avail_to_write;
 	uint32_t byte_avail_to_read;
 	uint32_t old_write_location;
 	uint32_t total_bytes_to_write = 0;
-
 	volatile uint32_t next_write_location;
 	uint64_t prev_indices = 0;
 
-	for (i = 0; i < iovlen; i++) {
-	    total_bytes_to_write += iov[i].iov_len;
-	}
+	for (i = 0; i < iovlen; i++)
+		total_bytes_to_write += iov[i].iov_len;
 
 	total_bytes_to_write += sizeof(uint64_t);
 
@@ -326,11 +333,9 @@ hv_ring_buffer_write(
 	 * Otherwise, the next time around, we think the ring buffer
 	 * is empty since the read index == write index
 	 */
-
 	if (byte_avail_to_write <= total_bytes_to_write) {
-
-	    mtx_unlock_spin(&out_ring_info->ring_lock);
-	    return (EAGAIN);
+		mtx_unlock_spin(&out_ring_info->ring_lock);
+		return (EAGAIN);
 	}
 
 	/*
@@ -341,8 +346,8 @@ hv_ring_buffer_write(
 	old_write_location = next_write_location;
 
 	for (i = 0; i < iovlen; i++) {
-	    next_write_location = copy_to_ring_buffer(out_ring_info,
-		next_write_location, iov[i].iov_base, iov[i].iov_len);
+		next_write_location = copy_to_ring_buffer(out_ring_info,
+		    next_write_location, iov[i].iov_base, iov[i].iov_len);
 	}
 
 	/*
@@ -350,9 +355,8 @@ hv_ring_buffer_write(
 	 */
 	prev_indices = get_ring_buffer_indices(out_ring_info);
 
-	next_write_location = copy_to_ring_buffer(
-		out_ring_info, next_write_location,
-		(char *) &prev_indices, sizeof(uint64_t));
+	next_write_location = copy_to_ring_buffer(out_ring_info,
+	    next_write_location, (char *)&prev_indices, sizeof(uint64_t));
 
 	/*
 	 * Full memory barrier before upding the write index. 
@@ -376,10 +380,8 @@ hv_ring_buffer_write(
  * @brief Read without advancing the read index.
  */
 int
-hv_ring_buffer_peek(
-	hv_vmbus_ring_buffer_info*	in_ring_info,
-	void*				buffer,
-	uint32_t			buffer_len)
+hv_ring_buffer_peek(hv_vmbus_ring_buffer_info *in_ring_info, void *buffer,
+    uint32_t buffer_len)
 {
 	uint32_t bytesAvailToWrite;
 	uint32_t bytesAvailToRead;
@@ -388,14 +390,14 @@ hv_ring_buffer_peek(
 	mtx_lock_spin(&in_ring_info->ring_lock);
 
 	get_ring_buffer_avail_bytes(in_ring_info, &bytesAvailToRead,
-		&bytesAvailToWrite);
+	    &bytesAvailToWrite);
 
 	/*
 	 * Make sure there is something to read
 	 */
 	if (bytesAvailToRead < buffer_len) {
-	    mtx_unlock_spin(&in_ring_info->ring_lock);
-	    return (EAGAIN);
+		mtx_unlock_spin(&in_ring_info->ring_lock);
+		return (EAGAIN);
 	}
 
 	/*
@@ -403,8 +405,8 @@ hv_ring_buffer_peek(
 	 */
 	nextReadLocation = get_next_read_location(in_ring_info);
 
-	nextReadLocation = copy_from_ring_buffer(
-		in_ring_info, (char *)buffer, buffer_len, nextReadLocation);
+	nextReadLocation = copy_from_ring_buffer(in_ring_info,
+	    (char *)buffer, buffer_len, nextReadLocation);
 
 	mtx_unlock_spin(&in_ring_info->ring_lock);
 
@@ -415,11 +417,8 @@ hv_ring_buffer_peek(
  * @brief Read and advance the read index.
  */
 int
-hv_ring_buffer_read(
-	hv_vmbus_ring_buffer_info*	in_ring_info,
-	void*				buffer,
-	uint32_t			buffer_len,
-	uint32_t			offset)
+hv_ring_buffer_read(hv_vmbus_ring_buffer_info *in_ring_info, void *buffer,
+    uint32_t buffer_len, uint32_t offset)
 {
 	uint32_t bytes_avail_to_write;
 	uint32_t bytes_avail_to_read;
@@ -427,37 +426,29 @@ hv_ring_buffer_read(
 	uint64_t prev_indices = 0;
 
 	if (buffer_len <= 0)
-	    return (EINVAL);
+		return (EINVAL);
 
 	mtx_lock_spin(&in_ring_info->ring_lock);
 
-	get_ring_buffer_avail_bytes(
-	    in_ring_info, &bytes_avail_to_read,
+	get_ring_buffer_avail_bytes(in_ring_info, &bytes_avail_to_read,
 	    &bytes_avail_to_write);
 
 	/*
 	 * Make sure there is something to read
 	 */
 	if (bytes_avail_to_read < buffer_len) {
-	    mtx_unlock_spin(&in_ring_info->ring_lock);
-	    return (EAGAIN);
+		mtx_unlock_spin(&in_ring_info->ring_lock);
+		return (EAGAIN);
 	}
 
-	next_read_location = get_next_read_location_with_offset(
-	    in_ring_info,
+	next_read_location = get_next_read_location_with_offset(in_ring_info,
 	    offset);
 
-	next_read_location = copy_from_ring_buffer(
-	    in_ring_info,
-	    (char *) buffer,
-	    buffer_len,
-	    next_read_location);
-
-	next_read_location = copy_from_ring_buffer(
-	    in_ring_info,
-	    (char *) &prev_indices,
-	    sizeof(uint64_t),
-	    next_read_location);
+	next_read_location = copy_from_ring_buffer(in_ring_info, (char *)buffer,
+	    buffer_len, next_read_location);
+
+	next_read_location = copy_from_ring_buffer(in_ring_info,
+	    (char *)&prev_indices, sizeof(uint64_t), next_read_location);
 
 	/*
 	 * Make sure all reads are done before we update the read index since
@@ -482,23 +473,20 @@ hv_ring_buffer_read(
  * Assume there is enough room. Handles wrap-around in dest case only!
  */
 static uint32_t
-copy_to_ring_buffer(
-	hv_vmbus_ring_buffer_info*	ring_info,
-	uint32_t 			start_write_offset,
-	const uint8_t			*src,
-	uint32_t			src_len)
+copy_to_ring_buffer(hv_vmbus_ring_buffer_info *ring_info,
+    uint32_t start_write_offset, const uint8_t *src, uint32_t src_len)
 {
 	char *ring_buffer = get_ring_buffer(ring_info);
 	uint32_t ring_buffer_size = get_ring_buffer_size(ring_info);
 	uint32_t fragLen;
 
-	if (src_len > ring_buffer_size - start_write_offset)  {
-	    /* wrap-around detected! */
-	    fragLen = ring_buffer_size - start_write_offset;
-	    memcpy(ring_buffer + start_write_offset, src, fragLen);
-	    memcpy(ring_buffer, src + fragLen, src_len - fragLen);
+	if (src_len > ring_buffer_size - start_write_offset) {
+		/* wrap-around detected! */
+		fragLen = ring_buffer_size - start_write_offset;
+		memcpy(ring_buffer + start_write_offset, src, fragLen);
+		memcpy(ring_buffer, src + fragLen, src_len - fragLen);
 	} else {
-	    memcpy(ring_buffer + start_write_offset, src, src_len);
+		memcpy(ring_buffer + start_write_offset, src, src_len);
 	}
 
 	start_write_offset += src_len;
@@ -512,24 +500,21 @@ copy_to_ring_buffer(
  *
  * Assume there is enough room. Handles wrap-around in src case only!
  */
-uint32_t
-copy_from_ring_buffer(
-	hv_vmbus_ring_buffer_info*	ring_info,
-	char*				dest,
-	uint32_t			dest_len,
-	uint32_t			start_read_offset)
+static uint32_t
+copy_from_ring_buffer(hv_vmbus_ring_buffer_info *ring_info, char *dest,
+    uint32_t dest_len, uint32_t start_read_offset)
 {
 	uint32_t fragLen;
 	char *ring_buffer = get_ring_buffer(ring_info);
 	uint32_t ring_buffer_size = get_ring_buffer_size(ring_info);
 
 	if (dest_len > ring_buffer_size - start_read_offset) {
-	    /*  wrap-around detected at the src */
-	    fragLen = ring_buffer_size - start_read_offset;
-	    memcpy(dest, ring_buffer + start_read_offset, fragLen);
-	    memcpy(dest + fragLen, ring_buffer, dest_len - fragLen);
+		/* wrap-around detected at the src */
+		fragLen = ring_buffer_size - start_read_offset;
+		memcpy(dest, ring_buffer + start_read_offset, fragLen);
+		memcpy(dest + fragLen, ring_buffer, dest_len - fragLen);
 	} else {
-	    memcpy(dest, ring_buffer + start_read_offset, dest_len);
+		memcpy(dest, ring_buffer + start_read_offset, dest_len);
 	}
 
 	start_read_offset += dest_len;
@@ -537,4 +522,3 @@ copy_from_ring_buffer(
 
 	return (start_read_offset);
 }
-

Modified: stable/11/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
==============================================================================
--- stable/11/sys/dev/hyperv/vmbus/hv_vmbus_priv.h	Mon Oct 17 03:24:03 2016	(r307461)
+++ stable/11/sys/dev/hyperv/vmbus/hv_vmbus_priv.h	Mon Oct 17 03:27:23 2016	(r307462)
@@ -45,13 +45,11 @@ struct vmbus_softc;
  * Private, VM Bus functions
  */
 struct sysctl_ctx_list;
-struct sysctl_oid_list;
+struct sysctl_oid;
 
-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);
+void	vmbus_br_sysctl_create(struct sysctl_ctx_list *ctx,
+	    struct sysctl_oid *br_tree, hv_vmbus_ring_buffer_info *br,
+	    const char *name);
 
 int			hv_vmbus_ring_buffer_init(
 				hv_vmbus_ring_buffer_info	*ring_info,

Modified: stable/11/sys/dev/hyperv/vmbus/vmbus_chan.c
==============================================================================
--- stable/11/sys/dev/hyperv/vmbus/vmbus_chan.c	Mon Oct 17 03:24:03 2016	(r307461)
+++ stable/11/sys/dev/hyperv/vmbus/vmbus_chan.c	Mon Oct 17 03:27:23 2016	(r307462)
@@ -171,24 +171,17 @@ vmbus_chan_sysctl_create(struct vmbus_ch
 	    chan, 0, vmbus_chan_sysctl_mnf, "I",
 	    "has monitor notification facilities");
 
-	/*
-	 * Create sysctl tree for RX bufring.
-	 */
-	br_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO,
-	    "in", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "");
-	if (br_tree != NULL) {
-		hv_ring_buffer_stat(ctx, SYSCTL_CHILDREN(br_tree),
-		    &chan->ch_rxbr, "inbound ring buffer stats");
-	}
-
-	/*
-	 * Create sysctl tree for TX bufring.
-	 */
 	br_tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(chid_tree), OID_AUTO,
-	    "out", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "");
+	    "br", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "");
 	if (br_tree != NULL) {
-		hv_ring_buffer_stat(ctx, SYSCTL_CHILDREN(br_tree),
-		    &chan->ch_txbr, "outbound ring buffer stats");
+		/*
+		 * Create sysctl tree for RX bufring.
+		 */
+		vmbus_br_sysctl_create(ctx, br_tree, &chan->ch_rxbr, "rx");
+		/*
+		 * Create sysctl tree for TX bufring.
+		 */
+		vmbus_br_sysctl_create(ctx, br_tree, &chan->ch_txbr, "tx");
 	}
 }
 

Modified: stable/11/sys/dev/hyperv/vmbus/vmbus_chanvar.h
==============================================================================
--- stable/11/sys/dev/hyperv/vmbus/vmbus_chanvar.h	Mon Oct 17 03:24:03 2016	(r307461)
+++ stable/11/sys/dev/hyperv/vmbus/vmbus_chanvar.h	Mon Oct 17 03:27:23 2016	(r307462)
@@ -41,31 +41,7 @@
 #include <dev/hyperv/include/vmbus.h>
 
 typedef struct {
-	/*
-	 * offset in bytes from the start of ring data below
-	 */
-	volatile uint32_t       write_index;
-	/*
-	 * offset in bytes from the start of ring data below
-	 */
-	volatile uint32_t       read_index;
-	/*
-	 * NOTE: The interrupt_mask field is used only for channels, but
-	 * vmbus connection also uses this data structure
-	 */
-	volatile uint32_t       interrupt_mask;
-	/* pad it to PAGE_SIZE so that data starts on a page */
-	uint8_t                 reserved[4084];
-
-	/*
-	 * WARNING: Ring data starts here
-	 *  !!! DO NOT place any fields below this !!!
-	 */
-	uint8_t			buffer[0];	/* doubles as interrupt mask */
-} __packed hv_vmbus_ring_buffer;
-
-typedef struct {
-	hv_vmbus_ring_buffer*	ring_buffer;
+	struct vmbus_bufring	*ring_buffer;
 	struct mtx		ring_lock;
 	uint32_t		ring_data_size;	/* ring_size */
 } hv_vmbus_ring_buffer_info;

Modified: stable/11/sys/dev/hyperv/vmbus/vmbus_reg.h
==============================================================================
--- stable/11/sys/dev/hyperv/vmbus/vmbus_reg.h	Mon Oct 17 03:24:03 2016	(r307461)
+++ stable/11/sys/dev/hyperv/vmbus/vmbus_reg.h	Mon Oct 17 03:27:23 2016	(r307462)
@@ -102,6 +102,37 @@ struct vmbus_mnf {
 CTASSERT(sizeof(struct vmbus_mnf) == PAGE_SIZE);
 
 /*
+ * Buffer ring
+ */
+struct vmbus_bufring {
+	/*
+	 * If br_windex == br_rindex, this bufring is empty; this
+	 * means we can _not_ write data to the bufring, if the
+	 * write is going to make br_windex same as br_rindex.
+	 */
+	volatile uint32_t	br_windex;
+	volatile uint32_t	br_rindex;
+
+	/*
+	 * Interrupt mask {0,1}
+	 *
+	 * For TX bufring, host set this to 1, when it is processing
+	 * the TX bufring, so that we can safely skip the TX event
+	 * notification to host.
+	 *
+	 * For RX bufring, once this is set to 1 by us, host will not
+	 * further dispatch interrupts to us, even if there are data
+	 * pending on the RX bufring.  This effectively disables the
+	 * interrupt of the channel to which this RX bufring is attached.
+	 */
+	volatile uint32_t	br_imask;
+
+	uint8_t			br_rsvd[4084];
+	uint8_t			br_data[];
+} __packed;
+CTASSERT(sizeof(struct vmbus_bufring) == PAGE_SIZE);
+
+/*
  * Channel
  */
 



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