Skip to content

Commit

Permalink
dsc-drivers: update ionic drivers to 24.03.4-001
Browse files Browse the repository at this point in the history
Under a large scale use we found that the check for a missed doorbell
was taking too much CPU, so we reworked the check to use a per-device
timer rather than a per-queue timer.

Internal patches:
    ionic: tighter test for active napi
    ionic: add per-device doorbell timer
    ionic: remove missed doorbell per-queue timer

Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
  • Loading branch information
emusln committed Apr 1, 2024
1 parent 23600d6 commit 889be07
Show file tree
Hide file tree
Showing 10 changed files with 89 additions and 47 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,12 +195,15 @@ As usual, if the Linux headers are elsewhere, add the appropriate -C magic:
- fix 16bit math issue when PAGE_SIZE >= 64KB
- restrict page-cache allocation to Rx queues

23-12-14 - driver update for 23.12.2-001
2023-12-14 - driver update for 23.12.2-001
- updates from upstream kernel fixes
- updates to FLR handling
- added AER error handling

24-03-19 - driver update for 24.03.1-002
2024-03-19 - driver update for 24.03.1-002
- Add XDP support
- Refactor Tx and Rx fast paths for performance
- Refactor struct sizes, layout, and usage for memory savings and performance

2024-04-01 - driver update for 24.03.4-001
- Fix to reduce impact of missed doorbell workaround
2 changes: 1 addition & 1 deletion drivers/linux/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ ALL = eth
endif

ifeq ($(DVER),)
DVER = "24.03.1-002"
DVER = "24.03.4-001"
endif
KCFLAGS += -Ddrv_ver=\\\"$(DVER)\\\"

Expand Down
1 change: 1 addition & 0 deletions drivers/linux/eth/ionic/ionic.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ struct ionic {
struct rw_semaphore vf_op_lock; /* lock for VF operations */
struct ionic_vf *vfs;
int num_vfs;
struct timer_list doorbell_timer;
struct timer_list watchdog_timer;
int watchdog_period;
};
Expand Down
4 changes: 4 additions & 0 deletions drivers/linux/eth/ionic/ionic_bus_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@ static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_deregister_devlink;
}

mod_timer(&ionic->doorbell_timer, jiffies + IONIC_NAPI_DEADLINE);
mod_timer(&ionic->watchdog_timer,
round_jiffies(jiffies + ionic->watchdog_period));

Expand Down Expand Up @@ -470,6 +471,7 @@ static void ionic_remove(struct pci_dev *pdev)
if (ionic->lif)
set_bit(IONIC_LIF_F_IN_SHUTDOWN, ionic->lif->state);

del_timer_sync(&ionic->doorbell_timer);
del_timer_sync(&ionic->watchdog_timer);

if (ionic->lif) {
Expand Down Expand Up @@ -509,6 +511,7 @@ void ionic_reset_prepare(struct pci_dev *pdev)
* scheduled and render these del/cancel calls useless (i.e. don't mix
* device triggered resets with userspace triggered resets).
*/
del_timer_sync(&ionic->doorbell_timer);
del_timer_sync(&ionic->watchdog_timer);

mutex_lock(&lif->queue_lock);
Expand Down Expand Up @@ -542,6 +545,7 @@ void ionic_reset_done(struct pci_dev *pdev)
if (err)
goto err_out;

mod_timer(&ionic->doorbell_timer, jiffies + IONIC_NAPI_DEADLINE);
mod_timer(&ionic->watchdog_timer, jiffies + 1);

err_out:
Expand Down
2 changes: 2 additions & 0 deletions drivers/linux/eth/ionic/ionic_bus_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ int ionic_probe(struct platform_device *pfdev)
goto err_out_deinit_lifs;
}

mod_timer(&ionic->doorbell_timer, jiffies + IONIC_NAPI_DEADLINE);
mod_timer(&ionic->watchdog_timer,
round_jiffies(jiffies + ionic->watchdog_period));

Expand Down Expand Up @@ -430,6 +431,7 @@ int ionic_remove(struct platform_device *pfdev)
struct ionic *ionic = platform_get_drvdata(pfdev);

if (ionic) {
del_timer_sync(&ionic->doorbell_timer);
del_timer_sync(&ionic->watchdog_timer);
ionic_lif_unregister(ionic->lif);
ionic_lif_deinit(ionic->lif);
Expand Down
25 changes: 21 additions & 4 deletions drivers/linux/eth/ionic/ionic_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,26 @@ void ionic_watchdog_init(struct ionic *ionic)
ioread8(&idev->dev_info_regs->fw_status);
}

static void ionic_doorbell_cb(struct timer_list *timer)
{
struct ionic *ionic = container_of(timer, struct ionic, doorbell_timer);
struct ionic_lif *lif = ionic->lif;
struct ionic_deferred_work *work;

if (test_bit(IONIC_LIF_F_IN_SHUTDOWN, lif->state))
return;

if (!test_bit(IONIC_LIF_F_FW_RESET, lif->state)) {
work = kzalloc(sizeof(*work), GFP_ATOMIC);
if (work) {
work->type = IONIC_DW_TYPE_DOORBELL;
ionic_lif_deferred_enqueue(&lif->deferred, work);
}
}

mod_timer(&ionic->doorbell_timer, jiffies + IONIC_NAPI_DEADLINE);
}

void ionic_init_devinfo(struct ionic *ionic)
{
struct ionic_dev *idev = &ionic->idev;
Expand Down Expand Up @@ -137,6 +157,7 @@ int ionic_dev_setup(struct ionic *ionic)
return -EFAULT;
}

timer_setup(&ionic->doorbell_timer, ionic_doorbell_cb, 0);
ionic_watchdog_init(ionic);

idev->db_pages = bar->vaddr;
Expand Down Expand Up @@ -724,10 +745,6 @@ void ionic_q_post(struct ionic_queue *q, bool ring_doorbell)
q->dbval | q->head_idx);

q->dbell_jiffies = jiffies;

if (q_to_qcq(q)->napi_qcq)
mod_timer(&q_to_qcq(q)->napi_qcq->napi_deadline,
jiffies + IONIC_NAPI_DEADLINE);
}
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/linux/eth/ionic/ionic_dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#define IONIC_DEV_INFO_REG_COUNT 32
#define IONIC_DEV_CMD_REG_COUNT 32

#define IONIC_NAPI_DEADLINE (HZ / 200) /* 5ms */
#define IONIC_NAPI_DEADLINE (HZ / 50) /* 20ms */
#define IONIC_ADMIN_DOORBELL_DEADLINE (HZ / 2) /* 500ms */
#define IONIC_TX_DOORBELL_DEADLINE (HZ / 100) /* 10ms */
#define IONIC_RX_MIN_DOORBELL_DEADLINE (HZ / 100) /* 10ms */
Expand Down
66 changes: 45 additions & 21 deletions drivers/linux/eth/ionic/ionic_lif.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,42 @@ static void ionic_dim_work(struct work_struct *work)
dim->state = DIM_START_MEASURE;
}

static void ionic_doorbell_check(struct ionic_lif *lif)
{
if (test_bit(IONIC_LIF_F_FW_RESET, lif->state) ||
test_bit(IONIC_LIF_F_IN_SHUTDOWN, lif->state))
return;

mutex_lock(&lif->queue_lock);

napi_schedule(&lif->adminqcq->napi);

if (test_bit(IONIC_LIF_F_UP, lif->state)) {
int i;

for (i = 0; i < lif->nxqs; i++) {
struct ionic_qcq *qcq;

qcq = lif->txqcqs[i];
if (qcq->flags & IONIC_QCQ_F_INTR)
napi_schedule(&qcq->napi);

qcq = lif->rxqcqs[i];
if (qcq->flags & IONIC_QCQ_F_INTR)
napi_schedule(&qcq->napi);
}

if (lif->hwstamp_txq &&
lif->hwstamp_txq->flags & IONIC_QCQ_F_INTR)
napi_schedule(&lif->hwstamp_txq->napi);
if (lif->hwstamp_rxq &&
lif->hwstamp_rxq->flags & IONIC_QCQ_F_INTR)
napi_schedule(&lif->hwstamp_rxq->napi);

}
mutex_unlock(&lif->queue_lock);
}

static void ionic_lif_deferred_work(struct work_struct *work)
{
struct ionic_lif *lif = container_of(work, struct ionic_lif, deferred.work);
Expand All @@ -112,6 +148,9 @@ static void ionic_lif_deferred_work(struct work_struct *work)
case IONIC_DW_TYPE_LINK_STATUS:
ionic_link_status_check(lif);
break;
case IONIC_DW_TYPE_DOORBELL:
ionic_doorbell_check(lif);
break;
case IONIC_DW_TYPE_LIF_RESET:
if (w->fw_status) {
ionic_lif_handle_fw_up(lif);
Expand Down Expand Up @@ -223,13 +262,6 @@ void ionic_link_status_check_request(struct ionic_lif *lif, bool can_sleep)
}
}

static void ionic_napi_deadline(struct timer_list *timer)
{
struct ionic_qcq *qcq = container_of(timer, struct ionic_qcq, napi_deadline);

napi_schedule(&qcq->napi);
}

static irqreturn_t ionic_isr(int irq, void *data)
{
struct napi_struct *napi = data;
Expand Down Expand Up @@ -347,7 +379,6 @@ static int ionic_qcq_disable(struct ionic_lif *lif, struct ionic_qcq *qcq, int f

if (qcq->napi.poll) {
napi_disable(&qcq->napi);
del_timer_sync(&qcq->napi_deadline);
synchronize_net();
}

Expand Down Expand Up @@ -898,7 +929,6 @@ static int ionic_lif_txq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state)) {
netif_napi_add(lif->netdev, &qcq->napi, ionic_tx_napi);
qcq->napi_qcq = qcq;
timer_setup(&qcq->napi_deadline, ionic_napi_deadline, 0);
}

qcq->flags |= IONIC_QCQ_F_INITED;
Expand Down Expand Up @@ -978,7 +1008,6 @@ static int ionic_lif_rxq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
netif_napi_add(lif->netdev, &qcq->napi, ionic_txrx_napi);

qcq->napi_qcq = qcq;
timer_setup(&qcq->napi_deadline, ionic_napi_deadline, 0);

qcq->flags |= IONIC_QCQ_F_INITED;

Expand Down Expand Up @@ -1234,7 +1263,6 @@ static int ionic_adminq_napi(struct napi_struct *napi, int budget)
struct ionic_dev *idev = &lif->ionic->idev;
unsigned long irqflags;
unsigned int flags = 0;
bool resched = false;
int rx_work = 0;
int tx_work = 0;
int n_work = 0;
Expand Down Expand Up @@ -1271,15 +1299,12 @@ static int ionic_adminq_napi(struct napi_struct *napi, int budget)
ionic_intr_credits(idev->intr_ctrl, intr->index, credits, flags);
}

if (!a_work && ionic_adminq_poke_doorbell(&lif->adminqcq->q))
resched = true;
if (lif->hwstamp_rxq && !rx_work && ionic_rxq_poke_doorbell(&lif->hwstamp_rxq->q))
resched = true;
if (lif->hwstamp_txq && !tx_work && ionic_txq_poke_doorbell(&lif->hwstamp_txq->q))
resched = true;
if (resched)
mod_timer(&lif->adminqcq->napi_deadline,
jiffies + IONIC_NAPI_DEADLINE);
if (!a_work)
ionic_adminq_poke_doorbell(&lif->adminqcq->q);
if (lif->hwstamp_rxq && !rx_work)
ionic_rxq_poke_doorbell(&lif->hwstamp_rxq->q);
if (lif->hwstamp_txq && !tx_work)
ionic_txq_poke_doorbell(&lif->hwstamp_txq->q);

return work_done;
}
Expand Down Expand Up @@ -3761,7 +3786,6 @@ static int ionic_lif_adminq_init(struct ionic_lif *lif)
netif_napi_add(lif->netdev, &qcq->napi, ionic_adminq_napi);

qcq->napi_qcq = qcq;
timer_setup(&qcq->napi_deadline, ionic_napi_deadline, 0);

napi_enable(&qcq->napi);

Expand Down
2 changes: 1 addition & 1 deletion drivers/linux/eth/ionic/ionic_lif.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ struct ionic_qcq {
u32 cmb_order;
bool armed;
struct dim dim;
struct timer_list napi_deadline;
struct ionic_queue q;
struct ionic_cq cq;
struct napi_struct napi;
Expand All @@ -142,6 +141,7 @@ enum ionic_deferred_work_type {
IONIC_DW_TYPE_RX_MODE,
IONIC_DW_TYPE_LINK_STATUS,
IONIC_DW_TYPE_LIF_RESET,
IONIC_DW_TYPE_DOORBELL,
};

struct ionic_deferred_work {
Expand Down
25 changes: 8 additions & 17 deletions drivers/linux/eth/ionic/ionic_txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1022,12 +1022,6 @@ void ionic_rx_fill(struct ionic_queue *q)

ionic_dbell_ring(q->lif->kern_dbpage, q->hw_type,
q->dbval | q->head_idx);

q->dbell_deadline = IONIC_RX_MIN_DOORBELL_DEADLINE;
q->dbell_jiffies = jiffies;

mod_timer(&q_to_qcq(q)->napi_qcq->napi_deadline,
jiffies + IONIC_NAPI_DEADLINE);
}

void ionic_rx_empty(struct ionic_queue *q)
Expand Down Expand Up @@ -1112,8 +1106,8 @@ int ionic_tx_napi(struct napi_struct *napi, int budget)
work_done, flags);
}

if (!work_done && ionic_txq_poke_doorbell(&qcq->q))
mod_timer(&qcq->napi_deadline, jiffies + IONIC_NAPI_DEADLINE);
if (!work_done)
ionic_txq_poke_doorbell(&qcq->q);

DEBUG_STATS_NAPI_POLL(qcq, work_done);

Expand Down Expand Up @@ -1159,8 +1153,8 @@ int ionic_rx_napi(struct napi_struct *napi, int budget)
work_done, flags);
}

if (!work_done && ionic_rxq_poke_doorbell(&qcq->q))
mod_timer(&qcq->napi_deadline, jiffies + IONIC_NAPI_DEADLINE);
if (!work_done)
ionic_rxq_poke_doorbell(&qcq->q);

DEBUG_STATS_NAPI_POLL(qcq, work_done);

Expand All @@ -1175,7 +1169,6 @@ int ionic_txrx_napi(struct napi_struct *napi, int budget)
struct ionic_qcq *txqcq;
struct ionic_lif *lif;
struct ionic_cq *txcq;
bool resched = false;
u32 rx_work_done = 0;
u32 tx_work_done = 0;
u32 flags = 0;
Expand Down Expand Up @@ -1210,12 +1203,10 @@ int ionic_txrx_napi(struct napi_struct *napi, int budget)
DEBUG_STATS_NAPI_POLL(rxqcq, rx_work_done);
DEBUG_STATS_NAPI_POLL(txqcq, tx_work_done);

if (!rx_work_done && ionic_rxq_poke_doorbell(&rxqcq->q))
resched = true;
if (!tx_work_done && ionic_txq_poke_doorbell(&txqcq->q))
resched = true;
if (resched)
mod_timer(&rxqcq->napi_deadline, jiffies + IONIC_NAPI_DEADLINE);
if (!rx_work_done)
ionic_rxq_poke_doorbell(&rxqcq->q);
if (!tx_work_done)
ionic_txq_poke_doorbell(&txqcq->q);

return rx_work_done;
}
Expand Down

0 comments on commit 889be07

Please sign in to comment.