ionic: remove desc, sg_desc and cmb_desc from desc_info

Remove the struct pointers from desc_info to use less space.
Instead of pointers in every desc_info to its descriptor,
we can use the queue descriptor index to find the individual
desc, desc_info, and sgl structs in their parallel arrays.

   struct ionic_desc_info
	Before:  /* size: 496, cachelines: 8, members: 10 */
	After:   /* size: 472, cachelines: 8, members: 7 */

Suggested-by: Neel Patel <npatel2@amd.com>
Reviewed-by: Brett Creeley <brett.creeley@amd.com>
Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Shannon Nelson 2024-03-06 15:29:46 -08:00 committed by David S. Miller
parent e3eec34977
commit d60984d39f
4 changed files with 45 additions and 60 deletions

View File

@ -708,38 +708,20 @@ int ionic_q_init(struct ionic_lif *lif, struct ionic_dev *idev,
void ionic_q_map(struct ionic_queue *q, void *base, dma_addr_t base_pa) void ionic_q_map(struct ionic_queue *q, void *base, dma_addr_t base_pa)
{ {
struct ionic_desc_info *cur;
unsigned int i;
q->base = base; q->base = base;
q->base_pa = base_pa; q->base_pa = base_pa;
for (i = 0, cur = q->info; i < q->num_descs; i++, cur++)
cur->desc = base + (i * q->desc_size);
} }
void ionic_q_cmb_map(struct ionic_queue *q, void __iomem *base, dma_addr_t base_pa) void ionic_q_cmb_map(struct ionic_queue *q, void __iomem *base, dma_addr_t base_pa)
{ {
struct ionic_desc_info *cur;
unsigned int i;
q->cmb_base = base; q->cmb_base = base;
q->cmb_base_pa = base_pa; q->cmb_base_pa = base_pa;
for (i = 0, cur = q->info; i < q->num_descs; i++, cur++)
cur->cmb_desc = base + (i * q->desc_size);
} }
void ionic_q_sg_map(struct ionic_queue *q, void *base, dma_addr_t base_pa) void ionic_q_sg_map(struct ionic_queue *q, void *base, dma_addr_t base_pa)
{ {
struct ionic_desc_info *cur;
unsigned int i;
q->sg_base = base; q->sg_base = base;
q->sg_base_pa = base_pa; q->sg_base_pa = base_pa;
for (i = 0, cur = q->info; i < q->num_descs; i++, cur++)
cur->sg_desc = base + (i * q->sg_desc_size);
} }
void ionic_q_post(struct ionic_queue *q, bool ring_doorbell, ionic_desc_cb cb, void ionic_q_post(struct ionic_queue *q, bool ring_doorbell, ionic_desc_cb cb,

View File

@ -122,11 +122,13 @@ static_assert(sizeof(struct ionic_log_event) == 64);
/* I/O */ /* I/O */
static_assert(sizeof(struct ionic_txq_desc) == 16); static_assert(sizeof(struct ionic_txq_desc) == 16);
static_assert(sizeof(struct ionic_txq_sg_desc) == 128); static_assert(sizeof(struct ionic_txq_sg_desc) == 128);
static_assert(sizeof(struct ionic_txq_sg_desc_v1) == 256);
static_assert(sizeof(struct ionic_txq_comp) == 16); static_assert(sizeof(struct ionic_txq_comp) == 16);
static_assert(sizeof(struct ionic_rxq_desc) == 16); static_assert(sizeof(struct ionic_rxq_desc) == 16);
static_assert(sizeof(struct ionic_rxq_sg_desc) == 128); static_assert(sizeof(struct ionic_rxq_sg_desc) == 128);
static_assert(sizeof(struct ionic_rxq_comp) == 16); static_assert(sizeof(struct ionic_rxq_comp) == 16);
static_assert(sizeof(struct ionic_rxq_comp) == sizeof(struct ionic_txq_comp));
/* SR/IOV */ /* SR/IOV */
static_assert(sizeof(struct ionic_vf_setattr_cmd) == 64); static_assert(sizeof(struct ionic_vf_setattr_cmd) == 64);
@ -212,25 +214,13 @@ struct ionic_buf_info {
#define IONIC_MAX_FRAGS (1 + IONIC_TX_MAX_SG_ELEMS_V1) #define IONIC_MAX_FRAGS (1 + IONIC_TX_MAX_SG_ELEMS_V1)
struct ionic_desc_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;
};
void __iomem *cmb_desc;
union {
void *sg_desc;
struct ionic_txq_sg_desc *txq_sg_desc;
struct ionic_rxq_sg_desc *rxq_sgl_desc;
};
unsigned int bytes; unsigned int bytes;
unsigned int nbufs; unsigned int nbufs;
struct ionic_buf_info bufs[MAX_SKB_FRAGS + 1];
ionic_desc_cb cb; ionic_desc_cb cb;
void *cb_arg; void *cb_arg;
struct xdp_frame *xdpf; struct xdp_frame *xdpf;
enum xdp_action act; enum xdp_action act;
struct ionic_buf_info bufs[MAX_SKB_FRAGS + 1];
}; };
#define IONIC_QUEUE_NAME_MAX_SZ 16 #define IONIC_QUEUE_NAME_MAX_SZ 16
@ -259,10 +249,15 @@ struct ionic_queue {
struct ionic_rxq_desc *rxq; struct ionic_rxq_desc *rxq;
struct ionic_admin_cmd *adminq; struct ionic_admin_cmd *adminq;
}; };
void __iomem *cmb_base; union {
void __iomem *cmb_base;
struct ionic_txq_desc __iomem *cmb_txq;
struct ionic_rxq_desc __iomem *cmb_rxq;
};
union { union {
void *sg_base; void *sg_base;
struct ionic_txq_sg_desc *txq_sgl; struct ionic_txq_sg_desc *txq_sgl;
struct ionic_txq_sg_desc_v1 *txq_sgl_v1;
struct ionic_rxq_sg_desc *rxq_sgl; struct ionic_rxq_sg_desc *rxq_sgl;
}; };
struct xdp_rxq_info *xdp_rxq_info; struct xdp_rxq_info *xdp_rxq_info;

View File

@ -191,6 +191,7 @@ static const char *ionic_opcode_to_str(enum ionic_cmd_opcode opcode)
static void ionic_adminq_flush(struct ionic_lif *lif) static void ionic_adminq_flush(struct ionic_lif *lif)
{ {
struct ionic_desc_info *desc_info; struct ionic_desc_info *desc_info;
struct ionic_admin_cmd *desc;
unsigned long irqflags; unsigned long irqflags;
struct ionic_queue *q; struct ionic_queue *q;
@ -203,8 +204,9 @@ static void ionic_adminq_flush(struct ionic_lif *lif)
q = &lif->adminqcq->q; q = &lif->adminqcq->q;
while (q->tail_idx != q->head_idx) { while (q->tail_idx != q->head_idx) {
desc = &q->adminq[q->tail_idx];
desc_info = &q->info[q->tail_idx]; desc_info = &q->info[q->tail_idx];
memset(desc_info->desc, 0, sizeof(union ionic_adminq_cmd)); memset(desc, 0, sizeof(union ionic_adminq_cmd));
desc_info->cb = NULL; desc_info->cb = NULL;
desc_info->cb_arg = NULL; desc_info->cb_arg = NULL;
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1); q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
@ -298,7 +300,7 @@ bool ionic_adminq_poke_doorbell(struct ionic_queue *q)
int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx) int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
{ {
struct ionic_desc_info *desc_info; struct ionic_admin_cmd *desc;
unsigned long irqflags; unsigned long irqflags;
struct ionic_queue *q; struct ionic_queue *q;
int err = 0; int err = 0;
@ -320,8 +322,8 @@ int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
if (err) if (err)
goto err_out; goto err_out;
desc_info = &q->info[q->head_idx]; desc = &q->adminq[q->head_idx];
memcpy(desc_info->desc, &ctx->cmd, sizeof(ctx->cmd)); memcpy(desc, &ctx->cmd, sizeof(ctx->cmd));
dev_dbg(&lif->netdev->dev, "post admin queue command:\n"); dev_dbg(&lif->netdev->dev, "post admin queue command:\n");
dynamic_hex_dump("cmd ", DUMP_PREFIX_OFFSET, 16, 1, dynamic_hex_dump("cmd ", DUMP_PREFIX_OFFSET, 16, 1,

View File

@ -99,6 +99,14 @@ bool ionic_rxq_poke_doorbell(struct ionic_queue *q)
return true; return true;
} }
static inline struct ionic_txq_sg_elem *ionic_tx_sg_elems(struct ionic_queue *q)
{
if (likely(q->sg_desc_size == sizeof(struct ionic_txq_sg_desc_v1)))
return q->txq_sgl_v1[q->head_idx].elems;
else
return q->txq_sgl[q->head_idx].elems;
}
static inline struct netdev_queue *q_to_ndq(struct net_device *netdev, static inline struct netdev_queue *q_to_ndq(struct net_device *netdev,
struct ionic_queue *q) struct ionic_queue *q)
{ {
@ -360,7 +368,7 @@ static int ionic_xdp_post_frame(struct ionic_queue *q, struct xdp_frame *frame,
u64 cmd; u64 cmd;
desc_info = &q->info[q->head_idx]; desc_info = &q->info[q->head_idx];
desc = desc_info->txq_desc; desc = &q->txq[q->head_idx];
buf_info = desc_info->bufs; buf_info = desc_info->bufs;
stats = q_to_tx_stats(q); stats = q_to_tx_stats(q);
@ -388,7 +396,7 @@ static int ionic_xdp_post_frame(struct ionic_queue *q, struct xdp_frame *frame,
bi = &buf_info[1]; bi = &buf_info[1];
sinfo = xdp_get_shared_info_from_frame(frame); sinfo = xdp_get_shared_info_from_frame(frame);
frag = sinfo->frags; frag = sinfo->frags;
elem = desc_info->txq_sg_desc->elems; elem = ionic_tx_sg_elems(q);
for (i = 0; i < sinfo->nr_frags; i++, frag++, bi++) { for (i = 0; i < sinfo->nr_frags; i++, frag++, bi++) {
dma_addr = ionic_tx_map_frag(q, frag, 0, skb_frag_size(frag)); dma_addr = ionic_tx_map_frag(q, frag, 0, skb_frag_size(frag));
if (dma_mapping_error(q->dev, dma_addr)) { if (dma_mapping_error(q->dev, dma_addr)) {
@ -768,18 +776,19 @@ bool ionic_rx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info)
} }
static inline void ionic_write_cmb_desc(struct ionic_queue *q, static inline void ionic_write_cmb_desc(struct ionic_queue *q,
void __iomem *cmb_desc,
void *desc) void *desc)
{ {
if (q_to_qcq(q)->flags & IONIC_QCQ_F_CMB_RINGS) /* Since Rx and Tx descriptors are the same size, we can
memcpy_toio(cmb_desc, desc, q->desc_size); * save an instruction or two and skip the qtype check.
*/
if (unlikely(q_to_qcq(q)->flags & IONIC_QCQ_F_CMB_RINGS))
memcpy_toio(&q->cmb_txq[q->head_idx], desc, sizeof(q->cmb_txq[0]));
} }
void ionic_rx_fill(struct ionic_queue *q) void ionic_rx_fill(struct ionic_queue *q)
{ {
struct net_device *netdev = q->lif->netdev; struct net_device *netdev = q->lif->netdev;
struct ionic_desc_info *desc_info; struct ionic_desc_info *desc_info;
struct ionic_rxq_sg_desc *sg_desc;
struct ionic_rxq_sg_elem *sg_elem; struct ionic_rxq_sg_elem *sg_elem;
struct ionic_buf_info *buf_info; struct ionic_buf_info *buf_info;
unsigned int fill_threshold; unsigned int fill_threshold;
@ -807,8 +816,8 @@ void ionic_rx_fill(struct ionic_queue *q)
nfrags = 0; nfrags = 0;
remain_len = len; remain_len = len;
desc = &q->rxq[q->head_idx];
desc_info = &q->info[q->head_idx]; desc_info = &q->info[q->head_idx];
desc = desc_info->desc;
buf_info = &desc_info->bufs[0]; buf_info = &desc_info->bufs[0];
if (!buf_info->page) { /* alloc a new buffer? */ if (!buf_info->page) { /* alloc a new buffer? */
@ -837,9 +846,8 @@ void ionic_rx_fill(struct ionic_queue *q)
nfrags++; nfrags++;
/* fill sg descriptors - buf[1..n] */ /* fill sg descriptors - buf[1..n] */
sg_desc = desc_info->sg_desc; sg_elem = q->rxq_sgl[q->head_idx].elems;
for (j = 0; remain_len > 0 && j < q->max_sg_elems; j++) { for (j = 0; remain_len > 0 && j < q->max_sg_elems; j++, sg_elem++) {
sg_elem = &sg_desc->elems[j];
if (!buf_info->page) { /* alloc a new sg buffer? */ if (!buf_info->page) { /* alloc a new sg buffer? */
if (unlikely(ionic_rx_page_alloc(q, buf_info))) { if (unlikely(ionic_rx_page_alloc(q, buf_info))) {
sg_elem->addr = 0; sg_elem->addr = 0;
@ -857,16 +865,14 @@ void ionic_rx_fill(struct ionic_queue *q)
} }
/* clear end sg element as a sentinel */ /* clear end sg element as a sentinel */
if (j < q->max_sg_elems) { if (j < q->max_sg_elems)
sg_elem = &sg_desc->elems[j];
memset(sg_elem, 0, sizeof(*sg_elem)); memset(sg_elem, 0, sizeof(*sg_elem));
}
desc->opcode = (nfrags > 1) ? IONIC_RXQ_DESC_OPCODE_SG : desc->opcode = (nfrags > 1) ? IONIC_RXQ_DESC_OPCODE_SG :
IONIC_RXQ_DESC_OPCODE_SIMPLE; IONIC_RXQ_DESC_OPCODE_SIMPLE;
desc_info->nbufs = nfrags; desc_info->nbufs = nfrags;
ionic_write_cmb_desc(q, desc_info->cmb_desc, desc); ionic_write_cmb_desc(q, desc);
ionic_rxq_post(q, false, ionic_rx_clean, NULL); ionic_rxq_post(q, false, ionic_rx_clean, NULL);
} }
@ -1399,7 +1405,7 @@ static void ionic_tx_tso_post(struct net_device *netdev, struct ionic_queue *q,
u16 vlan_tci, bool has_vlan, u16 vlan_tci, bool has_vlan,
bool start, bool done) bool start, bool done)
{ {
struct ionic_txq_desc *desc = desc_info->desc; struct ionic_txq_desc *desc = &q->txq[q->head_idx];
u8 flags = 0; u8 flags = 0;
u64 cmd; u64 cmd;
@ -1415,7 +1421,7 @@ static void ionic_tx_tso_post(struct net_device *netdev, struct ionic_queue *q,
desc->hdr_len = cpu_to_le16(hdrlen); desc->hdr_len = cpu_to_le16(hdrlen);
desc->mss = cpu_to_le16(mss); desc->mss = cpu_to_le16(mss);
ionic_write_cmb_desc(q, desc_info->cmb_desc, desc); ionic_write_cmb_desc(q, desc);
if (start) { if (start) {
skb_tx_timestamp(skb); skb_tx_timestamp(skb);
@ -1517,8 +1523,8 @@ static int ionic_tx_tso(struct net_device *netdev, struct ionic_queue *q,
chunk_len = min(frag_rem, seg_rem); chunk_len = min(frag_rem, seg_rem);
if (!desc) { if (!desc) {
/* fill main descriptor */ /* fill main descriptor */
desc = desc_info->txq_desc; desc = &q->txq[q->head_idx];
elem = desc_info->txq_sg_desc->elems; elem = ionic_tx_sg_elems(q);
desc_addr = frag_addr; desc_addr = frag_addr;
desc_len = chunk_len; desc_len = chunk_len;
} else { } else {
@ -1557,7 +1563,7 @@ static int ionic_tx_tso(struct net_device *netdev, struct ionic_queue *q,
static void ionic_tx_calc_csum(struct ionic_queue *q, struct sk_buff *skb, static void ionic_tx_calc_csum(struct ionic_queue *q, struct sk_buff *skb,
struct ionic_desc_info *desc_info) struct ionic_desc_info *desc_info)
{ {
struct ionic_txq_desc *desc = desc_info->txq_desc; struct ionic_txq_desc *desc = &q->txq[q->head_idx];
struct ionic_buf_info *buf_info = desc_info->bufs; struct ionic_buf_info *buf_info = desc_info->bufs;
struct ionic_tx_stats *stats = q_to_tx_stats(q); struct ionic_tx_stats *stats = q_to_tx_stats(q);
bool has_vlan; bool has_vlan;
@ -1585,7 +1591,7 @@ static void ionic_tx_calc_csum(struct ionic_queue *q, struct sk_buff *skb,
desc->csum_start = cpu_to_le16(skb_checksum_start_offset(skb)); desc->csum_start = cpu_to_le16(skb_checksum_start_offset(skb));
desc->csum_offset = cpu_to_le16(skb->csum_offset); desc->csum_offset = cpu_to_le16(skb->csum_offset);
ionic_write_cmb_desc(q, desc_info->cmb_desc, desc); ionic_write_cmb_desc(q, desc);
if (skb_csum_is_sctp(skb)) if (skb_csum_is_sctp(skb))
stats->crc32_csum++; stats->crc32_csum++;
@ -1596,7 +1602,7 @@ static void ionic_tx_calc_csum(struct ionic_queue *q, struct sk_buff *skb,
static void ionic_tx_calc_no_csum(struct ionic_queue *q, struct sk_buff *skb, static void ionic_tx_calc_no_csum(struct ionic_queue *q, struct sk_buff *skb,
struct ionic_desc_info *desc_info) struct ionic_desc_info *desc_info)
{ {
struct ionic_txq_desc *desc = desc_info->txq_desc; struct ionic_txq_desc *desc = &q->txq[q->head_idx];
struct ionic_buf_info *buf_info = desc_info->bufs; struct ionic_buf_info *buf_info = desc_info->bufs;
struct ionic_tx_stats *stats = q_to_tx_stats(q); struct ionic_tx_stats *stats = q_to_tx_stats(q);
bool has_vlan; bool has_vlan;
@ -1624,7 +1630,7 @@ static void ionic_tx_calc_no_csum(struct ionic_queue *q, struct sk_buff *skb,
desc->csum_start = 0; desc->csum_start = 0;
desc->csum_offset = 0; desc->csum_offset = 0;
ionic_write_cmb_desc(q, desc_info->cmb_desc, desc); ionic_write_cmb_desc(q, desc);
stats->csum_none++; stats->csum_none++;
} }
@ -1632,12 +1638,12 @@ static void ionic_tx_calc_no_csum(struct ionic_queue *q, struct sk_buff *skb,
static void ionic_tx_skb_frags(struct ionic_queue *q, struct sk_buff *skb, static void ionic_tx_skb_frags(struct ionic_queue *q, struct sk_buff *skb,
struct ionic_desc_info *desc_info) struct ionic_desc_info *desc_info)
{ {
struct ionic_txq_sg_desc *sg_desc = desc_info->txq_sg_desc;
struct ionic_buf_info *buf_info = &desc_info->bufs[1]; struct ionic_buf_info *buf_info = &desc_info->bufs[1];
struct ionic_txq_sg_elem *elem = sg_desc->elems;
struct ionic_tx_stats *stats = q_to_tx_stats(q); struct ionic_tx_stats *stats = q_to_tx_stats(q);
struct ionic_txq_sg_elem *elem;
unsigned int i; unsigned int i;
elem = ionic_tx_sg_elems(q);
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++, buf_info++, elem++) { for (i = 0; i < skb_shinfo(skb)->nr_frags; i++, buf_info++, elem++) {
elem->addr = cpu_to_le64(buf_info->dma_addr); elem->addr = cpu_to_le64(buf_info->dma_addr);
elem->len = cpu_to_le16(buf_info->len); elem->len = cpu_to_le16(buf_info->len);