Commit 4dcd4575 authored by Shannon Nelson's avatar Shannon Nelson Committed by David S. Miller

ionic: use specialized desc info structs

Make desc_info structure specific to the queue type, which
allows us to cut down the Rx and AdminQ descriptor sizes by
not including all the fields needed for the Tx desriptors.

Before:
    struct ionic_desc_info {
	/* size: 464, cachelines: 8, members: 6 */

After:
    struct ionic_tx_desc_info {
	/* size: 464, cachelines: 8, members: 6 */
    struct ionic_rx_desc_info {
	/* size: 224, cachelines: 4, members: 2 */
    struct ionic_admin_desc_info {
	/* size: 8, cachelines: 1, members: 1 */
Suggested-by: default avatarNeel Patel <npatel2@amd.com>
Reviewed-by: default avatarBrett Creeley <brett.creeley@amd.com>
Signed-off-by: default avatarShannon Nelson <shannon.nelson@amd.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 65e548f6
......@@ -687,15 +687,11 @@ int ionic_q_init(struct ionic_lif *lif, struct ionic_dev *idev,
return 0;
}
void ionic_q_post(struct ionic_queue *q, bool ring_doorbell, void *arg)
void ionic_q_post(struct ionic_queue *q, bool ring_doorbell)
{
struct ionic_desc_info *desc_info;
struct ionic_lif *lif = q->lif;
struct device *dev = q->dev;
desc_info = &q->info[q->head_idx];
desc_info->arg = 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",
......
......@@ -179,7 +179,6 @@ struct ionic_dev {
struct ionic_queue;
struct ionic_qcq;
struct ionic_desc_info;
#define IONIC_MAX_BUF_LEN ((u16)-1)
#define IONIC_PAGE_SIZE PAGE_SIZE
......@@ -199,23 +198,38 @@ struct ionic_buf_info {
u32 len;
};
#define IONIC_MAX_FRAGS (1 + IONIC_TX_MAX_SG_ELEMS_V1)
#define IONIC_TX_MAX_FRAGS (1 + IONIC_TX_MAX_SG_ELEMS_V1)
#define IONIC_RX_MAX_FRAGS (1 + IONIC_RX_MAX_SG_ELEMS)
struct ionic_desc_info {
struct ionic_tx_desc_info {
unsigned int bytes;
unsigned int nbufs;
void *arg;
struct sk_buff *skb;
struct xdp_frame *xdpf;
enum xdp_action act;
struct ionic_buf_info bufs[MAX_SKB_FRAGS + 1];
};
struct ionic_rx_desc_info {
unsigned int nbufs;
struct ionic_buf_info bufs[IONIC_RX_MAX_FRAGS];
};
struct ionic_admin_desc_info {
void *ctx;
};
#define IONIC_QUEUE_NAME_MAX_SZ 16
struct ionic_queue {
struct device *dev;
struct ionic_lif *lif;
struct ionic_desc_info *info;
union {
void *info;
struct ionic_tx_desc_info *tx_info;
struct ionic_rx_desc_info *rx_info;
struct ionic_admin_desc_info *admin_info;
};
u64 dbval;
unsigned long dbell_deadline;
unsigned long dbell_jiffies;
......@@ -367,7 +381,7 @@ int ionic_q_init(struct ionic_lif *lif, struct ionic_dev *idev,
struct ionic_queue *q, unsigned int index, const char *name,
unsigned int num_descs, size_t desc_size,
size_t sg_desc_size, unsigned int pid);
void ionic_q_post(struct ionic_queue *q, bool ring_doorbell, void *arg);
void ionic_q_post(struct ionic_queue *q, bool ring_doorbell);
bool ionic_q_is_posted(struct ionic_queue *q, unsigned int pos);
int ionic_heartbeat_check(struct ionic *ionic);
......
......@@ -536,6 +536,7 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type,
unsigned int num_descs, unsigned int desc_size,
unsigned int cq_desc_size,
unsigned int sg_desc_size,
unsigned int desc_info_size,
unsigned int pid, struct ionic_qcq **qcq)
{
struct ionic_dev *idev = &lif->ionic->idev;
......@@ -555,7 +556,7 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type,
new->q.dev = dev;
new->flags = flags;
new->q.info = vcalloc(num_descs, sizeof(*new->q.info));
new->q.info = vcalloc(num_descs, desc_info_size);
if (!new->q.info) {
netdev_err(lif->netdev, "Cannot allocate queue info\n");
err = -ENOMEM;
......@@ -713,7 +714,9 @@ static int ionic_qcqs_alloc(struct ionic_lif *lif)
IONIC_ADMINQ_LENGTH,
sizeof(struct ionic_admin_cmd),
sizeof(struct ionic_admin_comp),
0, lif->kern_pid, &lif->adminqcq);
0,
sizeof(struct ionic_admin_desc_info),
lif->kern_pid, &lif->adminqcq);
if (err)
return err;
ionic_debugfs_add_qcq(lif, lif->adminqcq);
......@@ -724,7 +727,9 @@ static int ionic_qcqs_alloc(struct ionic_lif *lif)
flags, IONIC_NOTIFYQ_LENGTH,
sizeof(struct ionic_notifyq_cmd),
sizeof(union ionic_notifyq_comp),
0, lif->kern_pid, &lif->notifyqcq);
0,
sizeof(struct ionic_admin_desc_info),
lif->kern_pid, &lif->notifyqcq);
if (err)
goto err_out;
ionic_debugfs_add_qcq(lif, lif->notifyqcq);
......@@ -942,6 +947,7 @@ int ionic_lif_create_hwstamp_txq(struct ionic_lif *lif)
err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, txq_i, "hwstamp_tx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
sizeof(struct ionic_tx_desc_info),
lif->kern_pid, &txq);
if (err)
goto err_qcq_alloc;
......@@ -1001,6 +1007,7 @@ int ionic_lif_create_hwstamp_rxq(struct ionic_lif *lif)
err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, rxq_i, "hwstamp_rx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
sizeof(struct ionic_rx_desc_info),
lif->kern_pid, &rxq);
if (err)
goto err_qcq_alloc;
......@@ -2027,6 +2034,7 @@ static int ionic_txrx_alloc(struct ionic_lif *lif)
for (i = 0; i < lif->nxqs; i++) {
err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, i, "tx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
sizeof(struct ionic_tx_desc_info),
lif->kern_pid, &lif->txqcqs[i]);
if (err)
goto err_out;
......@@ -2058,6 +2066,7 @@ static int ionic_txrx_alloc(struct ionic_lif *lif)
for (i = 0; i < lif->nxqs; i++) {
err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, i, "rx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
sizeof(struct ionic_rx_desc_info),
lif->kern_pid, &lif->rxqcqs[i]);
if (err)
goto err_out;
......@@ -2938,6 +2947,7 @@ int ionic_reconfigure_queues(struct ionic_lif *lif,
flags = IONIC_QCQ_F_TX_STATS | IONIC_QCQ_F_SG;
err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, i, "tx", flags,
4, desc_sz, comp_sz, sg_desc_sz,
sizeof(struct ionic_tx_desc_info),
lif->kern_pid, &lif->txqcqs[i]);
if (err)
goto err_out;
......@@ -2946,6 +2956,7 @@ int ionic_reconfigure_queues(struct ionic_lif *lif,
flags = lif->txqcqs[i]->flags & ~IONIC_QCQ_F_INTR;
err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, i, "tx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
sizeof(struct ionic_tx_desc_info),
lif->kern_pid, &tx_qcqs[i]);
if (err)
goto err_out;
......@@ -2967,6 +2978,7 @@ int ionic_reconfigure_queues(struct ionic_lif *lif,
flags = IONIC_QCQ_F_RX_STATS | IONIC_QCQ_F_SG;
err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, i, "rx", flags,
4, desc_sz, comp_sz, sg_desc_sz,
sizeof(struct ionic_rx_desc_info),
lif->kern_pid, &lif->rxqcqs[i]);
if (err)
goto err_out;
......@@ -2975,6 +2987,7 @@ int ionic_reconfigure_queues(struct ionic_lif *lif,
flags = lif->rxqcqs[i]->flags & ~IONIC_QCQ_F_INTR;
err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, i, "rx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
sizeof(struct ionic_rx_desc_info),
lif->kern_pid, &rx_qcqs[i]);
if (err)
goto err_out;
......@@ -3549,7 +3562,7 @@ static int ionic_lif_notifyq_init(struct ionic_lif *lif)
dev_dbg(dev, "notifyq->hw_index %d\n", q->hw_index);
/* preset the callback info */
q->info[0].arg = lif;
q->admin_info[0].ctx = lif;
qcq->flags |= IONIC_QCQ_F_INITED;
......@@ -3801,6 +3814,7 @@ static void ionic_lif_queue_identify(struct ionic_lif *lif)
union ionic_q_identity __iomem *q_ident;
struct ionic *ionic = lif->ionic;
struct ionic_dev *idev;
u16 max_frags;
int qtype;
int err;
......@@ -3868,17 +3882,16 @@ static void ionic_lif_queue_identify(struct ionic_lif *lif)
dev_dbg(ionic->dev, " qtype[%d].sg_desc_stride = %d\n",
qtype, qti->sg_desc_stride);
if (qti->max_sg_elems >= IONIC_MAX_FRAGS) {
qti->max_sg_elems = IONIC_MAX_FRAGS - 1;
dev_dbg(ionic->dev, "limiting qtype %d max_sg_elems to IONIC_MAX_FRAGS-1 %d\n",
qtype, qti->max_sg_elems);
}
if (qtype == IONIC_QTYPE_TXQ)
max_frags = IONIC_TX_MAX_FRAGS;
else if (qtype == IONIC_QTYPE_RXQ)
max_frags = IONIC_RX_MAX_FRAGS;
else
max_frags = 1;
if (qti->max_sg_elems > MAX_SKB_FRAGS) {
qti->max_sg_elems = MAX_SKB_FRAGS;
dev_dbg(ionic->dev, "limiting qtype %d max_sg_elems to MAX_SKB_FRAGS %d\n",
qtype, qti->max_sg_elems);
}
qti->max_sg_elems = min_t(u16, max_frags - 1, MAX_SKB_FRAGS);
dev_dbg(ionic->dev, "qtype %d max_sg_elems %d\n",
qtype, qti->max_sg_elems);
}
}
......
......@@ -190,7 +190,7 @@ static const char *ionic_opcode_to_str(enum ionic_cmd_opcode opcode)
static void ionic_adminq_flush(struct ionic_lif *lif)
{
struct ionic_desc_info *desc_info;
struct ionic_admin_desc_info *desc_info;
struct ionic_admin_cmd *desc;
unsigned long irqflags;
struct ionic_queue *q;
......@@ -205,9 +205,9 @@ static void ionic_adminq_flush(struct ionic_lif *lif)
while (q->tail_idx != q->head_idx) {
desc = &q->adminq[q->tail_idx];
desc_info = &q->info[q->tail_idx];
desc_info = &q->admin_info[q->tail_idx];
memset(desc, 0, sizeof(union ionic_adminq_cmd));
desc_info->arg = NULL;
desc_info->ctx = NULL;
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
}
spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
......@@ -248,10 +248,10 @@ static int ionic_adminq_check_err(struct ionic_lif *lif,
}
static void ionic_adminq_clean(struct ionic_queue *q,
struct ionic_desc_info *desc_info,
struct ionic_admin_desc_info *desc_info,
struct ionic_admin_comp *comp)
{
struct ionic_admin_ctx *ctx = desc_info->arg;
struct ionic_admin_ctx *ctx = desc_info->ctx;
if (!ctx)
return;
......@@ -277,7 +277,7 @@ bool ionic_notifyq_service(struct ionic_cq *cq)
comp = &((union ionic_notifyq_comp *)cq->base)[cq->tail_idx];
q = cq->bound_q;
lif = q->info[0].arg;
lif = q->admin_info[0].ctx;
netdev = lif->netdev;
eid = le64_to_cpu(comp->event.eid);
......@@ -320,8 +320,8 @@ bool ionic_notifyq_service(struct ionic_cq *cq)
bool ionic_adminq_service(struct ionic_cq *cq)
{
struct ionic_admin_desc_info *desc_info;
struct ionic_queue *q = cq->bound_q;
struct ionic_desc_info *desc_info;
struct ionic_admin_comp *comp;
u16 index;
......@@ -335,12 +335,12 @@ bool ionic_adminq_service(struct ionic_cq *cq)
return false;
do {
desc_info = &q->info[q->tail_idx];
desc_info = &q->admin_info[q->tail_idx];
index = q->tail_idx;
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
if (likely(desc_info->arg))
if (likely(desc_info->ctx))
ionic_adminq_clean(q, desc_info, comp);
desc_info->arg = NULL;
desc_info->ctx = NULL;
} while (index != le16_to_cpu(comp->comp_index));
return true;
......@@ -377,6 +377,7 @@ bool ionic_adminq_poke_doorbell(struct ionic_queue *q)
int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
{
struct ionic_admin_desc_info *desc_info;
struct ionic_admin_cmd *desc;
unsigned long irqflags;
struct ionic_queue *q;
......@@ -399,6 +400,9 @@ int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
if (err)
goto err_out;
desc_info = &q->admin_info[q->head_idx];
desc_info->ctx = ctx;
desc = &q->adminq[q->head_idx];
memcpy(desc, &ctx->cmd, sizeof(ctx->cmd));
......@@ -406,7 +410,7 @@ int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
dynamic_hex_dump("cmd ", DUMP_PREFIX_OFFSET, 16, 1,
&ctx->cmd, sizeof(ctx->cmd), true);
ionic_q_post(q, true, ctx);
ionic_q_post(q, true);
err_out:
spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment