diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c index ec4775f0ec163a2ac4e3d89851bedfb4a0d52db1..4321488d21795233dff7668db612280222c1c84b 100644 --- a/drivers/ntb/ntb_transport.c +++ b/drivers/ntb/ntb_transport.c @@ -124,6 +124,7 @@ struct ntb_transport_qp { bool client_ready; bool link_is_up; + bool active; u8 qp_num; /* Only 64 QP's are allowed. 0-63 */ u64 qp_bit; @@ -719,6 +720,7 @@ static int ntb_set_mw(struct ntb_transport_ctx *nt, int num_mw, static void ntb_qp_link_down_reset(struct ntb_transport_qp *qp) { qp->link_is_up = false; + qp->active = false; qp->tx_index = 0; qp->rx_index = 0; @@ -926,11 +928,13 @@ static void ntb_qp_link_work(struct work_struct *work) if (val & BIT(qp->qp_num)) { dev_info(&pdev->dev, "qp %d: Link Up\n", qp->qp_num); qp->link_is_up = true; + qp->active = true; if (qp->event_handler) qp->event_handler(qp->cb_data, qp->link_is_up); - tasklet_schedule(&qp->rxc_db_work); + if (qp->active) + tasklet_schedule(&qp->rxc_db_work); } else if (nt->link_is_up) schedule_delayed_work(&qp->link_work, msecs_to_jiffies(NTB_LINK_DOWN_TIMEOUT)); @@ -1411,7 +1415,8 @@ static void ntb_transport_rxc_db(unsigned long data) if (i == qp->rx_max_entry) { /* there is more work to do */ - tasklet_schedule(&qp->rxc_db_work); + if (qp->active) + tasklet_schedule(&qp->rxc_db_work); } else if (ntb_db_read(qp->ndev) & BIT_ULL(qp->qp_num)) { /* the doorbell bit is set: clear it */ ntb_db_clear(qp->ndev, BIT_ULL(qp->qp_num)); @@ -1422,7 +1427,8 @@ static void ntb_transport_rxc_db(unsigned long data) * ntb_process_rxc and clearing the doorbell bit: * there might be some more work to do. */ - tasklet_schedule(&qp->rxc_db_work); + if (qp->active) + tasklet_schedule(&qp->rxc_db_work); } } @@ -1760,6 +1766,8 @@ void ntb_transport_free_queue(struct ntb_transport_qp *qp) pdev = qp->ndev->pdev; + qp->active = false; + if (qp->tx_dma_chan) { struct dma_chan *chan = qp->tx_dma_chan; /* Putting the dma_chan to NULL will force any new traffic to be @@ -1793,7 +1801,7 @@ void ntb_transport_free_queue(struct ntb_transport_qp *qp) qp_bit = BIT_ULL(qp->qp_num); ntb_db_set_mask(qp->ndev, qp_bit); - tasklet_disable(&qp->rxc_db_work); + tasklet_kill(&qp->rxc_db_work); cancel_delayed_work_sync(&qp->link_work); @@ -1886,7 +1894,8 @@ int ntb_transport_rx_enqueue(struct ntb_transport_qp *qp, void *cb, void *data, ntb_list_add(&qp->ntb_rx_q_lock, &entry->entry, &qp->rx_pend_q); - tasklet_schedule(&qp->rxc_db_work); + if (qp->active) + tasklet_schedule(&qp->rxc_db_work); return 0; } @@ -2069,7 +2078,8 @@ static void ntb_transport_doorbell_callback(void *data, int vector) qp_num = __ffs(db_bits); qp = &nt->qp_vec[qp_num]; - tasklet_schedule(&qp->rxc_db_work); + if (qp->active) + tasklet_schedule(&qp->rxc_db_work); db_bits &= ~BIT_ULL(qp_num); }