Commit f1d2e894 authored by Shannon Nelson's avatar Shannon Nelson Committed by David S. Miller
Browse files

ionic: use index not pointer for queue tracking



Use index counters rather than pointers for tracking head
and tail in the queues to save a little memory and to perhaps
slightly faster queue processing.

Signed-off-by: default avatarShannon Nelson <snelson@pensando.io>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ea5a8b09
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -76,7 +76,7 @@ static int q_tail_show(struct seq_file *seq, void *v)
{
	struct ionic_queue *q = seq->private;

	seq_printf(seq, "%d\n", q->tail->index);
	seq_printf(seq, "%d\n", q->tail_idx);

	return 0;
}
@@ -86,7 +86,7 @@ static int q_head_show(struct seq_file *seq, void *v)
{
	struct ionic_queue *q = seq->private;

	seq_printf(seq, "%d\n", q->head->index);
	seq_printf(seq, "%d\n", q->head_idx);

	return 0;
}
@@ -96,7 +96,7 @@ static int cq_tail_show(struct seq_file *seq, void *v)
{
	struct ionic_cq *cq = seq->private;

	seq_printf(seq, "%d\n", cq->tail->index);
	seq_printf(seq, "%d\n", cq->tail_idx);

	return 0;
}
+23 −17
Original line number Diff line number Diff line
@@ -482,7 +482,7 @@ int ionic_cq_init(struct ionic_lif *lif, struct ionic_cq *cq,
	cq->bound_intr = intr;
	cq->num_descs = num_descs;
	cq->desc_size = desc_size;
	cq->tail = cq->info;
	cq->tail_idx = 0;
	cq->done_color = 1;

	cur = cq->info;
@@ -522,15 +522,18 @@ unsigned int ionic_cq_service(struct ionic_cq *cq, unsigned int work_to_do,
			      ionic_cq_cb cb, ionic_cq_done_cb done_cb,
			      void *done_arg)
{
	struct ionic_cq_info *cq_info;
	unsigned int work_done = 0;

	if (work_to_do == 0)
		return 0;

	while (cb(cq, cq->tail)) {
		if (cq->tail->last)
	cq_info = &cq->info[cq->tail_idx];
	while (cb(cq, cq_info)) {
		if (cq->tail_idx == cq->num_descs - 1)
			cq->done_color = !cq->done_color;
		cq->tail = cq->tail->next;
		cq->tail_idx = (cq->tail_idx + 1) & (cq->num_descs - 1);
		cq_info = &cq->info[cq->tail_idx];
		DEBUG_STATS_CQE_CNT(cq);

		if (++work_done >= work_to_do)
@@ -565,8 +568,8 @@ int ionic_q_init(struct ionic_lif *lif, struct ionic_dev *idev,
	q->num_descs = num_descs;
	q->desc_size = desc_size;
	q->sg_desc_size = sg_desc_size;
	q->tail = q->info;
	q->head = q->tail;
	q->tail_idx = 0;
	q->head_idx = 0;
	q->pid = pid;

	snprintf(q->name, sizeof(q->name), "L%d-%s%u", lif->index, name, index);
@@ -614,19 +617,22 @@ void ionic_q_post(struct ionic_queue *q, bool ring_doorbell, ionic_desc_cb cb,
		  void *cb_arg)
{
	struct device *dev = q->lif->ionic->dev;
	struct ionic_desc_info *desc_info;
	struct ionic_lif *lif = q->lif;

	q->head->cb = cb;
	q->head->cb_arg = cb_arg;
	q->head = q->head->next;
	desc_info = &q->info[q->head_idx];
	desc_info->cb = cb;
	desc_info->cb_arg = cb_arg;

	q->head_idx = (q->head_idx + 1) & (q->num_descs - 1);

	dev_dbg(dev, "lif=%d qname=%s qid=%d qtype=%d p_index=%d ringdb=%d\n",
		q->lif->index, q->name, q->hw_type, q->hw_index,
		q->head->index, ring_doorbell);
		q->head_idx, ring_doorbell);

	if (ring_doorbell)
		ionic_dbell_ring(lif->kern_dbpage, q->hw_type,
				 q->dbval | q->head->index);
				 q->dbval | q->head_idx);
}

static bool ionic_q_is_posted(struct ionic_queue *q, unsigned int pos)
@@ -634,8 +640,8 @@ static bool ionic_q_is_posted(struct ionic_queue *q, unsigned int pos)
	unsigned int mask, tail, head;

	mask = q->num_descs - 1;
	tail = q->tail->index;
	head = q->head->index;
	tail = q->tail_idx;
	head = q->head_idx;

	return ((pos - tail) & mask) < ((head - tail) & mask);
}
@@ -648,18 +654,18 @@ void ionic_q_service(struct ionic_queue *q, struct ionic_cq_info *cq_info,
	void *cb_arg;

	/* check for empty queue */
	if (q->tail->index == q->head->index)
	if (q->tail_idx == q->head_idx)
		return;

	/* stop index must be for a descriptor that is not yet completed */
	if (unlikely(!ionic_q_is_posted(q, stop_index)))
		dev_err(q->lif->ionic->dev,
			"ionic stop is not posted %s stop %u tail %u head %u\n",
			q->name, stop_index, q->tail->index, q->head->index);
			q->name, stop_index, q->tail_idx, q->head_idx);

	do {
		desc_info = q->tail;
		q->tail = desc_info->next;
		desc_info = &q->info[q->tail_idx];
		q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);

		cb = desc_info->cb;
		cb_arg = desc_info->cb_arg;
+37 −12
Original line number Diff line number Diff line
@@ -149,7 +149,13 @@ struct ionic_dev {
};

struct ionic_cq_info {
	union {
		void *cq_desc;
		struct ionic_txq_comp *txcq;
		struct ionic_rxq_comp *rxcq;
		struct ionic_admin_comp *admincq;
		struct ionic_notifyq_event *notifyq;
	};
	struct ionic_cq_info *next;
	unsigned int index;
	bool last;
@@ -169,8 +175,17 @@ struct ionic_page_info {
};

struct ionic_desc_info {
	union {
		void *desc;
		struct ionic_txq_desc *txq_desc;
		struct ionic_rxq_desc *rxq_desc;
		struct ionic_admin_cmd *adminq_desc;
	};
	union {
		void *sg_desc;
		struct ionic_txq_sg_desc *txq_sg_desc;
		struct ionic_rxq_sg_desc *rxq_sgl_desc;
	};
	struct ionic_desc_info *next;
	unsigned int index;
	unsigned int left;
@@ -183,22 +198,32 @@ struct ionic_desc_info {
#define IONIC_QUEUE_NAME_MAX_SZ		32

struct ionic_queue {
	struct device *dev;
	u64 dbell_count;
	u64 drop;
	u64 stop;
	u64 wake;
	struct ionic_lif *lif;
	struct ionic_desc_info *info;
	struct ionic_desc_info *tail;
	struct ionic_desc_info *head;
	struct ionic_dev *idev;
	u16 head_idx;
	u16 tail_idx;
	unsigned int index;
	unsigned int type;
	unsigned int hw_index;
	unsigned int hw_type;
	u64 dbval;
	union {
		void *base;
		struct ionic_txq_desc *txq;
		struct ionic_rxq_desc *rxq;
		struct ionic_admin_cmd *adminq;
	};
	union {
		void *sg_base;
		struct ionic_txq_sg_desc *txq_sgl;
		struct ionic_rxq_sg_desc *rxq_sgl;
	};
	dma_addr_t base_pa;
	dma_addr_t sg_base_pa;
	unsigned int num_descs;
@@ -225,9 +250,9 @@ struct ionic_cq {
	dma_addr_t base_pa;
	struct ionic_lif *lif;
	struct ionic_cq_info *info;
	struct ionic_cq_info *tail;
	struct ionic_queue *bound_q;
	struct ionic_intr_info *bound_intr;
	u16 tail_idx;
	bool done_color;
	unsigned int num_descs;
	u64 compl_count;
@@ -246,12 +271,12 @@ static inline void ionic_intr_init(struct ionic_dev *idev,

static inline unsigned int ionic_q_space_avail(struct ionic_queue *q)
{
	unsigned int avail = q->tail->index;
	unsigned int avail = q->tail_idx;

	if (q->head->index >= avail)
		avail += q->head->left - 1;
	if (q->head_idx >= avail)
		avail += q->num_descs - q->head_idx - 1;
	else
		avail -= q->head->index + 1;
		avail -= q->head_idx + 1;

	return avail;
}
+6 −6
Original line number Diff line number Diff line
@@ -632,9 +632,9 @@ static int ionic_lif_txq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
	dev_dbg(dev, "txq_init.ver %d\n", ctx.cmd.q_init.ver);
	dev_dbg(dev, "txq_init.intr_index %d\n", ctx.cmd.q_init.intr_index);

	q->tail = q->info;
	q->head = q->tail;
	cq->tail = cq->info;
	q->tail_idx = 0;
	q->head_idx = 0;
	cq->tail_idx = 0;

	err = ionic_adminq_post_wait(lif, &ctx);
	if (err)
@@ -689,9 +689,9 @@ static int ionic_lif_rxq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
	dev_dbg(dev, "rxq_init.ver %d\n", ctx.cmd.q_init.ver);
	dev_dbg(dev, "rxq_init.intr_index %d\n", ctx.cmd.q_init.intr_index);

	q->tail = q->info;
	q->head = q->tail;
	cq->tail = cq->info;
	q->tail_idx = 0;
	q->head_idx = 0;
	cq->tail_idx = 0;

	err = ionic_adminq_post_wait(lif, &ctx);
	if (err)
+6 −6
Original line number Diff line number Diff line
@@ -244,14 +244,15 @@ int ionic_lif_rss_config(struct ionic_lif *lif, u16 types,

int ionic_reset_queues(struct ionic_lif *lif, ionic_reset_cb cb, void *arg);

static inline void debug_stats_txq_post(struct ionic_queue *q,
					struct ionic_txq_desc *desc, bool dbell)
static inline void debug_stats_txq_post(struct ionic_queue *q, bool dbell)
{
	u8 num_sg_elems = ((le64_to_cpu(desc->cmd) >> IONIC_TXQ_DESC_NSGE_SHIFT)
						& IONIC_TXQ_DESC_NSGE_MASK);
	struct ionic_txq_desc *desc = &q->txq[q->head_idx];
	u8 num_sg_elems;

	q->dbell_count += dbell;

	num_sg_elems = ((le64_to_cpu(desc->cmd) >> IONIC_TXQ_DESC_NSGE_SHIFT)
						& IONIC_TXQ_DESC_NSGE_MASK);
	if (num_sg_elems > (IONIC_MAX_NUM_SG_CNTR - 1))
		num_sg_elems = IONIC_MAX_NUM_SG_CNTR - 1;

@@ -272,8 +273,7 @@ static inline void debug_stats_napi_poll(struct ionic_qcq *qcq,
#define DEBUG_STATS_CQE_CNT(cq)		((cq)->compl_count++)
#define DEBUG_STATS_RX_BUFF_CNT(q)	((q)->lif->rxqstats[q->index].buffers_posted++)
#define DEBUG_STATS_INTR_REARM(intr)	((intr)->rearm_count++)
#define DEBUG_STATS_TXQ_POST(q, txdesc, dbell) \
	debug_stats_txq_post(q, txdesc, dbell)
#define DEBUG_STATS_TXQ_POST(q, dbell)  debug_stats_txq_post(q, dbell)
#define DEBUG_STATS_NAPI_POLL(qcq, work_done) \
	debug_stats_napi_poll(qcq, work_done)

Loading