+ memset(&priv->err_intr_handle, 0, sizeof(priv->err_intr_handle));
+ if (priv->err_chnl) {
+#ifdef HAVE_IBV_DEVX_EVENT
+ union {
+ struct mlx5dv_devx_async_event_hdr event_resp;
+ uint8_t buf[sizeof(struct mlx5dv_devx_async_event_hdr) +
+ 128];
+ } out;
+
+ /* Clean all pending events. */
+ while (mlx5_glue->devx_get_event(priv->err_chnl,
+ &out.event_resp, sizeof(out.buf)) >=
+ (ssize_t)sizeof(out.event_resp.cookie))
+ ;
+#endif
+ mlx5_glue->devx_destroy_event_channel(priv->err_chnl);
+ priv->err_chnl = NULL;
+ }
+}
+
+int
+mlx5_vdpa_cqe_event_setup(struct mlx5_vdpa_priv *priv)
+{
+ int ret;
+ rte_cpuset_t cpuset;
+ pthread_attr_t attr;
+ char name[16];
+ const struct sched_param sp = {
+ .sched_priority = sched_get_priority_max(SCHED_RR),
+ };
+
+ if (!priv->eventc)
+ /* All virtqs are in poll mode. */
+ return 0;
+ pthread_attr_init(&attr);
+ ret = pthread_attr_setschedpolicy(&attr, SCHED_RR);
+ if (ret) {
+ DRV_LOG(ERR, "Failed to set thread sched policy = RR.");
+ return -1;
+ }
+ ret = pthread_attr_setschedparam(&attr, &sp);
+ if (ret) {
+ DRV_LOG(ERR, "Failed to set thread priority.");
+ return -1;
+ }
+ ret = pthread_create(&priv->timer_tid, &attr, mlx5_vdpa_event_handle,
+ (void *)priv);
+ if (ret) {
+ DRV_LOG(ERR, "Failed to create timer thread.");
+ return -1;
+ }
+ CPU_ZERO(&cpuset);
+ if (priv->event_core != -1)
+ CPU_SET(priv->event_core, &cpuset);
+ else
+ cpuset = rte_lcore_cpuset(rte_get_main_lcore());
+ ret = pthread_setaffinity_np(priv->timer_tid, sizeof(cpuset), &cpuset);
+ if (ret) {
+ DRV_LOG(ERR, "Failed to set thread affinity.");
+ return -1;
+ }
+ snprintf(name, sizeof(name), "vDPA-mlx5-%d", priv->vid);
+ ret = rte_thread_setname(priv->timer_tid, name);
+ if (ret)
+ DRV_LOG(DEBUG, "Cannot set timer thread name.");
+ return 0;
+}
+
+void
+mlx5_vdpa_cqe_event_unset(struct mlx5_vdpa_priv *priv)
+{
+ void *status;
+