示例#1
0
文件: cq.c 项目: 274914765/C
int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struct mlx4_mtt *mtt,
          struct mlx4_uar *uar, u64 db_rec, struct mlx4_cq *cq,
          int collapsed)
{
    struct mlx4_priv *priv = mlx4_priv(dev);
    struct mlx4_cq_table *cq_table = &priv->cq_table;
    struct mlx4_cmd_mailbox *mailbox;
    struct mlx4_cq_context *cq_context;
    u64 mtt_addr;
    int err;

    cq->cqn = mlx4_bitmap_alloc(&cq_table->bitmap);
    if (cq->cqn == -1)
        return -ENOMEM;

    err = mlx4_table_get(dev, &cq_table->table, cq->cqn);
    if (err)
        goto err_out;

    err = mlx4_table_get(dev, &cq_table->cmpt_table, cq->cqn);
    if (err)
        goto err_put;

    spin_lock_irq(&cq_table->lock);
    err = radix_tree_insert(&cq_table->tree, cq->cqn, cq);
    spin_unlock_irq(&cq_table->lock);
    if (err)
        goto err_cmpt_put;

    mailbox = mlx4_alloc_cmd_mailbox(dev);
    if (IS_ERR(mailbox)) {
        err = PTR_ERR(mailbox);
        goto err_radix;
    }

    cq_context = mailbox->buf;
    memset(cq_context, 0, sizeof *cq_context);

    cq_context->flags        = cpu_to_be32(!!collapsed << 18);
    cq_context->logsize_usrpage = cpu_to_be32((ilog2(nent) << 24) | uar->index);
    cq_context->comp_eqn        = priv->eq_table.eq[MLX4_EQ_COMP].eqn;
    cq_context->log_page_size   = mtt->page_shift - MLX4_ICM_PAGE_SHIFT;

    mtt_addr = mlx4_mtt_addr(dev, mtt);
    cq_context->mtt_base_addr_h = mtt_addr >> 32;
    cq_context->mtt_base_addr_l = cpu_to_be32(mtt_addr & 0xffffffff);
    cq_context->db_rec_addr     = cpu_to_be64(db_rec);

    err = mlx4_SW2HW_CQ(dev, mailbox, cq->cqn);
    mlx4_free_cmd_mailbox(dev, mailbox);
    if (err)
        goto err_radix;

    cq->cons_index = 0;
    cq->arm_sn     = 1;
    cq->uar        = uar;
    atomic_set(&cq->refcount, 1);
    init_completion(&cq->free);

    return 0;

err_radix:
    spin_lock_irq(&cq_table->lock);
    radix_tree_delete(&cq_table->tree, cq->cqn);
    spin_unlock_irq(&cq_table->lock);

err_cmpt_put:
    mlx4_table_put(dev, &cq_table->cmpt_table, cq->cqn);

err_put:
    mlx4_table_put(dev, &cq_table->table, cq->cqn);

err_out:
    mlx4_bitmap_free(&cq_table->bitmap, cq->cqn);

    return err;
}
示例#2
0
文件: cq.c 项目: Cai900205/test
int mlx4_cq_alloc(struct mlx4_dev *dev, int nent,
		  struct mlx4_mtt *mtt, struct mlx4_uar *uar, u64 db_rec,
		  struct mlx4_cq *cq, unsigned vector, int collapsed,
		  int timestamp_en)
{
	struct mlx4_priv *priv = mlx4_priv(dev);
	struct mlx4_cq_table *cq_table = &priv->cq_table;
	struct mlx4_cmd_mailbox *mailbox;
	struct mlx4_cq_context *cq_context;
	u64 mtt_addr;
	int err;

	if (vector > dev->caps.num_comp_vectors + dev->caps.comp_pool)
		return -EINVAL;

	cq->vector = vector;

	err = mlx4_cq_alloc_icm(dev, &cq->cqn);
	if (err)
		return err;

	spin_lock_irq(&cq_table->lock);
	err = radix_tree_insert(&cq_table->tree, cq->cqn, cq);
	spin_unlock_irq(&cq_table->lock);
	if (err)
		goto err_icm;

	mailbox = mlx4_alloc_cmd_mailbox(dev);
	if (IS_ERR(mailbox)) {
		err = PTR_ERR(mailbox);
		goto err_radix;
	}

	cq_context = mailbox->buf;
	memset(cq_context, 0, sizeof *cq_context);

	cq_context->flags	    = cpu_to_be32(!!collapsed << 18);
	if (timestamp_en)
		cq_context->flags  |= cpu_to_be32(1 << 19);

	cq_context->logsize_usrpage = cpu_to_be32((ilog2(nent) << 24) | uar->index);
	cq_context->comp_eqn	    = priv->eq_table.eq[vector].eqn;
	cq_context->log_page_size   = mtt->page_shift - MLX4_ICM_PAGE_SHIFT;

	mtt_addr = mlx4_mtt_addr(dev, mtt);
	cq_context->mtt_base_addr_h = mtt_addr >> 32;
	cq_context->mtt_base_addr_l = cpu_to_be32(mtt_addr & 0xffffffff);
	cq_context->db_rec_addr     = cpu_to_be64(db_rec);

	err = mlx4_SW2HW_CQ(dev, mailbox, cq->cqn);
	mlx4_free_cmd_mailbox(dev, mailbox);
	if (err)
		goto err_radix;

	cq->cons_index = 0;
	cq->arm_sn     = 1;
	cq->uar        = uar;

	cq->eqn = priv->eq_table.eq[cq->vector].eqn;
	cq->irq = priv->eq_table.eq[cq->vector].irq;

	return 0;

err_radix:
	spin_lock_irq(&cq_table->lock);
	radix_tree_delete(&cq_table->tree, cq->cqn);
	spin_unlock_irq(&cq_table->lock);

err_icm:
	mlx4_cq_free_icm(dev, cq->cqn);

	return err;
}
示例#3
0
int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struct mlx4_mtt *mtt,
		  struct mlx4_uar *uar, u64 db_rec, struct mlx4_cq *cq,
		  unsigned vector, int collapsed)
{
	struct mlx4_priv *priv = mlx4_priv(dev);
	struct mlx4_cq_table *cq_table = &priv->cq_table;
	struct mlx4_cmd_mailbox *mailbox;
	struct mlx4_cq_context *cq_context;
	u64 mtt_addr;
	int err;

	cq->vector = (vector == MLX4_LEAST_ATTACHED_VECTOR) ?
		mlx4_find_least_loaded_vector(priv) : vector;

	if (cq->vector > dev->caps.num_comp_vectors + dev->caps.poolsz)
		return -EINVAL;

	err = mlx4_cq_alloc_icm(dev, &cq->cqn);
	if (err)
		return err;

	spin_lock_irq(&cq_table->lock);
	err = radix_tree_insert(&cq_table->tree, cq->cqn, cq);
	spin_unlock_irq(&cq_table->lock);
	if (err)
		goto err_icm;

	mailbox = mlx4_alloc_cmd_mailbox(dev);
	if (IS_ERR(mailbox)) {
		err = PTR_ERR(mailbox);
		goto err_radix;
	}

	cq_context = mailbox->buf;
	memset(cq_context, 0, sizeof *cq_context);

	cq_context->flags	    = cpu_to_be32(!!collapsed << 18);
	cq_context->logsize_usrpage = cpu_to_be32((ilog2(nent) << 24) | uar->index);
	cq_context->comp_eqn	    = priv->eq_table.eq[cq->vector].eqn;
	cq_context->log_page_size   = mtt->page_shift - MLX4_ICM_PAGE_SHIFT;

	mtt_addr = mlx4_mtt_addr(dev, mtt);
	cq_context->mtt_base_addr_h = mtt_addr >> 32;
	cq_context->mtt_base_addr_l = cpu_to_be32(mtt_addr & 0xffffffff);
	cq_context->db_rec_addr     = cpu_to_be64(db_rec);

	err = mlx4_SW2HW_CQ(dev, mailbox, cq->cqn);
	mlx4_free_cmd_mailbox(dev, mailbox);
	if (err)
		goto err_radix;

	priv->eq_table.eq[cq->vector].load++;
	cq->cons_index = 0;
	cq->arm_sn     = 1;
	cq->uar        = uar;
	atomic_set(&cq->refcount, 1);
	init_completion(&cq->free);

	return 0;

err_radix:
	spin_lock_irq(&cq_table->lock);
	radix_tree_delete(&cq_table->tree, cq->cqn);
	spin_unlock_irq(&cq_table->lock);

err_icm:
	mlx4_cq_free_icm(dev, cq->cqn);

	return err;
}