From 65e548f6b0ffc4222a99feda8a033a2a9fb9f3e7 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Wed, 6 Mar 2024 15:29:50 -0800 Subject: ionic: remove the cq_info to save more memory With a little simple math we don't need another struct array to find the completion structs, so we can remove the ionic_cq_info altogether. This doesn't really save anything in the ionic_cq since it gets padded out to the cacheline, but it does remove the parallel array allocation of 8 * num_descriptors, or about 8 Kbytes per queue in a default configuration. Suggested-by: Neel Patel Reviewed-by: Brett Creeley Signed-off-by: Shannon Nelson Signed-off-by: David S. Miller --- drivers/net/ethernet/pensando/ionic/ionic.h | 4 +-- drivers/net/ethernet/pensando/ionic/ionic_dev.c | 23 ++------------- drivers/net/ethernet/pensando/ionic/ionic_dev.h | 11 +------ drivers/net/ethernet/pensando/ionic/ionic_lif.c | 37 +++++++----------------- drivers/net/ethernet/pensando/ionic/ionic_main.c | 18 +++++------- drivers/net/ethernet/pensando/ionic/ionic_txrx.c | 32 +++++++++----------- drivers/net/ethernet/pensando/ionic/ionic_txrx.h | 2 +- 7 files changed, 38 insertions(+), 89 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ethernet/pensando/ionic/ionic.h b/drivers/net/ethernet/pensando/ionic/ionic.h index 946c8ae1548f..2ccc2c2a06e3 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic.h +++ b/drivers/net/ethernet/pensando/ionic/ionic.h @@ -76,8 +76,8 @@ int ionic_adminq_post_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx); int ionic_adminq_post_wait_nomsg(struct ionic_lif *lif, struct ionic_admin_ctx *ctx); void ionic_adminq_netdev_err_print(struct ionic_lif *lif, u8 opcode, u8 status, int err); -bool ionic_notifyq_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info); -bool ionic_adminq_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info); +bool ionic_notifyq_service(struct ionic_cq *cq); +bool ionic_adminq_service(struct ionic_cq *cq); int ionic_dev_cmd_wait(struct ionic *ionic, unsigned long max_wait); int ionic_dev_cmd_wait_nomsg(struct ionic *ionic, unsigned long max_wait); diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.c b/drivers/net/ethernet/pensando/ionic/ionic_dev.c index 94bd0db34473..594e65a52010 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_dev.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.c @@ -633,39 +633,20 @@ int ionic_cq_init(struct ionic_lif *lif, struct ionic_cq *cq, return 0; } -void ionic_cq_map(struct ionic_cq *cq, void *base, dma_addr_t base_pa) -{ - struct ionic_cq_info *cur; - unsigned int i; - - cq->base = base; - cq->base_pa = base_pa; - - for (i = 0, cur = cq->info; i < cq->num_descs; i++, cur++) - cur->cq_desc = base + (i * cq->desc_size); -} - -void ionic_cq_bind(struct ionic_cq *cq, struct ionic_queue *q) -{ - cq->bound_q = q; -} - 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; - cq_info = &cq->info[cq->tail_idx]; - while (cb(cq, cq_info)) { + while (cb(cq)) { if (cq->tail_idx == cq->num_descs - 1) cq->done_color = !cq->done_color; + cq->tail_idx = (cq->tail_idx + 1) & (cq->num_descs - 1); - cq_info = &cq->info[cq->tail_idx]; if (++work_done >= work_to_do) break; diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h b/drivers/net/ethernet/pensando/ionic/ionic_dev.h index 2096aae1ef71..3ed4eaea9315 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h +++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h @@ -177,14 +177,6 @@ struct ionic_dev { struct ionic_devinfo dev_info; }; -struct ionic_cq_info { - union { - void *cq_desc; - struct ionic_admin_comp *admincq; - struct ionic_notifyq_event *notifyq; - }; -}; - struct ionic_queue; struct ionic_qcq; struct ionic_desc_info; @@ -282,7 +274,6 @@ struct ionic_intr_info { struct ionic_cq { struct ionic_lif *lif; - struct ionic_cq_info *info; struct ionic_queue *bound_q; struct ionic_intr_info *bound_intr; u16 tail_idx; @@ -365,7 +356,7 @@ int ionic_cq_init(struct ionic_lif *lif, struct ionic_cq *cq, unsigned int num_descs, size_t desc_size); void ionic_cq_map(struct ionic_cq *cq, void *base, dma_addr_t base_pa); void ionic_cq_bind(struct ionic_cq *cq, struct ionic_queue *q); -typedef bool (*ionic_cq_cb)(struct ionic_cq *cq, struct ionic_cq_info *cq_info); +typedef bool (*ionic_cq_cb)(struct ionic_cq *cq); typedef void (*ionic_cq_done_cb)(void *done_arg); unsigned int ionic_cq_service(struct ionic_cq *cq, unsigned int work_to_do, ionic_cq_cb cb, ionic_cq_done_cb done_cb, diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index 4cc879955d21..afac48427af8 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -433,8 +433,6 @@ static void ionic_qcq_free(struct ionic_lif *lif, struct ionic_qcq *qcq) ionic_xdp_unregister_rxq_info(&qcq->q); ionic_qcq_intr_free(lif, qcq); - vfree(qcq->cq.info); - qcq->cq.info = NULL; vfree(qcq->q.info); qcq->q.info = NULL; } @@ -542,9 +540,7 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type, { struct ionic_dev *idev = &lif->ionic->idev; struct device *dev = lif->ionic->dev; - dma_addr_t cq_base_pa = 0; struct ionic_qcq *new; - void *cq_base; int err; *qcq = NULL; @@ -578,19 +574,12 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type, err = ionic_alloc_qcq_interrupt(lif, new); if (err) - goto err_out; - - new->cq.info = vcalloc(num_descs, sizeof(*new->cq.info)); - if (!new->cq.info) { - netdev_err(lif->netdev, "Cannot allocate completion queue info\n"); - err = -ENOMEM; - goto err_out_free_irq; - } + goto err_out_free_q_info; err = ionic_cq_init(lif, &new->cq, &new->intr, num_descs, cq_desc_size); if (err) { netdev_err(lif->netdev, "Cannot initialize completion queue\n"); - goto err_out_free_cq_info; + goto err_out_free_irq; } if (flags & IONIC_QCQ_F_NOTIFYQ) { @@ -608,15 +597,15 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type, if (!new->q_base) { netdev_err(lif->netdev, "Cannot allocate qcq DMA memory\n"); err = -ENOMEM; - goto err_out_free_cq_info; + goto err_out_free_irq; } new->q.base = PTR_ALIGN(new->q_base, PAGE_SIZE); new->q.base_pa = ALIGN(new->q_base_pa, PAGE_SIZE); - cq_base = PTR_ALIGN(new->q_base + q_size, PAGE_SIZE); - cq_base_pa = ALIGN(new->q_base_pa + q_size, PAGE_SIZE); - ionic_cq_map(&new->cq, cq_base, cq_base_pa); - ionic_cq_bind(&new->cq, &new->q); + /* Base the NotifyQ cq.base off of the ALIGNed q.base */ + new->cq.base = PTR_ALIGN(new->q.base + q_size, PAGE_SIZE); + new->cq.base_pa = ALIGN(new->q_base_pa + q_size, PAGE_SIZE); + new->cq.bound_q = &new->q; } else { /* regular DMA q descriptors */ new->q_size = PAGE_SIZE + (num_descs * desc_size); @@ -625,7 +614,7 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type, if (!new->q_base) { netdev_err(lif->netdev, "Cannot allocate queue DMA memory\n"); err = -ENOMEM; - goto err_out_free_cq_info; + goto err_out_free_irq; } new->q.base = PTR_ALIGN(new->q_base, PAGE_SIZE); new->q.base_pa = ALIGN(new->q_base_pa, PAGE_SIZE); @@ -666,10 +655,9 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type, err = -ENOMEM; goto err_out_free_q; } - cq_base = PTR_ALIGN(new->cq_base, PAGE_SIZE); - cq_base_pa = ALIGN(new->cq_base_pa, PAGE_SIZE); - ionic_cq_map(&new->cq, cq_base, cq_base_pa); - ionic_cq_bind(&new->cq, &new->q); + new->cq.base = PTR_ALIGN(new->cq_base, PAGE_SIZE); + new->cq.base_pa = ALIGN(new->cq_base_pa, PAGE_SIZE); + new->cq.bound_q = &new->q; } if (flags & IONIC_QCQ_F_SG) { @@ -700,8 +688,6 @@ err_out_free_q: ionic_put_cmb(lif, new->cmb_pgid, new->cmb_order); } dma_free_coherent(dev, new->q_size, new->q_base, new->q_base_pa); -err_out_free_cq_info: - vfree(new->cq.info); err_out_free_irq: if (flags & IONIC_QCQ_F_INTR) { devm_free_irq(dev, new->intr.vector, &new->napi); @@ -2889,7 +2875,6 @@ static void ionic_swap_queues(struct ionic_qcq *a, struct ionic_qcq *b) swap(a->cq.desc_size, b->cq.desc_size); swap(a->cq.base, b->cq.base); swap(a->cq.base_pa, b->cq.base_pa); - swap(a->cq.info, b->cq.info); swap(a->cq_base, b->cq_base); swap(a->cq_base_pa, b->cq_base_pa); swap(a->cq_size, b->cq_size); diff --git a/drivers/net/ethernet/pensando/ionic/ionic_main.c b/drivers/net/ethernet/pensando/ionic/ionic_main.c index 023c2c37056e..2c092858bc0d 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_main.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_main.c @@ -249,16 +249,13 @@ 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_cq_info *cq_info) + struct ionic_admin_comp *comp) { struct ionic_admin_ctx *ctx = desc_info->arg; - struct ionic_admin_comp *comp; if (!ctx) return; - comp = cq_info->cq_desc; - memcpy(&ctx->comp, comp, sizeof(*comp)); dev_dbg(q->dev, "comp admin queue command:\n"); @@ -268,16 +265,17 @@ static void ionic_adminq_clean(struct ionic_queue *q, complete_all(&ctx->work); } -bool ionic_notifyq_service(struct ionic_cq *cq, - struct ionic_cq_info *cq_info) +bool ionic_notifyq_service(struct ionic_cq *cq) { - union ionic_notifyq_comp *comp = cq_info->cq_desc; struct ionic_deferred_work *work; + union ionic_notifyq_comp *comp; struct net_device *netdev; struct ionic_queue *q; struct ionic_lif *lif; u64 eid; + comp = &((union ionic_notifyq_comp *)cq->base)[cq->tail_idx]; + q = cq->bound_q; lif = q->info[0].arg; netdev = lif->netdev; @@ -320,14 +318,14 @@ bool ionic_notifyq_service(struct ionic_cq *cq, return true; } -bool ionic_adminq_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info) +bool ionic_adminq_service(struct ionic_cq *cq) { struct ionic_queue *q = cq->bound_q; struct ionic_desc_info *desc_info; struct ionic_admin_comp *comp; u16 index; - comp = cq_info->cq_desc; + comp = &((struct ionic_admin_comp *)cq->base)[cq->tail_idx]; if (!color_match(comp->color, cq->done_color)) return false; @@ -341,7 +339,7 @@ bool ionic_adminq_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info) index = q->tail_idx; q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1); if (likely(desc_info->arg)) - ionic_adminq_clean(q, desc_info, cq_info); + ionic_adminq_clean(q, desc_info, comp); desc_info->arg = NULL; } while (index != le16_to_cpu(comp->comp_index)); diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c index fcd6a2fe31d2..e7ebd2df1e23 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c @@ -23,7 +23,7 @@ static void ionic_tx_desc_unmap_bufs(struct ionic_queue *q, static void ionic_tx_clean(struct ionic_queue *q, struct ionic_desc_info *desc_info, - struct ionic_cq_info *cq_info); + struct ionic_txq_comp *comp); static inline void ionic_txq_post(struct ionic_queue *q, bool ring_dbell, void *arg) @@ -635,19 +635,16 @@ out_xdp_abort: static void ionic_rx_clean(struct ionic_queue *q, struct ionic_desc_info *desc_info, - struct ionic_cq_info *cq_info) + struct ionic_rxq_comp *comp) { struct net_device *netdev = q->lif->netdev; struct ionic_qcq *qcq = q_to_qcq(q); struct ionic_rx_stats *stats; - struct ionic_rxq_comp *comp; struct bpf_prog *xdp_prog; unsigned int headroom; struct sk_buff *skb; u16 len; - comp = cq_info->cq_desc + qcq->cq.desc_size - sizeof(*comp); - stats = q_to_rx_stats(q); if (comp->status) { @@ -722,7 +719,7 @@ static void ionic_rx_clean(struct ionic_queue *q, u64 hwstamp; cq_desc_hwstamp = - cq_info->cq_desc + + (void *)comp + qcq->cq.desc_size - sizeof(struct ionic_rxq_comp) - IONIC_HWSTAMP_CQ_NEGOFFSET; @@ -743,13 +740,13 @@ static void ionic_rx_clean(struct ionic_queue *q, napi_gro_frags(&qcq->napi); } -bool ionic_rx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info) +bool ionic_rx_service(struct ionic_cq *cq) { struct ionic_queue *q = cq->bound_q; struct ionic_desc_info *desc_info; struct ionic_rxq_comp *comp; - comp = cq_info->cq_desc + cq->desc_size - sizeof(*comp); + comp = &((struct ionic_rxq_comp *)cq->base)[cq->tail_idx]; if (!color_match(comp->pkt_type_color, cq->done_color)) return false; @@ -765,7 +762,7 @@ bool ionic_rx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info) 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); + ionic_rx_clean(q, desc_info, comp); desc_info->arg = NULL; @@ -1181,7 +1178,7 @@ static void ionic_tx_desc_unmap_bufs(struct ionic_queue *q, static void ionic_tx_clean(struct ionic_queue *q, struct ionic_desc_info *desc_info, - struct ionic_cq_info *cq_info) + struct ionic_txq_comp *comp) { struct ionic_tx_stats *stats = q_to_tx_stats(q); struct ionic_qcq *qcq = q_to_qcq(q); @@ -1204,13 +1201,13 @@ static void ionic_tx_clean(struct ionic_queue *q, return; if (unlikely(ionic_txq_hwstamp_enabled(q))) { - if (cq_info) { + if (comp) { struct skb_shared_hwtstamps hwts = {}; __le64 *cq_desc_hwstamp; u64 hwstamp; cq_desc_hwstamp = - cq_info->cq_desc + + (void *)comp + qcq->cq.desc_size - sizeof(struct ionic_txq_comp) - IONIC_HWSTAMP_CQ_NEGOFFSET; @@ -1236,7 +1233,7 @@ static void ionic_tx_clean(struct ionic_queue *q, napi_consume_skb(skb, 1); } -static bool ionic_tx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info, +static bool ionic_tx_service(struct ionic_cq *cq, unsigned int *total_pkts, unsigned int *total_bytes) { struct ionic_queue *q = cq->bound_q; @@ -1246,7 +1243,7 @@ static bool ionic_tx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info, unsigned int pkts = 0; u16 index; - comp = cq_info->cq_desc + cq->desc_size - sizeof(*comp); + comp = &((struct ionic_txq_comp *)cq->base)[cq->tail_idx]; if (!color_match(comp->color, cq->done_color)) return false; @@ -1259,7 +1256,7 @@ static bool ionic_tx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info, desc_info->bytes = 0; index = q->tail_idx; q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1); - ionic_tx_clean(q, desc_info, cq_info); + ionic_tx_clean(q, desc_info, comp); if (desc_info->arg) { pkts++; bytes += desc_info->bytes; @@ -1275,7 +1272,6 @@ static bool ionic_tx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info, unsigned int ionic_tx_cq_service(struct ionic_cq *cq, unsigned int work_to_do) { - struct ionic_cq_info *cq_info; unsigned int work_done = 0; unsigned int bytes = 0; unsigned int pkts = 0; @@ -1283,12 +1279,10 @@ unsigned int ionic_tx_cq_service(struct ionic_cq *cq, unsigned int work_to_do) if (work_to_do == 0) return 0; - cq_info = &cq->info[cq->tail_idx]; - while (ionic_tx_service(cq, cq_info, &pkts, &bytes)) { + while (ionic_tx_service(cq, &pkts, &bytes)) { if (cq->tail_idx == cq->num_descs - 1) cq->done_color = !cq->done_color; cq->tail_idx = (cq->tail_idx + 1) & (cq->num_descs - 1); - cq_info = &cq->info[cq->tail_idx]; if (++work_done >= work_to_do) break; diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.h b/drivers/net/ethernet/pensando/ionic/ionic_txrx.h index 68228bb8c119..9e73e324e7a1 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.h +++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.h @@ -14,7 +14,7 @@ int ionic_tx_napi(struct napi_struct *napi, int budget); int ionic_txrx_napi(struct napi_struct *napi, int budget); netdev_tx_t ionic_start_xmit(struct sk_buff *skb, struct net_device *netdev); -bool ionic_rx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info); +bool ionic_rx_service(struct ionic_cq *cq); int ionic_xdp_xmit(struct net_device *netdev, int n, struct xdp_frame **xdp, u32 flags); #endif /* _IONIC_TXRX_H_ */ -- cgit v1.2.3-59-g8ed1b