svn commit: r302886 - in head/sys/dev/hyperv: include netvsc vmbus

Sepherosa Ziehau sephe at FreeBSD.org
Fri Jul 15 07:53:47 UTC 2016


Author: sephe
Date: Fri Jul 15 07:53:45 2016
New Revision: 302886
URL: https://svnweb.freebsd.org/changeset/base/302886

Log:
  hyperv/vmbus: Cleanup channel packet receiving.
  
  MFC after:	1 week
  Sponsored by:	Microsoft OSTC
  Differential Revision:	https://reviews.freebsd.org/D7204

Modified:
  head/sys/dev/hyperv/include/hyperv.h
  head/sys/dev/hyperv/include/vmbus.h
  head/sys/dev/hyperv/netvsc/hv_net_vsc.c
  head/sys/dev/hyperv/vmbus/hv_channel.c
  head/sys/dev/hyperv/vmbus/vmbus_reg.h

Modified: head/sys/dev/hyperv/include/hyperv.h
==============================================================================
--- head/sys/dev/hyperv/include/hyperv.h	Fri Jul 15 07:45:30 2016	(r302885)
+++ head/sys/dev/hyperv/include/hyperv.h	Fri Jul 15 07:53:45 2016	(r302886)
@@ -90,28 +90,6 @@ struct hyperv_guid {
 
 int	hyperv_guid2str(const struct hyperv_guid *, char *, size_t);
 
-typedef struct {
-	uint16_t type;
-	uint16_t data_offset8;
-	uint16_t length8;
-	uint16_t flags;
-	uint64_t transaction_id;
-} __packed hv_vm_packet_descriptor;
-
-typedef struct {
-	uint32_t byte_count;
-	uint32_t byte_offset;
-} __packed hv_vm_transfer_page;
-
-typedef struct {
-	hv_vm_packet_descriptor	d;
-	uint16_t		transfer_page_set_id;
-	hv_bool_uint8_t		sender_owns_set;
-	uint8_t			reserved;
-	uint32_t		range_count;
-	hv_vm_transfer_page	ranges[1];
-} __packed hv_vm_transfer_page_packet_header;
-
 #define HW_MACADDR_LEN	6
 
 /*
@@ -298,13 +276,6 @@ hv_set_channel_read_state(hv_vmbus_chann
 		channel->ch_flags |= VMBUS_CHAN_FLAG_BATCHREAD;
 }
 
-int		hv_vmbus_channel_recv_packet_raw(
-				hv_vmbus_channel*	channel,
-				void*			buffer,
-				uint32_t		buffer_len,
-				uint32_t*		buffer_actual_len,
-				uint64_t*		request_id);
-
 int		hv_vmbus_channel_open(
 				hv_vmbus_channel*	channel,
 				uint32_t		send_ring_buffer_size,

Modified: head/sys/dev/hyperv/include/vmbus.h
==============================================================================
--- head/sys/dev/hyperv/include/vmbus.h	Fri Jul 15 07:45:30 2016	(r302885)
+++ head/sys/dev/hyperv/include/vmbus.h	Fri Jul 15 07:53:45 2016	(r302886)
@@ -47,6 +47,19 @@ struct vmbus_gpa {
 	uint64_t	gpa_page;
 } __packed;
 
+#define VMBUS_CHANPKT_SIZE_SHIFT	3
+
+#define VMBUS_CHANPKT_GETLEN(pktlen)	\
+	(((int)(pktlen)) << VMBUS_CHANPKT_SIZE_SHIFT)
+
+struct vmbus_chanpkt_hdr {
+	uint16_t	cph_type;	/* VMBUS_CHANPKT_TYPE_ */
+	uint16_t	cph_hlen;	/* header len, in 8 bytes */
+	uint16_t	cph_tlen;	/* total len, in 8 bytes */
+	uint16_t	cph_flags;	/* VMBUS_CHANPKT_FLAG_ */
+	uint64_t	cph_xactid;
+} __packed;
+
 #define VMBUS_CHANPKT_TYPE_INBAND	0x0006
 #define VMBUS_CHANPKT_TYPE_RXBUF	0x0007
 #define VMBUS_CHANPKT_TYPE_GPA		0x0009
@@ -54,6 +67,23 @@ struct vmbus_gpa {
 
 #define VMBUS_CHANPKT_FLAG_RC		0x0001	/* report completion */
 
+#define VMBUS_CHANPKT_CONST_DATA(pkt)		\
+	(const void *)((const uint8_t *)(pkt) +	\
+	VMBUS_CHANPKT_GETLEN((pkt)->cph_hlen))
+
+struct vmbus_rxbuf_desc {
+	uint32_t	rb_len;
+	uint32_t	rb_ofs;
+} __packed;
+
+struct vmbus_chanpkt_rxbuf {
+	struct vmbus_chanpkt_hdr cp_hdr;
+	uint16_t	cp_rxbuf_id;
+	uint16_t	cp_rsvd;
+	uint32_t	cp_rxbuf_cnt;
+	struct vmbus_rxbuf_desc cp_rxbuf[];
+} __packed;
+
 #define VMBUS_CHAN_SGLIST_MAX		32
 #define VMBUS_CHAN_PRPLIST_MAX		32
 
@@ -61,6 +91,8 @@ struct hv_vmbus_channel;
 
 int	vmbus_chan_recv(struct hv_vmbus_channel *chan, void *data, int *dlen,
 	    uint64_t *xactid);
+int	vmbus_chan_recv_pkt(struct hv_vmbus_channel *chan,
+	    struct vmbus_chanpkt_hdr *pkt, int *pktlen);
 
 int	vmbus_chan_send(struct hv_vmbus_channel *chan, uint16_t type,
 	    uint16_t flags, void *data, int dlen, uint64_t xactid);

Modified: head/sys/dev/hyperv/netvsc/hv_net_vsc.c
==============================================================================
--- head/sys/dev/hyperv/netvsc/hv_net_vsc.c	Fri Jul 15 07:45:30 2016	(r302885)
+++ head/sys/dev/hyperv/netvsc/hv_net_vsc.c	Fri Jul 15 07:53:45 2016	(r302886)
@@ -64,12 +64,12 @@ static int  hv_nv_destroy_send_buffer(ne
 static int  hv_nv_destroy_rx_buffer(netvsc_dev *net_dev);
 static int  hv_nv_connect_to_vsp(struct hn_softc *sc);
 static void hv_nv_on_send_completion(netvsc_dev *net_dev,
-    struct hv_vmbus_channel *, hv_vm_packet_descriptor *pkt);
+    struct hv_vmbus_channel *, const struct vmbus_chanpkt_hdr *pkt);
 static void hv_nv_on_receive_completion(struct hv_vmbus_channel *chan,
     uint64_t tid, uint32_t status);
 static void hv_nv_on_receive(netvsc_dev *net_dev,
     struct hn_softc *sc, struct hv_vmbus_channel *chan,
-    hv_vm_packet_descriptor *pkt);
+    const struct vmbus_chanpkt_hdr *pkt);
 
 /*
  *
@@ -726,13 +726,12 @@ hv_nv_on_device_remove(struct hn_softc *
  */
 static void
 hv_nv_on_send_completion(netvsc_dev *net_dev, struct hv_vmbus_channel *chan,
-    hv_vm_packet_descriptor *pkt)
+    const struct vmbus_chanpkt_hdr *pkt)
 {
-	nvsp_msg *nvsp_msg_pkt;
+	const nvsp_msg *nvsp_msg_pkt;
 	netvsc_packet *net_vsc_pkt;
 
-	nvsp_msg_pkt =
-	    (nvsp_msg *)((unsigned long)pkt + (pkt->data_offset8 << 3));
+	nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkt);
 
 	if (nvsp_msg_pkt->hdr.msg_type == nvsp_msg_type_init_complete
 		|| nvsp_msg_pkt->hdr.msg_type
@@ -749,7 +748,7 @@ hv_nv_on_send_completion(netvsc_dev *net
 		    nvsp_msg_1_type_send_rndis_pkt_complete) {
 		/* Get the send context */
 		net_vsc_pkt =
-		    (netvsc_packet *)(unsigned long)pkt->transaction_id;
+		    (netvsc_packet *)(unsigned long)pkt->cph_xactid;
 		if (NULL != net_vsc_pkt) {
 			if (net_vsc_pkt->send_buf_section_idx !=
 			    NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) {
@@ -829,10 +828,10 @@ hv_nv_on_send(struct hv_vmbus_channel *c
  */
 static void
 hv_nv_on_receive(netvsc_dev *net_dev, struct hn_softc *sc,
-    struct hv_vmbus_channel *chan, hv_vm_packet_descriptor *pkt)
+    struct hv_vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkthdr)
 {
-	hv_vm_transfer_page_packet_header *vm_xfer_page_pkt;
-	nvsp_msg *nvsp_msg_pkt;
+	const struct vmbus_chanpkt_rxbuf *pkt;
+	const nvsp_msg *nvsp_msg_pkt;
 	netvsc_packet vsc_pkt;
 	netvsc_packet *net_vsc_pkt = &vsc_pkt;
 	device_t dev = sc->hn_dev;
@@ -840,43 +839,31 @@ hv_nv_on_receive(netvsc_dev *net_dev, st
 	int i = 0;
 	int status = nvsp_status_success;
 
-	/*
-	 * All inbound packets other than send completion should be
-	 * xfer page packet.
-	 */
-	if (pkt->type != VMBUS_CHANPKT_TYPE_RXBUF) {
-		device_printf(dev, "packet type %d is invalid!\n", pkt->type);
-		return;
-	}
-
-	nvsp_msg_pkt = (nvsp_msg *)((unsigned long)pkt
-		+ (pkt->data_offset8 << 3));
+	nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkthdr);
 
 	/* Make sure this is a valid nvsp packet */
 	if (nvsp_msg_pkt->hdr.msg_type != nvsp_msg_1_type_send_rndis_pkt) {
-		device_printf(dev, "packet hdr type %d is invalid!\n",
-		    pkt->type);
+		device_printf(dev, "packet hdr type %u is invalid!\n",
+		    nvsp_msg_pkt->hdr.msg_type);
 		return;
 	}
 	
-	vm_xfer_page_pkt = (hv_vm_transfer_page_packet_header *)pkt;
+	pkt = (const struct vmbus_chanpkt_rxbuf *)pkthdr;
 
-	if (vm_xfer_page_pkt->transfer_page_set_id !=
-	    NETVSC_RECEIVE_BUFFER_ID) {
-		device_printf(dev, "transfer_page_set_id %d is invalid!\n",
-		    vm_xfer_page_pkt->transfer_page_set_id);
+	if (pkt->cp_rxbuf_id != NETVSC_RECEIVE_BUFFER_ID) {
+		device_printf(dev, "rxbuf_id %d is invalid!\n",
+		    pkt->cp_rxbuf_id);
 		return;
 	}
 
-	count = vm_xfer_page_pkt->range_count;
+	count = pkt->cp_rxbuf_cnt;
 
 	/* Each range represents 1 RNDIS pkt that contains 1 Ethernet frame */
 	for (i = 0; i < count; i++) {
 		net_vsc_pkt->status = nvsp_status_success;
-		net_vsc_pkt->data = (void *)((unsigned long)net_dev->rx_buf +
-		    vm_xfer_page_pkt->ranges[i].byte_offset);
-		net_vsc_pkt->tot_data_buf_len = 
-		    vm_xfer_page_pkt->ranges[i].byte_count;
+		net_vsc_pkt->data = ((uint8_t *)net_dev->rx_buf +
+		    pkt->cp_rxbuf[i].rb_ofs);
+		net_vsc_pkt->tot_data_buf_len = pkt->cp_rxbuf[i].rb_len;
 
 		hv_rf_on_receive(net_dev, chan, net_vsc_pkt);
 		if (net_vsc_pkt->status != nvsp_status_success) {
@@ -889,8 +876,7 @@ hv_nv_on_receive(netvsc_dev *net_dev, st
 	 * messages (not just data messages) will trigger a response
 	 * message back to the host.
 	 */
-	hv_nv_on_receive_completion(chan, vm_xfer_page_pkt->d.transaction_id,
-	    status);
+	hv_nv_on_receive_completion(chan, pkt->cp_hdr.cph_xactid, status);
 }
 
 /*
@@ -934,19 +920,19 @@ retry_send_cmplt:
  * Net VSC receiving vRSS send table from VSP
  */
 static void
-hv_nv_send_table(struct hn_softc *sc, hv_vm_packet_descriptor *pkt)
+hv_nv_send_table(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt)
 {
 	netvsc_dev *net_dev;
-	nvsp_msg *nvsp_msg_pkt;
+	const nvsp_msg *nvsp_msg_pkt;
 	int i;
-	uint32_t count, *table;
+	uint32_t count;
+	const uint32_t *table;
 
 	net_dev = hv_nv_get_inbound_net_device(sc);
 	if (!net_dev)
         	return;
 
-	nvsp_msg_pkt =
-	    (nvsp_msg *)((unsigned long)pkt + (pkt->data_offset8 << 3));
+	nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkt);
 
 	if (nvsp_msg_pkt->hdr.msg_type !=
 	    nvsp_msg5_type_send_indirection_table) {
@@ -962,8 +948,8 @@ hv_nv_send_table(struct hn_softc *sc, hv
 	        return;
 	}
 
-	table = (uint32_t *)
-	    ((unsigned long)&nvsp_msg_pkt->msgs.vers_5_msgs.send_table +
+	table = (const uint32_t *)
+	    ((const uint8_t *)&nvsp_msg_pkt->msgs.vers_5_msgs.send_table +
 	     nvsp_msg_pkt->msgs.vers_5_msgs.send_table.offset);
 
 	for (i = 0; i < count; i++)
@@ -980,44 +966,40 @@ hv_nv_on_channel_callback(void *xchan)
 	device_t dev = chan->ch_dev;
 	struct hn_softc *sc = device_get_softc(dev);
 	netvsc_dev *net_dev;
-	uint32_t bytes_rxed;
-	uint64_t request_id;
- 	hv_vm_packet_descriptor *desc;
-	uint8_t *buffer;
+	void *buffer;
 	int bufferlen = NETVSC_PACKET_SIZE;
-	int ret = 0;
 
 	net_dev = hv_nv_get_inbound_net_device(sc);
 	if (net_dev == NULL)
 		return;
 
 	buffer = chan->hv_chan_rdbuf;
-
 	do {
-		ret = hv_vmbus_channel_recv_packet_raw(chan,
-		    buffer, bufferlen, &bytes_rxed, &request_id);
+		struct vmbus_chanpkt_hdr *pkt = buffer;
+		uint32_t bytes_rxed;
+		int ret;
+
+		bytes_rxed = bufferlen;
+		ret = vmbus_chan_recv_pkt(chan, pkt, &bytes_rxed);
 		if (ret == 0) {
 			if (bytes_rxed > 0) {
-				desc = (hv_vm_packet_descriptor *)buffer;
-				switch (desc->type) {
+				switch (pkt->cph_type) {
 				case VMBUS_CHANPKT_TYPE_COMP:
 					hv_nv_on_send_completion(net_dev, chan,
-					    desc);
+					    pkt);
 					break;
 				case VMBUS_CHANPKT_TYPE_RXBUF:
-					hv_nv_on_receive(net_dev, sc, chan, desc);
+					hv_nv_on_receive(net_dev, sc, chan, pkt);
 					break;
 				case VMBUS_CHANPKT_TYPE_INBAND:
-					hv_nv_send_table(sc, desc);
+					hv_nv_send_table(sc, pkt);
 					break;
 				default:
 					device_printf(dev,
-					    "hv_cb recv unknow type %d "
-					    " packet\n", desc->type);
+					    "unknown chan pkt %u\n",
+					    pkt->cph_type);
 					break;
 				}
-			} else {
-				break;
 			}
 		} else if (ret == ENOBUFS) {
 			/* Handle large packet */
@@ -1036,6 +1018,9 @@ hv_nv_on_channel_callback(void *xchan)
 				break;
 			}
 			bufferlen = bytes_rxed;
+		} else {
+			/* No more packets */
+			break;
 		}
 	} while (1);
 

Modified: head/sys/dev/hyperv/vmbus/hv_channel.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_channel.c	Fri Jul 15 07:45:30 2016	(r302885)
+++ head/sys/dev/hyperv/vmbus/hv_channel.c	Fri Jul 15 07:53:45 2016	(r302886)
@@ -751,7 +751,7 @@ vmbus_chan_recv(struct hv_vmbus_channel 
 	dlen = VMBUS_CHANPKT_GETLEN(pkt.cph_tlen) - hlen;
 
 	if (*dlen0 < dlen) {
-		/* Return the size of this packet. */
+		/* Return the size of this packet's data. */
 		*dlen0 = dlen;
 		return ENOBUFS;
 	}
@@ -759,49 +759,37 @@ vmbus_chan_recv(struct hv_vmbus_channel 
 	*xactid = pkt.cph_xactid;
 	*dlen0 = dlen;
 
+	/* Skip packet header */
 	error = hv_ring_buffer_read(&chan->inbound, data, dlen, hlen);
 	KASSERT(!error, ("hv_ring_buffer_read failed"));
 
 	return 0;
 }
 
-/**
- * @brief Retrieve the raw packet on the specified channel
- */
 int
-hv_vmbus_channel_recv_packet_raw(
-	hv_vmbus_channel*	channel,
-	void*			buffer,
-	uint32_t		buffer_len,
-	uint32_t*		buffer_actual_len,
-	uint64_t*		request_id)
+vmbus_chan_recv_pkt(struct hv_vmbus_channel *chan,
+    struct vmbus_chanpkt_hdr *pkt0, int *pktlen0)
 {
-	int		ret;
-	uint32_t	packetLen;
-	hv_vm_packet_descriptor	desc;
-
-	*buffer_actual_len = 0;
-	*request_id = 0;
-
-	ret = hv_ring_buffer_peek(
-		&channel->inbound, &desc,
-		sizeof(hv_vm_packet_descriptor));
-
-	if (ret != 0)
-	    return (0);
+	struct vmbus_chanpkt_hdr pkt;
+	int error, pktlen;
 
-	packetLen = desc.length8 << 3;
-	*buffer_actual_len = packetLen;
+	error = hv_ring_buffer_peek(&chan->inbound, &pkt, sizeof(pkt));
+	if (error)
+		return error;
 
-	if (packetLen > buffer_len)
-	    return (ENOBUFS);
-
-	*request_id = desc.transaction_id;
+	pktlen = VMBUS_CHANPKT_GETLEN(pkt.cph_tlen);
+	if (*pktlen0 < pktlen) {
+		/* Return the size of this packet. */
+		*pktlen0 = pktlen;
+		return ENOBUFS;
+	}
+	*pktlen0 = pktlen;
 
-	/* Copy over the entire packet to the user buffer */
-	ret = hv_ring_buffer_read(&channel->inbound, buffer, packetLen, 0);
+	/* Include packet header */
+	error = hv_ring_buffer_read(&chan->inbound, pkt0, pktlen, 0);
+	KASSERT(!error, ("hv_ring_buffer_read failed"));
 
-	return (0);
+	return 0;
 }
 
 static void

Modified: head/sys/dev/hyperv/vmbus/vmbus_reg.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus_reg.h	Fri Jul 15 07:45:30 2016	(r302885)
+++ head/sys/dev/hyperv/vmbus/vmbus_reg.h	Fri Jul 15 07:53:45 2016	(r302886)
@@ -112,7 +112,6 @@ CTASSERT(sizeof(struct vmbus_mnf) == PAG
  * Channel packets
  */
 
-#define VMBUS_CHANPKT_SIZE_SHIFT	3
 #define VMBUS_CHANPKT_SIZE_ALIGN	(1 << VMBUS_CHANPKT_SIZE_SHIFT)
 
 #define VMBUS_CHANPKT_SETLEN(pktlen, len)		\
@@ -120,20 +119,9 @@ do {							\
 	(pktlen) = (len) >> VMBUS_CHANPKT_SIZE_SHIFT;	\
 } while (0)
 
-#define VMBUS_CHANPKT_GETLEN(pktlen)	\
-	(((int)(pktlen)) << VMBUS_CHANPKT_SIZE_SHIFT)
-
 #define VMBUS_CHANPKT_TOTLEN(tlen)	\
 	roundup2((tlen), VMBUS_CHANPKT_SIZE_ALIGN)
 
-struct vmbus_chanpkt_hdr {
-	uint16_t	cph_type;
-	uint16_t	cph_hlen;	/* header len, in 8 bytes */
-	uint16_t	cph_tlen;	/* total len, in 8 bytes */
-	uint16_t	cph_flags;
-	uint64_t	cph_xactid;
-} __packed;
-
 struct vmbus_chanpkt {
 	struct vmbus_chanpkt_hdr cp_hdr;
 } __packed;


More information about the svn-src-all mailing list