mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
ionic: fix completion descriptor access with 2x desc size
The old ionic_rx_service() and ionic_tx_service() used array
indexing to access completion descriptors:
comp = &((struct ionic_rxq_comp *)cq->base)[cq->tail_idx];
This assumes the stride is sizeof(struct ionic_rxq_comp) = 16 bytes.
However, when the IONIC_Q_F_2X_CQ_DESC flag is set, the actual
completion descriptor size is 32 bytes (2 * sizeof(comp)), and the
completion itself is located at the end of that 32-byte slot. Array
indexing with a 16-byte stride would access the wrong offset.
Use pointer arithmetic that accounts for the actual descriptor size
from cq->desc_size:
comp = cq->base +
cq->desc_size * cq->tail_idx +
cq->desc_size - sizeof(*comp);
This correctly calculates the completion location regardless of
descriptor size. For the common case where desc_size equals
sizeof(*comp), use array indexing in a likely() fast path to avoid
performance regression.
Fixes: 65e548f6b0 ("ionic: remove the cq_info to save more memory")
Signed-off-by: Prabu Thayalan <prabu.ponrajthayalan@amd.com>
Signed-off-by: Eric Joyner <eric.joyner@amd.com>
Reviewed-by: Brett Creeley <brett.creeley@amd.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260811195039.1315045-3-eric.joyner@amd.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
621f44af8c
commit
5da6ec6f06
|
|
@ -701,11 +701,7 @@ static void ionic_rx_clean(struct ionic_queue *q,
|
|||
__le64 *cq_desc_hwstamp;
|
||||
u64 hwstamp;
|
||||
|
||||
cq_desc_hwstamp =
|
||||
(void *)comp +
|
||||
qcq->cq.desc_size -
|
||||
sizeof(struct ionic_rxq_comp) -
|
||||
IONIC_HWSTAMP_CQ_NEGOFFSET;
|
||||
cq_desc_hwstamp = (void *)comp - IONIC_HWSTAMP_CQ_NEGOFFSET;
|
||||
|
||||
hwstamp = le64_to_cpu(*cq_desc_hwstamp);
|
||||
|
||||
|
|
@ -729,7 +725,12 @@ static bool __ionic_rx_service(struct ionic_cq *cq, struct bpf_prog *xdp_prog)
|
|||
struct ionic_queue *q = cq->bound_q;
|
||||
struct ionic_rxq_comp *comp;
|
||||
|
||||
comp = &((struct ionic_rxq_comp *)cq->base)[cq->tail_idx];
|
||||
if (likely(cq->desc_size == sizeof(*comp)))
|
||||
comp = &((struct ionic_rxq_comp *)cq->base)[cq->tail_idx];
|
||||
else
|
||||
comp = cq->base +
|
||||
cq->desc_size * cq->tail_idx +
|
||||
cq->desc_size - sizeof(*comp);
|
||||
|
||||
if (!color_match(comp->pkt_type_color, cq->done_color))
|
||||
return false;
|
||||
|
|
@ -1182,7 +1183,6 @@ static void ionic_tx_clean(struct ionic_queue *q,
|
|||
bool in_napi)
|
||||
{
|
||||
struct ionic_tx_stats *stats = q_to_tx_stats(q);
|
||||
struct ionic_qcq *qcq = q_to_qcq(q);
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (desc_info->xdpf) {
|
||||
|
|
@ -1207,11 +1207,7 @@ static void ionic_tx_clean(struct ionic_queue *q,
|
|||
__le64 *cq_desc_hwstamp;
|
||||
u64 hwstamp;
|
||||
|
||||
cq_desc_hwstamp =
|
||||
(void *)comp +
|
||||
qcq->cq.desc_size -
|
||||
sizeof(struct ionic_txq_comp) -
|
||||
IONIC_HWSTAMP_CQ_NEGOFFSET;
|
||||
cq_desc_hwstamp = (void *)comp - IONIC_HWSTAMP_CQ_NEGOFFSET;
|
||||
|
||||
hwstamp = le64_to_cpu(*cq_desc_hwstamp);
|
||||
|
||||
|
|
@ -1246,7 +1242,12 @@ static bool ionic_tx_service(struct ionic_cq *cq,
|
|||
unsigned int pkts = 0;
|
||||
u16 index;
|
||||
|
||||
comp = &((struct ionic_txq_comp *)cq->base)[cq->tail_idx];
|
||||
if (likely(cq->desc_size == sizeof(*comp)))
|
||||
comp = &((struct ionic_txq_comp *)cq->base)[cq->tail_idx];
|
||||
else
|
||||
comp = cq->base +
|
||||
cq->desc_size * cq->tail_idx +
|
||||
cq->desc_size - sizeof(*comp);
|
||||
|
||||
if (!color_match(comp->color, cq->done_color))
|
||||
return false;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user