예제 #1
0
/**
 * DPDK callback to start the device.
 *
 * Simulate device start by attaching all configured flows.
 *
 * @param dev
 *   Pointer to Ethernet device structure.
 *
 * @return
 *   0 on success, negative errno value on failure.
 */
int
mlx5_dev_start(struct rte_eth_dev *dev)
{
	struct priv *priv = dev->data->dev_private;
	int err;

	if (mlx5_is_secondary())
		return -E_RTE_SECONDARY;

	priv_lock(priv);
	if (priv->started) {
		priv_unlock(priv);
		return 0;
	}
	DEBUG("%p: allocating and configuring hash RX queues", (void *)dev);
	err = priv_create_hash_rxqs(priv);
	if (!err)
		err = priv_rehash_flows(priv);
	if (!err)
		priv->started = 1;
	else {
		ERROR("%p: an error occurred while configuring hash RX queues:"
		      " %s",
		      (void *)priv, strerror(err));
		/* Rollback. */
		priv_special_flow_disable_all(priv);
		priv_mac_addrs_disable(priv);
		priv_destroy_hash_rxqs(priv);
	}
	if (dev->data->dev_conf.fdir_conf.mode != RTE_FDIR_MODE_NONE)
		priv_fdir_enable(priv);
	priv_dev_interrupt_handler_install(priv, dev);
	priv_unlock(priv);
	return -err;
}
예제 #2
0
파일: mlx5.c 프로젝트: Mellanox/dpdk.org
/**
 * DPDK callback to close the device.
 *
 * Destroy all queues and objects, free memory.
 *
 * @param dev
 *   Pointer to Ethernet device structure.
 */
static void
mlx5_dev_close(struct rte_eth_dev *dev)
{
    struct priv *priv = mlx5_get_priv(dev);
    unsigned int i;

    priv_lock(priv);
    DEBUG("%p: closing device \"%s\"",
          (void *)dev,
          ((priv->ctx != NULL) ? priv->ctx->device->name : ""));
    /* In case mlx5_dev_stop() has not been called. */
    priv_dev_interrupt_handler_uninstall(priv, dev);
    priv_special_flow_disable_all(priv);
    priv_mac_addrs_disable(priv);
    priv_destroy_hash_rxqs(priv);

    /* Remove flow director elements. */
    priv_fdir_disable(priv);
    priv_fdir_delete_filters_list(priv);

    /* Prevent crashes when queues are still in use. */
    dev->rx_pkt_burst = removed_rx_burst;
    dev->tx_pkt_burst = removed_tx_burst;
    if (priv->rxqs != NULL) {
        /* XXX race condition if mlx5_rx_burst() is still running. */
        usleep(1000);
        for (i = 0; (i != priv->rxqs_n); ++i) {
            struct rxq *rxq = (*priv->rxqs)[i];
            struct rxq_ctrl *rxq_ctrl;

            if (rxq == NULL)
                continue;
            rxq_ctrl = container_of(rxq, struct rxq_ctrl, rxq);
            (*priv->rxqs)[i] = NULL;
            rxq_cleanup(rxq_ctrl);
            rte_free(rxq_ctrl);
        }
        priv->rxqs_n = 0;
        priv->rxqs = NULL;
    }
예제 #3
0
/**
 * DPDK callback to stop the device.
 *
 * Simulate device stop by detaching all configured flows.
 *
 * @param dev
 *   Pointer to Ethernet device structure.
 */
void
mlx5_dev_stop(struct rte_eth_dev *dev)
{
	struct priv *priv = dev->data->dev_private;

	if (mlx5_is_secondary())
		return;

	priv_lock(priv);
	if (!priv->started) {
		priv_unlock(priv);
		return;
	}
	DEBUG("%p: cleaning up and destroying hash RX queues", (void *)dev);
	priv_special_flow_disable_all(priv);
	priv_mac_addrs_disable(priv);
	priv_destroy_hash_rxqs(priv);
	priv_fdir_disable(priv);
	priv_dev_interrupt_handler_uninstall(priv, dev);
	priv->started = 0;
	priv_unlock(priv);
}
예제 #4
0
파일: mlx5.c 프로젝트: goby/dpdk
/**
 * DPDK callback to close the device.
 *
 * Destroy all queues and objects, free memory.
 *
 * @param dev
 *   Pointer to Ethernet device structure.
 */
static void
mlx5_dev_close(struct rte_eth_dev *dev)
{
	struct priv *priv = dev->data->dev_private;
	void *tmp;
	unsigned int i;

	priv_lock(priv);
	DEBUG("%p: closing device \"%s\"",
	      (void *)dev,
	      ((priv->ctx != NULL) ? priv->ctx->device->name : ""));
	/* In case mlx5_dev_stop() has not been called. */
	priv_dev_interrupt_handler_uninstall(priv, dev);
	priv_allmulticast_disable(priv);
	priv_promiscuous_disable(priv);
	priv_mac_addrs_disable(priv);
	priv_destroy_hash_rxqs(priv);
	/* Prevent crashes when queues are still in use. */
	dev->rx_pkt_burst = removed_rx_burst;
	dev->tx_pkt_burst = removed_tx_burst;
	if (priv->rxqs != NULL) {
		/* XXX race condition if mlx5_rx_burst() is still running. */
		usleep(1000);
		for (i = 0; (i != priv->rxqs_n); ++i) {
			tmp = (*priv->rxqs)[i];
			if (tmp == NULL)
				continue;
			(*priv->rxqs)[i] = NULL;
			rxq_cleanup(tmp);
			rte_free(tmp);
		}
		priv->rxqs_n = 0;
		priv->rxqs = NULL;
	}
	if (priv->txqs != NULL) {
		/* XXX race condition if mlx5_tx_burst() is still running. */
		usleep(1000);
		for (i = 0; (i != priv->txqs_n); ++i) {
			tmp = (*priv->txqs)[i];
			if (tmp == NULL)
				continue;
			(*priv->txqs)[i] = NULL;
			txq_cleanup(tmp);
			rte_free(tmp);
		}
		priv->txqs_n = 0;
		priv->txqs = NULL;
	}
	if (priv->pd != NULL) {
		assert(priv->ctx != NULL);
		claim_zero(ibv_dealloc_pd(priv->pd));
		claim_zero(ibv_close_device(priv->ctx));
	} else
		assert(priv->ctx == NULL);
	if (priv->rss_conf != NULL) {
		for (i = 0; (i != hash_rxq_init_n); ++i)
			rte_free((*priv->rss_conf)[i]);
		rte_free(priv->rss_conf);
	}
	priv_unlock(priv);
	memset(priv, 0, sizeof(*priv));
}