From ae24a8f88b3fc8ef463e8dffd41ebba48c81cfd4 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Wed, 6 Mar 2024 15:29:49 -0800 Subject: [PATCH] ionic: remove callback pointer from desc_info By reworking the queue service routines to have their own servicing loops we can remove the cb pointer from desc_info to save another 8 bytes per descriptor, This simplifies some of the queue handling indirection and makes the code a little easier to follow, and keeps service code in one place rather than jumping between code files. struct ionic_desc_info Before: /* size: 472, cachelines: 8, members: 7 */ After: /* size: 464, cachelines: 8, members: 6 */ Suggested-by: Neel Patel Reviewed-by: Brett Creeley Signed-off-by: Shannon Nelson Signed-off-by: David S. Miller --- .../net/ethernet/pensando/ionic/ionic_dev.c | 42 ++------------- .../net/ethernet/pensando/ionic/ionic_dev.h | 14 ++--- .../net/ethernet/pensando/ionic/ionic_lif.c | 2 +- .../net/ethernet/pensando/ionic/ionic_main.c | 38 +++++++++----- .../net/ethernet/pensando/ionic/ionic_txrx.c | 52 ++++++++----------- 5 files changed, 57 insertions(+), 91 deletions(-) diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.c b/drivers/net/ethernet/pensando/ionic/ionic_dev.c index b4889f8c14d8..94bd0db34473 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_dev.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.c @@ -706,16 +706,14 @@ 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, ionic_desc_cb cb, - void *cb_arg) +void ionic_q_post(struct ionic_queue *q, bool ring_doorbell, void *arg) { 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->cb = cb; - desc_info->cb_arg = cb_arg; + desc_info->arg = arg; q->head_idx = (q->head_idx + 1) & (q->num_descs - 1); @@ -735,7 +733,7 @@ void ionic_q_post(struct ionic_queue *q, bool ring_doorbell, ionic_desc_cb cb, } } -static bool ionic_q_is_posted(struct ionic_queue *q, unsigned int pos) +bool ionic_q_is_posted(struct ionic_queue *q, unsigned int pos) { unsigned int mask, tail, head; @@ -745,37 +743,3 @@ static bool ionic_q_is_posted(struct ionic_queue *q, unsigned int pos) return ((pos - tail) & mask) < ((head - tail) & mask); } - -void ionic_q_service(struct ionic_queue *q, struct ionic_cq_info *cq_info, - unsigned int stop_index) -{ - struct ionic_desc_info *desc_info; - ionic_desc_cb cb; - void *cb_arg; - u16 index; - - /* check for empty queue */ - 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->dev, - "ionic stop is not posted %s stop %u tail %u head %u\n", - q->name, stop_index, q->tail_idx, q->head_idx); - - do { - desc_info = &q->info[q->tail_idx]; - index = q->tail_idx; - q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1); - - cb = desc_info->cb; - cb_arg = desc_info->cb_arg; - - desc_info->cb = NULL; - desc_info->cb_arg = NULL; - - if (cb) - cb(q, desc_info, cq_info, cb_arg); - } while (index != stop_index); -} diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.h b/drivers/net/ethernet/pensando/ionic/ionic_dev.h index c70576be3714..2096aae1ef71 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_dev.h +++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.h @@ -189,10 +189,6 @@ struct ionic_queue; struct ionic_qcq; struct ionic_desc_info; -typedef void (*ionic_desc_cb)(struct ionic_queue *q, - struct ionic_desc_info *desc_info, - struct ionic_cq_info *cq_info, void *cb_arg); - #define IONIC_MAX_BUF_LEN ((u16)-1) #define IONIC_PAGE_SIZE PAGE_SIZE #define IONIC_PAGE_SPLIT_SZ (PAGE_SIZE / 2) @@ -216,8 +212,7 @@ struct ionic_buf_info { struct ionic_desc_info { unsigned int bytes; unsigned int nbufs; - ionic_desc_cb cb; - void *cb_arg; + void *arg; struct xdp_frame *xdpf; enum xdp_action act; struct ionic_buf_info bufs[MAX_SKB_FRAGS + 1]; @@ -381,10 +376,9 @@ 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, ionic_desc_cb cb, - void *cb_arg); -void ionic_q_service(struct ionic_queue *q, struct ionic_cq_info *cq_info, - unsigned int stop_index); +void ionic_q_post(struct ionic_queue *q, bool ring_doorbell, void *arg); +bool ionic_q_is_posted(struct ionic_queue *q, unsigned int pos); + int ionic_heartbeat_check(struct ionic *ionic); bool ionic_is_fw_running(struct ionic_dev *idev); diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index a9835ede446e..4cc879955d21 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -3564,7 +3564,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].cb_arg = lif; + q->info[0].arg = lif; qcq->flags |= IONIC_QCQ_F_INITED; diff --git a/drivers/net/ethernet/pensando/ionic/ionic_main.c b/drivers/net/ethernet/pensando/ionic/ionic_main.c index 46f2aa34330d..023c2c37056e 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_main.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_main.c @@ -207,8 +207,7 @@ static void ionic_adminq_flush(struct ionic_lif *lif) desc = &q->adminq[q->tail_idx]; desc_info = &q->info[q->tail_idx]; memset(desc, 0, sizeof(union ionic_adminq_cmd)); - desc_info->cb = NULL; - desc_info->cb_arg = NULL; + desc_info->arg = NULL; q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1); } spin_unlock_irqrestore(&lif->adminq_lock, irqflags); @@ -248,11 +247,11 @@ static int ionic_adminq_check_err(struct ionic_lif *lif, return err; } -static void ionic_adminq_cb(struct ionic_queue *q, - struct ionic_desc_info *desc_info, - struct ionic_cq_info *cq_info, void *cb_arg) +static void ionic_adminq_clean(struct ionic_queue *q, + struct ionic_desc_info *desc_info, + struct ionic_cq_info *cq_info) { - struct ionic_admin_ctx *ctx = cb_arg; + struct ionic_admin_ctx *ctx = desc_info->arg; struct ionic_admin_comp *comp; if (!ctx) @@ -280,7 +279,7 @@ bool ionic_notifyq_service(struct ionic_cq *cq, u64 eid; q = cq->bound_q; - lif = q->info[0].cb_arg; + lif = q->info[0].arg; netdev = lif->netdev; eid = le64_to_cpu(comp->event.eid); @@ -321,15 +320,30 @@ 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_cq_info *cq_info) { - struct ionic_admin_comp *comp = cq_info->cq_desc; + 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; if (!color_match(comp->color, cq->done_color)) return false; - ionic_q_service(cq->bound_q, cq_info, le16_to_cpu(comp->comp_index)); + /* check for empty queue */ + if (q->tail_idx == q->head_idx) + return false; + + do { + desc_info = &q->info[q->tail_idx]; + 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); + desc_info->arg = NULL; + } while (index != le16_to_cpu(comp->comp_index)); return true; } @@ -394,7 +408,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, ionic_adminq_cb, ctx); + ionic_q_post(q, true, ctx); err_out: spin_unlock_irqrestore(&lif->adminq_lock, irqflags); diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c index bc8e099ca1ac..fcd6a2fe31d2 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c @@ -23,19 +23,18 @@ 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, - void *cb_arg); + 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) + void *arg) { - ionic_q_post(q, ring_dbell, cb_func, cb_arg); + ionic_q_post(q, ring_dbell, arg); } static inline void ionic_rxq_post(struct ionic_queue *q, bool ring_dbell, - ionic_desc_cb cb_func, void *cb_arg) + void *arg) { - ionic_q_post(q, ring_dbell, cb_func, cb_arg); + ionic_q_post(q, ring_dbell, arg); } bool ionic_txq_poke_doorbell(struct ionic_queue *q) @@ -427,7 +426,7 @@ static int ionic_xdp_post_frame(struct ionic_queue *q, struct xdp_frame *frame, stats->pkts++; stats->bytes += len; - ionic_txq_post(q, ring_doorbell, ionic_tx_clean, NULL); + ionic_txq_post(q, ring_doorbell, NULL); return 0; } @@ -636,8 +635,7 @@ out_xdp_abort: static void ionic_rx_clean(struct ionic_queue *q, struct ionic_desc_info *desc_info, - struct ionic_cq_info *cq_info, - void *cb_arg) + struct ionic_cq_info *cq_info) { struct net_device *netdev = q->lif->netdev; struct ionic_qcq *qcq = q_to_qcq(q); @@ -767,10 +765,9 @@ 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, desc_info->cb_arg); + ionic_rx_clean(q, desc_info, cq_info); - desc_info->cb = NULL; - desc_info->cb_arg = NULL; + desc_info->arg = NULL; return true; } @@ -874,7 +871,7 @@ void ionic_rx_fill(struct ionic_queue *q) ionic_write_cmb_desc(q, desc); - ionic_rxq_post(q, false, ionic_rx_clean, NULL); + ionic_rxq_post(q, false, NULL); } ionic_dbell_ring(q->lif->kern_dbpage, q->hw_type, @@ -902,8 +899,7 @@ void ionic_rx_empty(struct ionic_queue *q) } desc_info->nbufs = 0; - desc_info->cb = NULL; - desc_info->cb_arg = NULL; + desc_info->arg = NULL; } q->head_idx = 0; @@ -1185,12 +1181,11 @@ 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, - void *cb_arg) + struct ionic_cq_info *cq_info) { struct ionic_tx_stats *stats = q_to_tx_stats(q); struct ionic_qcq *qcq = q_to_qcq(q); - struct sk_buff *skb = cb_arg; + struct sk_buff *skb; if (desc_info->xdpf) { ionic_xdp_tx_desc_clean(q->partner, desc_info); @@ -1204,6 +1199,7 @@ static void ionic_tx_clean(struct ionic_queue *q, ionic_tx_desc_unmap_bufs(q, desc_info); + skb = desc_info->arg; if (!skb) return; @@ -1263,13 +1259,12 @@ 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, desc_info->cb_arg); - if (desc_info->cb_arg) { + ionic_tx_clean(q, desc_info, cq_info); + if (desc_info->arg) { pkts++; bytes += desc_info->bytes; + desc_info->arg = NULL; } - desc_info->cb = NULL; - desc_info->cb_arg = NULL; } while (index != le16_to_cpu(comp->comp_index)); (*total_pkts) += pkts; @@ -1334,13 +1329,12 @@ void ionic_tx_empty(struct ionic_queue *q) desc_info = &q->info[q->tail_idx]; desc_info->bytes = 0; q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1); - ionic_tx_clean(q, desc_info, NULL, desc_info->cb_arg); - if (desc_info->cb_arg) { + ionic_tx_clean(q, desc_info, NULL); + if (desc_info->arg) { pkts++; bytes += desc_info->bytes; + desc_info->arg = NULL; } - desc_info->cb = NULL; - desc_info->cb_arg = NULL; } if (likely(!ionic_txq_hwstamp_enabled(q))) { @@ -1427,9 +1421,9 @@ static void ionic_tx_tso_post(struct net_device *netdev, struct ionic_queue *q, skb_tx_timestamp(skb); if (likely(!ionic_txq_hwstamp_enabled(q))) netdev_tx_sent_queue(q_to_ndq(netdev, q), skb->len); - ionic_txq_post(q, false, ionic_tx_clean, skb); + ionic_txq_post(q, false, skb); } else { - ionic_txq_post(q, done, NULL, NULL); + ionic_txq_post(q, done, NULL); } } @@ -1683,7 +1677,7 @@ static int ionic_tx(struct net_device *netdev, struct ionic_queue *q, ring_dbell = __netdev_tx_sent_queue(ndq, skb->len, netdev_xmit_more()); } - ionic_txq_post(q, ring_dbell, ionic_tx_clean, skb); + ionic_txq_post(q, ring_dbell, skb); return 0; } -- 2.34.1