+ return total;
+}
+
+static void
+mlx5_vdpa_arm_all_cqs(struct mlx5_vdpa_priv *priv)
+{
+ struct mlx5_vdpa_cq *cq;
+ int i;
+
+ for (i = 0; i < priv->nr_virtqs; i++) {
+ cq = &priv->virtqs[i].eqp.cq;
+ if (cq->cq && !cq->armed)
+ mlx5_vdpa_cq_arm(priv, cq);
+ }
+}
+
+static void *
+mlx5_vdpa_poll_handle(void *arg)
+{
+ struct mlx5_vdpa_priv *priv = arg;
+ int i;
+ struct mlx5_vdpa_cq *cq;
+ uint32_t total;
+ uint64_t current_tic;
+
+ pthread_mutex_lock(&priv->timer_lock);
+ while (!priv->timer_on)
+ pthread_cond_wait(&priv->timer_cond, &priv->timer_lock);
+ pthread_mutex_unlock(&priv->timer_lock);
+ while (1) {
+ total = 0;
+ for (i = 0; i < priv->nr_virtqs; i++) {
+ cq = &priv->virtqs[i].eqp.cq;
+ if (cq->cq && !cq->armed) {
+ uint32_t comp = mlx5_vdpa_cq_poll(cq);
+
+ if (comp) {
+ /* Notify guest for descs consuming. */
+ if (cq->callfd != -1)
+ eventfd_write(cq->callfd,
+ (eventfd_t)1);
+ total += comp;
+ }
+ }
+ }
+ current_tic = rte_rdtsc();
+ if (!total) {
+ /* No traffic ? stop timer and load interrupts. */
+ if (current_tic - priv->last_traffic_tic >=
+ rte_get_timer_hz() * MLX5_VDPA_NO_TRAFFIC_TIME_S) {
+ DRV_LOG(DEBUG, "Device %s traffic was stopped.",
+ priv->vdev->device->name);
+ mlx5_vdpa_arm_all_cqs(priv);
+ pthread_mutex_lock(&priv->timer_lock);
+ priv->timer_on = 0;
+ while (!priv->timer_on)
+ pthread_cond_wait(&priv->timer_cond,
+ &priv->timer_lock);
+ pthread_mutex_unlock(&priv->timer_lock);
+ continue;
+ }
+ } else {
+ priv->last_traffic_tic = current_tic;
+ }
+ usleep(priv->timer_delay_us);
+ }
+ return NULL;