Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 Jul 2016 07:36:54 +0000 (UTC)
From:      Sepherosa Ziehau <sephe@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r303370 - head/sys/dev/hyperv/vmbus
Message-ID:  <201607270736.u6R7as13095720@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sephe
Date: Wed Jul 27 07:36:54 2016
New Revision: 303370
URL: https://svnweb.freebsd.org/changeset/base/303370

Log:
  hyperv/vmbus: Cleanup RX bufring read process.
  
  MFC after:	1 week
  Sponsored by:	Microsoft
  Differential Revision:	https://reviews.freebsd.org/D7317

Modified:
  head/sys/dev/hyperv/vmbus/hv_ring_buffer.c
  head/sys/dev/hyperv/vmbus/vmbus_brvar.h

Modified: head/sys/dev/hyperv/vmbus/hv_ring_buffer.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_ring_buffer.c	Wed Jul 27 07:19:06 2016	(r303369)
+++ head/sys/dev/hyperv/vmbus/hv_ring_buffer.c	Wed Jul 27 07:36:54 2016	(r303370)
@@ -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 @@ vmbus_txbr_copyto(const struct vmbus_txb
 	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 @@ vmbus_txbr_write(struct vmbus_txbr *tbr,
 	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 @@ vmbus_rxbr_read(struct vmbus_rxbr *rbr, 
 	/*
 	 * 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 @@ vmbus_rxbr_read(struct vmbus_rxbr *rbr, 
 	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);
-}

Modified: head/sys/dev/hyperv/vmbus/vmbus_brvar.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus_brvar.h	Wed Jul 27 07:19:06 2016	(r303369)
+++ head/sys/dev/hyperv/vmbus/vmbus_brvar.h	Wed Jul 27 07:36:54 2016	(r303370)
@@ -80,7 +80,7 @@ void		vmbus_rxbr_deinit(struct vmbus_rxb
 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);
 



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