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

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

Modified:
  head/sys/dev/hyperv/include/hyperv.h
  head/sys/dev/hyperv/include/vmbus.h
  head/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
  head/sys/dev/hyperv/utilities/hv_heartbeat.c
  head/sys/dev/hyperv/utilities/hv_kvp.c
  head/sys/dev/hyperv/utilities/hv_shutdown.c
  head/sys/dev/hyperv/utilities/hv_timesync.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:35:01 2016        
(r302884)
+++ head/sys/dev/hyperv/include/hyperv.h        Fri Jul 15 07:45:30 2016        
(r302885)
@@ -298,13 +298,6 @@ hv_set_channel_read_state(hv_vmbus_chann
                channel->ch_flags |= VMBUS_CHAN_FLAG_BATCHREAD;
 }
 
-int            hv_vmbus_channel_recv_packet(
-                               hv_vmbus_channel*       channel,
-                               void*                   buffer,
-                               uint32_t                buffer_len,
-                               uint32_t*               buffer_actual_len,
-                               uint64_t*               request_id);
-
 int            hv_vmbus_channel_recv_packet_raw(
                                hv_vmbus_channel*       channel,
                                void*                   buffer,

Modified: head/sys/dev/hyperv/include/vmbus.h
==============================================================================
--- head/sys/dev/hyperv/include/vmbus.h Fri Jul 15 07:35:01 2016        
(r302884)
+++ head/sys/dev/hyperv/include/vmbus.h Fri Jul 15 07:45:30 2016        
(r302885)
@@ -59,6 +59,9 @@ struct vmbus_gpa {
 
 struct hv_vmbus_channel;
 
+int    vmbus_chan_recv(struct hv_vmbus_channel *chan, void *data, int *dlen,
+           uint64_t *xactid);
+
 int    vmbus_chan_send(struct hv_vmbus_channel *chan, uint16_t type,
            uint16_t flags, void *data, int dlen, uint64_t xactid);
 int    vmbus_chan_send_sglist(struct hv_vmbus_channel *chan,

Modified: head/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
==============================================================================
--- head/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c        Fri Jul 15 
07:35:01 2016        (r302884)
+++ head/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c        Fri Jul 15 
07:45:30 2016        (r302885)
@@ -778,12 +778,10 @@ hv_storvsc_on_channel_callback(void *xch
        struct hv_storvsc_request *request;
        struct vstor_packet *vstor_packet;
 
-       ret = hv_vmbus_channel_recv_packet(
-                       channel,
-                       packet,
-                       roundup2(VSTOR_PKT_SIZE, 8),
-                       &bytes_recvd,
-                       &request_id);
+       bytes_recvd = roundup2(VSTOR_PKT_SIZE, 8);
+       ret = vmbus_chan_recv(channel, packet, &bytes_recvd, &request_id);
+       KASSERT(ret != ENOBUFS, ("storvsc recvbuf is not large enough"));
+       /* XXX check bytes_recvd to make sure that it contains enough data */
 
        while ((ret == 0) && (bytes_recvd > 0)) {
                request = (struct hv_storvsc_request *)(uintptr_t)request_id;
@@ -817,12 +815,16 @@ hv_storvsc_on_channel_callback(void *xch
                                break;
                        }                       
                }
-               ret = hv_vmbus_channel_recv_packet(
-                               channel,
-                               packet,
-                               roundup2(VSTOR_PKT_SIZE, 8),
-                               &bytes_recvd,
-                               &request_id);
+
+               bytes_recvd = roundup2(VSTOR_PKT_SIZE, 8),
+               ret = vmbus_chan_recv(channel, packet, &bytes_recvd,
+                   &request_id);
+               KASSERT(ret != ENOBUFS,
+                   ("storvsc recvbuf is not large enough"));
+               /*
+                * XXX check bytes_recvd to make sure that it contains
+                * enough data
+                */
        }
 }
 

Modified: head/sys/dev/hyperv/utilities/hv_heartbeat.c
==============================================================================
--- head/sys/dev/hyperv/utilities/hv_heartbeat.c        Fri Jul 15 07:35:01 
2016        (r302884)
+++ head/sys/dev/hyperv/utilities/hv_heartbeat.c        Fri Jul 15 07:45:30 
2016        (r302885)
@@ -52,7 +52,7 @@ hv_heartbeat_cb(void *context)
 {
        uint8_t*                buf;
        hv_vmbus_channel*       channel;
-       uint32_t                recvlen;
+       int                     recvlen;
        uint64_t                requestid;
        int                     ret;
 
@@ -64,8 +64,10 @@ hv_heartbeat_cb(void *context)
        buf = softc->receive_buffer;
        channel = softc->channel;
 
-       ret = hv_vmbus_channel_recv_packet(channel, buf, PAGE_SIZE, &recvlen,
-                                           &requestid);
+       recvlen = PAGE_SIZE;
+       ret = vmbus_chan_recv(channel, buf, &recvlen, &requestid);
+       KASSERT(ret != ENOBUFS, ("hvheartbeat recvbuf is not large enough"));
+       /* XXX check recvlen to make sure that it contains enough data */
 
        if ((ret == 0) && recvlen > 0) {
 

Modified: head/sys/dev/hyperv/utilities/hv_kvp.c
==============================================================================
--- head/sys/dev/hyperv/utilities/hv_kvp.c      Fri Jul 15 07:35:01 2016        
(r302884)
+++ head/sys/dev/hyperv/utilities/hv_kvp.c      Fri Jul 15 07:45:30 2016        
(r302885)
@@ -626,8 +626,10 @@ hv_kvp_process_request(void *context, in
        kvp_buf = sc->util_sc.receive_buffer;
        channel = sc->util_sc.channel;
 
-       ret = hv_vmbus_channel_recv_packet(channel, kvp_buf, 2 * PAGE_SIZE,
-               &recvlen, &requestid);
+       recvlen = 2 * PAGE_SIZE;
+       ret = vmbus_chan_recv(channel, kvp_buf, &recvlen, &requestid);
+       KASSERT(ret != ENOBUFS, ("hvkvp recvbuf is not large enough"));
+       /* XXX check recvlen to make sure that it contains enough data */
 
        while ((ret == 0) && (recvlen > 0)) {
 
@@ -691,9 +693,11 @@ hv_kvp_process_request(void *context, in
                /*
                 * Try reading next buffer
                 */
-               recvlen = 0;
-               ret = hv_vmbus_channel_recv_packet(channel, kvp_buf, 2 * 
PAGE_SIZE,
-                       &recvlen, &requestid);
+               recvlen = 2 * PAGE_SIZE;
+               ret = vmbus_chan_recv(channel, kvp_buf, &recvlen, &requestid);
+               KASSERT(ret != ENOBUFS, ("hvkvp recvbuf is not large enough"));
+               /* XXX check recvlen to make sure that it contains enough data 
*/
+
                hv_kvp_log_info("%s: read: context %p, ret =%d, recvlen=%d\n",
                        __func__, context, ret, recvlen);
        }

Modified: head/sys/dev/hyperv/utilities/hv_shutdown.c
==============================================================================
--- head/sys/dev/hyperv/utilities/hv_shutdown.c Fri Jul 15 07:35:01 2016        
(r302884)
+++ head/sys/dev/hyperv/utilities/hv_shutdown.c Fri Jul 15 07:45:30 2016        
(r302885)
@@ -67,8 +67,11 @@ hv_shutdown_cb(void *context)
        softc = (hv_util_sc*)context;
        buf = softc->receive_buffer;
        channel = softc->channel;
-       ret = hv_vmbus_channel_recv_packet(channel, buf, PAGE_SIZE,
-                                           &recv_len, &request_id);
+
+       recv_len = PAGE_SIZE;
+       ret = vmbus_chan_recv(channel, buf, &recv_len, &request_id);
+       KASSERT(ret != ENOBUFS, ("hvshutdown recvbuf is not large enough"));
+       /* XXX check recv_len to make sure that it contains enough data */
 
        if ((ret == 0) && recv_len > 0) {
 

Modified: head/sys/dev/hyperv/utilities/hv_timesync.c
==============================================================================
--- head/sys/dev/hyperv/utilities/hv_timesync.c Fri Jul 15 07:35:01 2016        
(r302884)
+++ head/sys/dev/hyperv/utilities/hv_timesync.c Fri Jul 15 07:45:30 2016        
(r302885)
@@ -144,8 +144,10 @@ hv_timesync_cb(void *context)
        channel = softc->util_sc.channel;
        time_buf = softc->util_sc.receive_buffer;
 
-       ret = hv_vmbus_channel_recv_packet(channel, time_buf,
-               PAGE_SIZE, &recvlen, &requestId);
+       recvlen = PAGE_SIZE;
+       ret = vmbus_chan_recv(channel, time_buf, &recvlen, &requestId);
+       KASSERT(ret != ENOBUFS, ("hvtimesync recvbuf is not large enough"));
+       /* XXX check recvlen to make sure that it contains enough data */
 
        if ((ret == 0) && recvlen > 0) {
            icmsghdrp = (struct hv_vmbus_icmsg_hdr *) &time_buf[

Modified: head/sys/dev/hyperv/vmbus/hv_channel.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_channel.c      Fri Jul 15 07:35:01 2016        
(r302884)
+++ head/sys/dev/hyperv/vmbus/hv_channel.c      Fri Jul 15 07:45:30 2016        
(r302885)
@@ -736,45 +736,33 @@ vmbus_chan_send_prplist(struct hv_vmbus_
        return error;
 }
 
-/**
- * @brief Retrieve the user packet on the specified channel
- */
 int
-hv_vmbus_channel_recv_packet(
-       hv_vmbus_channel*       channel,
-       void*                   Buffer,
-       uint32_t                buffer_len,
-       uint32_t*               buffer_actual_len,
-       uint64_t*               request_id)
+vmbus_chan_recv(struct hv_vmbus_channel *chan, void *data, int *dlen0,
+    uint64_t *xactid)
 {
-       int                     ret;
-       uint32_t                user_len;
-       uint32_t                packet_len;
-       hv_vm_packet_descriptor desc;
+       struct vmbus_chanpkt_hdr pkt;
+       int error, dlen, hlen;
 
-       *buffer_actual_len = 0;
-       *request_id = 0;
+       error = hv_ring_buffer_peek(&chan->inbound, &pkt, sizeof(pkt));
+       if (error)
+               return error;
 
-       ret = hv_ring_buffer_peek(&channel->inbound, &desc,
-               sizeof(hv_vm_packet_descriptor));
-       if (ret != 0)
-               return (0);
-
-       packet_len = desc.length8 << 3;
-       user_len = packet_len - (desc.data_offset8 << 3);
-
-       *buffer_actual_len = user_len;
+       hlen = VMBUS_CHANPKT_GETLEN(pkt.cph_hlen);
+       dlen = VMBUS_CHANPKT_GETLEN(pkt.cph_tlen) - hlen;
 
-       if (user_len > buffer_len)
-               return (EINVAL);
+       if (*dlen0 < dlen) {
+               /* Return the size of this packet. */
+               *dlen0 = dlen;
+               return ENOBUFS;
+       }
 
-       *request_id = desc.transaction_id;
+       *xactid = pkt.cph_xactid;
+       *dlen0 = dlen;
 
-       /* Copy over the packet to the user buffer */
-       ret = hv_ring_buffer_read(&channel->inbound, Buffer, user_len,
-               (desc.data_offset8 << 3));
+       error = hv_ring_buffer_read(&chan->inbound, data, dlen, hlen);
+       KASSERT(!error, ("hv_ring_buffer_read failed"));
 
-       return (0);
+       return 0;
 }
 
 /**

Modified: head/sys/dev/hyperv/vmbus/vmbus_reg.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus_reg.h       Fri Jul 15 07:35:01 2016        
(r302884)
+++ head/sys/dev/hyperv/vmbus/vmbus_reg.h       Fri Jul 15 07:45:30 2016        
(r302885)
@@ -120,6 +120,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)
 
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to