Date: Fri, 15 Jul 2016 07:53:45 +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: r302886 - in head/sys/dev/hyperv: include netvsc vmbus Message-ID: <201607150753.u6F7rj2j031579@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201607150753.u6F7rj2j031579>