svn commit: r307462 - stable/11/sys/dev/hyperv/vmbus
Sepherosa Ziehau
sephe at FreeBSD.org
Mon Oct 17 03:27:25 UTC 2016
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
*/
More information about the svn-src-stable
mailing list