[dpdk-dev] [PATCH v2 7/7] virtio: add 1.0 support

2016-01-14 Thread Yuanhan Liu
Sigh... I have just send out v3 ...

On Thu, Jan 14, 2016 at 07:50:00AM +, Xie, Huawei wrote:
> On 1/12/2016 2:58 PM, Yuanhan Liu wrote:
> > +static inline void
> > +modern_write64_twopart(uint64_t val, uint32_t *lo, uint32_t *hi)
> > +{
> > +   modern_write32((uint32_t)val, lo);
> > +   modern_write32(val >> 32, hi);
> > +}
> > +
> 
> This is normal mmio read/write operation. ioread8/16/32/64 or just
> readxx is more meaningful name here.

I just want to make them looks like modern device related, which they
are.

> > +static void
> [SNIP]
> > +
> > +static void
> > +modern_write_dev_config(struct virtio_hw *hw, uint64_t offset,
> > +   void *src, int length)
> 
> define src as const

okay.

> 
> [snip]
> >  
> > +static inline void *
> > +get_cfg_addr(struct rte_pci_device *dev, struct virtio_pci_cap *cap)
> 
> No explicit inline for non performance critical functions.

okay.

> 
> > +{
> > +   uint8_t  bar= cap->bar;
> > +   uint32_t length = cap->length;
> > +   uint32_t offset = cap->offset;
> > +   uint8_t *base;
> > +
> > +   if (unlikely(bar > 5)) {
> Don't use constant value number whenever possible

I normally will not bother to define a macro for used once number,
espeically for some well known ones. Say, I won't define

#define UINT8_MAX_VALUE 0xff
> 
> No likely/unlikely for non performance critical functions

makes sense.

> > +   if (rte_eal_pci_map_device(dev) < 0) {
> > +   PMD_INIT_LOG(DEBUG, "failed to map pci device!");
> 
> s /DEBUG/ERR/

It's not an error; it's expected, say, when no UIO is bond.

--yliu


[dpdk-dev] [PATCH v2 7/7] virtio: add 1.0 support

2016-01-14 Thread Yuanhan Liu
On Thu, Jan 14, 2016 at 08:08:28AM +, Xie, Huawei wrote:
> On 1/14/2016 3:58 PM, Yuanhan Liu wrote:
> > On Thu, Jan 14, 2016 at 07:51:08AM +, Xie, Huawei wrote:
> >> On 1/14/2016 3:49 PM, Yuanhan Liu wrote:
> >>> On Thu, Jan 14, 2016 at 07:47:17AM +, Xie, Huawei wrote:
>  On 1/12/2016 2:58 PM, Yuanhan Liu wrote:
> > Modern (v1.0) virtio pci device defines several pci capabilities.
>  [snip]
> > +static void
> > +modern_notify_queue(struct virtio_hw *hw __rte_unused, struct 
> > virtqueue *vq)
> > +{
> > +   modern_write16(1, vq->notify_addr);
> > +}
>  Does virtio 1.0 only supports MMIO? MMIO has long VMEXIT latency than
>  PORT IO.
> >>> Virtio 1.0 supports three transport layer, including MMIO and PCI. And
> >>> we use PCI only in our pmd driver.
> >> I don't mean that MMIO but use memory mapped IO for configuration.
> > Then, yes.
> 
> 00:03.0 Ethernet controller: Red Hat, Inc Virtio network device
> Subsystem: Red Hat, Inc Device 0001
> Physical Slot: 3
> Flags: bus master, fast devsel, latency 0, IRQ 10
> I/O ports at c100 [size=32]
> Memory at febd1000 (32-bit, non-prefetchable) [size=4K]
> Memory at fe00 (64-bit, prefetchable) [size=8M]
> Expansion ROM at feb4 [disabled] [size=256K]
> Capabilities: [98] MSI-X: Enable+ Count=3 Masked-
> Capabilities: [84] Vendor Specific Information: Len=14 
> Capabilities: [70] Vendor Specific Information: Len=14 
> Capabilities: [60] Vendor Specific Information: Len=10 
> Capabilities: [50] Vendor Specific Information: Len=10 
> Capabilities: [40] Vendor Specific Information: Len=10 
> Kernel driver in use: igb_uio
> Kernel modules: virtio_pci
> 
> c100 is still there.

Yes,

> For the notification, try PORT IO if possible.

But it doesn't seem right to me to mix legacy registers in modern pci device.

--yliu


[dpdk-dev] [PATCH v2 7/7] virtio: add 1.0 support

2016-01-14 Thread Yuanhan Liu
On Thu, Jan 14, 2016 at 07:51:08AM +, Xie, Huawei wrote:
> On 1/14/2016 3:49 PM, Yuanhan Liu wrote:
> > On Thu, Jan 14, 2016 at 07:47:17AM +, Xie, Huawei wrote:
> >> On 1/12/2016 2:58 PM, Yuanhan Liu wrote:
> >>> Modern (v1.0) virtio pci device defines several pci capabilities.
> >> [snip]
> >>> +static void
> >>> +modern_notify_queue(struct virtio_hw *hw __rte_unused, struct virtqueue 
> >>> *vq)
> >>> +{
> >>> + modern_write16(1, vq->notify_addr);
> >>> +}
> >> Does virtio 1.0 only supports MMIO? MMIO has long VMEXIT latency than
> >> PORT IO.
> > Virtio 1.0 supports three transport layer, including MMIO and PCI. And
> > we use PCI only in our pmd driver.
> 
> I don't mean that MMIO but use memory mapped IO for configuration.

Then, yes.

--yliu


[dpdk-dev] [PATCH v2 7/7] virtio: add 1.0 support

2016-01-14 Thread Yuanhan Liu
On Thu, Jan 14, 2016 at 07:47:17AM +, Xie, Huawei wrote:
> On 1/12/2016 2:58 PM, Yuanhan Liu wrote:
> > Modern (v1.0) virtio pci device defines several pci capabilities.
> [snip]
> > +static void
> > +modern_notify_queue(struct virtio_hw *hw __rte_unused, struct virtqueue 
> > *vq)
> > +{
> > +   modern_write16(1, vq->notify_addr);
> > +}
> 
> Does virtio 1.0 only supports MMIO? MMIO has long VMEXIT latency than
> PORT IO.

Virtio 1.0 supports three transport layer, including MMIO and PCI. And
we use PCI only in our pmd driver.

--yliu


[dpdk-dev] [PATCH v2 7/7] virtio: add 1.0 support

2016-01-14 Thread Xie, Huawei
On 1/14/2016 4:21 PM, Yuanhan Liu wrote:
> On Thu, Jan 14, 2016 at 08:08:28AM +, Xie, Huawei wrote:
>> On 1/14/2016 3:58 PM, Yuanhan Liu wrote:
>>> On Thu, Jan 14, 2016 at 07:51:08AM +, Xie, Huawei wrote:
 On 1/14/2016 3:49 PM, Yuanhan Liu wrote:
> On Thu, Jan 14, 2016 at 07:47:17AM +, Xie, Huawei wrote:
>> On 1/12/2016 2:58 PM, Yuanhan Liu wrote:
>>> Modern (v1.0) virtio pci device defines several pci capabilities.
>> [snip]
>>> +static void
>>> +modern_notify_queue(struct virtio_hw *hw __rte_unused, struct 
>>> virtqueue *vq)
>>> +{
>>> +   modern_write16(1, vq->notify_addr);
>>> +}
>> Does virtio 1.0 only supports MMIO? MMIO has long VMEXIT latency than
>> PORT IO.
> Virtio 1.0 supports three transport layer, including MMIO and PCI. And
> we use PCI only in our pmd driver.
 I don't mean that MMIO but use memory mapped IO for configuration.
>>> Then, yes.
>> 00:03.0 Ethernet controller: Red Hat, Inc Virtio network device
>> Subsystem: Red Hat, Inc Device 0001
>> Physical Slot: 3
>> Flags: bus master, fast devsel, latency 0, IRQ 10
>> I/O ports at c100 [size=32]
>> Memory at febd1000 (32-bit, non-prefetchable) [size=4K]
>> Memory at fe00 (64-bit, prefetchable) [size=8M]
>> Expansion ROM at feb4 [disabled] [size=256K]
>> Capabilities: [98] MSI-X: Enable+ Count=3 Masked-
>> Capabilities: [84] Vendor Specific Information: Len=14 
>> Capabilities: [70] Vendor Specific Information: Len=14 
>> Capabilities: [60] Vendor Specific Information: Len=10 
>> Capabilities: [50] Vendor Specific Information: Len=10 
>> Capabilities: [40] Vendor Specific Information: Len=10 
>> Kernel driver in use: igb_uio
>> Kernel modules: virtio_pci
>>
>> c100 is still there.
> Yes,
>
>> For the notification, try PORT IO if possible.
> But it doesn't seem right to me to mix legacy registers in modern pci device.

On TLB and cache miss, this could cause plenty of cycles. Considering
that our current focus is dpdkvhost which doesn't need notification, let
us revisit this later.

>
>   --yliu
>



[dpdk-dev] [PATCH v2 7/7] virtio: add 1.0 support

2016-01-14 Thread Xie, Huawei
On 1/14/2016 3:58 PM, Yuanhan Liu wrote:
> On Thu, Jan 14, 2016 at 07:51:08AM +, Xie, Huawei wrote:
>> On 1/14/2016 3:49 PM, Yuanhan Liu wrote:
>>> On Thu, Jan 14, 2016 at 07:47:17AM +, Xie, Huawei wrote:
 On 1/12/2016 2:58 PM, Yuanhan Liu wrote:
> Modern (v1.0) virtio pci device defines several pci capabilities.
 [snip]
> +static void
> +modern_notify_queue(struct virtio_hw *hw __rte_unused, struct virtqueue 
> *vq)
> +{
> + modern_write16(1, vq->notify_addr);
> +}
 Does virtio 1.0 only supports MMIO? MMIO has long VMEXIT latency than
 PORT IO.
>>> Virtio 1.0 supports three transport layer, including MMIO and PCI. And
>>> we use PCI only in our pmd driver.
>> I don't mean that MMIO but use memory mapped IO for configuration.
> Then, yes.

00:03.0 Ethernet controller: Red Hat, Inc Virtio network device
Subsystem: Red Hat, Inc Device 0001
Physical Slot: 3
Flags: bus master, fast devsel, latency 0, IRQ 10
I/O ports at c100 [size=32]
Memory at febd1000 (32-bit, non-prefetchable) [size=4K]
Memory at fe00 (64-bit, prefetchable) [size=8M]
Expansion ROM at feb4 [disabled] [size=256K]
Capabilities: [98] MSI-X: Enable+ Count=3 Masked-
Capabilities: [84] Vendor Specific Information: Len=14 
Capabilities: [70] Vendor Specific Information: Len=14 
Capabilities: [60] Vendor Specific Information: Len=10 
Capabilities: [50] Vendor Specific Information: Len=10 
Capabilities: [40] Vendor Specific Information: Len=10 
Kernel driver in use: igb_uio
Kernel modules: virtio_pci

c100 is still there. For the notification, try PORT IO if possible.

>
>   --yliu
>



[dpdk-dev] [PATCH v2 7/7] virtio: add 1.0 support

2016-01-14 Thread Xie, Huawei
On 1/14/2016 3:49 PM, Yuanhan Liu wrote:
> On Thu, Jan 14, 2016 at 07:47:17AM +, Xie, Huawei wrote:
>> On 1/12/2016 2:58 PM, Yuanhan Liu wrote:
>>> Modern (v1.0) virtio pci device defines several pci capabilities.
>> [snip]
>>> +static void
>>> +modern_notify_queue(struct virtio_hw *hw __rte_unused, struct virtqueue 
>>> *vq)
>>> +{
>>> +   modern_write16(1, vq->notify_addr);
>>> +}
>> Does virtio 1.0 only supports MMIO? MMIO has long VMEXIT latency than
>> PORT IO.
> Virtio 1.0 supports three transport layer, including MMIO and PCI. And
> we use PCI only in our pmd driver.

I don't mean that MMIO but use memory mapped IO for configuration.

>
>   --yliu
>



[dpdk-dev] [PATCH v2 7/7] virtio: add 1.0 support

2016-01-14 Thread Xie, Huawei
On 1/12/2016 2:58 PM, Yuanhan Liu wrote:
> Modern (v1.0) virtio pci device defines several pci capabilities.
> Each cap has a configure structure corresponding to it, and the
> cap.bar and cap.offset fields tell us where to find it.
>
> Firstly, we map the pci resources by rte_eal_pci_map_device().
> We then could easily locate to a cfg structure by:

s/Locate/Locate to/

>
> cfg_addr = dev->mem_resources[cap.bar].addr + cap.offset;
>
> Therefore, the entrance of enabling modern (v1.0) pci device support
> is to iterate the pci capability lists, and to locate some configs
> we care; and they are:
>
> - common cfg
>
>   For generic virtio and virtuqueu configuration, such as setting/getting

typo for virtqueue

>   features, enabling a specific queue, and so on.
>
> - nofity cfg
>
>   Combining with `queue_notify_off' from common cfg, we could use it to
>   notify a specific virt queue.
>
> - device cfg
>
>   Where virtio_net_config structure locates.
is located
> If any of above cap is not found, we fallback to the legacy virtio
>
[SNIP]
>  
>  
>  
> +#define MODERN_READ_DEF(nr_bits, type)   \
> +static inline type   \
> +modern_read##nr_bits(type *addr) \
> +{\
> + return *(volatile type *)addr;  \
> +}
> +
> +#define MODERN_WRITE_DEF(nr_bits, type)  \
> +static inline void   \
> +modern_write##nr_bits(type val, type *addr)  \
> +{\
> + *(volatile type *)addr = val;   \
> +}
> +
> +MODERN_READ_DEF (8, uint8_t)
> +MODERN_WRITE_DEF(8, uint8_t)
> +
> +MODERN_READ_DEF (16, uint16_t)
> +MODERN_WRITE_DEF(16, uint16_t)
> +
> +MODERN_READ_DEF (32, uint32_t)
> +MODERN_WRITE_DEF(32, uint32_t)
> +
> +static inline void
> +modern_write64_twopart(uint64_t val, uint32_t *lo, uint32_t *hi)
> +{
> + modern_write32((uint32_t)val, lo);
> + modern_write32(val >> 32, hi);
> +}
> +

This is normal mmio read/write operation. ioread8/16/32/64 or just
readxx is more meaningful name here.
> +static void
[SNIP]
> +
> +static void
> +modern_write_dev_config(struct virtio_hw *hw, uint64_t offset,
> + void *src, int length)

define src as const

[snip]
>  
> +static inline void *
> +get_cfg_addr(struct rte_pci_device *dev, struct virtio_pci_cap *cap)

No explicit inline for non performance critical functions.

> +{
> + uint8_t  bar= cap->bar;
> + uint32_t length = cap->length;
> + uint32_t offset = cap->offset;
> + uint8_t *base;
> +
> + if (unlikely(bar > 5)) {
Don't use constant value number whenever possible

No likely/unlikely for non performance critical functions

> + PMD_INIT_LOG(ERR, "invalid bar: %u", bar);
> + return NULL;
> + }
> +
> + if (unlikely(offset + length > dev->mem_resource[bar].len)) {
> + PMD_INIT_LOG(ERR,
> + "invalid cap: overflows bar space: %u > %"PRIu64,
> + offset + length, dev->mem_resource[bar].len);
> + return NULL;
> + }
> +
> + base = dev->mem_resource[bar].addr;
> + if (unlikely(base == NULL)) {
> + PMD_INIT_LOG(ERR, "bar %u base addr is NULL", bar);
> + return NULL;
> + }
> +
> + return base + offset;
> +}
> +
> +static int
> +virtio_read_caps(struct rte_pci_device *dev, struct virtio_hw *hw)
> +{
> + uint8_t pos;
> + struct virtio_pci_cap cap;
> + int ret;
> +
> + if (rte_eal_pci_map_device(dev) < 0) {
> + PMD_INIT_LOG(DEBUG, "failed to map pci device!");

s /DEBUG/ERR/
> + return -1;
> + }
> +
> + ret = rte_eal_pci_read_config(dev, , 1, PCI_CAPABILITY_LIST);
> + 
[snip]



[dpdk-dev] [PATCH v2 7/7] virtio: add 1.0 support

2016-01-14 Thread Xie, Huawei
On 1/12/2016 2:58 PM, Yuanhan Liu wrote:
> Modern (v1.0) virtio pci device defines several pci capabilities.
[snip]
> +static void
> +modern_notify_queue(struct virtio_hw *hw __rte_unused, struct virtqueue *vq)
> +{
> + modern_write16(1, vq->notify_addr);
> +}

Does virtio 1.0 only supports MMIO? MMIO has long VMEXIT latency than
PORT IO.

[snip]


[dpdk-dev] [PATCH v2 7/7] virtio: add 1.0 support

2016-01-13 Thread Yuanhan Liu
On Wed, Jan 13, 2016 at 12:31:43PM +0900, Tetsuya Mukawa wrote:
> On 2016/01/12 15:59, Yuanhan Liu wrote:
> > +static int
> > +virtio_read_caps(struct rte_pci_device *dev, struct virtio_hw *hw)
> > +{
> > +   uint8_t pos;
> > +   struct virtio_pci_cap cap;
> > +   int ret;
> > +
> > +   if (rte_eal_pci_map_device(dev) < 0) {
> > +   PMD_INIT_LOG(DEBUG, "failed to map pci device!");
> > +   return -1;
> > +   }
> > +
> 
> Do you need to call rte_eal_pci_unmap_device() in somewhere in this file?

Yes, we should. I will see where I can find a proper place for it in
next version; eth_virtio_dev_uninit sounds like a good option.

> Anyway, I've reviewed and tested your all patches.
> And it seems except for it, I guess your patches are good.

Thank you for reviewing and testing it!

--yliu


[dpdk-dev] [PATCH v2 7/7] virtio: add 1.0 support

2016-01-13 Thread Tetsuya Mukawa
On 2016/01/12 15:59, Yuanhan Liu wrote:
> +static int
> +virtio_read_caps(struct rte_pci_device *dev, struct virtio_hw *hw)
> +{
> + uint8_t pos;
> + struct virtio_pci_cap cap;
> + int ret;
> +
> + if (rte_eal_pci_map_device(dev) < 0) {
> + PMD_INIT_LOG(DEBUG, "failed to map pci device!");
> + return -1;
> + }
> +

Do you need to call rte_eal_pci_unmap_device() in somewhere in this file?

Anyway, I've reviewed and tested your all patches.
And it seems except for it, I guess your patches are good.

Thanks,
Tetsuya




[dpdk-dev] [PATCH v2 7/7] virtio: add 1.0 support

2016-01-12 Thread Yuanhan Liu
Modern (v1.0) virtio pci device defines several pci capabilities.
Each cap has a configure structure corresponding to it, and the
cap.bar and cap.offset fields tell us where to find it.

Firstly, we map the pci resources by rte_eal_pci_map_device().
We then could easily locate to a cfg structure by:

cfg_addr = dev->mem_resources[cap.bar].addr + cap.offset;

Therefore, the entrance of enabling modern (v1.0) pci device support
is to iterate the pci capability lists, and to locate some configs
we care; and they are:

- common cfg

  For generic virtio and virtuqueu configuration, such as setting/getting
  features, enabling a specific queue, and so on.

- nofity cfg

  Combining with `queue_notify_off' from common cfg, we could use it to
  notify a specific virt queue.

- device cfg

  Where virtio_net_config structure locates.

- isr cfg

  Where to read isr (interrupt status).

If any of above cap is not found, we fallback to the legacy virtio
handling.

If succeed, hw->vtpci_ops is assigned to modern_ops, where all
operations are implemented by reading/writing a (or few) specific
configuration space from above 4 cfg structures. And that's basically
how this patch works.

Besides those changes, virtio 1.0 introduces a new status field:
FEATURES_OK, which is set after features negotiation is done.

Last, set the VIRTIO_F_VERSION_1 feature flag.

Signed-off-by: Yuanhan Liu 
---

v2: - re-read status after setting FEATURES_OK to make sure status is
  set correctly.

- Add isr reading and config irq setting support.

- Define some pci macro on our own to not get the dependency of
  linux/pci_regs.h, as there should be no such file at non-Linux
  platform
---
 doc/guides/rel_notes/release_2_3.rst |   3 +
 drivers/net/virtio/virtio_ethdev.c   |  24 ++-
 drivers/net/virtio/virtio_ethdev.h   |   3 +-
 drivers/net/virtio/virtio_pci.c  | 335 ++-
 drivers/net/virtio/virtio_pci.h  |  67 +++
 drivers/net/virtio/virtqueue.h   |   2 +
 6 files changed, 429 insertions(+), 5 deletions(-)

diff --git a/doc/guides/rel_notes/release_2_3.rst 
b/doc/guides/rel_notes/release_2_3.rst
index 99de186..c390d97 100644
--- a/doc/guides/rel_notes/release_2_3.rst
+++ b/doc/guides/rel_notes/release_2_3.rst
@@ -4,6 +4,9 @@ DPDK Release 2.3
 New Features
 

+* **Virtio 1.0 support.**
+
+  Enabled virtio 1.0 support for virtio pmd driver.

 Resolved Issues
 ---
diff --git a/drivers/net/virtio/virtio_ethdev.c 
b/drivers/net/virtio/virtio_ethdev.c
index 94e0c4a..1afaba4 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -927,7 +927,7 @@ virtio_vlan_filter_set(struct rte_eth_dev *dev, uint16_t 
vlan_id, int on)
return virtio_send_command(hw->cvq, , , 1);
 }

-static void
+static int
 virtio_negotiate_features(struct virtio_hw *hw)
 {
uint64_t host_features;
@@ -949,6 +949,22 @@ virtio_negotiate_features(struct virtio_hw *hw)
hw->guest_features = vtpci_negotiate_features(hw, host_features);
PMD_INIT_LOG(DEBUG, "features after negotiate = %"PRIx64,
hw->guest_features);
+
+   if (hw->modern) {
+   if (!vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) {
+   PMD_INIT_LOG(ERR,
+   "VIRTIO_F_VERSION_1 features is not enabled.");
+   return -1;
+   }
+   vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_FEATURES_OK);
+   if (!(vtpci_get_status(hw) & VIRTIO_CONFIG_STATUS_FEATURES_OK)) 
{
+   PMD_INIT_LOG(ERR,
+   "failed to set FEATURES_OK status!");
+   return -1;
+   }
+   }
+
+   return 0;
 }

 /*
@@ -1032,7 +1048,8 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)

/* Tell the host we've known how to drive the device. */
vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER);
-   virtio_negotiate_features(hw);
+   if (virtio_negotiate_features(hw) < 0)
+   return -1;

/* If host does not support status then disable LSC */
if (!vtpci_with_feature(hw, VIRTIO_NET_F_STATUS))
@@ -1043,7 +1060,8 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
rx_func_get(eth_dev);

/* Setting up rx_header size for the device */
-   if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF))
+   if (vtpci_with_feature(hw, VIRTIO_NET_F_MRG_RXBUF) ||
+   vtpci_with_feature(hw, VIRTIO_F_VERSION_1))
hw->vtnet_hdr_size = sizeof(struct virtio_net_hdr_mrg_rxbuf);
else
hw->vtnet_hdr_size = sizeof(struct virtio_net_hdr);
diff --git a/drivers/net/virtio/virtio_ethdev.h 
b/drivers/net/virtio/virtio_ethdev.h
index ae2d47d..fed9571 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -64,7 +64,8 @@
 1u << VIRTIO_NET_F_CTRL_VQ   | \
 1u