Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150115338
D7317.id18789.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D7317.id18789.diff
View Options
Index: head/sys/dev/hyperv/vmbus/hv_ring_buffer.c
===================================================================
--- head/sys/dev/hyperv/vmbus/hv_ring_buffer.c
+++ head/sys/dev/hyperv/vmbus/hv_ring_buffer.c
@@ -38,8 +38,8 @@
#define VMBUS_BR_WAVAIL(r, w, z) \
(((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w)))
-static uint32_t copy_from_ring_buffer(const struct vmbus_rxbr *rbr,
- char *dest, uint32_t dest_len, uint32_t start_read_offset);
+/* Increase bufing index */
+#define VMBUS_BR_IDXINC(idx, inc, sz) (((idx) + (inc)) % (sz))
static int
vmbus_br_sysctl_state(SYSCTL_HANDLER_ARGS)
@@ -244,20 +244,15 @@
uint32_t br_dsize = tbr->txbr_dsize;
if (cplen > br_dsize - windex) {
- uint32_t fraglen;
+ uint32_t fraglen = br_dsize - windex;
- /* Wrap-around detected! */
- fraglen = br_dsize - windex;
+ /* Wrap-around detected */
memcpy(br_data + windex, src, fraglen);
memcpy(br_data, src + fraglen, cplen - fraglen);
} else {
memcpy(br_data + windex, src, cplen);
}
-
- windex += cplen;
- windex %= br_dsize;
-
- return windex;
+ return VMBUS_BR_IDXINC(windex, cplen, br_dsize);
}
/*
@@ -331,46 +326,60 @@
return (0);
}
+static __inline uint32_t
+vmbus_rxbr_copyfrom(const struct vmbus_rxbr *rbr, uint32_t rindex,
+ void *dst0, int cplen)
+{
+ uint8_t *dst = dst0;
+ const uint8_t *br_data = rbr->rxbr_data;
+ uint32_t br_dsize = rbr->rxbr_dsize;
+
+ if (cplen > br_dsize - rindex) {
+ uint32_t fraglen = br_dsize - rindex;
+
+ /* Wrap-around detected. */
+ memcpy(dst, br_data + rindex, fraglen);
+ memcpy(dst + fraglen, br_data, cplen - fraglen);
+ } else {
+ memcpy(dst, br_data + rindex, cplen);
+ }
+ return VMBUS_BR_IDXINC(rindex, cplen, br_dsize);
+}
+
int
vmbus_rxbr_peek(struct vmbus_rxbr *rbr, void *data, int dlen)
{
- uint32_t bytesAvailToRead;
- uint32_t nextReadLocation = 0;
-
mtx_lock_spin(&rbr->rxbr_lock);
/*
* The requested data and the 64bits channel packet
* offset should be there at least.
*/
- bytesAvailToRead = vmbus_rxbr_avail(rbr);
- if (bytesAvailToRead < dlen + sizeof(uint64_t)) {
+ if (vmbus_rxbr_avail(rbr) < dlen + sizeof(uint64_t)) {
mtx_unlock_spin(&rbr->rxbr_lock);
return (EAGAIN);
}
-
- nextReadLocation = rbr->rxbr_rindex;
- nextReadLocation = copy_from_ring_buffer(rbr, data, dlen,
- nextReadLocation);
+ vmbus_rxbr_copyfrom(rbr, rbr->rxbr_rindex, data, dlen);
mtx_unlock_spin(&rbr->rxbr_lock);
return (0);
}
+/*
+ * NOTE:
+ * We assume (dlen + skip) == sizeof(channel packet).
+ */
int
-vmbus_rxbr_read(struct vmbus_rxbr *rbr, void *data, int dlen, uint32_t offset)
+vmbus_rxbr_read(struct vmbus_rxbr *rbr, void *data, int dlen, uint32_t skip)
{
- uint32_t bytes_avail_to_read;
- uint32_t next_read_location = 0;
- uint64_t prev_indices = 0;
+ uint32_t rindex, br_dsize = rbr->rxbr_dsize;
- KASSERT(dlen > 0, ("invalid dlen %d", dlen));
+ KASSERT(dlen + skip > 0, ("invalid dlen %d, offset %u", dlen, skip));
mtx_lock_spin(&rbr->rxbr_lock);
- bytes_avail_to_read = vmbus_rxbr_avail(rbr);
- if (bytes_avail_to_read < dlen + offset + sizeof(prev_indices)) {
+ if (vmbus_rxbr_avail(rbr) < dlen + skip + sizeof(uint64_t)) {
mtx_unlock_spin(&rbr->rxbr_lock);
return (EAGAIN);
}
@@ -378,16 +387,13 @@
/*
* Copy channel packet from RX bufring.
*/
- next_read_location = (rbr->rxbr_rindex + offset) % rbr->rxbr_dsize;
- next_read_location = copy_from_ring_buffer(rbr, data, dlen,
- next_read_location);
+ rindex = VMBUS_BR_IDXINC(rbr->rxbr_rindex, skip, br_dsize);
+ rindex = vmbus_rxbr_copyfrom(rbr, rindex, data, dlen);
/*
- * Discard this channel packet's start offset, which is useless
- * for us.
+ * Discard this channel packet's 64bits offset, which is useless to us.
*/
- next_read_location = copy_from_ring_buffer(rbr,
- (char *)&prev_indices, sizeof(uint64_t), next_read_location);
+ rindex = VMBUS_BR_IDXINC(rindex, sizeof(uint64_t), br_dsize);
/*
* XXX only compiler fence is needed.
@@ -398,34 +404,11 @@
wmb();
/*
- * Update the read index
+ * Update the read index _after_ the channel packet is fetched.
*/
- rbr->rxbr_rindex = next_read_location;
+ rbr->rxbr_rindex = rindex;
mtx_unlock_spin(&rbr->rxbr_lock);
return (0);
}
-
-static uint32_t
-copy_from_ring_buffer(const struct vmbus_rxbr *rbr, char *dest,
- uint32_t dest_len, uint32_t start_read_offset)
-{
- uint32_t fragLen;
- char *ring_buffer = rbr->rxbr_data;
- uint32_t ring_buffer_size = rbr->rxbr_dsize;
-
- 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);
- } else {
- memcpy(dest, ring_buffer + start_read_offset, dest_len);
- }
-
- start_read_offset += dest_len;
- start_read_offset %= ring_buffer_size;
-
- return (start_read_offset);
-}
Index: head/sys/dev/hyperv/vmbus/vmbus_brvar.h
===================================================================
--- head/sys/dev/hyperv/vmbus/vmbus_brvar.h
+++ head/sys/dev/hyperv/vmbus/vmbus_brvar.h
@@ -80,7 +80,7 @@
void vmbus_rxbr_setup(struct vmbus_rxbr *rbr, void *buf, int blen);
int vmbus_rxbr_peek(struct vmbus_rxbr *rbr, void *data, int dlen);
int vmbus_rxbr_read(struct vmbus_rxbr *rbr, void *data, int dlen,
- uint32_t offset);
+ uint32_t skip);
void vmbus_rxbr_intr_mask(struct vmbus_rxbr *rbr);
uint32_t vmbus_rxbr_intr_unmask(struct vmbus_rxbr *rbr);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Mar 30, 12:28 PM (12 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30583316
Default Alt Text
D7317.id18789.diff (5 KB)
Attached To
Mode
D7317: hyperv/vmbus: Cleanup RX bufring read process.
Attached
Detach File
Event Timeline
Log In to Comment