X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fbus%2Fvmbus%2Fvmbus_channel.c;h=119b9b367e1701dd066135ef98b999af9d47f185;hb=a5a0a43bc62ed5c735ae482dbc4d8a7af4b95eab;hp=cc5f3e8379a58463e0006b0d081044cf73c07288;hpb=530af95a7849f9dc8d8c4631f99396da5a29f48e;p=dpdk.git diff --git a/drivers/bus/vmbus/vmbus_channel.c b/drivers/bus/vmbus/vmbus_channel.c index cc5f3e8379..119b9b367e 100644 --- a/drivers/bus/vmbus/vmbus_channel.c +++ b/drivers/bus/vmbus/vmbus_channel.c @@ -26,18 +26,6 @@ vmbus_sync_set_bit(volatile uint32_t *addr, uint32_t mask) __sync_or_and_fetch(addr, mask); } -static inline void -vmbus_send_interrupt(const struct rte_vmbus_device *dev, uint32_t relid) -{ - uint32_t *int_addr; - uint32_t int_mask; - - int_addr = dev->int_page + relid / 32; - int_mask = 1u << (relid % 32); - - vmbus_sync_set_bit(int_addr, int_mask); -} - static inline void vmbus_set_monitor(const struct rte_vmbus_device *dev, uint32_t monitor_id) { @@ -55,10 +43,35 @@ static void vmbus_set_event(const struct rte_vmbus_device *dev, const struct vmbus_channel *chan) { - vmbus_send_interrupt(dev, chan->relid); 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. * @@ -173,6 +186,7 @@ bool rte_vmbus_chan_rx_empty(const struct vmbus_channel *channel) { const struct vmbus_br *br = &channel->rxbr; + rte_smp_rmb(); return br->vbr->rindex == br->vbr->windex; } @@ -187,7 +201,7 @@ void rte_vmbus_chan_signal_read(struct vmbus_channel *chan, uint32_t bytes_read) return; /* Make sure reading of pending happens after new read index */ - rte_mb(); + rte_smp_mb(); pending_sz = rbr->vbr->pending_send; if (!pending_sz) @@ -326,8 +340,15 @@ int vmbus_chan_create(const struct rte_vmbus_device *device, int rte_vmbus_chan_open(struct rte_vmbus_device *device, struct vmbus_channel **new_chan) { + struct mapped_vmbus_resource *uio_res; int err; + uio_res = vmbus_uio_find_resource(device); + if (!uio_res) { + VMBUS_LOG(ERR, "can't find uio resource"); + return -EINVAL; + } + err = vmbus_chan_create(device, device->relid, 0, device->monitor_id, new_chan); if (!err) @@ -370,11 +391,16 @@ void rte_vmbus_chan_close(struct vmbus_channel *chan) const struct rte_vmbus_device *device = chan->device; struct vmbus_channel *primary = device->primary; - if (chan != primary) + /* + * intentionally leak primary channel because + * secondary may still reference it + */ + if (chan != primary) { STAILQ_REMOVE(&primary->subchannel_list, chan, vmbus_channel, next); + rte_free(chan); + } - rte_free(chan); } static void vmbus_dump_ring(FILE *f, const char *id, const struct vmbus_br *br)