diff options
author | Shannon Nelson <shannon.nelson@amd.com> | 2024-03-06 15:29:46 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2024-03-08 11:54:33 +0000 |
commit | d60984d39f18780dd978963b1bc4c56ee3f44ef0 (patch) | |
tree | 8bf47d1220c3bf6a3e8717d0630dcd57e49abda6 | |
parent | e3eec3497731e227f02d6f83899ef23b34996b2b (diff) |
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>
-rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_dev.c | 18 | ||||
-rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_dev.h | 23 | ||||
-rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_main.c | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_txrx.c | 54 |
4 files changed, 45 insertions, 60 deletions
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.c b/drivers/net/ethernet/pensando/ionic/ionic_dev.c index 746072b4dbd0..fc83f80fba00 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_dev.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.c @@ -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) { - struct ionic_desc_info *cur; - unsigned int i; - q->base = base; 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) { - struct ionic_desc_info *cur; - unsigned int i; - q->cmb_base = base; 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) { - struct ionic_desc_info *cur; - unsigned int i; - q->sg_base = base; 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, diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h b/drivers/net/ethernet/pensando/ionic/ionic_dev.h index 516db910e8e8..d38c909478ea 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h +++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h @@ -122,11 +122,13 @@ static_assert(sizeof(struct ionic_log_event) == 64); /* I/O */ 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_v1) == 256); static_assert(sizeof(struct ionic_txq_comp) == 16); static_assert(sizeof(struct ionic_rxq_desc) == 16); static_assert(sizeof(struct ionic_rxq_sg_desc) == 128); static_assert(sizeof(struct ionic_rxq_comp) == 16); +static_assert(sizeof(struct ionic_rxq_comp) == sizeof(struct ionic_txq_comp)); /* SR/IOV */ 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) 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 nbufs; - struct ionic_buf_info bufs[MAX_SKB_FRAGS + 1]; ionic_desc_cb cb; void *cb_arg; struct xdp_frame *xdpf; enum xdp_action act; + struct ionic_buf_info bufs[MAX_SKB_FRAGS + 1]; }; #define IONIC_QUEUE_NAME_MAX_SZ 16 @@ -259,10 +249,15 @@ struct ionic_queue { struct ionic_rxq_desc *rxq; 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 { void *sg_base; struct ionic_txq_sg_desc *txq_sgl; + struct ionic_txq_sg_desc_v1 *txq_sgl_v1; struct ionic_rxq_sg_desc *rxq_sgl; }; struct xdp_rxq_info *xdp_rxq_info; diff --git a/drivers/net/ethernet/pensando/ionic/ionic_main.c b/drivers/net/ethernet/pensando/ionic/ionic_main.c index 29b4d039bbce..750a1ffaf855 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_main.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_main.c @@ -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) { struct ionic_desc_info *desc_info; + struct ionic_admin_cmd *desc; unsigned long irqflags; struct ionic_queue *q; @@ -203,8 +204,9 @@ static void ionic_adminq_flush(struct ionic_lif *lif) q = &lif->adminqcq->q; while (q->tail_idx != q->head_idx) { + desc = &q->adminq[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_arg = NULL; 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) { - struct ionic_desc_info *desc_info; + struct ionic_admin_cmd *desc; unsigned long irqflags; struct ionic_queue *q; int err = 0; @@ -320,8 +322,8 @@ int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx) if (err) goto err_out; - desc_info = &q->info[q->head_idx]; - memcpy(desc_info->desc, &ctx->cmd, sizeof(ctx->cmd)); + desc = &q->adminq[q->head_idx]; + memcpy(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, diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c index 6d168ad8c84f..bc8e099ca1ac 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c @@ -99,6 +99,14 @@ bool ionic_rxq_poke_doorbell(struct ionic_queue *q) 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, struct ionic_queue *q) { @@ -360,7 +368,7 @@ static int ionic_xdp_post_frame(struct ionic_queue *q, struct xdp_frame *frame, u64 cmd; desc_info = &q->info[q->head_idx]; - desc = desc_info->txq_desc; + desc = &q->txq[q->head_idx]; buf_info = desc_info->bufs; 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]; sinfo = xdp_get_shared_info_from_frame(frame); 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++) { dma_addr = ionic_tx_map_frag(q, frag, 0, skb_frag_size(frag)); 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, - void __iomem *cmb_desc, void *desc) { - if (q_to_qcq(q)->flags & IONIC_QCQ_F_CMB_RINGS) - memcpy_toio(cmb_desc, desc, q->desc_size); + /* Since Rx and Tx descriptors are the same size, we can + * 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) { struct net_device *netdev = q->lif->netdev; struct ionic_desc_info *desc_info; - struct ionic_rxq_sg_desc *sg_desc; struct ionic_rxq_sg_elem *sg_elem; struct ionic_buf_info *buf_info; unsigned int fill_threshold; @@ -807,8 +816,8 @@ void ionic_rx_fill(struct ionic_queue *q) nfrags = 0; remain_len = len; + desc = &q->rxq[q->head_idx]; desc_info = &q->info[q->head_idx]; - desc = desc_info->desc; buf_info = &desc_info->bufs[0]; if (!buf_info->page) { /* alloc a new buffer? */ @@ -837,9 +846,8 @@ void ionic_rx_fill(struct ionic_queue *q) nfrags++; /* fill sg descriptors - buf[1..n] */ - sg_desc = desc_info->sg_desc; - for (j = 0; remain_len > 0 && j < q->max_sg_elems; j++) { - sg_elem = &sg_desc->elems[j]; + sg_elem = q->rxq_sgl[q->head_idx].elems; + for (j = 0; remain_len > 0 && j < q->max_sg_elems; j++, sg_elem++) { if (!buf_info->page) { /* alloc a new sg buffer? */ if (unlikely(ionic_rx_page_alloc(q, buf_info))) { sg_elem->addr = 0; @@ -857,16 +865,14 @@ void ionic_rx_fill(struct ionic_queue *q) } /* clear end sg element as a sentinel */ - if (j < q->max_sg_elems) { - sg_elem = &sg_desc->elems[j]; + if (j < q->max_sg_elems) memset(sg_elem, 0, sizeof(*sg_elem)); - } desc->opcode = (nfrags > 1) ? IONIC_RXQ_DESC_OPCODE_SG : IONIC_RXQ_DESC_OPCODE_SIMPLE; 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); } @@ -1399,7 +1405,7 @@ static void ionic_tx_tso_post(struct net_device *netdev, struct ionic_queue *q, u16 vlan_tci, bool has_vlan, 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; 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->mss = cpu_to_le16(mss); - ionic_write_cmb_desc(q, desc_info->cmb_desc, desc); + ionic_write_cmb_desc(q, desc); if (start) { 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); if (!desc) { /* fill main descriptor */ - desc = desc_info->txq_desc; - elem = desc_info->txq_sg_desc->elems; + desc = &q->txq[q->head_idx]; + elem = ionic_tx_sg_elems(q); desc_addr = frag_addr; desc_len = chunk_len; } 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, 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_tx_stats *stats = q_to_tx_stats(q); 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_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)) 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, 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_tx_stats *stats = q_to_tx_stats(q); 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_offset = 0; - ionic_write_cmb_desc(q, desc_info->cmb_desc, desc); + ionic_write_cmb_desc(q, desc); 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, 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_txq_sg_elem *elem = sg_desc->elems; struct ionic_tx_stats *stats = q_to_tx_stats(q); + struct ionic_txq_sg_elem *elem; unsigned int i; + elem = ionic_tx_sg_elems(q); for (i = 0; i < skb_shinfo(skb)->nr_frags; i++, buf_info++, elem++) { elem->addr = cpu_to_le64(buf_info->dma_addr); elem->len = cpu_to_le16(buf_info->len); |