* [dpdk-dev] [PATCH 0/4] Virtio fixes
@ 2019-01-22 17:01 Tiwei Bie
2019-01-22 17:01 ` [dpdk-dev] [PATCH 1/4] net/virtio: fix the control vq support Tiwei Bie
` (4 more replies)
0 siblings, 5 replies; 14+ messages in thread
From: Tiwei Bie @ 2019-01-22 17:01 UTC (permalink / raw)
To: maxime.coquelin, zhihong.wang, dev
Tiwei Bie (4):
net/virtio: fix the control vq support
net/virtio-user: fix the control vq support
net/virtio: use virtio barrier in packed ring
net/virtio-user: fix used ring update in cvq handling
drivers/net/virtio/virtio_ethdev.c | 73 ++++++++++---------
drivers/net/virtio/virtio_rxtx.c | 4 +-
.../net/virtio/virtio_user/virtio_user_dev.c | 39 +++++-----
drivers/net/virtio/virtio_user_ethdev.c | 7 +-
drivers/net/virtio/virtqueue.h | 12 +--
5 files changed, 68 insertions(+), 67 deletions(-)
--
2.17.1
^ permalink raw reply [flat|nested] 14+ messages in thread
* [dpdk-dev] [PATCH 1/4] net/virtio: fix the control vq support
2019-01-22 17:01 [dpdk-dev] [PATCH 0/4] Virtio fixes Tiwei Bie
@ 2019-01-22 17:01 ` Tiwei Bie
[not found] ` <CGME20190123130903eucas1p2730776e71039a79024dd7602b5dcad7d@eucas1p2.samsung.com>
2019-01-23 22:03 ` [dpdk-dev] [PATCH 1/4] " Maxime Coquelin
2019-01-22 17:01 ` [dpdk-dev] [PATCH 2/4] net/virtio-user: " Tiwei Bie
` (3 subsequent siblings)
4 siblings, 2 replies; 14+ messages in thread
From: Tiwei Bie @ 2019-01-22 17:01 UTC (permalink / raw)
To: maxime.coquelin, zhihong.wang, dev
This patch mainly fixed below issues in the packed ring based
control vq support in virtio driver:
1. When parsing the used descriptors, we have to track the
number of descs that we need to skip;
2. vq->vq_free_cnt was decreased twice for a same desc;
Meanwhile, make the function name consistent with other parts.
Fixes: ec194c2f1895 ("net/virtio: support packed queue in send command")
Fixes: a4270ea4ff79 ("net/virtio: check head desc with correct wrap counter")
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
drivers/net/virtio/virtio_ethdev.c | 62 ++++++++++++++----------------
drivers/net/virtio/virtqueue.h | 12 +-----
2 files changed, 31 insertions(+), 43 deletions(-)
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index ee5a98b7c..a3fe65599 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -142,16 +142,17 @@ static const struct rte_virtio_xstats_name_off rte_virtio_txq_stat_strings[] = {
struct virtio_hw_internal virtio_hw_internal[RTE_MAX_ETHPORTS];
static struct virtio_pmd_ctrl *
-virtio_pq_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
- int *dlen, int pkt_num)
+virtio_send_command_packed(struct virtnet_ctl *cvq,
+ struct virtio_pmd_ctrl *ctrl,
+ int *dlen, int pkt_num)
{
struct virtqueue *vq = cvq->vq;
int head;
struct vring_packed_desc *desc = vq->ring_packed.desc_packed;
struct virtio_pmd_ctrl *result;
- bool avail_wrap_counter, used_wrap_counter;
- uint16_t flags;
+ bool avail_wrap_counter;
int sum = 0;
+ int nb_descs = 0;
int k;
/*
@@ -162,11 +163,10 @@ virtio_pq_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
*/
head = vq->vq_avail_idx;
avail_wrap_counter = vq->avail_wrap_counter;
- used_wrap_counter = vq->used_wrap_counter;
- desc[head].flags = VRING_DESC_F_NEXT;
desc[head].addr = cvq->virtio_net_hdr_mem;
desc[head].len = sizeof(struct virtio_net_ctrl_hdr);
vq->vq_free_cnt--;
+ nb_descs++;
if (++vq->vq_avail_idx >= vq->vq_nentries) {
vq->vq_avail_idx -= vq->vq_nentries;
vq->avail_wrap_counter ^= 1;
@@ -177,55 +177,51 @@ virtio_pq_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
+ sizeof(struct virtio_net_ctrl_hdr)
+ sizeof(ctrl->status) + sizeof(uint8_t) * sum;
desc[vq->vq_avail_idx].len = dlen[k];
- flags = VRING_DESC_F_NEXT;
+ desc[vq->vq_avail_idx].flags = VRING_DESC_F_NEXT |
+ VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
+ VRING_DESC_F_USED(!vq->avail_wrap_counter);
sum += dlen[k];
vq->vq_free_cnt--;
- flags |= VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
- VRING_DESC_F_USED(!vq->avail_wrap_counter);
- desc[vq->vq_avail_idx].flags = flags;
- rte_smp_wmb();
- vq->vq_free_cnt--;
+ nb_descs++;
if (++vq->vq_avail_idx >= vq->vq_nentries) {
vq->vq_avail_idx -= vq->vq_nentries;
vq->avail_wrap_counter ^= 1;
}
}
-
desc[vq->vq_avail_idx].addr = cvq->virtio_net_hdr_mem
+ sizeof(struct virtio_net_ctrl_hdr);
desc[vq->vq_avail_idx].len = sizeof(ctrl->status);
- flags = VRING_DESC_F_WRITE;
- flags |= VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
- VRING_DESC_F_USED(!vq->avail_wrap_counter);
- desc[vq->vq_avail_idx].flags = flags;
- flags = VRING_DESC_F_NEXT;
- flags |= VRING_DESC_F_AVAIL(avail_wrap_counter) |
- VRING_DESC_F_USED(!avail_wrap_counter);
- desc[head].flags = flags;
- rte_smp_wmb();
-
+ desc[vq->vq_avail_idx].flags = VRING_DESC_F_WRITE |
+ VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
+ VRING_DESC_F_USED(!vq->avail_wrap_counter);
vq->vq_free_cnt--;
+ nb_descs++;
if (++vq->vq_avail_idx >= vq->vq_nentries) {
vq->vq_avail_idx -= vq->vq_nentries;
vq->avail_wrap_counter ^= 1;
}
+ virtio_wmb(vq->hw->weak_barriers);
+ desc[head].flags = VRING_DESC_F_NEXT |
+ VRING_DESC_F_AVAIL(avail_wrap_counter) |
+ VRING_DESC_F_USED(!avail_wrap_counter);
+
+ virtio_wmb(vq->hw->weak_barriers);
virtqueue_notify(vq);
/* wait for used descriptors in virtqueue */
- do {
- rte_rmb();
+ while (!desc_is_used(&desc[head], vq))
usleep(100);
- } while (!__desc_is_used(&desc[head], used_wrap_counter));
+
+ virtio_rmb(vq->hw->weak_barriers);
/* now get used descriptors */
- while (desc_is_used(&desc[vq->vq_used_cons_idx], vq)) {
- vq->vq_free_cnt++;
- if (++vq->vq_used_cons_idx >= vq->vq_nentries) {
- vq->vq_used_cons_idx -= vq->vq_nentries;
- vq->used_wrap_counter ^= 1;
- }
+ vq->vq_free_cnt += nb_descs;
+ vq->vq_used_cons_idx += nb_descs;
+ if (vq->vq_used_cons_idx >= vq->vq_nentries) {
+ vq->vq_used_cons_idx -= vq->vq_nentries;
+ vq->used_wrap_counter ^= 1;
}
result = cvq->virtio_net_hdr_mz->addr;
@@ -266,7 +262,7 @@ virtio_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
sizeof(struct virtio_pmd_ctrl));
if (vtpci_packed_queue(vq->hw)) {
- result = virtio_pq_send_command(cvq, ctrl, dlen, pkt_num);
+ result = virtio_send_command_packed(cvq, ctrl, dlen, pkt_num);
goto out_unlock;
}
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index 7fcde5643..ca9d8e6e3 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -281,7 +281,7 @@ struct virtio_tx_region {
};
static inline int
-__desc_is_used(struct vring_packed_desc *desc, bool wrap_counter)
+desc_is_used(struct vring_packed_desc *desc, struct virtqueue *vq)
{
uint16_t used, avail, flags;
@@ -289,16 +289,9 @@ __desc_is_used(struct vring_packed_desc *desc, bool wrap_counter)
used = !!(flags & VRING_DESC_F_USED(1));
avail = !!(flags & VRING_DESC_F_AVAIL(1));
- return avail == used && used == wrap_counter;
+ return avail == used && used == vq->used_wrap_counter;
}
-static inline int
-desc_is_used(struct vring_packed_desc *desc, struct virtqueue *vq)
-{
- return __desc_is_used(desc, vq->used_wrap_counter);
-}
-
-
static inline void
vring_desc_init_packed(struct virtqueue *vq, int n)
{
@@ -354,7 +347,6 @@ virtqueue_enable_intr_packed(struct virtqueue *vq)
{
uint16_t *event_flags = &vq->ring_packed.driver_event->desc_event_flags;
-
if (vq->event_flags_shadow == RING_EVENT_FLAGS_DISABLE) {
virtio_wmb(vq->hw->weak_barriers);
vq->event_flags_shadow = RING_EVENT_FLAGS_ENABLE;
--
2.17.1
^ permalink raw reply [flat|nested] 14+ messages in thread
* [dpdk-dev] [PATCH 2/4] net/virtio-user: fix the control vq support
2019-01-22 17:01 [dpdk-dev] [PATCH 0/4] Virtio fixes Tiwei Bie
2019-01-22 17:01 ` [dpdk-dev] [PATCH 1/4] net/virtio: fix the control vq support Tiwei Bie
@ 2019-01-22 17:01 ` Tiwei Bie
2019-01-23 22:07 ` Maxime Coquelin
2019-01-22 17:01 ` [dpdk-dev] [PATCH 3/4] net/virtio: use virtio barrier in packed ring Tiwei Bie
` (2 subsequent siblings)
4 siblings, 1 reply; 14+ messages in thread
From: Tiwei Bie @ 2019-01-22 17:01 UTC (permalink / raw)
To: maxime.coquelin, zhihong.wang, dev
This patch fixed below issues in the packed ring based control
vq support in virtio user:
1. The idx_hdr should be used_idx instead of the id in the desc;
2. We just need to write out a single used descriptor for each
descriptor list;
3. The avail/used bits should be initialized to 0;
Meanwhile, make the function name consistent with other parts.
Fixes: 48a4464029a7 ("net/virtio-user: support control VQ for packed")
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
drivers/net/virtio/virtio_ethdev.c | 11 ++++++
.../net/virtio/virtio_user/virtio_user_dev.c | 37 +++++++++++--------
drivers/net/virtio/virtio_user_ethdev.c | 7 +---
3 files changed, 34 insertions(+), 21 deletions(-)
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index a3fe65599..7c4c1df00 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -224,6 +224,17 @@ virtio_send_command_packed(struct virtnet_ctl *cvq,
vq->used_wrap_counter ^= 1;
}
+ PMD_INIT_LOG(DEBUG, "vq->vq_free_cnt=%d\n"
+ "vq->vq_avail_idx=%d\n"
+ "vq->vq_used_cons_idx=%d\n"
+ "vq->avail_wrap_counter=%d\n"
+ "vq->used_wrap_counter=%d\n",
+ vq->vq_free_cnt,
+ vq->vq_avail_idx,
+ vq->vq_used_cons_idx,
+ vq->avail_wrap_counter,
+ vq->used_wrap_counter);
+
result = cvq->virtio_net_hdr_mz->addr;
return result;
}
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index c1919177d..89d287a74 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -632,9 +632,9 @@ desc_is_avail(struct vring_packed_desc *desc, bool wrap_counter)
}
static uint32_t
-virtio_user_handle_ctrl_msg_pq(struct virtio_user_dev *dev,
- struct vring_packed *vring,
- uint16_t idx_hdr)
+virtio_user_handle_ctrl_msg_packed(struct virtio_user_dev *dev,
+ struct vring_packed *vring,
+ uint16_t idx_hdr)
{
struct virtio_net_ctrl_hdr *hdr;
virtio_net_ctrl_ack status = ~0;
@@ -671,6 +671,10 @@ virtio_user_handle_ctrl_msg_pq(struct virtio_user_dev *dev,
*(virtio_net_ctrl_ack *)(uintptr_t)
vring->desc_packed[idx_status].addr = status;
+ /* Update used descriptor */
+ vring->desc_packed[idx_hdr].id = vring->desc_packed[idx_status].id;
+ vring->desc_packed[idx_hdr].len = sizeof(status);
+
return n_descs;
}
@@ -679,24 +683,25 @@ virtio_user_handle_cq_packed(struct virtio_user_dev *dev, uint16_t queue_idx)
{
struct virtio_user_queue *vq = &dev->packed_queues[queue_idx];
struct vring_packed *vring = &dev->packed_vrings[queue_idx];
- uint16_t id, n_descs;
+ uint16_t n_descs;
while (desc_is_avail(&vring->desc_packed[vq->used_idx],
vq->used_wrap_counter)) {
- id = vring->desc_packed[vq->used_idx].id;
- n_descs = virtio_user_handle_ctrl_msg_pq(dev, vring, id);
+ n_descs = virtio_user_handle_ctrl_msg_packed(dev, vring,
+ vq->used_idx);
- do {
- vring->desc_packed[vq->used_idx].flags =
- VRING_DESC_F_AVAIL(vq->used_wrap_counter) |
- VRING_DESC_F_USED(vq->used_wrap_counter);
- if (++vq->used_idx >= dev->queue_size) {
- vq->used_idx -= dev->queue_size;
- vq->used_wrap_counter ^= 1;
- }
- n_descs--;
- } while (n_descs);
+ rte_smp_wmb();
+ vring->desc_packed[vq->used_idx].flags =
+ VRING_DESC_F_WRITE |
+ VRING_DESC_F_AVAIL(vq->used_wrap_counter) |
+ VRING_DESC_F_USED(vq->used_wrap_counter);
+
+ vq->used_idx += n_descs;
+ if (vq->used_idx >= dev->queue_size) {
+ vq->used_idx -= dev->queue_size;
+ vq->used_wrap_counter ^= 1;
+ }
}
}
diff --git a/drivers/net/virtio/virtio_user_ethdev.c b/drivers/net/virtio/virtio_user_ethdev.c
index c01f45cab..6423e1f61 100644
--- a/drivers/net/virtio/virtio_user_ethdev.c
+++ b/drivers/net/virtio/virtio_user_ethdev.c
@@ -274,7 +274,6 @@ virtio_user_get_queue_num(struct virtio_hw *hw, uint16_t queue_id __rte_unused)
static void
virtio_user_setup_queue_packed(struct virtqueue *vq,
struct virtio_user_dev *dev)
-
{
uint16_t queue_idx = vq->vq_queue_index;
struct vring_packed *vring;
@@ -300,10 +299,8 @@ virtio_user_setup_queue_packed(struct virtqueue *vq,
dev->packed_queues[queue_idx].avail_wrap_counter = true;
dev->packed_queues[queue_idx].used_wrap_counter = true;
- for (i = 0; i < vring->num; i++) {
- vring->desc_packed[i].flags = VRING_DESC_F_USED(1) |
- VRING_DESC_F_AVAIL(1);
- }
+ for (i = 0; i < vring->num; i++)
+ vring->desc_packed[i].flags = 0;
}
static void
--
2.17.1
^ permalink raw reply [flat|nested] 14+ messages in thread
* [dpdk-dev] [PATCH 3/4] net/virtio: use virtio barrier in packed ring
2019-01-22 17:01 [dpdk-dev] [PATCH 0/4] Virtio fixes Tiwei Bie
2019-01-22 17:01 ` [dpdk-dev] [PATCH 1/4] net/virtio: fix the control vq support Tiwei Bie
2019-01-22 17:01 ` [dpdk-dev] [PATCH 2/4] net/virtio-user: " Tiwei Bie
@ 2019-01-22 17:01 ` Tiwei Bie
[not found] ` <CGME20190123155232eucas1p28bdd3a5c220452b81e21e48c19f3e5a7@eucas1p2.samsung.com>
2019-01-23 22:09 ` [dpdk-dev] [PATCH 3/4] " Maxime Coquelin
2019-01-22 17:01 ` [dpdk-dev] [PATCH 4/4] net/virtio-user: fix used ring update in cvq handling Tiwei Bie
2019-01-23 22:25 ` [dpdk-dev] [PATCH 0/4] Virtio fixes Maxime Coquelin
4 siblings, 2 replies; 14+ messages in thread
From: Tiwei Bie @ 2019-01-22 17:01 UTC (permalink / raw)
To: maxime.coquelin, zhihong.wang, dev
Always use the virtio variants which support the platform
memory ordering.
Fixes: 9230ab8d7913 ("net/virtio: support platform memory ordering")
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
drivers/net/virtio/virtio_rxtx.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index ebb86ef70..cc476b898 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -425,7 +425,7 @@ virtqueue_enqueue_recv_refill_packed(struct virtqueue *vq,
vq->vq_desc_head_idx = dxp->next;
if (vq->vq_desc_head_idx == VQ_RING_DESC_CHAIN_END)
vq->vq_desc_tail_idx = vq->vq_desc_head_idx;
- rte_smp_wmb();
+ virtio_wmb(hw->weak_barriers);
start_dp[idx].flags = flags;
if (++vq->vq_avail_idx >= vq->vq_nentries) {
vq->vq_avail_idx -= vq->vq_nentries;
@@ -687,7 +687,7 @@ virtqueue_enqueue_xmit_packed(struct virtnet_tx *txvq, struct rte_mbuf *cookie,
vq->vq_avail_idx = idx;
- rte_smp_wmb();
+ virtio_wmb(vq->hw->weak_barriers);
head_dp->flags = head_flags;
}
--
2.17.1
^ permalink raw reply [flat|nested] 14+ messages in thread
* [dpdk-dev] [PATCH 4/4] net/virtio-user: fix used ring update in cvq handling
2019-01-22 17:01 [dpdk-dev] [PATCH 0/4] Virtio fixes Tiwei Bie
` (2 preceding siblings ...)
2019-01-22 17:01 ` [dpdk-dev] [PATCH 3/4] net/virtio: use virtio barrier in packed ring Tiwei Bie
@ 2019-01-22 17:01 ` Tiwei Bie
2019-01-23 22:08 ` Maxime Coquelin
2019-01-23 22:25 ` [dpdk-dev] [PATCH 0/4] Virtio fixes Maxime Coquelin
4 siblings, 1 reply; 14+ messages in thread
From: Tiwei Bie @ 2019-01-22 17:01 UTC (permalink / raw)
To: maxime.coquelin, zhihong.wang, dev; +Cc: stable
When updating used ring, the id in used element should be the
index of the first desc in the desc chain.
Fixes: f9b9d1a55775 ("net/virtio-user: add multiple queues in device emulation")
Cc: stable@dpdk.org
Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
---
drivers/net/virtio/virtio_user/virtio_user_dev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/virtio/virtio_user/virtio_user_dev.c b/drivers/net/virtio/virtio_user/virtio_user_dev.c
index 89d287a74..d1157378d 100644
--- a/drivers/net/virtio/virtio_user/virtio_user_dev.c
+++ b/drivers/net/virtio/virtio_user/virtio_user_dev.c
@@ -722,7 +722,7 @@ virtio_user_handle_cq(struct virtio_user_dev *dev, uint16_t queue_idx)
/* Update used ring */
uep = &vring->used->ring[avail_idx];
- uep->id = avail_idx;
+ uep->id = desc_idx;
uep->len = n_descs;
vring->used->idx++;
--
2.17.1
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [dpdk-dev] [1/4] net/virtio: fix the control vq support
[not found] ` <CGME20190123130903eucas1p2730776e71039a79024dd7602b5dcad7d@eucas1p2.samsung.com>
@ 2019-01-23 13:09 ` Ilya Maximets
[not found] ` <CGME20190123163323eucas1p1baaec2c637cdc656ab9b26dbfd455bae@eucas1p1.samsung.com>
0 siblings, 1 reply; 14+ messages in thread
From: Ilya Maximets @ 2019-01-23 13:09 UTC (permalink / raw)
To: Tiwei Bie, maxime.coquelin, zhihong.wang, dev
On 22.01.2019 20:01, Tiwei Bie wrote:
> This patch mainly fixed below issues in the packed ring based
> control vq support in virtio driver:
>
> 1. When parsing the used descriptors, we have to track the
> number of descs that we need to skip;
> 2. vq->vq_free_cnt was decreased twice for a same desc;
>
> Meanwhile, make the function name consistent with other parts.
>
> Fixes: ec194c2f1895 ("net/virtio: support packed queue in send command")
> Fixes: a4270ea4ff79 ("net/virtio: check head desc with correct wrap counter")
>
> Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
> ---
> drivers/net/virtio/virtio_ethdev.c | 62 ++++++++++++++----------------
> drivers/net/virtio/virtqueue.h | 12 +-----
> 2 files changed, 31 insertions(+), 43 deletions(-)
>
> diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
> index ee5a98b7c..a3fe65599 100644
> --- a/drivers/net/virtio/virtio_ethdev.c
> +++ b/drivers/net/virtio/virtio_ethdev.c
> @@ -142,16 +142,17 @@ static const struct rte_virtio_xstats_name_off rte_virtio_txq_stat_strings[] = {
> struct virtio_hw_internal virtio_hw_internal[RTE_MAX_ETHPORTS];
>
> static struct virtio_pmd_ctrl *
> -virtio_pq_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
> - int *dlen, int pkt_num)
> +virtio_send_command_packed(struct virtnet_ctl *cvq,
> + struct virtio_pmd_ctrl *ctrl,
> + int *dlen, int pkt_num)
> {
> struct virtqueue *vq = cvq->vq;
> int head;
> struct vring_packed_desc *desc = vq->ring_packed.desc_packed;
> struct virtio_pmd_ctrl *result;
> - bool avail_wrap_counter, used_wrap_counter;
> - uint16_t flags;
> + bool avail_wrap_counter;
> int sum = 0;
> + int nb_descs = 0;
> int k;
>
> /*
> @@ -162,11 +163,10 @@ virtio_pq_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
> */
> head = vq->vq_avail_idx;
> avail_wrap_counter = vq->avail_wrap_counter;
> - used_wrap_counter = vq->used_wrap_counter;
> - desc[head].flags = VRING_DESC_F_NEXT;
> desc[head].addr = cvq->virtio_net_hdr_mem;
> desc[head].len = sizeof(struct virtio_net_ctrl_hdr);
> vq->vq_free_cnt--;
> + nb_descs++;
> if (++vq->vq_avail_idx >= vq->vq_nentries) {
> vq->vq_avail_idx -= vq->vq_nentries;
> vq->avail_wrap_counter ^= 1;
> @@ -177,55 +177,51 @@ virtio_pq_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
> + sizeof(struct virtio_net_ctrl_hdr)
> + sizeof(ctrl->status) + sizeof(uint8_t) * sum;
> desc[vq->vq_avail_idx].len = dlen[k];
> - flags = VRING_DESC_F_NEXT;
Looks like barriers was badly placed here before this patch.
Anyway, you need a write barrier here between {addr, len} and flags updates.
> + desc[vq->vq_avail_idx].flags = VRING_DESC_F_NEXT |
> + VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
> + VRING_DESC_F_USED(!vq->avail_wrap_counter);
> sum += dlen[k];
> vq->vq_free_cnt--;
> - flags |= VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
> - VRING_DESC_F_USED(!vq->avail_wrap_counter);
> - desc[vq->vq_avail_idx].flags = flags;
> - rte_smp_wmb();
> - vq->vq_free_cnt--;
> + nb_descs++;
> if (++vq->vq_avail_idx >= vq->vq_nentries) {
> vq->vq_avail_idx -= vq->vq_nentries;
> vq->avail_wrap_counter ^= 1;
> }
> }
>
> -
> desc[vq->vq_avail_idx].addr = cvq->virtio_net_hdr_mem
> + sizeof(struct virtio_net_ctrl_hdr);
> desc[vq->vq_avail_idx].len = sizeof(ctrl->status);
> - flags = VRING_DESC_F_WRITE;
> - flags |= VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
> - VRING_DESC_F_USED(!vq->avail_wrap_counter);
> - desc[vq->vq_avail_idx].flags = flags;
> - flags = VRING_DESC_F_NEXT;
> - flags |= VRING_DESC_F_AVAIL(avail_wrap_counter) |
> - VRING_DESC_F_USED(!avail_wrap_counter);
> - desc[head].flags = flags;
> - rte_smp_wmb();
> -
Same here. We need a write barrier to be sure that {addr, len} written
before updating flags.
Another way to avoid most of barriers is to work similar to
'flush_shadow_used_ring_packed',
i.e. update all the data in a loop - write barrier - update all the flags.
> + desc[vq->vq_avail_idx].flags = VRING_DESC_F_WRITE |
> + VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
> + VRING_DESC_F_USED(!vq->avail_wrap_counter);
> vq->vq_free_cnt--;
> + nb_descs++;
> if (++vq->vq_avail_idx >= vq->vq_nentries) {
> vq->vq_avail_idx -= vq->vq_nentries;
> vq->avail_wrap_counter ^= 1;
> }
>
> + virtio_wmb(vq->hw->weak_barriers);
> + desc[head].flags = VRING_DESC_F_NEXT |
> + VRING_DESC_F_AVAIL(avail_wrap_counter) |
> + VRING_DESC_F_USED(!avail_wrap_counter);
> +
> + virtio_wmb(vq->hw->weak_barriers);
> virtqueue_notify(vq);
>
> /* wait for used descriptors in virtqueue */
> - do {
> - rte_rmb();
> + while (!desc_is_used(&desc[head], vq))
> usleep(100);
> - } while (!__desc_is_used(&desc[head], used_wrap_counter));
> +
> + virtio_rmb(vq->hw->weak_barriers);
>
> /* now get used descriptors */
> - while (desc_is_used(&desc[vq->vq_used_cons_idx], vq)) {
> - vq->vq_free_cnt++;
> - if (++vq->vq_used_cons_idx >= vq->vq_nentries) {
> - vq->vq_used_cons_idx -= vq->vq_nentries;
> - vq->used_wrap_counter ^= 1;
> - }
> + vq->vq_free_cnt += nb_descs;
> + vq->vq_used_cons_idx += nb_descs;
> + if (vq->vq_used_cons_idx >= vq->vq_nentries) {
> + vq->vq_used_cons_idx -= vq->vq_nentries;
> + vq->used_wrap_counter ^= 1;
> }
>
> result = cvq->virtio_net_hdr_mz->addr;
> @@ -266,7 +262,7 @@ virtio_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
> sizeof(struct virtio_pmd_ctrl));
>
> if (vtpci_packed_queue(vq->hw)) {
> - result = virtio_pq_send_command(cvq, ctrl, dlen, pkt_num);
> + result = virtio_send_command_packed(cvq, ctrl, dlen, pkt_num);
> goto out_unlock;
> }
>
> diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
> index 7fcde5643..ca9d8e6e3 100644
> --- a/drivers/net/virtio/virtqueue.h
> +++ b/drivers/net/virtio/virtqueue.h
> @@ -281,7 +281,7 @@ struct virtio_tx_region {
> };
>
> static inline int
> -__desc_is_used(struct vring_packed_desc *desc, bool wrap_counter)
> +desc_is_used(struct vring_packed_desc *desc, struct virtqueue *vq)
> {
> uint16_t used, avail, flags;
>
> @@ -289,16 +289,9 @@ __desc_is_used(struct vring_packed_desc *desc, bool wrap_counter)
> used = !!(flags & VRING_DESC_F_USED(1));
> avail = !!(flags & VRING_DESC_F_AVAIL(1));
>
> - return avail == used && used == wrap_counter;
> + return avail == used && used == vq->used_wrap_counter;
> }
>
> -static inline int
> -desc_is_used(struct vring_packed_desc *desc, struct virtqueue *vq)
> -{
> - return __desc_is_used(desc, vq->used_wrap_counter);
> -}
> -
> -
> static inline void
> vring_desc_init_packed(struct virtqueue *vq, int n)
> {
> @@ -354,7 +347,6 @@ virtqueue_enable_intr_packed(struct virtqueue *vq)
> {
> uint16_t *event_flags = &vq->ring_packed.driver_event->desc_event_flags;
>
> -
> if (vq->event_flags_shadow == RING_EVENT_FLAGS_DISABLE) {
> virtio_wmb(vq->hw->weak_barriers);
> vq->event_flags_shadow = RING_EVENT_FLAGS_ENABLE;
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [dpdk-dev] [3/4] net/virtio: use virtio barrier in packed ring
[not found] ` <CGME20190123155232eucas1p28bdd3a5c220452b81e21e48c19f3e5a7@eucas1p2.samsung.com>
@ 2019-01-23 15:52 ` Ilya Maximets
0 siblings, 0 replies; 14+ messages in thread
From: Ilya Maximets @ 2019-01-23 15:52 UTC (permalink / raw)
To: Tiwei Bie, maxime.coquelin, zhihong.wang, dev
On 22.01.2019 20:01, Tiwei Bie wrote:
> Always use the virtio variants which support the platform
> memory ordering.
>
> Fixes: 9230ab8d7913 ("net/virtio: support platform memory ordering")
>
> Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
> ---
Thanks.
For some reason rte_smp_* barriers used directly here instead of virtio_*.
So, I missed them while rebasing on top of packed rings.
Acked-by: Ilya Maximets <i.maximets@samsung.com>
> drivers/net/virtio/virtio_rxtx.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
> index ebb86ef70..cc476b898 100644
> --- a/drivers/net/virtio/virtio_rxtx.c
> +++ b/drivers/net/virtio/virtio_rxtx.c
> @@ -425,7 +425,7 @@ virtqueue_enqueue_recv_refill_packed(struct virtqueue *vq,
> vq->vq_desc_head_idx = dxp->next;
> if (vq->vq_desc_head_idx == VQ_RING_DESC_CHAIN_END)
> vq->vq_desc_tail_idx = vq->vq_desc_head_idx;
> - rte_smp_wmb();
> + virtio_wmb(hw->weak_barriers);
> start_dp[idx].flags = flags;
> if (++vq->vq_avail_idx >= vq->vq_nentries) {
> vq->vq_avail_idx -= vq->vq_nentries;
> @@ -687,7 +687,7 @@ virtqueue_enqueue_xmit_packed(struct virtnet_tx *txvq, struct rte_mbuf *cookie,
>
> vq->vq_avail_idx = idx;
>
> - rte_smp_wmb();
> + virtio_wmb(vq->hw->weak_barriers);
> head_dp->flags = head_flags;
> }
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [dpdk-dev] [1/4] net/virtio: fix the control vq support
[not found] ` <CGME20190123163323eucas1p1baaec2c637cdc656ab9b26dbfd455bae@eucas1p1.samsung.com>
@ 2019-01-23 16:33 ` Ilya Maximets
2019-01-23 22:02 ` Maxime Coquelin
0 siblings, 1 reply; 14+ messages in thread
From: Ilya Maximets @ 2019-01-23 16:33 UTC (permalink / raw)
To: Tiwei Bie, maxime.coquelin, zhihong.wang, dev
Hmm. Nevermind.
Please, ignore my previous comments to this patch.
Patch seems compliant to spec, but the spec is not very clear.
Best regards, Ilya Maximets.
On 23.01.2019 16:09, Ilya Maximets wrote:
> On 22.01.2019 20:01, Tiwei Bie wrote:
>> This patch mainly fixed below issues in the packed ring based
>> control vq support in virtio driver:
>>
>> 1. When parsing the used descriptors, we have to track the
>> number of descs that we need to skip;
>> 2. vq->vq_free_cnt was decreased twice for a same desc;
>>
>> Meanwhile, make the function name consistent with other parts.
>>
>> Fixes: ec194c2f1895 ("net/virtio: support packed queue in send command")
>> Fixes: a4270ea4ff79 ("net/virtio: check head desc with correct wrap counter")
>>
>> Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
>> ---
>> drivers/net/virtio/virtio_ethdev.c | 62 ++++++++++++++----------------
>> drivers/net/virtio/virtqueue.h | 12 +-----
>> 2 files changed, 31 insertions(+), 43 deletions(-)
>>
>> diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
>> index ee5a98b7c..a3fe65599 100644
>> --- a/drivers/net/virtio/virtio_ethdev.c
>> +++ b/drivers/net/virtio/virtio_ethdev.c
>> @@ -142,16 +142,17 @@ static const struct rte_virtio_xstats_name_off rte_virtio_txq_stat_strings[] = {
>> struct virtio_hw_internal virtio_hw_internal[RTE_MAX_ETHPORTS];
>>
>> static struct virtio_pmd_ctrl *
>> -virtio_pq_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
>> - int *dlen, int pkt_num)
>> +virtio_send_command_packed(struct virtnet_ctl *cvq,
>> + struct virtio_pmd_ctrl *ctrl,
>> + int *dlen, int pkt_num)
>> {
>> struct virtqueue *vq = cvq->vq;
>> int head;
>> struct vring_packed_desc *desc = vq->ring_packed.desc_packed;
>> struct virtio_pmd_ctrl *result;
>> - bool avail_wrap_counter, used_wrap_counter;
>> - uint16_t flags;
>> + bool avail_wrap_counter;
>> int sum = 0;
>> + int nb_descs = 0;
>> int k;
>>
>> /*
>> @@ -162,11 +163,10 @@ virtio_pq_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
>> */
>> head = vq->vq_avail_idx;
>> avail_wrap_counter = vq->avail_wrap_counter;
>> - used_wrap_counter = vq->used_wrap_counter;
>> - desc[head].flags = VRING_DESC_F_NEXT;
>> desc[head].addr = cvq->virtio_net_hdr_mem;
>> desc[head].len = sizeof(struct virtio_net_ctrl_hdr);
>> vq->vq_free_cnt--;
>> + nb_descs++;
>> if (++vq->vq_avail_idx >= vq->vq_nentries) {
>> vq->vq_avail_idx -= vq->vq_nentries;
>> vq->avail_wrap_counter ^= 1;
>> @@ -177,55 +177,51 @@ virtio_pq_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
>> + sizeof(struct virtio_net_ctrl_hdr)
>> + sizeof(ctrl->status) + sizeof(uint8_t) * sum;
>> desc[vq->vq_avail_idx].len = dlen[k];
>> - flags = VRING_DESC_F_NEXT;
>
> Looks like barriers was badly placed here before this patch.
> Anyway, you need a write barrier here between {addr, len} and flags updates.
>
>> + desc[vq->vq_avail_idx].flags = VRING_DESC_F_NEXT |
>> + VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
>> + VRING_DESC_F_USED(!vq->avail_wrap_counter);
>> sum += dlen[k];
>> vq->vq_free_cnt--;
>> - flags |= VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
>> - VRING_DESC_F_USED(!vq->avail_wrap_counter);
>> - desc[vq->vq_avail_idx].flags = flags;
>> - rte_smp_wmb();
>> - vq->vq_free_cnt--;
>> + nb_descs++;
>> if (++vq->vq_avail_idx >= vq->vq_nentries) {
>> vq->vq_avail_idx -= vq->vq_nentries;
>> vq->avail_wrap_counter ^= 1;
>> }
>> }
>>
>> -
>> desc[vq->vq_avail_idx].addr = cvq->virtio_net_hdr_mem
>> + sizeof(struct virtio_net_ctrl_hdr);
>> desc[vq->vq_avail_idx].len = sizeof(ctrl->status);
>> - flags = VRING_DESC_F_WRITE;
>> - flags |= VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
>> - VRING_DESC_F_USED(!vq->avail_wrap_counter);
>> - desc[vq->vq_avail_idx].flags = flags;
>> - flags = VRING_DESC_F_NEXT;
>> - flags |= VRING_DESC_F_AVAIL(avail_wrap_counter) |
>> - VRING_DESC_F_USED(!avail_wrap_counter);
>> - desc[head].flags = flags;
>> - rte_smp_wmb();
>> -
>
> Same here. We need a write barrier to be sure that {addr, len} written
> before updating flags.
>
> Another way to avoid most of barriers is to work similar to
> 'flush_shadow_used_ring_packed',
> i.e. update all the data in a loop - write barrier - update all the flags.
>
>> + desc[vq->vq_avail_idx].flags = VRING_DESC_F_WRITE |
>> + VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
>> + VRING_DESC_F_USED(!vq->avail_wrap_counter);
>> vq->vq_free_cnt--;
>> + nb_descs++;
>> if (++vq->vq_avail_idx >= vq->vq_nentries) {
>> vq->vq_avail_idx -= vq->vq_nentries;
>> vq->avail_wrap_counter ^= 1;
>> }
>>
>> + virtio_wmb(vq->hw->weak_barriers);
>> + desc[head].flags = VRING_DESC_F_NEXT |
>> + VRING_DESC_F_AVAIL(avail_wrap_counter) |
>> + VRING_DESC_F_USED(!avail_wrap_counter);
>> +
>> + virtio_wmb(vq->hw->weak_barriers);
>> virtqueue_notify(vq);
>>
>> /* wait for used descriptors in virtqueue */
>> - do {
>> - rte_rmb();
>> + while (!desc_is_used(&desc[head], vq))
>> usleep(100);
>> - } while (!__desc_is_used(&desc[head], used_wrap_counter));
>> +
>> + virtio_rmb(vq->hw->weak_barriers);
>>
>> /* now get used descriptors */
>> - while (desc_is_used(&desc[vq->vq_used_cons_idx], vq)) {
>> - vq->vq_free_cnt++;
>> - if (++vq->vq_used_cons_idx >= vq->vq_nentries) {
>> - vq->vq_used_cons_idx -= vq->vq_nentries;
>> - vq->used_wrap_counter ^= 1;
>> - }
>> + vq->vq_free_cnt += nb_descs;
>> + vq->vq_used_cons_idx += nb_descs;
>> + if (vq->vq_used_cons_idx >= vq->vq_nentries) {
>> + vq->vq_used_cons_idx -= vq->vq_nentries;
>> + vq->used_wrap_counter ^= 1;
>> }
>>
>> result = cvq->virtio_net_hdr_mz->addr;
>> @@ -266,7 +262,7 @@ virtio_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
>> sizeof(struct virtio_pmd_ctrl));
>>
>> if (vtpci_packed_queue(vq->hw)) {
>> - result = virtio_pq_send_command(cvq, ctrl, dlen, pkt_num);
>> + result = virtio_send_command_packed(cvq, ctrl, dlen, pkt_num);
>> goto out_unlock;
>> }
>>
>> diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
>> index 7fcde5643..ca9d8e6e3 100644
>> --- a/drivers/net/virtio/virtqueue.h
>> +++ b/drivers/net/virtio/virtqueue.h
>> @@ -281,7 +281,7 @@ struct virtio_tx_region {
>> };
>>
>> static inline int
>> -__desc_is_used(struct vring_packed_desc *desc, bool wrap_counter)
>> +desc_is_used(struct vring_packed_desc *desc, struct virtqueue *vq)
>> {
>> uint16_t used, avail, flags;
>>
>> @@ -289,16 +289,9 @@ __desc_is_used(struct vring_packed_desc *desc, bool wrap_counter)
>> used = !!(flags & VRING_DESC_F_USED(1));
>> avail = !!(flags & VRING_DESC_F_AVAIL(1));
>>
>> - return avail == used && used == wrap_counter;
>> + return avail == used && used == vq->used_wrap_counter;
>> }
>>
>> -static inline int
>> -desc_is_used(struct vring_packed_desc *desc, struct virtqueue *vq)
>> -{
>> - return __desc_is_used(desc, vq->used_wrap_counter);
>> -}
>> -
>> -
>> static inline void
>> vring_desc_init_packed(struct virtqueue *vq, int n)
>> {
>> @@ -354,7 +347,6 @@ virtqueue_enable_intr_packed(struct virtqueue *vq)
>> {
>> uint16_t *event_flags = &vq->ring_packed.driver_event->desc_event_flags;
>>
>> -
>> if (vq->event_flags_shadow == RING_EVENT_FLAGS_DISABLE) {
>> virtio_wmb(vq->hw->weak_barriers);
>> vq->event_flags_shadow = RING_EVENT_FLAGS_ENABLE;
>>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [dpdk-dev] [1/4] net/virtio: fix the control vq support
2019-01-23 16:33 ` Ilya Maximets
@ 2019-01-23 22:02 ` Maxime Coquelin
0 siblings, 0 replies; 14+ messages in thread
From: Maxime Coquelin @ 2019-01-23 22:02 UTC (permalink / raw)
To: Ilya Maximets, Tiwei Bie, zhihong.wang, dev
On 1/23/19 5:33 PM, Ilya Maximets wrote:
> Hmm. Nevermind.
> Please, ignore my previous comments to this patch.
> Patch seems compliant to spec, but the spec is not very clear.
Ok, thanks for the review and the folluw-up.
Maxime
> Best regards, Ilya Maximets.
>
> On 23.01.2019 16:09, Ilya Maximets wrote:
>> On 22.01.2019 20:01, Tiwei Bie wrote:
>>> This patch mainly fixed below issues in the packed ring based
>>> control vq support in virtio driver:
>>>
>>> 1. When parsing the used descriptors, we have to track the
>>> number of descs that we need to skip;
>>> 2. vq->vq_free_cnt was decreased twice for a same desc;
>>>
>>> Meanwhile, make the function name consistent with other parts.
>>>
>>> Fixes: ec194c2f1895 ("net/virtio: support packed queue in send command")
>>> Fixes: a4270ea4ff79 ("net/virtio: check head desc with correct wrap counter")
>>>
>>> Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
>>> ---
>>> drivers/net/virtio/virtio_ethdev.c | 62 ++++++++++++++----------------
>>> drivers/net/virtio/virtqueue.h | 12 +-----
>>> 2 files changed, 31 insertions(+), 43 deletions(-)
>>>
>>> diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
>>> index ee5a98b7c..a3fe65599 100644
>>> --- a/drivers/net/virtio/virtio_ethdev.c
>>> +++ b/drivers/net/virtio/virtio_ethdev.c
>>> @@ -142,16 +142,17 @@ static const struct rte_virtio_xstats_name_off rte_virtio_txq_stat_strings[] = {
>>> struct virtio_hw_internal virtio_hw_internal[RTE_MAX_ETHPORTS];
>>>
>>> static struct virtio_pmd_ctrl *
>>> -virtio_pq_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
>>> - int *dlen, int pkt_num)
>>> +virtio_send_command_packed(struct virtnet_ctl *cvq,
>>> + struct virtio_pmd_ctrl *ctrl,
>>> + int *dlen, int pkt_num)
>>> {
>>> struct virtqueue *vq = cvq->vq;
>>> int head;
>>> struct vring_packed_desc *desc = vq->ring_packed.desc_packed;
>>> struct virtio_pmd_ctrl *result;
>>> - bool avail_wrap_counter, used_wrap_counter;
>>> - uint16_t flags;
>>> + bool avail_wrap_counter;
>>> int sum = 0;
>>> + int nb_descs = 0;
>>> int k;
>>>
>>> /*
>>> @@ -162,11 +163,10 @@ virtio_pq_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
>>> */
>>> head = vq->vq_avail_idx;
>>> avail_wrap_counter = vq->avail_wrap_counter;
>>> - used_wrap_counter = vq->used_wrap_counter;
>>> - desc[head].flags = VRING_DESC_F_NEXT;
>>> desc[head].addr = cvq->virtio_net_hdr_mem;
>>> desc[head].len = sizeof(struct virtio_net_ctrl_hdr);
>>> vq->vq_free_cnt--;
>>> + nb_descs++;
>>> if (++vq->vq_avail_idx >= vq->vq_nentries) {
>>> vq->vq_avail_idx -= vq->vq_nentries;
>>> vq->avail_wrap_counter ^= 1;
>>> @@ -177,55 +177,51 @@ virtio_pq_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
>>> + sizeof(struct virtio_net_ctrl_hdr)
>>> + sizeof(ctrl->status) + sizeof(uint8_t) * sum;
>>> desc[vq->vq_avail_idx].len = dlen[k];
>>> - flags = VRING_DESC_F_NEXT;
>>
>> Looks like barriers was badly placed here before this patch.
>> Anyway, you need a write barrier here between {addr, len} and flags updates.
>>
>>> + desc[vq->vq_avail_idx].flags = VRING_DESC_F_NEXT |
>>> + VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
>>> + VRING_DESC_F_USED(!vq->avail_wrap_counter);
>>> sum += dlen[k];
>>> vq->vq_free_cnt--;
>>> - flags |= VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
>>> - VRING_DESC_F_USED(!vq->avail_wrap_counter);
>>> - desc[vq->vq_avail_idx].flags = flags;
>>> - rte_smp_wmb();
>>> - vq->vq_free_cnt--;
>>> + nb_descs++;
>>> if (++vq->vq_avail_idx >= vq->vq_nentries) {
>>> vq->vq_avail_idx -= vq->vq_nentries;
>>> vq->avail_wrap_counter ^= 1;
>>> }
>>> }
>>>
>>> -
>>> desc[vq->vq_avail_idx].addr = cvq->virtio_net_hdr_mem
>>> + sizeof(struct virtio_net_ctrl_hdr);
>>> desc[vq->vq_avail_idx].len = sizeof(ctrl->status);
>>> - flags = VRING_DESC_F_WRITE;
>>> - flags |= VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
>>> - VRING_DESC_F_USED(!vq->avail_wrap_counter);
>>> - desc[vq->vq_avail_idx].flags = flags;
>>> - flags = VRING_DESC_F_NEXT;
>>> - flags |= VRING_DESC_F_AVAIL(avail_wrap_counter) |
>>> - VRING_DESC_F_USED(!avail_wrap_counter);
>>> - desc[head].flags = flags;
>>> - rte_smp_wmb();
>>> -
>>
>> Same here. We need a write barrier to be sure that {addr, len} written
>> before updating flags.
>>
>> Another way to avoid most of barriers is to work similar to
>> 'flush_shadow_used_ring_packed',
>> i.e. update all the data in a loop - write barrier - update all the flags.
>>
>>> + desc[vq->vq_avail_idx].flags = VRING_DESC_F_WRITE |
>>> + VRING_DESC_F_AVAIL(vq->avail_wrap_counter) |
>>> + VRING_DESC_F_USED(!vq->avail_wrap_counter);
>>> vq->vq_free_cnt--;
>>> + nb_descs++;
>>> if (++vq->vq_avail_idx >= vq->vq_nentries) {
>>> vq->vq_avail_idx -= vq->vq_nentries;
>>> vq->avail_wrap_counter ^= 1;
>>> }
>>>
>>> + virtio_wmb(vq->hw->weak_barriers);
>>> + desc[head].flags = VRING_DESC_F_NEXT |
>>> + VRING_DESC_F_AVAIL(avail_wrap_counter) |
>>> + VRING_DESC_F_USED(!avail_wrap_counter);
>>> +
>>> + virtio_wmb(vq->hw->weak_barriers);
>>> virtqueue_notify(vq);
>>>
>>> /* wait for used descriptors in virtqueue */
>>> - do {
>>> - rte_rmb();
>>> + while (!desc_is_used(&desc[head], vq))
>>> usleep(100);
>>> - } while (!__desc_is_used(&desc[head], used_wrap_counter));
>>> +
>>> + virtio_rmb(vq->hw->weak_barriers);
>>>
>>> /* now get used descriptors */
>>> - while (desc_is_used(&desc[vq->vq_used_cons_idx], vq)) {
>>> - vq->vq_free_cnt++;
>>> - if (++vq->vq_used_cons_idx >= vq->vq_nentries) {
>>> - vq->vq_used_cons_idx -= vq->vq_nentries;
>>> - vq->used_wrap_counter ^= 1;
>>> - }
>>> + vq->vq_free_cnt += nb_descs;
>>> + vq->vq_used_cons_idx += nb_descs;
>>> + if (vq->vq_used_cons_idx >= vq->vq_nentries) {
>>> + vq->vq_used_cons_idx -= vq->vq_nentries;
>>> + vq->used_wrap_counter ^= 1;
>>> }
>>>
>>> result = cvq->virtio_net_hdr_mz->addr;
>>> @@ -266,7 +262,7 @@ virtio_send_command(struct virtnet_ctl *cvq, struct virtio_pmd_ctrl *ctrl,
>>> sizeof(struct virtio_pmd_ctrl));
>>>
>>> if (vtpci_packed_queue(vq->hw)) {
>>> - result = virtio_pq_send_command(cvq, ctrl, dlen, pkt_num);
>>> + result = virtio_send_command_packed(cvq, ctrl, dlen, pkt_num);
>>> goto out_unlock;
>>> }
>>>
>>> diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
>>> index 7fcde5643..ca9d8e6e3 100644
>>> --- a/drivers/net/virtio/virtqueue.h
>>> +++ b/drivers/net/virtio/virtqueue.h
>>> @@ -281,7 +281,7 @@ struct virtio_tx_region {
>>> };
>>>
>>> static inline int
>>> -__desc_is_used(struct vring_packed_desc *desc, bool wrap_counter)
>>> +desc_is_used(struct vring_packed_desc *desc, struct virtqueue *vq)
>>> {
>>> uint16_t used, avail, flags;
>>>
>>> @@ -289,16 +289,9 @@ __desc_is_used(struct vring_packed_desc *desc, bool wrap_counter)
>>> used = !!(flags & VRING_DESC_F_USED(1));
>>> avail = !!(flags & VRING_DESC_F_AVAIL(1));
>>>
>>> - return avail == used && used == wrap_counter;
>>> + return avail == used && used == vq->used_wrap_counter;
>>> }
>>>
>>> -static inline int
>>> -desc_is_used(struct vring_packed_desc *desc, struct virtqueue *vq)
>>> -{
>>> - return __desc_is_used(desc, vq->used_wrap_counter);
>>> -}
>>> -
>>> -
>>> static inline void
>>> vring_desc_init_packed(struct virtqueue *vq, int n)
>>> {
>>> @@ -354,7 +347,6 @@ virtqueue_enable_intr_packed(struct virtqueue *vq)
>>> {
>>> uint16_t *event_flags = &vq->ring_packed.driver_event->desc_event_flags;
>>>
>>> -
>>> if (vq->event_flags_shadow == RING_EVENT_FLAGS_DISABLE) {
>>> virtio_wmb(vq->hw->weak_barriers);
>>> vq->event_flags_shadow = RING_EVENT_FLAGS_ENABLE;
>>>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [dpdk-dev] [PATCH 1/4] net/virtio: fix the control vq support
2019-01-22 17:01 ` [dpdk-dev] [PATCH 1/4] net/virtio: fix the control vq support Tiwei Bie
[not found] ` <CGME20190123130903eucas1p2730776e71039a79024dd7602b5dcad7d@eucas1p2.samsung.com>
@ 2019-01-23 22:03 ` Maxime Coquelin
1 sibling, 0 replies; 14+ messages in thread
From: Maxime Coquelin @ 2019-01-23 22:03 UTC (permalink / raw)
To: Tiwei Bie, zhihong.wang, dev
On 1/22/19 6:01 PM, Tiwei Bie wrote:
> This patch mainly fixed below issues in the packed ring based
> control vq support in virtio driver:
>
> 1. When parsing the used descriptors, we have to track the
> number of descs that we need to skip;
> 2. vq->vq_free_cnt was decreased twice for a same desc;
>
> Meanwhile, make the function name consistent with other parts.
>
> Fixes: ec194c2f1895 ("net/virtio: support packed queue in send command")
> Fixes: a4270ea4ff79 ("net/virtio: check head desc with correct wrap counter")
>
> Signed-off-by: Tiwei Bie <tiwei.bie@intel.com>
> ---
> drivers/net/virtio/virtio_ethdev.c | 62 ++++++++++++++----------------
> drivers/net/virtio/virtqueue.h | 12 +-----
> 2 files changed, 31 insertions(+), 43 deletions(-)
>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Thanks,
Maxime
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [dpdk-dev] [PATCH 2/4] net/virtio-user: fix the control vq support
2019-01-22 17:01 ` [dpdk-dev] [PATCH 2/4] net/virtio-user: " Tiwei Bie
@ 2019-01-23 22:07 ` Maxime Coquelin
0 siblings, 0 replies; 14+ messages in thread
From: Maxime Coquelin @ 2019-01-23 22:07 UTC (permalink / raw)
To: Tiwei Bie, zhihong.wang, dev
On 1/22/19 6:01 PM, Tiwei Bie wrote:
> This patch fixed below issues in the packed ring based control
> vq support in virtio user:
>
> 1. The idx_hdr should be used_idx instead of the id in the desc;
> 2. We just need to write out a single used descriptor for each
> descriptor list;
> 3. The avail/used bits should be initialized to 0;
>
> Meanwhile, make the function name consistent with other parts.
>
> Fixes: 48a4464029a7 ("net/virtio-user: support control VQ for packed")
>
> Signed-off-by: Tiwei Bie<tiwei.bie@intel.com>
> ---
> drivers/net/virtio/virtio_ethdev.c | 11 ++++++
> .../net/virtio/virtio_user/virtio_user_dev.c | 37 +++++++++++--------
> drivers/net/virtio/virtio_user_ethdev.c | 7 +---
> 3 files changed, 34 insertions(+), 21 deletions(-)
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Thanks,
Maxime
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [dpdk-dev] [PATCH 4/4] net/virtio-user: fix used ring update in cvq handling
2019-01-22 17:01 ` [dpdk-dev] [PATCH 4/4] net/virtio-user: fix used ring update in cvq handling Tiwei Bie
@ 2019-01-23 22:08 ` Maxime Coquelin
0 siblings, 0 replies; 14+ messages in thread
From: Maxime Coquelin @ 2019-01-23 22:08 UTC (permalink / raw)
To: Tiwei Bie, zhihong.wang, dev; +Cc: stable
On 1/22/19 6:01 PM, Tiwei Bie wrote:
> When updating used ring, the id in used element should be the
> index of the first desc in the desc chain.
>
> Fixes: f9b9d1a55775 ("net/virtio-user: add multiple queues in device emulation")
> Cc:stable@dpdk.org
>
> Signed-off-by: Tiwei Bie<tiwei.bie@intel.com>
> ---
> drivers/net/virtio/virtio_user/virtio_user_dev.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Thanks,
Maxime
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [dpdk-dev] [PATCH 3/4] net/virtio: use virtio barrier in packed ring
2019-01-22 17:01 ` [dpdk-dev] [PATCH 3/4] net/virtio: use virtio barrier in packed ring Tiwei Bie
[not found] ` <CGME20190123155232eucas1p28bdd3a5c220452b81e21e48c19f3e5a7@eucas1p2.samsung.com>
@ 2019-01-23 22:09 ` Maxime Coquelin
1 sibling, 0 replies; 14+ messages in thread
From: Maxime Coquelin @ 2019-01-23 22:09 UTC (permalink / raw)
To: Tiwei Bie, zhihong.wang, dev
On 1/22/19 6:01 PM, Tiwei Bie wrote:
> Always use the virtio variants which support the platform
> memory ordering.
>
> Fixes: 9230ab8d7913 ("net/virtio: support platform memory ordering")
>
> Signed-off-by: Tiwei Bie<tiwei.bie@intel.com>
> ---
> drivers/net/virtio/virtio_rxtx.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Thanks,
Maxime
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [dpdk-dev] [PATCH 0/4] Virtio fixes
2019-01-22 17:01 [dpdk-dev] [PATCH 0/4] Virtio fixes Tiwei Bie
` (3 preceding siblings ...)
2019-01-22 17:01 ` [dpdk-dev] [PATCH 4/4] net/virtio-user: fix used ring update in cvq handling Tiwei Bie
@ 2019-01-23 22:25 ` Maxime Coquelin
4 siblings, 0 replies; 14+ messages in thread
From: Maxime Coquelin @ 2019-01-23 22:25 UTC (permalink / raw)
To: Tiwei Bie, zhihong.wang, dev
On 1/22/19 6:01 PM, Tiwei Bie wrote:
> Tiwei Bie (4):
> net/virtio: fix the control vq support
> net/virtio-user: fix the control vq support
> net/virtio: use virtio barrier in packed ring
> net/virtio-user: fix used ring update in cvq handling
>
> drivers/net/virtio/virtio_ethdev.c | 73 ++++++++++---------
> drivers/net/virtio/virtio_rxtx.c | 4 +-
> .../net/virtio/virtio_user/virtio_user_dev.c | 39 +++++-----
> drivers/net/virtio/virtio_user_ethdev.c | 7 +-
> drivers/net/virtio/virtqueue.h | 12 +--
> 5 files changed, 68 insertions(+), 67 deletions(-)
>
Applied to dpdk-next-virtio/master.
Thanks,
Maxime
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2019-01-23 22:25 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-22 17:01 [dpdk-dev] [PATCH 0/4] Virtio fixes Tiwei Bie
2019-01-22 17:01 ` [dpdk-dev] [PATCH 1/4] net/virtio: fix the control vq support Tiwei Bie
[not found] ` <CGME20190123130903eucas1p2730776e71039a79024dd7602b5dcad7d@eucas1p2.samsung.com>
2019-01-23 13:09 ` [dpdk-dev] [1/4] " Ilya Maximets
[not found] ` <CGME20190123163323eucas1p1baaec2c637cdc656ab9b26dbfd455bae@eucas1p1.samsung.com>
2019-01-23 16:33 ` Ilya Maximets
2019-01-23 22:02 ` Maxime Coquelin
2019-01-23 22:03 ` [dpdk-dev] [PATCH 1/4] " Maxime Coquelin
2019-01-22 17:01 ` [dpdk-dev] [PATCH 2/4] net/virtio-user: " Tiwei Bie
2019-01-23 22:07 ` Maxime Coquelin
2019-01-22 17:01 ` [dpdk-dev] [PATCH 3/4] net/virtio: use virtio barrier in packed ring Tiwei Bie
[not found] ` <CGME20190123155232eucas1p28bdd3a5c220452b81e21e48c19f3e5a7@eucas1p2.samsung.com>
2019-01-23 15:52 ` [dpdk-dev] [3/4] " Ilya Maximets
2019-01-23 22:09 ` [dpdk-dev] [PATCH 3/4] " Maxime Coquelin
2019-01-22 17:01 ` [dpdk-dev] [PATCH 4/4] net/virtio-user: fix used ring update in cvq handling Tiwei Bie
2019-01-23 22:08 ` Maxime Coquelin
2019-01-23 22:25 ` [dpdk-dev] [PATCH 0/4] Virtio fixes Maxime Coquelin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).