Re: [PATCH v5 04/31] elx: libefc_sli: queue create/destroy/parse routines

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi James,

On Sun, Jan 03, 2021 at 09:11:07AM -0800, James Smart wrote:
> +int
> +sli_fc_rq_alloc(struct sli4 *sli4, struct sli4_queue *q,
> +		u32 n_entries, u32 buffer_size,
> +		struct sli4_queue *cq, bool is_hdr)
> +{
> +	if (__sli_queue_init(sli4, q, SLI4_QTYPE_RQ, SLI4_RQE_SIZE,
> +			     n_entries, SLI_PAGE_SIZE))
> +		return EFC_FAIL;
> +
> +	if (!sli_cmd_rq_create_v1(sli4, sli4->bmbx.virt, &q->dma, cq->id,
> +				  buffer_size)) {
> +		if (__sli_create_queue(sli4, q)) {
> +			efc_log_info(sli4, "Create queue failed %d\n", q->id);
> +			goto error;
> +		}
> +		if (is_hdr && q->id & 1) {
> +			efc_log_info(sli4, "bad header RQ_ID %d\n", q->id);
> +			goto error;
> +		} else if (!is_hdr  && (q->id & 1) == 0) {
> +			efc_log_info(sli4, "bad data RQ_ID %d\n", q->id);
> +			goto error;
> +		}
> +	} else {
> +		goto error;
> +	}

This could be written as

	if (sli_cmd_rq_create_v1())
		goto error;
        if (__sli_create_queue())
		goto error;



> +	if (is_hdr)
> +		q->u.flag |= SLI4_QUEUE_FLAG_HDR;
> +	else
> +		q->u.flag &= ~SLI4_QUEUE_FLAG_HDR;
> +	return EFC_SUCCESS;
> +error:
> +	__sli_queue_destroy(sli4, q);
> +	return EFC_FAIL;
> +}
> +
> +int
> +sli_fc_rq_set_alloc(struct sli4 *sli4, u32 num_rq_pairs,
> +		    struct sli4_queue *qs[], u32 base_cq_id,
> +		    u32 n_entries, u32 header_buffer_size,
> +		    u32 payload_buffer_size)
> +{
> +	u32 i;
> +	struct efc_dma dma = {0};
> +	struct sli4_rsp_cmn_create_queue_set *rsp = NULL;
> +	void __iomem *db_regaddr = NULL;
> +	u32 num_rqs = num_rq_pairs * 2;
> +
> +	for (i = 0; i < num_rqs; i++) {
> +		if (__sli_queue_init(sli4, qs[i], SLI4_QTYPE_RQ,
> +				     SLI4_RQE_SIZE, n_entries,
> +				     SLI_PAGE_SIZE)) {
> +			goto error;
> +		}
> +	}
> +
> +	if (sli_cmd_rq_create_v2(sli4, num_rqs, qs, base_cq_id,
> +			       header_buffer_size, payload_buffer_size, &dma)) {
> +		goto error;
> +	}
> +
> +	if (sli_bmbx_command(sli4)) {
> +		efc_log_err(sli4, "bootstrap mailbox write failed RQSet\n");
> +		goto error;
> +	}
> +
> +	if (sli4->if_type == SLI4_INTF_IF_TYPE_6)
> +		db_regaddr = sli4->reg[1] + SLI4_IF6_RQ_DB_REG;
> +	else
> +		db_regaddr = sli4->reg[0] + SLI4_RQ_DB_REG;
> +
> +	rsp = dma.virt;
> +	if (rsp->hdr.status) {
> +		efc_log_err(sli4, "bad create RQSet status=%#x addl=%#x\n",
> +		       rsp->hdr.status, rsp->hdr.additional_status);
> +		goto error;
> +	} else {
> +		for (i = 0; i < num_rqs; i++) {
> +			qs[i]->id = i + le16_to_cpu(rsp->q_id);
> +			if ((qs[i]->id & 1) == 0)
> +				qs[i]->u.flag |= SLI4_QUEUE_FLAG_HDR;
> +			else
> +				qs[i]->u.flag &= ~SLI4_QUEUE_FLAG_HDR;
> +
> +			qs[i]->db_regaddr = db_regaddr;
> +		}
> +	}

With the goto in first block you don't need the else block.

> +
> +	dma_free_coherent(&sli4->pci->dev, dma.size, dma.virt, dma.phys);
> +
> +	return EFC_SUCCESS;
> +
> +error:
> +	for (i = 0; i < num_rqs; i++)
> +		__sli_queue_destroy(sli4, qs[i]);
> +
> +	if (dma.virt)
> +		dma_free_coherent(&sli4->pci->dev, dma.size, dma.virt,
> +				  dma.phys);
> +
> +	return EFC_FAIL;
> +}

[...]

> +int
> +sli_cq_alloc_set(struct sli4 *sli4, struct sli4_queue *qs[],
> +		 u32 num_cqs, u32 n_entries, struct sli4_queue *eqs[])
> +{
> +	u32 i;
> +	struct efc_dma dma = {0};
> +	struct sli4_rsp_cmn_create_queue_set *res;
> +	void __iomem *db_regaddr;
> +
> +	/* Align the queue DMA memory */
> +	for (i = 0; i < num_cqs; i++) {
> +		if (__sli_queue_init(sli4, qs[i], SLI4_QTYPE_CQ,
> +				SLI4_CQE_BYTES, n_entries, SLI_PAGE_SIZE))
> +			goto error;
> +	}
> +
> +	if (sli_cmd_cq_set_create(sli4, qs, num_cqs, eqs, &dma))
> +		goto error;
> +
> +	if (sli_bmbx_command(sli4))
> +		goto error;
> +
> +	if (sli4->if_type == SLI4_INTF_IF_TYPE_6)
> +		db_regaddr = sli4->reg[1] + SLI4_IF6_CQ_DB_REG;
> +	else
> +		db_regaddr = sli4->reg[0] + SLI4_EQCQ_DB_REG;
> +
> +	res = dma.virt;
> +	if (res->hdr.status) {
> +		efc_log_err(sli4, "bad create CQSet status=%#x addl=%#x\n",
> +		       res->hdr.status, res->hdr.additional_status);
> +		goto error;
> +	} else {
> +		/* Check if we got all requested CQs. */
> +		if (le16_to_cpu(res->num_q_allocated) != num_cqs) {
> +			efc_log_crit(sli4, "Requested count CQs doesn't match.\n");
> +			goto error;
> +		}
> +		/* Fill the resp cq ids. */
> +		for (i = 0; i < num_cqs; i++) {
> +			qs[i]->id = le16_to_cpu(res->q_id) + i;
> +			qs[i]->db_regaddr = db_regaddr;
> +		}
> +	}

With the goto in the true block the else block is not needed.

> +
> +	dma_free_coherent(&sli4->pci->dev, dma.size, dma.virt, dma.phys);
> +
> +	return EFC_SUCCESS;
> +
> +error:
> +	for (i = 0; i < num_cqs; i++)
> +		__sli_queue_destroy(sli4, qs[i]);
> +
> +	if (dma.virt)
> +		dma_free_coherent(&sli4->pci->dev, dma.size, dma.virt,
> +				  dma.phys);
> +
> +	return EFC_FAIL;
> +}

[...]

> +int
> +sli_eq_read(struct sli4 *sli4, struct sli4_queue *q, u8 *entry)
> +{
> +	u8 *qe = q->dma.virt;
> +	u32 *qindex = NULL;
> +	unsigned long flags = 0;
> +	u8 clear = false, valid = false;
> +	u16 wflags = 0;
> +
> +	clear = (sli4->if_type == SLI4_INTF_IF_TYPE_6) ?  false : true;
> +
> +	qindex = &q->index;
> +
> +	spin_lock_irqsave(&q->lock, flags);

First, why does the q->index access not be protected by the lock and
second, why do you need the variable anyway? Can't you just use
q->index directly?

> +
> +	qe += *qindex * q->size;
> +
> +	/* Check if eqe is valid */
> +	wflags = le16_to_cpu(((struct sli4_eqe *)qe)->dw0w0_flags);
> +	valid = ((wflags & SLI4_EQE_VALID) == q->phase);
> +	if (!valid) {

valid is not used anywhere else. It could be avoided.

> +		spin_unlock_irqrestore(&q->lock, flags);
> +		return EFC_FAIL;
> +	}
> +
> +	if (clear) {

Clear is a local variable only used once here. And why do the
comparison right here where it's needed?

> +		wflags &= ~SLI4_EQE_VALID;
> +		((struct sli4_eqe *)qe)->dw0w0_flags =
> +						cpu_to_le16(wflags);
> +	}
> +
> +	memcpy(entry, qe, q->size);
> +	*qindex = (*qindex + 1) & (q->length - 1);
> +	q->n_posted++;
> +	/*
> +	 * For prism, the phase value will be used
> +	 * to check the validity of eq/cq entries.
> +	 * The value toggles after a complete sweep
> +	 * through the queue.
> +	 */
> +
> +	if (sli4->if_type == SLI4_INTF_IF_TYPE_6 && *qindex == 0)
> +		q->phase ^= (u16)0x1;
> +
> +	spin_unlock_irqrestore(&q->lock, flags);
> +
> +	return EFC_SUCCESS;
> +}
> +
> +int
> +sli_cq_read(struct sli4 *sli4, struct sli4_queue *q, u8 *entry)
> +{
> +	u8 *qe = q->dma.virt;
> +	u32 *qindex = NULL;
> +	unsigned long	flags = 0;
> +	u8 clear = false;
> +	u32 dwflags = 0;
> +	bool valid_bit_set;
> +
> +	clear = (sli4->if_type == SLI4_INTF_IF_TYPE_6) ?  false : true;
> +
> +	qindex = &q->index;
> +
> +	spin_lock_irqsave(&q->lock, flags);

The same question as above about q->index.

> +
> +	qe += *qindex * q->size;
> +
> +	/* Check if cqe is valid */
> +	dwflags = le32_to_cpu(((struct sli4_mcqe *)qe)->dw3_flags);
> +	valid_bit_set = (dwflags & SLI4_MCQE_VALID) != 0;
> +
> +	if (valid_bit_set != q->phase) {
> +		spin_unlock_irqrestore(&q->lock, flags);
> +		return EFC_FAIL;
> +	}
> +
> +	if (clear) {

Same comment as in the above function on 'clear'.

> +		dwflags &= ~SLI4_MCQE_VALID;
> +		((struct sli4_mcqe *)qe)->dw3_flags =
> +					cpu_to_le32(dwflags);
> +	}
> +
> +	memcpy(entry, qe, q->size);
> +	*qindex = (*qindex + 1) & (q->length - 1);
> +	q->n_posted++;
> +	/*
> +	 * For prism, the phase value will be used
> +	 * to check the validity of eq/cq entries.
> +	 * The value toggles after a complete sweep
> +	 * through the queue.
> +	 */
> +
> +	if (sli4->if_type == SLI4_INTF_IF_TYPE_6 && *qindex == 0)
> +		q->phase ^= (u16)0x1;
> +
> +	spin_unlock_irqrestore(&q->lock, flags);
> +
> +	return EFC_SUCCESS;
> +}
> +
> +int
> +sli_mq_read(struct sli4 *sli4, struct sli4_queue *q, u8 *entry)
> +{
> +	u8 *qe = q->dma.virt;
> +	u32 *qindex = NULL;
> +	unsigned long flags = 0;
> +
> +	qindex = &q->u.r_idx;
> +
> +	spin_lock_irqsave(&q->lock, flags);

qindex again.

> +
> +	qe += *qindex * q->size;
> +
> +	/* Check if mqe is valid */
> +	if (q->index == q->u.r_idx) {
> +		spin_unlock_irqrestore(&q->lock, flags);
> +		return EFC_FAIL;
> +	}
> +
> +	memcpy(entry, qe, q->size);
> +	*qindex = (*qindex + 1) & (q->length - 1);
> +
> +	spin_unlock_irqrestore(&q->lock, flags);
> +
> +	return EFC_SUCCESS;
> +}

Thanks,
Daniel



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux