[PATCH v3] vdpa/mlx5: workaround var offset within page

2022-06-15 Thread Yajun Wu
vDPA driver first uses kernel driver to allocate doorbell(VAR) area for
each device. Then uses var->mmap_off and var->length to mmap uverbs device
file as doorbell userspace virtual address.

Current kernel driver provides var->mmap_off equal to page start of VAR.
It's fine with x86 4K page server, because VAR physical address is only 4K
aligned thus locate in 4K page start.

But with aarch64 64K page server, the actual VAR physical address has
offset within page(not locate in 64K page start). So vDPA driver need add
this within page offset(caps.doorbell_bar_offset) to get right VAR virtual
address.

Fixes: 62c813706e4 ("vdpa/mlx5: map doorbell")
Cc: sta...@dpdk.org

Signed-off-by: Yajun Wu 
Acked-by: Matan Azrad 
Reviewed-by: Maxime Coquelin 
---
 drivers/vdpa/mlx5/mlx5_vdpa.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/vdpa/mlx5/mlx5_vdpa.c b/drivers/vdpa/mlx5/mlx5_vdpa.c
index 76fa5d4299..8a33a0c9a1 100644
--- a/drivers/vdpa/mlx5/mlx5_vdpa.c
+++ b/drivers/vdpa/mlx5/mlx5_vdpa.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -560,6 +561,9 @@ mlx5_vdpa_create_dev_resources(struct mlx5_vdpa_priv *priv)
rte_errno = errno;
return -rte_errno;
}
+   /* Add within page offset for 64K page system. */
+   priv->virtq_db_addr = (char *)priv->virtq_db_addr +
+   ((rte_mem_page_size() - 1) & priv->caps.doorbell_bar_offset);
DRV_LOG(DEBUG, "VAR address of doorbell mapping is %p.",
priv->virtq_db_addr);
priv->td = mlx5_devx_cmd_create_td(ctx);
@@ -705,7 +709,9 @@ mlx5_vdpa_release_dev_resources(struct mlx5_vdpa_priv *priv)
if (priv->td)
claim_zero(mlx5_devx_cmd_destroy(priv->td));
if (priv->virtq_db_addr)
-   claim_zero(munmap(priv->virtq_db_addr, priv->var->length));
+   /* Mask out the within page offset for munmap. */
+   claim_zero(munmap((void *)((uintptr_t)priv->virtq_db_addr &
+   ~(rte_mem_page_size() - 1)), priv->var->length));
if (priv->var)
mlx5_glue->dv_free_var(priv->var);
 }
-- 
2.30.2



[PATCH] common/mlx5: fix QP ack timeout configuration

2022-02-13 Thread Yajun Wu
VDPA driver creates two QPs(1 queue pair include 1 send queue
and 1 receive queue) per virtio queue to get traffic events
from NIC to SW.
Two QPs(called FW QP and SW QP) are created as loopback QP
and FW QP'SQ is connected to SW QP'RQ internally.

When packet receive or send out, HW will send WQE by FW QP'SQ,
then SW will get CQE from the CQ of SW QP.

With large scale and heavy traffic, the SQ's request may fail
to get ACK from RQ HW, because HW is busy.
SQ will retry the request with qpc.retry_count times and each time
wait for 4.096 uS *2^(ack_timeout) for the response. If still can’t
get RQ’s HW response, SQ will go to an error state.

16 is experienced value. It should not be too high or too low.
Too high will make QP waits too long in case it’s packet drop.
Too low will cause QP to go to an error state(retry-exceeded) easily.

Fixes: 15c3807e86a ("common/mlx5: support DevX QP operations")
Cc: sta...@dpdk.org

Signed-off-by: Yajun Wu 
Acked-by: Matan Azrad 
---
 drivers/common/mlx5/mlx5_devx_cmds.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/common/mlx5/mlx5_devx_cmds.c 
b/drivers/common/mlx5/mlx5_devx_cmds.c
index 2e807a0829..7732613c69 100644
--- a/drivers/common/mlx5/mlx5_devx_cmds.c
+++ b/drivers/common/mlx5/mlx5_devx_cmds.c
@@ -2279,7 +2279,7 @@ mlx5_devx_cmd_modify_qp_state(struct mlx5_devx_obj *qp, 
uint32_t qp_st_mod_op,
case MLX5_CMD_OP_RTR2RTS_QP:
qpc = MLX5_ADDR_OF(rtr2rts_qp_in, &in, qpc);
MLX5_SET(rtr2rts_qp_in, &in, qpn, qp->id);
-   MLX5_SET(qpc, qpc, primary_address_path.ack_timeout, 14);
+   MLX5_SET(qpc, qpc, primary_address_path.ack_timeout, 16);
MLX5_SET(qpc, qpc, log_ack_req_freq, 0);
MLX5_SET(qpc, qpc, retry_count, 7);
MLX5_SET(qpc, qpc, rnr_retry, 7);
-- 
2.27.0



[PATCH] vdpa/mlx5: fix queue enable drain CQ

2024-01-24 Thread Yajun Wu
For the case: `ethtool -L eth0 combined xxx` in VM, VQ will disable
and enable without calling device close. In such case, need add
drain CQ before reuse/reset event QP.

Fixes: 24969c7b62 ("vdpa/mlx5: reuse event queues")
Cc: sta...@dpdk.org

Signed-off-by: Yajun Wu 
Acked-by: Matan Azrad 
---
 drivers/vdpa/mlx5/mlx5_vdpa_event.c | 29 +++--
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/vdpa/mlx5/mlx5_vdpa_event.c 
b/drivers/vdpa/mlx5/mlx5_vdpa_event.c
index 9557c1042e..32430614d5 100644
--- a/drivers/vdpa/mlx5/mlx5_vdpa_event.c
+++ b/drivers/vdpa/mlx5/mlx5_vdpa_event.c
@@ -244,22 +244,30 @@ mlx5_vdpa_queues_complete(struct mlx5_vdpa_priv *priv)
return max;
 }
 
+static void
+mlx5_vdpa_drain_cq_one(struct mlx5_vdpa_priv *priv,
+   struct mlx5_vdpa_virtq *virtq)
+{
+   struct mlx5_vdpa_cq *cq = &virtq->eqp.cq;
+
+   mlx5_vdpa_queue_complete(cq);
+   if (cq->cq_obj.cq) {
+   cq->cq_obj.cqes[0].wqe_counter = rte_cpu_to_be_16(UINT16_MAX);
+   virtq->eqp.qp_pi = 0;
+   if (!cq->armed)
+   mlx5_vdpa_cq_arm(priv, cq);
+   }
+}
+
 void
 mlx5_vdpa_drain_cq(struct mlx5_vdpa_priv *priv)
 {
+   struct mlx5_vdpa_virtq *virtq;
unsigned int i;
 
for (i = 0; i < priv->caps.max_num_virtio_queues; i++) {
-   struct mlx5_vdpa_cq *cq = &priv->virtqs[i].eqp.cq;
-
-   mlx5_vdpa_queue_complete(cq);
-   if (cq->cq_obj.cq) {
-   cq->cq_obj.cqes[0].wqe_counter =
-   rte_cpu_to_be_16(UINT16_MAX);
-   priv->virtqs[i].eqp.qp_pi = 0;
-   if (!cq->armed)
-   mlx5_vdpa_cq_arm(priv, cq);
-   }
+   virtq = &priv->virtqs[i];
+   mlx5_vdpa_drain_cq_one(priv, virtq);
}
 }
 
@@ -632,6 +640,7 @@ mlx5_vdpa_event_qp_prepare(struct mlx5_vdpa_priv *priv, 
uint16_t desc_n,
if (eqp->cq.cq_obj.cq != NULL && log_desc_n == eqp->cq.log_desc_n) {
/* Reuse existing resources. */
eqp->cq.callfd = callfd;
+   mlx5_vdpa_drain_cq_one(priv, virtq);
/* FW will set event qp to error state in q destroy. */
if (reset && !mlx5_vdpa_qps2rst2rts(eqp))
rte_write32(rte_cpu_to_be_32(RTE_BIT32(log_desc_n)),
-- 
2.27.0



[PATCH] vdpa/mlx5: fix unregister kick handler order

2023-08-08 Thread Yajun Wu
The mlx5_vdpa_virtq_kick_handler function may still be running and waiting
on virtq->virtq_lock while mlx5_vdpa_cqe_event_unset function is trying to
re-initialize the virtq->virtq_lock.

This causes mlx5_vdpa_virtq_kick_handler thread can't be wake up and can't
be unregister. Following print may loop forever when calling
rte_vhost_driver_unregister(socket_path):

mlx5_vdpa: Try again to unregister fd 154 of virtq 11 interrupt
mlx5_vdpa: Try again to unregister fd 154 of virtq 11 interrupt
...

The fix is to move mlx5_vdpa_virtq_unregister_intr_handle before
mlx5_vdpa_cqe_event_unset.

Fixes: 057f7d2084 ("vdpa/mlx5: optimize datapath-control synchronization")
Cc: sta...@dpdk.org

Signed-off-by: Yajun Wu 
Acked-by: Matan Azrad 
---
 drivers/vdpa/mlx5/mlx5_vdpa.c | 1 +
 drivers/vdpa/mlx5/mlx5_vdpa_cthread.c | 1 -
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/vdpa/mlx5/mlx5_vdpa.c b/drivers/vdpa/mlx5/mlx5_vdpa.c
index f1737f82a8..8b1de8bd62 100644
--- a/drivers/vdpa/mlx5/mlx5_vdpa.c
+++ b/drivers/vdpa/mlx5/mlx5_vdpa.c
@@ -282,6 +282,7 @@ _internal_mlx5_vdpa_dev_close(struct mlx5_vdpa_priv *priv,
int ret = 0;
int vid = priv->vid;
 
+   mlx5_vdpa_virtq_unreg_intr_handle_all(priv);
mlx5_vdpa_cqe_event_unset(priv);
if (priv->state == MLX5_VDPA_STATE_CONFIGURED) {
ret |= mlx5_vdpa_lm_log(priv);
diff --git a/drivers/vdpa/mlx5/mlx5_vdpa_cthread.c 
b/drivers/vdpa/mlx5/mlx5_vdpa_cthread.c
index 6e6624e5a3..1d84e422d4 100644
--- a/drivers/vdpa/mlx5/mlx5_vdpa_cthread.c
+++ b/drivers/vdpa/mlx5/mlx5_vdpa_cthread.c
@@ -190,7 +190,6 @@ mlx5_vdpa_c_thread_handle(void *arg)
pthread_mutex_unlock(&virtq->virtq_lock);
break;
case MLX5_VDPA_TASK_DEV_CLOSE_NOWAIT:
-   mlx5_vdpa_virtq_unreg_intr_handle_all(priv);
pthread_mutex_lock(&priv->steer_update_lock);
mlx5_vdpa_steer_unset(priv);
pthread_mutex_unlock(&priv->steer_update_lock);
-- 
2.27.0



[PATCH] examples/vdpa: fix devices cleanup

2022-12-25 Thread Yajun Wu
Move rte_eal_cleanup to function vdpa_sample_quit which
handling all example app quit.
Otherwise rte_eal_cleanup won't be called on receiving signal
like SIGINT(control + c).

Fixes: 10aa3757 ("examples: add eal cleanup to examples")
Cc: sta...@dpdk.org

Signed-off-by: Yajun Wu 
Acked-by: Matan Azrad 
---
 examples/vdpa/main.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/examples/vdpa/main.c b/examples/vdpa/main.c
index 4c7e81d7b6..9149b66538 100644
--- a/examples/vdpa/main.c
+++ b/examples/vdpa/main.c
@@ -287,6 +287,8 @@ vdpa_sample_quit(void)
if (vports[i].ifname[0] != '\0')
close_vdpa(&vports[i]);
}
+   /* clean up the EAL */
+   rte_eal_cleanup();
 }
 
 static void
@@ -633,8 +635,5 @@ main(int argc, char *argv[])
vdpa_sample_quit();
}
 
-   /* clean up the EAL */
-   rte_eal_cleanup();
-
return 0;
 }
-- 
2.27.0



[PATCH] vdpa/mlx5: workaround var offset within page

2022-03-13 Thread Yajun Wu
vDPA driver first uses kernel driver to allocate doorbell(VAR) area for
each device. Then uses var->mmap_off and var->length to mmap uverbs device
file as doorbell userspace virtual address.

Current kernel driver provides var->mmap_off equal to page start of VAR.
It's fine with x86 4K page server, because VAR physical address is only 4K
aligned thus locate in 4K page start.

But with aarch64 64K page server, the actual VAR physical address has
offset within page(not locate in 64K page start). So vDPA driver need add
this within page offset(caps.doorbell_bar_offset) to get right VAR virtual
address.

Fixes: 62c813706e4 ("vdpa/mlx5: map doorbell")
Cc: sta...@dpdk.org

Signed-off-by: Yajun Wu 
Acked-by: Matan Azrad 
---
 drivers/vdpa/mlx5/mlx5_vdpa_virtq.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c 
b/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c
index 3416797d28..0748710a76 100644
--- a/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c
+++ b/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -123,7 +124,10 @@ mlx5_vdpa_virtqs_release(struct mlx5_vdpa_priv *priv)
priv->td = NULL;
}
if (priv->virtq_db_addr) {
-   claim_zero(munmap(priv->virtq_db_addr, priv->var->length));
+   /* Mask out the within page offset for ummap. */
+   claim_zero(munmap((void *)((uint64_t)priv->virtq_db_addr &
+   ~(rte_mem_page_size() - 1ULL)),
+   priv->var->length));
priv->virtq_db_addr = NULL;
}
priv->features = 0;
@@ -486,6 +490,10 @@ mlx5_vdpa_virtqs_prepare(struct mlx5_vdpa_priv *priv)
priv->virtq_db_addr = NULL;
goto error;
} else {
+   /* Add within page offset for 64K page system. */
+   priv->virtq_db_addr = (char *)priv->virtq_db_addr +
+   ((rte_mem_page_size() - 1) &
+   priv->caps.doorbell_bar_offset);
DRV_LOG(DEBUG, "VAR address of doorbell mapping is %p.",
priv->virtq_db_addr);
}
-- 
2.27.0



[PATCH v2] vdpa/mlx5: workaround var offset within page

2022-03-14 Thread Yajun Wu
vDPA driver first uses kernel driver to allocate doorbell(VAR) area for
each device. Then uses var->mmap_off and var->length to mmap uverbs device
file as doorbell userspace virtual address.

Current kernel driver provides var->mmap_off equal to page start of VAR.
It's fine with x86 4K page server, because VAR physical address is only 4K
aligned thus locate in 4K page start.

But with aarch64 64K page server, the actual VAR physical address has
offset within page(not locate in 64K page start). So vDPA driver need add
this within page offset(caps.doorbell_bar_offset) to get right VAR virtual
address.

Fixes: 62c813706e4 ("vdpa/mlx5: map doorbell")
Cc: sta...@dpdk.org

Signed-off-by: Yajun Wu 
Acked-by: Matan Azrad 
---
 drivers/vdpa/mlx5/mlx5_vdpa_virtq.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c 
b/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c
index 3416797d28..52287e7e58 100644
--- a/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c
+++ b/drivers/vdpa/mlx5/mlx5_vdpa_virtq.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -123,7 +124,9 @@ mlx5_vdpa_virtqs_release(struct mlx5_vdpa_priv *priv)
priv->td = NULL;
}
if (priv->virtq_db_addr) {
-   claim_zero(munmap(priv->virtq_db_addr, priv->var->length));
+   /* Mask out the within page offset for munmap. */
+   claim_zero(munmap((void *)((uintptr_t)priv->virtq_db_addr &
+   ~(rte_mem_page_size() - 1)), priv->var->length));
priv->virtq_db_addr = NULL;
}
priv->features = 0;
@@ -486,6 +489,10 @@ mlx5_vdpa_virtqs_prepare(struct mlx5_vdpa_priv *priv)
priv->virtq_db_addr = NULL;
goto error;
} else {
+   /* Add within page offset for 64K page system. */
+   priv->virtq_db_addr = (char *)priv->virtq_db_addr +
+   ((rte_mem_page_size() - 1) &
+   priv->caps.doorbell_bar_offset);
DRV_LOG(DEBUG, "VAR address of doorbell mapping is %p.",
priv->virtq_db_addr);
}
-- 
2.27.0