hyperv/vmbus: Move vmbus bufring definition to vmbus_reg.h

And add more comment about its fields.

MFC after:	1 week
Sponsored by:	Microsoft OSTC
Differential Revision:	https://reviews.freebsd.org/D7269
This commit is contained in:
Sepherosa Ziehau 2016-07-22 05:09:08 +00:00
parent bafad35c7d
commit 031e155216
3 changed files with 55 additions and 47 deletions

View file

@ -32,6 +32,7 @@
#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) \
@ -50,9 +51,9 @@ vmbus_br_sysctl_state(SYSCTL_HANDLER_ARGS)
uint32_t rindex, windex, intr_mask, ravail, wavail;
char state[256];
rindex = br->ring_buffer->read_index;
windex = br->ring_buffer->write_index;
intr_mask = br->ring_buffer->interrupt_mask;
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;
@ -78,13 +79,13 @@ vmbus_br_sysctl_state_bin(SYSCTL_HANDLER_ARGS)
const hv_vmbus_ring_buffer_info *br = arg1;
uint32_t rindex, windex, wavail, state[BR_STATE_MAX];
rindex = br->ring_buffer->read_index;
windex = br->ring_buffer->write_index;
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->interrupt_mask;
state[BR_STATE_IMSK] = br->ring_buffer->br_imask;
state[BR_STATE_WSPC] = wavail;
state[BR_STATE_RSPC] = br->ring_data_size - wavail;
@ -127,8 +128,8 @@ get_ring_buffer_avail_bytes(hv_vmbus_ring_buffer_info *rbi, uint32_t *read,
/*
* 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);
@ -141,7 +142,7 @@ get_ring_buffer_avail_bytes(hv_vmbus_ring_buffer_info *rbi, uint32_t *read,
static __inline uint32_t
get_next_write_location(hv_vmbus_ring_buffer_info *ring_info)
{
return ring_info->ring_buffer->write_index;
return ring_info->ring_buffer->br_windex;
}
/**
@ -151,7 +152,7 @@ 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;
}
/**
@ -160,7 +161,7 @@ set_next_write_location(hv_vmbus_ring_buffer_info *ring_info,
static __inline uint32_t
get_next_read_location(hv_vmbus_ring_buffer_info *ring_info)
{
return ring_info->ring_buffer->read_index;
return ring_info->ring_buffer->br_rindex;
}
/**
@ -171,7 +172,7 @@ 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;
@ -185,7 +186,7 @@ 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;
}
/**
@ -194,7 +195,7 @@ set_next_read_location(hv_vmbus_ring_buffer_info *ring_info,
static __inline void *
get_ring_buffer(hv_vmbus_ring_buffer_info *ring_info)
{
return ring_info->ring_buffer->buffer;
return ring_info->ring_buffer->br_data;
}
/**
@ -212,13 +213,13 @@ get_ring_buffer_size(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)
{
ring_info->ring_buffer->interrupt_mask = 1;
ring_info->ring_buffer->br_imask = 1;
mb();
}
@ -227,7 +228,7 @@ hv_ring_buffer_read_end(hv_vmbus_ring_buffer_info *ring_info)
{
uint32_t read, write;
ring_info->ring_buffer->interrupt_mask = 0;
ring_info->ring_buffer->br_imask = 0;
mb();
/*
@ -259,7 +260,7 @@ 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 */
@ -268,7 +269,7 @@ hv_ring_buffer_needsig_on_write(uint32_t old_write_location,
* 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);
@ -284,10 +285,10 @@ hv_vmbus_ring_buffer_init(hv_vmbus_ring_buffer_info *ring_info, void *buffer,
memset(ring_info, 0, sizeof(hv_vmbus_ring_buffer_info));
ring_info->ring_buffer = buffer;
ring_info->ring_buffer->read_index = 0;
ring_info->ring_buffer->write_index = 0;
ring_info->ring_buffer->br_rindex = 0;
ring_info->ring_buffer->br_windex = 0;
ring_info->ring_data_size = buffer_len - sizeof(hv_vmbus_ring_buffer);
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);

View file

@ -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;

View file

@ -101,6 +101,37 @@ struct vmbus_mnf {
} __packed;
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
*/