hyperv/vmbus: Cleanup channel receiving.
MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D7202
This commit is contained in:
parent
7bf5900964
commit
7c55724859
@ -298,13 +298,6 @@ hv_set_channel_read_state(hv_vmbus_channel* channel, boolean_t on)
|
||||
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,
|
||||
|
@ -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,
|
||||
|
@ -778,12 +778,10 @@ hv_storvsc_on_channel_callback(void *xchan)
|
||||
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 *xchan)
|
||||
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
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
||||
|
@ -626,8 +626,10 @@ hv_kvp_process_request(void *context, int pending)
|
||||
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, int pending)
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
||||
|
@ -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[
|
||||
|
@ -736,45 +736,33 @@ vmbus_chan_send_prplist(struct hv_vmbus_channel *chan,
|
||||
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);
|
||||
hlen = VMBUS_CHANPKT_GETLEN(pkt.cph_hlen);
|
||||
dlen = VMBUS_CHANPKT_GETLEN(pkt.cph_tlen) - hlen;
|
||||
|
||||
packet_len = desc.length8 << 3;
|
||||
user_len = packet_len - (desc.data_offset8 << 3);
|
||||
if (*dlen0 < dlen) {
|
||||
/* Return the size of this packet. */
|
||||
*dlen0 = dlen;
|
||||
return ENOBUFS;
|
||||
}
|
||||
|
||||
*buffer_actual_len = user_len;
|
||||
*xactid = pkt.cph_xactid;
|
||||
*dlen0 = dlen;
|
||||
|
||||
if (user_len > buffer_len)
|
||||
return (EINVAL);
|
||||
error = hv_ring_buffer_read(&chan->inbound, data, dlen, hlen);
|
||||
KASSERT(!error, ("hv_ring_buffer_read failed"));
|
||||
|
||||
*request_id = desc.transaction_id;
|
||||
|
||||
/* Copy over the packet to the user buffer */
|
||||
ret = hv_ring_buffer_read(&channel->inbound, Buffer, user_len,
|
||||
(desc.data_offset8 << 3));
|
||||
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user