mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-29 05:44:11 +00:00
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 <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:
parent
05c9447395
commit
ae24a8f88b
5 changed files with 57 additions and 91 deletions
|
@ -706,16 +706,14 @@ int ionic_q_init(struct ionic_lif *lif, struct ionic_dev *idev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
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, void *arg)
|
||||||
void *cb_arg)
|
|
||||||
{
|
{
|
||||||
struct ionic_desc_info *desc_info;
|
struct ionic_desc_info *desc_info;
|
||||||
struct ionic_lif *lif = q->lif;
|
struct ionic_lif *lif = q->lif;
|
||||||
struct device *dev = q->dev;
|
struct device *dev = q->dev;
|
||||||
|
|
||||||
desc_info = &q->info[q->head_idx];
|
desc_info = &q->info[q->head_idx];
|
||||||
desc_info->cb = cb;
|
desc_info->arg = arg;
|
||||||
desc_info->cb_arg = cb_arg;
|
|
||||||
|
|
||||||
q->head_idx = (q->head_idx + 1) & (q->num_descs - 1);
|
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;
|
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);
|
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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -189,10 +189,6 @@ struct ionic_queue;
|
||||||
struct ionic_qcq;
|
struct ionic_qcq;
|
||||||
struct ionic_desc_info;
|
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_MAX_BUF_LEN ((u16)-1)
|
||||||
#define IONIC_PAGE_SIZE PAGE_SIZE
|
#define IONIC_PAGE_SIZE PAGE_SIZE
|
||||||
#define IONIC_PAGE_SPLIT_SZ (PAGE_SIZE / 2)
|
#define IONIC_PAGE_SPLIT_SZ (PAGE_SIZE / 2)
|
||||||
|
@ -216,8 +212,7 @@ struct ionic_buf_info {
|
||||||
struct ionic_desc_info {
|
struct ionic_desc_info {
|
||||||
unsigned int bytes;
|
unsigned int bytes;
|
||||||
unsigned int nbufs;
|
unsigned int nbufs;
|
||||||
ionic_desc_cb cb;
|
void *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];
|
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,
|
struct ionic_queue *q, unsigned int index, const char *name,
|
||||||
unsigned int num_descs, size_t desc_size,
|
unsigned int num_descs, size_t desc_size,
|
||||||
size_t sg_desc_size, unsigned int pid);
|
size_t sg_desc_size, unsigned int pid);
|
||||||
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, void *arg);
|
||||||
void *cb_arg);
|
bool ionic_q_is_posted(struct ionic_queue *q, unsigned int pos);
|
||||||
void ionic_q_service(struct ionic_queue *q, struct ionic_cq_info *cq_info,
|
|
||||||
unsigned int stop_index);
|
|
||||||
int ionic_heartbeat_check(struct ionic *ionic);
|
int ionic_heartbeat_check(struct ionic *ionic);
|
||||||
bool ionic_is_fw_running(struct ionic_dev *idev);
|
bool ionic_is_fw_running(struct ionic_dev *idev);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
dev_dbg(dev, "notifyq->hw_index %d\n", q->hw_index);
|
||||||
|
|
||||||
/* preset the callback info */
|
/* preset the callback info */
|
||||||
q->info[0].cb_arg = lif;
|
q->info[0].arg = lif;
|
||||||
|
|
||||||
qcq->flags |= IONIC_QCQ_F_INITED;
|
qcq->flags |= IONIC_QCQ_F_INITED;
|
||||||
|
|
||||||
|
|
|
@ -207,8 +207,7 @@ static void ionic_adminq_flush(struct ionic_lif *lif)
|
||||||
desc = &q->adminq[q->tail_idx];
|
desc = &q->adminq[q->tail_idx];
|
||||||
desc_info = &q->info[q->tail_idx];
|
desc_info = &q->info[q->tail_idx];
|
||||||
memset(desc, 0, sizeof(union ionic_adminq_cmd));
|
memset(desc, 0, sizeof(union ionic_adminq_cmd));
|
||||||
desc_info->cb = NULL;
|
desc_info->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);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
|
spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
|
||||||
|
@ -248,11 +247,11 @@ static int ionic_adminq_check_err(struct ionic_lif *lif,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ionic_adminq_cb(struct ionic_queue *q,
|
static void ionic_adminq_clean(struct ionic_queue *q,
|
||||||
struct ionic_desc_info *desc_info,
|
struct ionic_desc_info *desc_info,
|
||||||
struct ionic_cq_info *cq_info, void *cb_arg)
|
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;
|
struct ionic_admin_comp *comp;
|
||||||
|
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
|
@ -280,7 +279,7 @@ bool ionic_notifyq_service(struct ionic_cq *cq,
|
||||||
u64 eid;
|
u64 eid;
|
||||||
|
|
||||||
q = cq->bound_q;
|
q = cq->bound_q;
|
||||||
lif = q->info[0].cb_arg;
|
lif = q->info[0].arg;
|
||||||
netdev = lif->netdev;
|
netdev = lif->netdev;
|
||||||
eid = le64_to_cpu(comp->event.eid);
|
eid = le64_to_cpu(comp->event.eid);
|
||||||
|
|
||||||
|
@ -321,15 +320,30 @@ bool ionic_notifyq_service(struct ionic_cq *cq,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ionic_adminq_service(struct ionic_cq *cq,
|
bool ionic_adminq_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info)
|
||||||
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))
|
if (!color_match(comp->color, cq->done_color))
|
||||||
return false;
|
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;
|
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,
|
dynamic_hex_dump("cmd ", DUMP_PREFIX_OFFSET, 16, 1,
|
||||||
&ctx->cmd, sizeof(ctx->cmd), true);
|
&ctx->cmd, sizeof(ctx->cmd), true);
|
||||||
|
|
||||||
ionic_q_post(q, true, ionic_adminq_cb, ctx);
|
ionic_q_post(q, true, ctx);
|
||||||
|
|
||||||
err_out:
|
err_out:
|
||||||
spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
|
spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
|
||||||
|
|
|
@ -23,19 +23,18 @@ static void ionic_tx_desc_unmap_bufs(struct ionic_queue *q,
|
||||||
|
|
||||||
static void ionic_tx_clean(struct ionic_queue *q,
|
static void ionic_tx_clean(struct ionic_queue *q,
|
||||||
struct ionic_desc_info *desc_info,
|
struct ionic_desc_info *desc_info,
|
||||||
struct ionic_cq_info *cq_info,
|
struct ionic_cq_info *cq_info);
|
||||||
void *cb_arg);
|
|
||||||
|
|
||||||
static inline void ionic_txq_post(struct ionic_queue *q, bool ring_dbell,
|
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,
|
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)
|
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->pkts++;
|
||||||
stats->bytes += len;
|
stats->bytes += len;
|
||||||
|
|
||||||
ionic_txq_post(q, ring_doorbell, ionic_tx_clean, NULL);
|
ionic_txq_post(q, ring_doorbell, NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -636,8 +635,7 @@ static bool ionic_run_xdp(struct ionic_rx_stats *stats,
|
||||||
|
|
||||||
static void ionic_rx_clean(struct ionic_queue *q,
|
static void ionic_rx_clean(struct ionic_queue *q,
|
||||||
struct ionic_desc_info *desc_info,
|
struct ionic_desc_info *desc_info,
|
||||||
struct ionic_cq_info *cq_info,
|
struct ionic_cq_info *cq_info)
|
||||||
void *cb_arg)
|
|
||||||
{
|
{
|
||||||
struct net_device *netdev = q->lif->netdev;
|
struct net_device *netdev = q->lif->netdev;
|
||||||
struct ionic_qcq *qcq = q_to_qcq(q);
|
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);
|
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
|
||||||
|
|
||||||
/* clean the related q entry, only one per qc completion */
|
/* 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->arg = NULL;
|
||||||
desc_info->cb_arg = NULL;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -874,7 +871,7 @@ void ionic_rx_fill(struct ionic_queue *q)
|
||||||
|
|
||||||
ionic_write_cmb_desc(q, desc);
|
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,
|
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->nbufs = 0;
|
||||||
desc_info->cb = NULL;
|
desc_info->arg = NULL;
|
||||||
desc_info->cb_arg = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
q->head_idx = 0;
|
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,
|
static void ionic_tx_clean(struct ionic_queue *q,
|
||||||
struct ionic_desc_info *desc_info,
|
struct ionic_desc_info *desc_info,
|
||||||
struct ionic_cq_info *cq_info,
|
struct ionic_cq_info *cq_info)
|
||||||
void *cb_arg)
|
|
||||||
{
|
{
|
||||||
struct ionic_tx_stats *stats = q_to_tx_stats(q);
|
struct ionic_tx_stats *stats = q_to_tx_stats(q);
|
||||||
struct ionic_qcq *qcq = q_to_qcq(q);
|
struct ionic_qcq *qcq = q_to_qcq(q);
|
||||||
struct sk_buff *skb = cb_arg;
|
struct sk_buff *skb;
|
||||||
|
|
||||||
if (desc_info->xdpf) {
|
if (desc_info->xdpf) {
|
||||||
ionic_xdp_tx_desc_clean(q->partner, desc_info);
|
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);
|
ionic_tx_desc_unmap_bufs(q, desc_info);
|
||||||
|
|
||||||
|
skb = desc_info->arg;
|
||||||
if (!skb)
|
if (!skb)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1263,13 +1259,12 @@ static bool ionic_tx_service(struct ionic_cq *cq, struct ionic_cq_info *cq_info,
|
||||||
desc_info->bytes = 0;
|
desc_info->bytes = 0;
|
||||||
index = q->tail_idx;
|
index = q->tail_idx;
|
||||||
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
|
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
|
||||||
ionic_tx_clean(q, desc_info, cq_info, desc_info->cb_arg);
|
ionic_tx_clean(q, desc_info, cq_info);
|
||||||
if (desc_info->cb_arg) {
|
if (desc_info->arg) {
|
||||||
pkts++;
|
pkts++;
|
||||||
bytes += desc_info->bytes;
|
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));
|
} while (index != le16_to_cpu(comp->comp_index));
|
||||||
|
|
||||||
(*total_pkts) += pkts;
|
(*total_pkts) += pkts;
|
||||||
|
@ -1334,13 +1329,12 @@ void ionic_tx_empty(struct ionic_queue *q)
|
||||||
desc_info = &q->info[q->tail_idx];
|
desc_info = &q->info[q->tail_idx];
|
||||||
desc_info->bytes = 0;
|
desc_info->bytes = 0;
|
||||||
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
|
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
|
||||||
ionic_tx_clean(q, desc_info, NULL, desc_info->cb_arg);
|
ionic_tx_clean(q, desc_info, NULL);
|
||||||
if (desc_info->cb_arg) {
|
if (desc_info->arg) {
|
||||||
pkts++;
|
pkts++;
|
||||||
bytes += desc_info->bytes;
|
bytes += desc_info->bytes;
|
||||||
|
desc_info->arg = NULL;
|
||||||
}
|
}
|
||||||
desc_info->cb = NULL;
|
|
||||||
desc_info->cb_arg = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (likely(!ionic_txq_hwstamp_enabled(q))) {
|
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);
|
skb_tx_timestamp(skb);
|
||||||
if (likely(!ionic_txq_hwstamp_enabled(q)))
|
if (likely(!ionic_txq_hwstamp_enabled(q)))
|
||||||
netdev_tx_sent_queue(q_to_ndq(netdev, q), skb->len);
|
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 {
|
} 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,
|
ring_dbell = __netdev_tx_sent_queue(ndq, skb->len,
|
||||||
netdev_xmit_more());
|
netdev_xmit_more());
|
||||||
}
|
}
|
||||||
ionic_txq_post(q, ring_dbell, ionic_tx_clean, skb);
|
ionic_txq_post(q, ring_dbell, skb);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue