X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fbus%2Fvmbus%2Fvmbus_channel.c;h=bd14c0662b465d07989f9fff78ace589b92212e6;hb=4cdc4d98313e717df7d1dba769d71e7e4050da54;hp=f9feada9b047368ad319332870fd88c4ac2bbc59;hpb=831dba47bd365b8a539dfb51fffdd01f8a436f6c;p=dpdk.git diff --git a/drivers/bus/vmbus/vmbus_channel.c b/drivers/bus/vmbus/vmbus_channel.c index f9feada9b0..bd14c0662b 100644 --- a/drivers/bus/vmbus/vmbus_channel.c +++ b/drivers/bus/vmbus/vmbus_channel.c @@ -59,6 +59,32 @@ vmbus_set_event(const struct rte_vmbus_device *dev, vmbus_set_monitor(dev, chan->monitor_id); } +/* + * Set the wait between when hypervisor examines the trigger. + */ +void +rte_vmbus_set_latency(const struct rte_vmbus_device *dev, + const struct vmbus_channel *chan, + uint32_t latency) +{ + uint32_t trig_idx = chan->monitor_id / VMBUS_MONTRIG_LEN; + uint32_t trig_offs = chan->monitor_id % VMBUS_MONTRIG_LEN; + + if (latency >= UINT16_MAX * 100) { + VMBUS_LOG(ERR, "invalid latency value %u", latency); + return; + } + + if (trig_idx >= VMBUS_MONTRIGS_MAX) { + VMBUS_LOG(ERR, "invalid monitor trigger %u", + trig_idx); + return; + } + + /* Host value is expressed in 100 nanosecond units */ + dev->monitor_page->lat[trig_idx][trig_offs] = latency / 100; +} + /* * Notify host that there are data pending on our TX bufring. * @@ -176,49 +202,37 @@ bool rte_vmbus_chan_rx_empty(const struct vmbus_channel *channel) return br->vbr->rindex == br->vbr->windex; } -static int vmbus_read_and_signal(struct vmbus_channel *chan, - void *data, size_t dlen, size_t skip) +/* Signal host after reading N bytes */ +void rte_vmbus_chan_signal_read(struct vmbus_channel *chan, uint32_t bytes_read) { struct vmbus_br *rbr = &chan->rxbr; - uint32_t write_sz, pending_sz, bytes_read; - int error; - - /* Record where host was when we started read (for debug) */ - rbr->windex = rbr->vbr->windex; - - /* Read data and skip packet header */ - error = vmbus_rxbr_read(rbr, data, dlen, skip); - if (error) - return error; + uint32_t write_sz, pending_sz; /* No need for signaling on older versions */ if (!rbr->vbr->feature_bits.feat_pending_send_sz) - return 0; + return; /* Make sure reading of pending happens after new read index */ rte_mb(); pending_sz = rbr->vbr->pending_send; if (!pending_sz) - return 0; + return; rte_smp_rmb(); write_sz = vmbus_br_availwrite(rbr, rbr->vbr->windex); - bytes_read = dlen + skip + sizeof(uint64_t); /* If there was space before then host was not blocked */ if (write_sz - bytes_read > pending_sz) - return 0; + return; /* If pending write will not fit */ if (write_sz <= pending_sz) - return 0; + return; vmbus_set_event(chan->device, chan); - return 0; } -/* TODO: replace this with inplace ring buffer (no copy) */ int rte_vmbus_chan_recv(struct vmbus_channel *chan, void *data, uint32_t *len, uint64_t *request_id) { @@ -256,10 +270,16 @@ int rte_vmbus_chan_recv(struct vmbus_channel *chan, void *data, uint32_t *len, if (request_id) *request_id = pkt.xactid; - /* Read data and skip the header */ - return vmbus_read_and_signal(chan, data, dlen, hlen); + /* Read data and skip packet header */ + error = vmbus_rxbr_read(&chan->rxbr, data, dlen, hlen); + if (error) + return error; + + rte_vmbus_chan_signal_read(chan, dlen + hlen + sizeof(uint64_t)); + return 0; } +/* TODO: replace this with inplace ring buffer (no copy) */ int rte_vmbus_chan_recv_raw(struct vmbus_channel *chan, void *data, uint32_t *len) { @@ -291,8 +311,13 @@ int rte_vmbus_chan_recv_raw(struct vmbus_channel *chan, if (unlikely(dlen > bufferlen)) return -ENOBUFS; - /* Put packet header in data buffer */ - return vmbus_read_and_signal(chan, data, dlen, 0); + /* Read data and skip packet header */ + error = vmbus_rxbr_read(&chan->rxbr, data, dlen, 0); + if (error) + return error; + + /* Return the number of bytes read */ + return dlen + sizeof(uint64_t); } int vmbus_chan_create(const struct rte_vmbus_device *device,