mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-04 16:15:11 +00:00
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: Shannon Nelson <snelson@pensando.io> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
ea5a8b09dc
commit
f1d2e894f1
7 changed files with 129 additions and 88 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -149,7 +149,13 @@ struct ionic_dev {
|
|||
};
|
||||
|
||||
struct ionic_cq_info {
|
||||
void *cq_desc;
|
||||
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 {
|
||||
void *desc;
|
||||
void *sg_desc;
|
||||
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;
|
||||
void *base;
|
||||
void *sg_base;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -181,15 +181,17 @@ static const char *ionic_opcode_to_str(enum ionic_cmd_opcode opcode)
|
|||
|
||||
static void ionic_adminq_flush(struct ionic_lif *lif)
|
||||
{
|
||||
struct ionic_queue *adminq = &lif->adminqcq->q;
|
||||
struct ionic_queue *q = &lif->adminqcq->q;
|
||||
struct ionic_desc_info *desc_info;
|
||||
|
||||
spin_lock(&lif->adminq_lock);
|
||||
|
||||
while (adminq->tail != adminq->head) {
|
||||
memset(adminq->tail->desc, 0, sizeof(union ionic_adminq_cmd));
|
||||
adminq->tail->cb = NULL;
|
||||
adminq->tail->cb_arg = NULL;
|
||||
adminq->tail = adminq->tail->next;
|
||||
while (q->tail_idx != q->head_idx) {
|
||||
desc_info = &q->info[q->tail_idx];
|
||||
memset(desc_info->desc, 0, sizeof(union ionic_adminq_cmd));
|
||||
desc_info->cb = NULL;
|
||||
desc_info->cb_arg = NULL;
|
||||
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
|
||||
}
|
||||
spin_unlock(&lif->adminq_lock);
|
||||
}
|
||||
|
@ -245,7 +247,8 @@ static void ionic_adminq_cb(struct ionic_queue *q,
|
|||
|
||||
static int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
|
||||
{
|
||||
struct ionic_queue *adminq;
|
||||
struct ionic_desc_info *desc_info;
|
||||
struct ionic_queue *q;
|
||||
int err = 0;
|
||||
|
||||
WARN_ON(in_interrupt());
|
||||
|
@ -253,10 +256,10 @@ static int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
|
|||
if (!lif->adminqcq)
|
||||
return -EIO;
|
||||
|
||||
adminq = &lif->adminqcq->q;
|
||||
q = &lif->adminqcq->q;
|
||||
|
||||
spin_lock(&lif->adminq_lock);
|
||||
if (!ionic_q_has_space(adminq, 1)) {
|
||||
if (!ionic_q_has_space(q, 1)) {
|
||||
err = -ENOSPC;
|
||||
goto err_out;
|
||||
}
|
||||
|
@ -265,13 +268,14 @@ static int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
|
|||
if (err)
|
||||
goto err_out;
|
||||
|
||||
memcpy(adminq->head->desc, &ctx->cmd, sizeof(ctx->cmd));
|
||||
desc_info = &q->info[q->head_idx];
|
||||
memcpy(desc_info->desc, &ctx->cmd, sizeof(ctx->cmd));
|
||||
|
||||
dev_dbg(&lif->netdev->dev, "post admin queue command:\n");
|
||||
dynamic_hex_dump("cmd ", DUMP_PREFIX_OFFSET, 16, 1,
|
||||
&ctx->cmd, sizeof(ctx->cmd), true);
|
||||
|
||||
ionic_q_post(adminq, true, ionic_adminq_cb, ctx);
|
||||
ionic_q_post(q, true, ionic_adminq_cb, ctx);
|
||||
|
||||
err_out:
|
||||
spin_unlock(&lif->adminq_lock);
|
||||
|
|
|
@ -22,7 +22,7 @@ static bool ionic_tx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info)
|
|||
static inline void ionic_txq_post(struct ionic_queue *q, bool ring_dbell,
|
||||
ionic_desc_cb cb_func, void *cb_arg)
|
||||
{
|
||||
DEBUG_STATS_TXQ_POST(q, q->head->desc, ring_dbell);
|
||||
DEBUG_STATS_TXQ_POST(q, ring_dbell);
|
||||
|
||||
ionic_q_post(q, ring_dbell, cb_func, cb_arg);
|
||||
}
|
||||
|
@ -235,14 +235,14 @@ static bool ionic_rx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info)
|
|||
return false;
|
||||
|
||||
/* check for empty queue */
|
||||
if (q->tail->index == q->head->index)
|
||||
if (q->tail_idx == q->head_idx)
|
||||
return false;
|
||||
|
||||
desc_info = q->tail;
|
||||
desc_info = &q->info[q->tail_idx];
|
||||
if (desc_info->index != le16_to_cpu(comp->comp_index))
|
||||
return false;
|
||||
|
||||
q->tail = desc_info->next;
|
||||
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
|
||||
|
||||
/* clean the related q entry, only one per qc completion */
|
||||
ionic_rx_clean(q, desc_info, cq_info, desc_info->cb_arg);
|
||||
|
@ -338,7 +338,7 @@ void ionic_rx_fill(struct ionic_queue *q)
|
|||
|
||||
for (i = ionic_q_space_avail(q); i; i--) {
|
||||
remain_len = len;
|
||||
desc_info = q->head;
|
||||
desc_info = &q->info[q->head_idx];
|
||||
desc = desc_info->desc;
|
||||
sg_desc = desc_info->sg_desc;
|
||||
page_info = &desc_info->pages[0];
|
||||
|
@ -387,7 +387,7 @@ void ionic_rx_fill(struct ionic_queue *q)
|
|||
}
|
||||
|
||||
ionic_dbell_ring(q->lif->kern_dbpage, q->hw_type,
|
||||
q->dbval | q->head->index);
|
||||
q->dbval | q->head_idx);
|
||||
}
|
||||
|
||||
static void ionic_rx_fill_cb(void *arg)
|
||||
|
@ -397,25 +397,29 @@ static void ionic_rx_fill_cb(void *arg)
|
|||
|
||||
void ionic_rx_empty(struct ionic_queue *q)
|
||||
{
|
||||
struct ionic_desc_info *cur;
|
||||
struct ionic_desc_info *desc_info;
|
||||
struct ionic_rxq_desc *desc;
|
||||
unsigned int i;
|
||||
u16 idx;
|
||||
|
||||
for (cur = q->tail; cur != q->head; cur = cur->next) {
|
||||
desc = cur->desc;
|
||||
idx = q->tail_idx;
|
||||
while (idx != q->head_idx) {
|
||||
desc_info = &q->info[idx];
|
||||
desc = desc_info->desc;
|
||||
desc->addr = 0;
|
||||
desc->len = 0;
|
||||
|
||||
for (i = 0; i < cur->npages; i++) {
|
||||
if (likely(cur->pages[i].page)) {
|
||||
ionic_rx_page_free(q, cur->pages[i].page,
|
||||
cur->pages[i].dma_addr);
|
||||
cur->pages[i].page = NULL;
|
||||
cur->pages[i].dma_addr = 0;
|
||||
for (i = 0; i < desc_info->npages; i++) {
|
||||
if (likely(desc_info->pages[i].page)) {
|
||||
ionic_rx_page_free(q, desc_info->pages[i].page,
|
||||
desc_info->pages[i].dma_addr);
|
||||
desc_info->pages[i].page = NULL;
|
||||
desc_info->pages[i].dma_addr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
cur->cb_arg = NULL;
|
||||
desc_info->cb_arg = NULL;
|
||||
idx = (idx + 1) & (q->num_descs - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -630,9 +634,9 @@ static bool ionic_tx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info)
|
|||
* several q entries completed for each cq completion
|
||||
*/
|
||||
do {
|
||||
desc_info = q->tail;
|
||||
q->tail = desc_info->next;
|
||||
ionic_tx_clean(q, desc_info, cq->tail, desc_info->cb_arg);
|
||||
desc_info = &q->info[q->tail_idx];
|
||||
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
|
||||
ionic_tx_clean(q, desc_info, cq_info, desc_info->cb_arg);
|
||||
desc_info->cb = NULL;
|
||||
desc_info->cb_arg = NULL;
|
||||
} while (desc_info->index != le16_to_cpu(comp->comp_index));
|
||||
|
@ -658,9 +662,9 @@ void ionic_tx_empty(struct ionic_queue *q)
|
|||
int done = 0;
|
||||
|
||||
/* walk the not completed tx entries, if any */
|
||||
while (q->head != q->tail) {
|
||||
desc_info = q->tail;
|
||||
q->tail = desc_info->next;
|
||||
while (q->head_idx != q->tail_idx) {
|
||||
desc_info = &q->info[q->tail_idx];
|
||||
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
|
||||
ionic_tx_clean(q, desc_info, NULL, desc_info->cb_arg);
|
||||
desc_info->cb = NULL;
|
||||
desc_info->cb_arg = NULL;
|
||||
|
@ -748,8 +752,8 @@ static void ionic_tx_tso_post(struct ionic_queue *q, struct ionic_txq_desc *desc
|
|||
static struct ionic_txq_desc *ionic_tx_tso_next(struct ionic_queue *q,
|
||||
struct ionic_txq_sg_elem **elem)
|
||||
{
|
||||
struct ionic_txq_sg_desc *sg_desc = q->head->sg_desc;
|
||||
struct ionic_txq_desc *desc = q->head->desc;
|
||||
struct ionic_txq_sg_desc *sg_desc = q->info[q->head_idx].txq_sg_desc;
|
||||
struct ionic_txq_desc *desc = q->info[q->head_idx].txq_desc;
|
||||
|
||||
*elem = sg_desc->elems;
|
||||
return desc;
|
||||
|
@ -758,13 +762,13 @@ static struct ionic_txq_desc *ionic_tx_tso_next(struct ionic_queue *q,
|
|||
static int ionic_tx_tso(struct ionic_queue *q, struct sk_buff *skb)
|
||||
{
|
||||
struct ionic_tx_stats *stats = q_to_tx_stats(q);
|
||||
struct ionic_desc_info *abort = q->head;
|
||||
struct ionic_desc_info *rewind_desc_info;
|
||||
struct device *dev = q->lif->ionic->dev;
|
||||
struct ionic_desc_info *rewind = abort;
|
||||
struct ionic_txq_sg_elem *elem;
|
||||
struct ionic_txq_desc *desc;
|
||||
unsigned int frag_left = 0;
|
||||
unsigned int offset = 0;
|
||||
u16 abort = q->head_idx;
|
||||
unsigned int len_left;
|
||||
dma_addr_t desc_addr;
|
||||
unsigned int hdrlen;
|
||||
|
@ -772,6 +776,7 @@ static int ionic_tx_tso(struct ionic_queue *q, struct sk_buff *skb)
|
|||
unsigned int seglen;
|
||||
u64 total_bytes = 0;
|
||||
u64 total_pkts = 0;
|
||||
u16 rewind = abort;
|
||||
unsigned int left;
|
||||
unsigned int len;
|
||||
unsigned int mss;
|
||||
|
@ -916,19 +921,20 @@ static int ionic_tx_tso(struct ionic_queue *q, struct sk_buff *skb)
|
|||
return 0;
|
||||
|
||||
err_out_abort:
|
||||
while (rewind->desc != q->head->desc) {
|
||||
ionic_tx_clean(q, rewind, NULL, NULL);
|
||||
rewind = rewind->next;
|
||||
while (rewind != q->head_idx) {
|
||||
rewind_desc_info = &q->info[rewind];
|
||||
ionic_tx_clean(q, rewind_desc_info, NULL, NULL);
|
||||
rewind = (rewind + 1) & (q->num_descs - 1);
|
||||
}
|
||||
q->head = abort;
|
||||
q->head_idx = abort;
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int ionic_tx_calc_csum(struct ionic_queue *q, struct sk_buff *skb)
|
||||
{
|
||||
struct ionic_txq_desc *desc = q->info[q->head_idx].txq_desc;
|
||||
struct ionic_tx_stats *stats = q_to_tx_stats(q);
|
||||
struct ionic_txq_desc *desc = q->head->desc;
|
||||
struct device *dev = q->lif->ionic->dev;
|
||||
dma_addr_t dma_addr;
|
||||
bool has_vlan;
|
||||
|
@ -967,8 +973,8 @@ static int ionic_tx_calc_csum(struct ionic_queue *q, struct sk_buff *skb)
|
|||
|
||||
static int ionic_tx_calc_no_csum(struct ionic_queue *q, struct sk_buff *skb)
|
||||
{
|
||||
struct ionic_txq_desc *desc = q->info[q->head_idx].txq_desc;
|
||||
struct ionic_tx_stats *stats = q_to_tx_stats(q);
|
||||
struct ionic_txq_desc *desc = q->head->desc;
|
||||
struct device *dev = q->lif->ionic->dev;
|
||||
dma_addr_t dma_addr;
|
||||
bool has_vlan;
|
||||
|
@ -1002,7 +1008,7 @@ static int ionic_tx_calc_no_csum(struct ionic_queue *q, struct sk_buff *skb)
|
|||
|
||||
static int ionic_tx_skb_frags(struct ionic_queue *q, struct sk_buff *skb)
|
||||
{
|
||||
struct ionic_txq_sg_desc *sg_desc = q->head->sg_desc;
|
||||
struct ionic_txq_sg_desc *sg_desc = q->info[q->head_idx].txq_sg_desc;
|
||||
unsigned int len_left = skb->len - skb_headlen(skb);
|
||||
struct ionic_txq_sg_elem *elem = sg_desc->elems;
|
||||
struct ionic_tx_stats *stats = q_to_tx_stats(q);
|
||||
|
|
Loading…
Reference in a new issue