struct ibv_context *attr_ctx = NULL;
struct ibv_device_attr device_attr;
struct ibv_device_attr_ex device_attr_ex;
+ struct rte_eth_dev *prev_dev = NULL;
struct mlx4_conf conf = {
.ports.present = 0,
.mr_ext_memseg_en = 1,
ERROR("can not attach rte ethdev");
rte_errno = ENOMEM;
err = rte_errno;
- goto error;
+ goto err_secondary;
}
priv = eth_dev->data->dev_private;
if (!priv->verbs_alloc_ctx.enabled) {
" from Verbs");
rte_errno = ENOTSUP;
err = rte_errno;
- goto error;
+ goto err_secondary;
}
eth_dev->device = &pci_dev->device;
eth_dev->dev_ops = &mlx4_dev_sec_ops;
err = mlx4_proc_priv_init(eth_dev);
if (err)
- goto error;
+ goto err_secondary;
/* Receive command fd from primary process. */
err = mlx4_mp_req_verbs_cmd_fd(eth_dev);
if (err < 0) {
err = rte_errno;
- goto error;
+ goto err_secondary;
}
/* Remap UAR for Tx queues. */
err = mlx4_tx_uar_init_secondary(eth_dev, err);
if (err) {
err = rte_errno;
- goto error;
+ goto err_secondary;
}
/*
* Ethdev pointer is still required as input since
claim_zero(mlx4_glue->close_device(ctx));
rte_eth_copy_pci_info(eth_dev, pci_dev);
rte_eth_dev_probing_finish(eth_dev);
+ prev_dev = eth_dev;
continue;
+err_secondary:
+ claim_zero(mlx4_glue->close_device(ctx));
+ rte_eth_dev_release_port(eth_dev);
+ if (prev_dev)
+ rte_eth_dev_release_port(prev_dev);
+ break;
}
/* Check port status. */
err = mlx4_glue->query_port(ctx, port, &port_attr);
priv, mem_event_cb);
rte_rwlock_write_unlock(&mlx4_shared_data->mem_event_rwlock);
rte_eth_dev_probing_finish(eth_dev);
+ prev_dev = eth_dev;
continue;
port_error:
rte_free(priv);
eth_dev->data->mac_addrs = NULL;
rte_eth_dev_release_port(eth_dev);
}
+ if (prev_dev)
+ mlx4_dev_close(prev_dev);
break;
}
- /*
- * XXX if something went wrong in the loop above, there is a resource
- * leak (ctx, pd, priv, dpdk ethdev) but we can do nothing about it as
- * long as the dpdk does not provide a way to deallocate a ethdev and a
- * way to enumerate the registered ethdevs to free the previous ones.
- */
error:
if (attr_ctx)
claim_zero(mlx4_glue->close_device(attr_ctx));