static void ionic_qcqs_free(struct ionic_lif *lif)
{
struct device *dev = lif->ionic->dev;
+ struct ionic_qcq *adminqcq;
+ unsigned long irqflags;
if (lif->notifyqcq) {
ionic_qcq_free(lif, lif->notifyqcq);
}
if (lif->adminqcq) {
- ionic_qcq_free(lif, lif->adminqcq);
- devm_kfree(dev, lif->adminqcq);
+ spin_lock_irqsave(&lif->adminq_lock, irqflags);
+ adminqcq = READ_ONCE(lif->adminqcq);
lif->adminqcq = NULL;
+ spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
+ if (adminqcq) {
+ ionic_qcq_free(lif, adminqcq);
+ devm_kfree(dev, adminqcq);
+ }
}
if (lif->rxqcqs) {
struct ionic_intr_info *intr = napi_to_cq(napi)->bound_intr;
struct ionic_lif *lif = napi_to_cq(napi)->lif;
struct ionic_dev *idev = &lif->ionic->idev;
+ unsigned long irqflags;
unsigned int flags = 0;
int n_work = 0;
int a_work = 0;
n_work = ionic_cq_service(&lif->notifyqcq->cq, budget,
ionic_notifyq_service, NULL, NULL);
+ spin_lock_irqsave(&lif->adminq_lock, irqflags);
if (lif->adminqcq && lif->adminqcq->flags & IONIC_QCQ_F_INITED)
a_work = ionic_cq_service(&lif->adminqcq->cq, budget,
ionic_adminq_service, NULL, NULL);
+ spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
work_done = max(n_work, a_work);
if (work_done < budget && napi_complete_done(napi, work_done)) {
static void ionic_adminq_flush(struct ionic_lif *lif)
{
- struct ionic_queue *q = &lif->adminqcq->q;
struct ionic_desc_info *desc_info;
+ unsigned long irqflags;
+ struct ionic_queue *q;
+
+ spin_lock_irqsave(&lif->adminq_lock, irqflags);
+ if (!lif->adminqcq) {
+ spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
+ return;
+ }
- spin_lock(&lif->adminq_lock);
+ q = &lif->adminqcq->q;
while (q->tail_idx != q->head_idx) {
desc_info = &q->info[q->tail_idx];
desc_info->cb_arg = NULL;
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
}
- spin_unlock(&lif->adminq_lock);
+ spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
}
static int ionic_adminq_check_err(struct ionic_lif *lif,
static int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
{
struct ionic_desc_info *desc_info;
+ unsigned long irqflags;
struct ionic_queue *q;
int err = 0;
- if (!lif->adminqcq)
+ spin_lock_irqsave(&lif->adminq_lock, irqflags);
+ if (!lif->adminqcq) {
+ spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
return -EIO;
+ }
q = &lif->adminqcq->q;
- spin_lock(&lif->adminq_lock);
if (!ionic_q_has_space(q, 1)) {
err = -ENOSPC;
goto err_out;
ionic_q_post(q, true, ionic_adminq_cb, ctx);
err_out:
- spin_unlock(&lif->adminq_lock);
+ spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
return err;
}