Skip to content

Commit

Permalink
ionic: protect adminq from early destroy
Browse files Browse the repository at this point in the history
Don't destroy the adminq while there is an outstanding request.

Signed-off-by: Shannon Nelson <snelson@pensando.io>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Shannon Nelson authored and David S. Miller committed Mar 19, 2021
1 parent 9e8eaf8 commit e768929
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 8 deletions.
14 changes: 12 additions & 2 deletions drivers/net/ethernet/pensando/ionic/ionic_lif.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,8 @@ static void ionic_qcq_free(struct ionic_lif *lif, struct ionic_qcq *qcq)
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);
Expand All @@ -401,9 +403,14 @@ static void ionic_qcqs_free(struct ionic_lif *lif)
}

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) {
Expand Down Expand Up @@ -886,6 +893,7 @@ static int ionic_adminq_napi(struct napi_struct *napi, int budget)
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;
Expand All @@ -895,9 +903,11 @@ static int ionic_adminq_napi(struct napi_struct *napi, int budget)
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)) {
Expand Down
22 changes: 16 additions & 6 deletions drivers/net/ethernet/pensando/ionic/ionic_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,17 @@ static const char *ionic_opcode_to_str(enum ionic_cmd_opcode opcode)

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];
Expand All @@ -199,7 +206,7 @@ static void ionic_adminq_flush(struct ionic_lif *lif)
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,
Expand Down Expand Up @@ -252,15 +259,18 @@ static void ionic_adminq_cb(struct ionic_queue *q,
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;
Expand All @@ -280,7 +290,7 @@ static int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
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;
}
Expand Down

0 comments on commit e768929

Please sign in to comment.