* Initialize common RSS context resources. * * Because ConnectX-3 hardware limitations require a fixed order in the * indirection table, WQs must be allocated sequentially to be part of a * common RSS context. * * Since a newly created WQ cannot be moved to a different context, this * function allocates them all at once, one for each configured Rx queue, * as well as all related resources
| 328 | * 0 on success, a negative errno value otherwise and rte_errno is set. |
| 329 | */ |
| 330 | int |
| 331 | mlx4_rss_init(struct mlx4_priv *priv) |
| 332 | { |
| 333 | struct rte_eth_dev *dev = ETH_DEV(priv); |
| 334 | uint8_t log2_range = rte_log2_u32(dev->data->nb_rx_queues); |
| 335 | uint32_t wq_num_prev = 0; |
| 336 | const char *msg; |
| 337 | unsigned int i; |
| 338 | int ret; |
| 339 | |
| 340 | if (priv->rss_init) |
| 341 | return 0; |
| 342 | if (ETH_DEV(priv)->data->nb_rx_queues > priv->hw_rss_max_qps) { |
| 343 | ERROR("RSS does not support more than %d queues", |
| 344 | priv->hw_rss_max_qps); |
| 345 | rte_errno = EINVAL; |
| 346 | return -rte_errno; |
| 347 | } |
| 348 | /* Prepare range for RSS contexts before creating the first WQ. */ |
| 349 | ret = mlx4_glue->dv_set_context_attr |
| 350 | (priv->ctx, |
| 351 | MLX4DV_SET_CTX_ATTR_LOG_WQS_RANGE_SZ, |
| 352 | &log2_range); |
| 353 | if (ret) { |
| 354 | ERROR("cannot set up range size for RSS context to %u" |
| 355 | " (for %u Rx queues), error: %s", |
| 356 | 1 << log2_range, dev->data->nb_rx_queues, strerror(ret)); |
| 357 | rte_errno = ret; |
| 358 | return -ret; |
| 359 | } |
| 360 | for (i = 0; i != ETH_DEV(priv)->data->nb_rx_queues; ++i) { |
| 361 | struct rxq *rxq = ETH_DEV(priv)->data->rx_queues[i]; |
| 362 | struct ibv_cq *cq; |
| 363 | struct ibv_wq *wq; |
| 364 | uint32_t wq_num; |
| 365 | |
| 366 | /* Attach the configured Rx queues. */ |
| 367 | if (rxq) { |
| 368 | MLX4_ASSERT(!rxq->usecnt); |
| 369 | ret = mlx4_rxq_attach(rxq); |
| 370 | if (!ret) { |
| 371 | wq_num = rxq->wq->wq_num; |
| 372 | goto wq_num_check; |
| 373 | } |
| 374 | ret = -ret; |
| 375 | msg = "unable to create Rx queue resources"; |
| 376 | goto error; |
| 377 | } |
| 378 | /* |
| 379 | * WQs are temporarily allocated for unconfigured Rx queues |
| 380 | * to maintain proper index alignment in indirection table |
| 381 | * by skipping unused WQ numbers. |
| 382 | * |
| 383 | * The reason this works at all even though these WQs are |
| 384 | * immediately destroyed is that WQNs are allocated |
| 385 | * sequentially and are guaranteed to never be reused in the |
| 386 | * same context by the underlying implementation. |
| 387 | */ |
no test coverage detected