interrupts are configured to the device in order to notify traffic for the
driver. Default value is 2s.
+- ``event_core`` parameter [int]
+
+ CPU core number to set polling thread affinity to, default to control plane
+ cpu.
+
Error handling
^^^^^^^^^^^^^^
{
struct mlx5_vdpa_priv *priv = opaque;
unsigned long tmp;
+ int n_cores = sysconf(_SC_NPROCESSORS_ONLN);
if (strcmp(key, "class") == 0)
return 0;
priv->event_us = (uint32_t)tmp;
} else if (strcmp(key, "no_traffic_time") == 0) {
priv->no_traffic_time_s = (uint32_t)tmp;
+ } else if (strcmp(key, "event_core") == 0) {
+ if (tmp >= (unsigned long)n_cores)
+ DRV_LOG(WARNING, "Invalid event_core %s.", val);
+ else
+ priv->event_core = tmp;
} else {
DRV_LOG(WARNING, "Invalid key %s.", key);
}
priv->event_mode = MLX5_VDPA_EVENT_MODE_DYNAMIC_TIMER;
priv->event_us = 0;
+ priv->event_core = -1;
priv->no_traffic_time_s = MLX5_VDPA_DEFAULT_NO_TRAFFIC_TIME_S;
if (devargs == NULL)
return;
mlx5_vdpa_cqe_event_setup(struct mlx5_vdpa_priv *priv)
{
int ret;
+ rte_cpuset_t cpuset;
+ pthread_attr_t attr;
+ char name[16];
if (!priv->eventc)
/* All virtqs are in poll mode. */
pthread_mutex_init(&priv->timer_lock, NULL);
pthread_cond_init(&priv->timer_cond, NULL);
priv->timer_on = 0;
- ret = pthread_create(&priv->timer_tid, NULL,
+ pthread_attr_init(&attr);
+ 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_attr_setaffinity_np(&attr, sizeof(cpuset),
+ &cpuset);
+ if (ret) {
+ DRV_LOG(ERR, "Failed to set thread affinity.");
+ return -1;
+ }
+ ret = pthread_create(&priv->timer_tid, &attr,
mlx5_vdpa_poll_handle, (void *)priv);
if (ret) {
DRV_LOG(ERR, "Failed to create timer thread.");
return -1;
}
+ snprintf(name, sizeof(name), "vDPA-mlx5-%d", priv->vid);
+ ret = pthread_setname_np(priv->timer_tid, name);
+ if (ret) {
+ DRV_LOG(ERR, "Failed to set timer thread name.");
+ return -1;
+ }
}
priv->intr_handle.fd = priv->eventc->fd;
priv->intr_handle.type = RTE_INTR_HANDLE_EXT;